找回密码
 注册
搜索
热搜: 回贴

Forgot的unpackme 1.7的简单脱壳,脱壳,脱壳技术

2010-1-30 18:22| 发布者: admin| 查看: 86| 评论: 0|原作者: 云天河


Forgot的unpackme 1.7的简单脱壳,脱壳,脱壳技术
2008年06月23日 星期一 下午 06:13
【软件名称】:forgot的unpackme 1.7

【下载地址】:见附件。

【脱壳声明】:初学Crack,只是感兴趣,没有其它目的。失误之处敬请诸位大侠赐教!

【操作系统】:winxp

【脱壳工具】:OD等传统工具



———————————————————————————————————————————

 

【脱壳过程】:



forgot的unpackme 1.7 和pack v0.1.6的变化不大,只是加了IAT简单加密。另外和1.6一样加了入口代码修改,但修改字节并不多。

如果看过我脱015版和016版的文章,那么可以省略相关的章节。





第一步,找d-process处:



用OD载入程序,忽略所有异常,bp WriteProcessMemory,F9运行程序,断下:



77E41A94 > 55 PUSH EBP////断下。

77E41A95 8BEC MOV EBP,ESP

77E41A97 51 PUSH ECX

77E41A98 51 PUSH ECX

77E41A99 8B45 0C MOV EAX,DWORD PTR SS:[EBP C]

77E41A9C 53 PUSH EBX



观察堆栈数据:



0032797C 0032B349 /CALL 到 WriteProcessMemory 来自 0032B344

00327980 00000034 |hProcess = 00000034

00327984 0032CA56 |Address = 32CA56////重要!记下备用。

00327988 0032C3C5 |Buffer = 0032C3C5

0032798C 0000029A |BytesToWrite = 29A (666.)////重要!记下备用。

00327990 00000000 \pBytesWritten = NULL







好,F9直接运行程序,等出现界面时,运行LordPE选中映像文件小的那个进程,然后部分DUMP,把从32CA56处开始大小为29A的数据DUMP下来,命名为32CA56.bin。



第二步,变双进程为单进程:



重新载入程序,bp CreateProcessA,运行程序,断下:



77E41BBC > 55 PUSH EBP////断在这儿。

77E41BBD 8BEC MOV EBP,ESP

77E41BBF 6A 00 PUSH 0

77E41BC1 FF75 2C PUSH DWORD PTR SS:[EBP 2C]

77E41BC4 FF75 28 PUSH DWORD PTR SS:[EBP 28]

77E41BC7 FF75 24 PUSH DWORD PTR SS:[EBP 24]



观察堆栈数据:



00327968 0032A22C /CALL 到 CreateProcessA 来自 0032A227

0032796C 00328F99 |ModuleFileName = "C:\Documents and Settings\csjwaman\桌面\1.7\1.7.exe"

00327970 0032A21D |CommandLine = "X"////调试标志。

00327974 00000000 |pProcessSecurity = NULL

00327978 00000000 |pThreadSecurity = NULL

0032797C 00000000 |InheritHandles = FALSE

00327980 00000003 |CreationFlags = DEBUG_PROCESS|DEBUG_ONLY_THIS_PROCESS

00327984 00000000 |pEnvironment = NULL

00327988 00000000 |CurrentDir = NULL

0032798C 00327CF4 |pStartupInfo = 00327CF4

00327990 00327CE4 \pProcessInfo = 00327CE4







重新载入程序,bp GetCommandLineA,运行程序,断下:



77E5E358 > A1 1476EB77 MOV EAX,DWORD PTR DS:[77EB7614]////断在这里。取消断点。

77E5E35D C3 RETN////返回。



返回到:



0032837C 68 9F6F56B6 PUSH B6566F9F

00328381 50 PUSH EAX

00328382 E8 5D000000 CALL 003283E4

00328387 EB FF JMP SHORT 00328388

00328389 71 78 JNO SHORT 00328403

0032838B C2 5000 RETN 50

0032838E ^ EB D3 JMP SHORT 00328363

00328390 5B POP EBX

00328391 F3: PREFIX REP: ; 多余的前缀







搜索二进制字符“803e58”,找到:



00328617 ^\71 EB JNO SHORT 00328604

00328619 ^ EB FA JMP SHORT 00328615

0032861B ^ EB 80 JMP SHORT 0032859D/////找到这里。这里有个花指令。

0032861D 3E:58 POP EAX

0032861F 0F84 8A410000 JE 0032C7AF

00328625 68 9F6F56B6 PUSH B6566F9F

0032862A 50 PUSH EAX

0032862B E8 5D000000 CALL 0032868D

