首页
社区
课程
招聘
[原创]VMP分析插件应用实例:一个简单的CrackMe
发表于: 2013-2-21 22:43 109176

[原创]VMP分析插件应用实例:一个简单的CrackMe

2013-2-21 22:43
109176
收藏
免费 9
支持
分享
最新回复 (155)
雪    币: 5
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
101
非常感谢zdhysd兄的回答。
还有问题是。我用吾爱版的OD在004CBAE8           9C                   PUSHFD分析虚拟机后,在00433BAF    60              pushad分析虚拟机程序,OD会直接退出,有时会提示分析失败,有时才成功。

还有就是,在4B77D0分析提示修改成arg(1,"检测内核调试器"); regModify(eax, "发现调试器")了
004C3918  |. /83  vJmp_00425E0A  callVM VMPCrack.004B77D0
怎么才能显示成:
004C3918  |.  83  vJmp_00425E0A   callVM <VMPCrack.检测调试器>
需要改哪里呢?

0041EC2E 添加分析提示
/*esp(4); arg(1,"检测虚拟机"); regModify(eax, "发现虚拟机"); initReg(ecx,20);initReg(eax,24);initReg(edx,1C);initReg(ebx,C);initReg(ebp,18);initReg(edi,28);initReg(esi,10)*/
这样是否正确呢?EAX在全部指令时并没发现,不知道设置成24是否正确
2013-9-24 21:24
0
雪    币: 1270
活跃值: (230)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
102
我这分析不会出错啊,用过好几个版本的od也没问题,不过没用过吾爱版的,也不太清楚是什么原因。调用目标如果有标签的话就会这样显示,在4B77D0加个标签就行了。
2013-9-24 21:57
0
雪    币: 630
活跃值: (570)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
103
mark 一下 精华啊 必须看
2013-9-24 22:33
0
雪    币: 81
活跃值: (100)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
104
我也有些VM内调用的相关问题
1.同样是vJmp,插件是通过什么原则来判断是虚拟机调用但是普通的跳转的呢?如何在跳转之前就计算出VMCALL的返回地址?我观察过调用前的堆栈并没有把返回值压栈。
2.我在填写初始寄存器时,使用第一种方法,把表达式切到产生数据,在一大堆vPUSH段并没有标出EBX,EDX之类的寄存器提示(可能是因为我之前手动改变过程序的跳转流程导致的),那我如何手动确定调用前eax之类的值呢?因为调用有发生改变的寄存器无法使用第2种方法。。。
3.我填写完初始寄存器后,重新分析,但是被调函数内的unknownInit一个都没有减少,全部都还在,是操作有问题吗?如果在填写完成后关闭OD,重新打开后再分析unknownInit才会变成相应寄存器
4.通过堆栈传递给被调函数的所有值里,除了寄存器变量以外,还传递了一些常量,我看了下常量是用来记录调用方堆栈开辟空间的长度的,那我该添加什么提示来告诉被调函数这是什么值呢,确保数据流不中断
5.我在一个vmCall填写了initReg(ebp,20)后,重新分析导致调用方分析出错(在调用点之前5个指令块之前),填写其他寄存器没有问题,一填写ebp重新分析就会错误,把ebp填写去掉再分析就恢复。错误的形式是多个寄存器被关联到同一个变量上了,比如v0 = eax,v0 = ebx,v0 = ebp,v0 = esi。我多次检查ebp确实位于堆栈偏移20的地方,就算填写错误,会导致调用之前那么远的地方分析错误吗?(我用的就是文中使用的crackme,填写的是壳开头未获取到api地址后的错误分支中的第一个vmCall)
2013-9-26 11:10
0
雪    币: 627
活跃值: (663)
能力值: ( LV9,RANK:270 )
在线值:
发帖
回帖
粉丝
105
多谢,多谢!膜拜~
2013-9-26 18:49
0
雪    币: 1270
活跃值: (230)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
106
1 如果执行vJmp时真实堆栈栈顶的值是有效的虚拟程序入口,插件就认为是虚拟机内调用,因为进入函数时栈顶是返回地址,函数退出后会从这里重新进入虚拟机。但是这样也有可能误判,比如壳的入口有很多动态地址的转移,有时就会弄错,但是一般程序中出错的几率不大,我也没想到更好的方法。调用前压栈的返回地址不是虚拟地址,是重新进入虚拟机的虚拟程序入口,插件通过分析这个入口来计算返回到哪里。

