看雪论坛
发新帖

[原创]VM代码的还原-插件篇

bambooqj 2017-5-15 12:32 2088

首先,先给出几个工具.大概都是伪码类的.之前也介绍过.
首先推荐的是zdhysd 师傅的VMP分析插件 1.4 之前介绍过了..

下载地址:http://bbs.pediy.com/thread-154621.htm


剩下的大家也都用过.一个是木木老师的OoWoodOne 堪比Ximo师傅的zeus 个人用的觉得比zeus更好用一点.而且带源码.

下载地址:http://bbs.pediy.com/thread-203683.htm


其他的一些ximo老师的zeus,noboy老师FkVMP 之类的大家都熟悉就不提了..

伪码类的VMP分析插件 1.4 用起来很好.除了某些小问题.而且最主要可以自定义规则识别.这个是很强大的地方..如果,对代码很熟悉那么还原起来 还是比较快的.只不过是手动还原罢了.容易出错.这些主要都是逻辑还原.本人觉得从技术上来讲纯asm还原并不现实.因为,我们所谓的轮转机制只不过是一个用寄存器体系 去理解的VM.跟实际寄存器并没有什么关系. 对于VM分析来讲  你用的是哪个寄存器 对我们对VM进行分析 并无影响.可以用伪码进行代表 还原逻辑.然后 再反推寄存器.这是一个很大的工程..根据我已知的消息.其实 已经有很多还原引擎 只不过 我们这些菜鸟未曾一见. 比如大部分cug ccg的前辈....好啦 吹逼就到这里.VM机制不是这个帖子要讲的.如果要讲 也不是我这个菜鸟能讲的..我只聊聊插件怎么用...233333

很早之前用过VMSweeper1.4  觉得不太好用 之后就没有关注过.然后,这几天有个项目要还原VM.开始的时候 用ZEUS 分析好vmhandler 然后到VMVMP 也就是 disp什么的那个地方 分配跳转的..英文不好.专业名词不会.大概理解吧...手动记事本写了三页..瞬间觉得不是人做的工作..心好痛.又不会编程.得了吧..找找现成插件吧..开始的时候用的VM 分析插件 handler 分析没错 但是算法分析有问题.调试起来问题很多..蛋疼的一腿..然后 就拿起了.VMSweeper 但是,还是不行.局限性太大...可是 默默的发现了 这玩意 还原VM还原起来 很是舒服啊. 除了很多插件上的BUG 但是 堆栈反推没有出错.于是有了这篇文章.

事先说明.这些插件使用的局限性很大.毕竟一个系统的还原插件不是一时可以写出来的.就算写出来 大部分师傅 也只是 扔着烂硬盘....对 别看别人 就是你brack老师....这篇文章 我只是简单讲解一下.实际应用之中会遇到很多问题.大部分时候不适合实际应用....

开课:


先上未被VM时候的原始代码

