概述

结构

  • vm_context(vm寄存器)
  • vm_stack(vm栈)
  • vm_instructions(vm指令)

流程

  • vm_entry
  • vm_context_init
  • vm_handle
  • vm_stack_restore
  • vm_exit

分析

vm_entry

#保存寄存器值到vmstack
0000 | 00411D37 | 68 E49B4100              | push 419BE4                       | eax: 41E029-> 41E029 ebx: | 0019FD2C: 411D35-> 419BE4                         |
0001 | 00411D3C | E9 B3990700              | jmp 48B6F4                        |                           |                                                   |
0002 | 0048B6F4 | 68 2DBA3A0F              | push F3ABA2D                      | esp: 19FD2C-> 19FD28      | 0019FD28: 19FE08-> F3ABA2D                        |
0003 | 0048B6F9 | E8 5E4BFEFF              | call 47025C                       | esp: 19FD28-> 19FD24      | 0019FD24: 41E029-> 48B6FE                         |
0004 | 0047025C | 57                       | push edi                          | esp: 19FD24-> 19FD20      | 0019FD20: 41E029-> 19FE08                         |
0006 | 00470260 | 51                       | push ecx                          | esp: 19FD20-> 19FD1C      | 0019FD1C: 5C0074-> 41E029                         |
0008 | 00470263 | 53                       | push ebx                          | esp: 19FD1C-> 19FD18      | 0019FD18: 730065-> 288000                         |
000A | 00470267 | 56                       | push esi                          | esp: 19FD18-> 19FD14      | 0019FD14: 74006D-> 19FD30                         |
000B | 00470268 | 9C                       | pushfd                            | esp: 19FD14-> 19FD10      | 0019FD10: 76005C-> 246                            |
000F | 00470272 | 52                       | push edx                          | esp: 19FD10-> 19FD0C      | 0019FD0C: 740063-> 1                              |
0012 | 00470277 | 55                       | push ebp                          | esp: 19FD0C-> 19FD08      | 0019FD08: 65006A-> 19FE08                         |
0016 | 00470281 | 50                       | push eax                          | esp: 19FD08-> 19FD04      | 0019FD04: 6F0072-> 41E029                         |
0018 | 00470286 | B8 00000000              | mov eax,0                         | eax: 410029-> 0           |                                                   |
001C | 00470296 | 50                       | push eax                          | esp: 19FD04-> 19FD00      | 0019FD00: 70005F-> 0                              |
------------------------------------------------------------------------------------
push 0				  0019FD00 $ ==>     00000000    ....     
push eax	$+4       0041E029    )àA.     vmtest.vmp._311FB91F_vmtest@cpp
push ebp	$+8       0019FE08    .þ..     
push edx	$+C       00000001    ....     
pushf	    $+10      00000246    F...     
push esi    $+14      0019FD30    0ý..     
push ebx	$+18      00356000    .`5.     .PEB.InheritedAddressSpace
push ecx	$+1C      0041E029    )àA.     vmtest.vmp._311FB91F_vmtest@cpp
push edi	$+20      0019FE08    .þ..     
call_retaddr	$+24      0048B6FE    þ¶H.     返回到 vmtest.vmp.__guard_xfg_check_icall_fptr+6C6FA 自 vmtest.vmp.__guard_xfg_check_icall_fptr+51258
push vm_key	$+28      0F3ABA2D    -º:.     
------------------------------------------------------------------------------------

#获取vm_key(解密后续vm_instructions)
0020 | 004702A2 | 8B7C24 28                | mov edi,dword ptr ss:[esp+28]     | edi: EB003385-> F3ABA2D   | 0019FD28: F3ABA2D-> F3ABA2D                       |
0022 | 004702A9 | 81EF 8530A157            | sub edi,57A13085                  | edi: F3ABA2D-> B79989A8   |                                                   |
0023 | 004702AF | C1C7 03                  | rol edi,3                         | edi: B79989A8-> BCCC4D45  |                                                   |
0027 | 004702BF | 81C7 5810F37A            | add edi,7AF31058                  | edi: BCCC4D45-> 37BF5D9D  |                                                   |
002B | 004702D0 | C1CF 03                  | ror edi,3                         | edi: 37BF5D9D-> A6F7EBB3  |                                                   |
002E | 004702DB | 8DBF DA42BE58            | lea edi,dword ptr ds:[edi+58BE42D | edi: A6F7EBB3-> FFB62E8D  |                                                   |
0030 | 004702E4 | F7D7                     | not edi                           | edi: FFB62E8D-> 49D172    |                                                   |
0034 | 004702F2 | 03F8                     | add edi,eax                       |                           |                                                   |


#ebp作为vsp(虚拟机栈顶指针)
0038 | 004702FE | 8BEC                     | mov ebp,esp                       | ebp: DA9EADF-> 19FD00     |                                                   |
#esp作为vm_context指针
003C | 0047030A | 81EC C0000000            | sub esp,C0                        | esp: 19FD00-> 19FC40      |                                                   |

#ebx存储vm_key值
0040 | 00470315 | 8BDF                     | mov ebx,edi                       | ebx: 32015A85-> 49D172    |     


#esi作为vm_ip
0045 | 00470322 | 8D35 22034700            | lea esi,dword ptr ds:[470322]     | esi: 6000022A-> 470322    |                                                   |

#edi作为vm_instructions指针,eax解密下一handle偏移
0047 | 0047032A | 8B07                     | mov eax,dword ptr ds:[edi]        | eax: FFFFFFFF-> 5660CB14  | 0049D172: 5660CB14-> 5660CB14                     |
0049 | 00470332 | 8DBF 04000000            | lea edi,dword ptr ds:[edi+4]      | edi: 49D172-> 49D176      |                                                   |
004A | 00470338 | 33C3                     | xor eax,ebx                       | eax: 5660CB14-> 56291A66  |                                                   |
004C | 0048D742 | 48                       | dec eax                           | eax: 56291A66-> 56291A65  |                                                   |
004F | 0048D74B | F7D0                     | not eax                           | eax: 56291A65-> A9D6E59A  |                                                   |
0051 | 0048D74E | 35 760E2B56              | xor eax,562B0E76                  | eax: A9D6E59A-> FFFDEBEC  |                                                   |
0053 | 004903F3 | F7D0                     | not eax                           | eax: FFFDEBEC-> 21413     |                                                   |
0055 | 0048DFA3 | 48                       | dec eax                           | eax: 21413-> 21412        |                                                   |
#ebx->vm_key更新
0057 | 0048DFA7 | 33D8                     | xor ebx,eax                       | ebx: 49D172-> 4BC560      |   

#vmhandle 跳转                                                |
005A | 0048DFB0 | 03F0                     | add esi,eax                       | esi: 470322-> 491734      |                                                   |
005C | 00445E43 | FFE6                     | jmp esi                           |                           |  

vm_context_init

重复vpop vm[x],将vm_stack栈上保存的初始寄存器值保存到vm_context

#取vm_stack栈顶元素
005D | 00491734 | 8B5425 00                | mov edx,dword ptr ss:[ebp]        | edx: 1-> 0                | 0019FD00: 0-> 0  
#ebp+4 vm_stack减小
0060 | 0049173E | 81C5 04000000            | add ebp,4                         | ebp: 19FD00-> 19FD04      |                                                   |
0064 | 0049174F | 0FB60F                   | movzx ecx,byte ptr ds:[edi]       | ecx: 417C06-> BB          | 0049D176: 2D77C5BB-> 2D77C5BB                     |
0067 | 0049175D | 81C7 01000000            | add edi,1                         | edi: 49D176-> 49D177      |                                                   |
0068 | 00491763 | 32CB                     | xor cl,bl                         | ecx: BB-> DB              |                                                   |
006B | 004A5868 | F6D1                     | not cl                            | ecx: DB-> 24              |                                                   |
006D | 004A586B | D0C9                     | ror cl,1                          | ecx: 24-> 12              |                                                   |
006E | 004A586D | F6D1                     | not cl                            | ecx: 12-> ED              |                                                   |
006F | 004A586F | 80F1 C9                  | xor cl,C9                         | ecx: ED-> 24              |                                                   |
0071 | 004A5875 | 32D9                     | xor bl,cl                         | ebx: 4BC560-> 4BC544      |   
#将原vm栈顶值存储到vm_context
0073 | 004A587C | 89140C                   | mov dword ptr ss:[esp+ecx],edx    |                           | 0019FC64: 0-> 0                                   |
#ebx->vm 下一个handle offset的加密数据
0077 | 004A588A | 8B17                     | mov edx,dword ptr ds:[edi]        | edx: 2EE0-> 962D77C5      | 0049D177: 962D77C5-> 962D77C5                     |
#vm_instructions指向下一vm指令数据
007A | 004695D6 | 81C7 04000000            | add edi,4                         | edi: 49D177-> 49D17B      |                                                   |
007C | 00460CA5 | 33D3                     | xor edx,ebx                       | edx: 962D77C5-> 9666B281  |                                                   |
007E | 0045BE64 | 81F2 7E4D7067            | xor edx,67704D7E                  | edx: 9666B281-> F116FFFF  |                                                   |
007F | 0045BE6A | C1C2 03                  | rol edx,3                         | edx: F116FFFF-> 88B7FFFF  |                                                   |
0081 | 0047BFB5 | 0FCA                     | bswap edx                         | edx: 88B7FFFF-> FFFFB788  |                                                   |
0083 | 00444FA0 | 4A                       | dec edx                           | edx: FFFFB788-> FFFFB787  |                                                   |
#更新ebx->vm_key
0085 | 00444FA2 | 33DA                     | xor ebx,edx                       | ebx: 4BC544-> FFB472C3    |                                                   |
0086 | 00444FA4 | 03F2                     | add esi,edx                       | esi: 491734-> 48CEBB      |                                                   |
0087 | 00444FA6 | E9 0E7AFFFF              | jmp 43C9B9                        |                           |                                                   |
0088 | 0043C9B9 | FFE6                     | jmp esi                           |                           |

--------------------------------------------------------------------------
Vpop +24h 0;
Vpop +3ch eax;
Vpop +14h ebp;
Vpop +30h edx;
Vpop +4h eflags;
Vpop +1ch esi;
Vpop +0 ebx;
Vpop +8h  ecx;
Vpop +10h edi;
//context init over
//stack
struct VM_Context
{
    +24h 0;
    +3ch eax;
    +14h ebp;
    +30h edx;
    +4h eflags;
    +1ch esi;
    +0 ebx;
    +8h  ecx;
    +10h edi;
};
struct vm_stack{
    //push 0				  0019FD00 $ ==>     00000000    ....     
    //push eax	$+4       0041E029    )àA.     vmtest.vmp._311FB91F_vmtest@cpp
    //push ebp	$+8       0019FE08    .þ..     
    //push edx	$+C       00000001    ....     
    //pushf	    $+10      00000246    F...     
    //push esi    $+14      0019FD30    0ý..     
    //push ebx	$+18      00356000    .`5.     .PEB.InheritedAddressSpace
    //push ecx	$+1C      0041E029    )àA.     vmtest.vmp._311FB91F_vmtest@cpp
