VMProtect分析-虚拟化流程

一、没有大炮我们自己造

首先编写一个简单的程序。

1
2
3
4
5
6
7
int main()
{
int a = 1;
a = a + 1;
printf("%d\n",a);
return 0;
}

编译后给程序添加vmp保护壳,这里选择的VMP版本为v3.5.0

image-20230105160101521

保护的函数为main函数,编译类型修改为虚拟。

image-20230105160113820

并且关闭一系列保护。

image-20230105160125791

编译完成后,可看到程序体积有一个翻倍增加。

image-20230105160139363

二、只能拉一点点

首先对原程序的汇编进行一个简单查看,用vs在main函数中打下断点运行后,查看反汇编窗口。

image-20230105160153886

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
00401040 55                   push        ebp  						;ebp=0x19ff74
00401041 8B EC mov ebp,esp ;ebp=0x19FF2C
00401043 51 push ecx ;ecx=0x0
00401044 C7 45 FC 01 00 00 00 mov dword ptr [ebp-4],1 ;ebp-4=0x19FF28 { int a = 1; }
0040104B 8B 45 FC mov eax,dword ptr [ebp-4] ;eax=0x1
0040104E 83 C0 01 add eax,1 ;eax=0x2
00401051 89 45 FC mov dword ptr [ebp-4],eax ;ebp-4=0x19FF28 { a = a + 1; }
00401054 8B 4D FC mov ecx,dword ptr [ebp-4] ;ecx=0x2
00401057 51 push ecx
00401058 68 FC 20 40 00 push 4020FCh ;"%d\n"
0040105D E8 0E 00 00 00 call 00401070 ;{ printf("%d\n",a); }
00401062 83 C4 08 add esp,8
00401065 33 C0 xor eax,eax
00401067 8B E5 mov esp,ebp
00401069 5D pop ebp
0040106A C3 ret

经过对vmp的分析,可知vmp会将一条代码指令进行拆分后以push和pop命令进行实现,其中push和pop为vmp自实现的函数,这种被vmp自实现用来代替原有指令的函数叫做handler;解密字节码并跳转到对应的handler,这个过程叫做dispatch.例如mov ebp,esp的执行在vmp下会被修改为如下代码:

image-20230105160206575

并且vmp会对通用寄存器有自己的解释。

1
2
3
4
5
6
7
8
EAX:通用寄存器
EDX:通用寄存器
ECX:通用寄存器
EDI:opcode
ESP:虚拟机的栈顶,v_esp
ESI:实际堆栈
EBP:虚拟机的执行地址,v_eip
EBX:滚动key

同时也有定义了自己的寄存器,用来存放一些临时数据。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
struct vm_context
{
uint32_t R0; //0x00
uint32_t R1; //0x04
uint32_t R2; //0x08
uint32_t R3; //0x0C
uint32_t R4; //0x10
uint32_t R5; //0x14
uint32_t R6; //0x18
uint32_t R7; //0x1C
uint32_t R8; //0x20
uint32_t R9; //0x24
uint32_t R10; //0x28
uint32_t R11; //0x2C
uint32_t R12; //0x30
uint32_t R13; //0x34
uint32_t R14; //0x38
uint32_t R15; //0x3C
}

三、时间会告诉你答案

把加了vmp壳的程序拖入OD,能看到属于VMP的入口点。

image-20230105160031408

其中push的内容为被加密了的opcode,opcode存放着的是所有的handler地址和一些操作寄存器的数据。

1、指令分析

下列所有的代码均为手工取出虚拟化后的代码,并且所有加了v或者v_前缀的内容均值的是vmp自定义的数据。由于vmp在执行函数时会退出虚拟机,函数执行完毕后重新进入虚拟机,因此流程只跟踪到执行printf函数完毕。


VMEntry

1
2
00475751    68 C3365BBC     push 0xBC5B36C3
00475756 E8 BE1FFAFF call test1_vm.00417719

VMInit

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
00417719    50              push eax                                 ; 保存堆栈
00417720 51 push ecx
00417721 9C pushfd
00417724 53 push ebx
00417727 56 push esi
0041772E 57 push edi
00417734 52 push edx
0041773D 55 push ebp
00417742 BA 00000000 mov edx,0x0
00417747 52 push edx
0041774A 8B7C24 28 mov edi,dword ptr ss:[esp+0x28] ;0xBC5B36C3获取外层push的参数
00417756 4F dec edi ;开始解密参数
0041775C 81F7 5442907B xor edi,0x7B904254
0041776F F7D7 not edi
0041777B F7DF neg edi
00417781 F7D7 not edi
0041778A 81EF 98071636 sub edi,0x36160798
00417797 C1CF 03 ror edi,0x3
004177A2 8D3C17 lea edi,dword ptr ds:[edi+edx] ;EDI=v_eip,内容以opcode形式存放
004177A5 8BF4 mov esi,esp ;保存原始esp
004177A7 81EC C0000000 sub esp,0xC0 ;开辟新堆栈,vm_context
004177AD 8BDF mov ebx,edi ;初始化滚动Key
004177B6 B8 00000000 mov eax,0x0
004177C2 2BD8 sub ebx,eax
004177CE 8D2D CE774100 lea ebp,dword ptr ds:[0x4177CE] ;获取虚拟机代码的起始地址
004177D7 8B17 mov edx,dword ptr ds:[edi] ;读取opcode
004177DA 81C7 04000000 add edi,0x4 ;递增opcode,跳到下一个opcode
0043DC1F 33D3 xor edx,ebx ;解密
0043DC26 F7DA neg edx
0043DC29 D1CA ror edx,1
00469F4B 4A dec edx
00469F4C 81F2 88622457 xor edx,0x57246288
00469F57 81EA B426A803 sub edx,0x3A826B4
00469F63 0FCA bswap edx
00469F66 81F2 F21FD256 xor edx,0x56D21FF2
004263AF C1CA 03 ror edx,0x3
004263B6 33DA xor ebx,edx ;更新滚动key
004263B8 03EA add ebp,edx ;计算出handler地址
004263BA ^ FFE5 jmp ebp ;test1_vm.004343B9

vPop r10

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
004343B9    8B0E            mov ecx,dword ptr ds:[esi]				;读取原始esp
004343C4 0FB607 movzx eax,byte ptr ds:[edi] ;读取opcode的第一个字节
004343C7 81C7 01000000 add edi,0x1 ;跳过读取的字节
004343CD 32C3 xor al,bl ;解密读取到的字节
004343CF 04 95 add al,0x95
004343D1 F6D8 neg al
0040ACDA FEC0 inc al
0040ACDE 34 28 xor al,0x28
0040ACEB 32D8 xor bl,al ;更新滚动key
0040ACEF 890C04 mov dword ptr ss:[esp+eax],ecx ;eax=0x28
0040ACF5 8B0F mov ecx,dword ptr ds:[edi] ;从opcode读取4字节
0040ACF8 81C7 04000000 add edi,0x4 ;递增opcode,跳到下一个opcode
0040AD03 33CB xor ecx,ebx ;解密读取到的4字节
0047679A C1C9 02 ror ecx,0x2
0047679D 81F1 7E7F9C09 xor ecx,0x99C7F7E
00448CC5 49 dec ecx
00448CC6 81F1 F25E4677 xor ecx,0x77465EF2
00448CCD 8D89 1A29644A lea ecx,dword ptr ds:[ecx+0x4A64291A]
00448CD3 33D9 xor ebx,ecx ;更新滚动key
00448CDA 03E9 add ebp,ecx
00449A6E 55 push ebp ;压栈下一个handler地址后跳转
00449A6F C3 retn ;0x46FF2C

vPop r12

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
0046FF2C    8B0E            mov ecx,dword ptr ds:[esi]				;读取原始esp
0046FF2E 8DB6 04000000 lea esi,dword ptr ds:[esi+0x4] ;原始esp+0x4, 此处两句指令对应 pop ecx
0046FF37 0FB607 movzx eax,byte ptr ds:[edi] ;读取opcode的第一个字节
0046FF3A 8DBF 01000000 lea edi,dword ptr ds:[edi+0x1] ;跳过读取的字节
0046FF48 32C3 xor al,bl ;解密读取到的字节
0046FF53 04 95 add al,0x95
00446B15 F6D8 neg al
00454B5C FEC0 inc al
00454B61 34 28 xor al,0x28
00454B64 32D8 xor bl,al ;更新滚动key
00454B66 890C04 mov dword ptr ss:[esp+eax],ecx ;eax=0x30
00454B6C 8B0F mov ecx,dword ptr ds:[edi] ;从opcode读取4字节
00454B72 8DBF 04000000 lea edi,dword ptr ds:[edi+0x4] ;递增opcode,跳到下一个opcode
00454B7A 33CB xor ecx,ebx ;解密读取到的4字节
00454B7C C1C9 02 ror ecx,0x2
00454B7F 81F1 7E7F9C09 xor ecx,0x99C7F7E
00422059 49 dec ecx
0042205D 81F1 F25E4677 xor ecx,0x77465EF2
00422065 8D89 1A29644A lea ecx,dword ptr ds:[ecx+0x4A64291A]
0042206B 33D9 xor ebx,ecx
0042206D 03E9 add ebp,ecx ;更新滚动key
00409147 /FFE5 jmp ebp ;0x00453841

vPop r8

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
00453841    8B0E            mov ecx,dword ptr ds:[esi]				;读取原始esp
00453846 81C6 04000000 add esi,0x4 ;原始esp+0x4, 此处两句指令对应 pop ecx
00453854 0FB607 movzx eax,byte ptr ds:[edi] ;读取opcode的第一个字节
00453857 81C7 01000000 add edi,0x1 ;跳过读取的字节
00453866 32C3 xor al,bl ;解密读取到的字节
0045386E 04 95 add al,0x95
00453870 F6D8 neg al
00458E65 FEC0 inc al
00458E6B 34 28 xor al,0x28
00458E6D 32D8 xor bl,al ;更新滚动key
00458E6F 890C04 mov dword ptr ss:[esp+eax],ecx ;eax=0x20
00458E7C 8B0F mov ecx,dword ptr ds:[edi] ;从opcode读取4字节
00479B0C 81C7 04000000 add edi,0x4 ;递增opcode,跳到下一个opcode
0041B623 33CB xor ecx,ebx
00470224 C1C9 02 ror ecx,0x2
00470227 81F1 7E7F9C09 xor ecx,0x99C7F7E
004452FB 49 dec ecx
004452FC 81F1 F25E4677 xor ecx,0x77465EF2
00445305 81C1 1A29644A add ecx,0x4A64291A
0044530B 33D9 xor ebx,ecx ;更新滚动key
0044530D 03E9 add ebp,ecx
0043AD66 55 push ebp
0043AD67 C3 retn ;0x00430521

vPop r6

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
00430521    8B0E            mov ecx,dword ptr ds:[esi]				;读取原始esp
00430523 81C6 04000000 add esi,0x4 ;原始esp+0x4, 此处两句指令对应 pop ecx
00430529 0FB607 movzx eax,byte ptr ds:[edi] ;读取opcode的第一个字节
004552EE 81C7 01000000 add edi,0x1 ;跳过读取的字节
004552F4 32C3 xor al,bl ;解密读取到的字节
004552F9 04 95 add al,0x95
004552FB F6D8 neg al
004552FD FEC0 inc al
00455303 34 28 xor al,0x28
00455309 32D8 xor bl,al ;更新滚动key
0045530C 890C04 mov dword ptr ss:[esp+eax],ecx ;eax=0x18
00455311 8B0F mov ecx,dword ptr ds:[edi] ;从opcode读取4字节
00455313 81C7 04000000 add edi,0x4 ;递增opcode,跳到下一个opcode
0045531F 33CB xor ecx,ebx
00455324 C1C9 02 ror ecx,0x2
0045532B 81F1 7E7F9C09 xor ecx,0x99C7F7E
00455331 49 dec ecx
00455332 81F1 F25E4677 xor ecx,0x77465EF2
00455339 81C1 1A29644A add ecx,0x4A64291A
00455345 33D9 xor ebx,ecx ;更新滚动key
00455347 03E9 add ebp,ecx
004781EB ^\FFE5 jmp ebp ;0x0043BD4C

vPop r3

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
0043BD4C    8B0E            mov ecx,dword ptr ds:[esi]				;读取原始esp
0043BD55 81C6 04000000 add esi,0x4 ;原始esp+0x4, 此处两句指令对应 pop ecx
0043BD5B 0FB607 movzx eax,byte ptr ds:[edi] ;读取opcode的第一个字节
0043BD66 8DBF 01000000 lea edi,dword ptr ds:[edi+0x1] ;跳过读取的字节
0043BD72 32C3 xor al,bl ;解密读取到的字节
0043BD74 04 95 add al,0x95
0043BD7A F6D8 neg al
00479730 FEC0 inc al
00424206 34 28 xor al,0x28
00424208 32D8 xor bl,al ;更新滚动key
0042420C 890C04 mov dword ptr ss:[esp+eax],ecx ;eax=0xC
0042420F 8B0F mov ecx,dword ptr ds:[edi] ;从opcode读取4字节
00424211 8DBF 04000000 lea edi,dword ptr ds:[edi+0x4] ;递增opcode,跳到下一个opcode
00424217 33CB xor ecx,ebx
0043796F C1C9 02 ror ecx,0x2
0041F44A 81F1 7E7F9C09 xor ecx,0x99C7F7E
004104C7 49 dec ecx
004104C8 81F1 F25E4677 xor ecx,0x77465EF2
004104CE 8D89 1A29644A lea ecx,dword ptr ds:[ecx+0x4A64291A]
004104D5 33D9 xor ebx,ecx ;更新滚动key
004104D7 03E9 add ebp,ecx
004536AD 55 push ebp
004536AE C3 retn ;0x0045E179