2 这确实不好办,只能自己根据调用前的内容和被调用函数退出时恢复的寄存器来推测了。实际上虚拟机内并没有真实寄存器这个概念,数据可以随便放,只要完成相同的操作就可以,相同的寄存器不同的时候也有可能放在不一样的虚拟寄存器中,所以插件很难自动分析。如果被调用函数改变了寄存器,那填不填提示也没什么区别了,反正寄存器已经被改变,调用前的值也不会保留到调用后。

3 好像确实有这个问题,原来没有发现,应该是插件的事,这个插件也不准备更新了,先这么用吧。

4 现在不会把调用方的数据传播到被调用函数,因为插件使用静态分析,而且每个函数是单独处理的,分析时不知道调用来自哪里,可以在被调用函数读取这些参数时添加const或exp提示。我没发现除了寄存器还传其它的东西,你说的那个每次虚拟机内调用都有吗,一般除了寄存器就是一些没用的东西了,比如初始vEIP、返回地址等,这么做是为了和虚拟机外部调用这个函数时初始堆栈长度相同,一般都是随机内容,函数不会使用的。多出来的东西可能是函数的参数,也就是真实堆栈里的内容,虚拟机内调用其实和普通调用是一样的,只不过初始化虚拟堆栈的部分调用方在虚拟机里做了。

5 我也遇到过这种情况,最后发现是填写提示后多个路径的vESP不同,堆栈数据错开了一定的位置,导致不同的数据重叠到一起了。EBP和堆栈指针有关,一般函数开始有push ebp;mov ebp,esp,结束有mov esp,ebp;pop ebp,填了这个的话后面vESP就会改变,如果这个路径正确的话,应该是有其他路径的vESP错了,把所有路径都填正确后就可以了,当然也不排除分析有误,你可以加载我的那个UDD文件后看看还会不会这样。
2013-9-27 12:16
0
雪    币: 81
活跃值: (100)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
107
谢谢LZ回答~
1.明白啦
2.通过追踪每个数据的源头,东拼西凑,最后都找全了,花了不少时间
3.不再更新了么,有些可惜,有开源的打算吗,这样后人可以继续改进
4.我指的常量就是,重定位,初始化检查之类的数据(再寄存器之前,寄存器之后一般也有2-4个数据,我还没确定是什么用的),在调用函数内也会进行一些运算,再传出来
5.用你的udd添加上我分析的initReg之后依然出现这种情况,我填写的ebp是在分析出错点之后的,怎么会引起之前的esp错误呢?
6.对于regModify(eax),是插件自动填写的,经过人工分析eax是一个字符串指针,指针本身调用后并没变化,指向的地址上的数据发生了变化,这种情况regModify(eax)有填写的必要么
7.要是想做64位程序vmp的分析有什么好的建议吗?
2013-9-27 13:15
0
雪    币: 1270
活跃值: (230)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
108
3 短时间内不太可能开源,看看我给别人的回复吧。


4 这些确实是有的,虚拟机内调用和从虚拟机外进入虚拟程序是一样的,初始堆栈都是那些东西,但是除寄存器以外的东西只在函数内有效,应该不会传出来。

5 我记得我那个udd都是填好了提示的啊,你那没有吗?edp影响的确实是后面的esp,但是算法分析时根据数据使用的方式来生成变量,后面多个路径的堆栈指针不同导致一些数据重叠到了一起,分析时当作同一个变量了。

6 只要eax值不变就不用填写,如果想反映字符串变化的话可以在调用方填写vMemModify或vStackModify。

7 64位程序我从来没分析过,也不好说什么了。
2013-9-27 14:44
0
雪    币: 81
活跃值: (100)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
109
5.你的udd里分析了所有正常会走到的路径,我特意挑了一条失败处理的路径(手动修改堆栈使获取api失败),分析的是失败处理中的一个vmCall
2013-9-27 15:09
0
雪    币: 105
活跃值: (38)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
110
学习了一下~!!!~!
2013-10-20 13:36
0
雪    币: 645
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
111
LZ大神 小弟跪拜下 真是好帖子 插件也很牛x
2013-10-23 20:11
0
雪    币: 10
活跃值: (64)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
112
很喜欢这类一步一步走的帖子
赞一个
2013-10-24 02:27
0
雪    币: 1644
活跃值: (53)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
113
强力!感谢分享。
2013-10-27 22:30
0
雪    币: 418
活跃值: (1404)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
114
看看代码,大段大段的灰色指令,估计超过80%,而且有很多连接转移,应该是加变形了。点击反汇编栏标题把显示模式切换到有效指令,这样就不会显示垃圾指令了。当然也可以直接看最终操作,这样更简单,但是算法分析后的结果已经和虚拟机没有什么关系了,这里为了了解一下虚拟机的原理先不使用这个功能,看看VMP是什么样的。由于不使用算法分析的结果,指令没有化简,代码量很大,最好从一些关键的部分比如转移等看起。

