【脱文作者】 simonzh2000
【使用工具】 Ollydbg1.10, LordPE
【破解平台】 Win2000 Pro SP4 English
【软件名称】 用 Thinstall2.517 加壳的 Mole.exe
【作者声明】 本笔记只用于学习交流, 初学Crack,只是感兴趣技术,没有其他目的, 如有不妥之处, 希望作者谅解.
学了 DardBull 兄弟的脱文, 我也脱了一下, 补充点东西.
用 OD 载入 Mole.exe, 用IsDebug V1.4插件去掉 OD 的调试器标志, 不忽略异常,
F9, 竟然运行了, 一个异常也没有, 和一般的壳有点不一样, 哈.
再用 TaskMgr 看看, 有二个进程, 看来是个调试壳. 这就好办了.
1.父进程 CreatePrcess 创建子进程, 再为子进程做个被调试标志
2.子进程在父进程调试下开始运行, 由于标志, 走不同的路线
3.父进程 用 WaitForDebugEvent 接受子进程产生的调试事件, 采取响应的措施
4.父进程处理好后, 调用 ContinueDebugEvent 继续子进程的运行, 重复3, 直到结束
重新来过, BP CreateProcessA, F9 , 断在下面
7FF760FA FF15 7470F87F CALL DWORD PTR DS:[7FF87074] ; KERNEL32.CreateProcessA
上下看看
7FF7600A 55 PUSH EBP
7FF7600B 8BEC MOV EBP,ESP
7FF7600D 81EC E0000000 SUB ESP,0E0
7FF76013 833D E86FF97F 0>CMP DWORD PTR DS:[7FF96FE8],0 // IsDebuggerPresent 地址有吗?
7FF7601A 75 1C JNZ SHORT 7FF76038
7FF7601C 68 F87BF87F PUSH 7FF87BF8 ; ASCII "IsDebuggerPresent"
7FF76021 68 EC7BF87F PUSH 7FF87BEC ; ASCII "kernel32"
7FF76026 FF15 D872F87F CALL DWORD PTR DS:[7FF872D8] ; KERNEL32.GetModuleHandleA
7FF7602C 50 PUSH EAX
7FF7602D FF15 C872F87F CALL DWORD PTR DS:[7FF872C8] ; KERNEL32.GetProcAddress
7FF76033 A3 E86FF97F MOV DWORD PTR DS:[7FF96FE8],EAX
7FF76038 C705 F06FF97F 9>MOV DWORD PTR DS:[7FF96FF0],94
7FF76042 68 F06FF97F PUSH 7FF96FF0 // LPOSVERSIONINFO
7FF76047 FF15 9C70F87F CALL DWORD PTR DS:[7FF8709C] ; KERNEL32.GetVersionExA
7FF7604D A1 AC69F97F MOV EAX,DWORD PTR DS:[7FF969AC]
7FF76052 25 00000002 AND EAX,2000000
7FF76057 85C0 TEST EAX,EAX
7FF76059 0F84 B3010000 JE 7FF76212
7FF7605F FF15 9870F87F CALL DWORD PTR DS:[7FF87098] ; KERNEL32.GetCurrentProcessId
7FF76065 50 PUSH EAX
7FF76066 68 FCCEF87F PUSH 7FF8CEFC ; ASCII "%d.df"
7FF7606B 8D85 38FFFFFF LEA EAX,DWORD PTR SS:[EBP-C8]
7FF76071 50 PUSH EAX
7FF76072 E8 5A0B0000 CALL 7FF76BD1 // sprintf(buffer, "%d.df", pid)
7FF76077 83C4 0C ADD ESP,0C
7FF7607A 8985 30FFFFFF MOV DWORD PTR SS:[EBP-D0],EAX
7FF76080 8B85 30FFFFFF MOV EAX,DWORD PTR SS:[EBP-D0]
7FF76086 8B00 MOV EAX,DWORD PTR DS:[EAX] // buffer1
7FF76088 8985 2CFFFFFF MOV DWORD PTR SS:[EBP-D4],EAX
7FF7608E FFB5 2CFFFFFF PUSH DWORD PTR SS:[EBP-D4]
7FF76094 6A 00 PUSH 0
7FF76096 6A 04 PUSH 4
7FF76098 FF15 9470F87F CALL DWORD PTR DS:[7FF87094] ; KERNEL32.OpenFileMappingA
7FF7609E 8945 FC MOV DWORD PTR SS:[EBP-4],EAX ; hFileMap
7FF760A1 8D8D 38FFFFFF LEA ECX,DWORD PTR SS:[EBP-C8]
7FF760A7 E8 690E0000 CALL 7FF76F15 // RtlFreeHeap(buffer1)
7FF760AC 837D FC 00 CMP DWORD PTR SS:[EBP-4],0 // OpenFileMapping 是否成功?
7FF760B0 0F85 5C010000 JNZ 7FF76212 // 成功了, 是子进程, 跳
7FF760B6 C785 58FFFFFF 4>MOV DWORD PTR SS:[EBP-A8],44 // 不成功, 是父进程
7FF760C0 8D85 58FFFFFF LEA EAX,DWORD PTR SS:[EBP-A8] // LPSTARTUPINFO
7FF760C6 50 PUSH EAX
7FF760C7 FF15 7870F87F CALL DWORD PTR DS:[7FF87078] ; KERNEL32.GetStartupInfoA
7FF760CD E8 0017FFFF CALL 7FF677D2 // 最终调用 GetCommandLine
7FF760D2 8985 40FFFFFF MOV DWORD PTR SS:[EBP-C0],EAX
7FF760D8 8D85 44FFFFFF LEA EAX,DWORD PTR SS:[EBP-BC] // LPPROCESS_INFORMATION
7FF760DE 50 PUSH EAX
7FF760DF 8D85 58FFFFFF LEA EAX,DWORD PTR SS:[EBP-A8] // LPSTARTUPINFO
7FF760E5 50 PUSH EAX
7FF760E6 6A 00 PUSH 0 // lpCurrentDirectory
7FF760E8 6A 00 PUSH 0 // lpEnvironment
7FF760EA 6A 02 PUSH 2 // CreationFlags = DEBUG_ONLY_THIS_PROCESS
7FF760EC 6A 00 PUSH 0 // bInheritHandles
7FF760EE 6A 00 PUSH 0 // lpThreadAttributes
7FF760F0 6A 00 PUSH 0 // lpProcessAttributes
7FF760F2 FFB5 40FFFFFF PUSH DWORD PTR SS:[EBP-C0] // lpCommandLine
7FF760F8 6A 00 PUSH 0 // lpApplicationName
7FF760FA FF15 7470F87F CALL DWORD PTR DS:[7FF87074] ; KERNEL32.CreateProcessA
7FF76100 85C0 TEST EAX,EAX
7FF76102 75 08 JNZ SHORT 7FF7610C
7FF76104 6A 00 PUSH 0
7FF76106 FF15 D472F87F CALL DWORD PTR DS:[7FF872D4] ; KERNEL32.ExitProcess
7FF7610C 833D E86FF97F 0>CMP DWORD PTR DS:[7FF96FE8],0
7FF76113 74 0F JE SHORT 7FF76124
7FF76115 FF15 E86FF97F CALL DWORD PTR DS:[7FF96FE8] ; KERNEL32.IsDebuggerPresent
7FF7611B 85C0 TEST EAX,EAX
7FF7611D 74 05 JE SHORT 7FF76124
7FF7611F E8 458CFEFF CALL 7FF5ED69 // 有 Debuger, 进入死循环
7FF76124 FFB5 4CFFFFFF PUSH DWORD PTR SS:[EBP-B4] // LPPROCESS_INFORMATION 中 子进程 pid
7FF7612A 68 FCCEF87F PUSH 7FF8CEFC ; ASCII "%d.df"
7FF7612F 8D85 34FFFFFF LEA EAX,DWORD PTR SS:[EBP-CC]
7FF76135 50 PUSH EAX // buffer2
7FF76136 E8 960A0000 CALL 7FF76BD1 // sprintf()
7FF7613B 83C4 0C ADD ESP,0C
7FF7613E 8985 28FFFFFF MOV DWORD PTR SS:[EBP-D8],EAX // 为子进程建立调试标志
7FF76144 8B85 28FFFFFF MOV EAX,DWORD PTR SS:[EBP-D8]
7FF7614A 8B00 MOV EAX,DWORD PTR DS:[EAX]
7FF7614C 8985 24FFFFFF MOV DWORD PTR SS:[EBP-DC],EAX
7FF76152 FFB5 24FFFFFF PUSH DWORD PTR SS:[EBP-DC]
7FF76158 6A 04 PUSH 4
7FF7615A 6A 00 PUSH 0
7FF7615C 68 04000008 PUSH 8000004
7FF76161 6A 00 PUSH 0
7FF76163 6A FF PUSH -1
7FF76165 FF15 8C70F87F CALL DWORD PTR DS:[7FF8708C] ; KERNEL32.CreateFileMappingA
7FF7616B 8985 54FFFFFF MOV DWORD PTR SS:[EBP-AC],EAX // hFileMap
7FF76171 8D8D 34FFFFFF LEA ECX,DWORD PTR SS:[EBP-CC]
7FF76177 E8 990D0000 CALL 7FF76F15 // RtlFreeHeap(buffer2)
7FF7617C 6A 01 PUSH 1
7FF7617E 58 POP EAX
7FF7617F 85C0 TEST EAX,EAX
7FF76181 0F84 8B000000 JE 7FF76212 // While( True ) { ... }
7FF76187 833D E86FF97F 0>CMP DWORD PTR DS:[7FF96FE8],0
7FF7618E 74 0F JE SHORT 7FF7619F
7FF76190 FF15 E86FF97F CALL DWORD PTR DS:[7FF96FE8] ; KERNEL32.IsDebuggerPresent
7FF76196 85C0 TEST EAX,EAX
7FF76198 74 05 JE SHORT 7FF7619F
7FF7619A E8 CA8BFEFF CALL 7FF5ED69 // 有 Debuger, 进入死循环
7FF7619F 6A FF PUSH -1 // Timeout = INFINITE
7FF761A1 8D45 9C LEA EAX,DWORD PTR SS:[EBP-64] // pDebugEvent
7FF761A4 50 PUSH EAX
7FF761A5 FF15 6072F87F CALL DWORD PTR DS:[7FF87260] ; KERNEL32.WaitForDebugEvent
7FF761AB 85C0 TEST EAX,EAX
7FF761AD 75 08 JNZ SHORT 7FF761B7
7FF761AF 6A 00 PUSH 0
7FF761B1 FF15 D472F87F CALL DWORD PTR DS:[7FF872D4] ; KERNEL32.ExitProcess
7FF761B7 C785 3CFFFFFF 0>MOV DWORD PTR SS:[EBP-C4],10002 // DBG_Continue
7FF761C1 8B45 9C MOV EAX,DWORD PTR SS:[EBP-64]
7FF761C4 8985 20FFFFFF MOV DWORD PTR SS:[EBP-E0],EAX // dwDebugEventCode
7FF761CA 83BD 20FFFFFF 0>CMP DWORD PTR SS:[EBP-E0],1 // EXCEPTION_DEBUG_EVENT
7FF761D1 74 0B JE SHORT 7FF761DE
7FF761D3 83BD 20FFFFFF 0>CMP DWORD PTR SS:[EBP-E0],5 // EXIT_PROCESS_DEBUG_EVENT
7FF761DA 74 17 JE SHORT 7FF761F3
7FF761DC EB 1D JMP SHORT 7FF761FB
7FF761DE 817D A8 0300008>CMP DWORD PTR SS:[EBP-58],80000003 // 调试时因代码中int3中断
7FF761E5 74 0A JE SHORT 7FF761F1
7FF761E7 C785 3CFFFFFF 0>MOV DWORD PTR SS:[EBP-C4],80010001 // DBG_EXCEPTION_NOT_HANDLED, 除了 int3, 子进程自己处理异常
7FF761F1 EB 08 JMP SHORT 7FF761FB
7FF761F3 6A 00 PUSH 0
7FF761F5 FF15 D472F87F CALL DWORD PTR DS:[7FF872D4] ; KERNEL32.ExitProcess
7FF761FB FFB5 3CFFFFFF PUSH DWORD PTR SS:[EBP-C4] // ContinueStatus
7FF76201 FF75 A4 PUSH DWORD PTR SS:[EBP-5C] // ThreadID
7FF76204 FF75 A0 PUSH DWORD PTR SS:[EBP-60] // pid
7FF76207 FF15 5C72F87F CALL DWORD PTR DS:[7FF8725C] ; KERNEL32.ContinueDebugEvent
7FF7620D ^ E9 6AFFFFFF JMP 7FF7617C // End of While
从上面可以看到, 7FF760B0 是分支点, 父进程只为子进程处理 Int3, 直接用 OD 做父进程, 去掉 IsDebug V1.4插件.
重新来过, Bp CreateFileMapping, F9, 断下
7FF76098 FF15 9470F87F CALL DWORD PTR DS:[7FF87094] ; KERNEL32.OpenFileMappingA
7FF7609E 8945 FC MOV DWORD PTR SS:[EBP-4],EAX
7FF760A1 8D8D 38FFFFFF LEA ECX,DWORD PTR SS:[EBP-C8]
7FF760A7 E8 690E0000 CALL 7FF76F15 // RtlFreeHeap(buffer1)
7FF760AC 837D FC 00 CMP DWORD PTR SS:[EBP-4],0
7FF760B0 0F85 5C010000 JNZ 7FF76212 // 强行跳
7FF76212 A1 AC69F97F MOV EAX,DWORD PTR DS:[7FF969AC]
7FF76217 25 08000004 AND EAX,4000008
7FF7621C 85C0 TEST EAX,EAX
7FF7621E 74 15 JE SHORT 7FF76235 // 强行跳过下面的监视线程
7FF76220 6A 00 PUSH 0
7FF76222 6A 00 PUSH 0
7FF76224 6A 00 PUSH 0
7FF76226 68 125DF77F PUSH 7FF75D12 ; ThreadFunction, 这个 Thread 是起检测作用的, 见最后
7FF7622B 6A 00 PUSH 0
7FF7622D 6A 00 PUSH 0
7FF7622F FF15 1872F87F CALL DWORD PTR DS:[7FF87218] ; KERNEL32.CreateThread
7FF76235 C9 LEAVE
7FF76236 C3 RETN // ret to 7FF42A35
7FF42A35 FFB5 DCFEFFFF PUSH DWORD PTR SS:[EBP-124] // 一路 F8 走
7FF42A3B 8B45 08 MOV EAX,DWORD PTR SS:[EBP+8]
7FF42A3E FF70 08 PUSH DWORD PTR DS:[EAX+8]
7FF42A41 E8 41550200 CALL 7FF67F87
...
7FF42B2F 50 PUSH EAX
7FF42B30 FFB5 DCFEFFFF PUSH DWORD PTR SS:[EBP-124]
7FF42B36 E8 FFE00100 CALL 7FF60C3A // 这里解密出完整的 IAT , 把 405000-40517F 数据考出来
7FF42B3B 83C4 0C ADD ESP,0C
...
14 55 00 00 00 00 00 00 DE 54 00 00 EE 54 00 00 FA 54 00 00 CC 54 00 00 BE 54 00 00 A8 54 00 00
00 00 00 00 E8 55 00 00 F8 55 00 00 06 56 00 00 16 56 00 00 2A 56 00 00 66 54 00 00 72 54 00 00
32 56 00 00 BC 53 00 00 CA 53 00 00 D6 53 00 00 E4 53 00 00 F2 53 00 00 00 54 00 00 14 54 00 00
22 54 00 00 30 54 00 00 3E 54 00 00 4E 54 00 00 5A 54 00 00 00 00 00 00 8C 54 00 00 00 00 00 00
8C 53 00 00 9E 53 00 00 7A 53 00 00 6C 53 00 00 5C 53 00 00 4A 53 00 00 3E 53 00 00 30 53 00 00
1E 53 00 00 0E 53 00 00 02 53 00 00 84 52 00 00 96 52 00 00 A8 52 00 00 B4 52 00 00 C6 52 00 00
D4 52 00 00 E4 52 00 00 F4 52 00 00 00 00 00 00 CE 55 00 00 B4 55 00 00 A2 55 00 00 92 55 00 00
7A 55 00 00 6A 55 00 00 46 55 00 00 36 55 00 00 5C 55 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0C 52 00 00 00 00 00 00 00 00 00 00 B0 53 00 00 80 50 00 00 B0 51 00 00 00 00 00 00 00 00 00 00
7E 54 00 00 24 50 00 00 04 52 00 00 00 00 00 00 00 00 00 00 9C 54 00 00 78 50 00 00 94 51 00 00
00 00 00 00 00 00 00 00 0A 55 00 00 08 50 00 00 8C 51 00 00 00 00 00 00 00 00 00 00 28 55 00 00
00 50 00 00 5C 52 00 00 00 00 00 00 00 00 00 00 DE 55 00 00 D0 50 00 00 00 00 00 00 00 00 00 00
7FF42B83 8D4401 18 LEA EAX,DWORD PTR DS:[ECX+EAX+18]
7FF42B87 8985 D0FDFFFF MOV DWORD PTR SS:[EBP-230],EAX
7FF42B8D C705 C86DF97F 0>MOV DWORD PTR DS:[7FF96DC8],2
7FF42B97 E8 77C80100 CALL 7FF5F413 // 这里处理 IAT
7FF42B9C 6A 00 PUSH 0
7FF42B9E 6A 01 PUSH 1
7FF42BA0 E8 D2EB0100 CALL 7FF61777
7FF42BA5 59 POP ECX
7FF42BA6 59 POP ECX
7FF42BA7 C705 C86DF97F 0>MOV DWORD PTR DS:[7FF96DC8],3
7FF42BB1 E8 9EEF0100 CALL 7FF61B54 // 这里处理 IAT
...
7FF42C48 /74 12 JE SHORT 7FF42C5C
7FF42C4A |FFB5 48FCFFFF PUSH DWORD PTR SS:[EBP-3B8]
7FF42C50 |68 6076F87F PUSH 7FF87660 ; ASCII "APISPY: Calling EXE Entry Point %x
"
7FF42C55 |E8 F6180000 CALL 7FF44550
7FF42C5A |59 POP ECX
7FF42C5B |59 POP ECX
7FF42C5C \FF95 48FCFFFF CALL DWORD PTR SS:[EBP-3B8] ; Mole.004010E3, OEP
把 405000-40517F 数据拷回去, OD, Dump, LordPE 修改 IAT RVA=5100, Size=8C, OK
// 检测线程, 500ms 执行一次,
// 进入的话, 里面有一个 INT3 异常, 注意不能用 shift+f9 过, OD 不能忽略, 必须 f9 过
// 还有一个内存访问异常, 要用 shift+f9 过 或者 OD 忽略
// 还用 CreateFile 检测 SoftICE
7FF75D12 55 PUSH EBP
7FF75D13 8BEC MOV EBP,ESP
7FF75D15 83EC 0C SUB ESP,0C
7FF75D18 833D E86FF97F 0>CMP DWORD PTR DS:[7FF96FE8],0 // IsDebuggerPresent 地址有吗?
7FF75D1F 75 1C JNZ SHORT 7FF75D3D
7FF75D21 68 F87BF87F PUSH 7FF87BF8 ; ASCII "IsDebuggerPresent"
7FF75D26 68 EC7BF87F PUSH 7FF87BEC ; ASCII "kernel32"
7FF75D2B FF15 D872F87F CALL DWORD PTR DS:[7FF872D8] ; KERNEL32.GetModuleHandleA
7FF75D31 50 PUSH EAX
7FF75D32 FF15 C872F87F CALL DWORD PTR DS:[7FF872C8] ; KERNEL32.GetProcAddress
7FF75D38 A3 E86FF97F MOV DWORD PTR DS:[7FF96FE8],EAX
7FF75D3D 6A 00 PUSH 0 // semaphore-object name
7FF75D3F 6A 01 PUSH 1 // maximum count
7FF75D41 6A 00 PUSH 0 // initial count
7FF75D43 6A 00 PUSH 0 // pointer to security attributes
7FF75D45 FF15 0472F87F CALL DWORD PTR DS:[7FF87204] ; KERNEL32.CreateSemaphoreA
7FF75D4B 8945 FC MOV DWORD PTR SS:[EBP-4],EAX // handle to Semaphore
7FF75D4E 6A 01 PUSH 1
7FF75D50 58 POP EAX
7FF75D51 85C0 TEST EAX,EAX
7FF75D53 0F84 94000000 JE 7FF75DED // While(True) { ... }
7FF75D59 A1 AC69F97F MOV EAX,DWORD PTR DS:[7FF969AC]
7FF75D5E 25 00000004 AND EAX,4000000
7FF75D63 85C0 TEST EAX,EAX
7FF75D65 74 18 JE SHORT 7FF75D7F
7FF75D67 833D E86FF97F 0>CMP DWORD PTR DS:[7FF96FE8],0 // 这一段应该永远不执行
7FF75D6E 74 0F JE SHORT 7FF75D7F
7FF75D70 FF15 E86FF97F CALL DWORD PTR DS:[7FF96FE8] ; KERNEL32.IsDebuggerPresent
7FF75D76 85C0 TEST EAX,EAX
7FF75D78 74 05 JE SHORT 7FF75D7F
7FF75D7A E8 EA8FFEFF CALL 7FF5ED69
7FF75D7F A1 AC69F97F MOV EAX,DWORD PTR DS:[7FF969AC]
7FF75D84 83E0 08 AND EAX,8
7FF75D87 85C0 TEST EAX,EAX
7FF75D89 74 4F JE SHORT 7FF75DDA
7FF75D8B 8365 F8 00 AND DWORD PTR SS:[EBP-8],0
7FF75D8F A1 8470F97F MOV EAX,DWORD PTR DS:[7FF97084]
7FF75D94 33D2 XOR EDX,EDX
7FF75D96 6A 02 PUSH 2
7FF75D98 59 POP ECX
7FF75D99 F7F1 DIV ECX
7FF75D9B 8955 F4 MOV DWORD PTR SS:[EBP-C],EDX
7FF75D9E 837D F4 00 CMP DWORD PTR SS:[EBP-C],0
7FF75DA2 74 08 JE SHORT 7FF75DAC
7FF75DA4 837D F4 01 CMP DWORD PTR SS:[EBP-C],1
7FF75DA8 74 0F JE SHORT 7FF75DB9
7FF75DAA EB 18 JMP SHORT 7FF75DC4
7FF75DAC E8 40000000 CALL 7FF75DF1 ; 这里有 2 个异常
7FF75DB1 0FB6C0 MOVZX EAX,AL ; 必须按上面的方法处理
7FF75DB4 8945 F8 MOV DWORD PTR SS:[EBP-8],EAX
7FF75DB7 EB 0B JMP SHORT 7FF75DC4
7FF75DB9 E8 B5000000 CALL 7FF75E73 ; 检测 SoftICE (CreateFile)
7FF75DBE 0FB6C0 MOVZX EAX,AL
7FF75DC1 8945 F8 MOV DWORD PTR SS:[EBP-8],EAX
7FF75DC4 837D F8 00 CMP DWORD PTR SS:[EBP-8],0
7FF75DC8 74 05 JE SHORT 7FF75DCF
7FF75DCA E8 9A8FFEFF CALL 7FF5ED69 // 有问题, 死循环
7FF75DCF A1 8470F97F MOV EAX,DWORD PTR DS:[7FF97084]
7FF75DD4 40 INC EAX
7FF75DD5 A3 8470F97F MOV DWORD PTR DS:[7FF97084],EAX
7FF75DDA 68 F4010000 PUSH 1F4 ; dwMilliseconds=500ms
7FF75DDF FF75 FC PUSH DWORD PTR SS:[EBP-4] ; handle to Semaphore
7FF75DE2 FF15 B870F87F CALL DWORD PTR DS:[7FF870B8] ; KERNEL32.WaitForSingleObject
7FF75DE8 ^ E9 61FFFFFF JMP 7FF75D4E ; End of While
7FF75DED C9 LEAVE
7FF75DEE C2 0400 RETN 4
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)