vPop r5

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
0045E179    8B0E            mov ecx,dword ptr ds:[esi]				;读取原始esp
0045E181 8DB6 04000000 lea esi,dword ptr ds:[esi+0x4] ;原始esp+0x4, 此处两句指令对应 pop ecx
0045E187 0FB607 movzx eax,byte ptr ds:[edi] ;读取opcode的第一个字节
0045E18A 81C7 01000000 add edi,0x1 ;跳过读取的字节
0045E193 32C3 xor al,bl ;解密读取到的字节
0045E197 04 95 add al,0x95
0045E199 F6D8 neg al
0047C824 FEC0 inc al
00459FC2 34 28 xor al,0x28
00459FC8 32D8 xor bl,al ;更新滚动key
00459FCC 890C04 mov dword ptr ss:[esp+eax],ecx ;eax=0x14
00459FCF 8B0F mov ecx,dword ptr ds:[edi] ;从opcode读取4字节
00459FD1 81C7 04000000 add edi,0x4 ;递增opcode,跳到下一个opcode
00459FD7 33CB xor ecx,ebx
00459FD9 C1C9 02 ror ecx,0x2
00459FDC 81F1 7E7F9C09 xor ecx,0x99C7F7E
00459FE2 49 dec ecx
00459FE3 81F1 F25E4677 xor ecx,0x77465EF2
00459FEE 81C1 1A29644A add ecx,0x4A64291A
00459FF4 33D9 xor ebx,ecx
00459FF6 03E9 add ebp,ecx ;更新滚动key
00479CA7 ^\FFE5 jmp ebp ;0x0046D3FB

vPop r9

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
0046D3FB    8B0E            mov ecx,dword ptr ds:[esi]				;读取原始esp
0046D3FD 81C6 04000000 add esi,0x4 ;原始esp+0x4, 此处两句指令对应 pop ecx
0046D403 0FB607 movzx eax,byte ptr ds:[edi] ;读取opcode的第一个字节
0046D407 8DBF 01000000 lea edi,dword ptr ds:[edi+0x1] ;跳过读取的字节
0046D413 32C3 xor al,bl ;解密读取到的字节
0046D415 04 95 add al,0x95
0046D41B F6D8 neg al
004264F7 FEC0 inc al
004264F9 34 28 xor al,0x28
004264FC 32D8 xor bl,al ;更新滚动key
00426500 890C04 mov dword ptr ss:[esp+eax],ecx ;eax=0x24
00426503 8B0F mov ecx,dword ptr ds:[edi] ;从opcode读取4字节
00426508 8DBF 04000000 lea edi,dword ptr ds:[edi+0x4] ;递增opcode,跳到下一个opcode
0042650F 33CB xor ecx,ebx
00426512 C1C9 02 ror ecx,0x2
0047CDC0 81F1 7E7F9C09 xor ecx,0x99C7F7E
00483DE1 49 dec ecx
00483DE8 81F1 F25E4677 xor ecx,0x77465EF2
00483DF9 8D89 1A29644A lea ecx,dword ptr ds:[ecx+0x4A64291A]
00483E02 33D9 xor ebx,ecx ;更新滚动key
00483E0B 03E9 add ebp,ecx
0047FFF9 ^\FFE5 jmp ebp ;0x0046C4CB

vPop r2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
0046C4CB    8B0E            mov ecx,dword ptr ds:[esi]				;读取原始esp
0046C4CD 8DB6 04000000 lea esi,dword ptr ds:[esi+0x4] ;原始esp+0x4, 此处两句指令对应 pop ecx
0046C4D7 0FB607 movzx eax,byte ptr ds:[edi] ;读取opcode的第一个字节
0046C4DD 81C7 01000000 add edi,0x1 ;跳过读取的字节
0046C4E3 32C3 xor al,bl ;解密读取到的字节
0046C4EA 04 95 add al,0x95
00445326 F6D8 neg al
00445328 FEC0 inc al
0044532B 34 28 xor al,0x28
00445332 32D8 xor bl,al ;更新滚动key
00445334 890C04 mov dword ptr ss:[esp+eax],ecx ;eax=0x8
0044533F 8B0F mov ecx,dword ptr ds:[edi] ;从opcode读取4字节
00445346 81C7 04000000 add edi,0x4 ;递增opcode,跳到下一个opcode
0044534C 33CB xor ecx,ebx
0044534E C1C9 02 ror ecx,0x2
00445351 81F1 7E7F9C09 xor ecx,0x99C7F7E
00478CFC 49 dec ecx
00478CFD 81F1 F25E4677 xor ecx,0x77465EF2
0046EDD9 81C1 1A29644A add ecx,0x4A64291A
0046EDE5 33D9 xor ebx,ecx ;更新滚动key
0046EDEA 03E9 add ebp,ecx
0043713E 55 push ebp
0043713F C3 retn ;0x00474E9C

vPop r4

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
00474E9C    8B0E            mov ecx,dword ptr ds:[esi]              ;读取原始esp
00474EA0 81C6 04000000 add esi,0x4 ;原始esp+0x4, 此处两句指令对应 pop ecx
00474EAB 0FB607 movzx eax,byte ptr ds:[edi] ;读取opcode的第一个字节
00474EAE 81C7 01000000 add edi,0x1 ;跳过读取的字节
00474EB6 32C3 xor al,bl ;解密读取到的字节
00445C08 04 95 add al,0x95
00445C0B F6D8 neg al
00483885 FEC0 inc al
00483887 34 28 xor al,0x28
0048388A 32D8 xor bl,al ;更新滚动key
00483890 890C04 mov dword ptr ss:[esp+eax],ecx ;eax=0x10
00483895 8B0F mov ecx,dword ptr ds:[edi] ;从opcode读取4字节
004376C4 8DBF 04000000 lea edi,dword ptr ds:[edi+0x4] ;递增opcode,跳到下一个opcode
004745C8 33CB xor ecx,ebx
0044E82C C1C9 02 ror ecx,0x2
0044E82F 81F1 7E7F9C09 xor ecx,0x99C7F7E
004072B1 49 dec ecx
004072B5 81F1 F25E4677 xor ecx,0x77465EF2
004072BB 81C1 1A29644A add ecx,0x4A64291A
004072C5 33D9 xor ebx,ecx ;更新滚动key
004072C9 03E9 add ebp,ecx
00471DC6 55 push ebp
00471DC7 C3 retn ;0x00476E65

vPop r0

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
00476E65    8B0E            mov ecx,dword ptr ds:[esi]              ;读取原始esp
00476E67 8DB6 04000000 lea esi,dword ptr ds:[esi+0x4] ;原始esp+0x4, 此处两句指令对应 pop ecx
00476E75 0FB607 movzx eax,byte ptr ds:[edi] ;读取opcode的第一个字节
0047D681 81C7 01000000 add edi,0x1 ;跳过读取的字节
0047D687 32C3 xor al,bl ;解密读取到的字节
0047D689 04 95 add al,0x95
0047D694 F6D8 neg al
0047C676 FEC0 inc al
0047C67B 34 28 xor al,0x28
0047C67F 32D8 xor bl,al ;更新滚动key
0047C681 890C04 mov dword ptr ss:[esp+eax],ecx ;eax=0x0
0047C68C 8B0F mov ecx,dword ptr ds:[edi] ;从opcode读取4字节
0047C68E 81C7 04000000 add edi,0x4 ;递增opcode,跳到下一个opcode
0046C29E 33CB xor ecx,ebx
0046C2A1 C1C9 02 ror ecx,0x2
0046C2A8 81F1 7E7F9C09 xor ecx,0x99C7F7E
0044B630 49 dec ecx
0044B631 81F1 F25E4677 xor ecx,0x77465EF2
0044B637 81C1 1A29644A add ecx,0x4A64291A
0044B648 33D9 xor ebx,ecx ;更新滚动key
0044B64D 03E9 add ebp,ecx
00422D63 /FFE5 jmp ebp ;0x00451F05

vPop r15

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
00451F05    8B0E            mov ecx,dword ptr ds:[esi]				;读取原始esp
00451F0A 81C6 04000000 add esi,0x4 ;原始esp+0x4, 此处两句指令对应 pop ecx
00451F15 0FB607 movzx eax,byte ptr ds:[edi] ;读取opcode的第一个字节
00451F18 81C7 01000000 add edi,0x1 ;跳过读取的字节
00451F1E 32C3 xor al,bl ;解密读取到的字节
00451F20 04 95 add al,0x95
00451F25 F6D8 neg al
004718C3 FEC0 inc al
004718C5 34 28 xor al,0x28
004718CA 32D8 xor bl,al ;更新滚动key
004718CC 890C04 mov dword ptr ss:[esp+eax],ecx ;eax=0x3C
004718CF 8B0F mov ecx,dword ptr ds:[edi] ;从opcode读取4字节
004718D1 81C7 04000000 add edi,0x4 ;递增opcode,跳到下一个opcode
004718D7 33CB xor ecx,ebx
004718D9 C1C9 02 ror ecx,0x2
004718DC 81F1 7E7F9C09 xor ecx,0x99C7F7E
004407D7 49 dec ecx
004407D8 81F1 F25E4677 xor ecx,0x77465EF2
004407E3 8D89 1A29644A lea ecx,dword ptr ds:[ecx+0x4A64291A]
004407EE 33D9 xor ebx,ecx ;更新滚动key
004407F0 03E9 add ebp,ecx
004407F2 FFE5 jmp ebp ;0x0045325C

vPush ebp(0x19ff74)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
0045325C    0FB60F          movzx ecx,byte ptr ds:[edi]				;读取opcode的第一个字节
00453267 8DBF 01000000 lea edi,dword ptr ds:[edi+0x1] ;跳过读取的字节
0045326D 32CB xor cl,bl ;解密读取到的字节
0045326F F6D9 neg cl
00453272 80F1 0E xor cl,0xE
00453278 80E9 21 sub cl,0x21
00453282 F6D9 neg cl
0045328E 80F1 E2 xor cl,0xE2
00453296 32D9 xor bl,cl ;更新滚动key
004532A5 8B140C mov edx,dword ptr ss:[esp+ecx] ;从v_esp中读取数据到edx
004532A8 81EE 04000000 sub esi,0x4 ;原始esp-0x4
004532B4 8916 mov dword ptr ds:[esi],edx ;edx=0x0019FF74,把读到的数据存到esp中,此处两句指令对应 push edx
004532BD 8B0F mov ecx,dword ptr ds:[edi] ;从opcode读取4字节
004532C4 8DBF 04000000 lea edi,dword ptr ds:[edi+0x4] ;递增opcode,跳到下一个opcode
0041B011 33CB xor ecx,ebx ;解密读取到的字节
0041B018 81E9 8C1F9123 sub ecx,0x23911F8C
0041B01E D1C9 ror ecx,1
004692ED 49 dec ecx
004692F3 F7D1 not ecx
004692FA 33D9 xor ebx,ecx ;更新滚动key
004692FC 03E9 add ebp,ecx
00462636 8D5424 60 lea edx,dword ptr ss:[esp+0x60] ;edx=v_esp+0x60
0046263A 3BF2 cmp esi,edx ;原始esp与edx比较
00481402 ^\0F87 04A9FCFF ja test1_vm.0044BD0C ;如果原始esp>edx就正常返回,防止原始esp内容覆盖了vm_context
00481408 8BC4 mov eax,esp ;将v_esp传给eax
0048140A B9 40000000 mov ecx,0x40
0048140F 8D5426 80 lea edx,dword ptr ds:[esi-0x80] ;把原始esp上台0x80大小,然后把地址传给edx
00467341 81E2 FCFFFFFF and edx,-0x4
00467347 2BD1 sub edx,ecx
00467349 8BE2 mov esp,edx ;把新的堆栈地址传给v_esp
0046734B 57 push edi
0045A32C 56 push esi
0045A330 9C pushfd
00489ACC 8BF0 mov esi,eax
00489AD2 8BFA mov edi,edx
0045B5BE F3:A4 rep movs byte ptr es:[edi],byte ptr ds:[esi] ;把原来v_esp的内容拷贝到新的v_esp
0045B5C2 9D popfd
0045818E 5E pop esi
00458194 5F pop edi
0044BD0C 55 push ebp
0044BD0D C3 retn ;0x004786D0

vPush esp(0x0019FF2C)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
004786D0    8BC6            mov eax,esi								;原始esp传给eax,当前esp保存的是变量a的地址
004786D8 81EE 04000000 sub esi,0x4 ;原始esp-0x4
004786DE 8906 mov dword ptr ds:[esi],eax ;把eax存到原始esp中,此处两句指令对应 push eax
004786E6 8B0F mov ecx,dword ptr ds:[edi] ;从opcode读取4字节
004786E8 81C7 04000000 add edi,0x4 ;递增opcode,跳到下一个opcode
004786EE 33CB xor ecx,ebx ;解密读取到的字节
0040AA81 49 dec ecx
0040AA82 D1C9 ror ecx,1
0040AA8C F7D9 neg ecx
0040AA95 81C1 0C094E44 add ecx,0x444E090C
0040AA9C 0FC9 bswap ecx
0040AA9F C1C9 02 ror ecx,0x2
0040AAAA 33D9 xor ebx,ecx ;更新滚动key
0040AAAC 03E9 add ebp,ecx
00462636 8D5424 60 lea edx,dword ptr ss:[esp+0x60] ;edx=v_esp+0x60
0046263A 3BF2 cmp esi,edx ;原始esp与edx比较
00481402 ^\0F87 04A9FCFF ja test1_vm.0044BD0C ;如果原始esp>edx就正常返回,防止原始esp内容覆盖了vm_context
00481408 8BC4 mov eax,esp
0048140A B9 40000000 mov ecx,0x40
0048140F 8D5426 80 lea edx,dword ptr ds:[esi-0x80] ;把原始esp上台0x80大小,然后把地址传给edx
00467341 81E2 FCFFFFFF and edx,-0x4
00467347 2BD1 sub edx,ecx
00467349 8BE2 mov esp,edx ;把新的堆栈地址传给v_esp
0046734B 57 push edi
0045A32C 56 push esi
0045A330 9C pushfd
00489ACC 8BF0 mov esi,eax
00489AD2 8BFA mov edi,edx
0045B5BE F3:A4 rep movs byte ptr es:[edi],byte ptr ds:[esi] ;把原来v_esp的内容拷贝到新的v_esp
0045B5C2 9D popfd
0045818E 5E pop esi
00458194 5F pop edi
0044BD0C 55 push ebp
0044BD0D C3 retn ;0x004343B9