在402810地址 分析虚拟程序后,怎么查看你上面说的这段代码,这段代码是哪里的,ollydbg cpu窗口中的,还是插件调试窗口中的,
在插件调试窗口中按ctrl+g 输入402810 后提示

---------------------------
转到地址
---------------------------
地址402810不在已分析的虚拟程序中
---------------------------
确定   
---------------------------
2013-10-31 21:31
0
雪    币: 1270
活跃值: (230)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
115
虚拟代码在插件的调试窗口里看,402810是被虚拟的函数的入口,不是虚拟代码的地址,想看对应的虚拟代码的话可以在分析点窗口中找到这个地址,然后菜单里选反汇编窗口中跟随vEIP。
2013-11-1 11:21
0
雪    币: 205
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
116
mark一下。
2013-11-3 18:47
0
雪    币: 282
活跃值: (32)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
117
看完了所有的回复,感觉如果能做成个视频就好了,因为即使是照着文字一步步操作都不是很清楚如何操作。

不过楼主还是很细致的回答这些简单的操作问题。
2013-11-7 10:35
0
雪    币: 34
活跃值: (18)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
118
学习学习再学习
2013-11-18 11:05
0
雪    币: 645
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
119
Z大 不是人类 外星人 这么强的插件  光看文章 消化就得消化几天的了 太强了
2013-11-24 22:12
0
雪    币: 645
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
120
假如没有插件的话 估计真好像人与天斗的感觉
2013-11-24 22:15
0
雪    币: 201
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
121
工具还不会用 学习如何使用
2013-12-19 17:44
0
雪    币: 103
活跃值: (126)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
122
不仅是长 简直是长 厉害
2013-12-23 19:55
0
雪    币: 129
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
123
好复杂 全然不懂
2013-12-23 20:55
0
雪    币: 5
活跃值: (12)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
124
下面讲一下VMP的脱壳吧,这是我脱的第一个壳,原来一直感觉脱壳没什么用,带壳分析带壳修改对大部分程序都可以,这次想测试插件才研究了一下VMP脱壳。我不会脱壳,方法都是自己想的,可能不是很好。在插件的帮助下很快就把VMP加壳的原理和各种检测看懂了,感觉还不是太难,只是一些修复比较麻烦。先从入口跟踪一下,看看VMP都做了什么。
代码:
005BB9EE  /$  13  vPopReg4 vR10
005BB992  |.  2B  vReadMemSs4    DWORD m0 = DWORD SS:[Je(SubFlag(0, 0)) + 28]
005BB961  |.  94  vJmp_005BED37  if (0 != 0) goto VMPCrack.005B820C

我在重启后按分析虚拟机程序,遇到一个vret之后就直接到系统API的领空了,然后没找到虚拟入口就直接返回到临时指令块了,也就是楼主上面的这个地址 完全不能分析 只能执行,下面的地址是直接返回的地址
7C92EB8B >  8BD4            mov edx,esp
7C92EB8D    0F34            sysenter
7C92EB8F    90              nop
7C92EB90    90              nop
7C92EB91    90              nop
7C92EB92    90              nop
7C92EB93    90              nop
7C92EB94 >  C3              retn
这个返回地址的堆栈值,也没找到相关返回的虚拟地址 求指点

0012FD20   7C92D625  返回到 ntdll.7C92D625
0012FD24   7C92EACF  返回到 ntdll.7C92EACF 来自 ntdll.ZwContinue
2014-1-7 14:51
0
雪    币: 1270
活跃值: (230)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
125
启动后第一次分析虚拟程序是在哪里,入口是005AAECF,会不会是先中断到tls(005ADA31)了,这里只有很少的操作就返回了,因为已经分析过虚拟机了,后面执行入口时会直接中断到临时指令块。
2014-1-7 21:36
0
游客
登录 | 注册 方可回帖
返回
//