【练手软件下载地址】:http://count.skycn.com/softdownload.phpid=3265&url=http://jscz.driversky.com/down/fotobatch_setup.exe
【破 解 人】:BestChao
【调试环境】:WinXP、OllyICE、LordPE、ImportREC
【作者声明】:初学Crack,只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
一、准备工作
老规矩设置Ollydbg忽略所有异常,用IsDebug 1.4插件去掉Ollydbg的调试器标志。
1 侦壳:我用FI 4.01a 查一下 显示为 Armadillo 4.00 {glue}
2 判断进程:启动程序。然后在 Windows 任务管理器或LordPE里查看是单进程的Armadillo还是双进程的。
呵呵 是双进程的,这里介绍一个工具
ArmadilloFindProtected12 可以查看 RAM的保护方式
二 、脱壳
1 OD载入
00747C43 > 55 PUSH EBP //停在这里
00747C44 8BEC MOV EBP,ESP
00747C46 6A FF PUSH -1
00747C48 68 900F7700 PUSH fotobatc.00770F90
00747C4D 68 80797400 PUSH fotobatc.00747980
00747C52 64:A1 00000000 MOV EAX,DWORD PTR FS:[0]
00747C58 50 PUSH EAX
00747C59 64:8925 0000000>MOV DWORD PTR FS:[0],ESP
00747C60 83EC 58 SUB ESP,58
00747C63 53 PUSH EBX
00747C64 56 PUSH ESI
00747C65 57 PUSH EDI
下断点
BP WaitForDebugEvent
中断后取消断点,看堆栈:
0012DC8C 00737D86 /CALL 到 WaitForDebugEvent 来自 fotobatc.00737D80 // 反汇编窗口跟随
0012DC90 0012ED7C |pDebugEvent = 0012ED7C //注意这里
0012DC94 000003E8 \Timeout = 1000. ms
0012DC98 7C930738 ntdll.7C930738
在数据窗口定位到0012ED7C处,准备看OEP值
接着下断:BP WriteProcessMemory
搜索命令:or eax,0FFFFFFF8
0073830A 83BD CCF5FFFF 0>CMP DWORD PTR SS:[EBP-A34],0
\\下断,Shift+F9中断下来 把[ebp-A34]=[0012CD7C]=000001B7清0 ★
0060FE4A 0F8C A8020000 jl 006100F8
00738311 0F8C A8020000 JL fotobatc.007385BF
00738317 8B8D CCF5FFFF MOV ECX,DWORD PTR SS:[EBP-A34] //补丁1地址
0073831D 3B0D 88247700 CMP ECX,DWORD PTR DS:[772488]
// 补丁2地址
00738323 0F8D 96020000 JGE fotobatc.007385BF
//解码结束后跳转00738323 在00738323 处下断
00738329 8B95 40F6FFFF MOV EDX,DWORD PTR SS:[EBP-9C0]
0073832F 81E2 FF000000 AND EDX,0FF
00738335 85D2 TEST EDX,EDX
00738337 0F84 AD000000 JE fotobatc.007383EA
0073833D 6A 00 PUSH 0
0073833F 8BB5 CCF5FFFF MOV ESI,DWORD PTR SS:[EBP-A34]
00738345 C1E6 04 SHL ESI,4
00738348 8B85 CCF5FFFF MOV EAX,DWORD PTR SS:[EBP-A34]
0073834E 25 07000080 AND EAX,80000007
00738353 79 05 JNS SHORT fotobatc.0073835A
00738355 48 DEC EAX
00738356 83C8 F8 OR EAX,FFFFFFF8 //搜索找到这里 ^-^
00738359 40 INC EAX
0073835A 33C9 XOR ECX,ECX
0073835C 8A88 08FE7600 MOV CL,BYTE PTR DS:[EAX+76FE08]
00738362 8B95 CCF5FFFF MOV EDX,DWORD PTR SS:[EBP-A34]
00738368 81E2 07000080 AND EDX,80000007
0073836E 79 05 JNS SHORT fotobatc.00738375
00738370 4A DEC EDX
00738371 83CA F8 OR EDX,FFFFFFF8
00738374 42 INC EDX
00738375 33C0 XOR EAX,EAX
00738377 8A82 09FE7600 MOV AL,BYTE PTR DS:[EDX+76FE09]
0073837D 8B3C8D 98B37600 MOV EDI,DWORD PTR DS:[ECX*4+76B398]
00738384 333C85 98B37600 XOR EDI,DWORD PTR DS:[EAX*4+76B398]
0073838B 8B8D CCF5FFFF MOV ECX,DWORD PTR SS:[EBP-A34]
00738391 81E1 07000080 AND ECX,80000007
00738397 79 05 JNS SHORT fotobatc.0073839E
00738399 49 DEC ECX
0073839A 83C9 F8 OR ECX,FFFFFFF8
0073839D 41 INC ECX
0073839E 33D2 XOR EDX,EDX
007383A0 8A91 0AFE7600 MOV DL,BYTE PTR DS:[ECX+76FE0A]
007383A6 333C95 98B37600 XOR EDI,DWORD PTR DS:[EDX*4+76B398]
007383AD 8B85 CCF5FFFF MOV EAX,DWORD PTR SS:[EBP-A34]
007383B3 99 CDQ
007383B4 B9 1C000000 MOV ECX,1C
007383B9 F7F9 IDIV ECX
007383BB 8BCA MOV ECX,EDX
007383BD D3EF SHR EDI,CL
007383BF 83E7 0F AND EDI,0F
007383C2 03F7 ADD ESI,EDI
007383C4 8B15 6C247700 MOV EDX,DWORD PTR DS:[77246C]
007383CA 8D04B2 LEA EAX,DWORD PTR DS:[EDX+ESI*4]
007383CD 50 PUSH EAX
007383CE 8B8D CCF5FFFF MOV ECX,DWORD PTR SS:[EBP-A34]
007383D4 51 PUSH ECX
007383D5 E8 68210000 CALL fotobatc.0073A542
007383DA 83C4 0C ADD ESP,0C
007383DD 25 FF000000 AND EAX,0FF //在这里打补丁
007383E2 85C0 TEST EAX,EAX
007383E4 0F84 D5010000 JE fotobatc.007385BF
007383EA 837D D8 00 CMP DWORD PTR SS:[EBP-28],0
007383EE 75 27 JNZ SHORT fotobatc.00738417
找到第一处在0073830A处,在其上cmp dword ptr ss:[ebp-A34],0处设置断点
Patch代码:
inc dword ptr ss:[ebp-0A34] //补丁1地址
mov dword ptr ds:[772488+4],1 //补丁2地址
jmp 0073830A //跳转清0的地址
看OEP
2AA02C
取消WriteProcessMemory处断点,继续Shift+F9,中断在007385bf 处
此时子进程代码已经解开,运行LordPE,完全Dump出子进程
如何判断父和子?选择附加 红色的 就是父 当然另外一个 就是子咯 :)
二、搞定输入表
再次载入主程序FotoBatch.EXE
下断:BP DebugActiveProcess 中断后看堆栈:
0012DC90 00737BDA /CALL 到 DebugActiveProcess 来自 fotobatc.00737BD4
0012DC94 00000808 \ProcessId = 808 EDC
0012DC98 7C930738 ntdll.7C930738
新开一个OllyDbg,附加进程ID DEC的子进程
F9,再F12,会暂停在EP处
00747C43 >- EB FE JMP SHORT fotobatc.<ModuleEntryPoint>
//子进程在EP处死循环 恢复原来EP处的代码:55 8B
切换单进程。BP OpenMutexA Shift+F9,中断后看堆栈:
0012F798 007337B8 /CALL 到 OpenMutexA 来自 fotobatc.007337B2
0012F79C 001F0001 |Access = 1F0001
0012F7A0 00000000 |Inheritable = FALSE
0012F7A4 0012FDD8 \MutexName = "808::DACEE4B483" //注意 0012FDD8
0012F7A8 7C935F0B 返回到 ntdll.7C935F0B 来自 ntdll.bsearch
Ctrl+G:401000 键入以下分离代码
00401000 60 PUSHAD
00401001 9C PUSHFD
00401002 68 D8FD1200 PUSH 12FDD8 ; ASCII "808::DACEE4B483"
00401007 33C0 XOR EAX,EAX
00401009 50 PUSH EAX
0040100A 50 PUSH EAX
0040100B E8 2FDB407C CALL kernel32.CreateMutexA
00401010 9D POPFD
00401011 61 POPAD
00401012 - E9 04DC407C JMP kernel32.OpenMutexA
60 9C 68 D8 FD 12 00 33 C0 50 50 E8 2F DB 40 7C 9D 61 E9 04 DC 40 7C
在401000处新建EIP,F9运行,再次中断在OpenMutexA处。
返回401000处,“撤销选择”,清掉写入的代码。再取消OpenMutexA断点。
下断:HE GetModuleHandleA Shift+F9,注意看堆栈:
0012EF24 77F45BD8 /CALL 到 GetModuleHandleA 来自 77F45BD2
0012EF28 77F4501C \pModule = "KERNEL32.DLL"
0012EF2C 00000001
0012F73C 007328F3 /CALL 到 GetModuleHandleA 来自 fotobatc.007328ED
0012F740 00000000 \pModule = NULL
0012F744 0012F750
00129528 01087105 /CALL 到 GetModuleHandleA 来自 010870FF
0012952C 0109BC1C \pModule = "kernel32.dll"
00129530 0109CEC4 ASCII "VirtualAlloc"
00129528 01087122 /CALL 到 GetModuleHandleA 来自 0108711C
0012952C 0109BC1C \pModule = "kernel32.dll"
00129530 0109CEB8 ASCII "VirtualFree"
0012928C 01075FC9 /CALL 到 GetModuleHandleA 来自 01075FC3
00129290 001293DC \pModule = "kernel32.dll" //ALT+F9返回
堆栈如上变化时,取消GetModuleHandleA处断点,Alt+F9返回
01075FC9 8B0D AC400A01 MOV ECX,DWORD PTR DS:[10A40AC] //返回到这里
01075FCF 89040E MOV DWORD PTR DS:[ESI+ECX],EAX
01075FD2 A1 AC400A01 MOV EAX,DWORD PTR DS:[10A40AC]
01075FD7 391C06 CMP DWORD PTR DS:[ESI+EAX],EBX
01075FDA 75 16 JNZ SHORT 01075FF2
01075FDC 8D85 B4FEFFFF LEA EAX,DWORD PTR SS:[EBP-14C]
01075FE2 50 PUSH EAX
01075FE3 FF15 BC620901 CALL DWORD PTR DS:[10962BC] ; kernel32.LoadLibraryA
01075FE9 8B0D AC400A01 MOV ECX,DWORD PTR DS:[10A40AC]
01075FEF 89040E MOV DWORD PTR DS:[ESI+ECX],EAX
01075FF2 A1 AC400A01 MOV EAX,DWORD PTR DS:[10A40AC]
01075FF7 391C06 CMP DWORD PTR DS:[ESI+EAX],EBX
01075FFA 0F84 2F010000 JE 0107612F //改JE 为JMP 避开IAT加密 ^-^
01076000 33C9 XOR ECX,ECX
01076002 8B07 MOV EAX,DWORD PTR DS:[EDI]
01076004 3918 CMP DWORD PTR DS:[EAX],EBX
01076006 74 06 JE SHORT 0107600E
01076008 41 INC ECX
01076009 83C0 0C ADD EAX,0C
0107600C ^ EB F6 JMP SHORT 01076004
0107600E 8BD9 MOV EBX,ECX
01076010 C1E3 02 SHL EBX,2
01076013 53 PUSH EBX
01076014 E8 45F20100 CALL 0109525E ; JMP to msvcrt.??2@YAPAXI@Z
01076019 8B0D A4400A01 MOV ECX,DWORD PTR DS:[10A40A4]
0107601F 89040E MOV DWORD PTR DS:[ESI+ECX],EAX
01076022 53 PUSH EBX
01076023 E8 36F20100 CALL 0109525E ; JMP to msvcrt.??2@YAPAXI@Z
这个东东在处理输入表的时候还有时间校验,不处理的话会导致某些函数被加密
下断:BP GetTickCount 中断后取消断点返回
0108C318 8985 A4D4FFFF MOV DWORD PTR SS:[EBP-2B5C],EAX ; fotobatc.008218DE
// 返回到这里 一片红色海洋。。
0108C31E 6A 01 PUSH 1
0108C320 58 POP EAX
0108C321 85C0 TEST EAX,EAX
0108C323 0F84 A8030000 JE 0108C6D1
0108C329 8B85 84D9FFFF MOV EAX,DWORD PTR SS:[EBP-267C]
0108C32F 66:8B00 MOV AX,WORD PTR DS:[EAX]
0108C332 66:8985 64C2FFF>MOV WORD PTR SS:[EBP-3D9C],AX
0108C339 8B85 84D9FFFF MOV EAX,DWORD PTR SS:[EBP-267C]
0108C33F 40 INC EAX
0108C340 40 INC EAX
0108C341 8985 84D9FFFF MOV DWORD PTR SS:[EBP-267C],EAX
0108C347 0FB785 64C2FFFF MOVZX EAX,WORD PTR SS:[EBP-3D9C]
0108C34E 50 PUSH EAX
0108C34F FFB5 84D9FFFF PUSH DWORD PTR SS:[EBP-267C]
0108C355 8D85 70CAFFFF LEA EAX,DWORD PTR SS:[EBP-3590]
0108C35B 50 PUSH EAX
0108C35C E8 F78E0000 CALL 01095258 ; JMP to msvcrt.memcpy
下面还有一处GetTickCount取时间
0108C6AD /73 1D JNB SHORT 0108C6CC
0108C6AF |8B85 10D9FFFF MOV EAX,DWORD PTR SS:[EBP-26F0]
0108C6B5 |8B8D 68CAFFFF MOV ECX,DWORD PTR SS:[EBP-3598]
0108C6BB |8908 MOV DWORD PTR DS:[EAX],ECX
0108C6BD |8B85 10D9FFFF MOV EAX,DWORD PTR SS:[EBP-26F0]
0108C6C3 |83C0 04 ADD EAX,4
0108C6C6 |8985 10D9FFFF MOV DWORD PTR SS:[EBP-26F0],EAX
0108C6CC ^\E9 4DFCFFFF JMP 0108C31E
0108C6D1 FF15 7C620901 CALL DWORD PTR DS:[109627C] ; kernel32.GetTickCount
// 找到这个注释 kernel32.GetTickCount
0108C6D7 2B85 A4D4FFFF SUB EAX,DWORD PTR SS:[EBP-2B5C]
0108C6DD 8B8D A8D4FFFF MOV ECX,DWORD PTR SS:[EBP-2B58]
0108C6E3 6BC9 32 IMUL ECX,ECX,32
0108C6E6 81C1 D0070000 ADD ECX,7D0
0108C6EC 3BC1 CMP EAX,ECX //时间效验
0108C6EE 76 07 JBE SHORT 0108C6F7 //改JBE为 JMP
0108C6F0 C685 34D9FFFF 0>MOV BYTE PTR SS:[EBP-26CC],1
0108C6F7 83BD E4D7FFFF 0>CMP DWORD PTR SS:[EBP-281C],0
0108C6FE 0F85 8A000000 JNZ 0108C78E //在这里跟随 然后在下面一行中断后输入表处理完毕
0108C704 0FB685 94D4FFFF MOVZX EAX,BYTE PTR SS:[EBP-2B6C]
0108C70B 85C0 TEST EAX,EAX
0108C70D 74 7F JE SHORT 0108C78E
OEP 2AA02C
RAV 2E7280
大小 940
今天的重点 就是熟悉COMPY2的3个补丁位置和手动定位RAV和大小
谢谢各位高人看完小人这篇破文^-^
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)