0x00 前言
写之前就在想该以一个怎样的方式阐述这些东西,最终还是决定以逆推的方式来描述
另外 先回答下问题 分析的是vmp的主程序,很早的版本
0x01 虚拟化后
测试的指令
- 68 34504200 PUSH OFFSET zf.??_C@_02MECO@?$CFd?$AA@ ; /format = "%d"
- E8 13010000 CALL zf.scanf ; \scanf
- 83C4 08 ADD ESP,0x8
- 817D FC 33020000 CMP DWORD PTR SS:[EBP-0x4],0x233
- 75 09 JNZ SHORT zf.00401062
复制代码
被用来vm的两条指令:
- 817DFC33020000 cmp dword ptr [ebp-04],00000233
- 7509 jnz 00401062
复制代码
先看看是cmp被vm之后的情况,因为既然大S提到了这个,看了他的帖子,所以叫他大S
- 1.lodsd -0x233
- push -0x233
-
- stack_top fffffdcd
-
- 2.lodsb [index]
- push _context[index] <===> push ebp
-
- stack_top ebp
- fffffdcd
-
- 3.lodsb [disp]
- push disp
-
- stack_top disp
- ebp
- fffffdcd
-
- 4.pop disp
- add ebp,dis <===> get addr input
-
- stack_top ebp+disp
- fffffdcd
-
- 5.pop addr (input)
- push input
-
- stack_top input
- fffffdcd
-
- 6.pop input
- add [-0x233],input ... get a
-
- stack_top fffffe48
-
- pushfw
-
- stack_top fe480296
-
- 7.push eflags
- stack_top 02960216
- 00fffffe48
-
- 8.push stack
- stack_top ebp
- 02960216
- fffffe48
-
- 9.pop stack
- push [stack]
-
- stack_top 02160216
- fe480296
-
- 10.and(not(eflags),not(eflags))
- stack_top fde9fde9
-
- stack_top 0296fde9
- fffffe48
-
- 11.lodsw ~0x400
- push ~0x400
-
- stack_top FDE9FBFF
- FE480296
-
- 11.and(not(eflags),not(~0x400)) = and(eflags,0x400)
- stack_top 02160400
-
- stack_top 02960000
- fffffe48
-
- 12.pop result
- add [pushfw],result
-
- stack_top fe480296 <==> 0296+result
-
- 13.lodsb [index]
- pop _context[index]
-
- _context[index] == 0296
- stack_top fffffe48
-
- 14.pop a
-
- eax == a <==> fffffe48
- stack_top ebp
-
- 15.push lodsw[esi]
- push 0x11
-
- stack_top FF48FFEE
- 0018
-
- 16.push [pushfw]
- stack_top FFEE0296
- 0018FF48
- 17.push [pushfw]
- stack_top 02960296
- FF48FFEE
- 00000018
-
- 18.and(not(pushfw),not(pushfw))
- stack_top FD69FD69
- FF48FFEE
- 00000018
-
- stack_top FFEEFD69
- 0018FF48
-
- 19.and(0x11,pushfw)
- stack_top FF480010 <==> and(0x11,0x269)
- 0018
-
-
- 20.push pushfw
- stack_top 00100296
- 0018FF48
-
- 21.lodb push 0x11
- stack_top 02960011
- FF480010
- 0018
-
-
- 22.and(not(pushfw),not(0x11))
- stack_top 0010FD68
- 0018FF48
-
- 23.and(not(result),not(0x11))
- stack_top FF480287
- 0018
-
- 24.lodb [index]
- push _context[index] <===> push [pushfw]
-
- stack_top 02870296
- 0018FF48
-
- 24.lodb [index]
- push _context[index] <===> push [pushfw]
-
- stack_top 02960296
- FF480287
- 0018
-
- 25.and(296,296)
-
- stack_top 0287FD69
- 0018FF48
-
- 26.lodw ~0x400
- push ~0x400
-
- stack_top FD69FBFF
- FF480287
- 0018
-
- 27.and(0x400,0x296)
-
- stack_top 02870000
- 0018FF48
-
- 28.pop result
- add [esp],result
-
- stack_top FF480287
- 00000018
-
- 29.lodsb [index]
- pop _context[index] <==> result save to context
-
- stack_top 0018FF48
-
- 28.lodsb [index]
- push _context[index]
-
- stack_top 00000000
- 0018FF48
-
复制代码
以上就是cmp的vm流程
hex如下
- 0042FB21 6C CD FD CF 05 38 FC 69
- 0042FB29 C4 C1 B6 08 0C 8E 99 57
- 0042FB31 FF FB 99 3B 5D 08 08 57
- 0042FB39 EE FF B6 08 FA 08 99 99
- 0042FB41 E9 08 A0 11 99 99 B6 08
- 0042FB49 B6 08 99 57 FF FB 99 3B
- 0042FB51 5D 08 18 0C
复制代码
0x10 原由
那么我们先来看看是如何得到这些hex
代码很简单
匹配就行了,那么我们来看看匹配表,注意到上一篇的handle_size == 1488 / 8
恩,vmp实现虚拟引擎的核心可以说就是这些虚拟规则。注意到我是用的这些,而不是186个,因为在写之前,我担心版本太老,所以又去逆了逆v2.12.3,发现框架太体差不多,不过代码量优化了很多。还有昨天看了看大Z哥的帖子,对里面有句话感触很深(它们的价值来自于本身的神秘面纱)。但毕竟吧,vmp也3.x,代码重构了,我想也可以谈一谈了。扯远了。
查看引用表的地方
在看看RandIndexArray的引用,来到这个地方
注意到这里可能是乱序之后的,那么如果说不乱序的话,这个表和vm_opcode的应该是一一对应的关系
举例:
定位到handler_table,
则有
- Handle_471094:
- LODS BYTE PTR DS:[ESI]
- PUSH DWORD PTR DS:[EDI+EAX*4]
- 对应
- 01 02 02 00 00 00 00 00
复制代码
如下:
- struct _vmp_esi_table _esi_table[] = {
- {0x1,0x2,0x2,0x0,0x0,0x0,0x0,0x0,"LODS BYTE PTR DS:[ESI] PUSH DWORD PTR DS:[EDI+EAX*4]" }
- ,{0x1,0x1,0x2,0x0,0x0,0x0,0x0,0x0,"LODS DWORD PTR DS:[ESI] PUSH EAX" }
- ,{0x1,0x2,0x2,0x0,0x1,0x0,0x0,0x0,"PUSH ESP" }
- ,{0x1,0x3,0x2,0x0,0x0,0x0,0x0,0x0,"POP EAX PUSH DWORD PTR ES:[EAX]" }
- ,{0x1,0x3,0x2,0x0,0x1,0x0,0x0,0x0,"POP EAX PUSH DWORD PTR CS:[EAX]" }
- ,{0x1,0x3,0x2,0x0,0x2,0x0,0x0,0x0,"POP EAX PUSH DWORD PTR SS:[EAX]" }
- ,{0x1,0x3,0x2,0x0,0x3,0x0,0x0,0x0,"POP EAX PUSH DWORD PTR DS:[EAX]" }
- ,{0x1,0x3,0x2,0x0,0x4,0x0,0x0,0x0,"POP EAX PUSH DWORD PTR FS:[EAX]" }
- ,{0x1,0x3,0x2,0x0,0x5,0x0,0x0,0x0,"POP EAX PUSH DWORD PTR GS:[EAX]" }
- ,{0x1,0x2,0x1,0x0,0x0,0x0,0x0,0x0,"LODS BYTE PTR DS:[ESI] PUSH WORD PTR DS:[EDI+EAX*4]" }
- ,{0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,"LODS WORD PTR DS:[ESI] ADD AX,BX ADD BX,AX PUSH AX"}
- ,{0x1,0x1,0x1,0x0,0x1,0x0,0x0,0x0,"LODS WORD PTR DS:[ESI] ADD AX,BX ADD BX,AX CWDE PUSH EAX"}
- ,{0x1,0x3,0x1,0x0,0x0,0x0,0x0,0x0,"POP EDX PUSH WORD PTR ES:[EDX]" }
- ,{0x1,0x3,0x1,0x0,0x1,0x0,0x0,0x0,"POP EDX PUSH WORD PTR CS:[EDX]" }
- ,{0x1,0x3,0x1,0x0,0x2,0x0,0x0,0x0,"POP EDX PUSH WORD PTR SS:[EDX]" }
- ,{0x1,0x3,0x1,0x0,0x3,0x0,0x0,0x0,"POP EDX PUSH WORD PTR DS:[EDX]" }
- ,{0x1,0x3,0x1,0x0,0x4,0x0,0x0,0x0,"POP EDX PUSH WORD PTR FS:[EDX]" }
- ,{0x1,0x3,0x1,0x0,0x5,0x0,0x0,0x0,"POP EDX PUSH WORD PTR GS:[EDX]" }
- ,{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"}
- ,{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"}
- ,{0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,"LODS BYTE PTR DS:[ESI] ADD AL,BL ADD BL,AL PUSH AX"}
- ,{0x1,0x1,0x0,0x0,0x1,0x0,0x0,0x0,"LODS BYTE PTR DS:[ESI] ADD AL,BL ADD BL,AL CBW CWDE PUSH EAX"}
- ,{0x1,0x3,0x0,0x0,0x0,0x0,0x0,0x0,"POP EAX MOV AL,BYTE PTR ES:[EDX] PUSH AX"}
- ,{0x1,0x3,0x0,0x0,0x1,0x0,0x0,0x0,"POP EAX MOV AL,BYTE PTR CS:[EDX] PUSH AX"}
- ,{0x1,0x3,0x0,0x0,0x2,0x0,0x0,0x0,"POP EAX MOV AL,BYTE PTR SS:[EDX] PUSH AX"}
- ,{0x1,0x3,0x0,0x0,0x3,0x0,0x0,0x0,"POP EAX MOV AL,BYTE PTR DS:[EDX] PUSH AX"}
- ,{0x1,0x3,0x0,0x0,0x4,0x0,0x0,0x0,"POP EAX MOV AL,BYTE PTR FS:[EDX] PUSH AX"}
- ,{0x1,0x3,0x0,0x0,0x5,0x0,0x0,0x0,"POP EAX MOV AL,BYTE PTR GS:[EDX] PUSH AX"}
- ,{0x1,0x5,0x1,0x0,0x0,0x0,0x0,0x0,"PUSH ES" }
- ,{0x1,0x5,0x1,0x0,0x1,0x0,0x0,0x0,"PUSH CS" }
- ,{0x1,0x5,0x1,0x0,0x2,0x0,0x0,0x0,"PUSH SS" }
- ,{0x1,0x5,0x1,0x0,0x3,0x0,0x0,0x0,"PUSH DS" }
- ,{0x1,0x5,0x1,0x0,0x4,0x0,0x0,0x0,"PUSH FS" }
- ,{0x1,0x5,0x1,0x0,0x5,0x0,0x0,0x0,"PUSH GS" }
- ,{0x1,0x2,0x1,0x0,0x1,0x0,0x0,0x0,"PUSH SP" }
- ,{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]"}
- ,{0x2,0x1,0x2,0x0,0x0,0x0,0x0,0x0,"POP EAX"}
- ,{0x2,0x2,0x2,0x0,0x1,0x0,0x0,0x0,"POP ESP"}
- ,{0x2,0x3,0x2,0x0,0x0,0x0,0x0,0x0,"POP EAX POP DWORD PTR ES:[EAX]"}
- ,{0x2,0x3,0x2,0x0,0x1,0x0,0x0,0x0,"POP EAX POP DWORD PTR CS:[EAX]"}
- ,{0x2,0x3,0x2,0x0,0x2,0x0,0x0,0x0,"POP EAX POP DWORD PTR SS:[EAX]" }
- ,{0x2,0x3,0x2,0x0,0x3,0x0,0x0,0x0,"POP EAX POP DWORD PTR DS:[EAX]" }
- ,{0x2,0x3,0x2,0x0,0x4,0x0,0x0,0x0,"POP EAX POP DWORD PTR FS:[EAX]" }
- ,{0x2,0x3,0x2,0x0,0x5,0x0,0x0,0x0,"POP EAX POP DWORD PTR GS:[EAX]" }
- ,{0x2,0x2,0x1,0x0,0x0,0x0,0x0,0x0,"LODS BYTE PTR DS:[ESI] POP WORD PTR DS:[EDI+EAX*4]" }
- ,{0x2,0x1,0x1,0x0,0x0,0x0,0x0,0x0,"POP AX" }
- ,{0x2,0x3,0x1,0x0,0x0,0x0,0x0,0x0,"POP EAX POP WORD PTR ES:[EAX]" }
- ,{0x2,0x3,0x1,0x0,0x1,0x0,0x0,0x0,"POP EAX POP WORD PTR CS:[EAX]" }
- ,{0x2,0x3,0x1,0x0,0x2,0x0,0x0,0x0,"POP EAX POP WORD PTR SS:[EAX]" }
- ,{0x2,0x3,0x1,0x0,0x3,0x0,0x0,0x0,"POP EAX POP WORD PTR DS:[EAX]" }
- ,{0x2,0x3,0x1,0x0,0x4,0x0,0x0,0x0,"POP EAX POP WORD PTR FS:[EAX]" }
- ,{0x2,0x3,0x1,0x0,0x5,0x0,0x0,0x0,"POP EAX POP WORD PTR GS:[EAX]" }
- ,{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"}
- ,{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"}
- ,{0x1,0x6,0x2,0x0,0x0,0x0,0x0,0x0,"MOV EAX,CR0 PUSH EAX"}
- ,{0x1,0x6,0x2,0x0,0x1,0x0,0x0,0x0,"MOV EAX,CR1 PUSH EAX"}
- ,{0x1,0x6,0x2,0x0,0x2,0x0,0x0,0x0,"MOV EAX,CR2 PUSH EAX"}
- ,{0x1,0x6,0x2,0x0,0x3,0x0,0x0,0x0,"MOV EAX,CR3 PUSH EAX"}
- ,{0x1,0x6,0x2,0x0,0x4,0x0,0x0,0x0,"MOV EAX,CR4 PUSH EAX"}
- ,{0x1,0x6,0x2,0x0,0x5,0x0,0x0,0x0,"MOV EAX,CR5 PUSH EAX"}
- ,{0x1,0x6,0x2,0x0,0x6,0x0,0x0,0x0,"MOV EAX,CR6 PUSH EAX"}
- ,{0x1,0x6,0x2,0x0,0x7,0x0,0x0,0x0,"MOV EAX,CR7 PUSH EAX"}
- ,{0x2,0x6,0x2,0x0,0x0,0x0,0x0,0x0,"POP EAX MOV CR0,EAX"}
- ,{0x2,0x6,0x2,0x0,0x1,0x0,0x0,0x0,"POP EAX MOV CR1,EAX"}
- ,{0x2,0x6,0x2,0x0,0x2,0x0,0x0,0x0,"POP EAX MOV CR2,EAX"}
- ,{0x2,0x6,0x2,0x0,0x3,0x0,0x0,0x0,"POP EAX MOV CR3,EAX"}
- ,{0x2,0x6,0x2,0x0,0x4,0x0,0x0,0x0,"POP EAX MOV CR4,EAX"}
- ,{0x2,0x6,0x2,0x0,0x5,0x0,0x0,0x0,"POP EAX MOV CR5,EAX"}
- ,{0x2,0x6,0x2,0x0,0x6,0x0,0x0,0x0,"POP EAX MOV CR6,EAX"}
- ,{0x2,0x6,0x2,0x0,0x7,0x0,0x0,0x0,"POP EAX MOV CR7,EAX"}
- ,{0x1,0x7,0x2,0x0,0x0,0x0,0x0,0x0,"MOV EAX,DR0 PUSH EAX"}
- ,{0x1,0x7,0x2,0x0,0x1,0x0,0x0,0x0,"MOV EAX,DR1 PUSH EAX"}
- ,{0x1,0x7,0x2,0x0,0x2,0x0,0x0,0x0,"MOV EAX,DR2 PUSH EAX"}
- ,{0x1,0x7,0x2,0x0,0x3,0x0,0x0,0x0,"MOV EAX,DR3 PUSH EAX"}
- ,{0x1,0x7,0x2,0x0,0x4,0x0,0x0,0x0,"MOV EAX,DR4 PUSH EAX"}
- ,{0x1,0x7,0x2,0x0,0x5,0x0,0x0,0x0,"MOV EAX,DR5 PUSH EAX"}
- ,{0x1,0x7,0x2,0x0,0x6,0x0,0x0,0x0,"MOV EAX,DR6 PUSH EAX"}
- ,{0x1,0x7,0x2,0x0,0x7,0x0,0x0,0x0,"MOV EAX,DR7 PUSH EAX"}
- ,{0x2,0x7,0x2,0x0,0x0,0x0,0x0,0x0,"POP EAX MOV DR0,EAX"}
- ,{0x2,0x7,0x2,0x0,0x1,0x0,0x0,0x0,"POP EAX MOV DR1,EAX"}
- ,{0x2,0x7,0x2,0x0,0x2,0x0,0x0,0x0,"POP EAX MOV DR2,EAX"}
- ,{0x2,0x7,0x2,0x0,0x3,0x0,0x0,0x0,"POP EAX MOV DR3,EAX"}
- ,{0x2,0x7,0x2,0x0,0x4,0x0,0x0,0x0,"POP EAX MOV DR4,EAX"}
- ,{0x2,0x7,0x2,0x0,0x5,0x0,0x0,0x0,"POP EAX MOV DR5,EAX"}
- ,{0x2,0x7,0x2,0x0,0x6,0x0,0x0,0x0,"POP EAX MOV DR6,EAX"}
- ,{0x2,0x7,0x2,0x0,0x7,0x0,0x0,0x0,"POP EAX MOV DR7,EAX"}
- ,{0x2,0x1,0x0,0x0,0x0,0x0,0x0,0x0,"POP AX" }
- ,{0x2,0x3,0x0,0x0,0x0,0x0,0x0,0x0,"POP EAX POP AX MOV BYTE PTR ES:[EDX],AL"}
- ,{0x2,0x3,0x0,0x0,0x1,0x0,0x0,0x0,"POP EDX POP AX MOV BYTE PTR CS:[EDX],AL"}
- ,{0x2,0x3,0x0,0x0,0x2,0x0,0x0,0x0,"POP EDX POP AX MOV BYTE PTR SS:[EDX],AL"}
- ,{0x2,0x3,0x0,0x0,0x3,0x0,0x0,0x0,"POP EDX POP AX MOV BYTE PTR DS:[EDX],AL"}
- ,{0x2,0x3,0x0,0x0,0x4,0x0,0x0,0x0,"POP EDX POP AX MOV BYTE PTR FS:[EDX],AL"}
- ,{0x2,0x3,0x0,0x0,0x5,0x0,0x0,0x0,"POP EDX POP AX MOV BYTE PTR GS:[EDX],AL"}
- ,{0x2,0x5,0x1,0x0,0x0,0x0,0x0,0x0,"POP ES" }
- ,{0x2,0x5,0x1,0x0,0x2,0x0,0x0,0x0,"POP SS" }
- ,{0x2,0x5,0x1,0x0,0x3,0x0,0x0,0x0,"POP DS" }
- ,{0x2,0x5,0x1,0x0,0x4,0x0,0x0,0x0,"POP FS" }
- ,{0x2,0x5,0x1,0x0,0x5,0x0,0x0,0x0,"POP GS" }
- ,{0x2,0x2,0x1,0x0,0x1,0x0,0x0,0x0,"POP SP" }
- ,{0x4,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"POP EAX ADD DWORD PTR SS:[ESP],EAX"}
- ,{0x4,0x0,0x2,0x0,0x1,0x0,0x0,0x0,"POP EAX ADD DWORD PTR SS:[ESP],EAX PUSHFW"}
- ,{0x4,0x0,0x1,0x0,0x0,0x0,0x0,0x0,"POP AX ADD DWORD PTR SS:[ESP],AX" }
- ,{0x4,0x0,0x1,0x0,0x1,0x0,0x0,0x0,"POP AX ADD DWORD PTR SS:[ESP],AX PUSHFW" }
- ,{0x4,0x0,0x0,0x0,0x0,0x0,0x0,0x0,"POP AX ADD BYTE PTR SS:[ESP],AL" }
- ,{0x4,0x0,0x0,0x0,0x1,0x0,0x0,0x0,"POP AX ADD BYTE PTR SS:[ESP],AL PUSHFW" }
- ,{0xF6,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"POP EAX NOT EAX NOT DWORD PTR SS:[ESP] AND DWORD PTR SS:[ESP],EAX"}
- ,{0xF6,0x0,0x2,0x0,0x1,0x0,0x0,0x0,"POP EAX NOT EAX NOT DWORD PTR SS:[ESP] AND DWORD PTR SS:[ESP],EAX PUSHFW"}
- ,{0xF6,0x0,0x1,0x0,0x0,0x0,0x0,0x0,"NOT DWORD PTR SS:[ESP] POP AX AND WORD PTR SS:[ESP],AX" }
- ,{0xF6,0x0,0x1,0x0,0x1,0x0,0x0,0x0,"NOT DWORD PTR SS:[ESP] POP AX AND WORD PTR SS:[ESP],AX PUSHFW" }
- ,{0xF6,0x0,0x0,0x0,0x0,0x0,0x0,0x0,"POP AX POP CX NOT AL NOT CL AND AL,CL PUSH AX"}
- ,{0xF6,0x0,0x0,0x0,0x1,0x0,0x0,0x0,"POP AX POP CX NOT AL NOT CL AND AL,CL PUSH AX PUSHFW"}
- ,{0x1C,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"POP EAX POP CX SHL EAX,CL PUSH EAX"}
- ,{0x1C,0x0,0x2,0x0,0x1,0x0,0x0,0x0,"POP EAX POP CX SHL EAX,CL PUSH EAX PUSHFW"}
- ,{0x1C,0x0,0x1,0x0,0x0,0x0,0x0,0x0,"POP AX POP CX SHL AX,CL PUSH AX"}
- ,{0x1C,0x0,0x1,0x0,0x1,0x0,0x0,0x0,"POP AX POP CX SHL AX,CL PUSH AX PUSHFW"}
- ,{0x1C,0x0,0x0,0x0,0x0,0x0,0x0,0x0,"POP AX POP CX SHL AL,CL PUSH AX"}
- ,{0x1C,0x0,0x0,0x0,0x1,0x0,0x0,0x0,"POP AX POP CX SHL AL,CL PUSH AX PUSHFW"}
- ,{0x1D,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"POP EAX POP CX SHR EAX,CL PUSH EAX"}
- ,{0x1D,0x0,0x2,0x0,0x1,0x0,0x0,0x0,"POP EAX POP CX SHR EAX,CL PUSH EAX PUSHFW"}
- ,{0x1D,0x0,0x1,0x0,0x0,0x0,0x0,0x0,"POP AX POP CX SHR AX,CL PUSH AX"}
- ,{0x1D,0x0,0x1,0x0,0x1,0x0,0x0,0x0,"POP AX POP CX SHR AX,CL PUSH AX PUSHFW"}
- ,{0x1D,0x0,0x0,0x0,0x0,0x0,0x0,0x0,"POP AX POP CX SHR AL,CL PUSH AX"}
- ,{0x1D,0x0,0x0,0x0,0x1,0x0,0x0,0x0,"POP AX POP CX SHR AL,CL PUSH AX PUSHFW"}
- ,{0xF8,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"POP EAX POPAD POPFD RETN"}
- ,{0x3D,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"POP EDX POP EAX POP ECX DIV ECX PUSH EAX PUSH EDX"}
- ,{0x3D,0x0,0x1,0x0,0x0,0x0,0x0,0x0,"POP DX POP AX POP CX DIV CX PUSH AX PUSH DX" }
- ,{0x3D,0x0,0x0,0x0,0x0,0x0,0x0,0x0,"POP AX POP CX DIV CL PUSH AX" }
- ,{0x3F,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"POP EDX POP EAX POP ECX IDIV ECX PUSH EAX"}
- ,{0x3F,0x0,0x1,0x0,0x0,0x0,0x0,0x0,"POP DX POP AX POP CX IDIV CX PUSH AX PUSH DX" }
- ,{0x3F,0x0,0x0,0x0,0x0,0x0,0x0,0x0,"POP AX POP CX IDIV CL PUSH AX" }
- ,{0x40,0x0,0x2,0x0,0x1,0x0,0x0,0x0,"POP EDX POP EAX MUL EDX PUSH EAX PUSH EDX PUSHFW" }
- ,{0x40,0x0,0x1,0x0,0x1,0x0,0x0,0x0,"POP DX POP AX MUL EX PUSH AX PUSH DX PUSHFW" }
- ,{0x40,0x0,0x0,0x0,0x1,0x0,0x0,0x0,"POP DX POP AX MUL DL PUSH AX PUSHFW" }
- ,{0x3E,0x0,0x2,0x0,0x1,0x0,0x0,0x0,"POP EDX POP EAX IMUL EDX PUSH EAX PUSH EDX PUSHFW" }
- ,{0x3E,0x0,0x1,0x0,0x1,0x0,0x0,0x0,"POP DX POP AX IMUL DX PUSH AX PUSH DX PUSHFW" }
- ,{0x3E,0x0,0x0,0x0,0x1,0x0,0x0,0x0,"POP DX POP AX IMUL DL PUSH AX PUSHFW"}
- ,{0x1C,0x0,0x3,0x0,0x1,0x0,0x0,0x0,"POP EAX POP EDX POP CX SHLD EAX,EDX,CL PUSH EAX PUSHFW"}
- ,{0x1D,0x0,0x3,0x0,0x1,0x0,0x0,0x0,"POP EAX POP EDX POP CX SHRD EAX,EDX,CL POUSH EAX PUSHFW"}
- ,{0xF7,0x0,0x2,0x0,0x1,0x0,0x0,0x0,"POP EAX POPAD POPFD RETF" }
- ,{0x2E,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"WAIT" }
- ,{0xB6,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"FILD DWORD PTR SS:[ESP]" }
- ,{0xB6,0x0,0x3,0x0,0x0,0x0,0x0,0x0,"FILD QWORD PTR SS:[ESP]" }
- ,{0xBB,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"FLD DWORD PTR SS:[ESP]" }
- ,{0xBB,0x0,0x3,0x0,0x0,0x0,0x0,0x0,"FLD QWORD PTR SS:[ESP]" }
- ,{0xBB,0x0,0x4,0x0,0x0,0x0,0x0,0x0,"FLD TBYTE PTR SS:[ESP]" }
- ,{0xA0,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"FADD DWORD PTR SS:[ESP]" }
- ,{0xA0,0x0,0x3,0x0,0x0,0x0,0x0,0x0,"FADD QWORD PTR SS:[ESP]" }
- ,{0xA4,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"FSUB DWORD PTR SS:[ESP]" }
- ,{0xA4,0x0,0x3,0x0,0x0,0x0,0x0,0x0,"FSUB QWORD PTR SS:[ESP]" }
- ,{0xA5,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"FSUBR DWORD PTR SS:[ESP]" }
- ,{0xA5,0x0,0x3,0x0,0x0,0x0,0x0,0x0,"FSUBR QWORD PTR SS:[ESP]" }
- ,{0xBC,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"FSTP DWORD PTR SS:[ESP]" }
- ,{0xBC,0x0,0x3,0x0,0x0,0x0,0x0,0x0,"FSTP QWORD PTR SS:[ESP]" }
- ,{0xBC,0x0,0x4,0x0,0x0,0x0,0x0,0x0,"FSTP TBYTE PTR SS:[ESP]" }
- ,{0xA6,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"FDIV DWORD PTR SS:[ESP]" }
- ,{0xA6,0x0,0x3,0x0,0x0,0x0,0x0,0x0,"FDIV QWORD PTR SS:[ESP]" }
- ,{0xA1,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"FMUL DWORD PTR SS:[ESP]" }
- ,{0xA1,0x0,0x3,0x0,0x0,0x0,0x0,0x0,"FMUL QWORD PTR SS:[ESP]" }
- ,{0xA3,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"FCOMP DWORD PTR SS:[ESP]" }
- ,{0xA3,0x0,0x3,0x0,0x0,0x0,0x0,0x0,"FCOMP QWORD PTR SS:[ESP]" }
- ,{0xC8,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"FCHS" }
- ,{0xDB,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"FSQRT" }
- ,{0xEE,0x0,0x1,0x0,0x0,0x0,0x0,0x0,"FSTSW AX PUSH AX" }
- ,{0xC6,0x0,0x1,0x0,0x0,0x0,0x0,0x0,"FSTCW WORD PTR SS:[ESP]" }
- ,{0xC4,0x0,0x1,0x0,0x0,0x0,0x0,0x0,"FLDCW WORD PTR SS:[ESP]" }
- ,{0xE3,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"F2XM1" }
- ,{0xC9,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"FABS" }
- ,{0xE6,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"FCLEX" }
- ,{0xE0,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"FCOS" }
- ,{0xD7,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"FDECSTP" }
- ,{0xD8,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"FINCSTP" }
- ,{0xE5,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"FINIT" }
- ,{0xD0,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"FLDLN2" }
- ,{0xCF,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"FLDLG2" }
- ,{0xD9,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"FPREM" }
- ,{0xD6,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"FPREM1" }
- ,{0xD3,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"FPTAN" }
- ,{0xDD,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"FRNDINT" }
- ,{0xDF,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"FSIN" }
- ,{0xE1,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"FTST" }
- ,{0xD2,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"FYL2X" }
- ,{0xD4,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"FPATAN" }
- ,{0xD1,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"FLDZ" }
- ,{0xB8,0x0,0x1,0x0,0x0,0x0,0x0,0x0,"FISTP WORD PTR SS:[ESP]" }
- ,{0xB8,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"FISTP DWORD PTR SS:[ESP]" }
- ,{0xB8,0x0,0x3,0x0,0x0,0x0,0x0,0x0,"FISTP QWORD PTR SS:[ESP]" }
- };
复制代码
Btw:不保证全对哈,最好看看,哈哈
接着我们看一看Vmp_GetVmHandleIndex的调用
ida的有点乱,把这个函数整理之后
- void _func_101()
- {
- _vmp_setIndexToStruct( esi, _vmp_getVmHandlerIndex( esi->_var1_vm_mnemonic, 0, esi->_var3_lval, (esi->ispushfw) != 0);
- }
-
- void _func_104()
- {
- _vmp_setIndexToStruct( esi, _vmp_getVmHandlerIndex( esi->_var1_vm_mnemonic, 0, esi->_var3_lval, 0));
- }
-
- void _func_3(}
- {
- _vmp_setIndexToStruct( esi, _vmp_getVmHandlerIndex( esi->_var1_vm_mnemonic, 0, esi->_var3_lval, 1));
- }
-
- int _getindex( int _n)
- {
- switch(_n)
- {
- case 1:
- return 0;
- case 2:
- return 1;
- case 3:
- return 2;
- case 5:
- return 4;
- case 6:
- return 5;
- default:
- return 3;
- }
- }
-
- _DWORD *__usercall Vmp_FindAndSetTOStruct@<eax>(struct_esi *a1@<eax>, int _size@<ebx>, int _i@<esi>)
- {
- esi->_esi_size = 0;
- if( esi->_var1_vm_mnemonic > 0xc4)
- {
- switch(esi->_var1_vm_mnemonic)
- {
- case 0xC6:
- case 0xC8:
- case 0xC9:
- case 0xCF:
- case 0xD0:
- case 0xD1:
- case 0xD2:
- case 0xD3:
- case 0xD4:
- case 0xD6:
- case 0xD7:
- case 0xD8:
- case 0xD9:
- case 0xDB:
- case 0xDD:
- case 0xDF:
- case 0xE0:
- case 0xE1:
- case 0xE3:
- case 0xE5:
- case 0xE6:
- case 0xEE:
- case 0xF8:
- {
- _func_104();
- return;
- }
- case 0xF6:
- {
- _func_101();
- return;
- }
- case 0xF7:
- {
- _func_3();
- break;
- }
- default:
- return;
- }
- }
-
- if( esi->_var1_vm_mnemonic == 0xC4)
- {
- _func_104();
- return;
- }
- if( esi->_var1_vm_mnemonic > 0x40)
- {
- if( esi->_var1_vm_mnemonic > 0xb6)
- {
- if( esi->_var1_vm_mnemonic != 0xb8 && esi->_var1_vm_mnemonic - 0xbb >= 2)
- {
- return;
- }
- }
- else if( esi->_var1_vm_mnemonic != 0xb6)
- {
- if( esi->_var1_vm_mnemonic == 0x8b)
- {
- esi->_hex = esi->_displacement_immediate;
- esi->size += 4;
- return;
- }
- if( esi->_var1_vm_mnemonic - 0xA0 >= 2 && esi->_var1_vm_mnemonic - 0xA3 >= 4)
- {
- return ;
- }
- }
- _func_104();
- return;
- }
- if ( esi->_var1_vm_mnemonic == 0x40 ) // mul
- _func_104();
- return;
- if ( esi->_var1_vm_mnemonic > 0x2E )
- {
- if ( esi->_var1_vm_mnemonic != 0x3D )
- {
- if ( esi->_var1_vm_mnemonic == 0x3E ) // pop dx
- _func_101();
- return;
- if ( esi->_var1_vm_mnemonic != 0x3F )
- return;
- }
- _func_104();
- return;
- }
- if ( esi->_var1_vm_mnemonic == 0x2E ) // wait
- _func_104();
- return;
- if ( esi->_var1_vm_mnemonic - 1 >= 2 )
- {
- if ( esi->_var1_vm_mnemonic != 4 && esi->_var1_vm_mnemonic - 28 >= 2 )// !=4 || >= 0x1E
- return;
- _func_101();
- return;
- }
- if ( esi->_var1_vm_mnemonic - 1 != 0 )
- {
- if ( esi->_var1_vm_mnemonic == 2 ) // pop
- {
- switch ( _esi->_var2_addressing_mode )
- {
- case 1:
- {
- _vmp_setIndexToStruct( esi, _vmp_getVmHandlerIndex( 2, 1, esi->_var3_lval, 0));// pop eax|ax
- break;
- }
- case 2:
- {
- if ( _esi->_var3_lval >= 3 || _esi->_REG_Index != 4 )
- {
- int flag = !_esi->_var3_lval && (_esi->_REG_Index & 4) == 4;
- _vmp_setIndexToStruct( esi, _vmp_getVmHandlerIndex(2, 2, _esi->_var3_lval, flag);
- _hex2 = Vmp_GetEmptyVMContext(_esi->Struct_vtable_477C54,_esi->_var3_lval,_esi->_REG_Index,1);
- saveToStruct(_esi, _hex2);
- }
- else
- {
- _vmp_setIndexToStruct( esi, _vmp_getVmHandlerIndex(2, 2, _esi->_var3_lval, 1));// pop sp|esp
- }
- break;
- }
- case 3:
- {
- _vmp_setIndexToStruct( esi, _vmp_getVmHandlerIndex(2, 3, _esi->_var3_lval, _getindex(esi->var5));
- break;
- }
- case 5:
- {
- _vmp_setIndexToStruct( esi, _vmp_getVmHandlerIndex(2, 5, 1, _esi->_REG_Index));// pop prefiexreg_index
- break;
- }
- case 6:
- {
- _vmp_setIndexToStruct( esi, _vmp_getVmHandlerIndex(2, 6, 2, _esi->_REG_Index));
- break;
- }
- case 7:
- {
- _vmp_setIndexToStruct( esi, _vmp_getVmHandlerIndex(2, 7, 2, _esi->_REG_Index));
- break;
- }
- default:
- break;
- }
- }
- }
- else if ( _esi->_var2_addressing_mode == 1 )
- {
- switch ( _esi->_rand_switch )
- {
- case 1:
- {
- do
- v5 = rand()%(-1);
- while ( !v5 && 0 == *_esi->_Displacement_Immediate );
- _lval_disp_imm = *_esi->_Displacement_Immediate - v5;
- v6 = sub_47817C(_esi);
- v7 = getStruct_1(_esi->Struct_vtable_477C54, v6 + 1);
- *v7->_Displacement_Immediate = v5;
- Vmp_FindAndSetTOStruct(v7, v5, _lval_disp_imm);
- }
- break;
- case 2:
- {
- do
- v8 = ~*_esi->_Displacement_Immediate & rand()%(-1);
- while ( !v8 && 0 == ~*_esi->_Displacement_Immediate );
- _lval_disp_imm = v8 | ~*_esi->_Displacement_Immediate & ~v8;
- v9 = sub_47817C(_esi);
- v10 = getStruct_1(_esi->Struct_vtable_477C54, v9 + 1);
- *v10->_Displacement_Immediate = v8;
- Vmp_FindAndSetTOStruct(v10, v8, _lval_disp_imm);
- }
- break;
- case 3:
- {
- v11 = 0;
- v12 = *_esi->_Displacement_Immediate;
- while ( !(v12 & 1) ) //偶数
- {
- v12 >>= 1;
- ++v11;
- }
- v13 = System::__linkproc__ RandInt(v11);
- _lval_disp_imm = v13 + 1;
- v14 = *_esi->_Displacement_Immediate >> (v13 + 1);
- v15 = sub_47817C(_esi);
- v16 = getStruct_1(_esi->Struct_vtable_477C54, v15 + 1);
- *v16->_Displacement_Immediate = v14;
- Vmp_FindAndSetTOStruct(v16, v14, _lval_disp_imm);
- break;
- }
- case 4:
- {
- v17 = 0;
- while ( _esi->__var4 == 2 && *_esi->_Displacement_Immediate >= 0 || _esi->__var4 == 1 && (*_esi->_Displacement_Immediate & 0x8000) == 0 )
- {
- *_esi->_Displacement_Immediate *= 2;
- ++v17;
- }
- v19 = System::__linkproc__ RandInt(v17);
- _lval_disp_imm = v19 + 1;
- v20 = *_esi->_Displacement_Immediate << (v19 + 1);
- v21 = sub_47817C(_esi);
- v22 = getStruct_1(_esi->Struct_vtable_477C54, v21 + 1);
- *v22->_Displacement_Immediate = v20;
- Vmp_FindAndSetTOStruct(v22, v20, _lval_disp_imm);
- break;
- }
- default:
- {
- _lval_disp_imm = *_esi->_Displacement_Immediate;
- break;
- }
- }
- if ( _esi->_rand_switch )
- {
- setAddress(&_esi->_esi_hex[8], *(&off_4CE17C + _esi->_var1_vm_interpreter_mnemonic));
- if ( _esi->_var3_lval == 1 )
- {
- a2a = _lval_disp_imm;
- LOBYTE(v66) = 0;
- sub_409984(&str____4x[1], &a2a, 0, v64);
- System::__linkproc__ LStrCat(&_esi->_esi_hex[8], *v64);
- }
- else if ( _esi->_var3_lval == 2 )
- {
- a2a = _lval_disp_imm;
- LOBYTE(v66) = 0;
- sub_409984(&str____8x[1], &a2a, 0, v67);
- System::__linkproc__ LStrCat(&_esi->_esi_hex[8], *v67);
- }
- if ( _esi->__var4 == 1 )
- {
- a2a = *_esi->_Displacement_Immediate;
- LOBYTE(v66) = 0;
- sub_409984(&str___4x[1], &a2a, 0, v62);
- setAddress(&_esi->_esi_hex[12], *v62);
- }
- else if ( _esi->__var4 == 2 )
- {
- a2a = *_esi->_Displacement_Immediate;
- LOBYTE(v66) = 0;
- sub_409984(&str___8x[1], &a2a, 0, v63);
- setAddress(&_esi->_esi_hex[12], *v63);
- }
- }
- else
- {
- Free_Mem(&_esi->_esi_hex[12]);
- }
- if ( _esi->_var3_lval == 1 )
- {
- if ( _lval_disp_imm & 0xFF00 )
- {
- _vmp_setIndexToStruct( esi, _vmp_getVmHandlerIndex( 1, 1, 1, 0);// LODS WORD PTR DS:[ESI] ADD AX,BX ADD BX,AX PUSH AX
- Move_Word(_esi, _lval_disp_imm);
- }
- else
- {
- _vmp_setIndexToStruct( esi, _vmp_getVmHandlerIndex( 1, 1, 0, 0);// LODS BYTE PTR DS:[ESI] ADD AL,BL ADD BL,AL PUSH AX
- saveToStruct(_esi, _lval_disp_imm);
- }
- }
- else if ( _esi->_var3_lval == 2 )
- {
- if ( _esi->_ispushfw & 2 || _lval_disp_imm != Byte_Extension(_lval_disp_imm) )
- {
- if ( _esi->_ispushfw & 2 || _lval_disp_imm != Word_Extension(_lval_disp_imm) )
- {
- _vmp_setIndexToStruct( esi, _vmp_getVmHandlerIndex( 1, 1, 2, 0);// LODS DWORD PTR DS:[ESI] ADD EAX,EBX ADD EBX,EAX PUSH EAX
- Move_Dword(_esi, _lval_disp_imm);
- }
- else
- {
- _vmp_setIndexToStruct( esi, _vmp_getVmHandlerIndex( 1, 1, 1, 1);// LODS WORD PTR DS:[ESI] ADD AX,BX ADD BX,AX CWDE PUSH EAX
- Move_Word(_esi, _lval_disp_imm);
- }
- }
- else
- {
- _vmp_setIndexToStruct( esi, _vmp_getVmHandlerIndex( 1, 1, 0, 1);// LODS BYTE PTR DS:[ESI] ADD AL,BL ADD BL,AL CBW CWDE PUSH EAX
- saveToStruct(_esi, _lval_disp_imm);
- }
- }
- else
- {
- _vmp_setIndexToStruct( esi, _vmp_getVmHandlerIndex( 1, 1, 0, 0);// LODS BYTE PTR DS:[ESI] ADD AL,BL ADD BL,AL PUSH AX
- saveToStruct(_esi, _lval_disp_imm);
- }
- }
- else
- {
- switch ( _esi->_var2_addressing_mode )
- {
- case 2:
- {
- if ( _esi->_var3_lval >= 3 || _esi->_REG_Index != 4 )
- {
- _vmp_setIndexToStruct( esi,_vmp_getVmHandlerIndex(1, 2, _esi->_var3_lval, _esi->_var3_lval == 0 && (_esi->_REG_Index & 4) == 4);//利用空间 push _context[]
- v34 = Vmp_GetEmptyVMContext(_esi->Struct_vtable_477C54,_esi->_var3_lval,_esi->_REG_Index,0);//选择index
- saveToStruct(_esi, v34);
- }
- else
- {
- _vmp_setIndexToStruct( esi, _vmp_getVmHandlerIndex( 1, 2, _esi->_var3_lval, 1);//// push sp|esp
- }
- break;
- }
- case 3:
- {
- _vmp_setIndexToStruct( esi, _vmp_getVmHandlerIndex(1,3,_esi->_var3_lval,_getindex(_esi->_var5));// pop e?x push ? ptr ?
- break;
- }
- case 5:
- {
- _vmp_setIndexToStruct( esi, _vmp_getVmHandlerIndex( 1, 5, 1, _esi->_REG_Index));//push prefix_reg
- break;
- }
- case 6:
- {
- _vmp_setIndexToStruct( esi, _vmp_getVmHandlerIndex( 1, 6, 2, _esi->_REG_Index));//mov eax,cr_index push eax
- break;
- }
- case 7:
- {
- _vmp_setIndexToStruct( esi, _vmp_getVmHandlerIndex( 1, 7, 2, _esi->_REG_Index));// mov eax,dr_index push eax
- break;
- }
- default:
- {
- break;
- }
- }
- }
- }
复制代码
1. 判断vm_mnemonic
2. 再判断寻址方式以及类型
继续,我们看看vm_mnemonic怎么得到的
- 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)
- {
- v8 = (var1->Vtable_477C54->SetCapacity)();
- if ( var6 & 8 )
- Classes::TList::Add(_var1->Ptr_Struct_Vtable_40F3B8, v8);
- v8->_var1_vm_interpreter_mnemonic = _var1_vm_mnemonic;
- v8->_var2_addressing_mode = _var2_addressing_mode;
- v8->_var3_lval_type_byte_word_dword_or_vm_displacement = _3_lval_type;
- if ( var6 & 0x20 )
- v8->_ispushfw |= 0x20u;
- switch ( _var2_addressing_mode ) // 第3个参数进行switch
- {
- case 0:
- if ( _var5_index == 1 )
- v8->_ispushfw |= 1u;
- else
- v8->_ispushfw &= 0xFEu;
- break;
- case 1: // 先判断类型 第4个参数进行判断
- if ( _3_lval_type < 1u ) // [base]
- {
- *v8->_Displacement_Immediate = (char)_var5_index;
- }
- else if ( _3_lval_type == 1 ) // [base + disp8]
- {
- *v8->_Displacement_Immediate = (short)_var5_index;
- }
- else // [base + disp32]
- {
- *v8->_Displacement_Immediate = _var5_index;
- }
- if ( var6 & 0x10 )
- {
- v8->_ispushfw |= 8u;
- v9 = var7;
- v8->_init0xffff_oppositecondition = var7;
- }
- if ( var6 & 2 )
- v8->_ispushfw |= 2u;
- if ( var6 & 1 )
- {
- LOBYTE(v9) = 1;
- v31 = 1;
- }
- else
- {
- LOBYTE(v9) = 0;
- v31 = 0;
- }
- if ( var6 & 0x40 )
- v31 |= 0x40u;
- if ( var6 & 4 )
- {
- if ( _3_lval_type >= 3 ) // qword的拆分吗
- {
- if ( _var1->Struct_Vtable_477E80->Struct_Vtable_477F00->_vm_type & 4 )
- {
- v8->__var4 = _3_lval_type;
- _rand_type[0] = 1;
- _rand_type[2] = 1;
- if ( statisticsbinaryis1count(~*v8->_Displacement_Immediate, _3_lval_type) >= 3u )// 统计奇数为 大于3
- {
- _rand_type[1] = 2;
- _rand_type[3] = 2;
- }
- else
- {
- _rand_type[1] = 1;
- _rand_type[3] = 1;
- }
- if ( !(v8->_ispushfw & 2) && *v8->_Displacement_Immediate )
- {
- if ( !(v8->_Displacement_Immediate[0] & 1) )
- _rand_type[2] = 3;
- if ( _3_lval_type == 2 && v8->_Displacement_Immediate[3] >= 0
- || _3_lval_type == 1 && v8->_Displacement_Immediate[1] >= 0 )
- {
- _rand_type[3] = 4;
- }
- }
- v8->_rand_switch = _rand_type[rand()%4];
- switch ( v8->_rand_switch )
- {
- case 1:
- {
- Vmp_SetEsiStruct(_var1, 1, 1, _3_lval_type, 0, v31 | 2, -1);// LODS DWORD PTR DS:[ESI] PUSH EAX
- Vmp_SetEsiStruct(_var1, 4, 0, _3_lval_type, 0, v31, -1);// POP EAX ADD DWORD PTR SS:[ESP],EAX
- break;
- }
- case 2:
- {
- Vmp_SetEsiStruct(_var1, 1, 1, _3_lval_type, 0, v31 | 2, -1);
- 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
- break;
- }
- case 3:
- {
- v8->_var3_lval_type_byte_word_dword_or_vm_displacement = 1;
- Vmp_SetEsiStruct(_var1, 1, 1, _3_lval_type, 0, v31 | 2, -1);
- LOBYTE(v9) = Vmp_SetEsiStruct(_var1, 0x1C, 0, _3_lval_type, 0, v31, -1);// POP EAX POP CX SHL EAX,CL PUSH EAX
- break;
- default:
- if ( v8->_rand_switch == 4 )
- {
- v8->_var3_lval_type_byte_word_dword_or_vm_displacement = 1;
- Vmp_SetEsiStruct(_var1, 1, 1, _3_lval_type, 0, v31|2, -1);//LODS DWORD PTR DS:[ESI] PUSH EAX
- Vmp_SetEsiStruct(_var1, 0x1D, 0, _3_lval_type, 0, v31, -1);// POP EAX POP CX SHR EAX,CL PUSH EAX
- }
- break;
- }
- }
- }
- }
- }
- }
- if ( _3_lval_type == 2 && var6 & 0x10 && _1_interpreter_mnemonic != 0x8Bu )// [base + disp32]
- {
- if ( var7 == -1 )
- {
- v9 = 3;
- }
- else
- {
- v9 = sub_479128(*&_var1->Struct_Vtable_477E80->Struct_Vtable_477F00->Struct_table_477E80->field_60, var7)->field_C;
- }
- switch(v9)
- {
- case 3:
- {
- Vmp_SetEsiStruct(_var1, 1, 2, 2, 10, v31, -1);//LODS BYTE PTR DS:[ESI] PUSH DWORD PTR DS:[EDI+EAX*4]
- Vmp_SetEsiStruct(_var1, 4, 0, 2, 0, v31, -1);//POP EAX ADD DWORD PTR SS:[ESP],EAX
- break;
- }
- case 2:
- {
- Vmp_SetEsiStruct(_var1, 1, 1, 1, 0, v31, -1);//LODS WORD PTR DS:[ESI] PUSH AX
- Vmp_SetEsiStruct(_var1, 1, 2, 1, 10, v31, -1);//LODS BYTE PTR DS:[ESI] PUSH WORD PTR DS:[EDI+EAX*4]
- Vmp_SetEsiStruct(_var1, 4, 0, 2, 0, v31, -1);//POP EAX ADD DWORD PTR SS:[ESP],EAX
- break;
- }
- case 1:
- {
- Vmp_SetEsiStruct(_var1, 1, 2, 2, 10, v31, -1);// LODS BYTE PTR DS:[ESI] PUSH DWORD PTR DS:[EDI+EAX*4]
- Vmp_SetEsiStruct(_var1, 2, 1, 1, 0, v31, -1);// LODS BYTE PTR DS:[ESI] POP WORD PTR DS:[EDI+EAX*4]
- Vmp_SetEsiStruct(_var1, 1, 1, 1, 0, v31, -1);// LODS WORD PTR DS:[ESI] PUSH AX
- Vmp_SetEsiStruct(_var1, 4, 0, 2, 0, v31, -1);// POP EAX ADD DWORD PTR SS:[ESP],EAX
- break;
- }
- }
- if ( !(var6 & 0x40) && !(var6 & 8) && _1_interpreter_mnemonic == 1 )
- {
- if ( _var1->Struct_Vtable_477E80->Struct_Vtable_477F00->_vm_type & 0x20 )
- {
- v9 = rand()%2 - 1;
- if ( !v9 )//(int)[esp] += [[esi]]
- {
- v31 |= 0x40u;
- v23 = sub_48BC1C(_var1->Struct_Vtable_477E80->Struct_Vtable_477F00, &v30);
- Vmp_SetEsiStruct(_var1, 1, 1, 2, v30, v31 | 0x14, -1);// LODS DWORD PTR DS:[ESI] PUSH EAX
- Vmp_SetEsiStruct(_var1, 1, 3, _3_lval_type, 0, v31, -1);// POP EAX PUSH DWORD PTR SS:[EAX]
- Vmp_SetEsiStruct(_var1, 1, 1, _3_lval_type, -v23, v31 | 4, -1);// LODS DWORD PTR DS:[ESI] PUSH EAX
- Vmp_SetEsiStruct(_var1, 4, 0, _3_lval_type, 0, v31, -1);// POP EAX
- Vmp_SetEsiStruct(_var1, 4, 0, _3_lval_type, 0, v31, -1);// POP EAX ADD DWORD PTR SS:[ESP],EAX
- }
- }
- }
- break;
- case 2:
- case 5:
- case 6:
- case 7:
- v8->_REG_Index = _var5_index;
- break;
- case 3:
- v8->field_F = _var5_index;
- break;
- default:
- break;
- }
- if ( var6 & 1 ) // 奇数成立
- Vmp_FindAndSetTOStruct(v8, var6, v8);// Make
- return v9;
- }
复制代码
可以发现由传参决定并对于某些方式递归调用
继续寻找怎么来的
定位到cmp。看看vmp是如何实现对cmp,jcc的膨胀的
首先可以很直观的看到,在早期版本中
把sub cmp sbb放在一起来处理
那么看看是如何usedisasmstruct的
- char __usercall _get_prefix@<al>(int index@<eax>, int a2)
- {
- _operand = ( _disasm + 21 * _operand_index + 24)
- if ( _disasm.About_Prefixes == 4 )
- return 0;
- if ( _disasm.About_Prefixes == 0
- && (v2->FirstVar_Trans_ModRM_mod & 0x10
- && (v2->ThirdVar_SIB__Base_Index - 4) < 2
- || v2->FirstVar_Trans_ModRM_mod & 4
- && (v2->SecondVar_Trans_ModRM_rm_Index - 4) < 2) )
- {
- return 3;
- }
- return _disasm.About_Prefixes;
- }
-
-
-
- int __usercall Vmp_UseDisasmStruct@<eax>(int _operand_index@<eax>, char a2@<dl>, int a3@<ecx>, int a4@<ebx>, int a5)
- {
- _operand = ( _disasm + 21 * _operand_index + 24);
- if ( _operand.FirstVar_Trans_ModRM.mod == 0 ) // FirstVar_Trans_ModRM.mod == 0 return
- return 0;
- int ret = 1;
- if ( a2 & 4 )
- {
- _Type = 1;
- }
- else if ( a2 & 8 )
- {
- _Type = 2;
- }
- else
- {
- _Type = _operand->About_Lval_Byte_Word_Dword;
- }
- BYTE1(__n) = 0;
- if ( _operand->FirstVar_Trans_ModRM_mod == 0x24 )// prefix
- {
- if ( a2 & 1 && (__n = *(a5 - 4), *(__n + 22) != 1) )// != push
- {
- _vmp_SetEsiStruct(*(a5 - 4), 2, 5, 1, _operand->SecondVar_Trans_ModRM_rm_Index, 0, -1);// POP PREFIX
- if ( _Type == 2 )
- {
- _vmp_SetEsiStruct(*(a5 - 4), 2, 1, 1, 0, 0, -1);// POP AX
- }
- }
- else // pop
- {
- if ( _Type == 2 )
- {
- _vmp_SetEsiStruct(*(a5 - 4), 1, 1, 1, 0, 0, -1);// LODS WORD PTR DS:[ESI] PUSH AX
- }
- _vmp_SetEsiStruct(*(a5 - 4), 1, 5, 1, _operand->SecondVar_Trans_ModRM_rm_Index, 0, -1);// PUSH PREFIX
- }
- }
- else if ( _operand->FirstVar_Trans_ModRM_mod == 0x84 )// DR?
- {
- if ( a2 & 1 && _disasm->Mnemonic_Counter_4CE17C != 1 ) // Mnemonic_Counter_4CE17C != 1 push
- {
- _vmp_SetEsiStruct(*(a5 - 4), 2, 7, 2, _operand->SecondVar_Trans_ModRM_rm_Index, 0, -1);// POP EAX MOV DR?,EAX
- }
- else
- {
- _vmp_SetEsiStruct(*(a5 - 4), 1, 7, 2, _operand->SecondVar_Trans_ModRM_rm_Index, 0, -1);// MOV EAX,DR? PUSH EAX
- }
- }
- else
- {
- if ( _operand->FirstVar_Trans_ModRM_mod == 0x44 )// CR?
- {
- if ( a2 & 1 && _disasm->Mnemonic_Counter_4CE17C != 1 ) // push
- {
- _vmp_SetEsiStruct(*(a5 - 4), 2, 6, 2, _operand->SecondVar_Trans_ModRM_rm_Index, 0, -1);// POP EAX MOV CR?,EAX
- }
- else
- {
- _vmp_SetEsiStruct(*(a5 - 4), 1, 6, 2, _operand->SecondVar_Trans_ModRM_rm_Index, 0, -1);// MOV CR?,EAX PUSH EAX
- }
- }
- else
- {
- if ( _operand->FirstVar_Trans_ModRM_mod & 2 )
- {
- if ( _operand->FirstVar_Trans_ModRM_mod & 8 )
- _Size = 2; // 0xC 0xE
- else
- _Size = _Type;
- v15 = _operand->RestHex_Lval_Displacement_Immediate;
- RestHex_Displacement_Immediate = _operand->RestHex_Lval_Displacement_Immediate;
- if ( _operand->Lavl_Btye_Word_Dword ) // if(v8->Lavl_Btye_Word_Dword != 0)
- {
- if ( _operand->Lavl_Btye_Word_Dword == 1 && _Size == 2 ) // word
- {
- RestHex_Displacement_Immediate = Word_Extension(_operand->RestHex_Lval_Displacement_Immediate);
- }
- }
- else if ( _Size == 2 ) // dword
- {
- RestHex_Displacement_Immediate = Byte_Extension(_operand->RestHex_Lval_Displacement_Immediate);
- }
- else if ( _Size == 1 ) // word
- {
- RestHex_Displacement_Immediate = Byte_Extension_Word(_operand->RestHex_Lval_Displacement_Immediate);
- }
- if ( !(_operand->FirstVar_Trans_ModRM_mod & 8) && _a2 & 2 )
- {
- if ( _disasm->Mnemonic_Counter_4CE17C != 0x13 && _disasm->Mnemonic_Counter_4CE17C != 0x43 )// sbb 0x44不算
- // Opcode_counter_4CE17C != 19 || != 67
- // _str_sub || _str_cmp
- RestHex_Displacement_Immediate = ~RestHex_Displacement_Immediate;// 反码
- else
- RestHex_Displacement_Immediate = -RestHex_Displacement_Immediate;//
- // sub || cmp
- // 补码
- }
- if ( _operand->Lavl_Btye_Word_Dword == 2 )
- {
- __Type1 = 4;
- v16 = *(*(a5 - 4) + 0x80);
- if ( v16 && *(v16 + 8) )
- __Type1 = 0xE;
- }
- else
- {
- __Type1 = 0;
- }
- if ( _operand->Fix > 0xFFFFFFFF || (_disasm->Mnemonic_Counter_4CE17C + 0xC) < 2u && !_operand_index && _operand->FirstVar_Trans_ModRM_mod == 2 )// _disasm->Mnemonic_Counter_4CE17C <===> mnemonic
- {
- __Type1 |= 0x10u;
- } // 到时候好从[esi]读出补码或反码
- // 在push
- // 那么下面就是与输入的数进行and
- _vmp_SetEsiStruct(*(a5 - 4), 1, 1, _Size, RestHex_Displacement_Immediate, __Type1, _operand->Fix);
- } // lods immediate push eax
- if ( _operand->FirstVar_Trans_ModRM_mod & 4 )
- {
- if ( _operand->FirstVar_Trans_ModRM_mod & 8 )
- {
- if ( _operand->SibFirstVar_SIB_Scable_Index )
- {
- _vmp_SetEsiStruct(*(a5 - 4), 1, 1, 1, _operand->SibFirstVar_SIB_Scable_Index, 0, -1);// LODS WORD PTR DS:[ESI] PUSH EAX
- }
- if ( _operand->About_RegType_8_16_32 == 1 )
- {
- _vmp_SetEsiStruct(*(a5 - 4), 1, 1, 1, 0, 0, -1);// LODS WORD PTR DS:[ESI] PUSH AX
- }
- _vmp_SetEsiStruct( *(a5 - 4), 1, 2, _operand->About_RegType_8_16_32, _operand->SecondVar_Trans_ModRM_rm_Index,0,-1);
- if ( _operand->SecondVar_Trans_ModRM_rm_Index == 4 )// sp
- sub_486A30(2u, a5);
- }
- else
- {
- if ( _a2 & 1 && _disasm->Mnemonic_Counter_4CE17C != 1 )
- {
- _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]
- }
- else
- {
- _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]
- }
- if ( _Type < 3 && _operand->SecondVar_Trans_ModRM_rm_Index == 4 && !(_a2 & 1) )
- sub_486A30(_Type, a5);//ADD DWORD PTR SS:[ESP],LODSD DS:[ESI]
- }
- }
- if ( _operand->FirstVar_Trans_ModRM_mod & 8 )
- {
- if ( _operand->FirstVar_Trans_ModRM_mod & 4 && _operand->SibFirstVar_SIB_Scable_Index )
- {
- _vmp_SetEsiStruct(*(a5 - 4), 28, 0, 2u, 0, 0, -1);
- }
- if ( _operand->FirstVar_Trans_ModRM_mod & 0x10 )
- {
- if ( _operand->About_RegType_8_16_32 == 1 )
- {
- _vmp_SetEsiStruct(*(a5 - 4), 1, 1, 1u, 0, 0, -1);
- }
- _vmp_SetEsiStruct(*(a5 - 4), 1, 2, _operand->About_RegType_8_16_32, _operand->ThirdVar_SIB__Base_Index, 0, -1);
- if ( _operand->ThirdVar_SIB__Base_Index == 4 )
- sub_486A30(2, a5);//ADD DWORD PTR SS:[ESP],LODSD DS:[ESI]
- if ( _operand->FirstVar_Trans_ModRM_mod & 4 )
- {
- _vmp_SetEsiStruct(*(a5 - 4), 4, 0, 2u, 0, 0, -1);
- }
- }
- if ( _operand->FirstVar_Trans_ModRM_mod & 2 && (_operand->FirstVar_Trans_ModRM_mod & 4 || _operand->FirstVar_Trans_ModRM_mod & 0x10) )
- {
- _vmp_SetEsiStruct(*(a5 - 4), 4, 0, 2u, 0, 0, -1);
- }
- if ( !(_a2 & 0x10) )//addressing prefix:[eax]
- {
- if ( _a2 & 1 )
- {
- v25 = _get_prefix(__operand_index, a5) & 0x7F;
- _vmp_SetEsiStruct(*(a5 - 4), 2, 3, _Type, v25, 0, -1);//POP EAX POP DWORD PTR prefix:[EAX]
- }
- else
- {
- v27 = _get_prefix(__operand_index, a5) & 0x7F;
- _vmp_SetEsiStruct(*(a5 - 4), 1, 3, _Type, v27, 0, -1);//POP EAX PUSH DWORD PTR prefix:[EAX]
- }
- }
- }
- }
- }
- return ret;
- }
复制代码
结合刚开始给的,则有先读operand[1]
注意到:
- if ( _disasm->Mnemonic_Counter_4CE17C != 0x13 && _disasm->Mnemonic_Counter_4CE17C != 0x43 )
- // sbb 0x44不算 Opcode_counter_4CE17C != 19 || != 67 _str_sub || _str_cmp
- RestHex_Displacement_Immediate = ~RestHex_Displacement_Immediate;// 反码
- else
- RestHex_Displacement_Immediate = -RestHex_Displacement_Immediate;// sub || cmp 补码
复制代码
然后其他的对应膨胀规则看看就明白了
分析sub_485884
分析sub_4857DC
可以看到这整套就是一个计算好初始eflags,然后压入_context的过程
分析sub_4858E0
这里就没注释了,可以对照规则
至此,早期版本中的cmp就这样vm了
一个细节的地方
注意到Vmp_SetEsiStruct函数
- v8 = (var1->Vtable_477C54->SetCapacity)();
- if ( var6 & 8 )
- Classes::TList::Add(_var1->Ptr_Struct_Vtable_40F3B8, v8);
复制代码
那么我们可以这样理解,在早期版本
vm的基本单位是指令,而指令通过反编译得到 ----> _struct_disasm
加上一个list,抽象出来
- _struct_disasm
- {
- ……
- …..
- list<?> ls;
- };
复制代码
注意到esi是怎样生成的,通过那些规则,故
- _struct_disasm
- {
- ……
- …..
- list<_struct_esi> ls;
- };
复制代码
同时我们可以猜一猜vmp设计的思路
一开始应该是vm的各种运算(add sub mul xor)
这个不难,如果叫我们来实现,直接将代码替换就可以了
- 稍微面向一点
- switch(mnemonic)
- {
- case _sub:
- case _cmp
- }
- 再面向一些,查表
- int _table[] = {1,2,3,4……}
- switch(mnemonic)
- {
- case _sub:
- index = 1;
- case _cmp:
- index = 2;
- }
复制代码
最后在进行匹配
我不知道其他的vm引擎是怎么设计的,如果是我写的话应该也会这样。
第一步可以看成写编译器的语法分析
- 另外
- {0xF6,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"POP EAX NOT EAX NOT DWORD PTR SS:[ESP] AND DWORD PTR SS:[ESP],EAX"}
- 这个0xf6取得蛮有意思的
复制代码
在说说jcc
注意到
这几个参数,已上个帖子提到
恩,很多人爆破提到的shr。这个我想动态跟一跟,因为我觉得设计得很好
- push add1
-
- push 0
- add [add1],0
- stack_top 0042fbcd
-
- push addr2
- push 0
- add [addr2],0 //这两个地址很有意思
- stack_top 0042fb9b
- 0042fbcd
-
- lodw [not(0x40)]
- push not(0x40
- lodb [index]
- push _context[index] ----> push eflags
- stack_top ffbf0287
-
-
- not [esp] ---> 0040fd78
- pop ax
- and [esp],ax
- stack_top fb9b0040
- fbcd0042
- 0042
-
- losb [index]
- pop _context[index] ---> 0x40
- stack_top 42fb9b
- 42fbcb
- 001848
-
- losb [4]
- push 4
- stack_top fb9b0004
- fbcd0042
- 0042
-
- Lodb [index]
- Push _context[_index]
- Stack_top 00040040
- 0042fb9b
- 0042fbcd
-
- Pop ax
- Pop cx
- Shr ax,cl ---> result == 0x4
- Push ax
- Stack_top fb9b0004
- Fbcd0042
- 0042
-
- //这个4很有意思
- Lodb [index]
- Pop _context[index] ---> 4
- stack_top 0042fb9b
- 0042fbcd
-
-
- Push esp //注意到这里
- stack_top 0018FE98(addr_42fb9b)
- 0042FB9B
- 0042FBCD
-
-
- Lodsb [index]
- Push ax --> 0
- Stack_top fe98000
- Fb9b0018
- Fbcd0042
- Ff480042
-
-
- Lodsb [index]
- Push _context[index] ---> 0x4
- Stack_top 00000004
- 0018fe98
- Pop eax ---> eax == 0x4
- add [esp],eax
- stack_top 0018FE98(addr_42fb9b)
- 0042FB9B
- 0042FBCD
复制代码
注意到这里,很重要
vmp先压了两个地址然后取eflags运算进行shr,通常会得到4
那么这个4是用来干什么的
我们看看这两个地址的内容
- 恩,没错。实现了分支
- 在注意到这里的地址
-
- Stack_top 0018fe9c(addr_0042fbcd)
- 0042fb9b
- 0042fbcd
-
- Pop eax
- Push [eax]
- Stack_top 0042fbcd
- 0042fb9b
- 0042fbcd
-
- 但是有个问题,vmp怎么修改esi
- Lodsd [vmp_entry]
- Push vmp_entry
- Stack_top 0042F000(vmp_entry)
- 00000000(_addressing)
- 0042fbcd
-
- Pop eax
- Add [esp],eax
- Stack_top 0042f000
- 0042fbcd
-
- 保存环境
-
- Stack_top 00000000
- 0018FEF4
- 00000000
- 0018FEF4
- 0018FE84
- 7EFDE000
- 00000000
- 00425036
- 00000001
- 00000287
- 0042F000
- 0042FBCD
复制代码
这样就返回vm_entry,改变esi了
看到这,相信大家应该有很多爆破的思路了吧
0x11 结束语
就这样,先写到这里
|