*vsp* //push edi	$+20      0019FE08    .þ..     
    //call_retaddr	$+24      0048B6FE    þ¶H.     返回到 vmtest.vmp.__guard_xfg_check_icall_fptr+6C6FA
    //push vm_key	$+28      0F3ABA2D    -º:.  
}
------------------------------------------------------------------------------------

vm_handle

;一般而言,edi表示vm_instructions指针
;		 ebx表示vm_key
;而vsp、vip值则要根据vm_entry来判断
;这里ebp表示vsp,指向vm_stack栈顶,
#vpush imm4
sub ebp,4; lea ebp,[ebp-4]
mov [ebp+0],xxx

#vpush vm[x]
sub ebp 4;lea ebp,[ebp-4]
mov R,VM[X]
mov [ebp],R

;vpush 指令中会有check_vsp操作
#check_vsp
lea eax,dword ptr ss:[esp+60]                                    
cmp ebp,eax                                                               
ja tonext_handle  

#vpop vm[x]
mov R,[ebp]
add ebp 4;lea ebp,[ebp84]
mov VM[X],R

;lvsp 类似mov ebp [ebp]操作
;vpushvsp

;vadd 表示vmstack[0],vmstack[+4] 值相加,结果保存在vmstack[+4],eflags保存在vmstack[+4]
#vadd
mov r,[ebp]
add [ebp+4],r
pushfq
pop [ebp]-->ebp+0 eflag,+4 addresult
;通常操作结束后,后面紧跟vpop vm[x],将eflags保存到vmcontext[y]中,后面vsp则指向了上面的结果


