首页
社区
课程
招聘
[原创]VMP1.7讲解[破解vmp程序的关键点]
发表于: 2010-2-7 19:22 29316

[原创]VMP1.7讲解[破解vmp程序的关键点]

2010-2-7 19:22
29316

有点标题党,其实贴的是海风月影的帖子http://bbs.pediy.com/showthread.php?t=82618
之后的学习笔记而已.通过分析代码,发觉似乎理解了一点.喜不自禁.
故写下来与大家分享一下和日后回顾一下
并感谢大牛们的分析,希望能继续爆料

本笔记所使用的demo是由VMP1.7加的notepad.exe的EP.
主要内容为:分析以VMP处,调用IsDebuggerPresent,判断返回值后走哪条流程..

由于VMP1.7 Handle垃圾指令太多,故而写了个OD小插件F7分析Handle转义为对应x86指令.
所以看到的会有点不同了

先上IsDebuggerPresent返回1的代码,代码乱且多,请看注释的关键代码
vm_call_IsDebuggerPresent
call的返回值为:00000001      ;返回值为1
vm_popDword reg[14],数据为:00000000
vm_popDword reg[2C],数据为:7C800000
vm_popDword reg[28],数据为:00000001  ;保存EAX
vm_popDword reg[08],数据为:0007FF88
vm_popDword reg[3C],数据为:7C800000
vm_popDword reg[04],数据为:000A0608
vm_popDword reg[34],数据为:0000022A
vm_popDword reg[30],数据为:0007FF74
vm_popDword reg[24],数据为:0007FF98
vm_popDword reg[0C],数据为:00000206
vm_popDword reg[20],数据为:0103A148
vm_popDword reg[00],数据为:4E89BA21
vm_pushDword,数据为:11426946  ;后面的跳转地址1
vm_pushDword,数据为:114217BD  ;后面的跳转地址2
vm_push_esp
vm_pushbyte reg[28],数据为:01  ;压入AL的值
vm_pushbyte reg[28],数据为:01  ;压入AL的值
vm_nna_byte,数据为:FE  ;第一处not_not_and  (~al) & ~(al)
vm_popDword reg[18],数据为:00000282
vm_push_esp
vm_check,数据为:00FE   ;这个虽然叫check指令,但其实就是mov BYTE ptr ds:[esp],BYTE ptr ds:[esp+4] ,所以这里也压入的是上面的NNA过后的FE
vm_nna_byte,数据为:01  ;第二处not_not_and,由于是残留的,所以相当帖子中说的三次not_not_and了, 也就是说上面的代码就等价于test al,al操作了.
vm_popDword reg[00],数据为:00000202  ;保存eflags,用它来判断是否该跳转的哈
vm_popbyte reg[28],数据为:01
vm_pushword,数据为:0004  ;两个候选答案,04 00
vm_pushDword reg[00],数据为:00000202  ;然后又压入eflags
vm_push_esp
vm_pushDword,数据为:00000202  ;mov DWORD ptr ds:[esp],DWORD ptr ds:[esp+4]
vm_nna_Dword,数据为:FFFFFDFD  ;第一处NNA,即 (~eflags) & (~eflags)
vm_popDword reg[18],数据为:00000282
vm_pushDword,数据为:FFFFFFBF  ;这个是事先NNA过的数据,NOT一下FFFFFFBF 就为40了
vm_nna_Dword,数据为:00000000  ;则这里是第三次了,相当于test eflags,40  ,也就是判断ZF啦
vm_popDword reg[20],数据为:00000246
vm_operation_Dword [esp+4],数据为:00000000   ;这里把上面的结果处理了一下,如果为0,转换后的结果为0,如果不为0,就转换为4了,两个地址跳表嘛.
vm_popDword reg[20],数据为:00000246
vm_add_Dword [esp+4],[esp],数据为:0007F790 ;这里就算下要跳向地址的地址,后面就是取出0007F790的内容,然后解密,改变esi的值,jump过去..
vm_popDword reg[38],数据为:00000206
vm_pushDword,数据为:114217BD
vm_popDword reg[0C],数据为:114217BD
vm_popDword reg[20],数据为:114217BD
vm_popDword reg[38],数据为:11426946
vm_pushDword reg[0C],数据为:114217BD
vm_push_esp
vm_pushDword,数据为:114217BD
vm_popDword reg[18],数据为:114217BD
vm_pushDword reg[18],数据为:114217BD
vm_nna_Dword,数据为:EEBDE842
vm_popDword reg[20],数据为:00000286
vm_pushDword,数据为:EFBEE2A6
vm_nna_Dword,数据为:10401519
vm_popDword reg[10],数据为:00000202
vm_pushDword,数据为:10411D59
vm_pushDword reg[18],数据为:114217BD
vm_nna_Dword,数据为:EEBCE002
vm_popDword reg[38],数据为:00000282
vm_nna_Dword,数据为:01030AE4  ;解密出地址
vm_popDword reg[1C],数据为:00000206
vm_popDword reg[38],数据为:01030AE4
vm_pushDword reg[10],数据为:00000202
vm_pushDword reg[20],数据为:00000286
vm_pushDword reg[08],数据为:0007FF88
vm_pushDword reg[34],数据为:0000022A
vm_pushDword reg[2C],数据为:7C800000
vm_pushDword reg[24],数据为:0007FF98
vm_pushDword reg[30],数据为:0007FF74,
vm_pushDword reg[04],数据为:000A0608
vm_pushDword reg[00],数据为:00000202
vm_pushDword reg[24],数据为:0007FF98
vm_pushDword reg[28],数据为:00000001
vm_pushDword reg[14],数据为:00000000
vm_pushDword reg[38],数据为:01030AE4
vm_jump,数据为:01030AE4 ;跳过去,流程改变..