vPop ebp(0x19FF2C)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
004343B9    8B0E            mov ecx,dword ptr ds:[esi]				;读取原始esp,ecx=保存了变量a的地址
004343BE 81C6 04000000 add esi,0x4 ;原始esp+0x4, 此处两句指令对应 pop ecx
004343C4 0FB607 movzx eax,byte ptr ds:[edi] ;读取opcode的第一个字节
004343C7 81C7 01000000 add edi,0x1 ;跳过读取的字节
004343CD 32C3 xor al,bl ;解密读取到的字节
004343CF 04 95 add al,0x95
004343D1 F6D8 neg al
0040ACDA FEC0 inc al
0040ACDE 34 28 xor al,0x28
0040ACEB 32D8 xor bl,al ;更新滚动key
0040ACEF 890C04 mov dword ptr ss:[esp+eax],ecx ;ecx=0x0019FF2C
0040ACF5 8B0F mov ecx,dword ptr ds:[edi] ;从opcode读取4字节
0040ACF8 81C7 04000000 add edi,0x4 ;递增opcode,跳到下一个opcode
0040AD03 33CB xor ecx,ebx
0047679A C1C9 02 ror ecx,0x2
0047679D 81F1 7E7F9C09 xor ecx,0x99C7F7E
00448CC5 49 dec ecx
00448CC6 81F1 F25E4677 xor ecx,0x77465EF2
00448CCD 8D89 1A29644A lea ecx,dword ptr ds:[ecx+0x4A64291A]
00448CD3 33D9 xor ebx,ecx ;更新滚动key
00448CDA 03E9 add ebp,ecx
00449A6E 55 push ebp
00449A6F C3 retn ;0x0045225C

vPush ecx(0x0)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
0045225C    0FB60F          movzx ecx,byte ptr ds:[edi]				;读取opcode的第一个字节                                                 ; test1_vm.0043D0C3
00452265 8DBF 01000000 lea edi,dword ptr ds:[edi+0x1] ;跳过读取的字节
0045226B 32CB xor cl,bl ;解密读取到的字节
0045226D F6D9 neg cl
00452273 80F1 0E xor cl,0xE
0045227D 80E9 21 sub cl,0x21
0045228B F6D9 neg cl
0045228D 80F1 E2 xor cl,0xE2
00452292 32D9 xor bl,cl ;更新滚动key
00452297 8B140C mov edx,dword ptr ss:[esp+ecx] ;从vm_stack读取数据
0045229A 81EE 04000000 sub esi,0x4
004522AE 8916 mov dword ptr ds:[esi],edx ;push edx
004522B0 8B0F mov ecx,dword ptr ds:[edi] ;从opcode读取4字节
004522B3 8DBF 04000000 lea edi,dword ptr ds:[edi+0x4] ;递增opcode,跳到下一个opcode
004522BE 33CB xor ecx,ebx
0045676E 81E9 8C1F9123 sub ecx,0x23911F8C
00456776 D1C9 ror ecx,1
00463F87 49 dec ecx
00463F8C F7D1 not ecx
0041EFFB 33D9 xor ebx,ecx ;更新滚动key
0041F001 03E9 add ebp,ecx
00462636 8D5424 60 lea edx,dword ptr ss:[esp+0x60]
00445778 3BF2 cmp esi,edx ;检查堆栈
00481402 ^\0F87 04A9FCFF ja test1_vm.0044BD0C
00481408 8BC4 mov eax,esp
0048140A B9 40000000 mov ecx,0x40
0048140F 8D5426 80 lea edx,dword ptr ds:[esi-0x80]
00467341 81E2 FCFFFFFF and edx,-0x4
00467347 2BD1 sub edx,ecx
00467349 8BE2 mov esp,edx
0046734B 57 push edi ; test1_vm.0043D0C3
0045A32C 56 push esi
0045A330 9C pushfd
00489ACC 8BF0 mov esi,eax ; test1_vm.0043D0C3
00489AD2 8BFA mov edi,edx
0045B5BE F3:A4 rep movs byte ptr es:[edi],byte ptr ds:[esi]
0045B5C2 9D popfd
0045818E 5E pop esi ; 0019FF2C ; test1_vm.0043D0C3
00458194 5F pop edi ; 0019FF2C
0044BD0C 55 push ebp ; test1_vm.0045225C
0044BD0D C3 retn ;0047E64B

vPush esp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
0047E64B    0FB60F          movzx ecx,byte ptr ds:[edi]				;读取opcode的第一个字节
0047E65A 81C7 01000000 add edi,0x1 ;跳过读取的字节
0047E661 32CB xor cl,bl ;解密读取到的字节
0047E663 F6D9 neg cl
0047E66B 80F1 0E xor cl,0xE
0047E670 80E9 21 sub cl,0x21
0047E673 80C2 96 add dl,0x96
0047E681 F6D9 neg cl
0047E683 80F1 E2 xor cl,0xE2
0047E686 32D9 xor bl,cl ;更新滚动key
0047E68E 8B140C mov edx,dword ptr ss:[esp+ecx]
0047E697 81EE 04000000 sub esi,0x4
0047E6A2 8916 mov dword ptr ds:[esi],edx ;push edx
0047E6AC 8B0F mov ecx,dword ptr ds:[edi] ;从opcode读取4字节
0047E6B4 81C7 04000000 add edi,0x4 ;递增opcode,跳到下一个opcode
0047E6BF 33CB xor ecx,ebx
0047E6C8 81E9 8C1F9123 sub ecx,0x23911F8C
0047E6CF D1C9 ror ecx,1
0044CE2D 49 dec ecx
0044CE2E F7D1 not ecx
0044CE30 33D9 xor ebx,ecx ;更新滚动key
0044CE33 03E9 add ebp,ecx
00462636 8D5424 60 lea edx,dword ptr ss:[esp+0x60]
0046263A 3BF2 cmp esi,edx ;堆栈检查
00481402 ^\0F87 04A9FCFF ja test1_vm.0044BD0C
00481408 8BC4 mov eax,esp
0048140A B9 40000000 mov ecx,0x40
0048140F 8D5426 80 lea edx,dword ptr ds:[esi-0x80]
00467341 81E2 FCFFFFFF and edx,-0x4
00467347 2BD1 sub edx,ecx
00467349 8BE2 mov esp,edx
0046734B 57 push edi
0045A32C 56 push esi
0045A330 9C pushfd
00489ACC 8BF0 mov esi,eax
00489AD2 8BFA mov edi,edx
0045B5BE F3:A4 rep movs byte ptr es:[edi],byte ptr ds:[esi]
0045B5C2 9D popfd
0045818E 5E pop esi
00458194 5F pop edi
0044BD0C 55 push ebp
0044BD0D C3 retn ;0x00454C04

vPush 1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
00454C04    8B0F            mov ecx,dword ptr ds:[edi]				;从opcode读取4字节
004131C1 81C7 04000000 add edi,0x4 ;递增opcode,跳到下一个opcode
004131C7 33CB xor ecx,ebx ;解密读取到的字节
004131C9 41 inc ecx
004503B4 F7D9 neg ecx
00455A33 41 inc ecx
00455A34 81F1 66772375 xor ecx,0x75237766
00455A3B 33D9 xor ebx,ecx
00455A40 81EE 04000000 sub esi,0x4
00447C2B 890E mov dword ptr ds:[esi],ecx ;push ecx
00447C35 8B0F mov ecx,dword ptr ds:[edi] ;从opcode读取4字节
00447C37 8DBF 04000000 lea edi,dword ptr ds:[edi+0x4] ;递增opcode,跳到下一个opcode
00447C41 33CB xor ecx,ebx ;解密读取到的字节
00447C49 F7D9 neg ecx
0041448F 8D89 6233DE7C lea ecx,dword ptr ds:[ecx+0x7CDE3362]
00414495 F7D9 neg ecx
00414497 F7D1 not ecx
00414499 33D9 xor ebx,ecx
0041449B 03E9 add ebp,ecx
00462636 8D5424 60 lea edx,dword ptr ss:[esp+0x60]
0046263A 3BF2 cmp esi,edx ;堆栈检查
00481402 ^\0F87 04A9FCFF ja test1_vm.0044BD0C
00481408 8BC4 mov eax,esp
0048140A B9 40000000 mov ecx,0x40
0048140F 8D5426 80 lea edx,dword ptr ds:[esi-0x80]
00467341 81E2 FCFFFFFF and edx,-0x4
00467347 2BD1 sub edx,ecx
00467349 8BE2 mov esp,edx
0046734B 57 push edi
0045A32C 56 push esi
0045A330 9C pushfd
00489ACC 8BF0 mov esi,eax
00489AD2 8BFA mov edi,edx
0045B5BE F3:A4 rep movs byte ptr es:[edi],byte ptr ds:[esi]
0045B5C2 9D popfd
0045818E 5E pop esi
00458194 5F pop edi
0044BD0C 55 push ebp
0044BD0D C3 retn ;0041043E

vPush ebp(0x0019FF2C)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
0041043E    0FB60F          movzx ecx,byte ptr ds:[edi]				;读取opcode的第一个字节
00410443 8DBF 01000000 lea edi,dword ptr ds:[edi+0x1] ;跳过读取的字节
0041044E 32CB xor cl,bl ;解密读取到的字节
00410450 F6D9 neg cl
00410452 80F1 0E xor cl,0xE
00410460 80E9 21 sub cl,0x21
0041046B F6D9 neg cl
0041046D D2D2 rcl dl,cl
0041046F F6DE neg dh
00410471 80F1 E2 xor cl,0xE2
00410479 32D9 xor bl,cl ;更新滚动key
0041047D 8B140C mov edx,dword ptr ss:[esp+ecx]
00410480 81EE 04000000 sub esi,0x4
00410489 8916 mov dword ptr ds:[esi],edx ;push edx
00410497 8B0F mov ecx,dword ptr ds:[edi] ;从opcode读取4字节
0041049E 8DBF 04000000 lea edi,dword ptr ds:[edi+0x4] ;递增opcode,跳到下一个opcode
004104A4 33CB xor ecx,ebx
004104A8 81E9 8C1F9123 sub ecx,0x23911F8C
004104B1 D1C9 ror ecx,1
004104B3 49 dec ecx
00440D59 F7D1 not ecx
00440D5C 33D9 xor ebx,ecx
004251B5 03E9 add ebp,ecx
00462636 8D5424 60 lea edx,dword ptr ss:[esp+0x60]
0046263A 3BF2 cmp esi,edx ;堆栈检查
00481402 ^\0F87 04A9FCFF ja test1_vm.0044BD0C
00481408 8BC4 mov eax,esp
0048140A B9 40000000 mov ecx,0x40
0048140F 8D5426 80 lea edx,dword ptr ds:[esi-0x80]
00467341 81E2 FCFFFFFF and edx,-0x4
00467347 2BD1 sub edx,ecx
00467349 8BE2 mov esp,edx
0046734B 57 push edi
0045A32C 56 push esi
0045A330 9C pushfd
00489ACC 8BF0 mov esi,eax
00489AD2 8BFA mov edi,edx
0045B5BE F3:A4 rep movs byte ptr es:[edi],byte ptr ds:[esi]
0045B5C2 9D popfd
0045818E 5E pop esi
00458194 5F pop edi
0044BD0C 55 push ebp
0044BD0D C3 retn ;0043E97B

vPush -4(0xFFFFFFFC)

变量a地址相对于ebp的相对偏移

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
0043E97B    8B0F            mov ecx,dword ptr ds:[edi]				;从opcode读取4字节
0044140D 81C7 04000000 add edi,0x4 ;递增opcode,跳到下一个opcode
00441418 33CB xor ecx,ebx
0047D18C 41 inc ecx
0047D18D F7D9 neg ecx
00450AE0 41 inc ecx
00450AE1 81F1 66772375 xor ecx,0x75237766
00450AE7 33D9 xor ebx,ecx ;更新滚动key
00450AEA 8DB6 FCFFFFFF lea esi,dword ptr ds:[esi-0x4]
00450AF2 890E mov dword ptr ds:[esi],ecx ;push ecx
00450AF8 8B0F mov ecx,dword ptr ds:[edi]
00450AFA 81C7 04000000 add edi,0x4
00450B07 33CB xor ecx,ebx
00450B0C F7D9 neg ecx
00450B0E 8D89 6233DE7C lea ecx,dword ptr ds:[ecx+0x7CDE3362]
00450B17 F7D9 neg ecx
00450B19 F7D1 not ecx
00450B1B 33D9 xor ebx,ecx
00450B1E 03E9 add ebp,ecx
00462636 8D5424 60 lea edx,dword ptr ss:[esp+0x60]
0046263A 3BF2 cmp esi,edx
00481402 ^\0F87 04A9FCFF ja test1_vm.0044BD0C
00481408 8BC4 mov eax,esp
0048140A B9 40000000 mov ecx,0x40
0048140F 8D5426 80 lea edx,dword ptr ds:[esi-0x80]
00467341 81E2 FCFFFFFF and edx,-0x4
00467347 2BD1 sub edx,ecx
00467349 8BE2 mov esp,edx
0046734B 57 push edi
0045A32C 56 push esi
0045A32D 0FB7F2 movzx esi,dx
0045A330 9C pushfd
00489ACC 8BF0 mov esi,eax
00489AD2 8BFA mov edi,edx
0045B5BE F3:A4 rep movs byte ptr es:[edi],byte ptr ds:[esi]
0045B5C0 0BFB or edi,ebx
0045B5C2 9D popfd
0045818E 5E pop esi
00458194 5F pop edi
0044BD0C 55 push ebp
0044BD0D C3 retn ;0040423D
1
2
3
4
mov eax,dword ptr ds:[v_esp]	;变量a地址相对于ebp的相对偏移
mov edx,dword ptr ds:[v_esp+0x4]
add eax,edx
mov dword ptr ds:[v_esp+0x4],eax

