VMProtect基础教程(二)伪指令汇总

2016-12-21 17:39    129人浏览    标签:,     0 条评论

虚拟机加密,是指像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。

0043DC0A命名:VM_MOVdw_EDISTACKdw_EBPSTACKdw

 

1
2
3
4
5
6
7
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

0043E7E6命名: VM_MOVw_EDISTACKw_EBPSTACKw

 

1
2
3
4
5
6
7
8
9
10
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

0043D374命名:VM_MOVb_EDISTACKb_EBPSTACKw

 

1
2
3
4
5
6
7
8
9
10
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

0043D21C命名:VM_PUSHw_IMMEDIATEw

 

1
2
3
4
5
6
7
8
9
10
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

0043E83F命名:VM_PUSHdw_IMMEDIATEdw

 

1
2
3
4
5
6
7
8
9
10
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

0043DB11命名:VM_PUSHdw_IMMEDIATEw

 

1
2
3
4
5
6
7
8
9
10
11
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

0043D978命名:VM_PUSHw_IMMEDIATEb

 

1
2
3
4
5
6
7
8
9
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

0043D3A5命名:VM_PUSHdw_IMMEDIATEb

 

1
2
3
4
5
6
7
8
9
10
11
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

0043CF24命名:VM_ADDdw_EBPSTACK

 

1
2
3
4
5
6
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标志存储在栈顶。

0043D43B命名:VM_PUSHdw_MEMORYdw

 

1
2
3
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

0043E9CA命名:VM_PUSHw_MEMORYw

 

1
2
3
4
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

0043D8BD命名:VM_PUSHw_MEMORYb

 

1
2
3
4
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

0043DC56命名:VM_PUSHw_EDISTACKw

 

1
2
3
4
5
6
7
8
9
10
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

0043CF81命名:VM_PUSHw_EDISTACKb

 

1
2
3
4
5
6
7
8
9
10
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

0043D72E命名:VM_PUSHdw_EBP

 

1
2
3
0043D72F  /.  89E8          MOV EAX,EBP                              ; *
0043E613  /$  83ED 04       SUB EBP,4                                ; *
0043E61C  |.  8945 00       MOV DWORD PTR SS:[EBP],EAX               ; *

功能:复制EBP指针到EBPSTACK栈顶

0043EABE命名:VM_COPYdw_EBPSTACK

 

1
2
3
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

0043E790命名:VM_COPYw_EBPSTACK

 

1
2
3
4
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移动到栈顶内存地址内

相关资讯

留言评论

发表评论

电子邮件地址不会被公开。 必填项已用*标注

慧都2016年终促销
系统推荐