PC Guard for Win32 V5.0 DEMO 脱壳 —— PCGWIN32.EXE 主程序
下载页面: http://www.sofpro.com/downl.htm
软件大小: 692 KB
发布日期: by Blagoje Ceklic. 03.IX.2003.
【软件简介】:PC Guard for Win32 is a professional software protection and licensing system. With PC Guard for Win32 you can easily protect Windows 95/98/NT 32bit EXE/DLL applications from illegal distribution and reverse engineering . Even more, you don't need any source code editing or programming experience for this. Everything is fully automatic!
【作者声明】:初学Crack,只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
【调试环境】:WinXP、Ollydbg1.09、PEiD、LordPE、ImportREC
—————————————————————————————————
【脱壳过程】:
用Ollydbg手动脱壳,老规矩:载入后弹出“是压缩代码——要继续进行分析吗?”,点“否”。
设置Ollydbg忽略所有异常。下断:BP LoadLibraryA F9运行,断下!
00483000 FC cld
====>进入OD后断在这!
77E605D8 837C24 04 00 cmp dword ptr ss:[esp+4],0
====>断在这!继续F9运行,不断拦下!
77E605DD 53 push ebx
77E605DE 56 push esi
77E605DF 74 19 je short kernel32.77E605FA
77E605E1 68 9C5BE777 push kernel32.77E75B9C
77E605E6 FF7424 10 push dword ptr ss:[esp+10]
77E605EA FF15 9013E477 call dword ptr ds:[<&ntdll._strcmpi>]
77E605F0 85C0 test eax,eax
77E605F2 59 pop ecx
77E605F3 59 pop ecx
77E605F4 0F84 76AF0100 je kernel32.77E7B570
77E605FA 6A 00 push 0
77E605FC 6A 00 push 0
77E605FE FF7424 14 push dword ptr ss:[esp+14]
77E60602 E8 B1FFFFFF call kernel32.LoadLibraryExA
77E60607 5E pop esi
77E60608 5B pop ebx
77E60609 C2 0400 retn 4
确定弹出的“入口点预警”对话框,这时可以看见堆栈出现的这些DLL名。
0012FF28 0042D750 FileName = "COMCTL32.dll"
0012FF28 0042D774 FileName = "IMAGEHLP.dll"
0012FF28 0042DD74 FileName = "comdlg32.dll"
0012FF28 0042DE46 FileName = "VERSION.dll"
中断4次,出现VERSION.dll。再F9两次程序就运行啦,停!取消这个断点!
————————————————————————
再下断: BP GetProcAddress F9运行,断下! 取消这个断点!
77E5A5FD 55 push ebp
====>断在这!CTRL+F9执行到返回
77E5A5FE 8BEC mov ebp,esp
77E5A600 51 push ecx
77E5A601 51 push ecx
77E5A602 53 push ebx
77E5A603 57 push edi
77E5A604 8B7D 0C mov edi,dword ptr ss:[ebp+C]
77E5A607 BB FFFF0000 mov ebx,0FFFF
77E5A60C 3BFB cmp edi,ebx
77E5A60E 0F86 6B83FFFF jbe kernel32.77E5297F
77E5A614 57 push edi
77E5A615 8D45 F8 lea eax,dword ptr ss:[ebp-8]
77E5A618 50 push eax
77E5A619 FF15 8012E477 call dword ptr ds:[<&ntdll.RtlInitString>]
77E5A61F 8D45 0C lea eax,dword ptr ss:[ebp+C]
77E5A622 50 push eax
77E5A623 6A 00 push 0
77E5A625 8D45 F8 lea eax,dword ptr ss:[ebp-8]
77E5A628 50 push eax
77E5A629 6A 00 push 0
77E5A62B FF75 08 push dword ptr ss:[ebp+8]
77E5A62E E8 B4F2FFFF call kernel32.77E598E7
77E5A633 50 push eax
77E5A634 E8 BEFFFFFF call <jmp.&ntdll.LdrGetProcedureAddress>
77E5A639 85C0 test eax,eax
77E5A63B 0F8C 5725FFFF jl kernel32.77E4CB98
77E5A641 6A 00 push 0
77E5A643 FF75 08 push dword ptr ss:[ebp+8]
77E5A646 E8 9CF2FFFF call kernel32.77E598E7
77E5A64B 3945 0C cmp dword ptr ss:[ebp+C],eax
77E5A64E 0F84 A1870200 je kernel32.77E82DF5
77E5A654 8B45 0C mov eax,dword ptr ss:[ebp+C]
77E5A657 5F pop edi
77E5A658 5B pop ebx
77E5A659 C9 leave
77E5A65A C2 0800 retn 8
====>返回到 0047DCE6
0047DCE6 0BC0 or eax,eax
0047DCE8 74 12 je short 0047DCFC
0047DCEA 5D pop ebp
0047DCEB 5F pop edi
0047DCEC 5E pop esi
0047DCED 5A pop edx
0047DCEE 59 pop ecx
0047DCEF 5B pop ebx
0047DCF0 C3 retn
====>返回到 0047DBD1
————————————————————————
0047DBD1 EB 01 jmp short 0047DBD4
====>返回到这里!:-) 不用F7蜗牛般跟踪,向下找RET
0047DBD3 898B BD3AF041 mov dword ptr ds:[ebx+41F03ABD],ecx
0047DBD9 009CEB 01D59DEB add byte ptr ds:[ebx+ebp*8+EB9DD501],bl
0047DBE0 010B add dword ptr ds:[ebx],ecx
0047DBE2 03BD 40384200 add edi,dword ptr ss:[ebp+423840]
0047DBE8 EB 01 jmp short 0047DBEB
0047DBEA E3 60 jecxz short 0047DC4C
0047DBEC E8 03000000 call 0047DBF4
0047DBF1 D2EB shr bl,cl
0047DBF3 0B58 EB or ebx,dword ptr ds:[eax-15]
0047DBF6 0148 40 add dword ptr ds:[eax+40],ecx
0047DBF9 EB 01 jmp short 0047DBFC
0047DBFB 35 FFE0E761 xor eax,61E7E0FF
0047DC00 89048F mov dword ptr ds:[edi+ecx*4],eax
0047DC03 EB 01 jmp short 0047DC06
0047DC05 89F7 mov edi,esi
0047DC07 8570 38 test dword ptr ds:[eax+38],esi
0047DC0A 42 inc edx
0047DC0B 0000 add byte ptr ds:[eax],al
0047DC0D 0000 add byte ptr ds:[eax],al
0047DC0F 04 9C add al,9C
0047DC11 EB 01 jmp short 0047DC14
0047DC13 D5 9D aad 9D
0047DC15 EB 01 jmp short 0047DC18
0047DC17 0B740B EB or esi,dword ptr ds:[ebx+ecx-15]
0047DC1B 01E3 add ebx,esp
0047DC1D EB 01 jmp short 0047DC20
0047DC1F D4 E8 aam 0E8
0047DC21 14 00 adc al,0
0047DC23 0000 add byte ptr ds:[eax],al
0047DC25 41 inc ecx
0047DC26 E9 24FFFFFF jmp 0047DB4F
0047DC2B B8 FFFFFFFF mov eax,-1
0047DC30 C3 retn
====>此处下断!会节省不少时间。F9直接断在这!
BTW:常有朋友问“你们怎么知道这里跳那里不跳、此处该下断彼处又不用下断?”等等,偶只能很遗憾的回答:偶仅仅是菜鸟,偶也只知其然而不知其所以然。但偶知道的“此处下断!会节省不少时间”是偶试了N次,有的甚至是花了数天的时间才实践、总结出来的。由于水平低微,只能做到这一步了,请诸位见谅!
————————————————————————
0046F30C EB 01 jmp short 0046F30F
====>0047DC30返回到这里!
0046F30F 60 pushad
0046F310 E8 03000000 call 0046F318
0046F318 58 pop eax
0046F319 EB 01 jmp short 0046F31C
0046F31C 40 inc eax
0046F31D EB 01 jmp short 0046F320
0046F320 FFE0 jmp eax
0046F316 EB 0B jmp short 0046F323
0046F323 61 popad
0046F324 85C0 test eax,eax
0046F326 9C pushfd
0046F327 EB 01 jmp short 0046F32A
0046F32A 9D popfd
0046F32B EB 01 jmp short 0046F32E
0046F32E 0F84 B0000000 je 0046F3E4
====>看到这个je 0046F3E4 向下找0046F3E4在其上面的JMP处下断!
0046F3DF E9 6B240100 jmp 0048184F
====>在这下断!F9断下!呵呵,又偷了点巧 :-)
0046F3E4 B8 05000000 mov eax,5
====>在0046F3E4上面的JMP处下断!
0048184F 8B85 48384200 mov eax,dword ptr ss:[ebp+423848]
00481855 EB 01 jmp short 00481858
00481858 8DB5 C72E4200 lea esi,dword ptr ss:[ebp+422EC7]
0048185E EB 01 jmp short 00481861
00481861 EB 01 jmp short 00481864
00481864 B9 98020000 mov ecx,298
00481869 60 pushad
0048186A E8 03000000 call 00481872
00481872 EB 01 jmp short 00481875
00481875 58 pop eax
00481876 EB 01 jmp short 00481879
00481879 40 inc eax
0048187A EB 01 jmp short 0048187D
0048187D FFE0 jmp eax
00481870 EB 0E jmp short 00481880
00481880 61 popad
00481881 0006 add byte ptr ds:[esi],al
00481883 EB 01 jmp short 00481886
00481886 EB 01 jmp short 00481889
00481889 D1C8 ror eax,1
0048188B EB 01 jmp short 0048188E
0048188E 4E dec esi
0048188F EB 01 jmp short 00481892
00481892 EB 01 jmp short 00481895
00481895 E2 EA loopd short 00481881
====>F4下去跳出LOOP
00481897 9C pushfd
00481898 EB 01 jmp short 0048189B
0048189B 9D popfd
0048189C EB 01 jmp short 0048189F
0048189F F7857038420000000020 test dword ptr ss:[ebp+423870],20000000
004818A9 0F85 85000000 jnz 00481934
00481934 81ED 4DF1B84A sub ebp,4AB8F14D
0048193A 9C pushfd
0048193B EB 01 jmp short 0048193E
0048193E 9D popfd
0048193F EB 01 jmp short 00481942
00481942 60 pushad
00481943 EB 01 jmp short 00481946
00481946 E8 15000000 call 00481960
00481960 2BFF sub edi,edi
00481962 60 pushad
00481963 E8 03000000 call 0048196B
0048196B EB 01 jmp short 0048196E
0048196E 58 pop eax
0048196F EB 01 jmp short 00481972
00481972 40 inc eax
00481973 EB 01 jmp short 00481976
00481976 FFE0 jmp eax
00481969 EB 0E jmp short 00481979
00481979 61 popad
0048197A 64:FF37 push dword ptr fs:[edi]
0048197D 9C pushfd
0048197E EB 01 jmp short 00481981
00481981 9D popfd
00481982 EB 01 jmp short 00481985
00481985 64:8927 mov dword ptr fs:[edi],esp
00481988 EB 01 jmp short 0048198B
0048198B EB 01 jmp short 0048198E
0048198E F1 int1
====>异常!看看堆栈区的第二条地址是 0048194B
0048194B EB 01 jmp short 0048194E
====>堆栈区的第二条地址 设断 F9断在此处
0048194E EB 01 jmp short 00481951
00481951 8B6424 08 mov esp,dword ptr ss:[esp+8]
00481955 EB 01 jmp short 00481958
00481958 EB 45 jmp short 0048199F
0048199F EB 01 jmp short 004819A2
004819A2 EB 01 jmp short 004819A5
004819A5 85E4 test esp,esp
004819A7 9C pushfd
004819A8 EB 01 jmp short 004819AB
004819AB 9D popfd
004819AC EB 01 jmp short 004819AF
004819AF 79 0C jns short 004819BD
004819BD 33C0 xor eax,eax
004819BF EB 01 jmp short 004819C2
004819C2 EB 01 jmp short 004819C5
004819C5 64:8F00 pop dword ptr fs:[eax]
004819C8 60 pushad
004819C9 E8 03000000 call 004819D1
004819D1 EB 01 jmp short 004819D4
004819D4 58 pop eax
004819D5 EB 01 jmp short 004819D8
004819D8 40 inc eax
004819D9 EB 01 jmp short 004819DC
004819DC FFE0 jmp eax
004819CF EB 0E jmp short 004819DF
004819DF 61 popad
004819E0 58 pop eax
004819E1 EB 01 jmp short 004819E4
004819E4 60 pushad
004819E5 E8 03000000 call 004819ED
004819ED 58 pop eax
004819EE EB 01 jmp short 004819F1
004819F1 40 inc eax
004819F2 EB 01 jmp short 004819F5
004819F5 FFE0 jmp eax
004819EB EB 0B jmp short 004819F8
004819F8 61 popad
004819F9 61 popad
004819FA 9C pushfd
004819FB EB 01 jmp short 004819FE
004819FE 9D popfd
004819FF EB 01 jmp short 00481A02
00481A02 81C5 4DF1B84A add ebp,4AB8F14D
00481A08 60 pushad
00481A09 E8 03000000 call 00481A11
00481A11 EB 01 jmp short 00481A14
00481A14 58 pop eax
00481A15 EB 01 jmp short 00481A18
00481A18 40 inc eax
00481A19 EB 01 jmp short 00481A1C
00481A1C FFE0 jmp eax
00481A0F EB 0E jmp short 00481A1F
00481A1F 61 popad
00481A20 8B85 48384200 mov eax,dword ptr ss:[ebp+423848]
00481A26 60 pushad
00481A27 E8 03000000 call 00481A2F
00481A2F EB 01 jmp short 00481A32
00481A32 58 pop eax
00481A33 EB 01 jmp short 00481A36
00481A36 40 inc eax
00481A37 EB 01 jmp short 00481A3A
00481A3A FFE0 jmp eax
00481A2D EB 0E jmp short 00481A3D
00481A3D 61 popad
00481A3E 3385 C42E4200 xor eax,dword ptr ss:[ebp+422EC4]
====>EAX=F253D0A0 XOR F2518C81=00025C21 这是OEP的偏移值
00481A44 9C pushfd
00481A45 EB 01 jmp short 00481A48
00481A4C 0385 40384200 add eax,dword ptr ss:[ebp+423840] ; PCGWIN32.00400000
====>EAX=00025C21 + 00400000=00425C21 这就是OEP值 :-)
00481A52 EB 01 jmp short 00481A55
00481A55 60 pushad
00481A56 E8 03000000 call 00481A5E
00481A5E 58 pop eax
00481A5F EB 01 jmp short 00481A62
00481A62 40 inc eax
00481A63 EB 01 jmp short 00481A66
00481A66 FFE0 jmp eax
00481A5C EB 0B jmp short 00481A69
00481A69 61 popad
00481A6A 8BA5 4C394200 mov esp,dword ptr ss:[ebp+42394C]
00481A70 9C pushfd
00481A71 EB 01 jmp short 00481A74
00481A74 9D popfd
00481A75 EB 01 jmp short 00481A78
00481A78 50 push eax
00481A79 60 pushad
00481A7A E8 03000000 call 00481A82
00481A82 EB 01 jmp short 00481A85
00481A85 58 pop eax
00481A86 EB 01 jmp short 00481A89
00481A89 40 inc eax
00481A8A EB 01 jmp short 00481A8D
00481A8D FFE0 jmp eax
00481A80 EB 0E jmp short 00481A90
00481A90 61 popad
00481A91 8B85 30394200 mov eax,dword ptr ss:[ebp+423930]
00481A97 9C pushfd
00481A98 EB 01 jmp short 00481A9B
00481A9B 9D popfd
00481A9C EB 01 jmp short 00481A9F
00481A9F 8BB5 40394200 mov esi,dword ptr ss:[ebp+423940]
00481AA5 60 pushad
00481AA6 E8 03000000 call 00481AAE
00481AAE EB 01 jmp short 00481AB1
00481AB1 58 pop eax
00481AB2 EB 01 jmp short 00481AB5
00481AB5 40 inc eax
00481AB6 EB 01 jmp short 00481AB9
00481AB9 FFE0 jmp eax
00481AAC EB 0E jmp short 00481ABC
00481ABC 61 popad
00481ABD 8BBD 44394200 mov edi,dword ptr ss:[ebp+423944]
00481AC3 9C pushfd
00481AC4 EB 01 jmp short 00481AC7
00481AC7 9D popfd
00481AC8 EB 01 jmp short 00481ACB
00481ACB 8B9D 34394200 mov ebx,dword ptr ss:[ebp+423934]
00481AD1 60 pushad
00481AD2 E8 03000000 call 00481ADA
00481ADA EB 01 jmp short 00481ADD
00481ADD 58 pop eax
00481ADE EB 01 jmp short 00481AE1
00481AE1 40 inc eax
00481AE2 EB 01 jmp short 00481AE5
00481AE5 FFE0 jmp eax
00481AD8 EB 0E jmp short 00481AE8
00481AE8 61 popad
00481AE9 8B8D 38394200 mov ecx,dword ptr ss:[ebp+423938]
00481AEF EB 01 jmp short 00481AF2
00481AF2 60 pushad
00481AF3 E8 03000000 call 00481AFB
00481AFB 58 pop eax
00481AFC EB 01 jmp short 00481AFF
00481AFF 40 inc eax
00481B00 EB 01 jmp short 00481B03
00481B03 FFE0 jmp eax
00481AF9 EB 0B jmp short 00481B06
00481B06 61 popad
00481B07 8B95 3C394200 mov edx,dword ptr ss:[ebp+42393C]
00481B0D 9C pushfd
00481B0E EB 01 jmp short 00481B11
00481B11 9D popfd
00481B12 EB 01 jmp short 00481B15
00481B15 8BAD 48394200 mov ebp,dword ptr ss:[ebp+423948]
00481B1B 60 pushad
00481B1C E8 03000000 call 00481B24
00481B24 EB 01 jmp short 00481B27
00481B27 58 pop eax
00481B28 EB 01 jmp short 00481B2B
00481B2B 40 inc eax
00481B2C EB 01 jmp short 00481B2F
00481B2F FFE0 jmp eax
00481B22 EB 0E jmp short 00481B32
00481B32 61 popad
00481B33 C3 retn
====>飞向光明之巅! 返回至 00425C21
————————————————————————
00425C21 55 push ebp
====>在这儿用LordPE纠正ImageSize后完全DUMP这个进程
00425C22 8BEC mov ebp,esp
00425C24 6A FF push -1
00425C26 68 A8CF4200 push 42CFA8
00425C2B 68 289B4200 push 429B28
00425C30 64:A1 00000000 mov eax,dword ptr fs:[0]
00425C36 50 push eax
00425C37 64:8925 00000000 mov dword ptr fs:[0],esp
00425C3E 83EC 58 sub esp,58
00425C41 53 push ebx
00425C42 56 push esi
00425C43 57 push edi
00425C44 8965 E8 mov dword ptr ss:[ebp-18],esp
00425C47 FF15 08C14200 call dword ptr ds:[42C108] ; kernel32.GetVersion
———————————————————————
运行ImportREC,选择这个进程。把OEP改为00025C21,点IT AutoSearch,点“Get Import”,有2个函数无效。奇怪,不能用“追踪层次2、3”修复,否则PC Guard自动退出!如果CUT掉则修复的程序可以运行,但是退出时会非法操作。呵呵,试着将其改为:kernel32.dll ExitProcess FixDump,正常运行!VC++ 6.0 编写,576K->612K 重建PE后是564K
—————————————————————————————————
☆☆☆☆☆☆☆☆☆ ☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆
☆☆☆☆☆☆☆☆☆☆ 再简化一下上面的脱壳步骤,呵呵,能省就省吧!:-) ☆☆☆☆☆☆☆☆☆☆
☆☆☆☆☆☆☆☆☆ ☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆
设置Ollydbg忽略除了“单步中断”之外的所有异常。
00483000 FC cld
====>进入OD后断在这!F9运行,断下!
004836D8 EB 01 jmp short PCGWIN32.004836DB
====>第1个单步异常
SHIFT+F9 通过异常,不用记下次数,呵呵,直到程序弹出一系列的“入口点预警”就停下!
把那些对话框一一确定之。呵呵,看看偶现在停在什么地方? :-)
0048198F EB 01 jmp short 00481992
====>停在这个单步异常的地方
看看堆栈:
0012FF24 0012FFE0 指针到下一个 SEH 记录
0012FF28 0048194B SE 句柄 //呵呵,这是什么?
0048194B就是 0048198E int1 异常的堆栈区的第二条地址!!:-) 又快了点,接下来就可以找OEP了!
—————————————————————————————————
以上的脱壳过程是针对 PC Guard for Win32 V5.0 DEMO 版的PCGWIN32.EXE主程序,而不是那种没有KEY就无法运行的保护类型的加壳程序。偶也简单测试了一下,以上寻找OEP的过程同样适用于用这个版本加壳的其他同类程序!当然有些地方是不可能完全一样的,有兴趣的朋友可以自己测试。
这个帖子是偶在 看雪论坛 的第 1000 个帖子,谨以此篇简单的脱壳笔记留个简单的纪念。:-)
—————————————————————————————————
, _/
/| _.-~/ _ , 青春都一饷
( /~ / ~-._ |
`\ _/ ~ ) 忍把浮名
_-~~~-.) )__/;;,. _ //'
/'_, --~ ~~~- ,;;___( (.-~~~-. 换了破解轻狂
`~ _( ,_..-- ( ,;'' / ~-- /._`
/~~//' /' `~ ) /--.._, )_ `~
" `~" " `" /~'` `\~~
" " "~' ""
Cracked By 巢水工作坊——fly [OCN][FCG]
2003-10-26 00:00