首页
社区
课程
招聘
[原创]一个简单的加vmp1.63的crackme正向追踪
2008-8-3 01:15 15636

[原创]一个简单的加vmp1.63的crackme正向追踪

2008-8-3 01:15
15636
今天儿子较乖,让我能静下心来多打会电脑。
    早就想试下heXer的key了,没找到vmp1.64,只好装了个1.63,竟然也注册成功,感受了key的强大。
    之前跟过一个海风提供的用vmp1.60的notepad,变形很多,vmopcodetable也加密了,虽然rokyxue给出了简化方法,不过还是不敢跟进去,怕浪费太多的时间和精力。手工怎能和机器对抗?

目的:希望能正向分析一个自己设计的加了vmp的代码,在vmp中寻找原始代码的痕迹。
      根据rokyxue分析,vmp1.63虽然加了很多变形,但与vmp1.2x虚拟机主体相同。确认在vmp引擎中仍保留的是vmp1.2x的opcode结构,同时esi为opcode指针。ecx为opcode解密后的地址。

过程:
    写了个最简单的明码比较的crackme,在注册按钮事件里加了vmp的marker。
#define  VMBEGIN 
 __asm    
    {  
      _emit 0xEB
      _emit 0x10  
      _emit 0x56  
      _emit 0x4D  
      _emit 0x50 
      _emit 0x72 
      _emit 0x6F 
      _emit 0x74 
      _emit 0x65 
      _emit 0x63 
      _emit 0x74 
      _emit 0x20 
      _emit 0x62 
      _emit 0x65 
      _emit 0x67 
      _emit 0x69 
      _emit 0x6E 
      _emit 0x00
    }
	namelen=GetDlgItemText(IDC_NAME,&name[0],15);
	regcodelen=GetDlgItemText(IDC_REGCODE,®code[0],4095);

	if (namelen==0||namelen>15||regcodelen!=16)
		return;
	
	strupr(®code[0]);//
	for(tmpi=0;tmpi<regcodelen;tmpi++)
	{
		if (regcode[tmpi]>0x39||regcode[tmpi]<0x30)
			if(regcode[tmpi]>'F'||regcode[tmpi]<'A')
				return;
	}
	if(!strcmp(&name[0],"wangdell")&&!strcmp(®code[0],"FEDCBA9876543210"))
		MessageBox("OK!",0,MB_OK);
	else
		MessageBox("FAILED!",0,MB_OK);
#define  VMEND
    __asm 
    {  
      _emit 0xEB
      _emit 0x0E  
      _emit 0x56   
      _emit 0x4D   
      _emit 0x50 
      _emit 0x72 
      _emit 0x6F 
      _emit 0x74 
      _emit 0x65 
      _emit 0x63 
      _emit 0x74 
      _emit 0x20 
      _emit 0x65 
      _emit 0x6E 
      _emit 0x64 
      _emit 0x00
    }

使用vmp1.63加了一个最大速度的(vmptest-ms.exe),和一个最大保护的(vmtest-mp.exe)
一、最大速度的(vmptest-ms.exe)
1、寻找虚拟机引擎
在vmp段下断点。shift-f9直达vmp引擎。(0x42d91d)
2、寻找虚拟机取指令处
f7单步执行直到
0042DD96    8B0C85 A6F64200 mov     ecx, dword ptr [eax*4+42F6A6]    ; getcodeaddr

ecx里为加密的opcode的addr
继续f7,观察ecx直到其变化为一个正常的位于vmp区段地址,此时opcode地址已解密。
继续f7,观察代码窗口,当发现retn xx时,停止,并加标签vm_execute,如下
0042F35E    C2 5400         retn    54                               ; vm_excute

3、寻找两个常用vmopcode(VM_push_CT,VM_pop_CT)
通常如果第一次通过retn跳转进入的就是VM_push_CT了。不过我们用个统计的方法,使用如下OD脚本
/*
Script written by wangdell
record opcode
20080802
//0x42e30b
*/
//test for vmprotect 1.63 release

var tmp1            
var tmp2            
var tmp3            
var tmp4            
var tmp5            
var tmp6            
var tmp7            
var tmp8            
var tmp9
var tmp10            
var imgbase

var bpVMenginejmp
var count


cmp $VERSION, "1.47"		//比较版本是否>1.47
jb odbgver
dbh				//hide od
BPHWCALL  //clear hardware breakpoint
BC				//clear software breakpoint
BPMC			//clear Memory breakpoint

mov count,0