总结下上面的,
VMP跳转之前,会先在栈里存放着两个加密过后的地址数据.
一个为条件成立跳的,一个为不成立跳的.
经过三次not_not_and al,al之后,
然后再not_not_and eflags,40 来判断ZF位是否被置位.
也就相当于我们熟悉的两句代码
test al,al
je xxx

好了,就到这里了,然后贴下IsDebuggerPresent返回0的流程,对照的看看

vm_call_IsDebuggerPresent
call的返回值为:00000000
vm_popDword reg[28],数据为:00000000
vm_pushDword,数据为:11426946
vm_pushDword,数据为:114217BD
vm_nna_byte,数据为:FF
vm_nna_byte,数据为:00
vm_popDword reg[00],数据为:00000246  ;保存eflags,很明显看出ZF位是被置位了
vm_popbyte reg[28],数据为:00
vm_pushword,数据为:0004
vm_pushDword reg[00],数据为:00000246
vm_push_esp
vm_pushDword,数据为:00000246
vm_nna_Dword,数据为:FFFFFDB9
vm_popDword reg[18],数据为:00000282
vm_pushDword,数据为:FFFFFFBF
vm_nna_Dword,数据为:00000040
vm_popDword reg[20],数据为:00000202
vm_operation_Dword [esp+4],数据为:00000004  ;这里计算的结果就为4了,也就是跳到第二个地址去
vm_popDword reg[20],数据为:00000202
vm_add_Dword [esp+4],[esp],数据为:0007F794  ;0007F794  上段代码此处为0007F790
vm_pushDword,数据为:11426946  ;取出0007F794加密后地址数据
vm_nna_Dword,数据为:0103741F  ;解密出要跳转的地址
vm_jump,数据为:0103741F  ;jump
vm_popDword reg[2C],数据为:00000000,pcode地址为:0103741F
Log file closed

NOTEPAD.vmp.rar


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

上传的附件:
收藏
免费 7
支持
分享
最新回复 (44)
雪    币: 1121
活跃值: (1321)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
2
楼主分析的好,占位学习
2010-2-7 19:27
0
雪    币: 2242
活跃值: (488)
能力值: ( LV9,RANK:200 )
在线值:
发帖
回帖
粉丝
3
完了,不管怎么编辑还是好乱
2010-2-7 19:34
0
雪    币: 50141
活跃值: (20730)
能力值: (RANK:350 )
在线值:
发帖
回帖
粉丝
4
在记事本里排版,直接复制上来。
另外,代码不用code标签括住。
2010-2-7 20:06
0
雪    币: 2242
活跃值: (488)
能力值: ( LV9,RANK:200 )
在线值:
发帖
回帖
粉丝
5
谢谢老大提示
稍微好一点了,不过还是蛮乱
谢谢给予优秀贴
2010-2-7 20:20
0
雪    币: 1491
活跃值: (985)
能力值: (RANK:860 )
在线值:
发帖
回帖
粉丝
6
把文件当做附件发上来嘛,呵呵
2010-2-7 20:25
0
雪    币: 62
活跃值: (72)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
7
只能膜拜,不能学习
2010-2-7 20:51
0
雪    币: 210
活跃值: (20)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
看得好晕啊。。。
2010-2-7 22:00
0
雪    币: 2242
活跃值: (488)
能力值: ( LV9,RANK:200 )
在线值:
发帖
回帖
粉丝
9
阿,什么文件.log.txt?


