原创|其它|编辑:郝浩|2012-11-07 17:30:10.000|阅读 1127 次
概述:虚拟机加密,是指像VMP这样的保护程序,它会把源程序的X86指令变成自定义的伪指令,等到执行的时候,VMP内置在保护程序中的VM就会启动,读取伪指令,然后解析执行。
# 慧都年终大促·界面/图表报表/文档/IDE等千款热门软控件火热促销中 >>
相关链接:
代码保护利器VMProtect在线订购315特惠,个人授权专享折扣立即购买>>
虚拟机加密,是指像VMP这样的保护程序,它会把源程序的X86指令变成自定义的伪指令,等到执行的时候,VMP内置在保护程序中的VM就会启动,读取伪指令,然后解析执行。VMP是一个堆栈虚拟机,它的一切操作都是基于堆栈传递的。在VMP中,每一个伪指令就是一个handler,VM中有一个核心的Dispatch部分,它通过读取程序的bytecode,然后在DispatchiTable里面定位到不同的handler中执行。绝大多数情况下,在一个handler中执行完成后,程序将回到Dispatch部分,然后到next handler中执行。
下面就将VM所需的伪指令一一罗列,为使伪指令表达清晰,首先介绍以下伪指令的命名方式:移动到EBPSTACK的数据使用PUSH指令,移动到EDISTACK的数据使用MOV指令。在VM中,对数据的操作包括byte和dword,而存储的方式是word和dword,当遇到byte和word交织在一起的时候,可以就把数据作为word操作来看。
以:VM_PUSHw_MEMORYb为例说明命名规则:伪指令的命名统一使用VM_开头;并接上直观的助记符PUSH;EBPSTACK是移动的目的地;MEMORY是移动的来源地;w代表word、b代表byte、dw代表dword;这条指令的表示:这是一条移动指令,把1个byte的数据从内存块移动到EBPSTACK,存储时是按照word来存储。在VMP的伪指令中包含有大量的花指令和junk code。
0043DC19 |. F6D8 NEG AL ; * 0043DC26 |. C0C8 07 ROR AL,7 ; * 0043DC34 |. 2C 20 SUB AL,20 ; * 0043DC41 |. 24 3C AND AL,3C ; * 0043E080 |$ 8B55 00 MOV EDX,DWORD PTR SS:[EBP] ; * 0043E086 |. 83C5 04 ADD EBP,4 ; * 0043D3D7 /> /891438 MOV DWORD PTR DS:[EDI+EAX],EDX
功能:把EBPSTACK栈顶1个dword的数据存储到EDISTACK
0043E7EC 0FB646 FF MOVZX EAX,BYTE PTR DS:[ESI-1] ; * 0043E7F6 28D8 SUB AL,BL ; * 0043E7FE C0C8 05 ROR AL,5 ; * 0043E80C F6D8 NEG AL ; * 0043E816 34 0E XOR AL,0E ; * 0043E822 28C3 SUB BL,AL ; * 0043E82E 66:8B55 00 MOV DX,WORD PTR SS:[EBP] ; * 0043E835 83C5 02 ADD EBP,2 ; * 0043F03F 4E DEC ESI ; * 0043F045 66:891438 MOV WORD PTR DS:[EDI+EAX],DX ; *
功能:把EBPSTACK栈顶1个word的数据存储到EDISTACK
0043D377 |. 8A46 FF MOV AL,BYTE PTR DS:[ESI-1] ; * 0043F148 /> \30D8 XOR AL,BL ; * 0043D460 |. FEC0 INC AL ; |* 0043D469 |. C0C8 07 ROR AL,7 ; |* 0043D473 |. FEC0 INC AL ; |* 0043D215 |. 30C3 XOR BL,AL ; * 0043EA9C |. 4E DEC ESI ; * 0043EAA0 |. 66:8B55 00 MOV DX,WORD PTR SS:[EBP] ; * 0043EAAC |. 83C5 02 ADD EBP,2 ; * 0043DBDA /> /881438 MOV BYTE PTR DS:[EDI+EAX],DL ; *
把EBPSTACK栈顶1个word的数据按照byte的方式存储到EDISTACK
0043D21F 66:8B46 FE MOV AX,WORD PTR DS:[ESI-2] ; * 0043D22D 86E0 XCHG AL,AH ; * 0043E01A 66:29D8 SUB AX,BX ; * 0043E022 66:05 71F2 ADD AX,0F271 ; * 0043E036 66:F7D8 NEG AX ; * 0043E03D 66:35 A61C XOR AX,1CA6 ; * 0043E054 66:29C3 SUB BX,AX ; * 0043E054 66:29C3 SUB BX,AX ; * 0043E976 8D76 FE LEA ESI,[ESI-2] ; * 0043D094 /66:8945 00 MOV WORD PTR SS:[EBP],AX
功能:从ESI数据中取得1个word的立即数压入EBPSTACK
0043E845 . 8B46 FC MOV EAX,DWORD PTR DS:[ESI-4] ; * 0043E84D . 0FC8 BSWAP EAX ; * 0043E852 . 01D8 ADD EAX,EBX ; * 0043E857 . C1C8 04 ROR EAX,4 ; * 0043D952 . 8D76 FC LEA ESI,[ESI-4] ; * 0043D956 . 2D E131FF38 SUB EAX,38FF31E1 ; * 0043D967 . C1C0 0A ROL EAX,0A ; |* 0043D96C . 01C3 ADD EBX,EAX ; |* 0043D970 . 83ED 04 SUB EBP,4 ; |* 0043D710 |$ 8945 00 MOV DWORD PTR SS:[EBP],EAX ; *
功能:从ESI数据中获得1个dword的立即数,压入EBPSTACK
0043DB1E 66:8B46 FE MOV AX,WORD PTR DS:[ESI-2] ; * 0043D171 /86E0 XCHG AL,AH ; * 0043E948 66:29D8 SUB AX,BX ; * 0043E951 66:05 71F2 ADD AX,0F271 ; * 0043E95C 66:F7D8 NEG AX ; * 0043E969 8D76 FE LEA ESI,[ESI-2] ; * 0043D62C 66:35 A61C XOR AX,1CA6 ; * 0043D640 \66:29C3 SUB BX,AX ; * 0043D648 98 CWDE ; * 0043D190 83ED 04 SUB EBP,4 ; * 0043D933 8945 00 MOV DWORD PTR SS:[EBP],EAX ; *
功能:从ESI数据中获得1个word的立即数,按照dword的方式压入EBPSTACK
0043D979 . 0FB646 FF MOVZX EAX,BYTE PTR DS:[ESI-1] ; * 0043D97E . 30D8 XOR AL,BL ; * 0043D1ED . FEC8 DEC AL ; * 0043D1F0 . F6D8 NEG AL ; * 0043D1F7 . F6D0 NOT AL ; * 0043D1FD . 30C3 XOR BL,AL ; * 0043CEE8 > /83ED 02 SUB EBP,2 ; * 0043DD79 |. 66:8945 00 MOV WORD PTR SS:[EBP],AX ; |* 0043DD62 /$ 4E DEC ESI ; *
功能:从ESI数据中获得1个byte的立即数,按照word的方式压入EBPSTACK
0043D3A7 0FB646 FF MOVZX EAX,BYTE PTR DS:[ESI-1] ; * 0043D3AC 30D8 XOR AL,BL ; * 0043D848 FEC8 DEC AL ; * 0043D855 F6D8 NEG AL ; * 0043D866 F6D0 NOT AL ; * 0043D86D 30C3 XOR BL,AL ; * 0043ED8C 66:98 CBW ; * 0043CF7B 98 CWDE ; * 0043EC00 8D76 FF LEA ESI,[ESI-1] ; * 0043DB94 83ED 04 SUB EBP,4 ; * 0043DB9F 8945 00 MOV DWORD PTR SS:[EBP],EAX ; *
功能:从ESI数据中获得1个byte的立即数,按照dword的方式压入EBPSTACK
0043CF2F |. 8B45 00 MOV EAX,DWORD PTR SS:[EBP] ; * 0043EED3 |. 0145 04 ADD DWORD PTR SS:[EBP+4],EAX ; * 0043CE4F |. 9C PUSHFD ; * 0043CE50 |. 8F4424 3C POP DWORD PTR SS:[ESP+3C] ; * 0043D1BF /> \FF7424 3C PUSH DWORD PTR SS:[ESP+3C] ; * 0043D1C3 |. 8F45 00 POP DWORD PTR SS:[EBP] ; *
功能:把EBPSTACK栈顶的2个dword数据相加,结果存储在[EBP+4],EFLAGS标志存储在栈顶。
0043D43F 8B45 00 MOV EAX,DWORD PTR SS:[EBP] ; * 0043D10A 8B00 MOV EAX,DWORD PTR DS:[EAX] ; * 0043D447 8945 00 MOV DWORD PTR SS:[EBP],EAX ; *
功能:把EBPSTACK栈顶数据作为内存地址,从中读取1个dword的数据压入EBPSTACK
0043E9D0 8B45 00 MOV EAX,DWORD PTR SS:[EBP] ; * 0043E9D9 83C5 02 ADD EBP,2 ; * 0043DEBB 66:36:8B00 MOV AX,WORD PTR SS:[EAX] ; * 0043DDC4 66:8945 00 MOV WORD PTR SS:[EBP],AX ; *
功能:把EBPSTACK栈顶数据作为内存地址,从中读取1个word的数据压入EBPSTACK
0043D57B |. 8B55 00 MOV EDX,DWORD PTR SS:[EBP] 0043D589 |. 83C5 02 ADD EBP,2 ; * 0043D591 |. 8A02 MOV AL,BYTE PTR DS:[EDX] ; * 0043E70B |. 66:8945 00 MOV WORD PTR SS:[EBP],AX ; *
功能:把EBPSTACK栈顶数据作为内存地址,从中读取1个byte的数据,按照word的方式压入EBPSTACK
0043DC5C 8A46 FF MOV AL,BYTE PTR DS:[ESI-1] ; * 0043DC66 28D8 SUB AL,BL ; * 0043DC6D C0C8 05 ROR AL,5 ; * 0043EADA 4E DEC ESI ; * 0043EE2E \F6D8 NEG AL ; * 0043EE34 34 0E XOR AL,0E ; * 0043E740 28C3 SUB BL,AL ; * 0043E746 66:8B0438 MOV AX,WORD PTR DS:[EDI+EAX] ; * 0043D9E4 83ED 02 SUB EBP,2 ; * 0043EE44 66:8945 00 MOV WORD PTR SS:[EBP],AX ; *
功能:从EDISTACK中读取1个word数据压入EBPSTACK
0043CF84 8A46 FF MOV AL,BYTE PTR DS:[ESI-1] ; * 0043CF8E 30D8 XOR AL,BL ; * 0043EE0A \FEC0 INC AL ; * 0043EE11 C0C8 07 ROR AL,7 ; * 0043EE1E FEC0 INC AL ; * 0043D59C 30C3 XOR BL,AL ; * 0043D2CE 4E DEC ESI ; * 0043D2D7 8A0438 MOV AL,BYTE PTR DS:[EDI+EAX] ; * 0043D2E6 83ED 02 SUB EBP,2 ; * 0043D075 66:8945 00 MOV WORD PTR SS:[EBP],AX ; *
功能:从EDISTACK中读取1个byte数据,按照word方式压入EBPSTACK
0043D72F /. 89E8 MOV EAX,EBP ; * 0043E613 /$ 83ED 04 SUB EBP,4 ; * 0043E61C |. 8945 00 MOV DWORD PTR SS:[EBP],EAX ; *
功能:复制EBP指针到EBPSTACK栈顶
0043EACC 8B45 00 MOV EAX,DWORD PTR SS:[EBP] ; * 0043DE1B 36:8B00 MOV EAX,DWORD PTR SS:[EAX] ; * 0043DE25 8945 00 MOV DWORD PTR SS:[EBP],EAX ; *
功能:把EBPSTACK栈顶数据作为堆栈地址,从中读取一个dword的数据压入EBPSTACK
0043E79C |. 8B55 00 MOV EDX,DWORD PTR SS:[EBP] ; * 0043E7A7 |. 83C5 02 ADD EBP,2 ; * 0043E7AE |. 36:8A02 MOV AL,BYTE PTR SS:[EDX] ; * 0043D01B |. 66:8945 00 MOV WORD PTR SS:[EBP],AX ; *
功能:把EBPSTACK栈顶数据作为堆栈地址,从中读取一个byte的数据,按照word的方式压入EBPSTACK
0043D770
EBPSTACK的byte逻辑右移指令
0043EAE0
VM_JMP跳转指令,重新给ESI赋值EBPSTACK栈顶数据
0043E199
复制EBPSTACK栈顶1个word的数据
0043DB00
把EBPSTACK栈顶数据作为地址,读取其中1个word的数据压入EBPSTACK
0043D82E
VM_DIV除法指令
0043ED1F
CPUID指令,结果压入EBPSTACK。
0043ECF6
把EBPSTACK数据1个byte移动到栈顶内存地址内
0043E770
给EBP寄存器的低word位赋值栈顶数据
0043D253
把SS段寄存器压入EBPSTACK栈顶
0043CDC9
另一种方式的word版NAND,不过这个是在EBPSTACK堆栈内完成运算过程
0043D2F5
EBPSTACK的byte逻辑左移指令
0043D6E7
EBPSTACK的word逻辑左移指令
0043DBAC
EBPSTACK的word逻辑右移指令
0043E06B
EBPSTACK的word加法
0043E8CD
把EAX和EDX压入EBPSTACK
0043E13C
把EBPSTACK数据1个word移动到栈顶内存地址内
本站文章除注明转载外,均为本站原创或翻译。欢迎任何形式的转载,但请务必注明出处、不得修改原文相关链接,如果存在内容上的异议请邮件反馈至chenjj@cahobeh.cn