最近在搞P-Code编码解码的引擎,于是对P-Code有了一些理解。
也发现了现在很多网络上关于P-Code文章的的一些错误。
首先,在昨天以前,我也一直认为P-Code只有一种形式的变长指令,在安于此生大牛的帖子里我也是这么说的,可是事实却不是如此。
目前关于P-Code指令格式的文章,国内好像基本都是转载国外的。
而国外的好像也都是同一出处,应该都是出自wktvbdebugger目录下那个chm文档。
那个文档里有应该算是当时最全面的P-Code指令的介绍了。我得承认wktvbdbg的作者真的很牛。
但是人都会犯错,大牛也不例外,今天在研究我那个引擎解析P-Code指令参数时,发现指令长度跟vbvm实际取的参数不一致。
起先一直认为是我错了。研究了好久,才发现是wktvbdbg的作者错了。先把代码发上来看看:

661007BF > /0FB706 movzx eax, word ptr ds:[esi] ; 取第2个WORD参数
661007C2 . |83C6 02 add esi, 0x2 ; 增加指令指针
661007C5 . |42 inc edx
661007C6 . |74 05 je short msvbvm60.661007CD
661007C8 . |8B75 A8 mov esi, dword ptr ss:[ebp-0x58]
661007CB . |03F0 add esi, eax
661007CD > |33C0 xor eax, eax ; eax置零
661007CF . |8A06 mov al, byte ptr ds:[esi] ; 取下个操作码
661007D1 . |46 inc esi ; 自增指令指针
661007D2 . |FF2485 5CD40F66 jmp dword ptr ds:[eax*4+0x660FD45C] ; 跳转到处理函数
661007D9 > |BB 9B631066 mov ebx, msvbvm60.6610639B
661007DE .^|EB D2 jmp short msvbvm60.661007B2
661007E0 > |BB CE5E1066 mov ebx, msvbvm60.__vbaForEachCollVar
661007E5 .^|EB CB jmp short msvbvm60.661007B2
661007E7 > |BB E7631066 mov ebx, msvbvm60.661063E7 ; ebx放入函数地址
661007EC > |0FBF06 movsx eax, word ptr ds:[esi] ; 取第1个WORD参数
661007EF . |83C6 02 add esi, 0x2 ; 增加指令指针
661007F2 . |03C5 add eax, ebp
661007F4 . |50 push eax
661007F5 . |FFD3 call ebx
661007F7 . |8BD0 mov edx, eax
661007F9 . |F7D2 not edx
661007FB .^ EB C2 jmp short msvbvm60.661007BF ; 无条件跳转
[URL="http://46fK9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8Y4N6%4N6#2)9J5k6i4k6T1i4K6u0V1k6r3g2U0L8$3#2H3K9h3I4W2M7W2)9J5k6h3!0J5k6#2)9J5c8X3S2A6M7%4c8G2M7Y4W2Q4x3X3g2Z5N6r3@1`."]VB Decompiler History[/URL]
0xFE前缀:
LateMemNamed* :
/*A6h*/ LateMemNamedCall
/*A7h*/ LateMemNamedCallLdVar
/*A8h*/ LateMemNamedCallStVar
/*A9h*/ LateMemNamedStAd
LateIdNamed* :
/*AAh*/ LateIdNamedCall
/*ABh*/ LateIdNamedCallLdVar
/*ACh*/ LateIdNamedCallStVar
/*ADh*/ LateIdNamedStAd
66101167 > 0FB716 movzx edx, word ptr ds:[esi] ; 后缀长度
6610116A . |0FB746 02 movzx eax, word ptr ds:[esi+0x2]
6610116E . |83EA 04 sub edx, 0x4 ; 后缀长度-4
66101171 . |0FB75E 04 movzx ebx, word ptr ds:[esi+0x4]
66101175 . |83C6 06 add esi, 0x6 ; 增加指令指针
66101178 . |33FF xor edi, edi
6610117A . |B9 01000000 mov ecx, 0x1
6610117F > |57 push edi
66101180 . |D1EA shr edx, 1 ; 后缀长度右移1位 (后缀长度 / 2)
66101182 . |52 push edx
66101183 . |56 push esi
66101184 . |D1E2 shl edx, 1 ; 后缀长度左移1位 (后缀长度 * 2)
66101186 . |03F2 add esi, edx ; 指令指针+后缀长度
66101188 . |53 push ebx
66101189 . |8BD4 mov edx, esp
6610118B . |83C2 10 add edx, 0x10
6610118E . |52 push edx
6610118F . |51 push ecx
66101190 . |FF75 AC push dword ptr ss:[ebp-0x54]
66101193 . |50 push eax
66101194 . |FF75 B4 push dword ptr ss:[ebp-0x4C]
66101197 . |E8 EC6D0000 call msvbvm60.66107F88
6610119C .^|E9 19FDFFFF jmp msvbvm60.66100EBA
[培训]科锐逆向工程师培训第53期2025年7月8日开班!