计算变量a的地址,ebp-4

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
0040423D    8B06            mov eax,dword ptr ds:[esi]			;从原始esp读取变量a地址相对于edx的偏移
00404243 8B56 04 mov edx,dword ptr ds:[esi+0x4] ;从原始esp+4 读取ebp
00404248 03C2 add eax,edx ;相加后eax为变量a地址
0044AFE5 8946 04 mov dword ptr ds:[esi+0x4],eax ;eax压入原始esp+4 位置
0044AFED 9C pushfd
0044AFEE 8F06 pop dword ptr ds:[esi]
0044AFF7 8B0F mov ecx,dword ptr ds:[edi]
0044AFF9 81C7 04000000 add edi,0x4
0044B000 33CB xor ecx,ebx
004056EF C1C9 03 ror ecx,0x3
004056F6 F7D1 not ecx
004056F8 81C1 C448053F add ecx,0x3F0548C4
00405701 81F1 2A55B526 xor ecx,0x26B5552A
00405707 81E9 864A0664 sub ecx,0x64064A86
00405710 33D9 xor ebx,ecx
00405718 03E9 add ebp,ecx
0040571A 55 push ebp
0040571B C3 retn ;0046FF2C

vPop r12

将偏移弹到R12

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
0046FF2C    8B0E            mov ecx,dword ptr ds:[esi]			;从原始esp读取变量a地址相对于edx的偏移
0046FF2E 8DB6 04000000 lea esi,dword ptr ds:[esi+0x4] ;原地esp+4,pop ecx
0046FF37 0FB607 movzx eax,byte ptr ds:[edi] ;读取opcode的第一个字节
0046FF3A 8DBF 01000000 lea edi,dword ptr ds:[edi+0x1] ;跳过读取的字节
0046FF48 32C3 xor al,bl ;解密读取到的字节
0046FF53 04 95 add al,0x95
00446B15 F6D8 neg al
00454B5C FEC0 inc al
00454B61 34 28 xor al,0x28
00454B64 32D8 xor bl,al
00454B66 890C04 mov dword ptr ss:[esp+eax],ecx ;出栈
00454B6C 8B0F mov ecx,dword ptr ds:[edi]
00454B72 8DBF 04000000 lea edi,dword ptr ds:[edi+0x4]
00454B7A 33CB xor ecx,ebx
00454B7C C1C9 02 ror ecx,0x2
00454B7F 81F1 7E7F9C09 xor ecx,0x99C7F7E
00422059 49 dec ecx
0042205D 81F1 F25E4677 xor ecx,0x77465EF2
00422065 8D89 1A29644A lea ecx,dword ptr ds:[ecx+0x4A64291A]
0042206B 33D9 xor ebx,ecx
0042206D 03E9 add ebp,ecx
00409147 /FFE5 jmp ebp ;0041D673
1
2
3
mov 	eax,dword ptr ds:[v_esp]	;变量a地址
mov edx,dword ptr ds:[v_esp+0x4] ;之前vPush进来的1
mov dword ptr ds:[eax],edx ;mov dword ptr [ebp-4],1

mov dword ptr [ebp-4],1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
0041D673    8B06            mov eax,dword ptr ds:[esi]			;变量a的地址
0041D67D 8B56 04 mov edx,dword ptr ds:[esi+0x4] ;之前vPush进来的1
0041D688 8DB6 08000000 lea esi,dword ptr ds:[esi+0x8] ;出栈
0046C3DB 36:8910 mov dword ptr ss:[eax],edx ;给变量a赋值,a=1
0046C3DE 8B07 mov eax,dword ptr ds:[edi]
0046C3E0 81C7 04000000 add edi,0x4
0046C3E6 33C3 xor eax,ebx
0041CA25 F7D0 not eax
0041CA28 8D80 39CAABFE lea eax,dword ptr ds:[eax-0x15435C7]
0041CA31 35 CE111A71 xor eax,0x711A11CE
0041CA3B 8D80 03AE9DB8 lea eax,dword ptr ds:[eax-0x476251FD]
0041CA42 33D8 xor ebx,eax
0041CA45 03E8 add ebp,eax
00483D3B ^\FFE5 jmp ebp ;0045BC24

vPush -4(0xFFFFFFFC)

变量a地址相对于ebp的相对偏移

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
0045BC24    8B0F            mov ecx,dword ptr ds:[edi]						;从opcode读取4字节
0045BC2C 81C7 04000000 add edi,0x4 ;递增opcode,跳到下一个opcode
0045BC33 33CB xor ecx,ebx
0046BEC4 41 inc ecx
00431C1F F7D9 neg ecx
00474669 41 inc ecx
00474672 81F1 66772375 xor ecx,0x75237766
00474678 33D9 xor ebx,ecx ;更新滚动key
0047467C 81EE 04000000 sub esi,0x4
00474684 890E mov dword ptr ds:[esi],ecx ;push ecx
0047468B 8B0F mov ecx,dword ptr ds:[edi]
0047468D 8DBF 04000000 lea edi,dword ptr ds:[edi+0x4]
00474695 33CB xor ecx,ebx
00474697 F7D9 neg ecx
00474699 81C1 6233DE7C add ecx,0x7CDE3362
0047469F F7D9 neg ecx
0043D8C9 F7D1 not ecx
0043D8CB 33D9 xor ebx,ecx
00488CC8 03E9 add ebp,ecx
00462636 8D5424 60 lea edx,dword ptr ss:[esp+0x60]
0046263A 3BF2 cmp esi,edx ;堆栈检查
00481402 ^\0F87 04A9FCFF ja test1_vm.0044BD0C
00481408 8BC4 mov eax,esp
0048140A B9 40000000 mov ecx,0x40
0048140F 8D5426 80 lea edx,dword ptr ds:[esi-0x80]
00467341 81E2 FCFFFFFF and edx,-0x4
00467347 2BD1 sub edx,ecx
00467349 8BE2 mov esp,edx
0046734B 57 push edi
0045A32C 56 push esi
0045A330 9C pushfd
00489ACC 8BF0 mov esi,eax
00489AD2 8BFA mov edi,edx
0045B5BE F3:A4 rep movs byte ptr es:[edi],byte ptr ds:[esi]
0045B5C2 9D popfd
0045818E 5E pop esi
00458194 5F pop edi
0044BD0C 55 push ebp
0044BD0D C3 retn ;00435011
1
2
3
4
mov	eax,dword ptr ds:[v_esp]	;变量a地址相对于ebp的相对偏移
mov edx,dword ptr ds:[v_esp+0x4]
add eax,edx
mov dword ptr ds:[v_esp+0x4],eax

计算变量a的地址,ebp-4

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
00435011    8B06            mov eax,dword ptr ds:[esi]				;从原始esp获取变量a地址相对于ebp的相对偏移
0043501B 8B56 04 mov edx,dword ptr ds:[esi+0x4] ;从原始esp+4,获取ebp
00435023 03C2 add eax,edx ;相加得到变量a的地址
00435028 8946 04 mov dword ptr ds:[esi+0x4],eax ;入栈
00435034 9C pushfd
0043503B 8F06 pop dword ptr ds:[esi] ;保存ELF到vm_stack栈顶
00435043 8B0F mov ecx,dword ptr ds:[edi]
00435047 8DBF 04000000 lea edi,dword ptr ds:[edi+0x4]
00435055 33CB xor ecx,ebx
00435057 C1C9 03 ror ecx,0x3
0043505A F7D1 not ecx
0043505D 81C1 C448053F add ecx,0x3F0548C4
00435065 81F1 2A55B526 xor ecx,0x26B5552A
00435070 8D89 7AB5F99B lea ecx,dword ptr ds:[ecx-0x64064A86]
0043507D 33D9 xor ebx,ecx
00435082 03E9 add ebp,ecx
0046DD9A ^\FFE5 jmp ebp ;0x00453841

vPop r11

将偏移弹出

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
00453841    8B0E            mov ecx,dword ptr ds:[esi]				;从原始esp读取数据
00453846 81C6 04000000 add esi,0x4
00453854 0FB607 movzx eax,byte ptr ds:[edi] ;读取opcode的第一个字节
00453857 81C7 01000000 add edi,0x1 ;跳过读取的字节
00453866 32C3 xor al,bl ;解密读取到的字节
0045386E 04 95 add al,0x95
00453870 F6D8 neg al
00458E65 FEC0 inc al
00458E6B 34 28 xor al,0x28
00458E6D 32D8 xor bl,al
00458E6F 890C04 mov dword ptr ss:[esp+eax],ecx
00458E7C 8B0F mov ecx,dword ptr ds:[edi]
00479B0C 81C7 04000000 add edi,0x4
0041B623 33CB xor ecx,ebx ; test1_vm.00439ED8
00470224 C1C9 02 ror ecx,0x2
00470227 81F1 7E7F9C09 xor ecx,0x99C7F7E
004452FB 49 dec ecx
004452FC 81F1 F25E4677 xor ecx,0x77465EF2
00445305 81C1 1A29644A add ecx,0x4A64291A
0044530B 33D9 xor ebx,ecx
0044530D 03E9 add ebp,ecx
0043AD66 55 push ebp ; test1_vm.00453841
0043AD67 C3 retn ;00463862
1
2
3
mov	edx,dword ptr ds:[esi]
mov eax,dword ptr ss:[edx]
mov dword ptr ds:[v_esp],eax ;将变量a的值覆盖到esp

把变量a的值存放栈顶

1
2
3
4
5
6
7
8
9
10
11
12
13
14
00463862    8B16            mov edx,dword ptr ds:[esi]			;从原始esp读取变量a的地址
0046386C 36:8B02 mov eax,dword ptr ss:[edx] ;读取变量a的内容
0046C75B 8906 mov dword ptr ds:[esi],eax ;把内容覆盖到变量a的地址
0046C762 8B07 mov eax,dword ptr ds:[edi] ;从opcode读取4字节
00481FFA 8DBF 04000000 lea edi,dword ptr ds:[edi+0x4]
00482003 33C3 xor eax,ebx
0048200B 05 84307C17 add eax,0x177C3084
00444EE2 0FC8 bswap eax
00444EE4 40 inc eax
00444EE7 F7D0 not eax
00444EE9 33D8 xor ebx,eax
00444EEB 03E8 add ebp,eax
00442693 55 push ebp
00442694 C3 retn ;00430521
1
2
将变量a的值弹到寄存器R15中,联合上面几句等价于
mov eax,dword ptr [ebp-4]

vPop r15

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
00430521    8B0E            mov ecx,dword ptr ds:[esi]			;取出变量a的值
00430523 81C6 04000000 add esi,0x4
00430529 0FB607 movzx eax,byte ptr ds:[edi]
004552EE 81C7 01000000 add edi,0x1
004552F4 32C3 xor al,bl
004552F9 04 95 add al,0x95
004552FB F6D8 neg al
004552FD FEC0 inc al
00455303 34 28 xor al,0x28
00455309 32D8 xor bl,al
0045530C 890C04 mov dword ptr ss:[esp+eax],ecx
00455311 8B0F mov ecx,dword ptr ds:[edi]
00455313 81C7 04000000 add edi,0x4
0045531F 33CB xor ecx,ebx
00455324 C1C9 02 ror ecx,0x2
0045532B 81F1 7E7F9C09 xor ecx,0x99C7F7E
00455331 49 dec ecx
00455332 81F1 F25E4677 xor ecx,0x77465EF2
00455339 81C1 1A29644A add ecx,0x4A64291A
00455345 33D9 xor ebx,ecx
00455347 03E9 add ebp,ecx
004781EB ^\FFE5 jmp ebp ;004693CB

vPush 1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
004693CB    8B0F            mov ecx,dword ptr ds:[edi]					;获取1
004693D3 8DBF 04000000 lea edi,dword ptr ds:[edi+0x4]
0046E6FE 33CB xor ecx,ebx
00443D5F 41 inc ecx
00443D61 F7D9 neg ecx
004141FF 41 inc ecx
00414206 81F1 66772375 xor ecx,0x75237766
0041420C 33D9 xor ebx,ecx
0041420E 81EE 04000000 sub esi,0x4
00414214 890E mov dword ptr ds:[esi],ecx ;push
00414221 8B0F mov ecx,dword ptr ds:[edi]
0047C17B 81C7 04000000 add edi,0x4
0047C181 33CB xor ecx,ebx
0042DAB1 F7D9 neg ecx
0042DABC 81C1 6233DE7C add ecx,0x7CDE3362
0042DAC4 F7D9 neg ecx
0042DAC8 F7D1 not ecx
0042DACB 33D9 xor ebx,ecx
0042DACD 03E9 add ebp,ecx
00462636 8D5424 60 lea edx,dword ptr ss:[esp+0x60]
0046263A 3BF2 cmp esi,edx
00481402 ^\0F87 04A9FCFF ja test1_vm.0044BD0C
00481408 8BC4 mov eax,esp
0048140A B9 40000000 mov ecx,0x40
0048140F 8D5426 80 lea edx,dword ptr ds:[esi-0x80]
00467341 81E2 FCFFFFFF and edx,-0x4
00467347 2BD1 sub edx,ecx
00467349 8BE2 mov esp,edx
0046734B 57 push edi
0045A32C 56 push esi
0045A32D 0FB7F2 movzx esi,dx
0045A330 9C pushfd
00489ACC 8BF0 mov esi,eax
00489AD2 8BFA mov edi,edx
0045B5BE F3:A4 rep movs byte ptr es:[edi],byte ptr ds:[esi]
0045B5C2 9D popfd
0045818E 5E pop esi
00458194 5F pop edi
0044BD0C 55 push ebp
0044BD0D C3 retn ;0x00421D3D

取出R15寄存器的值,然后压栈