004010A1  /.  55            push ebp
004010A2  |.  8BEC          mov ebp,esp
004010A4  |.  81EC 0C000000 sub esp,0xC
004010AA  |.  C745 FC 00000>mov [local.1],0x0
004010B1  |.  C745 F8 00000>mov [local.2],0x0
004010B8  |.  EB 10         jmp short 测试.004010CA
004010BA  |.  56 4D 50 72 6>ascii "VMProtect begin",0
004010CA  |>  B8 A8E64700   mov eax,测试.0047E6A8                      ;  ASCII "23333"
004010CF  |.  50            push eax
004010D0  |.  8B5D FC       mov ebx,[local.1]
004010D3  |.  85DB          test ebx,ebx
004010D5  |.  74 09         je short 测试.004010E0
004010D7  |.  53            push ebx
004010D8  |.  E8 00010000   call 测试.004011DD                         ;  jmp 到 <测试.内存释放>
004010DD  |.  83C4 04       add esp,0x4
004010E0  |>  58            pop eax
004010E1  |.  8945 FC       mov [local.1],eax
004010E4  |.  B8 AEE64700   mov eax,测试.0047E6AE                      ;  你猜
004010E9  |.  50            push eax
004010EA  |.  8B5D F8       mov ebx,[local.2]
004010ED  |.  85DB          test ebx,ebx
004010EF  |.  74 09         je short 测试.004010FA
004010F1  |.  53            push ebx
004010F2  |.  E8 E6000000   call 测试.004011DD                         ;  jmp 到 <测试.内存释放>
004010F7  |.  83C4 04       add esp,0x4
004010FA  |>  58            pop eax
004010FB  |.  8945 F8       mov [local.2],eax
004010FE  |.  8B45 F8       mov eax,[local.2]
00401101  |.  50            push eax
00401102  |.  FF75 FC       push [local.1]
00401105  |.  E8 FAFEFFFF   call <测试.文本比较>
0040110A  |.  83C4 08       add esp,0x8
0040110D  |.  83F8 00       cmp eax,0x0
00401110  |.  0F85 46000000 jnz 测试.0040115C
00401116  |.  68 04000080   push 0x80000004
0040111B  |.  6A 00         push 0x0
0040111D  |.  8B45 F8       mov eax,[local.2]
00401120  |.  85C0          test eax,eax
00401122  |.  75 05         jnz short 测试.00401129
00401124  |.  B8 B3E64700   mov eax,测试.0047E6B3
00401129  |>  50            push eax
0040112A  |.  68 01030080   push 0x80000301
0040112F  |.  6A 00         push 0x0
00401131  |.  68 00000000   push 0x0
00401136  |.  68 04000080   push 0x80000004
0040113B  |.  6A 00         push 0x0
0040113D  |.  8B45 FC       mov eax,[local.1]
00401140  |.  85C0          test eax,eax
00401142  |.  75 05         jnz short 测试.00401149
00401144  |.  B8 B3E64700   mov eax,测试.0047E6B3
00401149  |>  50            push eax
0040114A  |.  68 03000000   push 0x3
0040114F  |.  BB B0124000   mov ebx,<测试.未知命令>
00401154  |.  E8 8A000000   call 测试.004011E3                         ;  jmp 到 <测试.核心库命令调用>
00401159  |.  83C4 28       add esp,0x28
0040115C  |>  EB 0E         jmp short 测试.0040116C
0040115E  |.  56 4D 50 72 6>ascii "VMProtect end",0
0040116C  |>  8B5D FC       mov ebx,[local.1]
0040116F  |.  85DB          test ebx,ebx
00401171  |.  74 09         je short 测试.0040117C
00401173  |.  53            push ebx
00401174  |.  E8 64000000   call 测试.004011DD                         ;  jmp 到 <测试.内存释放>
00401179  |.  83C4 04       add esp,0x4
0040117C  |>  8B5D F8       mov ebx,[local.2]
0040117F  |.  85DB          test ebx,ebx
00401181  |.  74 09         je short 测试.0040118C
00401183  |.  53            push ebx
00401184  |.  E8 54000000   call 测试.004011DD                         ;  jmp 到 <测试.内存释放>
00401189  |.  83C4 04       add esp,0x4
0040118C  |>  8BE5          mov esp,ebp
0040118E  |.  5D            pop ebp
0040118F  \.  C3            retn

很明显啦易语言代码...反正我菜...


以下为VM后代码.

