飘云阁

 找回密码
 加入我们

QQ登录

只需一步,快速开始

查看: 11754|回复: 23

[原创] 谈谈vmp的还原(2)

[复制链接]
  • TA的每日心情
    擦汗
    2016-4-19 21:35
  • 签到天数: 3 天

    [LV.2]偶尔看看I

    发表于 2018-3-26 13:55:13 | 显示全部楼层 |阅读模式
    0x00 前言
    写之前就在想该以一个怎样的方式阐述这些东西,最终还是决定以逆推的方式来描述
    另外 先回答下问题 分析的是vmp的主程序,很早的版本

    0x01 虚拟化后

    测试的指令

    1. 68 34504200      PUSH OFFSET zf.??_C@_02MECO@?$CFd?$AA@   ; /format = "%d"
    2. E8 13010000      CALL zf.scanf                            ; \scanf
    3. 83C4 08          ADD ESP,0x8
    4. 817D FC 33020000 CMP DWORD PTR SS:[EBP-0x4],0x233
    5. 75 09            JNZ SHORT zf.00401062
    复制代码

    被用来vm的两条指令:

    1. 817DFC33020000          cmp dword ptr [ebp-04],00000233
    2. 7509                    jnz 00401062
    复制代码

    先看看是cmp被vm之后的情况,因为既然大S提到了这个,看了他的帖子,所以叫他大S


    1. 1.lodsd -0x233
    2.   push -0x233
    3.    
    4. stack_top   fffffdcd
    5.    
    6. 2.lodsb [index]
    7.   push _context[index] <===> push ebp
    8.    
    9. stack_top   ebp
    10.         fffffdcd

    11. 3.lodsb [disp]
    12.   push disp
    13.    
    14. stack_top   disp
    15.         ebp
    16.         fffffdcd

    17. 4.pop disp
    18.   add ebp,dis <===> get addr input

    19. stack_top   ebp+disp
    20.         fffffdcd
    21.      
    22. 5.pop addr (input)
    23.   push input

    24. stack_top   input
    25.         fffffdcd

    26. 6.pop input
    27.   add [-0x233],input ... get a
    28.      
    29. stack_top   fffffe48
    30.    
    31.   pushfw
    32.      
    33. stack_top   fe480296

    34. 7.push eflags
    35. stack_top    02960216
    36.              00fffffe48

    37. 8.push stack
    38. stack_top   ebp
    39.         02960216
    40.         fffffe48

    41. 9.pop stack
    42.   push [stack]
    43.    
    44. stack_top   02160216
    45.         fe480296

    46. 10.and(not(eflags),not(eflags))
    47. stack_top   fde9fde9

    48. stack_top   0296fde9
    49.         fffffe48

    50. 11.lodsw ~0x400
    51.     push ~0x400
    52.      
    53. stack_top   FDE9FBFF
    54.         FE480296
    55.      
    56. 11.and(not(eflags),not(~0x400)) = and(eflags,0x400)
    57. stack_top   02160400

    58. stack_top   02960000
    59.         fffffe48

    60. 12.pop result
    61.    add [pushfw],result
    62.      
    63. stack_top   fe480296 <==> 0296+result
    64.      
    65. 13.lodsb [index]
    66.    pop _context[index]

    67. _context[index] == 0296
    68. stack_top   fffffe48

    69. 14.pop a

    70. eax == a <==> fffffe48
    71. stack_top ebp

    72. 15.push lodsw[esi]
    73.    push 0x11
    74.      
    75. stack_top   FF48FFEE
    76.             0018

    77. 16.push [pushfw]
    78. stack_top   FFEE0296
    79.             0018FF48
    80. 17.push [pushfw]
    81. stack_top   02960296
    82.         FF48FFEE
    83.         00000018

    84. 18.and(not(pushfw),not(pushfw))
    85. stack_top   FD69FD69
    86.         FF48FFEE
    87.         00000018
    88.             
    89. stack_top   FFEEFD69
    90.         0018FF48

    91. 19.and(0x11,pushfw)
    92. stack_top   FF480010 <==> and(0x11,0x269)
    93.                 0018


    94. 20.push pushfw
    95. stack_top   00100296
    96.         0018FF48

    97. 21.lodb push 0x11
    98. stack_top    02960011
    99.              FF480010
    100.                  0018


    101. 22.and(not(pushfw),not(0x11))
    102. stack_top       0010FD68
    103.         0018FF48

    104. 23.and(not(result),not(0x11))
    105. stack_top       FF480287
    106.             0018

    107. 24.lodb [index]
    108.    push _context[index] <===> push [pushfw]
    109.      
    110. stack_top       02870296
    111.         0018FF48
    112.             
    113. 24.lodb [index]
    114.    push _context[index] <===> push [pushfw]
    115.      
    116. stack_top       02960296
    117.         FF480287
    118.             0018

    119. 25.and(296,296)

    120. stack_top       0287FD69
    121.         0018FF48

    122. 26.lodw ~0x400
    123.     push ~0x400
    124.      
    125. stack_top       FD69FBFF
    126.                 FF480287
    127.         0018
    128.                  
    129. 27.and(0x400,0x296)

    130. stack_top   02870000
    131.         0018FF48

    132. 28.pop result
    133.    add [esp],result
    134.    
    135. stack_top   FF480287
    136.         00000018
    137.               
    138. 29.lodsb [index]
    139.      pop _context[index] <==> result save to context
    140.      
    141. stack_top   0018FF48

    142. 28.lodsb [index]
    143.      push _context[index]
    144.    
    145. stack_top   00000000
    146.                 0018FF48
    复制代码

    以上就是cmp的vm流程

    hex如下

    1. 0042FB21  6C CD FD CF 05 38 FC 69
    2. 0042FB29  C4 C1 B6 08 0C 8E 99 57
    3. 0042FB31  FF FB 99 3B 5D 08 08 57
    4. 0042FB39  EE FF B6 08 FA 08 99 99
    5. 0042FB41  E9 08 A0 11 99 99 B6 08
    6. 0042FB49  B6 08 99 57 FF FB 99 3B
    7. 0042FB51  5D 08 18 0C
    复制代码


    0x10 原由

    那么我们先来看看是如何得到这些hex
    1.png

    代码很简单
    匹配就行了,那么我们来看看匹配表,注意到上一篇的handle_size == 1488 / 8
    2.png

    恩,vmp实现虚拟引擎的核心可以说就是这些虚拟规则。注意到我是用的这些,而不是186个,因为在写之前,我担心版本太老,所以又去逆了逆v2.12.3,发现框架太体差不多,不过代码量优化了很多。还有昨天看了看大Z哥的帖子,对里面有句话感触很深(它们的价值来自于本身的神秘面纱)。但毕竟吧,vmp也3.x,代码重构了,我想也可以谈一谈了。扯远了。
    查看引用表的地方
    3.png

    在看看RandIndexArray的引用,来到这个地方
    4.png

    注意到这里可能是乱序之后的,那么如果说不乱序的话,这个表和vm_opcode的应该是一一对应的关系
    举例:
    5.png

    定位到handler_table,
    则有

    1. Handle_471094:
    2. LODS BYTE PTR DS:[ESI]
    3. PUSH DWORD PTR DS:[EDI+EAX*4]
    4. 对应
    5. 01 02 02 00 00 00 00 00
    复制代码


    如下:


    1. struct _vmp_esi_table _esi_table[] = {
    2.     {0x1,0x2,0x2,0x0,0x0,0x0,0x0,0x0,"LODS BYTE PTR DS:[ESI] PUSH DWORD PTR DS:[EDI+EAX*4]" }
    3.     ,{0x1,0x1,0x2,0x0,0x0,0x0,0x0,0x0,"LODS DWORD PTR DS:[ESI] PUSH EAX" }
    4.     ,{0x1,0x2,0x2,0x0,0x1,0x0,0x0,0x0,"PUSH ESP" }
    5.     ,{0x1,0x3,0x2,0x0,0x0,0x0,0x0,0x0,"POP EAX PUSH DWORD PTR ES:[EAX]" }
    6.     ,{0x1,0x3,0x2,0x0,0x1,0x0,0x0,0x0,"POP EAX PUSH DWORD PTR CS:[EAX]" }
    7.     ,{0x1,0x3,0x2,0x0,0x2,0x0,0x0,0x0,"POP EAX PUSH DWORD PTR SS:[EAX]" }
    8.     ,{0x1,0x3,0x2,0x0,0x3,0x0,0x0,0x0,"POP EAX PUSH DWORD PTR DS:[EAX]" }
    9.     ,{0x1,0x3,0x2,0x0,0x4,0x0,0x0,0x0,"POP EAX PUSH DWORD PTR FS:[EAX]" }
    10.     ,{0x1,0x3,0x2,0x0,0x5,0x0,0x0,0x0,"POP EAX PUSH DWORD PTR GS:[EAX]" }
    11.     ,{0x1,0x2,0x1,0x0,0x0,0x0,0x0,0x0,"LODS BYTE PTR DS:[ESI] PUSH WORD PTR DS:[EDI+EAX*4]" }
    12.     ,{0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,"LODS WORD PTR DS:[ESI] ADD AX,BX ADD BX,AX PUSH AX"}
    13.     ,{0x1,0x1,0x1,0x0,0x1,0x0,0x0,0x0,"LODS WORD PTR DS:[ESI] ADD AX,BX ADD BX,AX CWDE PUSH EAX"}
    14.     ,{0x1,0x3,0x1,0x0,0x0,0x0,0x0,0x0,"POP EDX PUSH WORD PTR ES:[EDX]" }
    15.     ,{0x1,0x3,0x1,0x0,0x1,0x0,0x0,0x0,"POP EDX PUSH WORD PTR CS:[EDX]" }
    16.     ,{0x1,0x3,0x1,0x0,0x2,0x0,0x0,0x0,"POP EDX PUSH WORD PTR SS:[EDX]" }
    17.     ,{0x1,0x3,0x1,0x0,0x3,0x0,0x0,0x0,"POP EDX PUSH WORD PTR DS:[EDX]" }
    18.     ,{0x1,0x3,0x1,0x0,0x4,0x0,0x0,0x0,"POP EDX PUSH WORD PTR FS:[EDX]" }
    19.     ,{0x1,0x3,0x1,0x0,0x5,0x0,0x0,0x0,"POP EDX PUSH WORD PTR GS:[EDX]" }
    20.     ,{0x1,0x2,0x0,0x0,0x0,0x0,0x0,0x0,"LODS BYTE PTR DS:[ESI] ADD AL,BL ADD BL,AL MOV AL,BYTE PTR DS:[EDI+EAX*4] PUSH AX"}
    21.     ,{0x1,0x2,0x0,0x0,0x1,0x0,0x0,0x0,"LODS BYTE PTR DS:[ESI] ADD AL,BL ADD BL,AL MOV AL,BYTE PTR DS:[EDI+EAX*4+0x1] PUSH AX"}
    22.     ,{0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,"LODS BYTE PTR DS:[ESI] ADD AL,BL ADD BL,AL PUSH AX"}
    23.     ,{0x1,0x1,0x0,0x0,0x1,0x0,0x0,0x0,"LODS BYTE PTR DS:[ESI] ADD AL,BL ADD BL,AL CBW CWDE PUSH EAX"}
    24.     ,{0x1,0x3,0x0,0x0,0x0,0x0,0x0,0x0,"POP EAX MOV AL,BYTE PTR ES:[EDX] PUSH AX"}
    25.     ,{0x1,0x3,0x0,0x0,0x1,0x0,0x0,0x0,"POP EAX MOV AL,BYTE PTR CS:[EDX] PUSH AX"}
    26.     ,{0x1,0x3,0x0,0x0,0x2,0x0,0x0,0x0,"POP EAX MOV AL,BYTE PTR SS:[EDX] PUSH AX"}
    27.     ,{0x1,0x3,0x0,0x0,0x3,0x0,0x0,0x0,"POP EAX MOV AL,BYTE PTR DS:[EDX] PUSH AX"}
    28.     ,{0x1,0x3,0x0,0x0,0x4,0x0,0x0,0x0,"POP EAX MOV AL,BYTE PTR FS:[EDX] PUSH AX"}
    29.     ,{0x1,0x3,0x0,0x0,0x5,0x0,0x0,0x0,"POP EAX MOV AL,BYTE PTR GS:[EDX] PUSH AX"}
    30.     ,{0x1,0x5,0x1,0x0,0x0,0x0,0x0,0x0,"PUSH ES" }
    31.     ,{0x1,0x5,0x1,0x0,0x1,0x0,0x0,0x0,"PUSH CS" }
    32.     ,{0x1,0x5,0x1,0x0,0x2,0x0,0x0,0x0,"PUSH SS" }
    33.     ,{0x1,0x5,0x1,0x0,0x3,0x0,0x0,0x0,"PUSH DS" }
    34.     ,{0x1,0x5,0x1,0x0,0x4,0x0,0x0,0x0,"PUSH FS" }
    35.     ,{0x1,0x5,0x1,0x0,0x5,0x0,0x0,0x0,"PUSH GS" }
    36.     ,{0x1,0x2,0x1,0x0,0x1,0x0,0x0,0x0,"PUSH SP" }
    37.     ,{0x2,0x2,0x2,0x0,0x0,0x0,0x0,0x0,"LODS BYTE PTR DS:[ESI] ADD AL,BL ADD BL,AL POP DWORD PTR DS:[EDI+EAX*4]"}
    38.     ,{0x2,0x1,0x2,0x0,0x0,0x0,0x0,0x0,"POP EAX"}
    39.     ,{0x2,0x2,0x2,0x0,0x1,0x0,0x0,0x0,"POP ESP"}
    40.     ,{0x2,0x3,0x2,0x0,0x0,0x0,0x0,0x0,"POP EAX POP DWORD PTR ES:[EAX]"}
    41.     ,{0x2,0x3,0x2,0x0,0x1,0x0,0x0,0x0,"POP EAX POP DWORD PTR CS:[EAX]"}
    42.     ,{0x2,0x3,0x2,0x0,0x2,0x0,0x0,0x0,"POP EAX POP DWORD PTR SS:[EAX]" }
    43.     ,{0x2,0x3,0x2,0x0,0x3,0x0,0x0,0x0,"POP EAX POP DWORD PTR DS:[EAX]" }
    44.     ,{0x2,0x3,0x2,0x0,0x4,0x0,0x0,0x0,"POP EAX POP DWORD PTR FS:[EAX]" }
    45.     ,{0x2,0x3,0x2,0x0,0x5,0x0,0x0,0x0,"POP EAX POP DWORD PTR GS:[EAX]" }
    46.     ,{0x2,0x2,0x1,0x0,0x0,0x0,0x0,0x0,"LODS BYTE PTR DS:[ESI] POP WORD PTR DS:[EDI+EAX*4]" }
    47.     ,{0x2,0x1,0x1,0x0,0x0,0x0,0x0,0x0,"POP AX" }
    48.     ,{0x2,0x3,0x1,0x0,0x0,0x0,0x0,0x0,"POP EAX POP WORD PTR ES:[EAX]" }
    49.     ,{0x2,0x3,0x1,0x0,0x1,0x0,0x0,0x0,"POP EAX POP WORD PTR CS:[EAX]" }
    50.     ,{0x2,0x3,0x1,0x0,0x2,0x0,0x0,0x0,"POP EAX POP WORD PTR SS:[EAX]" }
    51.     ,{0x2,0x3,0x1,0x0,0x3,0x0,0x0,0x0,"POP EAX POP WORD PTR DS:[EAX]" }
    52.     ,{0x2,0x3,0x1,0x0,0x4,0x0,0x0,0x0,"POP EAX POP WORD PTR FS:[EAX]" }
    53.     ,{0x2,0x3,0x1,0x0,0x5,0x0,0x0,0x0,"POP EAX POP WORD PTR GS:[EAX]" }
    54.     ,{0x2,0x2,0x0,0x0,0x0,0x0,0x0,0x0,"POP DX LODS BYTE PTR DS:[ESI] ADD AL,BL ADD BL,AL MOV BYTE PTR DS:[EDI+EAX*4],DL"}
    55.     ,{0x2,0x2,0x0,0x0,0x1,0x0,0x0,0x0,"POP DX LODS BYTE PTR DS:[ESI] ADD AL,BL ADD BL,AL MOV BYTE PTR DS:[EDI+EAX*4+1],DL"}
    56.     ,{0x1,0x6,0x2,0x0,0x0,0x0,0x0,0x0,"MOV EAX,CR0 PUSH EAX"}
    57.     ,{0x1,0x6,0x2,0x0,0x1,0x0,0x0,0x0,"MOV EAX,CR1 PUSH EAX"}
    58.     ,{0x1,0x6,0x2,0x0,0x2,0x0,0x0,0x0,"MOV EAX,CR2 PUSH EAX"}
    59.     ,{0x1,0x6,0x2,0x0,0x3,0x0,0x0,0x0,"MOV EAX,CR3 PUSH EAX"}
    60.     ,{0x1,0x6,0x2,0x0,0x4,0x0,0x0,0x0,"MOV EAX,CR4 PUSH EAX"}
    61.     ,{0x1,0x6,0x2,0x0,0x5,0x0,0x0,0x0,"MOV EAX,CR5 PUSH EAX"}
    62.     ,{0x1,0x6,0x2,0x0,0x6,0x0,0x0,0x0,"MOV EAX,CR6 PUSH EAX"}
    63.     ,{0x1,0x6,0x2,0x0,0x7,0x0,0x0,0x0,"MOV EAX,CR7 PUSH EAX"}
    64.     ,{0x2,0x6,0x2,0x0,0x0,0x0,0x0,0x0,"POP EAX MOV CR0,EAX"}
    65.     ,{0x2,0x6,0x2,0x0,0x1,0x0,0x0,0x0,"POP EAX MOV CR1,EAX"}
    66.     ,{0x2,0x6,0x2,0x0,0x2,0x0,0x0,0x0,"POP EAX MOV CR2,EAX"}
    67.     ,{0x2,0x6,0x2,0x0,0x3,0x0,0x0,0x0,"POP EAX MOV CR3,EAX"}
    68.     ,{0x2,0x6,0x2,0x0,0x4,0x0,0x0,0x0,"POP EAX MOV CR4,EAX"}
    69.     ,{0x2,0x6,0x2,0x0,0x5,0x0,0x0,0x0,"POP EAX MOV CR5,EAX"}
    70.     ,{0x2,0x6,0x2,0x0,0x6,0x0,0x0,0x0,"POP EAX MOV CR6,EAX"}
    71.     ,{0x2,0x6,0x2,0x0,0x7,0x0,0x0,0x0,"POP EAX MOV CR7,EAX"}
    72.     ,{0x1,0x7,0x2,0x0,0x0,0x0,0x0,0x0,"MOV EAX,DR0 PUSH EAX"}
    73.     ,{0x1,0x7,0x2,0x0,0x1,0x0,0x0,0x0,"MOV EAX,DR1 PUSH EAX"}
    74.     ,{0x1,0x7,0x2,0x0,0x2,0x0,0x0,0x0,"MOV EAX,DR2 PUSH EAX"}
    75.     ,{0x1,0x7,0x2,0x0,0x3,0x0,0x0,0x0,"MOV EAX,DR3 PUSH EAX"}
    76.     ,{0x1,0x7,0x2,0x0,0x4,0x0,0x0,0x0,"MOV EAX,DR4 PUSH EAX"}
    77.     ,{0x1,0x7,0x2,0x0,0x5,0x0,0x0,0x0,"MOV EAX,DR5 PUSH EAX"}
    78.     ,{0x1,0x7,0x2,0x0,0x6,0x0,0x0,0x0,"MOV EAX,DR6 PUSH EAX"}
    79.     ,{0x1,0x7,0x2,0x0,0x7,0x0,0x0,0x0,"MOV EAX,DR7 PUSH EAX"}
    80.     ,{0x2,0x7,0x2,0x0,0x0,0x0,0x0,0x0,"POP EAX MOV DR0,EAX"}
    81.     ,{0x2,0x7,0x2,0x0,0x1,0x0,0x0,0x0,"POP EAX MOV DR1,EAX"}
    82.     ,{0x2,0x7,0x2,0x0,0x2,0x0,0x0,0x0,"POP EAX MOV DR2,EAX"}
    83.     ,{0x2,0x7,0x2,0x0,0x3,0x0,0x0,0x0,"POP EAX MOV DR3,EAX"}
    84.     ,{0x2,0x7,0x2,0x0,0x4,0x0,0x0,0x0,"POP EAX MOV DR4,EAX"}
    85.     ,{0x2,0x7,0x2,0x0,0x5,0x0,0x0,0x0,"POP EAX MOV DR5,EAX"}
    86.     ,{0x2,0x7,0x2,0x0,0x6,0x0,0x0,0x0,"POP EAX MOV DR6,EAX"}
    87.     ,{0x2,0x7,0x2,0x0,0x7,0x0,0x0,0x0,"POP EAX MOV DR7,EAX"}
    88.     ,{0x2,0x1,0x0,0x0,0x0,0x0,0x0,0x0,"POP AX" }
    89.     ,{0x2,0x3,0x0,0x0,0x0,0x0,0x0,0x0,"POP EAX POP AX MOV BYTE PTR ES:[EDX],AL"}
    90.     ,{0x2,0x3,0x0,0x0,0x1,0x0,0x0,0x0,"POP EDX POP AX MOV BYTE PTR CS:[EDX],AL"}
    91.     ,{0x2,0x3,0x0,0x0,0x2,0x0,0x0,0x0,"POP EDX POP AX MOV BYTE PTR SS:[EDX],AL"}
    92.     ,{0x2,0x3,0x0,0x0,0x3,0x0,0x0,0x0,"POP EDX POP AX MOV BYTE PTR DS:[EDX],AL"}
    93.     ,{0x2,0x3,0x0,0x0,0x4,0x0,0x0,0x0,"POP EDX POP AX MOV BYTE PTR FS:[EDX],AL"}
    94.     ,{0x2,0x3,0x0,0x0,0x5,0x0,0x0,0x0,"POP EDX POP AX MOV BYTE PTR GS:[EDX],AL"}
    95.     ,{0x2,0x5,0x1,0x0,0x0,0x0,0x0,0x0,"POP ES" }
    96.     ,{0x2,0x5,0x1,0x0,0x2,0x0,0x0,0x0,"POP SS" }
    97.     ,{0x2,0x5,0x1,0x0,0x3,0x0,0x0,0x0,"POP DS" }
    98.     ,{0x2,0x5,0x1,0x0,0x4,0x0,0x0,0x0,"POP FS" }
    99.     ,{0x2,0x5,0x1,0x0,0x5,0x0,0x0,0x0,"POP GS" }
    100.     ,{0x2,0x2,0x1,0x0,0x1,0x0,0x0,0x0,"POP SP" }
    101.     ,{0x4,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"POP EAX ADD DWORD PTR SS:[ESP],EAX"}
    102.     ,{0x4,0x0,0x2,0x0,0x1,0x0,0x0,0x0,"POP EAX ADD DWORD PTR SS:[ESP],EAX PUSHFW"}
    103.     ,{0x4,0x0,0x1,0x0,0x0,0x0,0x0,0x0,"POP AX ADD DWORD PTR SS:[ESP],AX" }
    104.     ,{0x4,0x0,0x1,0x0,0x1,0x0,0x0,0x0,"POP AX ADD DWORD PTR SS:[ESP],AX PUSHFW" }
    105.     ,{0x4,0x0,0x0,0x0,0x0,0x0,0x0,0x0,"POP AX ADD BYTE PTR SS:[ESP],AL" }
    106.     ,{0x4,0x0,0x0,0x0,0x1,0x0,0x0,0x0,"POP AX ADD BYTE PTR SS:[ESP],AL PUSHFW" }
    107.     ,{0xF6,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"POP EAX NOT EAX NOT DWORD PTR SS:[ESP] AND DWORD PTR SS:[ESP],EAX"}
    108.     ,{0xF6,0x0,0x2,0x0,0x1,0x0,0x0,0x0,"POP EAX NOT EAX NOT DWORD PTR SS:[ESP] AND DWORD PTR SS:[ESP],EAX PUSHFW"}
    109.     ,{0xF6,0x0,0x1,0x0,0x0,0x0,0x0,0x0,"NOT DWORD PTR SS:[ESP] POP AX AND WORD PTR SS:[ESP],AX" }
    110.     ,{0xF6,0x0,0x1,0x0,0x1,0x0,0x0,0x0,"NOT DWORD PTR SS:[ESP] POP AX AND WORD PTR SS:[ESP],AX PUSHFW" }
    111.     ,{0xF6,0x0,0x0,0x0,0x0,0x0,0x0,0x0,"POP AX POP CX NOT AL NOT CL AND AL,CL PUSH AX"}
    112.     ,{0xF6,0x0,0x0,0x0,0x1,0x0,0x0,0x0,"POP AX POP CX NOT AL NOT CL AND AL,CL PUSH AX PUSHFW"}
    113.     ,{0x1C,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"POP EAX POP CX SHL EAX,CL PUSH EAX"}
    114.     ,{0x1C,0x0,0x2,0x0,0x1,0x0,0x0,0x0,"POP EAX POP CX SHL EAX,CL PUSH EAX PUSHFW"}
    115.     ,{0x1C,0x0,0x1,0x0,0x0,0x0,0x0,0x0,"POP AX POP CX SHL AX,CL PUSH AX"}
    116.     ,{0x1C,0x0,0x1,0x0,0x1,0x0,0x0,0x0,"POP AX POP CX SHL AX,CL PUSH AX PUSHFW"}
    117.     ,{0x1C,0x0,0x0,0x0,0x0,0x0,0x0,0x0,"POP AX POP CX SHL AL,CL PUSH AX"}
    118.     ,{0x1C,0x0,0x0,0x0,0x1,0x0,0x0,0x0,"POP AX POP CX SHL AL,CL PUSH AX PUSHFW"}
    119.     ,{0x1D,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"POP EAX POP CX SHR EAX,CL PUSH EAX"}
    120.     ,{0x1D,0x0,0x2,0x0,0x1,0x0,0x0,0x0,"POP EAX POP CX SHR EAX,CL PUSH EAX PUSHFW"}
    121.     ,{0x1D,0x0,0x1,0x0,0x0,0x0,0x0,0x0,"POP AX POP CX SHR AX,CL PUSH AX"}
    122.     ,{0x1D,0x0,0x1,0x0,0x1,0x0,0x0,0x0,"POP AX POP CX SHR AX,CL PUSH AX PUSHFW"}
    123.     ,{0x1D,0x0,0x0,0x0,0x0,0x0,0x0,0x0,"POP AX POP CX SHR AL,CL PUSH AX"}
    124.     ,{0x1D,0x0,0x0,0x0,0x1,0x0,0x0,0x0,"POP AX POP CX SHR AL,CL PUSH AX PUSHFW"}
    125.     ,{0xF8,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"POP EAX POPAD POPFD RETN"}
    126.     ,{0x3D,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"POP EDX POP EAX POP ECX DIV ECX PUSH EAX PUSH EDX"}
    127.     ,{0x3D,0x0,0x1,0x0,0x0,0x0,0x0,0x0,"POP DX POP AX POP CX DIV CX PUSH AX PUSH DX" }
    128.     ,{0x3D,0x0,0x0,0x0,0x0,0x0,0x0,0x0,"POP AX POP CX DIV CL PUSH AX" }
    129.     ,{0x3F,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"POP EDX POP EAX POP ECX IDIV ECX PUSH EAX"}
    130.     ,{0x3F,0x0,0x1,0x0,0x0,0x0,0x0,0x0,"POP DX POP AX POP CX IDIV CX PUSH AX PUSH DX" }
    131.     ,{0x3F,0x0,0x0,0x0,0x0,0x0,0x0,0x0,"POP AX POP CX IDIV CL PUSH AX" }
    132.     ,{0x40,0x0,0x2,0x0,0x1,0x0,0x0,0x0,"POP EDX POP EAX MUL EDX PUSH EAX PUSH EDX PUSHFW" }
    133.     ,{0x40,0x0,0x1,0x0,0x1,0x0,0x0,0x0,"POP DX POP AX MUL EX PUSH AX PUSH DX PUSHFW" }
    134.     ,{0x40,0x0,0x0,0x0,0x1,0x0,0x0,0x0,"POP DX POP AX MUL DL PUSH AX PUSHFW" }
    135.     ,{0x3E,0x0,0x2,0x0,0x1,0x0,0x0,0x0,"POP EDX POP EAX IMUL EDX PUSH EAX PUSH EDX PUSHFW" }
    136.     ,{0x3E,0x0,0x1,0x0,0x1,0x0,0x0,0x0,"POP DX POP AX IMUL DX PUSH AX PUSH DX PUSHFW" }
    137.     ,{0x3E,0x0,0x0,0x0,0x1,0x0,0x0,0x0,"POP DX POP AX IMUL DL PUSH AX PUSHFW"}
    138.     ,{0x1C,0x0,0x3,0x0,0x1,0x0,0x0,0x0,"POP EAX POP EDX POP CX SHLD EAX,EDX,CL PUSH EAX PUSHFW"}
    139.     ,{0x1D,0x0,0x3,0x0,0x1,0x0,0x0,0x0,"POP EAX POP EDX POP CX SHRD EAX,EDX,CL POUSH EAX PUSHFW"}
    140.     ,{0xF7,0x0,0x2,0x0,0x1,0x0,0x0,0x0,"POP EAX POPAD POPFD RETF" }
    141.     ,{0x2E,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"WAIT" }
    142.     ,{0xB6,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"FILD DWORD PTR SS:[ESP]" }
    143.     ,{0xB6,0x0,0x3,0x0,0x0,0x0,0x0,0x0,"FILD QWORD PTR SS:[ESP]" }
    144.     ,{0xBB,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"FLD DWORD PTR SS:[ESP]" }
    145.     ,{0xBB,0x0,0x3,0x0,0x0,0x0,0x0,0x0,"FLD QWORD PTR SS:[ESP]" }
    146.     ,{0xBB,0x0,0x4,0x0,0x0,0x0,0x0,0x0,"FLD TBYTE PTR SS:[ESP]" }
    147.     ,{0xA0,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"FADD DWORD PTR SS:[ESP]" }
    148.     ,{0xA0,0x0,0x3,0x0,0x0,0x0,0x0,0x0,"FADD QWORD PTR SS:[ESP]" }
    149.     ,{0xA4,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"FSUB DWORD PTR SS:[ESP]" }
    150.     ,{0xA4,0x0,0x3,0x0,0x0,0x0,0x0,0x0,"FSUB QWORD PTR SS:[ESP]" }
    151.     ,{0xA5,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"FSUBR DWORD PTR SS:[ESP]" }
    152.     ,{0xA5,0x0,0x3,0x0,0x0,0x0,0x0,0x0,"FSUBR QWORD PTR SS:[ESP]" }
    153.     ,{0xBC,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"FSTP DWORD PTR SS:[ESP]" }
    154.     ,{0xBC,0x0,0x3,0x0,0x0,0x0,0x0,0x0,"FSTP QWORD PTR SS:[ESP]" }
    155.     ,{0xBC,0x0,0x4,0x0,0x0,0x0,0x0,0x0,"FSTP TBYTE PTR SS:[ESP]" }
    156.     ,{0xA6,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"FDIV DWORD PTR SS:[ESP]" }
    157.     ,{0xA6,0x0,0x3,0x0,0x0,0x0,0x0,0x0,"FDIV QWORD PTR SS:[ESP]" }
    158.     ,{0xA1,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"FMUL DWORD PTR SS:[ESP]" }
    159.     ,{0xA1,0x0,0x3,0x0,0x0,0x0,0x0,0x0,"FMUL QWORD PTR SS:[ESP]" }
    160.     ,{0xA3,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"FCOMP DWORD PTR SS:[ESP]" }
    161.     ,{0xA3,0x0,0x3,0x0,0x0,0x0,0x0,0x0,"FCOMP QWORD PTR SS:[ESP]" }
    162.     ,{0xC8,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"FCHS" }
    163.     ,{0xDB,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"FSQRT" }
    164.     ,{0xEE,0x0,0x1,0x0,0x0,0x0,0x0,0x0,"FSTSW AX PUSH AX" }
    165.     ,{0xC6,0x0,0x1,0x0,0x0,0x0,0x0,0x0,"FSTCW WORD PTR SS:[ESP]" }
    166.     ,{0xC4,0x0,0x1,0x0,0x0,0x0,0x0,0x0,"FLDCW WORD PTR SS:[ESP]" }
    167.     ,{0xE3,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"F2XM1" }
    168.     ,{0xC9,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"FABS" }
    169.     ,{0xE6,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"FCLEX" }
    170.     ,{0xE0,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"FCOS" }
    171.     ,{0xD7,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"FDECSTP" }
    172.     ,{0xD8,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"FINCSTP" }
    173.     ,{0xE5,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"FINIT" }
    174.     ,{0xD0,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"FLDLN2" }
    175.     ,{0xCF,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"FLDLG2" }
    176.     ,{0xD9,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"FPREM" }
    177.     ,{0xD6,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"FPREM1" }
    178.     ,{0xD3,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"FPTAN" }
    179.     ,{0xDD,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"FRNDINT" }
    180.     ,{0xDF,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"FSIN" }
    181.     ,{0xE1,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"FTST" }
    182.     ,{0xD2,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"FYL2X" }
    183.     ,{0xD4,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"FPATAN" }
    184.     ,{0xD1,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"FLDZ" }
    185.     ,{0xB8,0x0,0x1,0x0,0x0,0x0,0x0,0x0,"FISTP WORD PTR SS:[ESP]" }
    186.     ,{0xB8,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"FISTP DWORD PTR SS:[ESP]" }
    187.     ,{0xB8,0x0,0x3,0x0,0x0,0x0,0x0,0x0,"FISTP QWORD PTR SS:[ESP]" }
    188. };
    复制代码


    Btw:不保证全对哈,最好看看,哈哈
    接着我们看一看Vmp_GetVmHandleIndex的调用
    6.png

    ida的有点乱,把这个函数整理之后

    1. void _func_101()
    2. {
    3.     _vmp_setIndexToStruct( esi, _vmp_getVmHandlerIndex( esi->_var1_vm_mnemonic, 0, esi->_var3_lval, (esi->ispushfw) != 0);
    4. }

    5. void _func_104()
    6. {
    7.     _vmp_setIndexToStruct( esi, _vmp_getVmHandlerIndex( esi->_var1_vm_mnemonic, 0, esi->_var3_lval, 0));
    8. }

    9. void _func_3(}
    10. {
    11.     _vmp_setIndexToStruct( esi, _vmp_getVmHandlerIndex( esi->_var1_vm_mnemonic, 0, esi->_var3_lval, 1));
    12. }

    13. int _getindex( int _n)
    14. {
    15.     switch(_n)
    16.     {
    17.     case 1:
    18.         return 0;
    19.     case 2:
    20.         return 1;
    21.     case 3:
    22.         return 2;
    23.     case 5:
    24.         return 4;
    25.     case 6:
    26.         return 5;
    27.     default:
    28.         return 3;
    29.     }
    30. }

    31. _DWORD *__usercall Vmp_FindAndSetTOStruct@<eax>(struct_esi *a1@<eax>, int _size@<ebx>, int _i@<esi>)
    32. {
    33.     esi->_esi_size = 0;
    34.     if( esi->_var1_vm_mnemonic > 0xc4)
    35.     {
    36.         switch(esi->_var1_vm_mnemonic)
    37.         {
    38.         case 0xC6:
    39.         case 0xC8:
    40.         case 0xC9:
    41.         case 0xCF:
    42.         case 0xD0:
    43.         case 0xD1:
    44.         case 0xD2:
    45.         case 0xD3:
    46.         case 0xD4:
    47.         case 0xD6:
    48.         case 0xD7:
    49.         case 0xD8:
    50.         case 0xD9:
    51.         case 0xDB:
    52.         case 0xDD:
    53.         case 0xDF:
    54.         case 0xE0:
    55.         case 0xE1:
    56.         case 0xE3:
    57.         case 0xE5:
    58.         case 0xE6:
    59.         case 0xEE:
    60.         case 0xF8:
    61.             {
    62.                 _func_104();
    63.                 return;
    64.             }
    65.         case 0xF6:
    66.             {
    67.                 _func_101();
    68.                 return;
    69.             }
    70.         case 0xF7:
    71.             {
    72.                 _func_3();
    73.                 break;
    74.             }
    75.         default:
    76.             return;
    77.         }
    78.     }

    79.     if( esi->_var1_vm_mnemonic == 0xC4)
    80.     {
    81.         _func_104();
    82.         return;
    83.     }
    84.     if( esi->_var1_vm_mnemonic > 0x40)
    85.     {
    86.         if( esi->_var1_vm_mnemonic > 0xb6)
    87.         {
    88.             if( esi->_var1_vm_mnemonic != 0xb8 && esi->_var1_vm_mnemonic - 0xbb >= 2)
    89.             {
    90.                 return;
    91.             }
    92.         }
    93.         else if( esi->_var1_vm_mnemonic != 0xb6)
    94.         {
    95.             if( esi->_var1_vm_mnemonic == 0x8b)
    96.             {
    97.                 esi->_hex = esi->_displacement_immediate;
    98.                 esi->size += 4;
    99.                 return;
    100.             }
    101.             if( esi->_var1_vm_mnemonic - 0xA0 >= 2 && esi->_var1_vm_mnemonic - 0xA3 >= 4)
    102.             {
    103.                 return ;
    104.             }
    105.         }
    106.         _func_104();
    107.         return;
    108.     }
    109.     if ( esi->_var1_vm_mnemonic == 0x40 )          // mul
    110.         _func_104();
    111.     return;
    112.     if ( esi->_var1_vm_mnemonic > 0x2E )
    113.     {
    114.         if ( esi->_var1_vm_mnemonic != 0x3D )
    115.         {
    116.             if ( esi->_var1_vm_mnemonic == 0x3E )      // pop dx
    117.                 _func_101();
    118.             return;
    119.             if ( esi->_var1_vm_mnemonic != 0x3F )
    120.                 return;
    121.         }
    122.         _func_104();
    123.         return;
    124.     }
    125.     if ( esi->_var1_vm_mnemonic == 0x2E )          // wait
    126.         _func_104();
    127.     return;
    128.     if ( esi->_var1_vm_mnemonic - 1 >= 2 )
    129.     {
    130.         if ( esi->_var1_vm_mnemonic != 4 && esi->_var1_vm_mnemonic - 28 >= 2 )// !=4 || >= 0x1E
    131.             return;
    132.         _func_101();
    133.         return;
    134.     }
    135.     if ( esi->_var1_vm_mnemonic - 1 != 0 )
    136.     {
    137.         if ( esi->_var1_vm_mnemonic == 2 )                              // pop
    138.         {
    139.             switch ( _esi->_var2_addressing_mode )
    140.             {
    141.             case 1:
    142.                 {
    143.                     _vmp_setIndexToStruct( esi, _vmp_getVmHandlerIndex( 2, 1, esi->_var3_lval, 0));// pop eax|ax
    144.                     break;
    145.                 }
    146.             case 2:   
    147.                 {
    148.                     if ( _esi->_var3_lval >= 3 || _esi->_REG_Index != 4 )
    149.                     {
    150.                         int flag = !_esi->_var3_lval && (_esi->_REG_Index & 4) == 4;
    151.                         _vmp_setIndexToStruct( esi, _vmp_getVmHandlerIndex(2, 2, _esi->_var3_lval, flag);
    152.                         _hex2 = Vmp_GetEmptyVMContext(_esi->Struct_vtable_477C54,_esi->_var3_lval,_esi->_REG_Index,1);
    153.                         saveToStruct(_esi, _hex2);
    154.                     }
    155.                     else
    156.                     {
    157.                         _vmp_setIndexToStruct( esi, _vmp_getVmHandlerIndex(2, 2, _esi->_var3_lval, 1));// pop sp|esp
    158.                     }
    159.                     break;
    160.                 }
    161.             case 3:
    162.                 {
    163.                     _vmp_setIndexToStruct( esi, _vmp_getVmHandlerIndex(2, 3, _esi->_var3_lval, _getindex(esi->var5));
    164.                     break;
    165.                 }
    166.             case 5:
    167.                 {
    168.                     _vmp_setIndexToStruct( esi, _vmp_getVmHandlerIndex(2, 5, 1, _esi->_REG_Index));// pop prefiexreg_index
    169.                     break;
    170.                 }
    171.             case 6:
    172.                 {
    173.                     _vmp_setIndexToStruct( esi, _vmp_getVmHandlerIndex(2, 6, 2, _esi->_REG_Index));
    174.                     break;
    175.                 }
    176.             case 7:
    177.                 {
    178.                     _vmp_setIndexToStruct( esi, _vmp_getVmHandlerIndex(2, 7, 2, _esi->_REG_Index));
    179.                     break;
    180.                 }
    181.             default:
    182.                 break;
    183.             }
    184.         }
    185.     }
    186.     else if ( _esi->_var2_addressing_mode == 1 )
    187.     {
    188.         switch ( _esi->_rand_switch )
    189.         {
    190.         case 1:
    191.             {
    192.                 do
    193.                 v5 = rand()%(-1);
    194.                 while ( !v5 && 0 == *_esi->_Displacement_Immediate );
    195.                 _lval_disp_imm = *_esi->_Displacement_Immediate - v5;
    196.                 v6 = sub_47817C(_esi);
    197.                 v7 = getStruct_1(_esi->Struct_vtable_477C54, v6 + 1);
    198.                 *v7->_Displacement_Immediate = v5;
    199.                 Vmp_FindAndSetTOStruct(v7, v5, _lval_disp_imm);
    200.             }
    201.             break;
    202.         case 2:
    203.             {
    204.                 do
    205.                 v8 = ~*_esi->_Displacement_Immediate & rand()%(-1);
    206.                 while ( !v8 && 0 == ~*_esi->_Displacement_Immediate );
    207.                 _lval_disp_imm = v8 | ~*_esi->_Displacement_Immediate & ~v8;
    208.                 v9 = sub_47817C(_esi);
    209.                 v10 = getStruct_1(_esi->Struct_vtable_477C54, v9 + 1);
    210.                 *v10->_Displacement_Immediate = v8;
    211.                 Vmp_FindAndSetTOStruct(v10, v8, _lval_disp_imm);
    212.             }
    213.             break;
    214.         case 3:
    215.             {
    216.                 v11 = 0;
    217.                 v12 = *_esi->_Displacement_Immediate;
    218.                 while ( !(v12 & 1) ) //偶数
    219.                 {
    220.                     v12 >>= 1;
    221.                     ++v11;
    222.                 }
    223.                 v13 = System::__linkproc__ RandInt(v11);
    224.                 _lval_disp_imm = v13 + 1;
    225.                 v14 = *_esi->_Displacement_Immediate >> (v13 + 1);
    226.                 v15 = sub_47817C(_esi);
    227.                 v16 = getStruct_1(_esi->Struct_vtable_477C54, v15 + 1);
    228.                 *v16->_Displacement_Immediate = v14;
    229.                 Vmp_FindAndSetTOStruct(v16, v14, _lval_disp_imm);
    230.                 break;
    231.             }
    232.         case 4:
    233.             {
    234.                 v17 = 0;
    235.                 while ( _esi->__var4 == 2 && *_esi->_Displacement_Immediate >= 0 || _esi->__var4 == 1 && (*_esi->_Displacement_Immediate & 0x8000) == 0 )
    236.                 {
    237.                     *_esi->_Displacement_Immediate *= 2;
    238.                     ++v17;
    239.                 }
    240.                 v19 = System::__linkproc__ RandInt(v17);
    241.                 _lval_disp_imm = v19 + 1;
    242.                 v20 = *_esi->_Displacement_Immediate << (v19 + 1);
    243.                 v21 = sub_47817C(_esi);
    244.                 v22 = getStruct_1(_esi->Struct_vtable_477C54, v21 + 1);
    245.                 *v22->_Displacement_Immediate = v20;
    246.                 Vmp_FindAndSetTOStruct(v22, v20, _lval_disp_imm);
    247.                 break;
    248.             }
    249.         default:
    250.             {
    251.                 _lval_disp_imm = *_esi->_Displacement_Immediate;
    252.                 break;
    253.             }
    254.         }
    255.         if ( _esi->_rand_switch )
    256.         {
    257.             setAddress(&_esi->_esi_hex[8], *(&off_4CE17C + _esi->_var1_vm_interpreter_mnemonic));
    258.             if ( _esi->_var3_lval == 1 )
    259.             {
    260.                 a2a = _lval_disp_imm;
    261.                 LOBYTE(v66) = 0;
    262.                 sub_409984(&str____4x[1], &a2a, 0, v64);
    263.                 System::__linkproc__ LStrCat(&_esi->_esi_hex[8], *v64);
    264.             }
    265.             else if ( _esi->_var3_lval == 2 )
    266.             {
    267.                 a2a = _lval_disp_imm;
    268.                 LOBYTE(v66) = 0;
    269.                 sub_409984(&str____8x[1], &a2a, 0, v67);
    270.                 System::__linkproc__ LStrCat(&_esi->_esi_hex[8], *v67);
    271.             }
    272.             if ( _esi->__var4 == 1 )
    273.             {
    274.                 a2a = *_esi->_Displacement_Immediate;
    275.                 LOBYTE(v66) = 0;
    276.                 sub_409984(&str___4x[1], &a2a, 0, v62);
    277.                 setAddress(&_esi->_esi_hex[12], *v62);
    278.             }
    279.             else if ( _esi->__var4 == 2 )
    280.             {
    281.                 a2a = *_esi->_Displacement_Immediate;
    282.                 LOBYTE(v66) = 0;
    283.                 sub_409984(&str___8x[1], &a2a, 0, v63);
    284.                 setAddress(&_esi->_esi_hex[12], *v63);
    285.             }
    286.         }
    287.         else
    288.         {
    289.             Free_Mem(&_esi->_esi_hex[12]);
    290.         }
    291.         if ( _esi->_var3_lval == 1 )
    292.         {
    293.             if ( _lval_disp_imm & 0xFF00 )
    294.             {
    295.                 _vmp_setIndexToStruct( esi, _vmp_getVmHandlerIndex( 1, 1, 1, 0);// LODS WORD PTR DS:[ESI] ADD AX,BX ADD BX,AX PUSH AX
    296.                 Move_Word(_esi, _lval_disp_imm);
    297.             }
    298.             else
    299.             {
    300.                 _vmp_setIndexToStruct( esi, _vmp_getVmHandlerIndex( 1, 1, 0, 0);// LODS BYTE PTR DS:[ESI] ADD AL,BL ADD BL,AL PUSH AX
    301.                 saveToStruct(_esi, _lval_disp_imm);
    302.             }
    303.         }
    304.         else if ( _esi->_var3_lval == 2 )
    305.         {
    306.             if ( _esi->_ispushfw & 2 || _lval_disp_imm != Byte_Extension(_lval_disp_imm) )
    307.             {
    308.                 if ( _esi->_ispushfw & 2 || _lval_disp_imm != Word_Extension(_lval_disp_imm) )
    309.                 {
    310.                     _vmp_setIndexToStruct( esi, _vmp_getVmHandlerIndex( 1, 1, 2, 0);// LODS DWORD PTR DS:[ESI] ADD EAX,EBX ADD EBX,EAX PUSH EAX
    311.                     Move_Dword(_esi, _lval_disp_imm);
    312.                 }
    313.                 else
    314.                 {
    315.                     _vmp_setIndexToStruct( esi, _vmp_getVmHandlerIndex( 1, 1, 1, 1);// LODS WORD PTR DS:[ESI] ADD AX,BX ADD BX,AX CWDE PUSH EAX
    316.                     Move_Word(_esi, _lval_disp_imm);
    317.                 }
    318.             }
    319.             else
    320.             {
    321.                 _vmp_setIndexToStruct( esi, _vmp_getVmHandlerIndex( 1, 1, 0, 1);// LODS BYTE PTR DS:[ESI] ADD AL,BL ADD BL,AL CBW CWDE PUSH EAX
    322.                 saveToStruct(_esi, _lval_disp_imm);
    323.             }
    324.         }
    325.         else
    326.         {
    327.             _vmp_setIndexToStruct( esi, _vmp_getVmHandlerIndex( 1, 1, 0, 0);// LODS BYTE PTR DS:[ESI] ADD AL,BL ADD BL,AL PUSH AX
    328.             saveToStruct(_esi, _lval_disp_imm);
    329.         }
    330.     }
    331.     else
    332.     {
    333.         switch ( _esi->_var2_addressing_mode )
    334.         {
    335.         case 2:
    336.             {
    337.                 if ( _esi->_var3_lval >= 3 || _esi->_REG_Index != 4 )
    338.                 {
    339.                     _vmp_setIndexToStruct( esi,_vmp_getVmHandlerIndex(1, 2, _esi->_var3_lval, _esi->_var3_lval == 0 && (_esi->_REG_Index & 4) == 4);//利用空间  push _context[]
    340.                     v34 = Vmp_GetEmptyVMContext(_esi->Struct_vtable_477C54,_esi->_var3_lval,_esi->_REG_Index,0);//选择index
    341.                     saveToStruct(_esi, v34);
    342.                 }
    343.                 else
    344.                 {
    345.                     _vmp_setIndexToStruct( esi, _vmp_getVmHandlerIndex( 1, 2, _esi->_var3_lval, 1);//// push sp|esp
    346.                 }
    347.                 break;
    348.             }
    349.         case 3:
    350.             {
    351.                 _vmp_setIndexToStruct( esi, _vmp_getVmHandlerIndex(1,3,_esi->_var3_lval,_getindex(_esi->_var5));// pop e?x push ? ptr ?
    352.                 break;
    353.             }
    354.         case 5:
    355.             {
    356.                 _vmp_setIndexToStruct( esi, _vmp_getVmHandlerIndex( 1, 5, 1, _esi->_REG_Index));//push prefix_reg
    357.                 break;
    358.             }
    359.         case 6:
    360.             {
    361.                 _vmp_setIndexToStruct( esi, _vmp_getVmHandlerIndex( 1, 6, 2, _esi->_REG_Index));//mov eax,cr_index push eax
    362.                 break;
    363.             }
    364.         case 7:
    365.             {
    366.                 _vmp_setIndexToStruct( esi, _vmp_getVmHandlerIndex( 1, 7, 2, _esi->_REG_Index));// mov eax,dr_index push eax
    367.                 break;
    368.             }
    369.         default:
    370.             {
    371.                 break;
    372.             }
    373.         }
    374.     }
    375. }
    复制代码


    1.       判断vm_mnemonic
    2.       再判断寻址方式以及类型
    继续,我们看看vm_mnemonic怎么得到的

    1. char __fastcall Vmp_SetEsiStruct(struct_vtable_477C54 *var1, char _var1_interpreter_mnemonic, char _var2_addressing_mode, unsigned __int8 _3_lval_type, int _var5_index, int var6, int var7)
    2. {
    3.     v8 = (var1->Vtable_477C54->SetCapacity)();
    4.     if ( var6 & 8 )
    5.         Classes::TList::Add(_var1->Ptr_Struct_Vtable_40F3B8, v8);
    6.     v8->_var1_vm_interpreter_mnemonic = _var1_vm_mnemonic;
    7.     v8->_var2_addressing_mode = _var2_addressing_mode;
    8.     v8->_var3_lval_type_byte_word_dword_or_vm_displacement = _3_lval_type;
    9.     if ( var6 & 0x20 )
    10.         v8->_ispushfw |= 0x20u;
    11.     switch ( _var2_addressing_mode )                 // 第3个参数进行switch
    12.     {
    13.     case 0:
    14.         if ( _var5_index == 1 )
    15.             v8->_ispushfw |= 1u;
    16.         else
    17.             v8->_ispushfw &= 0xFEu;
    18.         break;
    19.     case 1:                                     // 先判断类型 第4个参数进行判断
    20.         if ( _3_lval_type < 1u )                  // [base]
    21.         {
    22.             *v8->_Displacement_Immediate = (char)_var5_index;
    23.         }
    24.         else if ( _3_lval_type == 1 )             // [base + disp8]
    25.         {
    26.             *v8->_Displacement_Immediate = (short)_var5_index;
    27.         }
    28.         else                                      // [base + disp32]
    29.         {
    30.             *v8->_Displacement_Immediate = _var5_index;
    31.         }
    32.         if ( var6 & 0x10 )
    33.         {
    34.             v8->_ispushfw |= 8u;
    35.             v9 = var7;
    36.             v8->_init0xffff_oppositecondition = var7;
    37.         }
    38.         if ( var6 & 2 )
    39.             v8->_ispushfw |= 2u;
    40.         if ( var6 & 1 )
    41.         {
    42.             LOBYTE(v9) = 1;
    43.             v31 = 1;
    44.         }
    45.         else
    46.         {
    47.             LOBYTE(v9) = 0;
    48.             v31 = 0;
    49.         }
    50.         if ( var6 & 0x40 )
    51.             v31 |= 0x40u;
    52.         if ( var6 & 4 )
    53.         {
    54.             if ( _3_lval_type >= 3 )                              // qword的拆分吗
    55.             {
    56.                 if ( _var1->Struct_Vtable_477E80->Struct_Vtable_477F00->_vm_type & 4 )
    57.                 {
    58.                     v8->__var4 = _3_lval_type;
    59.                     _rand_type[0] = 1;
    60.                     _rand_type[2] = 1;
    61.                     if ( statisticsbinaryis1count(~*v8->_Displacement_Immediate, _3_lval_type) >= 3u )// 统计奇数为 大于3
    62.                     {
    63.                         _rand_type[1] = 2;
    64.                         _rand_type[3] = 2;
    65.                     }
    66.                     else
    67.                     {
    68.                         _rand_type[1] = 1;
    69.                         _rand_type[3] = 1;
    70.                     }
    71.                     if ( !(v8->_ispushfw & 2) && *v8->_Displacement_Immediate )
    72.                     {
    73.                         if ( !(v8->_Displacement_Immediate[0] & 1) )
    74.                             _rand_type[2] = 3;
    75.                         if ( _3_lval_type == 2 && v8->_Displacement_Immediate[3] >= 0
    76.                             || _3_lval_type == 1 && v8->_Displacement_Immediate[1] >= 0 )
    77.                         {
    78.                             _rand_type[3] = 4;
    79.                         }
    80.                     }
    81.                     v8->_rand_switch = _rand_type[rand()%4];
    82.                     switch ( v8->_rand_switch )
    83.                     {
    84.                     case 1:
    85.                         {
    86.                             Vmp_SetEsiStruct(_var1, 1, 1, _3_lval_type, 0, v31 | 2, -1);// LODS DWORD PTR DS:[ESI] PUSH EAX
    87.                             Vmp_SetEsiStruct(_var1, 4, 0, _3_lval_type, 0, v31, -1);// POP EAX ADD DWORD PTR SS:[ESP],EAX
    88.                             break;
    89.                         }
    90.                     case 2:
    91.                         {
    92.                             Vmp_SetEsiStruct(_var1, 1, 1, _3_lval_type, 0, v31 | 2, -1);
    93.                             Vmp_SetEsiStruct(_var1, 0xF6, 0, _3_lval_type, 0, v31, -1);// POP EAX NOT EAX NOT DWORD PTR SS:[ESP] AND DWORD PTR SS:[ESP],EAX
    94.                             break;
    95.                         }
    96.                     case 3:
    97.                         {
    98.                             v8->_var3_lval_type_byte_word_dword_or_vm_displacement = 1;
    99.                             Vmp_SetEsiStruct(_var1, 1, 1, _3_lval_type, 0, v31 | 2, -1);
    100.                             LOBYTE(v9) = Vmp_SetEsiStruct(_var1, 0x1C, 0, _3_lval_type, 0, v31, -1);// POP EAX POP CX SHL EAX,CL PUSH EAX
    101.                             break;
    102.                             default:
    103.                             if ( v8->_rand_switch == 4 )
    104.                             {
    105.                                 v8->_var3_lval_type_byte_word_dword_or_vm_displacement = 1;
    106.                                 Vmp_SetEsiStruct(_var1, 1, 1, _3_lval_type, 0, v31|2, -1);//LODS DWORD PTR DS:[ESI] PUSH EAX
    107.                                 Vmp_SetEsiStruct(_var1, 0x1D, 0, _3_lval_type, 0, v31, -1);// POP EAX POP CX SHR EAX,CL PUSH EAX
    108.                             }
    109.                             break;
    110.                         }
    111.                     }
    112.                 }
    113.             }
    114.         }
    115.     }
    116.     if ( _3_lval_type == 2 && var6 & 0x10 && _1_interpreter_mnemonic != 0x8Bu )// [base + disp32]
    117.     {
    118.         if ( var7 == -1 )
    119.         {
    120.             v9 = 3;
    121.         }
    122.         else
    123.         {
    124.             v9 = sub_479128(*&_var1->Struct_Vtable_477E80->Struct_Vtable_477F00->Struct_table_477E80->field_60, var7)->field_C;
    125.         }
    126.         switch(v9)
    127.         {
    128.         case 3:
    129.             {
    130.                 Vmp_SetEsiStruct(_var1, 1, 2, 2, 10, v31, -1);//LODS BYTE PTR DS:[ESI] PUSH DWORD PTR DS:[EDI+EAX*4]
    131.                 Vmp_SetEsiStruct(_var1, 4, 0, 2, 0, v31, -1);//POP EAX ADD DWORD PTR SS:[ESP],EAX
    132.                 break;
    133.             }
    134.         case 2:
    135.             {
    136.                 Vmp_SetEsiStruct(_var1, 1, 1, 1, 0, v31, -1);//LODS WORD PTR DS:[ESI] PUSH AX
    137.                 Vmp_SetEsiStruct(_var1, 1, 2, 1, 10, v31, -1);//LODS BYTE PTR DS:[ESI] PUSH WORD PTR DS:[EDI+EAX*4]
    138.                 Vmp_SetEsiStruct(_var1, 4, 0, 2, 0, v31, -1);//POP EAX ADD DWORD PTR SS:[ESP],EAX
    139.                 break;
    140.             }
    141.         case 1:
    142.             {
    143.                 Vmp_SetEsiStruct(_var1, 1, 2, 2, 10, v31, -1);// LODS BYTE PTR DS:[ESI] PUSH DWORD PTR DS:[EDI+EAX*4]
    144.                 Vmp_SetEsiStruct(_var1, 2, 1, 1, 0, v31, -1);// LODS BYTE PTR DS:[ESI] POP WORD PTR DS:[EDI+EAX*4]
    145.                 Vmp_SetEsiStruct(_var1, 1, 1, 1, 0, v31, -1);// LODS WORD PTR DS:[ESI] PUSH AX
    146.                 Vmp_SetEsiStruct(_var1, 4, 0, 2, 0, v31, -1);// POP EAX ADD DWORD PTR SS:[ESP],EAX
    147.                 break;
    148.             }
    149.         }
    150.         if ( !(var6 & 0x40) && !(var6 & 8) && _1_interpreter_mnemonic == 1 )
    151.         {
    152.             if ( _var1->Struct_Vtable_477E80->Struct_Vtable_477F00->_vm_type & 0x20 )
    153.             {
    154.                 v9 = rand()%2 - 1;
    155.                 if ( !v9 )//(int)[esp] += [[esi]]
    156.                 {
    157.                     v31 |= 0x40u;
    158.                     v23 = sub_48BC1C(_var1->Struct_Vtable_477E80->Struct_Vtable_477F00, &v30);
    159.                     Vmp_SetEsiStruct(_var1, 1, 1, 2, v30, v31 | 0x14, -1);// LODS DWORD PTR DS:[ESI] PUSH EAX
    160.                     Vmp_SetEsiStruct(_var1, 1, 3, _3_lval_type, 0, v31, -1);// POP EAX PUSH DWORD PTR SS:[EAX]
    161.                     Vmp_SetEsiStruct(_var1, 1, 1, _3_lval_type, -v23, v31 | 4, -1);// LODS DWORD PTR DS:[ESI] PUSH EAX
    162.                     Vmp_SetEsiStruct(_var1, 4, 0, _3_lval_type, 0, v31, -1);// POP EAX
    163.                     Vmp_SetEsiStruct(_var1, 4, 0, _3_lval_type, 0, v31, -1);// POP EAX ADD DWORD PTR SS:[ESP],EAX
    164.                 }
    165.             }
    166.         }
    167.         break;
    168.         case 2:
    169.         case 5:
    170.         case 6:
    171.         case 7:
    172.             v8->_REG_Index = _var5_index;
    173.             break;
    174.         case 3:
    175.             v8->field_F = _var5_index;
    176.             break;
    177.         default:
    178.             break;
    179.     }
    180.     if ( var6 & 1 )                               // 奇数成立
    181.         Vmp_FindAndSetTOStruct(v8, var6, v8);// Make
    182.     return v9;
    183. }
    复制代码


    可以发现由传参决定并对于某些方式递归调用
    继续寻找怎么来的
    7.png
    8.png

    定位到cmp。看看vmp是如何实现对cmp,jcc的膨胀的
    9.png

    首先可以很直观的看到,在早期版本中
    把sub cmp sbb放在一起来处理
    那么看看是如何usedisasmstruct的


    1. char __usercall _get_prefix@<al>(int index@<eax>, int a2)
    2. {
    3.     _operand = ( _disasm + 21 * _operand_index + 24)
    4.     if ( _disasm.About_Prefixes == 4 )
    5.         return 0;
    6.     if ( _disasm.About_Prefixes == 0
    7.         && (v2->FirstVar_Trans_ModRM_mod & 0x10
    8.         && (v2->ThirdVar_SIB__Base_Index - 4) < 2
    9.         || v2->FirstVar_Trans_ModRM_mod & 4
    10.         && (v2->SecondVar_Trans_ModRM_rm_Index - 4) < 2) )
    11.     {
    12.         return 3;
    13.     }
    14.     return _disasm.About_Prefixes;
    15. }



    16. int __usercall Vmp_UseDisasmStruct@<eax>(int _operand_index@<eax>, char a2@<dl>, int a3@<ecx>, int a4@<ebx>, int a5)
    17. {
    18.     _operand = ( _disasm + 21 * _operand_index + 24);
    19.     if ( _operand.FirstVar_Trans_ModRM.mod == 0 )               // FirstVar_Trans_ModRM.mod == 0  return
    20.         return 0;
    21.     int ret = 1;
    22.     if ( a2 & 4 )
    23.     {
    24.         _Type = 1;
    25.     }
    26.     else if ( a2 & 8 )
    27.     {
    28.         _Type = 2;
    29.     }
    30.     else
    31.     {
    32.         _Type = _operand->About_Lval_Byte_Word_Dword;
    33.     }
    34.     BYTE1(__n) = 0;
    35.     if ( _operand->FirstVar_Trans_ModRM_mod == 0x24 )// prefix
    36.     {
    37.         if ( a2 & 1 && (__n = *(a5 - 4), *(__n + 22) != 1) )// != push
    38.         {
    39.             _vmp_SetEsiStruct(*(a5 - 4), 2, 5, 1, _operand->SecondVar_Trans_ModRM_rm_Index, 0, -1);// POP PREFIX
    40.             if ( _Type == 2 )
    41.             {
    42.                 _vmp_SetEsiStruct(*(a5 - 4), 2, 1, 1, 0, 0, -1);// POP AX
    43.             }
    44.         }
    45.         else                                        // pop
    46.         {
    47.             if ( _Type == 2 )
    48.             {
    49.                 _vmp_SetEsiStruct(*(a5 - 4), 1, 1, 1, 0, 0, -1);// LODS WORD PTR DS:[ESI] PUSH AX
    50.             }
    51.             _vmp_SetEsiStruct(*(a5 - 4), 1, 5, 1, _operand->SecondVar_Trans_ModRM_rm_Index, 0, -1);// PUSH PREFIX
    52.         }
    53.     }
    54.     else if ( _operand->FirstVar_Trans_ModRM_mod == 0x84 )// DR?
    55.     {
    56.         if ( a2 & 1 && _disasm->Mnemonic_Counter_4CE17C != 1 )     // Mnemonic_Counter_4CE17C != 1 push
    57.         {
    58.             _vmp_SetEsiStruct(*(a5 - 4), 2, 7, 2, _operand->SecondVar_Trans_ModRM_rm_Index, 0, -1);// POP EAX MOV DR?,EAX
    59.         }
    60.         else
    61.         {
    62.             _vmp_SetEsiStruct(*(a5 - 4), 1, 7, 2, _operand->SecondVar_Trans_ModRM_rm_Index, 0, -1);// MOV EAX,DR? PUSH EAX
    63.         }
    64.     }
    65.     else
    66.     {
    67.         if ( _operand->FirstVar_Trans_ModRM_mod == 0x44 )// CR?
    68.         {
    69.             if ( a2 & 1 && _disasm->Mnemonic_Counter_4CE17C != 1 )   // push
    70.             {
    71.                 _vmp_SetEsiStruct(*(a5 - 4), 2, 6, 2, _operand->SecondVar_Trans_ModRM_rm_Index, 0, -1);// POP EAX MOV CR?,EAX
    72.             }
    73.             else
    74.             {
    75.                 _vmp_SetEsiStruct(*(a5 - 4), 1, 6, 2, _operand->SecondVar_Trans_ModRM_rm_Index, 0, -1);// MOV CR?,EAX PUSH EAX
    76.             }
    77.         }
    78.         else
    79.         {
    80.             if ( _operand->FirstVar_Trans_ModRM_mod & 2 )
    81.             {
    82.                 if ( _operand->FirstVar_Trans_ModRM_mod & 8 )
    83.                     _Size = 2;                            // 0xC 0xE
    84.                 else
    85.                     _Size = _Type;
    86.                 v15 = _operand->RestHex_Lval_Displacement_Immediate;
    87.                 RestHex_Displacement_Immediate = _operand->RestHex_Lval_Displacement_Immediate;
    88.                 if ( _operand->Lavl_Btye_Word_Dword )                              // if(v8->Lavl_Btye_Word_Dword != 0)
    89.                 {
    90.                     if ( _operand->Lavl_Btye_Word_Dword == 1 && _Size == 2 )         // word
    91.                     {
    92.                         RestHex_Displacement_Immediate = Word_Extension(_operand->RestHex_Lval_Displacement_Immediate);
    93.                     }
    94.                 }
    95.                 else if ( _Size == 2 )                  // dword
    96.                 {
    97.                     RestHex_Displacement_Immediate = Byte_Extension(_operand->RestHex_Lval_Displacement_Immediate);
    98.                 }
    99.                 else if ( _Size == 1 )                  // word
    100.                 {
    101.                     RestHex_Displacement_Immediate = Byte_Extension_Word(_operand->RestHex_Lval_Displacement_Immediate);
    102.                 }
    103.                 if ( !(_operand->FirstVar_Trans_ModRM_mod & 8) && _a2 & 2 )
    104.                 {
    105.                     if ( _disasm->Mnemonic_Counter_4CE17C != 0x13 && _disasm->Mnemonic_Counter_4CE17C != 0x43 )// sbb 0x44不算
    106.                         // Opcode_counter_4CE17C != 19 || != 67
    107.                         //                    _str_sub || _str_cmp
    108.                         RestHex_Displacement_Immediate = ~RestHex_Displacement_Immediate;// 反码
    109.                     else
    110.                         RestHex_Displacement_Immediate = -RestHex_Displacement_Immediate;//
    111.                     // sub || cmp
    112.                     // 补码
    113.                 }
    114.                 if ( _operand->Lavl_Btye_Word_Dword == 2 )
    115.                 {
    116.                     __Type1 = 4;
    117.                     v16 = *(*(a5 - 4) + 0x80);
    118.                     if ( v16 && *(v16 + 8) )
    119.                         __Type1 = 0xE;
    120.                 }
    121.                 else
    122.                 {
    123.                     __Type1 = 0;
    124.                 }
    125.                 if ( _operand->Fix > 0xFFFFFFFF || (_disasm->Mnemonic_Counter_4CE17C + 0xC) < 2u && !_operand_index && _operand->FirstVar_Trans_ModRM_mod == 2 )// _disasm->Mnemonic_Counter_4CE17C <===> mnemonic
    126.                 {
    127.                     __Type1 |= 0x10u;
    128.                 }                                       // 到时候好从[esi]读出补码或反码
    129.                 // 在push
    130.                 // 那么下面就是与输入的数进行and
    131.                 _vmp_SetEsiStruct(*(a5 - 4), 1, 1, _Size, RestHex_Displacement_Immediate, __Type1, _operand->Fix);
    132.             }                                         // lods immediate push eax
    133.             if ( _operand->FirstVar_Trans_ModRM_mod & 4 )
    134.             {
    135.                 if ( _operand->FirstVar_Trans_ModRM_mod & 8 )
    136.                 {
    137.                     if ( _operand->SibFirstVar_SIB_Scable_Index )
    138.                     {
    139.                         _vmp_SetEsiStruct(*(a5 - 4), 1, 1, 1, _operand->SibFirstVar_SIB_Scable_Index, 0, -1);// LODS WORD PTR DS:[ESI] PUSH EAX
    140.                     }
    141.                     if ( _operand->About_RegType_8_16_32 == 1 )
    142.                     {
    143.                         _vmp_SetEsiStruct(*(a5 - 4), 1, 1, 1, 0, 0, -1);// LODS WORD PTR DS:[ESI] PUSH AX
    144.                     }
    145.                     _vmp_SetEsiStruct( *(a5 - 4), 1, 2, _operand->About_RegType_8_16_32, _operand->SecondVar_Trans_ModRM_rm_Index,0,-1);
    146.                     if ( _operand->SecondVar_Trans_ModRM_rm_Index == 4 )// sp
    147.                         sub_486A30(2u, a5);
    148.                 }
    149.                 else
    150.                 {
    151.                     if ( _a2 & 1 && _disasm->Mnemonic_Counter_4CE17C != 1 )
    152.                     {
    153.                         _vmp_SetEsiStruct(*(a5 - 4), 2, 2, _Type, _operand->SecondVar_Trans_ModRM_rm_Index, 0, -1);// LODS BYTE PTR DS:[ESI] POP DWORD PTR DS:[EDI+EAX*4]
    154.                     }
    155.                     else
    156.                     {
    157.                         _vmp_SetEsiStruct(*(a5 - 4), 1, 2, _Type, _operand->SecondVar_Trans_ModRM_rm_Index, 0, -1);// LODS BYTE PTR DS:[ESI] PUSH DWORD PTR DS:[EDI+EAX*4]
    158.                     }
    159.                     if ( _Type < 3 && _operand->SecondVar_Trans_ModRM_rm_Index == 4 && !(_a2 & 1) )
    160.                         sub_486A30(_Type, a5);//ADD DWORD PTR SS:[ESP],LODSD DS:[ESI]
    161.                 }
    162.             }
    163.             if ( _operand->FirstVar_Trans_ModRM_mod & 8 )
    164.             {
    165.                 if ( _operand->FirstVar_Trans_ModRM_mod & 4 && _operand->SibFirstVar_SIB_Scable_Index )
    166.                 {
    167.                     _vmp_SetEsiStruct(*(a5 - 4), 28, 0, 2u, 0, 0, -1);
    168.                 }
    169.                 if ( _operand->FirstVar_Trans_ModRM_mod & 0x10 )
    170.                 {
    171.                     if ( _operand->About_RegType_8_16_32 == 1 )
    172.                     {
    173.                         _vmp_SetEsiStruct(*(a5 - 4), 1, 1, 1u, 0, 0, -1);
    174.                     }
    175.                     _vmp_SetEsiStruct(*(a5 - 4), 1, 2, _operand->About_RegType_8_16_32, _operand->ThirdVar_SIB__Base_Index, 0, -1);
    176.                     if ( _operand->ThirdVar_SIB__Base_Index == 4 )
    177.                         sub_486A30(2, a5);//ADD DWORD PTR SS:[ESP],LODSD DS:[ESI]
    178.                     if ( _operand->FirstVar_Trans_ModRM_mod & 4 )
    179.                     {
    180.                         _vmp_SetEsiStruct(*(a5 - 4), 4, 0, 2u, 0, 0, -1);
    181.                     }
    182.                 }
    183.                 if ( _operand->FirstVar_Trans_ModRM_mod & 2 && (_operand->FirstVar_Trans_ModRM_mod & 4 || _operand->FirstVar_Trans_ModRM_mod & 0x10) )
    184.                 {
    185.                     _vmp_SetEsiStruct(*(a5 - 4), 4, 0, 2u, 0, 0, -1);
    186.                 }
    187.                 if ( !(_a2 & 0x10) )//addressing prefix:[eax]
    188.                 {
    189.                     if ( _a2 & 1 )
    190.                     {
    191.                         v25 = _get_prefix(__operand_index, a5) & 0x7F;
    192.                         _vmp_SetEsiStruct(*(a5 - 4), 2, 3, _Type, v25, 0, -1);//POP EAX POP DWORD PTR prefix:[EAX]
    193.                     }
    194.                     else
    195.                     {
    196.                         v27 = _get_prefix(__operand_index, a5) & 0x7F;
    197.                         _vmp_SetEsiStruct(*(a5 - 4), 1, 3, _Type, v27, 0, -1);//POP EAX PUSH DWORD PTR prefix:[EAX]
    198.                     }
    199.                 }
    200.             }
    201.         }
    202.     }
    203.     return ret;
    204. }
    复制代码



    结合刚开始给的,则有先读operand[1]
    注意到:


    1. if ( _disasm->Mnemonic_Counter_4CE17C != 0x13 && _disasm->Mnemonic_Counter_4CE17C != 0x43 )
    2. // sbb 0x44不算 Opcode_counter_4CE17C != 19 || != 67  _str_sub || _str_cmp
    3.     RestHex_Displacement_Immediate = ~RestHex_Displacement_Immediate;// 反码
    4. else
    5.     RestHex_Displacement_Immediate = -RestHex_Displacement_Immediate;// sub || cmp 补码
    复制代码


    然后其他的对应膨胀规则看看就明白了
    10.png

    分析sub_485884
    11.png

    分析sub_4857DC
    12.png

    可以看到这整套就是一个计算好初始eflags,然后压入_context的过程
    分析sub_4858E0
    这里就没注释了,可以对照规则
    13.png


    至此,早期版本中的cmp就这样vm了
    一个细节的地方
    注意到Vmp_SetEsiStruct函数


    1. v8 = (var1->Vtable_477C54->SetCapacity)();
    2. if ( var6 & 8 )
    3. Classes::TList::Add(_var1->Ptr_Struct_Vtable_40F3B8, v8);
    复制代码


    那么我们可以这样理解,在早期版本
    vm的基本单位是指令,而指令通过反编译得到 ----> _struct_disasm
    加上一个list,抽象出来


    1. _struct_disasm
    2. {
    3.     ……
    4.     …..
    5.     list<?> ls;
    6. };
    复制代码


    注意到esi是怎样生成的,通过那些规则,故


    1. _struct_disasm
    2. {
    3.     ……
    4.      …..
    5.     list<_struct_esi> ls;
    6. };
    复制代码


    同时我们可以猜一猜vmp设计的思路
    一开始应该是vm的各种运算(add sub mul xor)
    这个不难,如果叫我们来实现,直接将代码替换就可以了


    1. 稍微面向一点
    2. switch(mnemonic)
    3. {
    4. case _sub:
    5. case _cmp
    6. }
    7. 再面向一些,查表
    8. int _table[] = {1,2,3,4……}
    9. switch(mnemonic)
    10. {
    11. case _sub:
    12. index = 1;
    13. case _cmp:
    14. index = 2;
    15. }
    复制代码


    最后在进行匹配
    我不知道其他的vm引擎是怎么设计的,如果是我写的话应该也会这样。
    第一步可以看成写编译器的语法分析


    1. 另外
    2. {0xF6,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"POP EAX NOT EAX NOT DWORD PTR SS:[ESP] AND DWORD PTR SS:[ESP],EAX"}
    3. 这个0xf6取得蛮有意思的
    复制代码


    在说说jcc
    14.png

    注意到
    15.png

    这几个参数,已上个帖子提到
    16.png
    17.png
    18.png

    恩,很多人爆破提到的shr。这个我想动态跟一跟,因为我觉得设计得很好

    1. push add1

    2. push 0
    3. add [add1],0  
    4. stack_top   0042fbcd

    5. push addr2
    6. push 0
    7. add [addr2],0 //这两个地址很有意思
    8. stack_top   0042fb9b
    9.             0042fbcd

    10. lodw [not(0x40)]
    11. push not(0x40
    12. lodb [index]
    13. push _context[index] ----> push eflags
    14. stack_top ffbf0287


    15. not [esp]  ---> 0040fd78
    16. pop ax
    17. and [esp],ax
    18. stack_top   fb9b0040
    19.             fbcd0042
    20.                 0042

    21. losb [index]
    22. pop _context[index] ---> 0x40
    23. stack_top   42fb9b
    24.             42fbcb
    25.             001848

    26. losb [4]
    27. push 4
    28. stack_top   fb9b0004
    29.             fbcd0042
    30.                 0042

    31. Lodb [index]
    32. Push _context[_index]
    33. Stack_top   00040040
    34.             0042fb9b
    35.             0042fbcd

    36. Pop ax
    37. Pop cx
    38. Shr ax,cl  ---> result == 0x4
    39. Push ax
    40. Stack_top   fb9b0004
    41.             Fbcd0042
    42.                 0042

    43. //这个4很有意思
    44. Lodb [index]
    45. Pop _context[index] ---> 4
    46. stack_top   0042fb9b
    47.             0042fbcd


    48. Push esp //注意到这里
    49. stack_top   0018FE98(addr_42fb9b)
    50.             0042FB9B
    51.             0042FBCD


    52. Lodsb [index]
    53. Push ax  --> 0
    54. Stack_top   fe98000
    55.             Fb9b0018
    56.             Fbcd0042
    57.             Ff480042


    58. Lodsb [index]
    59. Push _context[index] ---> 0x4
    60. Stack_top   00000004
    61.             0018fe98
    62. Pop eax   --->       eax == 0x4
    63. add [esp],eax
    64. stack_top   0018FE98(addr_42fb9b)
    65.             0042FB9B
    66.             0042FBCD
    复制代码


    注意到这里,很重要
    vmp先压了两个地址然后取eflags运算进行shr,通常会得到4
    那么这个4是用来干什么的
    我们看看这两个地址的内容
    19.png
    20.png



    1. 恩,没错。实现了分支
    2. 在注意到这里的地址

    3. Stack_top   0018fe9c(addr_0042fbcd)
    4.             0042fb9b
    5.             0042fbcd

    6. Pop eax
    7. Push [eax]
    8. Stack_top   0042fbcd
    9.             0042fb9b
    10.             0042fbcd

    11. 但是有个问题,vmp怎么修改esi
    12. Lodsd [vmp_entry]
    13. Push vmp_entry
    14. Stack_top   0042F000(vmp_entry)
    15.             00000000(_addressing)
    16.             0042fbcd

    17. Pop eax
    18. Add [esp],eax
    19. Stack_top   0042f000
    20.             0042fbcd

    21. 保存环境

    22. Stack_top   00000000
    23.             0018FEF4
    24.             00000000
    25.             0018FEF4
    26.             0018FE84
    27.             7EFDE000
    28.             00000000
    29.             00425036
    30.             00000001
    31.             00000287
    32.             0042F000
    33.             0042FBCD
    复制代码


    21.png
    22.png

    这样就返回vm_entry,改变esi了
    看到这,相信大家应该有很多爆破的思路了吧

    0x11 结束语
    就这样,先写到这里



    评分

    参与人数 7威望 +60 飘云币 +76 收起 理由
    Bu弃 + 20 + 20 赞一个!
    0xcb + 4 + 4 赞一个!
    tree_fly + 20 赞一个!
    2402436533 + 20 + 20 很给力!
    飞天 + 4 + 4 赞一个!
    NoNameX2016 + 8 + 8 很给力!
    bjcar + 4 很给力!

    查看全部评分

    本帖被以下淘专辑推荐:

    PYG19周年生日快乐!
  • TA的每日心情
    擦汗
    2022-12-5 14:15
  • 签到天数: 34 天

    [LV.5]常住居民I

    发表于 2018-3-27 17:19:01 | 显示全部楼层
    好贴,菜鸟来学习了。
    PYG19周年生日快乐!
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    无聊
    6 小时前
  • 签到天数: 1394 天

    [LV.10]以坛为家III

    发表于 2018-3-27 18:48:46 | 显示全部楼层
    支持楼主分享好的分析文章。
    PYG19周年生日快乐!
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    奋斗
    2021-9-29 15:05
  • 签到天数: 114 天

    [LV.6]常住居民II

    发表于 2018-3-28 20:39:04 | 显示全部楼层
    先读一遍学习下,等忙过去了,自己实践实践,感谢分享
    PYG19周年生日快乐!
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2024-3-10 17:48
  • 签到天数: 106 天

    [LV.6]常住居民II

    发表于 2018-4-4 15:05:59 | 显示全部楼层
            PYG有你更精彩!
    PYG19周年生日快乐!
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    奋斗
    3 天前
  • 签到天数: 370 天

    [LV.9]以坛为家II

    发表于 2018-4-5 23:49:54 | 显示全部楼层
    估计没几个人看得懂。很详细,不过3.x的重构代码比这个要复杂多了。
    PYG19周年生日快乐!
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    慵懒
    2022-1-10 21:59
  • 签到天数: 109 天

    [LV.6]常住居民II

    发表于 2018-4-8 18:14:59 | 显示全部楼层
    一脸懵逼的进来,一脸懵逼的出去。看不懂,还需学习。膜拜下。
    PYG19周年生日快乐!
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    4 小时前
  • 签到天数: 943 天

    [LV.10]以坛为家III

    发表于 2018-4-11 08:25:51 | 显示全部楼层
    还需学习。膜拜
    PYG19周年生日快乐!
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2020-6-2 19:32
  • 签到天数: 4 天

    [LV.2]偶尔看看I

    发表于 2018-5-8 18:29:16 | 显示全部楼层
    非常感谢分享,给力
    PYG19周年生日快乐!
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    无聊
    2018-5-18 21:05
  • 签到天数: 1 天

    [LV.1]初来乍到

    发表于 2018-5-18 21:13:02 | 显示全部楼层
    谢您的分享谢谢您的分享
    PYG19周年生日快乐!
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 登录 | 加入我们

    本版积分规则

    快速回复 返回顶部 返回列表