vPush 15

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
00421D3D    0FB60F          movzx ecx,byte ptr ds:[edi]				;opcode获取一字节
00421D43 8DBF 01000000 lea edi,dword ptr ds:[edi+0x1]
00421D49 32CB xor cl,bl
00421D55 F6D9 neg cl
00421D5B 80F1 0E xor cl,0xE
00421D64 80E9 21 sub cl,0x21
00421D6D F6D9 neg cl
00421D72 80F1 E2 xor cl,0xE2
00421D78 32D9 xor bl,cl
00421D81 8B140C mov edx,dword ptr ss:[esp+ecx] ;获取R15寄存器的值
00421D87 8DB6 FCFFFFFF lea esi,dword ptr ds:[esi-0x4]
00421D95 8916 mov dword ptr ds:[esi],edx push edx
00421D9D 8B0F mov ecx,dword ptr ds:[edi]
00455281 8DBF 04000000 lea edi,dword ptr ds:[edi+0x4]
00455289 33CB xor ecx,ebx
0045528E 81E9 8C1F9123 sub ecx,0x23911F8C
00455294 D1C9 ror ecx,1
0043425D 49 dec ecx
00434263 F7D1 not ecx
00434267 33D9 xor ebx,ecx
00434269 81FC 1B356876 cmp esp,0x7668351B
0043426F 03E9 add ebp,ecx
00462636 8D5424 60 lea edx,dword ptr ss:[esp+0x60]
0046263A 3BF2 cmp esi,edx
00481402 ^\0F87 04A9FCFF ja test1_vm.0044BD0C
00481408 8BC4 mov eax,esp
0048140A B9 40000000 mov ecx,0x40
0048140F 8D5426 80 lea edx,dword ptr ds:[esi-0x80]
00467341 81E2 FCFFFFFF and edx,-0x4
00467347 2BD1 sub edx,ecx
00467349 8BE2 mov esp,edx
0046734B 57 push edi ; test1_vm.0043D111
0045A32C 56 push esi
0045A330 9C pushfd
00489ACC 8BF0 mov esi,eax
00489AD2 8BFA mov edi,edx
0045B5BE F3:A4 rep movs byte ptr es:[edi],byte ptr ds:[esi]
0045B5C2 9D popfd
0045818E 5E pop esi
00458194 5F pop edi
0044BD0C 55 push ebp
0044BD0D C3 retn ;0x004616C3
1
2
vAdd	dword ptr ds:[v_esp+0x4],R15	;add         eax,1 
mov dword ptr ds:[v_esp],EFL

vAdd dword ptr ds:[v_esp+0x4],R15

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
004616C3    8B06             mov eax,dword ptr ds:[esi]					;读取R15
004616CC 8B56 04 mov edx,dword ptr ds:[esi+0x4] ;读取数值1
004616D6 03C2 add eax,edx ;相加
004616E0 8946 04 mov dword ptr ds:[esi+0x4],eax ;将结果压入原始esp+4
004616E6 9C pushfd
004616E8 8F06 pop dword ptr ds:[esi] ;然后将efl写入到原始esp
004616F1 8B0F mov ecx,dword ptr ds:[edi]
00428439 81C7 04000000 add edi,0x4
00428446 33CB xor ecx,ebx
00428448 C1C9 03 ror ecx,0x3
004810BD F7D1 not ecx
004810BF 8D89 C448053F lea ecx,dword ptr ds:[ecx+0x3F0548C4]
004810C5 81F1 2A55B526 xor ecx,0x26B5552A
004810D0 8D89 7AB5F99B lea ecx,dword ptr ds:[ecx-0x64064A86]
004810D6 33D9 xor ebx,ecx
004810E0 03E9 add ebp,ecx
0040F74A /FFE5 jmp ebp ;0x0043BD4C

把保存的EFL弹到R7

vPop r7

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
0043BD4C    8B0E             mov ecx,dword ptr ds:[esi]				;从v_stack栈顶取出保存的efl
0043BD5B 0FB607 movzx eax,byte ptr ds:[edi] ;读取一字节的opcode
0043BD66 8DBF 01000000 lea edi,dword ptr ds:[edi+0x1]
0043BD72 32C3 xor al,bl
0043BD74 04 95 add al,0x95
0043BD7A F6D8 neg al
00479730 FEC0 inc al
00424206 34 28 xor al,0x28
00424208 32D8 xor bl,al
0042420C 890C04 mov dword ptr ss:[esp+eax],ecx ;push ecx
0042420F 8B0F mov ecx,dword ptr ds:[edi]
00424211 8DBF 04000000 lea edi,dword ptr ds:[edi+0x4]
00424217 33CB xor ecx,ebx
0043796F C1C9 02 ror ecx,0x2
0041F44A 81F1 7E7F9C09 xor ecx,0x99C7F7E
004104C7 49 dec ecx
004104C8 81F1 F25E4677 xor ecx,0x77465EF2
004104CE 8D89 1A29644A lea ecx,dword ptr ds:[ecx+0x4A64291A]
004104D5 33D9 xor ebx,ecx
004104D7 03E9 add ebp,ecx
004536AD 55 push ebp
004536AE C3 retn ;0x0045E179

vPop r4

把上面vAdd的结果弹到R4

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
0045E179    8B0E             mov ecx,dword ptr ds:[esi]				;从v_stack栈顶取出保存的efl
0045E181 8DB6 04000000 lea esi,dword ptr ds:[esi+0x4]
0045E187 0FB607 movzx eax,byte ptr ds:[edi] ;读取一字节的opcode
0045E18A 81C7 01000000 add edi,0x1
0045E193 32C3 xor al,bl
0045E197 04 95 add al,0x95
0045E199 F6D8 neg al
0047C824 FEC0 inc al
00459FC2 34 28 xor al,0x28
00459FC8 32D8 xor bl,al
00459FCC 890C04 mov dword ptr ss:[esp+eax],ecx ;pop
00459FCF 8B0F mov ecx,dword ptr ds:[edi]
00459FD1 81C7 04000000 add edi,0x4
00459FD7 33CB xor ecx,ebx
00459FD9 C1C9 02 ror ecx,0x2
00459FDC 81F1 7E7F9C09 xor ecx,0x99C7F7E
00459FE2 49 dec ecx
00459FE3 81F1 F25E4677 xor ecx,0x77465EF2
00459FEE 81C1 1A29644A add ecx,0x4A64291A
00459FF4 33D9 xor ebx,ecx
00459FF6 03E9 add ebp,ecx
00479CA7 ^\FFE5 jmp ebp ;0x0040EB2E

vPush r4

R4入栈

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
0040EB2E    0FB60F           movzx ecx,byte ptr ds:[edi]		;读取一字节的opcode
0040EB37 8DBF 01000000 lea edi,dword ptr ds:[edi+0x1]
0040EB40 32CB xor cl,bl
0040EB4F F6D9 neg cl
0040EB51 80F1 0E xor cl,0xE
0040EB5B 80E9 21 sub cl,0x21
0040EB68 F6D9 neg cl
0040EB6E 80F1 E2 xor cl,0xE2
0040EB76 32D9 xor bl,cl
00440ED1 8B140C mov edx,dword ptr ss:[esp+ecx] ;
00440ED8 81EE 04000000 sub esi,0x4
00440EDE 8916 mov dword ptr ds:[esi],edx ;
00440EE0 8B0F mov ecx,dword ptr ds:[edi]
0041D911 81C7 04000000 add edi,0x4
0041D91A 33CB xor ecx,ebx
0042EDBF 81E9 8C1F9123 sub ecx,0x23911F8C
0042AD19 D1C9 ror ecx,1
0042AD1B 49 dec ecx
0042AD1C F7D1 not ecx
0042AD1E 33D9 xor ebx,ecx
004526DB 03E9 add ebp,ecx
00462636 8D5424 60 lea edx,dword ptr ss:[esp+0x60]
0046263A 3BF2 cmp esi,edx
00481402 ^\0F87 04A9FCFF ja test1_vm.0044BD0C
00481408 8BC4 mov eax,esp
0048140A B9 40000000 mov ecx,0x40
0048140F 8D5426 80 lea edx,dword ptr ds:[esi-0x80]
00467341 81E2 FCFFFFFF and edx,-0x4
00467347 2BD1 sub edx,ecx
00467349 8BE2 mov esp,edx
0046734B 57 push edi
0045A32C 56 push esi
0045A330 9C pushfd
00489ACC 8BF0 mov esi,eax
00489AD2 8BFA mov edi,edx
0045B5BE F3:A4 rep movs byte ptr es:[edi],byte ptr ds:[esi] ; test1_vm.00412728
0045B5C2 9D popfd
0045818E 5E pop esi ; test1_vm.0043D124
00458194 5F pop edi
0044BD0C 55 push ebp
0044BD0D C3 retn ;0x004184B3

vPush R0(0x0019FF2C)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
004184B3    0FB60F           movzx ecx,byte ptr ds:[edi]
004184C1 8DBF 01000000 lea edi,dword ptr ds:[edi+0x1]
004184C7 32CB xor cl,bl
004184CB F6D9 neg cl
004184D4 80F1 0E xor cl,0xE
004184DC 80E9 21 sub cl,0x21
004184DF F6D9 neg cl
004184E1 80F1 E2 xor cl,0xE2
004184E6 32D9 xor bl,cl
004184E8 8B140C mov edx,dword ptr ss:[esp+ecx]
004184F0 8DB6 FCFFFFFF lea esi,dword ptr ds:[esi-0x4]
00418501 8916 mov dword ptr ds:[esi],edx
00418503 8B0F mov ecx,dword ptr ds:[edi]
0041850A 81C7 04000000 add edi,0x4
00418510 33CB xor ecx,ebx
00418516 81E9 8C1F9123 sub ecx,0x23911F8C
004402C4 D1C9 ror ecx,1
004178C0 49 dec ecx
0044E1FF F7D1 not ecx
0044E204 33D9 xor ebx,ecx
0044E20A 03E9 add ebp,ecx
00462636 8D5424 60 lea edx,dword ptr ss:[esp+0x60]
0046263A 3BF2 cmp esi,edx
00481402 ^\0F87 04A9FCFF ja test1_vm.0044BD0C
00481408 8BC4 mov eax,esp
0048140A B9 40000000 mov ecx,0x40
0048140F 8D5426 80 lea edx,dword ptr ds:[esi-0x80]
00467341 81E2 FCFFFFFF and edx,-0x4
00467347 2BD1 sub edx,ecx
00467349 8BE2 mov esp,edx
0046734B 57 push edi
0045A32C 56 push esi
0045A330 9C pushfd
00489ACC 8BF0 mov esi,eax
00489AD2 8BFA mov edi,edx
0045B5BE F3:A4 rep movs byte ptr es:[edi],byte ptr ds:[esi]
0045B5C2 9D popfd
0045818E 5E pop esi
00458194 5F pop edi
0044BD0C 55 push ebp
0044BD0D C3 retn ;0x004394F5

vPush -4(0xFFFFFFFC)

变量a地址相对于ebp的相对偏移

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
004394F5    8B0F             mov ecx,dword ptr ds:[edi]
004394F7 81C7 04000000 add edi,0x4
00439503 33CB xor ecx,ebx
0043B90E 41 inc ecx
0043B912 F7D9 neg ecx
00446A07 41 inc ecx
00446A11 81F1 66772375 xor ecx,0x75237766
00446A1B 33D9 xor ebx,ecx
00446A21 81EE 04000000 sub esi,0x4
00446A30 890E mov dword ptr ds:[esi],ecx
00446A38 8B0F mov ecx,dword ptr ds:[edi]
00446A40 8DBF 04000000 lea edi,dword ptr ds:[edi+0x4]
0043C79B 33CB xor ecx,ebx
0045F6AB F7D9 neg ecx
0045F6AE 8D89 6233DE7C lea ecx,dword ptr ds:[ecx+0x7CDE3362]
004538B9 F7D9 neg ecx
004538BB F7D1 not ecx
004538BD 33D9 xor ebx,ecx
004538C4 03E9 add ebp,ecx
00462636 8D5424 60 lea edx,dword ptr ss:[esp+0x60]
0046263A 3BF2 cmp esi,edx
00481402 ^\0F87 04A9FCFF ja test1_vm.0044BD0C
00481408 8BC4 mov eax,esp
0048140A B9 40000000 mov ecx,0x40
0048140F 8D5426 80 lea edx,dword ptr ds:[esi-0x80]
00467341 81E2 FCFFFFFF and edx,-0x4
00467347 2BD1 sub edx,ecx
00467349 8BE2 mov esp,edx
0046734B 57 push edi
0045A32C 56 push esi
0045A32D 0FB7F2 movzx esi,dx
0045A330 9C pushfd
00489ACC 8BF0 mov esi,eax
00489AD2 8BFA mov edi,edx
0045B5BE F3:A4 rep movs byte ptr es:[edi],byte ptr ds:[esi]
0045B5C2 9D popfd
0045818E 5E pop esi
00458194 5F pop edi
0044BD0C 55 push ebp
0044BD0D C3 retn ;0x0046389F
1
2
3
4
5
mov	eax,dword ptr ds:[v_esp]	;变量a地址相对于ebp的相对偏移
mov edx,dword ptr ds:[v_esp+0x4]
add eax,edx
mov dword ptr ds:[v_esp+0x4],eax
mov dword ptr ds:[v_esp],efl

计算变量a的地址,ebp-4

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
0046389F    8B06             mov eax,dword ptr ds:[esi]
004638A4 8B56 04 mov edx,dword ptr ds:[esi+0x4]
004638AE 03C2 add eax,edx
004638B0 8946 04 mov dword ptr ds:[esi+0x4],eax
004638B3 9C pushfd
004638B9 8F06 pop dword ptr ds:[esi]
004638BB 8B0F mov ecx,dword ptr ds:[edi]
004638BD 81C7 04000000 add edi,0x4
004638CA 33CB xor ecx,ebx
004638CE C1C9 03 ror ecx,0x3
004638D8 F7D1 not ecx
004638E1 8D89 C448053F lea ecx,dword ptr ds:[ecx+0x3F0548C4]
004638E9 81F1 2A55B526 xor ecx,0x26B5552A
004638EF 8D89 7AB5F99B lea ecx,dword ptr ds:[ecx-0x64064A86]
004638F5 33D9 xor ebx,ecx
004638F8 03E9 add ebp,ecx
0045D98A 55 push ebp
0045D98B C3 retn ;0x0046D3FB

vPop r12