004010A1   .  55            push ebp
004010A2   .  8BEC          mov ebp,esp
004010A4   .  81EC 0C000000 sub esp,0xC
004010AA   .  C745 FC 00000>mov dword ptr ss:[ebp-0x4],0x0
004010B1   .  C745 F8 00000>mov dword ptr ss:[ebp-0x8],0x0
004010B8   .- E9 BB4F0B00   jmp 测试_vmp.004B6078
004010BD   .- E9 5F250B00   jmp 测试_vmp.004B3621
004010C2   .  66:8945 04    mov word ptr ss:[ebp+0x4],ax
004010C6   .  E8 B8430B00   call 测试_vmp.004B5483
004010CB   .  E8 C5270B00   call 测试_vmp.004B3895
004010D0   .- E9 61460B00   jmp 测试_vmp.004B5736
004010D5   .  66:890C24     mov word ptr ss:[esp],cx
004010D9   .  f3:9c         rep pushfd
004010DB   .  8F0424        pop dword ptr ss:[esp]
004010DE   .- E9 66470B00   jmp 测试_vmp.004B5849
004010E3   .  F6C5 82       test ch,0x82
004010E6   .  0FBAE1 11     bt ecx,0x11
004010EA   .  F6D0          not al
004010EC   .  9C            pushfd
004010ED   .  F8            clc
004010EE   .  66:0FBAE1 0D  bt cx,0xD
004010F3   .  F6D2          not dl
004010F5   .  9C            pushfd
004010F6   .  83ED 02       sub ebp,0x2
004010F9   .  38C0          cmp al,al
004010FB   .  9C            pushfd
004010FC   .  38F6          cmp dh,dh
004010FE   .  66:81FA C6CB  cmp dx,0xCBC6
00401103   .  20D0          and al,dl
00401105   .  60            pushad
00401106   .  E8 DC320B00   call 测试_vmp.004B43E7
0040110B   .  877424 3C     xchg dword ptr ss:[esp+0x3C],esi
0040110F   .  66:FFCE       dec si
00401112   .  FF35 4D364B00 push dword ptr ds:[0x4B364D]
00401118   .  8F4424 38     pop dword ptr ss:[esp+0x38]
0040111C   .  F7D6          not esi
0040111E   .  66:0FBEF1     movsx si,cl
00401122   .  C74424 34 000>mov dword ptr ss:[esp+0x34],0x0
0040112A   .  66:FFC6       inc si
0040112D   .  8DB6 E17141B8 lea esi,dword ptr ds:[esi+0xB84171E1]
00401133   .  66:BE 82B3    mov si,0xB382
00401137   .  8B7424 64     mov esi,dword ptr ss:[esp+0x64]
0040113B   .  9C            pushfd
0040113C   .  880424        mov byte ptr ss:[esp],al
0040113F   .  68 3D6E302B   push 0x2B306E3D
00401144   .  9C            pushfd
00401145   .  4E            dec esi
00401146   .  9C            pushfd
00401147   .  883C24        mov byte ptr ss:[esp],bh
0040114A   .  8D6424 44     lea esp,dword ptr ss:[esp+0x44]
0040114E   .- E9 F4400B00   jmp 测试_vmp.004B5247
00401153   .  66:0FA3C9     bt cx,cx
00401157   .  68 FF4EB743   push 0x43B74EFF
0040115C   .  E8 202F0B00   call 测试_vmp.004B4081
00401161   .  882424        mov byte ptr ss:[esp],ah
00401164   .- E9 5F460B00   jmp 测试_vmp.004B57C8
00401169      0B            db 0B
0040116A   .  0D 488B5DFC   or eax,0xFC5D8B48
0040116F   .  85DB          test ebx,ebx
00401171   .  74 09         je short 测试_vmp.0040117C
00401173   .  53            push ebx
00401174   .  E8 64000000   call 测试_vmp.004011DD
00401179   .  83C4 04       add esp,0x4
0040117C   >  8B5D F8       mov ebx,dword ptr ss:[ebp-0x8]
0040117F   .  85DB          test ebx,ebx
00401181   .  74 09         je short 测试_vmp.0040118C
00401183   .  53            push ebx
00401184   .  E8 54000000   call 测试_vmp.004011DD
00401189   .  83C4 04       add esp,0x4
0040118C   >  8BE5          mov esp,ebp
0040118E   .  5D            pop ebp
0040118F   .  C3            retn

VM后的代码 其实贴不贴没啥区别...

以下都是截图.


首先 按照我的截图操作.选中

然后




这个时候F9跑起来.然后按F1 程序就开始分析了.分析之后 会在OD目录下生成一个文件夹.里边 文件 我简单讲解一下.trc结尾的是跟踪部分.map 根据前缀 可以分为几种.一类作为堆栈  一类寄存器  一类 操作码 其他我也就不太清楚了.233333

我们要关注的是log 文件.  log文件有虚拟机入口分析 指令表指令分析.也就是opcode 对应的VM指令是啥...还有一部分就是我们要的 根据堆栈还原回来的指令操作.很精简了..
代码如下:

