VStartVM:
00402230 > 50 PUSH EAX
00402231 53 PUSH EBX
00402232 51 PUSH ECX
00402233 52 PUSH EDX
00402234 56 PUSH ESI
00402235 57 PUSH EDI
00402236 55 PUSH EBP
00402237 9C PUSHFD
00402238 8B7424 20 MOV ESI,DWORD PTR SS:[ESP+20] ;参数 字节码开始的地址
0040223C 8BEC MOV EBP,ESP ;ebp就是堆栈
0040223E 81EC 00020000 SUB ESP,200
00402244 8BFC MOV EDI,ESP edi就是VMContext
00402246 83EC 40 SUB ESP,40
VMDispatcher:
00402249 0FB606 MOVZX EAX,BYTE PTR DS:[ESI] 获得bytecode
0040224C 8D76 01 LEA ESI,DWORD PTR DS:[ESI+1] 跳过这个字节
0040224F EB 00 JMP SHORT APIhash.00402251 跳刀Handler 这里简写 jmp dword ptr [eax*4+JUMPADDR]
Vbegin:
00402251 8B45 00 MOV EAX,DWORD PTR SS:[EBP]
00402254 8947 1C MOV DWORD PTR DS:[EDI+1C],EAX ;v_dfl
00402257 83C5 04 ADD EBP,4
0040225A 83C5 04 ADD EBP,4 ;这里省略 v_ebp mov [edi+0x18],eax
0040225D 83C5 04 ADD EBP,4 ;这里省略 v_edi mov [edi+0x14],eax
00402260 83C5 04 ADD EBP,4 ;这里省略 v_esi mov [edi+0x10],eax
00402263 83C5 04 ADD EBP,4 ;这里省略 v_edx mov [edi+0x0C],eax
00402266 83C5 04 ADD EBP,4 ;这里省略 v_ecx mov [edi+0x08],eax
00402269 83C5 04 ADD EBP,4 ;这里省略 v_ebx mov [edi+0x04],eax
0040226C 83C5 04 ADD EBP,4 ;这里省略 v_eax mov [edi],eax
0040226F 83C5 04 ADD EBP,4 ;这里是省略参数 最开始的返回函数被弹出
00402272 ^ EB D5 JMP SHORT APIhash.00402249 ;跳回VMDispatcher:
之后 堆栈就平衡了 VMContext结构存放在当前使用的堆栈更靠下面的一部分 所以应该避免VMContext被覆盖的情况
但是如果不小很多 的话就会在某条指令后改写 VMContext的内容 所以设计了下面的:
VCheckESP:
00402274 8D87 00010000 LEA EAX,DWORD PTR DS:[EDI+100] VMContext +0x100 就是往堆栈下走 跟 真实的ESP比 小于继续执行 否则就要执行JL后面的内容
0040227A 3BC5 CMP EAX,EBP
0040227C ^ 7C D1 JL SHORT APIhash.0040224F
0040227E 8BD7 MOV EDX,EDI EDX = VMContext
00402280 8BCC MOV ECX,ESP ECX = 当前假的的ESP 这个就更小了 VMContext在ESP上面
00402282 2BCA SUB ECX,EDX ECX-EDX
00402284 56 PUSH ESI 保存IP指针
00402285 8BF4 MOV ESI,ESP ESI = 当前IP指针
00402287 83EC 60 SUB ESP,60
0040228A 8BFC MOV EDI,ESP 把它赋值给 VMContext
0040228C 57 PUSH EDI 保存新的edi 地址
0040228D 83EC 40 SUB ESP,40 假个esp 再往上走
00402290 FC CLD
00402291 F3:A4 REP MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI] ESI往上跑
00402293 5F POP EDI 还原VMContext
00402294 5E POP ESI 还原IP指针
00402295 ^ EB B2 JMP SHORT APIhash.00402249
00402297 90 NOP
一些会涉及堆栈的Handler在执行后跳转到VCheckESP判断ESP是否接近 VMContext 如果是就将VMContext赋值到更远的位置存放