小哥一直是我学习的目标
2010-2-7 22:23
0
雪    币: 100
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
厉害支持
2010-2-7 23:05
0
雪    币: 2067
活跃值: (82)
能力值: ( LV9,RANK:180 )
在线值:
发帖
回帖
粉丝
11
好像很复杂.没整理较不适合阅读.
2010-2-7 23:45
0
雪    币: 1844
活跃值: (35)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
12
完全看不懂,所以只好保留意见
2010-2-8 00:42
0
雪    币: 6
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
请发F7插件
2010-2-8 04:23
0
雪    币: 2242
活跃值: (488)
能力值: ( LV9,RANK:200 )
在线值:
发帖
回帖
粉丝
14
调试信息nop掉了,现在貌似好多了
2010-2-8 08:05
0
雪    币: 2067
活跃值: (82)
能力值: ( LV9,RANK:180 )
在线值:
发帖
回帖
粉丝
15
m . 除了排版. 主要我是说你没整理为 "可供了解"
因为很乱我没细看, 但是我知道里面至少用到
  1. 以 NOR 门实现 NOT
  2. 以 NOR 门实现 AND
  注: 你写的 nna 或 not_not_and 其实叫 NOR 门

你单纯写注解, 就有如我们常在版上看到的自动汇编注解插件

mov  eax, ebx    ; 将ebx赋于eax

是没意义的
2010-2-8 10:57
0
雪    币: 2242
活跃值: (488)
能力值: ( LV9,RANK:200 )
在线值:
发帖
回帖
粉丝
16
前面都说了这是http://bbs.pediy.com/showthread.php?t=82618的进行代码讲解..

难道我非要把别人的资料拷贝过来强调讲解那个是NOR门?

我喜欢BugHoHo说的not_not_and和not_not_or,很直观
2010-2-8 11:03
0
雪    币: 2067
活跃值: (82)
能力值: ( LV9,RANK:180 )
在线值:
发帖
回帖
粉丝
17
习惯不同. 算我多言了.
2010-2-8 11:19
0
雪    币: 7325
活跃值: (3803)
能力值: (RANK:1130 )
在线值:
发帖
回帖
粉丝
18
科锐出来的好强大
2010-2-8 11:58
0
雪    币: 2242
活跃值: (488)
能力值: ( LV9,RANK:200 )
在线值:
发帖
回帖
粉丝
19
谢谢海风大哥的夸奖,主要还是借你帖子的光

不过,我这贴有没有把你帖子的思路讲明白阿?

别人说看不懂,sessiondiy说写了跟没写一样.知道代码乱,但也不至于这么烂吧
2010-2-8 12:12
0
雪    币: 2067
活跃值: (82)
能力值: ( LV9,RANK:180 )
在线值:
发帖
回帖
粉丝
20
不是的. 可能我脑子比较转不过来.
我看到上半部是 and (test) 指令的实现.
下半部是 jcc 指令的实现.
你的方法分析得很细. 不错.
2010-2-8 12:21
0
雪    币: 202
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
21
进来 学习了
2010-2-8 14:13
0
雪    币: 223
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
22
很牛了,能识别handler类型。。可读性高很多啊
2010-2-8 16:20
0
雪    币: 76
活跃值: (27)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
23
我何时能达到兄弟你的境界啊
2010-2-8 22:42
0
雪    币: 147
活跃值: (11)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
24
S牛不是说看不懂,只是说太乱了,不适合新手阅读
2010-2-8 22:52
0
雪    币: 136
活跃值: (150)
能力值: ( LV9,RANK:140 )
在线值:
发帖
回帖
粉丝
25
此贴 呵呵 科锐 还能教出这样的学生啊 不错
2010-2-9 16:47
0
游客
登录 | 注册 方可回帖
返回
// // 统计代码