首页
社区
课程
招聘
[原创]初学脱壳 盼望指点
发表于: 2010-2-8 00:35 5309

[原创]初学脱壳 盼望指点

2010-2-8 00:35
5309
这两天闲着没事看了一下脱壳教程http://bbs.pediy.com/showthread.php?t=20366,以前没脱过壳,一直就得加壳挺没意思的。这个教程中第一个例子比较容易,可是第二个例子的输入表不能用ImportRec修复。第二个例子加的壳是PE-Armor V0.49,这到底是个什么壳我也不知道。(第二个例子虽然加的是PE-Armor V0.49,但是本文分析的文件不是这个教程中的,末尾有附件)
按照教程可得到入口的汇编代码如下:
004010CC    FFD7            CALL EDI
004010CE    58              POP EAX
004010CF    83EC 44         SUB ESP,44
004010D2    56              PUSH ESI
004010D3    90              NOP
004010D4    E8 B518F8FF     CALL 0038298E
一看这入口就有点奇怪,ImportRec修复一下输入表,入口改成push ebp和mov ebp,esp,运行一下弹出错误的对话框。这时候拿加壳前的程序比较一下,发现有些函数调用改成了如下形式:
004010D3    90              NOP
004010D4    E8 B518F8FF     CALL 0038298E
004010D9    8BF0            MOV ESI,EAX
根据对照上面调用的是GetCommandLineA。
进去0038298E:
0038298E    50              PUSH EAX                    
0038298F    60              PUSHAD
00382990    E8 06000000     CALL 0038299B
00382995    8B6424 08       MOV ESP,DWORD PTR SS:[ESP+8]
00382999    EB 20           JMP SHORT 003829BB
0038299B    64:FF35 0000000>PUSH DWORD PTR FS:[0]
003829A2    64:8925 0000000>MOV DWORD PTR FS:[0],ESP
003829A9    9C              PUSHFD
003829AA    810C24 00010000 OR DWORD PTR SS:[ESP],100
003829B1    9D              POPFD
003829B2    90              NOP
003829B3    64:8F05 0000000>POP DWORD PTR FS:[0]
CALL 0038299B这个调用是个关键,我开始以为这个调用没什么用,经过多少次F8(不知道按了多少次CTRL+F2),终于知道这个地方只能F7。这个调用用于安装SEH,然后触发单步异常。执行这个NOP指令后,就会触发异常。当然这个地方也让我CTRL+F2了N回,一直想NOP怎么会触发异常,最后没办法打开调试选项一个个试。触发异常后会进入00382995。最后F7到003829CC:
003829CC    5D              POP EBP
003829CD    8B6D 00         MOV EBP,DWORD PTR SS:[EBP]
003829D0    8B7C24 24       MOV EDI,DWORD PTR SS:[ESP+24]                               ; unpackme.004010D9
003829D4    8BB5 AF060000   MOV ESI,DWORD PTR SS:[EBP+6AF]
003829DA    03F5            ADD ESI,EBP
003829DC    8B06            MOV EAX,DWORD PTR DS:[ESI]
003829DE    33D2            XOR EDX,EDX
003829F5    3BF8            CMP EDI,EAX
003829F7    75 0A           JNZ SHORT 00382A03
003829F9    0AD2            OR DL,DL
003829FB    75 04           JNZ SHORT 00382A01
003829FD    EB 09           JMP SHORT 00382A08
003829FF    EB 02           JMP SHORT 00382A03
00382A01    EB 2F           JMP SHORT 00382A32
00382A03    83C6 08         ADD ESI,8
00382A06  ^ EB D4           JMP SHORT 003829DC
00382A08    8B46 04         MOV EAX,DWORD PTR DS:[ESI+4]
00382A17    2BC7            SUB EAX,EDI
00382A19    F7D0            NOT EAX
00382A1B    C1C0 10         ROL EAX,10
00382A2A    8B00            MOV EAX,DWORD PTR DS:[EAX]
00382A2C    894424 20       MOV DWORD PTR SS:[ESP+20],EAX
00382A30    61              POPAD
00382A31    C3              RETN
这段汇编代码中有不少垃圾指令,这个我没有列出来。粗略看这段代码,它应该试在搜索什么东西。观察EDI值为004010D9,难道就为了搜索这个值?如下数据是ESI所指向的地址。
00383474  00401A5C  unpackme.00401A5C
00383478  9C481A1B
0038347C  00401523  unpackme.00401523
00383480  9C4414E2
00383484  0040346F  unpackme.0040346F
00383488  9C40342E
。。。。。。
003835B4  004010D9  unpackme.004010D9
003835B8  9C5C1098
搜索之后是一段计算过程,计算过程如下:
EDI =  004010D9   EAX = 9C5C1098
EAX = EAX - EDI = 63E40040
ROL 10就是将高低调换一下位置,最后
EAX = 004063E4
这时候查看数据
004063E4  7C812C8D  kernel32.GetCommandLineA
004063E8  7C810082  kernel32.GlobalUnlock
004063EC  7C839418  kernel32._lread
目前就分析到此了,能力有限还没法修复脱壳后的程序。被替换的函数有好多呢,不知道哪位高人有没有简单易懂的方法快速替换。看了几个脱这个壳的例子,都没看懂。有人用脚本,这个更不懂了。最后说下怎么快速到达入口004010CC,教程上的方法适合第一次跟踪。如果像我这样不停的CTRL+F2那就有点费时了。我的方法:
1、忽略所有异常 在004010CC下内存写入断点,F9;
2、如果没啥问题的话应该断在00382712,这时候在00382715(这个地址可以选别的)F2,清除内存断点,F9
3、中断在00382715,清除断点,然后在004010CC内存访问断点,F9;
4、最后就到达了00401CC了。
一些简单的壳分析http://bbs.pediy.com/showthread.php?t=106596 第二个例子就在其中

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