001B00BC: pushfd
001B00C2: test efl, 0x00000100
001B0230: jz 0x001B0392
001B02F8: push rvm_08
001B0040: popfd
001B038D: jmp 0x92FCF1B4
001B0392: label_1B0392:
001B0455: pop esi
001B062F: eax = 0x0047E6A8
001B063A: push eax
001B0656: ebx = [ebp + 0xFFFFFFFC]
001B0660: test ebx, ebx
001B07FC: jz 0x001B0A91
001B08C3: push ebx
001B0927: call 0x004011DD
001B09C2: esp = esp + 4
001B0A91: label_1B0A91:
001B0B53: pop rvm_38
001B0B75: eax = 0x0047E6AE
001B0B80: [ebp + 0xFFFFFFFC] = rvm_38
001B0B85: push eax
001B0BA1: ebx = [ebp + 0xFFFFFFF8]
001B0BAB: test ebx, ebx
001B0D45: jz 0x001B0FDA
001B0E0C: push ebx
001B0E70: call 0x004011DD
001B0F0F: push iEFL
001B0040: popfd
001B0F16: esp = {add 4, __$esp + 4}
001B0FDA: label_1B0FDA:
001B109D: pop rvm_04
001B10BF: [ebp + 0xFFFFFFF8] = rvm_04
001B10DA: eax = [ebp + 0xFFFFFFF8]
001B10E4: push eax
001B1100: push [ebp + 0xFFFFFFFC]
001B1162: call 0x00401004
001B11FD: esp = esp + 8
001B120B: cmp eax, 0
001B13FF: jnz 0x001B1EE3
001B14C8: push 0x80000004
001B14CD: push 0
001B14E8: rvm_04 = [ebp + 0xFFFFFFF8]
001B14F2: test rvm_04, rvm_04
001B168F: jnz 0x001B1825
001B1758: rvm_14 = 0x0047E6B3
001B1825: label_1B1825:
001B18E8: push rvm_28
001B18EE: push 0x80000301
001B18F3: push 0
001B18F8: push 0
001B18FD: push 0x80000004
001B1902: push 0
001B191D: rvm_18 = [ebp + 0xFFFFFFFC]
001B1927: test rvm_18, rvm_18
001B1AAC: jnz 0x001B1C41
001B1B74: eax = 0x0047E6B3
001B1C41: label_1B1C41:
001B1D04: push eax
001B1D0A: push 3
001B1D0F: ebx = 0x004012B0
001B1D78: call 0x004011E3
001B1E13: esp = esp + 4
001B1EE3: label_1B1EE3:
001B2002: jmp 0x0040116C

相信我 只要你不傻..怎么还原 一目了然........


带有浮点寄存器 XMM 寄存器的需要手动肉眼还原. 这个插件把代码转换操作之后申请内存出来的汇编代码..相信我.只要你汇编 还行.肉眼还原 基本也就是时间问题..插件很牛逼..很屌...  这个插件是我见过最傻瓜..最简单的还原工具.                

想想像我这种菜B很是惆怅啊...B老师 直接能心算还原.我还停留在只能用别人的工具上面.差距好大...心好痛.


别说这个帖子没用 鄙视我菜.. 这玩意出来好几年了..  技术好的觉得没啥说的必要这么简单的东西..技术菜的不知道.  


我自己也觉得 这么菜的帖子发出来没B格...但是,我觉得发很多原理大家都云里雾里的.不如直接发个插件使用方法.难者不会 会者不难.但是VM这玩意不一样..就算你知道原理.他特么也是体力活...想想我手写三页记事本的还原 还特么没啥卵用..心痛. 不会编程 只能纯手动了.


响应穆恩师傅的帖子:http://bbs.pediy.com/thread-217588.htm


==============================================================================================

==============================================================================================

以下是其他一些知识点


之前,破VM程序可以破.但是,只限制余 利用调用函数  利用XX门修改判断 之类的小技巧.从来没有认真研究过核心的东西.
写个文章自我研究 共同进步. 
插件下熟悉VM指令 脱离插件后自己识别指令.
http://bbs.pediy.com/showthread.php?t=82618
http://bbs.pediy.com/showthread.php?t=121412
http://bbs.pediy.com/showthread.php?t=155215
正向角度
http://bbs.pediy.com/showthread.php?t=116601

如何站在巨人的肩膀上,进行无尽的装逼.

感谢各位前辈提供的资料让小菜们学习.


物理寄存器与VMP寄存器的对应关系
edi=vReg 虚拟寄存器的首地址大小为[0x40]
ebp=vESP 虚拟栈指针
esi=vEIP 虚拟机的EIP
eax,edx,ecx,ebx 保存临时数据 大部分时间作为垃圾寄存器
///////////////////////////////////
ESI 即VM.EIP
EDI 指向虚拟机通用寄存器的地址,[EDI + XXXX]是虚拟机在操作内存,且EDI指向虚拟机的堆栈的上限, 用[EDI + EAX]向下发展
EBP 指向虚拟机堆栈的栈顶,且EBP指向堆栈下限并向上发展
EAX 计算将要执行的指令序列号和选择虚拟机通用寄存器,指令执行时用作中间变量.其它时候用作花指令
EDX 执行时通常用作中间变量,其它大部分时间用来做花指令
EBX BL用作校验码.
ECX SHLD,SHRD时用作中间变量,其他大部分时间用来做花指令
ESP 指向垃圾,这个寄存器就是用来迷惑追踪者的,一般对ESP的操作都是花指令,大部分可以忽略
小笨笨的这个更全.
////////////////////////////////////////////////////////////////////////////////////////////