将EFL弹出堆栈

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
0046D3FB    8B0E             mov ecx,dword ptr ds:[esi]
0046D3FD 81C6 04000000 add esi,0x4
0046D403 0FB607 movzx eax,byte ptr ds:[edi]
0046D407 8DBF 01000000 lea edi,dword ptr ds:[edi+0x1]
0046D413 32C3 xor al,bl
0046D415 04 95 add al,0x95
0046D41B F6D8 neg al
004264F7 FEC0 inc al
004264F9 34 28 xor al,0x28
004264FC 32D8 xor bl,al
00426500 890C04 mov dword ptr ss:[esp+eax],ecx
00426503 8B0F mov ecx,dword ptr ds:[edi]
00426508 8DBF 04000000 lea edi,dword ptr ds:[edi+0x4]
0042650F 33CB xor ecx,ebx
00426512 C1C9 02 ror ecx,0x2
0047CDC0 81F1 7E7F9C09 xor ecx,0x99C7F7E
00483DE1 49 dec ecx
00483DE8 81F1 F25E4677 xor ecx,0x77465EF2
00483DF9 8D89 1A29644A lea ecx,dword ptr ds:[ecx+0x4A64291A]
00483E02 33D9 xor ebx,ecx
00483E0B 03E9 add ebp,ecx
0047FFF9 ^\FFE5 jmp ebp ;0x00452B62
1
2
3
mov 	eax,dword ptr ds:[v_esp]	;变量a地址
mov edx,dword ptr ds:[v_esp+0x4] ;之前vPush进来的eax
mov dword ptr ds:[eax],edx ;mov dword ptr [ebp-4],eax

把计算的结果存回变量a

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
00452B62    8B06             mov eax,dword ptr ds:[esi]				;变量a的地址
00452B6B 8B56 04 mov edx,dword ptr ds:[esi+0x4] ;a的值
00452B71 8DB6 08000000 lea esi,dword ptr ds:[esi+0x8]
00452B7E 36:8910 mov dword ptr ss:[eax],edx
00452B88 8B07 mov eax,dword ptr ds:[edi]
00452B8D 81C7 04000000 add edi,0x4
00452B96 33C3 xor eax,ebx
00452B9C F7D0 not eax
00452BA3 8D80 39CAABFE lea eax,dword ptr ds:[eax-0x15435C7]
00452BA9 35 CE111A71 xor eax,0x711A11CE
00452BB3 8D80 03AE9DB8 lea eax,dword ptr ds:[eax-0x476251FD]
00452BB9 33D8 xor ebx,eax
00452BBC 03E8 add ebp,eax
0040AABF 55 push ebp
0040AAC0 C3 retn ;0x004494C2

vPush R0(0x0019FF2C)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
004494C2    0FB60F           movzx ecx,byte ptr ds:[edi]
004494CC 8DBF 01000000 lea edi,dword ptr ds:[edi+0x1]
004494DA 32CB xor cl,bl
004494DC F6D9 neg cl
004494DF 80F1 0E xor cl,0xE
004494E8 80E9 21 sub cl,0x21
004494EB F6D9 neg cl
004494F4 80F1 E2 xor cl,0xE2
004494FD 32D9 xor bl,cl
00449503 8B140C mov edx,dword ptr ss:[esp+ecx]
0044950A 81EE 04000000 sub esi,0x4
00449511 8916 mov dword ptr ds:[esi],edx
00449516 8B0F mov ecx,dword ptr ds:[edi]
00449518 81C7 04000000 add edi,0x4
0042DC24 33CB xor ecx,ebx
0042DC27 81E9 8C1F9123 sub ecx,0x23911F8C
0042DC30 D1C9 ror ecx,1
0043242E 49 dec ecx
00432430 F7D1 not ecx
00432433 33D9 xor ebx,ecx
00432436 03E9 add ebp,ecx
00462636 8D5424 60 lea edx,dword ptr ss:[esp+0x60]
0046263A 3BF2 cmp esi,edx
00481402 ^\0F87 04A9FCFF ja test1_vm.0044BD0C
00481408 8BC4 mov eax,esp
0048140A B9 40000000 mov ecx,0x40
0048140F 8D5426 80 lea edx,dword ptr ds:[esi-0x80]
00467341 81E2 FCFFFFFF and edx,-0x4
00467347 2BD1 sub edx,ecx
00467349 8BE2 mov esp,edx
0046734B 57 push edi
0045A32C 56 push esi
0045A330 9C pushfd
00489ACC 8BF0 mov esi,eax
00489AD2 8BFA mov edi,edx
0045B5BE F3:A4 rep movs byte ptr es:[edi],byte ptr ds:[esi]
0045B5C2 9D popfd
0045818E 5E pop esi
00458194 5F pop edi
0044BD0C 55 push ebp
0044BD0D C3 retn ;0x0044A08D

vPush -4(0xFFFFFFFC)

变量a地址相对于ebp的相对偏移

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
0044A08D    8B0F             mov ecx,dword ptr ds:[edi]
0044A08F 81C7 04000000 add edi,0x4
0041917F 33CB xor ecx,ebx
00477182 41 inc ecx
0041182A F7D9 neg ecx
0041996A 41 inc ecx
0041996B 81F1 66772375 xor ecx,0x75237766
00419972 33D9 xor ebx,ecx
00419979 8DB6 FCFFFFFF lea esi,dword ptr ds:[esi-0x4]
0041997F 890E mov dword ptr ds:[esi],ecx
00419981 8B0F mov ecx,dword ptr ds:[edi]
00419987 8DBF 04000000 lea edi,dword ptr ds:[edi+0x4]
0044414F 33CB xor ecx,ebx
00444154 F7D9 neg ecx
00444159 8D89 6233DE7C lea ecx,dword ptr ds:[ecx+0x7CDE3362]
004774CA F7D9 neg ecx
004774CD F7D1 not ecx
004774D0 33D9 xor ebx,ecx
004774D3 03E9 add ebp,ecx
00462636 8D5424 60 lea edx,dword ptr ss:[esp+0x60]
0046263A 3BF2 cmp esi,edx
00481402 ^\0F87 04A9FCFF ja test1_vm.0044BD0C
00481408 8BC4 mov eax,esp
0048140A B9 40000000 mov ecx,0x40
0048140F 8D5426 80 lea edx,dword ptr ds:[esi-0x80]
00467341 81E2 FCFFFFFF and edx,-0x4
00467347 2BD1 sub edx,ecx
00467349 8BE2 mov esp,edx
0046734B 57 push edi
0045A32C 56 push esi
0045A32D 0FB7F2 movzx esi,dx
0045A330 9C pushfd
00489ACC 8BF0 mov esi,eax
00489AD2 8BFA mov edi,edx
0045B5BE F3:A4 rep movs byte ptr es:[edi],byte ptr ds:[esi]
0045B5C2 9D popfd
0045818E 5E pop esi ; test1_vm.0043D148
00458194 5F pop edi
0044BD0C 55 push ebp
0044BD0D C3 retn ;0x0042A0F0
1
2
3
4
5
mov	eax,dword ptr ds:[v_esp]	;变量a地址相对于ebp的相对偏移
mov edx,dword ptr ds:[v_esp+0x4]
add eax,edx
mov dword ptr ds:[v_esp+0x4],eax
mov dword ptr ds:[v_esp],efl

计算变量a的地址,ebp-4

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
0042A0F0    8B06             mov eax,dword ptr ds:[esi]
0042A0FD 8B56 04 mov edx,dword ptr ds:[esi+0x4]
0042A105 03C2 add eax,edx
0042A107 8946 04 mov dword ptr ds:[esi+0x4],eax
0042A10D 9C pushfd
0042A112 8F06 pop dword ptr ds:[esi]
0042A11B 8B0F mov ecx,dword ptr ds:[edi]
0042A11D 81C7 04000000 add edi,0x4
0042A129 33CB xor ecx,ebx
004670D9 C1C9 03 ror ecx,0x3
0041C461 F7D1 not ecx
0041C468 8D89 C448053F lea ecx,dword ptr ds:[ecx+0x3F0548C4]
0041C46E 81F1 2A55B526 xor ecx,0x26B5552A
0041C474 81E9 864A0664 sub ecx,0x64064A86
0041C482 33D9 xor ebx,ecx
0044C712 03E9 add ebp,ecx
0045ACDE 55 push ebp
0045ACDF C3 retn ;0x0046C4CB

vPop r15

将EFL弹出

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
0046C4CB    8B0E             mov ecx,dword ptr ds:[esi]
0046C4CD 8DB6 04000000 lea esi,dword ptr ds:[esi+0x4]
0046C4D7 0FB607 movzx eax,byte ptr ds:[edi]
0046C4E3 32C3 xor al,bl
0046C4EA 04 95 add al,0x95
00445326 F6D8 neg al
00445328 FEC0 inc al
0044532B 34 28 xor al,0x28
00445332 32D8 xor bl,al
00445334 890C04 mov dword ptr ss:[esp+eax],ecx
0044533F 8B0F mov ecx,dword ptr ds:[edi]
00445346 81C7 04000000 add edi,0x4
0044534C 33CB xor ecx,ebx
0044534E C1C9 02 ror ecx,0x2
00445351 81F1 7E7F9C09 xor ecx,0x99C7F7E
00478CFC 49 dec ecx
00478CFD 81F1 F25E4677 xor ecx,0x77465EF2
0046EDD9 81C1 1A29644A add ecx,0x4A64291A
0046EDE5 33D9 xor ebx,ecx
0046EDEA 03E9 add ebp,ecx
0043713E 55 push ebp
0043713F C3 retn ;0x00437854
1
2
3
mov 	eax,dword ptr ds:[v_esp]	;变量a地址
mov edx,dword ptr ds:[eax] ;
mov dword ptr ds:[v_esp],edx

把变量a的值存放栈顶

1
2
3
4
5
6
7
8
9
10
11
12
13
14
00437854    8B16             mov edx,dword ptr ds:[esi]
00437858 36:8B02 mov eax,dword ptr ss:[edx]
0043785C 8906 mov dword ptr ds:[esi],eax ;把变量a的值读出来后存放值v_stack栈顶
00437863 8B07 mov eax,dword ptr ds:[edi]
00437865 8DBF 04000000 lea edi,dword ptr ds:[edi+0x4]
0043786D 33C3 xor eax,ebx
0043786F 05 84307C17 add eax,0x177C3084
00480A5B 0FC8 bswap eax
0041D7F7 40 inc eax
0041D7FC F7D0 not eax
0041D7FE 33D8 xor ebx,eax
0041D803 03E8 add ebp,eax
0042FA74 55 push ebp
0042FA75 C3 retn ;0x00474E9C

vPop r12

将变量a的值保存到寄存器R12,相当于mov ecx,dword ptr [ebp-4]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
00474E9C    8B0E             mov ecx,dword ptr ds:[esi]
00474EA0 81C6 04000000 add esi,0x4
00474EAB 0FB607 movzx eax,byte ptr ds:[edi]
00474EAE 81C7 01000000 add edi,0x1
00474EB6 32C3 xor al,bl
00445C08 04 95 add al,0x95
00445C0B F6D8 neg al
00483885 FEC0 inc al
00483887 34 28 xor al,0x28
0048388A 32D8 xor bl,al
00483890 890C04 mov dword ptr ss:[esp+eax],ecx
00483895 8B0F mov ecx,dword ptr ds:[edi]
004376C4 8DBF 04000000 lea edi,dword ptr ds:[edi+0x4]
004745C8 33CB xor ecx,ebx
0044E82C C1C9 02 ror ecx,0x2
0044E82F 81F1 7E7F9C09 xor ecx,0x99C7F7E
004072B5 81F1 F25E4677 xor ecx,0x77465EF2
004072BB 81C1 1A29644A add ecx,0x4A64291A
004072C5 33D9 xor ebx,ecx
004072C9 03E9 add ebp,ecx
00471DC6 55 push ebp
00471DC7 C3 retn ;0x00405372

vPush R12

push ecx

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
00405372    0FB60F           movzx ecx,byte ptr ds:[edi]
0040537B 81C7 01000000 add edi,0x1
00405384 32CB xor cl,bl
00405389 F6D9 neg cl
0040538D 80F1 0E xor cl,0xE
00405393 80E9 21 sub cl,0x21
00405396 F6D9 neg cl
004053A0 80F1 E2 xor cl,0xE2
004053A8 32D9 xor bl,cl
004053B1 8B140C mov edx,dword ptr ss:[esp+ecx]
004053B9 8DB6 FCFFFFFF lea esi,dword ptr ds:[esi-0x4]
004053C4 8916 mov dword ptr ds:[esi],edx
004053C9 8B0F mov ecx,dword ptr ds:[edi]
00474617 8DBF 04000000 lea edi,dword ptr ds:[edi+0x4]
00474622 33CB xor ecx,ebx
0047462F 81E9 8C1F9123 sub ecx,0x23911F8C
00474636 D1C9 ror ecx,1
004863EB 49 dec ecx
00435EA6 F7D1 not ecx
00435EAE 33D9 xor ebx,ecx
00435EB8 03E9 add ebp,ecx
00462636 8D5424 60 lea edx,dword ptr ss:[esp+0x60]
0046263A 3BF2 cmp esi,edx
00481402 ^\0F87 04A9FCFF ja test1_vm.0044BD0C
00481408 8BC4 mov eax,esp
0048140A B9 40000000 mov ecx,0x40
0048140F 8D5426 80 lea edx,dword ptr ds:[esi-0x80]
00467341 81E2 FCFFFFFF and edx,-0x4
00467347 2BD1 sub edx,ecx
00467349 8BE2 mov esp,edx
0046734B 57 push edi
0045A32C 56 push esi
0045A330 9C pushfd
00489ACC 8BF0 mov esi,eax
00489AD2 8BFA mov edi,edx
0045B5BE F3:A4 rep movs byte ptr es:[edi],byte ptr ds:[esi]
0045B5C2 9D popfd
0045818E 5E pop esi ; test1_vm.0043D162
00458194 5F pop edi
0044BD0C 55 push ebp
0044BD0D C3 retn //0x004357B8

vPush 4020FCh