00328630 EB FF JMP SHORT 00328631





NOP掉花指令后:



0032861B 90 NOP

0032861C 803E 58 CMP BYTE PTR DS:[ESI],58////58为调试标志。用于判断是否为子进程。

0032861F 0F84 8A410000 JE 0032C7AF////此处改为JMP!可以变为单进程。

00328625 68 9F6F56B6 PUSH B6566F9F

0032862A 50 PUSH EAX

0032862B E8 5D000000 CALL 0032868D





00A19217 90 NOP

00A19218 803E 58 CMP BYTE PTR DS:[ESI],58

00A1921B 0F84 CA3F0000 JE 00A1D1EB

00A19221 68 9F6F56B6 PUSH B6566F9F

00A19226 50 PUSH EAX

00A19227 E8 5D000000 CALL 00A19289





第三步,修补程序:



修改上面这个跳转后,用十六进制工具把32CA56.bin的数据复盖掉OD的DUMP区从0032CA56处开始的29A个字节数据。



第四步,查找入口:



做完上述工作后,在OD的CPU窗口,Ctrl G,输入0032CA56,点确定后来到:



0032CA4D ^\71 EB JNO SHORT 0032CA3A

0032CA4F ^ EB FA JMP SHORT 0032CA4B

0032CA51 ^ EB F0 JMP SHORT 0032CA43////NOP掉。

0032CA53 0FC7C8 CMPXCHG8B EAX////NOP掉。

0032CA56 FFC3 INC EBX/////来到这里。

0032CA58 FFC8 DEC EAX

0032CA5A F7D8 NEG EAX

0032CA5C F7C1 2DF16825 TEST ECX,2568F12D

0032CA62 8BD9 MOV EBX,ECX

0032CA64 01CB ADD EBX,ECX

0032CA66 85CB TEST EBX,ECX

0032CA68 8BDA MOV EBX,EDX

0032CA6A C1CB F3 ROR EBX,0F3 ; 移动常数超出 1..31 的范围

0032CA6D C7C3 BE948305 MOV EBX,58394BE

0032CA73 87D8 XCHG EAX,EBX

0032CA75 0FA5D3 SHLD EBX,EDX,CL

0032CA78 87C0 XCHG EAX,EAX



搜索二进制字符“6150C3”,找到:



0032FDFE ^\71 EB JNO SHORT 0032FDEB

0032FE00 ^ EB FA JMP SHORT 0032FDFC

0032FE02 EB 50 JMP SHORT 0032FE54

0032FE04 8D78 02 LEA EDI,DWORD PTR DS:[EAX 2]

0032FE07 EB 02 JMP SHORT 0032FE0B////在这里F2下断。

0032FE09 61 POPAD////找到这里。

0032FE0A 50 PUSH EAX

0032FE0B C3 RETN////返回入口!



在0032FE07处断下后,EAX=403A3F,这就是入口地址。



00403A3F FFD7 CALL NEAR EDI////返回到这里。入口代码被修改了。

00403A41 58 POP EAX

00403A42 90 NOP

00403A43 90 NOP

00403A44 E8 63910000 CALL 1_7.0040CBAC

00403A49 85C0 TEST EAX,EAX

00403A4B 74 26 JE SHORT 1_7.00403A73

00403A4D 68 00000200 PUSH 20000

00403A52 6A 40 PUSH 40

00403A54 E8 2F910000 CALL 1_7.0040CB88

00403A59 A3 C0E14000 MOV DWORD PTR DS:[40E1C0],EAX

00403A5E 68 BCE04000 PUSH 1_7.0040E0BC

00403A63 E8 10000000 CALL 1_7.00403A78



到入口后观察堆栈区:



00327D68 0040E034 1_7.0040E034////这就是被偷的代码。

00327D6C 0042F73C 返回到 1_7.0042F73C



补回代码后:



00403A3F 68 34E04000 PUSH 1_7.0040E034////这才象入口嘛:)

00403A44 E8 63910000 CALL 1_7.0040CBAC

00403A49 85C0 TEST EAX,EAX

00403A4B 74 26 JE SHORT 1_7.00403A73

00403A4D 68 00000200 PUSH 20000

00403A52 6A 40 PUSH 40

00403A54 E8 2F910000 CALL 1_7.0040CB88

00403A59 A3 C0E14000 MOV DWORD PTR DS:[40E1C0],EAX

00403A5E 68 BCE04000 PUSH 1_7.0040E0BC

00403A63 E8 10000000 CALL 1_7.00403A78

00403A68 FF35 C0E14000 PUSH DWORD PTR DS:[40E1C0]

00403A6E E8 1B910000 CALL 1_7.0040CB8E