ask_jmp:
ask "Enter EIP of VM_execute"
mov bpVMenginejmp,$RESULT
cmp bpVMenginejmp,0
je  ask_jmp
bp  $RESULT

log "VM Trace start!"
run_to_bp:
EOB  bp_record
ESTO           	//step to bp(vm_execute)

bp_record:
log ecx
jmp run_to_bp

odbgver:
msg "本脚本须配合 ODbgscript 1.47 或以上的版本"
jmp end

end:
ret 

运行脚本,输入第2步确定的vm_execute地址,脚本执行几秒后,终止脚本,观察log窗口。
Script Log Window
Address    Message
42F35E     VM Trace start!
42F35E     ecx: 0042D6A5
42F35E     ecx: 0042D6A5
42F35E     ecx: 0042D6A5
42F35E     ecx: 0042D6A5
42F35E     ecx: 0042D6A5
42F35E     ecx: 0042D6A5
42F35E     ecx: 0042D6A5
42F35E     ecx: 0042D6A5
42F35E     ecx: 0042D6A5
42F35E     ecx: 0042D6A5
42F35E     ecx: 0042D6A5
42F35E     ecx: 0042DB4B
42F35E     ecx: 0042D6A5
42F35E     ecx: 0042D95D
42F35E     ecx: 0042D95D
42F35E     ecx: 0042D95D
42F35E     ecx: 0042D95D
42F35E     ecx: 0042D95D
42F35E     ecx: 0042D95D
42F35E     ecx: 0042D95D
42F35E     ecx: 0042D95D
42F35E     ecx: 0042D95D
42F35E     ecx: 0042D95D
42F35E     ecx: 0042D95D
42F35E     ecx: 0042D95D
42F35E     ecx: 0042D95D
42F35E     ecx: 0042F3F0
42F35E     ecx: 0042D6A5
42F35E     ecx: 0042D6A5
42F35E     ecx: 0042D6A5
42F35E     ecx: 0042D6A5
42F35E     ecx: 0042D6A5
42F35E     ecx: 0042D6A5
42F35E     ecx: 0042D6A5
42F35E     ecx: 0042D6A5
42F35E     ecx: 0042D6A5
42F35E     ecx: 0042D6A5
42F35E     ecx: 0042D6A5
42F35E     ecx: 0042D6A5
42F35E     ecx: 00401254
42F35E     ecx: 00401254
42F35E     ecx: 0042E4BC
........

看到 0042D6A5 在开始处有10余条,其后 0042D95D 也有10余条,隔一条后,又有10余条0042D6A5。。。
根据以往vmp1.2x的经验,0042D6A5为VM_push_CT,0042D95D为VM_pop_CT,增加标签。