push “%d\n”

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
004357B8    8B0F             mov ecx,dword ptr ds:[edi]
004357BD 8DBF 04000000 lea edi,dword ptr ds:[edi+0x4]
004357C5 33CB xor ecx,ebx
004357D0 F7D9 neg ecx
004357D2 41 inc ecx
004357D5 81F1 66772375 xor ecx,0x75237766
004357E1 33D9 xor ebx,ecx
004357E3 81EE 04000000 sub esi,0x4
004357EA 890E mov dword ptr ds:[esi],ecx
004357EC 8B0F mov ecx,dword ptr ds:[edi]
004357EE 81C7 04000000 add edi,0x4
004357F8 33CB xor ecx,ebx
004357FA F7D9 neg ecx
00435802 8D89 6233DE7C lea ecx,dword ptr ds:[ecx+0x7CDE3362]
0043580F F7D1 not ecx
0043581A 33D9 xor ebx,ecx
0043581C 03E9 add ebp,ecx
00462636 8D5424 60 lea edx,dword ptr ss:[esp+0x60]
0046263A 3BF2 cmp esi,edx
00481402 ^\0F87 04A9FCFF ja test1_vm.0044BD0C
00481408 8BC4 mov eax,esp
0048140A B9 40000000 mov ecx,0x40
0048140F 8D5426 80 lea edx,dword ptr ds:[esi-0x80]
00467341 81E2 FCFFFFFF and edx,-0x4
00467347 2BD1 sub edx,ecx
00467349 8BE2 mov esp,edx
0046734B 57 push edi
0045A32C 56 push esi
0045A330 9C pushfd
00489ACC 8BF0 mov esi,eax
00489AD2 8BFA mov edi,edx
0045B5BE F3:A4 rep movs byte ptr es:[edi],byte ptr ds:[esi]
0045B5C2 9D popfd
0045818E 5E pop esi ; test1_vm.0043D167
00458194 5F pop edi
0044BD0C 55 push ebp
0044BD0D C3 retn ;0x0043AA20

vPush VMEntry

重新进入虚拟机的入口,也就是printf执行完毕后的返回地址

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
0043AA20    8B0F             mov ecx,dword ptr ds:[edi]
0043AA26 81C7 04000000 add edi,0x4
0043AA2E 33CB xor ecx,ebx
0047C322 F7D9 neg ecx
0047C324 41 inc ecx
0047C32B 81F1 66772375 xor ecx,0x75237766
0042C668 33D9 xor ebx,ecx
0042C66B 81EE 04000000 sub esi,0x4
0042C674 890E mov dword ptr ds:[esi],ecx
0042C67F 8B0F mov ecx,dword ptr ds:[edi]
0042C687 8DBF 04000000 lea edi,dword ptr ds:[edi+0x4]
0042C699 33CB xor ecx,ebx
0045ED4D F7D9 neg ecx
0045ED4F 8D89 6233DE7C lea ecx,dword ptr ds:[ecx+0x7CDE3362]
0045ED55 F7D9 neg ecx
0045ED5D F7D1 not ecx
0045ED60 33D9 xor ebx,ecx
00446EEF 03E9 add ebp,ecx
00462636 8D5424 60 lea edx,dword ptr ss:[esp+0x60]
0046263A 3BF2 cmp esi,edx
00481402 ^\0F87 04A9FCFF ja test1_vm.0044BD0C
00481408 8BC4 mov eax,esp
0048140A B9 40000000 mov ecx,0x40
0048140F 8D5426 80 lea edx,dword ptr ds:[esi-0x80]
00467341 81E2 FCFFFFFF and edx,-0x4
00467347 2BD1 sub edx,ecx
00467349 8BE2 mov esp,edx
0046734B 57 push edi
0045A32C 56 push esi
0045A32D 0FB7F2 movzx esi,dx
0045A330 9C pushfd
00489ACC 8BF0 mov esi,eax
00489AD2 8BFA mov edi,edx
0045B5BE F3:A4 rep movs byte ptr es:[edi],byte ptr ds:[esi]
0045B5C2 9D popfd
0045818E 5E pop esi ; test1_vm.0043D16F
00458194 5F pop edi
0044BD0C 55 push ebp
0044BD0D C3 retn ;0x0044A38D

vPush printf

将printf函数地址压入栈

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
0044A38D    8B0F             mov ecx,dword ptr ds:[edi]
0044A38F 81C7 04000000 add edi,0x4
0044A395 33CB xor ecx,ebx
00441810 41 inc ecx
00441816 F7D9 neg ecx
0041C24A 41 inc ecx
0041C250 81F1 66772375 xor ecx,0x75237766
0041C259 33D9 xor ebx,ecx
0041C260 8DB6 FCFFFFFF lea esi,dword ptr ds:[esi-0x4]
0041C26A 890E mov dword ptr ds:[esi],ecx
0041C270 8B0F mov ecx,dword ptr ds:[edi]
0041C273 81C7 04000000 add edi,0x4
0041C279 33CB xor ecx,ebx
0041C27B F7D9 neg ecx
0041C286 8D89 6233DE7C lea ecx,dword ptr ds:[ecx+0x7CDE3362]
0041C28C F7D9 neg ecx
00435617 F7D1 not ecx
0043561B 33D9 xor ebx,ecx
00435622 03E9 add ebp,ecx
00462636 8D5424 60 lea edx,dword ptr ss:[esp+0x60]
0046263A 3BF2 cmp esi,edx
00481402 ^\0F87 04A9FCFF ja test1_vm.0044BD0C
00481408 8BC4 mov eax,esp
0048140A B9 40000000 mov ecx,0x40
0048140F 8D5426 80 lea edx,dword ptr ds:[esi-0x80]
00467341 81E2 FCFFFFFF and edx,-0x4
00467347 2BD1 sub edx,ecx
00467349 8BE2 mov esp,edx
0046734B 57 push edi
0045A32C 56 push esi
0045A32D 0FB7F2 movzx esi,dx
0045A330 9C pushfd
00489ACC 8BF0 mov esi,eax
00489AD2 8BFA mov edi,edx
0045B5BE F3:A4 rep movs byte ptr es:[edi],byte ptr ds:[esi]
0045B5C2 9D popfd
0045818E 5E pop esi ; test1_vm.0043D177
00458194 5F pop edi
0044BD0C 55 push ebp
0044BD0D C3 retn ;0x004126A8

vPush R4(2)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
004126A8    0FB60F           movzx ecx,byte ptr ds:[edi]
004126B4 8DBF 01000000 lea edi,dword ptr ds:[edi+0x1]
004126C0 32CB xor cl,bl
004126C4 F6D9 neg cl
004126CD 80F1 0E xor cl,0xE
004126D3 80E9 21 sub cl,0x21
004126DF F6D9 neg cl
004126E1 80F1 E2 xor cl,0xE2
004126E4 32D9 xor bl,cl
004126E6 8B140C mov edx,dword ptr ss:[esp+ecx]
004126F0 8DB6 FCFFFFFF lea esi,dword ptr ds:[esi-0x4]
004126F6 8916 mov dword ptr ds:[esi],edx
004126FE 8B0F mov ecx,dword ptr ds:[edi]
00412702 81C7 04000000 add edi,0x4
0041270D 33CB xor ecx,ebx
00412718 81E9 8C1F9123 sub ecx,0x23911F8C
0041271F D1C9 ror ecx,1
00412721 49 dec ecx
00489F7A F7D1 not ecx
00445362 33D9 xor ebx,ecx
00445369 03E9 add ebp,ecx
00462636 8D5424 60 lea edx,dword ptr ss:[esp+0x60]
0046263A 3BF2 cmp esi,edx
00481402 ^\0F87 04A9FCFF ja test1_vm.0044BD0C
00481408 8BC4 mov eax,esp
0048140A B9 40000000 mov ecx,0x40
0048140F 8D5426 80 lea edx,dword ptr ds:[esi-0x80]
00467341 81E2 FCFFFFFF and edx,-0x4
00467347 2BD1 sub edx,ecx
00467349 8BE2 mov esp,edx
0046734B 57 push edi
0045A32C 56 push esi
0045A32D 0FB7F2 movzx esi,dx
0045A330 9C pushfd
00489ACC 8BF0 mov esi,eax
00489AD2 8BFA mov edi,edx
0045B5BE F3:A4 rep movs byte ptr es:[edi],byte ptr ds:[esi]
0045B5C2 9D popfd
0045818E 5E pop esi ; test1_vm.0043D17F
00458194 5F pop edi
0044BD0C 55 push ebp
0044BD0D C3 retn ;0x0047B785

vPush R5(2)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
0047B785    0FB60F           movzx ecx,byte ptr ds:[edi]
0047B790 8DBF 01000000 lea edi,dword ptr ds:[edi+0x1]
0047B79E 32CB xor cl,bl
0047B7AA F6D9 neg cl
0047B7AC 80F1 0E xor cl,0xE
0047B7B3 80E9 21 sub cl,0x21
0040EEF9 F6D9 neg cl
0040EEFE 80F1 E2 xor cl,0xE2
0040EF01 32D9 xor bl,cl
0040EF07 8B140C mov edx,dword ptr ss:[esp+ecx]
0040EF0D 8DB6 FCFFFFFF lea esi,dword ptr ds:[esi-0x4]
0040EF17 8916 mov dword ptr ds:[esi],edx
0040EF20 8B0F mov ecx,dword ptr ds:[edi]
0040EF22 8DBF 04000000 lea edi,dword ptr ds:[edi+0x4]
0040EF28 33CB xor ecx,ebx
0040EF2A 81E9 8C1F9123 sub ecx,0x23911F8C
0040EF32 D1C9 ror ecx,1
00430F23 49 dec ecx
00430F29 F7D1 not ecx
00430F2B 33D9 xor ebx,ecx
00430F2E 03E9 add ebp,ecx
00462636 8D5424 60 lea edx,dword ptr ss:[esp+0x60]
0046263A 3BF2 cmp esi,edx
00481402 ^\0F87 04A9FCFF ja test1_vm.0044BD0C
00481408 8BC4 mov eax,esp
0048140A B9 40000000 mov ecx,0x40
0048140F 8D5426 80 lea edx,dword ptr ds:[esi-0x80]
00467341 81E2 FCFFFFFF and edx,-0x4
00467347 2BD1 sub edx,ecx
00467349 8BE2 mov esp,edx
0046734B 57 push edi
0045A32C 56 push esi
0045A32D 0FB7F2 movzx esi,dx
0045A330 9C pushfd
00489ACC 8BF0 mov esi,eax
00489AD2 8BFA mov edi,edx
0045B5BE F3:A4 rep movs byte ptr es:[edi],byte ptr ds:[esi]
0045B5C2 9D popfd
0045818E 5E pop esi
00458194 5F pop edi
0044BD0C 55 push ebp
0044BD0D C3 retn ;0x0045325C

vPush

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
0045325C    0FB60F           movzx ecx,byte ptr ds:[edi]
00453267 8DBF 01000000 lea edi,dword ptr ds:[edi+0x1]
0045326D 32CB xor cl,bl
0045326F F6D9 neg cl
00453272 80F1 0E xor cl,0xE
00453278 80E9 21 sub cl,0x21
00453282 F6D9 neg cl
0045328E 80F1 E2 xor cl,0xE2
00453291 80EA 48 sub dl,0x48
00453296 32D9 xor bl,cl
004532A5 8B140C mov edx,dword ptr ss:[esp+ecx]
004532A8 81EE 04000000 sub esi,0x4
004532B4 8916 mov dword ptr ds:[esi],edx
004532BD 8B0F mov ecx,dword ptr ds:[edi]
004532C4 8DBF 04000000 lea edi,dword ptr ds:[edi+0x4]
0041B011 33CB xor ecx,ebx
0041B018 81E9 8C1F9123 sub ecx,0x23911F8C
0041B01E D1C9 ror ecx,1
004692ED 49 dec ecx
004692F3 F7D1 not ecx
004692FA 33D9 xor ebx,ecx
004692FC 03E9 add ebp,ecx
00462636 8D5424 60 lea edx,dword ptr ss:[esp+0x60]
0046263A 3BF2 cmp esi,edx
00481402 ^\0F87 04A9FCFF ja test1_vm.0044BD0C
00481408 8BC4 mov eax,esp
0048140A B9 40000000 mov ecx,0x40
0048140F 8D5426 80 lea edx,dword ptr ds:[esi-0x80]
00467341 81E2 FCFFFFFF and edx,-0x4
00467347 2BD1 sub edx,ecx
00467349 8BE2 mov esp,edx
0046734B 57 push edi
0045A32C 56 push esi
0045A32D 0FB7F2 movzx esi,dx
0045A330 9C pushfd
00489ACC 8BF0 mov esi,eax
00489AD2 8BFA mov edi,edx
0045B5BE F3:A4 rep movs byte ptr es:[edi],byte ptr ds:[esi]
0045B5C2 9D popfd
0045818E 5E pop esi ; test1_vm.0043D189
00458194 5F pop edi
0044BD0C 55 push ebp
0044BD0D C3 retn ;0x0045225C

vPush

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
0045225C    0FB60F           movzx ecx,byte ptr ds:[edi]                                         
00452265 8DBF 01000000 lea edi,dword ptr ds:[edi+0x1]
0045226B 32CB xor cl,bl
0045226D F6D9 neg cl
00452273 80F1 0E xor cl,0xE
0045227D 80E9 21 sub cl,0x21
0045228B F6D9 neg cl
0045228D 80F1 E2 xor cl,0xE2
00452292 32D9 xor bl,cl
00452297 8B140C mov edx,dword ptr ss:[esp+ecx]
0045229A 81EE 04000000 sub esi,0x4
004522AE 8916 mov dword ptr ds:[esi],edx
004522B0 8B0F mov ecx,dword ptr ds:[edi]
004522B3 8DBF 04000000 lea edi,dword ptr ds:[edi+0x4]
004522BE 33CB xor ecx,ebx
0045676E 81E9 8C1F9123 sub ecx,0x23911F8C
00456776 D1C9 ror ecx,1
00463F87 49 dec ecx
00463F8C F7D1 not ecx
0041EFFB 33D9 xor ebx,ecx
0041F001 03E9 add ebp,ecx
00462636 8D5424 60 lea edx,dword ptr ss:[esp+0x60]
0046263A 3BF2 cmp esi,edx
00481402 ^\0F87 04A9FCFF ja test1_vm.0044BD0C
00481408 8BC4 mov eax,esp
0048140A B9 40000000 mov ecx,0x40
0048140F 8D5426 80 lea edx,dword ptr ds:[esi-0x80]
00467341 81E2 FCFFFFFF and edx,-0x4
00467347 2BD1 sub edx,ecx
00467349 8BE2 mov esp,edx
0046734B 57 push edi
0045A32C 56 push esi
0045A330 9C pushfd
00489ACC 8BF0 mov esi,eax
00489AD2 8BFA mov edi,edx
0045B5BE F3:A4 rep movs byte ptr es:[edi],byte ptr ds:[esi]
0045B5C2 9D popfd
0045818E 5E pop esi
00458194 5F pop edi
0044BD0C 55 push ebp
0044BD0D C3 retn ;0x0047E64B

