本帖最后由 kexinkids 于 2013-7-12 18:58 编辑
感觉易语言的程序手动脱壳后总是修复不了,可能水平有限吧。。。最近脱几个upx/aspack壳的失败对我打击很大,还好有了脱壳机和脱壳脚本。
闲言少叙。用一次esp定律到达这里
[Plain Text] 纯文本查看 复制代码 004A9F75 8D4424 80 LEA EAX,DWORD PTR SS:[ESP-80]
004A9F79 6A 00 PUSH 0
004A9F7B 39C4 CMP ESP,EAX ; kernel32.BaseThreadInitThunk
004A9F7D ^ 75 FA JNZ SHORT 第三集.004A9F79
004A9F7F 83EC 80 SUB ESP,-80
004A9F82 - E9 4648FAFF JMP 第三集.0044E7CD ; 解码完毕,准备跳到oep
004A9F87 0000 ADD BYTE PTR DS:[EAX],AL
004A9F89 0000 ADD BYTE PTR DS:[EAX],AL
004A9F8B 0000 ADD BYTE PTR DS:[EAX],AL
004A9F8D 0000 ADD BYTE PTR DS:[EAX],AL
004A9F8F 0000 ADD BYTE PTR DS:[EAX],AL
004A9F91 0000 ADD BYTE PTR DS:[EAX],AL
004A9F93 0000 ADD BYTE PTR DS:[EAX],AL
不要小看了下面的这些
[Plain Text] 纯文本查看 复制代码 004A9F8D 0000 ADD BYTE PTR DS:[EAX],AL
我们一会儿要用到这些空字节做文章。
继续走,到达oep,查字符串,发现可疑字符串为 注册码与用户名不匹配!
跟进去,代码停在
004012C3 E8 260E0000 CALL 第三集.004020EE
004012C8 83C4 04 ADD ESP,4
004012CB 837D F4 00 CMP DWORD PTR SS:[EBP-C],0
004012CF 0F84 8C000000 JE 第三集.00401361 ;关键跳
004012D5 6A 00 PUSH 0
004012D7 68 76FC4600 PUSH 第三集.0046FC76 ; 已注册感谢您的支持!注册码与用户名不匹配!
004012DC 6A FF PUSH -1
004012DE 6A 08 PUSH 8
004012E0 68 6D190116 PUSH 1601196D
004012E5 68 01000152 PUSH 52010001
004012EA E8 170E0000 CALL 第三集.00402106
004012EF 83C4 18 ADD ESP,18
004012F2 6A 00 PUSH 0
004012F4 68 FF000000 PUSH 0FF
004012F9 6A FF PUSH -1
004012FB 6A 10 PUSH 10
004012FD 68 6D190116 PUSH 1601196D
00401302 68 01000152 PUSH 52010001
00401307 E8 FA0D0000 CALL 第三集.00402106
0040130C 83C4 18 ADD ESP,18
0040130F 6A 00 PUSH 0
00401311 68 FF000000 PUSH 0FF
00401316 6A FF PUSH -1
00401318 6A 10 PUSH 10
0040131A 68 6C190116 PUSH 1601196C
0040131F 68 01000152 PUSH 52010001
00401324 E8 DD0D0000 CALL 第三集.00402106
00401329 83C4 18 ADD ESP,18
0040132C 6A 00 PUSH 0
0040132E 6A 00 PUSH 0
00401330 6A 00 PUSH 0
00401332 68 01030080 PUSH 80000301
00401337 6A 00 PUSH 0
00401339 68 00000000 PUSH 0
0040133E 68 04000080 PUSH 80000004
00401343 6A 00 PUSH 0
00401345 68 7DFC4600 PUSH 第三集.0046FC7D ; 感谢您的支持!注册码与用户名不匹配!
0040134A 68 03000000 PUSH 3
0040134F BB 40284000 MOV EBX,第三集.00402840
00401354 E8 A10D0000 CALL 第三集.004020FA
00401359 83C4 28 ADD ESP,28
0040135C E9 30000000 JMP 第三集.00401391
00401361 6A 00 PUSH 0 ;失败跳转的目的地
00401363 6A 00 PUSH 0
00401365 6A 00 PUSH 0
00401367 68 01030080 PUSH 80000301
0040136C 6A 00 PUSH 0
0040136E 68 00000000 PUSH 0
00401373 68 04000080 PUSH 80000004
00401378 6A 00 PUSH 0
0040137A 68 8CFC4600 PUSH 第三集.0046FC8C ; 注册码与用户名不匹配!
0040137F 68 03000000 PUSH 3
00401384 BB 40284000 MOV EBX,第三集.00402840
判断失败则跳到 00401361。因此我们要把
[Plain Text] 纯文本查看 复制代码 004012CF 0F84 8C000000 JE 第三集.00401361 ;关键跳
给nop掉。如果我们直接nop的话,然后用od保存文件,会提示
这是因为带壳的缘故,不解压缩,则无法定位代码地址。
我们应该明白,我们的目的就是把这一句给nop掉就ok了(也即从004012CF开始的6个字节)。所以我们回到帖子开头,解码完毕,跳到oep的关键句。
[Plain Text] 纯文本查看 复制代码
004A9F82 - E9 4648FAFF JMP 第三集.0044E7CD ; 解码完毕,准备跳到oep
004A9F87 0000 ADD BYTE PTR DS:[EAX],AL
004A9F89 0000 ADD BYTE PTR DS:[EAX],AL
004A9F8B 0000 ADD BYTE PTR DS:[EAX],AL
004A9F8D 0000 ADD BYTE PTR DS:[EAX],AL
004A9F8F 0000 ADD BYTE PTR DS:[EAX],AL
004A9F91 0000 ADD BYTE PTR DS:[EAX],AL
004A9F93 0000 ADD BYTE PTR DS:[EAX],AL
我们需要在程序跳到oep执行之前,将程序中相应的代码nop掉。所以我们这样做
[Plain Text] 纯文本查看 复制代码 MOV EAX,第三集.004012CF ;要patch的地址送EAX
MOV DWORD PTR DS:[EAX],90909090 ;给EAX地址处送一个DWORD值 90909090,转化为汇编代码也就是4个NOP
MOV MOV EAX,第三集.004012D3 ;还有两个字节要nop掉,这里我们把指针移动到下一个需要patch的地址 004012CF+4 = 004012D3。其中的4也就是一个DWORD的长度
MOV WORD PTR DS:[EAX],9090 ;给EAX地址处送一个WORD值 9090,转化为汇编代码也就是2个NOP
JMP 第三集.0044E7CD ;无论我们之前做了些什么,最后总是要跳到oep的。
其实跟内存补丁的原理是一样的,不过upx壳特意在jmp到oep的语句下面留了这么大的空白字段方便让我们做点事情。
最后,不要忘记把上面那句jmp oep给nop掉,不然我们的patch代码是不会执行到的。
保存到可执行文件,执行->注册,已经被爆破了。
|