【文章标题】: 手脱Minke 1.0.1的壳
【文章作者】: lovebird/爱鸟
【作者邮箱】: lovebird_ustc#126.com
【软件名称】: Minkecn加压的Unpacktest
【软件大小】: 压缩前104KB 压缩后126KB//这个也叫压缩...
【下载地址】: 在附件里面
【加壳方式】: Minke 1.0.1
【保护方式】: Minke 1.0.1
【编写语言】: VC++ 6.0 Debug
【使用工具】: LordPe OD Peid.94
【操作平台】: XP Sp3+Vmware
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
使用Minkecn加压我提供的UnpackTest 生成一个Minke-Unpacktest.exe的文件。Peid一扫,结果是
Borland Delphi 6.0 - 7.0 [Overlay]//深度扫描和核心扫描均是这个 欺骗我的Peid签名成功
不管它,直接od载入:
10004020 > $ 55 PUSH EBP ; 停在这里
10004021 . 8BEC MOV EBP,ESP
10004023 . 83C4 F0 ADD ESP,-10
10004026 . 53 PUSH EBX
10004027 . 56 PUSH ESI ; 伪造的Delphi入口
10004028 . B8 E83F0010 MOV EAX,Minke-Un.10003FE8
1000402D . E8 7AF6FFFF CALL Minke-Un.100036AC
10004032 . BE 68660010 MOV ESI,Minke-Un.10006668
10004037 . 33C0 XOR EAX,EAX
10004039 . 55 PUSH EBP
1000403A . 68 DB400010 PUSH Minke-Un.100040DB
1000403F . 64:FF30 PUSH DWORD PTR FS:[EAX]
10004042 . 64:8920 MOV DWORD PTR FS:[EAX],ESP
10004045 . E8 FAF8FFFF CALL Minke-Un.10003944
1000404A . BA EC400010 MOV EDX,Minke-Un.100040EC ; ASCII "CA18"
1000404F . 8BC6 MOV EAX,ESI ; 上一个字符串是此壳标示符
10004051 . E8 F2FAFFFF CALL Minke-Un.10003B48
10004056 . 8BD8 MOV EBX,EAX
10004058 . B8 6C660010 MOV EAX,Minke-Un.1000666C
1000405D . 8B16 MOV EDX,DWORD PTR DS:[ESI]
1000405F . E8 88F2FFFF CALL Minke-Un.100032EC
10004064 . B8 6C660010 MOV EAX,Minke-Un.1000666C
注意到 停在1000XXXX空间,而不是Peid扫描得到的00004020,顿生疑惑。不管它,继续F8
跟下去。说一下,这里是一个压缩壳(我还在弄压缩壳,大虾烦指导如何进入加密壳领域),
毫无反追反调。一路F8下去:
100040B0 . E8 A7E4FFFF CALL Minke-Un.1000255C
100040B5 . 8BC3 MOV EAX,EBX
100040B7 . E8 C4FBFFFF CALL Minke-Un.10003C80 ; 此处F7
100040BC . E8 E7F8FFFF CALL Minke-Un.100039A8 ; 第一次跟 在这里跑飞
100040C1 . 8BC3 MOV EAX,EBX
100040C3 . E8 B0E3FFFF CALL Minke-Un.10002478
100040C8 . E8 DBF8FFFF CALL Minke-Un.100039A8
100040CD . 33C0 XOR EAX,EAX
100040CF . 5A POP EDX
100040D0 . 59 POP ECX
100040D1 . 59 POP ECX
100040D2 . 64:8910 MOV DWORD PTR FS:[EAX],EDX
100040D5 . 68 E2400010 PUSH Minke-Un.100040E2
100040DA > C3 RETN ; RET 用作跳转到 100040E2
第一次追踪在100040BC处跑飞 所以运行代码在100040B7处。Ctrl+F2,重新来过。在100040B7处F7进去
来到这儿:
10003C80 /$ 55 PUSH EBP ; F7过来 到了这儿
10003C81 |. 8BEC MOV EBP,ESP
10003C83 |. 81C4 B8FEFFFF ADD ESP,-148 ; 好深的栈
10003C89 |. 53 PUSH EBX
10003C8A |. 56 PUSH ESI
10003C8B |. 57 PUSH EDI
10003C8C |. 33D2 XOR EDX,EDX
10003C8E |. 8995 B8FEFFFF MOV DWORD PTR SS:[EBP-148],EDX
10003C94 |. 8945 FC MOV DWORD PTR SS:[EBP-4],EAX
10003C97 |. 33C0 XOR EAX,EAX
10003C99 |. 55 PUSH EBP
于是进行再次的F8操作,行不几步,到了这里:
10003E44 |. E8 3FE8FFFF CALL Minke-Un.10002688
10003E49 |. 8B85 B8FEFFFF MOV EAX,DWORD PTR SS:[EBP-148]
10003E4F |. E8 40F4FFFF CALL Minke-Un.10003294
10003E54 |. 50 PUSH EAX ; |CommandLine
10003E55 |. 6A 00 PUSH 0 ; |ModuleFileName = NULL
10003E57 |. E8 04F9FFFF CALL <JMP.&kernel32.CreateProcessA> ; \CreateProcessA
10003E5C |. C785 10FFFFFF>MOV DWORD PTR SS:[EBP-F0],10007
10003E66 |. 8D85 10FFFFFF LEA EAX,DWORD PTR SS:[EBP-F0]
10003E6C |. 50 PUSH EAX ; /pContext
10003E6D |. 8B85 04FFFFFF MOV EAX,DWORD PTR SS:[EBP-FC] ; |
10003E73 |. 50 PUSH EAX ; |hThread
10003E74 |. E8 07F9FFFF CALL <JMP.&kernel32.GetThreadContext> ; \GetThreadContext
10003E79 |. E8 2AFBFFFF CALL Minke-Un.100039A8
10003E7E |. 8D45 F4 LEA EAX,DWORD PTR SS:[EBP-C]
10003E81 |. 50 PUSH EAX ; /pBytesRead
10003E82 |. 6A 04 PUSH 4 ; |BytesToRead = 4
10003E84 |. 8D45 F8 LEA EAX,DWORD PTR SS:[EBP-8] ; |
10003E87 |. 50 PUSH EAX ; |Buffer
10003E88 |. 8B45 B4 MOV EAX,DWORD PTR SS:[EBP-4C] ; |
10003E8B |. 83C0 08 ADD EAX,8 ; |
10003E8E |. 50 PUSH EAX ; |pBaseAddress
10003E8F |. 8B85 00FFFFFF MOV EAX,DWORD PTR SS:[EBP-100] ; |
10003E95 |. 50 PUSH EAX ; |hProcess
10003E96 |. E8 FDF8FFFF CALL <JMP.&kernel32.ReadProcessMemory> ; \ReadProcessMemory
此处看来不妙,难道是进程检测?继续跟踪
10003E9D |. 68 00300000 PUSH 3000
10003EA2 |. 8B45 EC MOV EAX,DWORD PTR SS:[EBP-14]
10003EA5 |. 50 PUSH EAX
10003EA6 |. 8B45 E0 MOV EAX,DWORD PTR SS:[EBP-20]
10003EA9 |. 8B40 34 MOV EAX,DWORD PTR DS:[EAX+34] ; 此处D eax
10003EAC |. 50 PUSH EAX
10003EAD |. 8B85 00FFFFFF MOV EAX,DWORD PTR SS:[EBP-100]
10003EB3 |. 50 PUSH EAX
10003EB4 |. E8 FFF8FFFF CALL <JMP.&kernel32.VirtualAllocEx>
10003EB9 |. 8D45 F4 LEA EAX,DWORD PTR SS:[EBP-C]
在10003EA9处d eax,可以看到内存指向的地址
008DA0F4 50 45 00 00 4C 01 06 00 43 D3 40 4B 00 00 00 00 PE..L.C覢K....
008DA104 00 00 00 00 E0 00 0E 01 0B 01 06 00 00 40 01 00 ....?..@.
008DA114 00 50 00 00 00 00 00 00 30 1B 00 00 00 10 00 00 .P......0.....
008DA124 00 10 00 00 00 00 40 00 00 10 00 00 00 10 00 00 .....@.......
008DA134 04 00 00 00 00 00 00 00 04 00 00 00 00 00 00 00 ..............
008DA144 00 A0 01 00 00 10 00 00 00 00 00 00 02 00 00 00 .?...........
008DA154 00 00 10 00 00 10 00 00 00 00 10 00 00 10 00 00 ............
008DA164 00 00 00 00 10 00 00 00 00 00 00 00 00 00 00 00 ...............
008DA174 00 70 01 00 64 00 00 00 00 80 01 00 A6 0C 00 00 .p.d....€.?..
008DA184 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
008DA194 00 90 01 00 50 02 00 00 00 50 01 00 1C 00 00 00 .?.P...P....
008DA1A4 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
008DA1B4 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
008DA1C4 00 00 00 00 00 00 00 00 54 73 01 00 F0 02 00 00 ........Ts.?..
008DA1D4 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
008DA1E4 00 00 00 00 00 00 00 00 2E 74 65 78 74 00 00 00 .........text...
008DA1F4 70 30 01 00 00 10 00 00 00 40 01 00 00 10 00 00 p0.....@....
008DA204 00 00 00 00 00 00 00 00 00 00 00 00 20 00 00 60 ............ ..`
008DA214 2E 72 64 61 74 61 00 00 C9 05 00 00 00 50 01 00 .rdata..?...P.
008DA224 00 10 00 00 00 50 01 00 00 00 00 00 00 00 00 00 ....P.........
008DA234 00 00 00 00 40 00 00 40 2E 64 61 74 61 00 00 00 ....@..@.data...
008DA244 14 09 00 00 00 60 01 00 00 10 00 00 00 60 01 00 ....`.....`.
008DA254 00 00 00 00 00 00 00 00 00 00 00 00 40 00 00 C0 ............@..
这里实质上就是我们要Dump的文件的PE部分头 。往前翻一翻转存窗口 就能看见:
008DA014 4D 5A 90 00 03 00 00 00 04 00 00 00 FF FF 00 00 MZ?........
008DA024 B8 00 00 00 00 00 00 00 40 00 00 00 00 00 00 00 ?......@.......
008DA034 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
008DA044 00 00 00 00 00 00 00 00 00 00 00 00 E0 00 00 00 ............?..
008DA054 0E 1F BA 0E 00 B4 09 CD 21 B8 01 4C CD 21 54 68 ?.???L?Th
008DA064 69 73 20 70 72 6F 67 72 61 6D 20 63 61 6E 6E 6F is program canno
008DA074 74 20 62 65 20 72 75 6E 20 69 6E 20 44 4F 53 20 t be run in DOS
008DA084 6D 6F 64 65 2E 0D 0D 0A 24 00 00 00 00 00 00 00 mode....$.......
008DA094 85 46 CE 8E C1 27 A0 DD C1 27 A0 DD C1 27 A0 DD 匜螏?犦?犦?犦
008DA0A4 A3 38 B3 DD C5 27 A0 DD 42 3B AE DD C0 27 A0 DD ?齿?犦B;?犦
008DA0B4 AE 38 AA DD CA 27 A0 DD AE 38 A4 DD C3 27 A0 DD ??犦?ぽ?犦
008DA0C4 F7 01 A4 DD C2 27 A0 DD C1 27 A1 DD B8 27 A0 DD ?ぽ?犦?≥?犦
008DA0D4 F7 01 AB DD C7 27 A0 DD 06 21 A6 DD C0 27 A0 DD ??犦!?犦
008DA0E4 52 69 63 68 C1 27 A0 DD 00 00 00 00 00 00 00 00 Rich?犦........
这里是不是很熟悉?应该是生成的新文件的DOS头。不管了 继续F8
10003F02 |. 8B45 E0 MOV EAX,DWORD PTR SS:[EBP-20]
10003F05 |. 8B40 34 MOV EAX,DWORD PTR DS:[EAX+34]
10003F08 |. 8B55 E0 MOV EDX,DWORD PTR SS:[EBP-20]
10003F0B |. 0342 28 ADD EAX,DWORD PTR DS:[EDX+28]
10003F0E |. 8945 C0 MOV DWORD PTR SS:[EBP-40],EAX ; 此处得到OEP
10003F11 |. 8D85 10FFFFFF LEA EAX,DWORD PTR SS:[EBP-F0]
在此处将几段拼接在一起,OEP为10003F0E处的eax值 由上述语句可以看到,存入了EBP-40
F8一下,然后看堆栈:
EBP-60 > 00000038
EBP-5C > 00000023
EBP-58 > 00000023
EBP-54 > 0012F72C
EBP-50 > 0012FB08
EBP-4C > 7FFDE000
EBP-48 > 00150000
EBP-44 > 0012F518
EBP-40 > 00401B30//此处就是OEP
EBP-3C > 0012F958
EBP-38 > 7C810705 kernel32.7C810705
EBP-34 > 0000001B
EBP-30 > 00000200
EBP-2C > 0012FFFC
EBP-28 > 00000023
EBP-24 > 008F4018
EBP-20 > 008DA0F4 ASCII "PE"//pe头
EBP-1C > 0090E018
EBP-18 > 000003EC
EBP-14 > 0001A000
EBP-10 > 00001000
EBP-C > 00000004
EBP-8 > 10000000 ASCII "MZP"//dos头
EBP-4 > 008DA014
继续F8,到10003F2B处:
10003F24 |. 8B85 04FFFFFF MOV EAX,DWORD PTR SS:[EBP-FC]
10003F2A |. 50 PUSH EAX ; /hThread
10003F2B |. E8 70F8FFFF CALL <JMP.&kernel32.ResumeThread> ; \ResumeThread
10003F30 |. 33C0 XOR EAX,EAX
10003F32 |. 5A POP EDX
10003F33 |. 59 POP ECX
10003F34 |. 59 POP ECX
10003F35 |. 64:8910 MOV DWORD PTR FS:[EAX],EDX
此时在cmd窗口输入tasklist:
Minke-Unpacktest.exe 1628 Console 0 1,820 K//这是加壳后的镜像
Minke-Unpacktest.exe 1632 Console 0 176 K//这个是我们要转存的程序
cmd.exe 1364 Console 0 2,940 K
conime.exe 492 Console 0 3,400 K
继续F8
10003F17 |. 50 PUSH EAX ; /pContext
10003F18 |. 8B85 04FFFFFF MOV EAX,DWORD PTR SS:[EBP-FC] ; |
10003F1E |. 50 PUSH EAX ; |hThread
10003F1F |. E8 84F8FFFF CALL <JMP.&kernel32.SetThreadContext> ; \SetThreadContext
10003F24 |. 8B85 04FFFFFF MOV EAX,DWORD PTR SS:[EBP-FC]
10003F2A |. 50 PUSH EAX ; /hThread
10003F2B |. E8 70F8FFFF CALL <JMP.&kernel32.ResumeThread> ; \ResumeThread
10003F30 |. 33C0 XOR EAX,EAX ; 此处程序运行起来了 是转存的好时机
10003F32 |. 5A POP EDX
10003F33 |. 59 POP ECX
10003F34 |. 59 POP ECX
在10003F30处打开LordPe,选择基址为00400000的那个程序,先点“纠正映像大小”,然后转存之,结果
“无法抓取内存”。真是岂有此理。如果不点“纠正映像大小”,然后转存,虽然能成功,但是结果什么都不是。
我注意到纠正映像大小之前,映像大小是1A0000,纠正之后,变成了27000。《加密与解密 三》中提到,出现
“无法抓取内存”根本原因是对于内存段的保护问题。于是我ALt+M看OD的内存段,发现没有00400000~00427000段,
这下更改一途也不行。也请高手指点,如何随意更改某一内存段(读/写/执行)的属性?
既然这样不行,我们就区域脱壳吧,LordPe中在镜像中[右键]|[区域脱壳],查看00400000 大小是1A000,发现是XRW。
dump出来,改名为dump.exe,运行后,正好就是原始文件。而0041A000之后有段内存是NOACESS属性,怪不得dump不出来。
至此,脱壳完成,运行正常。
--------------------------------------------------------------------------------
【经验总结】
这个壳是我在学习压缩壳的过程中遇到的。开始比较茫然,在看雪和Upk等一些破解论坛上也找不到它的脱法,所以就在这
里写下来,文章比较菜,高手飘过。
此破解过程有相关动画,我明天上传到网盘上。
既然分析完了特征,现在可以总结一下秒脱手段:
断点bpx WriteProcessMemory,shift+F9两次 F8五次,看EAX,就是OEP
//OEP可能在修复中有用 如果不是壳上壳 可以不考虑上面一步 直接进行下面的步骤
//注意脱壳段 要包含OEP
然后bpx ResumeThread shift+F9 F8 用lordPE照文中方法dump即可
--------------------------------------------------------------------------------
【版权声明】: 本文原创于看雪技术论坛, 转载请注明作者并保持文章的完整, 谢谢!
2010年01月12日 1:32:41
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!