vPush

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
0047E64B    0FB60F           movzx ecx,byte ptr ds:[edi]
0047E661 32CB xor cl,bl
0047E663 F6D9 neg cl
0047E66B 80F1 0E xor cl,0xE
0047E670 80E9 21 sub cl,0x21
0047E681 F6D9 neg cl
0047E683 80F1 E2 xor cl,0xE2
0047E686 32D9 xor bl,cl
0047E68E 8B140C mov edx,dword ptr ss:[esp+ecx]
0047E697 81EE 04000000 sub esi,0x4
0047E6A2 8916 mov dword ptr ds:[esi],edx
0047E6AC 8B0F mov ecx,dword ptr ds:[edi]
0047E6B4 81C7 04000000 add edi,0x4
0047E6BA 66:81FE 6D64 cmp si,0x646D
0047E6BF 33CB xor ecx,ebx
0047E6C8 81E9 8C1F9123 sub ecx,0x23911F8C
0047E6CF D1C9 ror ecx,1
0044CE2D 49 dec ecx
0044CE2E F7D1 not ecx
0044CE30 33D9 xor ebx,ecx
0044CE33 03E9 add ebp,ecx
00462636 8D5424 60 lea edx,dword ptr ss:[esp+0x60]
0046263A 3BF2 cmp esi,edx
00481402 ^\0F87 04A9FCFF ja test1_vm.0044BD0C
00481408 8BC4 mov eax,esp
0048140A B9 40000000 mov ecx,0x40
0048140F 8D5426 80 lea edx,dword ptr ds:[esi-0x80]
00467341 81E2 FCFFFFFF and edx,-0x4
00467347 2BD1 sub edx,ecx
00467349 8BE2 mov esp,edx
0046734B 57 push edi
0045A32C 56 push esi
0045A330 9C pushfd
00489ACC 8BF0 mov esi,eax
00489AD2 8BFA mov edi,edx
0045B5BE F3:A4 rep movs byte ptr es:[edi],byte ptr ds:[esi]
0045B5C2 9D popfd
0045818E 5E pop esi
00458194 5F pop edi
0044BD0C 55 push ebp
0044BD0D C3 retn ;0x0041043E

vPush

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
0041043E    0FB60F           movzx ecx,byte ptr ds:[edi]
00410443 8DBF 01000000 lea edi,dword ptr ds:[edi+0x1]
0041044E 32CB xor cl,bl
00410450 F6D9 neg cl
00410452 80F1 0E xor cl,0xE
00410460 80E9 21 sub cl,0x21
0041046B F6D9 neg cl
00410471 80F1 E2 xor cl,0xE2
00410479 32D9 xor bl,cl
0041047D 8B140C mov edx,dword ptr ss:[esp+ecx]
00410480 81EE 04000000 sub esi,0x4
00410489 8916 mov dword ptr ds:[esi],edx
00410497 8B0F mov ecx,dword ptr ds:[edi]
0041049E 8DBF 04000000 lea edi,dword ptr ds:[edi+0x4]
004104A4 33CB xor ecx,ebx
004104A8 81E9 8C1F9123 sub ecx,0x23911F8C
004104B1 D1C9 ror ecx,1
004104B3 49 dec ecx
00440D59 F7D1 not ecx
00440D5C 33D9 xor ebx,ecx
004251B5 03E9 add ebp,ecx
00462636 8D5424 60 lea edx,dword ptr ss:[esp+0x60]
0046263A 3BF2 cmp esi,edx
00481402 ^\0F87 04A9FCFF ja test1_vm.0044BD0C
00481408 8BC4 mov eax,esp
0048140A B9 40000000 mov ecx,0x40
0048140F 8D5426 80 lea edx,dword ptr ds:[esi-0x80]
00467341 81E2 FCFFFFFF and edx,-0x4
00467347 2BD1 sub edx,ecx
00467349 8BE2 mov esp,edx
0046734B 57 push edi
0045A32C 56 push esi
0045A32D 0FB7F2 movzx esi,dx
0045A330 9C pushfd
00489ACC 8BF0 mov esi,eax
00489AD2 8BFA mov edi,edx
0045B5BE F3:A4 rep movs byte ptr es:[edi],byte ptr ds:[esi]
0045B5C2 9D popfd
0045818E 5E pop esi ; test1_vm.0043D198
00458194 5F pop edi
0044BD0C 55 push ebp
0044BD0D C3 retn ;0x00421D3D

vPush

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
00421D3D    0FB60F           movzx ecx,byte ptr ds:[edi]
00421D43 8DBF 01000000 lea edi,dword ptr ds:[edi+0x1]
00421D49 32CB xor cl,bl
00421D55 F6D9 neg cl
00421D5B 80F1 0E xor cl,0xE
00421D64 80E9 21 sub cl,0x21
00421D6D F6D9 neg cl
00421D72 80F1 E2 xor cl,0xE2
00421D78 32D9 xor bl,cl
00421D81 8B140C mov edx,dword ptr ss:[esp+ecx]
00421D87 8DB6 FCFFFFFF lea esi,dword ptr ds:[esi-0x4]
00421D95 8916 mov dword ptr ds:[esi],edx
00421D9D 8B0F mov ecx,dword ptr ds:[edi]
00455281 8DBF 04000000 lea edi,dword ptr ds:[edi+0x4]
00455289 33CB xor ecx,ebx
0045528E 81E9 8C1F9123 sub ecx,0x23911F8C
00455294 D1C9 ror ecx,1
0043425D 49 dec ecx
00434263 F7D1 not ecx
00434267 33D9 xor ebx,ecx
0043426F 03E9 add ebp,ecx
00462636 8D5424 60 lea edx,dword ptr ss:[esp+0x60]
0046263A 3BF2 cmp esi,edx
00481402 ^\0F87 04A9FCFF ja test1_vm.0044BD0C
00481408 8BC4 mov eax,esp
0048140A B9 40000000 mov ecx,0x40
0048140F 8D5426 80 lea edx,dword ptr ds:[esi-0x80]
00467341 81E2 FCFFFFFF and edx,-0x4
00467347 2BD1 sub edx,ecx
00467349 8BE2 mov esp,edx
0046734B 57 push edi
0045A32C 56 push esi
0045A32D 0FB7F2 movzx esi,dx
0045A330 9C pushfd
00489ACC 8BF0 mov esi,eax
00489AD2 8BFA mov edi,edx
0040D075 FC cld
0045B5BE F3:A4 rep movs byte ptr es:[edi],byte ptr ds:[esi]
0045B5C2 9D popfd
0045818E 5E pop esi ; test1_vm.0043D19D
00458194 5F pop edi
0044BD0C 55 push ebp
0044BD0D C3 retn ;0x0040EB2E

vPush

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
0040EB2E    0FB60F           movzx ecx,byte ptr ds:[edi]
0040EB37 8DBF 01000000 lea edi,dword ptr ds:[edi+0x1]
0040EB40 32CB xor cl,bl
0040EB4F F6D9 neg cl
0040EB51 80F1 0E xor cl,0xE
0040EB5B 80E9 21 sub cl,0x21
0040EB68 F6D9 neg cl
0040EB6E 80F1 E2 xor cl,0xE2
0040EB76 32D9 xor bl,cl
00440ED1 8B140C mov edx,dword ptr ss:[esp+ecx]
00440ED8 81EE 04000000 sub esi,0x4
00440EDE 8916 mov dword ptr ds:[esi],edx
00440EE0 8B0F mov ecx,dword ptr ds:[edi]
0041D911 81C7 04000000 add edi,0x4
0041D91A 33CB xor ecx,ebx
0042EDBF 81E9 8C1F9123 sub ecx,0x23911F8C
0042AD19 D1C9 ror ecx,1
0042AD1B 49 dec ecx
0042AD1C F7D1 not ecx
0042AD1E 33D9 xor ebx,ecx
004526DB 03E9 add ebp,ecx
00462636 8D5424 60 lea edx,dword ptr ss:[esp+0x60]
0046263A 3BF2 cmp esi,edx
00481402 ^\0F87 04A9FCFF ja test1_vm.0044BD0C
00481408 8BC4 mov eax,esp
0048140A B9 40000000 mov ecx,0x40
0048140F 8D5426 80 lea edx,dword ptr ds:[esi-0x80]
00467341 81E2 FCFFFFFF and edx,-0x4
00467347 2BD1 sub edx,ecx
00467349 8BE2 mov esp,edx
0046734B 57 push edi
0045A32C 56 push esi
0045A32D 0FB7F2 movzx esi,dx
0045A330 9C pushfd
00489ACC 8BF0 mov esi,eax
00489AD2 8BFA mov edi,edx
0045B5BE F3:A4 rep movs byte ptr es:[edi],byte ptr ds:[esi]
0045B5C2 9D popfd
0045818E 5E pop esi ; test1_vm.0043D1A2
00458194 5F pop edi
0044BD0C 55 push ebp
0044BD0D C3 retn ;0x00415543

VMExit

退出虚拟机,执行printf

1
2
3
4
5
6
7
8
9
10
00415543    8BE6             mov esp,esi
0041554A 5D pop ebp ; 0019FF2C
0041554B 5A pop edx ; 0019FF2C
0041554D 5F pop edi ; 0019FF2C
0041554E 5E pop esi ; 0019FF2C
0041554F 5B pop ebx ; 0019FF2C
00415550 9D popfd
00415557 59 pop ecx ; 0019FF2C
00415558 58 pop eax ; 0019FF2C
0043B984 C3 retn

printf执行完毕后重新回到入口函数执行

2、防侧漏用苏菲

因为是push指令,需要检查栈是否发生溢出,防止vm_context被真实堆栈覆盖。

VMP堆栈检查

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
00462636    8D5424 60       lea edx,dword ptr ss:[esp+0x60]			;edx=v_esp+0x60
0046263A 3BF2 cmp esi,edx ;原始esp与edx比较
00481402 ^\0F87 04A9FCFF ja test1_vm.0044BD0C ;如果原始esp>edx就正常返回,防止原始esp内容覆盖了vm_context
00481408 8BC4 mov eax,esp ;将v_esp传给eax
0048140A B9 40000000 mov ecx,0x40
0048140F 8D5426 80 lea edx,dword ptr ds:[esi-0x80] ;把原始esp上台0x80大小,然后把地址传给edx
00467341 81E2 FCFFFFFF and edx,-0x4
00467347 2BD1 sub edx,ecx
00467349 8BE2 mov esp,edx ;把新的堆栈地址传给v_esp
0046734B 57 push edi
0045A32C 56 push esi
0045A330 9C pushfd
00489ACC 8BF0 mov esi,eax
00489AD2 8BFA mov edi,edx
0045B5BE F3:A4 rep movs byte ptr es:[edi],byte ptr ds:[esi] ;把原来v_esp的内容拷贝到新的v_esp
0045B5C2 9D popfd
0045818E 5E pop esi
00458194 5F pop edi
0044BD0C 55 push ebp
0044BD0D C3 retn ;0x004786D0

3、简单提几句

  • vmp在初始化时会保存当前环境,将寄存器通过push进行保存,退出虚拟机时恢复寄存器
  • 在执行系统函数时,vmp会退出虚拟机,恢复初始环境;函数执行完毕后重新进入虚拟机。
  • vmp的虚拟化技术是通过将一条一句进行拆分,然后以push和pop形式进行实现,因此被称为栈虚拟机。
  • opcode的第一个字节若为操作数,则该操作数指向为vm_context的其中一个寄存器;若为四字节则为下一个要跳转的handler地址。
  • vmp是真的恶心啊。

四、真理只在大炮射程之内

经过对VMP虚拟化代码的分析后,可以使用push和pop指令按照vmp虚拟化的方式对原始的汇编语句继续改写,进行娱乐。

模拟VMP指令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
#include <iostream>

char format[] = "%d\n";
char* p = format;
__declspec(naked) void my_test()
{
__asm {
push ebp

// mov ebp,esp
push esp
pop ebp

push ecx

// mov dword ptr[ebp - 4], 1
push 1
push ebp
push 0FFFFFFFCh
mov eax, dword ptr[esp]
mov edx, dword ptr[esp + 4]
add eax, edx
mov dword ptr[esp + 4], eax
pop esi
mov eax, dword ptr[esp]
mov edx, dword ptr[esp + 4]
mov dword ptr[eax], edx

// mov eax, dword ptr[ebp - 4]
push 0FFFFFFFCh
mov eax, dword ptr[esp]
mov edx, dword ptr[esp + 4]
add eax, edx
mov dword ptr[esp + 4], eax
pop esi
mov eax, dword ptr[esp]
mov edx, dword ptr[eax]
mov dword ptr[esp], edx
pop eax

// add eax, 1
push 1
push eax
mov eax,dword ptr[esp]
mov edx,dword ptr[esp+4]
add eax,edx
mov dword ptr[esp+4],eax
pop esi

// mov dword ptr[ebp - 4], eax
push ebp
push 0FFFFFFFCh
mov eax, dword ptr[esp]
mov edx, dword ptr[esp + 4]
add eax, edx
mov dword ptr[esp + 4], eax
pop esi
mov eax, dword ptr[esp]
mov edx, dword ptr[esp + 4]
mov dword ptr[eax], edx
pop esi

// mov ecx, dword ptr[ebp - 4]
push ebp
push 0FFFFFFFCh
mov eax, dword ptr[esp]
mov edx, dword ptr[esp + 4]
add eax, edx
mov dword ptr[esp + 4], eax
pop esi
mov eax, dword ptr[esp]
mov edx, dword ptr[eax]
mov dword ptr[esp], edx
pop ecx
add esp, 8

push ecx
push p

//call返回的地址
push Next

// call 00401070
push printf
ret

Next :

//add esp, 8
push 8
push esp
mov eax,dword ptr[esp]
mov edx, dword ptr[esp+4]
add eax,edx
mov dword ptr[esp+4],eax
pop esi
mov esi,dword ptr[esp]

xor eax, eax

//mov esp,ebp
push ebp
pop esp

pop ebp
ret
}
}

int main()
{
my_test();
}

运行无任何问题且能正常输出。

image-20230105162339766

五、精准射击