第五步,查找IAT加密处



到入口后F7跟踪:



00403A3F 68 34E04000 PUSH 1_7.0040E034////F7

00403A44 E8 63910000 CALL 1_7.0040CBAC////F7进入!

00403A49 85C0 TEST EAX,EAX

00403A4B 74 26 JE SHORT 1_7.00403A73



进入后:



0040CB6A 68 F0A6E577 PUSH kernel32.CloseHandle

0040CB6F C3 RETN

0040CB70 68 76B4E577 PUSH kernel32.CreateFileA

0040CB75 C3 RETN

0040CB76 68 FD98E577 PUSH kernel32.ExitProcess

0040CB7B C3 RETN

0040CB7C 68 6416E677 PUSH kernel32.GetFileSize

0040CB81 C3 RETN

0040CB82 68 9BA2E577 PUSH kernel32.GetTickCount

0040CB87 C3 RETN

0040CB88 68 9E56E577 PUSH kernel32.GlobalAlloc

0040CB8D C3 RETN

0040CB8E 68 D957E577 PUSH kernel32.GlobalFree

0040CB93 C3 RETN

0040CB94 68 4EABE577 PUSH kernel32.ReadFile ; ASCII "j h"

0040CB99 C3 RETN

0040CB9A 68 2EF0E577 PUSH kernel32.SetFilePointer

0040CB9F C3 RETN

0040CBA0 68 3AF1E577 PUSH kernel32.WriteFile

0040CBA5 C3 RETN

0040CBA6 68 0AB0D377 PUSH user32.MessageBoxA

0040CBAB C3 RETN

0040CBAC 68 90233276 PUSH comdlg32.GetOpenFileNameA////到这里。

0040CBB1 C3 RETN



跳转表都被改成 PUSH XXXXXXXX 然后 RETN 的形式了!看开始处是40CB6A。



好,重新载入程序,按上述方法到第四步后,在40CB6A处下内存访问断点,然后F9运行程序,断下几次后会来到:



0032F976 03BD 66CB4000 ADD EDI,DWORD PTR SS:[EBP 40CB66]

0032F97C 81C7 00100000 ADD EDI,1000

0032F982 66:8139 FF25 CMP WORD PTR DS:[ECX],25FF////会断在这里。这里开始处理IAT跳转表。

0032F987 74 02 JE SHORT 0032F98B////修改为JMP 32F9C8

0032F989 EB 05 JMP SHORT 0032F990

0032F98B 3941 02 CMP DWORD PTR DS:[ECX 2],EAX

0032F98E 72 07 JB SHORT 0032F997

0032F990 41 INC ECX

0032F991 3BCF CMP ECX,EDI

0032F993 ^ 72 ED JB SHORT 0032F982

0032F995 EB 27 JMP SHORT 0032F9BE

0032F997 8B59 02 MOV EBX,DWORD PTR DS:[ECX 2]

0032F99A 8B1B MOV EBX,DWORD PTR DS:[EBX]

0032F99C C601 68 MOV BYTE PTR DS:[ECX],68////IAT跳转改为PUSH xxxxxxxx,然后再RETN的形式。

0032F99F 8959 01 MOV DWORD PTR DS:[ECX 1],EBX

0032F9A2 C641 05 C3 MOV BYTE PTR DS:[ECX 5],0C3////RETN

0032F9A6 83C1 06 ADD ECX,6

0032F9A9 66:8139 FF25 CMP WORD PTR DS:[ECX],25FF

0032F9AE 75 04 JNZ SHORT 0032F9B4

0032F9B0 3BCF CMP ECX,EDI

0032F9B2 ^ 72 CE JB SHORT 0032F982

0032F9B4 83C1 02 ADD ECX,2

0032F9B7 66:8139 FF25 CMP WORD PTR DS:[ECX],25FF

0032F9BC ^ 74 D9 JE SHORT 0032F997

0032F9BE 83C1 24 ADD ECX,24

0032F9C1 66:8139 FF25 CMP WORD PTR DS:[ECX],25FF

0032F9C6 ^ 74 CF JE SHORT 0032F997

0032F9C8 61 POPAD



把0032F987处直接修改为JMP 32F9C8 就可以得到完整的IAT跳转表了。



到入口后就可以用PETOOLS来DUMP了(因为用LORDPE不行!),再用ImportREC v142 修复IAT, OK完工!


最新评论

QQ|小黑屋|最新主题|手机版|微赢网络技术论坛 ( 苏ICP备08020429号 )

GMT+8, 2024-9-29 21:20 , Processed in 0.185521 second(s), 12 queries , Gzip On, MemCache On.

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

返回顶部