;vmov 类似pop r1;pop r2; mov [r1],r2
#vmov
mov eax,dword ptr ds:[ebp]   
mov edx,dword ptr ds:[ebp+4] 
add ebp,8                    
mov dword ptr ss:[eax],edx 

vm_stack_restore

Vpush vm[10h] 19FE08
Vpush vm[8] 41E029
Vpush vm[0] 288000
Vpush vm[1ch] 19FD30
Vpush vm[28h] 246
Vpush vm[30h] 1
Vpush vm[14h] 19FE08
Vpush vm[3ch] 41E029

vm_exit

vm_exit
0B83 | 004A40E7 | 8BE5                     | mov esp,ebp                       | esp: 19FC40-> 19FD08      |                                                   |
0B85 | 004A40EF | 58                       | pop eax                           | eax: 19FCA0-> 41E029 esp: | 0019FD08: 41E029-> 41E029                         |
0B87 | 0045CAF3 | 5D                       | pop ebp                           | esp: 19FD0C-> 19FD10 ebp: | 0019FD0C: 19FE08-> 19FE08                         |
0B89 | 0045CAF7 | 5A                       | pop edx                           | edx: 17001-> 1 esp: 19FD1 | 0019FD10: 1-> 1                                   |
0B8C | 0045CB00 | 9D                       | popfd                             | esp: 19FD14-> 19FD18      | 0019FD14: 246-> 246                               |
0B8D | 0045CB01 | 5E                       | pop esi                           | esp: 19FD18-> 19FD1C esi: | 0019FD18: 19FD30-> 19FD30                         |
0B8F | 00481248 | 5B                       | pop ebx                           | ebx: 48D200-> 288000 esp: | 0019FD1C: 288000-> 288000                         |
0B91 | 0048124B | 59                       | pop ecx                           | ecx: 559F253A-> 41E029 es | 0019FD20: 41E029-> 41E029                         |
0B94 | 00481253 | 5F                       | pop edi                           | esp: 19FD24-> 19FD28 edi: | 0019FD24: 19FE08-> 19FE08                         |
;ret  
ret                        

