vmp1.8test破解(超详细!)——作者:csjwaman
说明:
以前一直没敢玩VM的东东,因为那都是牛牛们的专利。这个东东,牛牛们、大大们不屑玩。国庆假期有些空闲时间,我就斗胆看了下,
觉得挺有意思。花了二个多小时(大大们不要笑话),跟踪了一下,把过程记录下来,为和我一样的菜鸟提供点参考。
vmp1.8test.exe为VMP1.8加壳
帖子见:http://www.unpack.cn/viewthread.php?tid=41042&extra=page%3D1
原帖子的说明:
vmp 1.8 CrackME
这次没钱了 (上次给海风骗了一笔 ,没法 )
当然如果爆的漂亮,我还是会去帮你+10 的,我这人就是厚道
VMP 是随机加密的 , 1.8 比 1.7(上次那个多了个效验),别怕
不要求多小字节数 , 还是上次那个模板 ( 没劲去再编译一个了 )
还是保留了上一次一个模式,没对关键代码做淫荡的 V 处理,一运行都傻傻的躺在那里 。
要求还是和上次一样 :
什么什么不能用 L 啊,什么不能 UN 啊,不用输入任何东西点击出现 OK 啊
只是给刚入门的朋友玩玩 ,那些什么牛牛啊,飘飘的远离
破解过程:
1、直接用OD载入,运行后来到401000处,搜索字符串:
Found strings are
Address Disassembly Text string
00400000 DEC EBP (Initial CPU selection)
004014DB PUSH 0x403024 ASCII "ok" /////关键字符
004014ED PUSH 0x403020 ASCII "no" /////
004087DF MOV ESI,0x401364 ASCII "D$h"
00409B56 MOV ESI,0x4018B9 ASCII "Ix"
0040A8F9 MOV EBP,0x4018B9 ASCII "Ix"
0040C61B MOV EDI,0x4014EF ASCII "0@"
0040C7D0 MOV EDI,0x4014EF ASCII "0@"
0040CBC7 MOV ESI,0x4018B9 ASCII "Ix"
00419B29 ADD DWORD PTR DS:[EBX-0x7E],0x5ADEF64B ASCII "izeCriticalSectionAndSpinCount"
来到代码处:
004014B8 49 DEC ECX
004014B9 8D7C24 1C LEA EDI,DWORD PTR SS:[ESP+0x1C]
004014BD 8BD1 MOV EDX,ECX
004014BF 83C9 FF OR ECX,-0x1
004014C2 F2:AE REPNE SCAS BYTE PTR ES:[EDI]
004014C4 F7D1 NOT ECX
004014C6 49 DEC ECX
004014C7 83FA 05 CMP EDX,0x5
004014CA 7C 33 JL SHORT 004014FF ; 用户名长度比较,可以直接NOP,或者直接跳到004014D7,机器码EB0B
004014CC 83F9 05 CMP ECX,0x5 ; 直接跳更好,可以少改两个字节。
004014CF 7C 2E JL SHORT 004014FF ; 注册码长度比较
004014D1 0FAFCA IMUL ECX,EDX
004014D4 83F9 1E CMP ECX,0x1E
004014D7 50 PUSH EAX
004014D8 50 PUSH EAX
004014D9 75 12 JNZ SHORT 004014ED ; 注册成功与否比较,NOP
004014DB 68 24304000 PUSH 0x403024 ; ASCII "ok"
004014E0 8BCE MOV ECX,ESI
004014E2 E8 F1A10000 CALL 0040B6D8 ; 成功对话框
004014E7 5F POP EDI
004014E8 5E POP ESI
004014E9 83C4 28 ADD ESP,0x28
004014EC C3 RETN
004014ED 68 20304000 PUSH 0x403020 ; ASCII "no"
004014F2 8BCE MOV ECX,ESI
004014F4 E8 026D0000 CALL 004081FB ; 失败对话框
004014F9 5F POP EDI
004014FA 5E POP ESI
004014FB 83C4 28 ADD ESP,0x28
004014FE C3 RETN
004014FF 6A 00 PUSH 0x0
00401501 E8 D2960000 CALL 0040ABD8 ; 0040ABD8
00401506 8190 90909090 90909090 ADC DWORD PTR DS:[EAX-0x6F6F6F70],0x90909090
00401510 8B41 20 MOV EAX,DWORD PTR DS:[ECX+0x20]
00401513 6A 00 PUSH 0x0
00401515 50 PUSH EAX
00401516 50 PUSH EAX
00401517 E8 9BA70000 CALL 0040BCB7 ; 0040BCB7
0040151C C3 RETN
0040151D 90 NOP
0040151E 90 NOP
0040151F 90 NOP
00401520 8B41 20 MOV EAX,DWORD PTR DS:[ECX+0x20]
00401523 6A 01 PUSH 0x1
从以上分析得知,共得修改4个字节。
2、定位解密代码
在004014CA处下硬件访问BYTE断点,重新载入程序并运行,断下:
00413D53 F8 CLC
00413D54 85C9 TEST ECX,ECX
00413D56 60 PUSHAD
00413D57 9C PUSHFD
00413D58 E8 2BA80000 CALL 0041E588
00413D5D F6D3 NOT BL
00413D5F AA STOS BYTE PTR ES:[EDI]
00413D60 FF7424 04 PUSH DWORD PTR SS:[ESP+0x4] ;断在这里
00413D64 E8 88190000 CALL 004156F1
00413D69 8B75 04 MOV ESI,DWORD PTR SS:[EBP+0x4]
00413D6C 60 PUSHAD
00413D6D F9 STC
00413D6E F6C3 1F TEST BL,0x1F
00413D71 E8 FE180000 CALL 00415674
00413D76 68 C4880103 PUSH 0x30188C4
寄存器:
EAX 0000007C
ECX 00000000
EDX 00401060 vmp1_8te.00401060
EBX 000000FE
ESP 0012F77C
EBP 0000000E
ESI 00414A6F vmp1_8te.00414A6F ///下一个待解密的数据
EDI 004014CB vmp1_8te.004014CB ///下一个将写入的地址
EIP 00413D60 vmp1_8te.00413D60
00414A6E处为61 解密后为7C
00414A6F处为93 解密后为33
单步跟踪一下:
00410E43 AC LODS BYTE PTR DS:[ESI] ////取数据到AL
00410E44 66:0FBAE5 02 BT BP,0x2
00410E49 08CB OR BL,CL
00410E4B 80CB A9 OR BL,0xA9
00410E4E 3C E1 CMP AL,0xE1 ///与E1比较,不知什么用处
00410E50 34 19 XOR AL,0x19 ///xor 19
00410E52 E9 57540000 JMP 004162AE
004162AE F8 CLC
004162AF 68 51CFA3FD PUSH 0xFDA3CF51
004162B4 68 23CF272B PUSH 0x2B27CF23
004162B9 C0C0 02 ROL AL,0x2 ///rol
004162BC C0D3 03 RCL BL,0x3
004162BF 08DB OR BL,BL
004162C1 F8 CLC
004162C2 F6C6 12 TEST DH,0x12
004162C5 2C 5D SUB AL,0x5D ///sub
004162C7 18E3 SBB BL,AH
004162C9 F6D8 NEG AL ///neg
004162CB 0F99C3 SETNS BL
004162CE ^ E9 8ADAFFFF JMP 00413D5D
00413D5D F6D3 NOT BL
00413D5F AA STOS BYTE PTR ES:[EDI] ////写入
00413D60 FF7424 04 PUSH DWORD PTR SS:[ESP+0x4]
00413D64 E8 88190000 CALL 004156F1
00413D69 8B75 04 MOV ESI,DWORD PTR SS:[EBP+0x4]
从以上可以很容易找出解密算法:
XOR AL,0x19
ROL AL,0x2
SUB AL,0x5D
NEG AL
用穷举法可以很容易解密数据:
@0x401000:
xor eax,eax
xor ebx,ebx
@L000:
XOR AL,0x19
ROL AL,0x2
SUB AL,0x5D
NEG AL
CMP AL,0xEB ////比较是否已经得到我们想要的值EB、0B、90
@L005:
JE @L005 ////得到数据后死循环
MOV AL,BL
INC BL
JMP @L000
运算后得:
EB-85
0B-8D
90-6A
对程序作如下修改:
414A6E:61->85
414A6F:93->8D
414A7D:23->6A
414A7E:CB->6A
3、去除自校验
修改后运行程序出错,有校验。出错时代码都没有解密。
在414A6E处下硬件访问BYTE断点。断下:
00422146 3202 XOR AL,BYTE PTR DS:[EDX] ///EDX=414A6E
00422148 881C24 MOV BYTE PTR SS:[ESP],BL ///断在这里
0042214B 68 577EF4FF PUSH 0xFFF47E57
00422150 9C PUSHFD
00422151 885C24 04 MOV BYTE PTR SS:[ESP+0x4],BL
00422155 42 INC EDX
00422156 E8 2FF5FFFF CALL 0042168A
0042168A /E9 551A0000 JMP 004230E4
004230E4 66:890C24 MOV WORD PTR SS:[ESP],CX
004230E8 FF4D 00 DEC DWORD PTR SS:[EBP] ///[ebp]为待计算数据块长度
004230EB E8 C7F6FFFF CALL 004227B7
004227B7 ^\E9 29F1FFFF JMP 004218E5
004218E5 880C24 MOV BYTE PTR SS:[ESP],CL
004218E8 8D6424 58 LEA ESP,DWORD PTR SS:[ESP+0x58]
004218EC 0F85 40090000 JNZ 00422232 ///判断数据块是否已经计算完成
004218F2 ^ E9 8AFFFFFF JMP 00421881 ///数据块解密完成,继续计算下一块
004218F7 E9 99060000 JMP 00421F95
取消原硬件断点,然后在004218F2处下硬件执行断点,看计算到哪个数据块以后出错。用脚本记录一下:
var aman ///用于记录中断次数
lc
bphws 4218f2,"x"
looper:
inc aman
log aman
esto
log eax ///EAX为校验值
jmp looper ///循环到出错为止
等程序出错后:EAX=0x5D798D9E aman=1A
接着跟踪原程序,修改一下脚本:
var aman
lc
bphws 4218f2,"x"
looper:
inc aman
log aman
esto
log eax
cmp aman,1a ///中断1a次后结束
je over
jmp looper
over:
ret
用修改后的脚本跑原程序,中断后:EAX=0xB61A6083 这个就是正确的校验值。
再次修改程序:
将
004218F2 ^ E9 8AFFFFFF JMP 00421881
修改为:
004218F2 /E9 751D0000 JMP 0042366C ////跳到补丁处
补丁处0042366C代码:
CMP EAX,0x5D798D9E ///这个还得重新确定一次,因为我们已经再次修改了代码,校验值变化了。
MOV EAX,0xB61A6083 ///如果最终的错误校验值出现了,就将正确值写入EAX
JMP SHORT 00421881 ///补回原代码
重新确定错误的校验值为0xBE1D4042
因此0042366C处的补丁代码可以修改为:
cmp eax,0xBE1D4042
je @fix
jmp 421881
@fix:
MOV EAX,0xB61A6083
JMP SHORT 00421881
打上补丁以后,运行程序,又出错。看来还有校验。但通过观察发现这次出错时,代码都已经解开。
继续在004218f2处下硬件执行断点,用脚本记录出错时中断的次数,发现当中断7C次后,程序出错。
此时EAX=0x8D698D9D
用脚本(原来的1A改为7C)跟踪原程序,正确的值应为0x9D7989B2
于是,补丁处的代码如下:
0042366C 3D 42401DBE CMP EAX,0xBE1D4042 ///第一次校验时的错误值
00423671 74 09 JE SHORT 0042367C
00423673 3D 9D8D698D CMP EAX,0x8D698D9D ///第二次校验时的错误值
00423678 74 09 JE SHORT 00423683
0042367A EB 0C JMP SHORT 00423688
0042367C B8 83601AB6 MOV EAX,0xB61A6083 ///第一次校验时的正确值
00423681 EB 05 JMP SHORT 00423688
00423683 B8 B289799D MOV EAX,0x9D7989B2 ///第二次校验时的正确值
00423688 ^ E9 F4E1FFFF JMP 00421881 ///补上原代码
0042368D 90 NOP
补丁后程序正常运行,至此破解完成。
另,估计还有其他破解方法,没有尝试。如可以等校验过后再修改字节,等解码结束,再恢复字节。
注意:
补丁地址0042366C处没有校验,所以写补丁对校验值没影响。
如果补丁处也有校验的话,不知该怎么办了!
已经有(0)位网友发表了评论,你也评一评吧!
原创文章如转载,请注明:转载自Eddy Blog
原文地址:http://www.rrgod.com/decryption/93.html 欢迎订阅Eddy Blog。