VMP 逻辑
OR(|)     或-------有1出1,全0出0
AND(&)    与-------有0出0,全1出1
NOT(~)    非-------0出1, 1出0
NAND(~&)  与非-----有0出1,全1出0(与的非)
NOR(~|)   或非-----有0出0,全1出0,全0出1(或的非)
XOR(^)    异或-----同为1,异为0

------------------------------------------------
用NAND实现全部公式简化  不知道推的对不对...

NOT(~a)=a ~& a

AND(a&b)=(a ~& a) ~& (b ~& b)

OR(a|b)=(a ~& b) ~& (a ~& b)

XOR(a^b)=((a ~& a) ~& (b ~& b)) ~& (a ~& b)
------------------------------------------------
VMP内的基本运算指令
ADD 加法(A+B)

NAND 非(a~&b)

SHL 左移(a<<b)

SHR 右移(a>>b)

SHLD 双精度左移(a<<x<-(h)b)

SHRD 双精度右移(a>>x->(l)b)

DIV 除法

.....
......
....... 汇编能实现的这个大部分都能实现.
-----------------------------------------------
Handler基本指令
VM_Add_16(word加法)

VM_Add_32(Dword加法)

VM_Add_8(byte加法)

VM_Nor_16(word或非)

VM_Nor_32(Dword加法)  

VM_Nor_8(byte加法) 

VM_Shl_16(word左移)

VM_Shl_32(Dword左移)

VM_Shl_8(byte左移)

VM_Shld(双精度左移)

VM_Shr_16(word右移)

VM_Shr_32(Dword右移)

VM_Shr_8(byte右移)

VM_Shrd(双精度右移)

....
......
........
还有很多 加减乘除等等.不一一举例了.


本主题帖已收到 0 次赞赏,累计¥0.00
最新回复 (15)
MaYil 2017-5-15 14:04
2
感谢分享
AASSMM 2017-5-15 16:55
3
堪比滴水5万的课程
evilor 2017-5-15 17:59
4
你这么牛逼,难道是师从B牛Brack?
bambooqj 2017-5-15 19:42
5
evilor 你这么牛逼,难道是师从B牛Brack?
B牛哪能收我这种菜鸡...都是他偶尔透露一句半句给我而已.师傅才是入门弟子.
MOVESP 2017-5-16 06:45
6
看看大牛们的技术,觉得自己要走的路还长,像vmp大牛应该都是自己写的自动分析工具,上次我只是简单跟踪了一下就写了六七页,没敢进入虚拟机,完全就是体力活
土豆粉 2017-5-16 14:32
7
楼主厉害哦。
1
sxpp 2017-5-16 19:14
8
给赞一个
windson 2017-5-18 11:12
9
感谢分享
南方的兽 2017-5-19 00:55
10
我们能做个朋友吗?

1
隔壁雷哥 2017-5-20 12:00
11
我们能做朋友么
材鸟 2017-5-20 16:50
12
001B00BC:  pushfd
001B00C2:  test  efl,  0x00000100
001B0230:  jz  0x001B0392
开头的这一段如何得来的?有点看不懂,求指教
bambooqj 2017-5-21 01:31
13
材鸟 001B00BC: pushfd 001B00C2: test efl, 0x00000100 001B0230: jz 0x001B0392 开头的这一段如何得来的?有点看不懂,求指教
这段基本都会有.验证VM的.跟原始代码没关系.
材鸟 2017-5-21 02:18
14
bambooqj 这段基本都会有.验证VM的.跟原始代码没关系.
插件生成的.LOG文件里有记录吗?那就太叼了!~~还是根据.LOG文件提供的信息再去跟踪得来的?
sssccc 2017-5-22 00:22
15
厉害了 
chinasmu 2017-5-22 09:13
16
看我头像
返回



©2000-2017 看雪学院 | Based on Xiuno BBS | 知道创宇带宽支持 | 微信公众号:ikanxue
Time: 0.014, SQL: 9 / 京ICP备10040895号-17