举例

_RTC_CheckEsp()

;jnz     short esperror
;retn
;vm_handle
vpop +20h ret   0048B6FE
vpop +34h key   vm_bliock 0F3ABA2D

vpushvsp  19FD2C
vpush imm4 4
vadd --> 19FD30  ==19FD2C+4   vsp+4
vpop vm[c]   eflag  216l
lvsp--mov ebp [ebp]to add_result—>ebp 19FD30

vpushvsp
vpush vm[1c] 19FD30
vpush vm[1c] 19FD30

not not and  [ebp+4]FFE602CF

vpop vm[28h]->eflag FFB3332F
[ebp]FFE602CF,[ebp+4] 19FD30
vadd    FFE602CF+ 19FD30== FFFFFFFF  [ebp]eflag 286
vpop vm[38h] 286

vpushvsp
lvsp  get FFFFFFFF
not not or   [ebp+0] eflag [ebp+4] 0

vpop vm[20] eflag 246
vpop vm[34h]

vpush vm[38] 286
vpush imm4 815
not not or  FFFFFFFB
vpop vm[28] 282

vpushvsp 19FD2C
lvsp ebp  FFFFFFFB

not not or ->4
vpop vm[2ch] 202
vpush vm[20h] 246
vpush imm4 FFFFF7EA
not not or FFFFFDBD  [ebp+4] eflag [ebp]