4、寻找两个关键vmopcode(VM_JMP,VM_RETN)
重新运行程序,并重新运行脚本,终止后观察脚本日志窗口
42F35E     VM Trace start!
......
42F35E     ecx: 0042D6A5 | offset <vmptest1.VM_push_CT>
42F35E     ecx: 0042D95D | offset <vmptest1.VM_pop_CT>
42F35E     ecx: 0042D95D | offset <vmptest1.VM_pop_CT>
42F35E     ecx: 0042D95D | offset <vmptest1.VM_pop_CT>
42F35E     ecx: 0042D95D | offset <vmptest1.VM_pop_CT>
42F35E     ecx: 0042D95D | offset <vmptest1.VM_pop_CT>
42F35E     ecx: 0042D95D | offset <vmptest1.VM_pop_CT>
42F35E     ecx: 0042D95D | offset <vmptest1.VM_pop_CT>
42F35E     ecx: 0042D95D | offset <vmptest1.VM_pop_CT>
42F35E     ecx: 0042D95D | offset <vmptest1.VM_pop_CT>
42F35E     ecx: 0042D95D | offset <vmptest1.VM_pop_CT>
42F35E     ecx: 0042DED5  ////////////////此为VM_retn
42F35E     ecx: 0042D6A5 | offset <vmptest1.VM_push_CT>
42F35E     ecx: 0042D6A5 | offset <vmptest1.VM_push_CT>
42F35E     ecx: 0042D6A5 | offset <vmptest1.VM_push_CT>
42F35E     ecx: 0042D6A5 | offset <vmptest1.VM_push_CT>
42F35E     ecx: 0042D6A5 | offset <vmptest1.VM_push_CT>
42F35E     ecx: 0042D6A5 | offset <vmptest1.VM_push_CT>
42F35E     ecx: 0042D6A5 | offset <vmptest1.VM_push_CT>
42F35E     ecx: 0042D6A5 | offset <vmptest1.VM_push_CT>
42F35E     ecx: 0042D6A5 | offset <vmptest1.VM_push_CT>
42F35E     ecx: 0042D6A5 | offset <vmptest1.VM_push_CT>
42F35E     ecx: 0042D6A5 | offset <vmptest1.VM_push_CT>
42F35E     ecx: 0042D6A5 | offset <vmptest1.VM_push_CT>
........
42F35E     ecx: 0042D95D | offset <vmptest1.VM_pop_CT>
42F35E     ecx: 0042D95D | offset <vmptest1.VM_pop_CT>
42F35E     ecx: 0042D95D | offset <vmptest1.VM_pop_CT>
42F35E     ecx: 0042D95D | offset <vmptest1.VM_pop_CT>
42F35E     ecx: 0042D95D | offset <vmptest1.VM_pop_CT>
42F35E     ecx: 0042D95D | offset <vmptest1.VM_pop_CT>
42F35E     ecx: 0042D95D | offset <vmptest1.VM_pop_CT>
42F35E     ecx: 0042D95D | offset <vmptest1.VM_pop_CT>
42F35E     ecx: 0042D95D | offset <vmptest1.VM_pop_CT>
42F35E     ecx: 0042D95D | offset <vmptest1.VM_pop_CT>
42F35E     ecx: 0042D95D | offset <vmptest1.VM_pop_CT>
42F35E     ecx: 0042D95D | offset <vmptest1.VM_pop_CT>
42F35E     ecx: 0042D95D | offset <vmptest1.VM_pop_CT>
42F35E     ecx: 0042F3F0 | ////////////////此为VM_jmp
42F35E     ecx: 0042D6A5 | offset <vmptest1.VM_push_CT>
42F35E     ecx: 0042D6A5 | offset <vmptest1.VM_push_CT>
42F35E     ecx: 0042D6A5 | offset <vmptest1.VM_push_CT>
42F35E     ecx: 0042D6A5 | offset <vmptest1.VM_push_CT>
42F35E     ecx: 0042D6A5 | offset <vmptest1.VM_push_CT>
42F35E     ecx: 0042D6A5 | offset <vmptest1.VM_push_CT>
42F35E     ecx: 0042D6A5 | offset <vmptest1.VM_push_CT>
42F35E     ecx: 0042D6A5 | offset <vmptest1.VM_push_CT>
42F35E     ecx: 0042D6A5 | offset <vmptest1.VM_push_CT>
42F35E     ecx: 0042D6A5 | offset <vmptest1.VM_push_CT>
42F35E     ecx: 0042D6A5 | offset <vmptest1.VM_push_CT>
42F35E     ecx: 0042D6A5 | offset <vmptest1.VM_push_CT>
......

在日志窗中寻找上面的代码片段,即VMM_push_CT n和VMM_pop_CT n。
在VMM_pop_CT n和VMM_push_CT n通常只隔有1条指令,搜索所有的这样代码段
只有2条指令符合这一要求,他们就是VM_JMP和VM_RETN。
它们的区分方法是,分别设断后,跟进去,很明显其中一个有esi的赋值,此为VM_jmp。另一个则在指令执行结尾处有retn xx。
5、追踪比对原始代码
去除所有断点,然后分别在VM_jmp开始处设断,在VM_retn结尾处设断(也就是retn xx)
0042F3F0 >  8D3455 4A022F33 lea     esi, dword ptr [edx*2+332F024A]

0042E9A0    C2 3C00         retn    3C

重新f9运行,在断点处观察堆栈和寄存器,可观察到一些原始代码的痕迹。

二、加最大保护(vmtest-mp.exe)
类似上面方法。

总结:
vmp1.63很强大,key也很强大。

[CTF入门培训]顶尖高校博士及硕士团队亲授《30小时教你玩转CTF》,视频+靶场+题目!助力进入CTF世界