上传的附件:
收藏
免费 0
支持
分享
最新回复 (4)
雪    币: 424
活跃值: (10)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
2
被替换的是有点多,所以我才写脚本的嘛

说一下我找的思路:
先让eip到被劫走的地方,然后对单步进入call中
这个时候对iat所在的段下内存断点,然后运行程序
会在mov eax, [eax]这一句断下来,这时eax就是对应的IAT的位置
再把调用处的call改成call [此时的eax]即可
就是有点多......

说实话这个壳就是我从那个脱壳教材里载下来的,本来一直搞不定,耗了好久,才认真去分析了一篇
2010-2-8 11:11
0
雪    币: 377
活跃值: (10)
能力值: ( LV9,RANK:170 )
在线值:
发帖
回帖
粉丝
3
[QUOTE=resty;759675]被替换的是有点多,所以我才写脚本的嘛

说一下我找的思路:
先让eip到被劫走的地方,然后对单步进入call中
这个时候对iat所在的段下内存断点,然后运行程序
会在mov eax, [eax]这一句断下来,这时eax就是对应的IAT的位置
再把调用处的call改成call [此时的ea...[/QUOTE]
mov oesp, esp
mov caddr, $RESULT
mov eip, caddr
sti
sti
//然后再下内存断点
BPRM 00401000, 6000
run
BPMC
mov ebp, caddr
EXEC
mov word [ebp], 15FF
mov dword [ebp+2], eax
ENDE
利用了你上面那段脚本,直接把偷出去的代码全部恢复了,用ollydump转存,脱壳后文件可以运行
下面是我凑的脚本(初次弄脚本 搞的乱七八糟的)
var count
var addr
var patchaddr
bpwm 4010CC,4
run
bpmc
bp 382715
run
bc 382715
bprm 4010cc,4
run
bpmc
log "Hello world"
mov count,0
mov addr,401000
loc1:
find addr,#90E8#
mov addr,$RESULT
mov patchaddr,addr
add addr,6
cmp $RESULT, 0
je loc2
//log addr
//log $RESULT
mov eip,patchaddr
sti
sti
bprm 401000,6000
run
bpmc
mov ebp,patchaddr
EXEC
mov word [ebp],15FF
mov dword [ebp+2],eax
ENDE
add count,1
//log count
jmp loc1
loc2:
log "end"
eval "被替换的call个数{count}"
log $RESULT
入口手动修复的
不过这个壳用LoadPE没法转存,不知道为什么
2010-2-9 00:49
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
路过, 学习了。
2010-2-10 01:00
0
雪    币: 10077
活跃值: (2458)
能力值: ( LV7,RANK:115 )
在线值:
发帖
回帖
粉丝
5
学习学习。。
2010-3-5 15:16
0
游客
登录 | 注册 方可回帖
返回
//