vpop vm[2ch] 286

vpushvsp 19FD28

lvsp    [19FD28] FFFFFDBD
	[ebp] FFFFFDBD [ebp+4] FFFFFDBD
not not or 242
	[ebp]eflag 206
Vpop vm[34h] 206
Vadd ->242+4= 246
Vpop vm[18h] 202
Vpop vm[28h] 246

一系列操作其实就是个jcc
最终得到结果246d->eflags->‭11110110‬
ZF=1
JNZ不满足,不跳转,ret

image


add(1,5c)

push key 6860C86B
push retaddr 42AE36
push ebx 288000
push edx 1
push eax 41E029
push ecx 41E029
push ebp 19FE08
push edi 19FE08
pushfd->eflag 246
push esi 19FD30
push ecx 0

;ebx->vm_key
;edi->vm_ins
;ebp->vip
;esi->vsp



vpop vm[2ch] 0
vpop vm[18h] 19FD30
vpop vm[[ch] 246
vpop vm[28h] 19FE08
vpop vm[14h] 19FE08
vpop vm[8] 41E029
vpop vm[10h] 41E029
vpop vm[0] 1
vpop vm[1ch] 288000
vpop vm[3c] 42AE36
vpop vm[30h] 6860C86B



vpush vm[14h] 19FE08->orig_ebp
vpush imm4 c
vadd ch+ 19FE08= 19FE14

vpop vm[4] 216  eflag
vpush vm[14h] 19FE08—orig_ebp
vpush imm4 8
vadd 8+ 19FE08h= 19FE10

vpop vm[30h] 212 eflag

lvsp  [19FE10]->1
vpop vm[3c] 1
lvsp  [9FE14]->5c
vpush vm[3c] 1
vadd 1+5c=5d
vpop vm[30h] 202 eflag
vpop vm[4] 5d

vpush vm[4] 5d
vpush vm[14] 19FE08
vpush imm4 FFFFFFF8
vadd FFFFFFF8+ 19FE08

vpop vm[24h] eflag 217
vmov—> [19FE00] 5d

vpushvsp 19FD30
vpop vm[38h] 19FD30

vpush imm4 411D5A
vpush vm[2c] 0
vadd 0+ 411D5A
vpop vm[c] 206
vpush vm[1c] 288000
vpush vm[0] 1
vpush vm[4] 5d
vpush vm[8] 41E029
vpush vm[14h] 19FE08
vpush vm[28h] 19FE08
vpush vm[30h] 202
vpush vm[38h] 19FD30

pop esi
pop eflags
pop edi
pop ebp
pop ecx
pop eax
pop edx
pop ebx
ret


参考链接

VMProtect 2 – Detailed Analysis of the Virtual Machine Architecture
VMProtect 3.3.1虚拟机&代码混淆机制入门
VMProtect 3.09 虚拟机架构浅析

原文地址:http://www.cnblogs.com/DirWang/p/16800955.html

1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长! 2. 分享目的仅供大家学习和交流,请务用于商业用途! 3. 如果你也有好源码或者教程,可以到用户中心发布,分享有积分奖励和额外收入! 4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解! 5. 如有链接无法下载、失效或广告,请联系管理员处理! 6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需! 7. 如遇到加密压缩包,默认解压密码为"gltf",如遇到无法解压的请联系管理员! 8. 因为资源和程序源码均为可复制品,所以不支持任何理由的退款兑现,请斟酌后支付下载 声明:如果标题没有注明"已测试"或者"测试可用"等字样的资源源码均未经过站长测试.特别注意没有标注的源码不保证任何可用性