收藏
点赞7
打赏
分享
最新回复 (21)
雪    币: 1946
活跃值: (238)
能力值: (RANK:330 )
在线值:
发帖
回帖
粉丝
Bughoho 8 2008-8-3 01:29
2
0
不错,不过这样的分析方法已经落后了
雪    币: 287
活跃值: (102)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
cxhcxh 3 2008-8-3 03:48
3
0
期待bughoho的高级方法
雪    币: 87
活跃值: (47)
能力值: ( LV12,RANK:250 )
在线值:
发帖
回帖
粉丝
wangdell 6 2008-8-3 08:58
4
0
在没有搞到fg的工具之前,笨人只好用笨方法,自娱自乐。
落后的方法无需加精了吧,免的误导大家。
雪    币: 485
活跃值: (12)
能力值: ( LV9,RANK:490 )
在线值:
发帖
回帖
粉丝
petnt 12 2008-8-3 10:11
5
0
或许落后的才是我等需要的。。。
雪    币: 14
活跃值: (18)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
hdy981 2008-8-3 10:38
6
0
奇怪的是key我怎么用不了,老是提示:不是正确的注册表文件格式……
雪    币: 609
活跃值: (207)
能力值: ( LV12,RANK:441 )
在线值:
发帖
回帖
粉丝
yangjt 10 2008-8-3 11:05
7
0
楼上的Key是盗版的……
雪    币: 437
活跃值: (243)
能力值: ( LV12,RANK:240 )
在线值:
发帖
回帖
粉丝
bzhkl 5 2008-8-3 11:47
8
0
key文件放入VMP所在目录就可以了。
雪    币: 425
活跃值: (412)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
鸡蛋壳 2008-8-3 11:50
9
0
攻击一小段算法理论上任何VM都可以被逆向,但逆向一个工程,那就很棘手了。所以VM加密可以让商业破解价值水涨船高,是个好事。
雪    币: 7300
活跃值: (3758)
能力值: (RANK:1130 )
在线值:
发帖
回帖
粉丝
海风月影 22 2008-8-3 14:26
10
0
最大保护里面有随机校验,爆破了也不一定稳定
wangdell可以试试看这个附件呢
http://www.unpack.cn/viewthread.php?tid=27643&page=1#pid285106

加VMP1.63前的版本在这里,可以对比一下

http://bbs.pediy.com/showthread.php?t=58356
雪    币: 85242
活跃值: (198545)
能力值: (RANK:10 )
在线值:
发帖
回帖
粉丝
linhanshi 2008-8-3 14:38
11
0
support.
雪    币: 136
活跃值: (105)
能力值: ( LV9,RANK:140 )
在线值:
发帖
回帖
粉丝
夜凉如水 3 2008-8-5 02:30
12
0
呵呵 不做评价了
雪    币: 109
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
maokecheng 2008-8-6 00:13
13
0
都是牛人啊,看了VMP,我是知难而退了,哎,,,
雪    币: 87
活跃值: (47)
能力值: ( LV12,RANK:250 )
在线值:
发帖
回帖
粉丝
wangdell 6 2008-8-6 21:19
14
0
我爆了一个,好像还算稳定。
试一下,如果没问题,我再发个破文。
上传的附件:
雪    币: 7300
活跃值: (3758)
能力值: (RANK:1130 )
在线值:
发帖
回帖
粉丝
海风月影 22 2008-8-6 21:30
15
0
猛点check和确定,一般3-4次后程序会退出

如果看不清楚,那么用OD载入,去掉所有忽略异常的勾,猛点几次,就会出异常了
雪    币: 87
活跃值: (47)
能力值: ( LV12,RANK:250 )
在线值:
发帖
回帖
粉丝
wangdell 6 2008-8-6 21:36
16
0
被你言中。果然。偶尔也会几十次不会退出。看来没必要发破文了。
雪    币: 7300
活跃值: (3758)
能力值: (RANK:1130 )
在线值:
发帖
回帖
粉丝
海风月影 22 2008-8-6 21:43
17
0
关键里面有个随机校验
搞不定啊。。。
雪    币: 87
活跃值: (47)
能力值: ( LV12,RANK:250 )
在线值:
发帖
回帖
粉丝
wangdell 6 2008-8-6 21:52
18
0
估计只是vm引擎的代码校验吧?确实在调试时会有异常的情况,没碰到太多,就没在意。
现在我是patch在vmcode里面,估计patch在其外应该不会有问题吧,可恶的是关键代码段是动态生成的。
雪    币: 206
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
yamu 2008-9-23 14:28
19
0
收藏了 来留言 对lz的辛苦表示感谢
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
快乐熊熊 2008-9-26 13:27
20
0
虽然不懂...还是要顶
雪    币: 716
活跃值: (162)
能力值: ( LV9,RANK:250 )
在线值:
发帖
回帖
粉丝
elance 6 2008-11-28 17:49
21
0
这么好的文章不能被遗忘
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
dreamxvip 2008-11-29 21:26
22
0
VMP实在是太难,看了几天头发掉了不少,但还是没搞出来.
游客
登录 | 注册 方可回帖
返回