【脱文作者】 simonzh2000[US]
【使用工具】 Peid0.92, Ollydbg1.10(反Antidbg版), ImportREC1.60, LordPE
【破解平台】 Win2000SP4 English
【软件名称】 EF Process Manager 2.41
【软件简介】 http://www.efsoftware.com
Windows 进程管理器, 比 Windows 自带的 TaskMgr 强多了. 可显示和关闭进程, 进程所用的 DLL.
对检测一些木马特别有用. 脱老王的壳时候帮了我的大忙.
【软件大小】 862K
【加壳方式】 ASProtect 1.23 加壳的 EXE 和 DLL
【作者声明】 本笔记只用于学习交流, 初学Crack,只是感兴趣技术,没有其他目的, 如有不妥之处, 请谅解
代码:
OD 设置不忽略异常 00E739EC 3100 XOR DWORD PTR DS:[EAX],EAX ; // 最后一个异常 00E739EE 64:8F05 0000000>POP DWORD PTR FS:[0] ; // 异常处理完毕, 这里继续 00E739F5 58 POP EAX ; // 下面 F7, F4 走, 两个地方 F8 00E739F6 833D B07EE700 0>CMP DWORD PTR DS:[E77EB0],0 00E739FD 74 14 JE SHORT 00E73A13 00E739FF 6A 0C PUSH 0C 00E73A01 B9 B07EE700 MOV ECX,0E77EB0 00E73A06 8D45 F8 LEA EAX,DWORD PTR SS:[EBP-8] 00E73A09 BA 04000000 MOV EDX,4 00E73A0E E8 2DD1FFFF CALL 00E70B40 ; // F8 00E73A13 FF75 FC PUSH DWORD PTR SS:[EBP-4] 00E73A16 FF75 F8 PUSH DWORD PTR SS:[EBP-8] 00E73A19 8B45 F4 MOV EAX,DWORD PTR SS:[EBP-C] 00E73A1C 8338 00 CMP DWORD PTR DS:[EAX],0 00E73A1F 74 02 JE SHORT 00E73A23 00E73A21 FF30 PUSH DWORD PTR DS:[EAX] 00E73A23 FF75 F0 PUSH DWORD PTR SS:[EBP-10] 00E73A26 FF75 EC PUSH DWORD PTR SS:[EBP-14] 00E73A29 C3 RETN ... 00E86FF2 81C2 82150000 ADD EDX,1582 00E86FF8 51 PUSH ECX 00E86FF9 66:8BCB MOV CX,BX 00E86FFC 5E POP ESI 00E86FFD 68 00000000 PUSH 0 00E87002 68 9E206D4E PUSH 4E6D209E 00E87007 0F8F 03000000 JG 00E87010 00E8700D 0FB7CB MOVZX ECX,BX 00E87010 59 POP ECX 00E87011 5B POP EBX 00E87012 66:BE 6FFE MOV SI,0FE6F 00E87016 8B041A MOV EAX,DWORD PTR DS:[EDX+EBX] 00E87019 66:BF 686F MOV DI,6F68 00E8701D 81E8 EA018818 SUB EAX,188801EA 00E87023 B9 BD62D90D MOV ECX,0DD962BD 00E87028 81F0 DB4C7A47 XOR EAX,477A4CDB 00E8702E E8 05000000 CALL 00E87038 00E87033 B9 FE5FAC75 MOV ECX,75AC5FFE 00E87038 B9 F11A7326 MOV ECX,26731AF1 00E8703D 5E POP ESI 00E8703E 81C0 78A3DF3E ADD EAX,3EDFA378 00E87044 0FBFF6 MOVSX ESI,SI 00E87047 50 PUSH EAX 00E87048 E8 11000000 CALL 00E8705E 00E8704D E5 BA IN EAX,0BA 00E8704F 6BC8 61 IMUL ECX,EAX,61 00E87052 8647 74 XCHG BYTE PTR DS:[EDI+74],AL 00E87055 9D POPFD 00E87056 12E3 ADC AH,BL 00E87058 ^ E0 99 LOOPDNE SHORT 00E86FF3 00E8705A 5E POP ESI 00E8705B 3F AAS 00E8705C 0C 55 OR AL,55 00E8705E 5E POP ESI 00E8705F 8F041A POP DWORD PTR DS:[EDX+EBX] 00E87062 83EB 04 SUB EBX,4 00E87065 66:8BF1 MOV SI,CX 00E87068 81FB 54EBFFFF CMP EBX,-14AC 00E8706E 0F85 18000000 JNZ 00E8708C 00E87074 66:8BCE MOV CX,SI 00E87077 E9 2D000000 JMP 00E870A9 ;// 循环出口, 注意这段代码位置不固定 00E8707C |58 POP EAX 00E8707D |B1 96 MOV CL,96 00E8707F |17 POP SS 00E87080 |04 ED ADD AL,0ED 00E87082 |22B3 70E96E0F AND DH,BYTE PTR DS:[EBX+F6EE970] 00E87088 |9C PUSHFD 00E87089 |A5 MOVS DWORD PTR ES:[EDI],DWORD PTR DS:[ES> 00E8708A |7A 2B JPE SHORT 00E870B7 00E8708C |81C1 34733571 ADD ECX,71357334 00E87092 ^|E9 7FFFFFFF JMP 00E87016 00E87097 |D2A3 A0591EFF SHL BYTE PTR DS:[EBX+FF1E59A0],CL 00E8709D |CC INT3 00E8709E |15 2A1BB891 ADC EAX,91B81B2A 00E870A3 |F6F7 DIV BH 00E870A5 |64:CD 82 INT 82 00E870A8 |93 XCHG EAX,EBX 00E870A9 \22FA AND BH,DL 00E870AB E7 F0 OUT 0F0,EAX 00E870AD 2089 327392EF AND BYTE PTR DS:[ECX+EF927332],CL 00E870B3 F9 STC 00E870B4 9C PUSHFD 00E870B5 ^ E3 E4 JECXZ SHORT 00E8709B 00E870B7 95 XCHG EAX,EBP 00E870B8 3249 52 XOR CL,BYTE PTR DS:[ECX+52] 00E870BB ^ E3 9E JECXZ SHORT 00E8705B 00E8713F 8901 MOV DWORD PTR DS:[ECX],EAX 00E87141 8D8D 94E14B00 LEA ECX,DWORD PTR SS:[EBP+4BE194] 00E87147 8D85 94F34B00 LEA EAX,DWORD PTR SS:[EBP+4BF394] 00E8714D 51 PUSH ECX 00E8714E 50 PUSH EAX 00E8714F E8 76FFFFFF CALL 00E870CA ; // F8 00E87154 61 POPAD 00E87155 EB 01 JMP SHORT 00E87158 00E864F7 57 PUSH EDI 00E864F8 9C PUSHFD 00E864F9 FC CLD 00E864FA BF 3765E800 MOV EDI,0E86537 00E864FF B9 5E140000 MOV ECX,145E 00E86504 F3:AA REP STOS BYTE PTR ES:[EDI] 00E86506 9D POPFD 00E86507 5F POP EDI 00E86508 59 POP ECX 00E86509 C3 RETN ; // return to 421AB4, Stolen code 后的 OEP // 这是 Stolen Code, 大部分最后一个异常后可找到, VC6 程序, 分析 Stack 也可搞定 00421A8E 55 PUSH EBP 00421A8F 8BEC MOV EBP,ESP 00421A91 6A FF PUSH -1 00421A93 68 F0A44200 PUSH EFPrcMan.0042A4F0 00421A98 68 E4434200 PUSH EFPrcMan.004243E4 00421A9D 64:A1 00000000 MOV EAX,DWORD PTR FS:[0] 00421AA3 50 PUSH EAX 00421AA4 64:8925 0000000>MOV DWORD PTR FS:[0],ESP 00421AAB 83C4 A8 ADD ESP,-58 00421AAE 53 PUSH EBX 00421AAF 56 PUSH ESI 00421AB0 57 PUSH EDI 00421AB1 8965 E8 MOV DWORD PTR SS:[EBP-18],ESP 55 8B EC 6A FF 68 F0 A4 42 00 68 E4 43 42 00 64 A1 00 00 00 00 50 64 89 25 00 00 00 00 83 C4 A8 53 56 57 89 65 E8 00421AB4 FF15 2CA24200 CALL DWORD PTR DS:[42A22C] ; // GetVersion 00421ABA 33D2 XOR EDX,EDX 00421ABC 8AD4 MOV DL,AH 00421ABE 8915 7C1C4300 MOV DWORD PTR DS:[431C7C],EDX 00421AC4 8BC8 MOV ECX,EAX 00421AC6 81E1 FF000000 AND ECX,0FF 00421ACC 890D 781C4300 MOV DWORD PTR DS:[431C78],ECX 00421AD2 C1E1 08 SHL ECX,8 00421AD5 03CA ADD ECX,EDX 00421AD7 890D 741C4300 MOV DWORD PTR DS:[431C74],ECX 00421ADD C1E8 10 SHR EAX,10 00421AE0 A3 701C4300 MOV DWORD PTR DS:[431C70],EAX 00421AE5 6A 01 PUSH 1 00421AE7 E8 CA3D0000 CALL EFPrcMan.004258B6 // 到 42A22C 看一下, 很容易知道 IAT 位于 42A000, 长度 424, ImportRec 后 // 见到 Comctl32 有 7 个被加密了, Kernel32 有 100 多个被加密了, user32 有 1 个被加密 // 重新来过 00E733A6 3100 XOR DWORD PTR DS:[EAX],EAX ; // 这个异常后处理 IAT ; // Why? 看着 42A000 区域按 Shift+F9 呗 00E733A8 EB 01 JMP SHORT 00E733AB ; // 异常处理完毕, 这里继续 // 到这里后去 42A09C 下 Memory On Write 断点, 这里是 Kerner32 的第一个函数, // F9, 断在 00E732C0 00E7351E AC LODS BYTE PTR DS:[ESI] 00E7351F 80F8 00 CMP AL,0 00E73522 ^ 74 DD JE SHORT 00E73501 00E73524 80F8 01 CMP AL,1 00E73527 75 06 JNZ SHORT 00E7352F 00E73529 8345 F8 04 ADD DWORD PTR SS:[EBP-8],4 00E7352D ^ EB EF JMP SHORT 00E7351E 00E7352F 53 PUSH EBX 00E73530 56 PUSH ESI 00E73531 53 PUSH EBX 00E73532 8D5D F8 LEA EBX,DWORD PTR SS:[EBP-8] 00E73535 53 PUSH EBX 00E73536 80F8 05 CMP AL,5 00E73539 74 06 JE SHORT 00E73541 00E7353B 0FB60E MOVZX ECX,BYTE PTR DS:[ESI] 00E7353E 41 INC ECX 00E7353F EB 05 JMP SHORT 00E73546 00E73541 B9 04000000 MOV ECX,4 00E73546 01CE ADD ESI,ECX 00E73548 E8 E7FCFFFF CALL 00E73234 ; // 这个 CALL 处理一个函数, 仅供参考, F7 到下面 00E7354D 5B POP EBX 00E7354E ^ EB CE JMP SHORT 00E7351E 00E732B4 E8 47FCFFFF CALL 00E72F00 ; // 这个 CALL 相当于 GetProcAddress 00E732B9 E8 7EFEFFFF CALL 00E7313C ; // 这个 CALL 加密上面的地址, 把他 NOP 掉 00E732BE 8B17 MOV EDX,DWORD PTR DS:[EDI] 00E732C0 8902 MOV DWORD PTR DS:[EDX],EAX ; // EAX 改成 SetEndOfFile 的地址, 取消断点, F9 到下一个异常 00E732C2 EB 7E JMP SHORT 00E73342 // 恢复刚才 NOP 掉的地方, 继续走到 OEP, 补上 Stolen code, DUMP, // IMPortRec 后发现大部分函数 OK, 还有 7 个没搞定, 手动跟踪修复一下, 很容易的 42A0D4 GetCurrentProcess 42A134 GetModuleHandleA 42A198 GetProcAddress 42A1B4 GetCurrentProcessId 42A22C GetVersion 42A230 GetCommandLineA 42A354 DialogBoxParamA FixDump 时取消 Add New Section, RVA = 32C00, Size = 12AC, Fixdump, 得到 EFPrc.EXE 安装文件夹里有 EFPrcMan.EXE 主程序 EFPrcMan 里面有安装日期, 试用30天, 这个文件破坏,叫你重装 EFPrc.INI 语言, 窗口设置 EFPMRES.DLL 也用 ASProtect 加壳 下面开始脱 EFPMRES.DLL, ImageBase = 1000 0000 除了重定位表, 所有过程与 EXE 相同, 得到 Dumped.DLL: 10001000 B8 01000000 MOV EAX,1 10001005 C2 0C00 RETN 0C 10001008 90 NOP 10001009 90 NOP 1000100A 90 NOP 1000100B 90 NOP 1000100C 90 NOP 1000100D 90 NOP 1000100E 90 NOP 1000100F 90 NOP 10001010 8BC1 MOV EAX,ECX 10001012 C700 C0A00010 MOV DWORD PTR DS:[EAX],E.1000A0C0 10001018 C740 04 B0B1001>MOV DWORD PTR DS:[EAX+4],E.1000B1B0 1000101F C740 08 20B7001>MOV DWORD PTR DS:[EAX+8],E.1000B720 10001026 C740 0C 80B3001>MOV DWORD PTR DS:[EAX+C],E.1000B380 1000102D C740 10 68BE001>MOV DWORD PTR DS:[EAX+10],E.1000BE68 10001034 C740 14 B8B9001>MOV DWORD PTR DS:[EAX+14],E.1000B9B8 1000103B C740 18 08BB001>MOV DWORD PTR DS:[EAX+18],E.1000BB08 10001042 C740 1C 30BF001>MOV DWORD PTR DS:[EAX+1C],E.1000BF30 10001049 C740 20 58BC001>MOV DWORD PTR DS:[EAX+20],E.1000BC58 10001050 C3 RETN 从上可见, 10001014 处的 1000A0C0 是重定位后的结果. 我们写一个程序 TwoDLL.EXE , 将 EFPMRES.DLL 加载到不同于 1000 0000 的地方, #include <windows.h> int APIENTRY WinMain( HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpszCmdLine, int nCmdShow  { LoadLibrary("E.DLL"); // 第一次加载到 1000 0000, 重定位不起作用 LoadLibrary("F.DLL"); // 第二次加载到其他地方, 重定位起作用 .... } 用 OD 载入 TWoDLL.EXE, 不忽略异常, F9, 00401000 /$ 83EC 44 SUB ESP,44 00401003 |. 56 PUSH ESI 00401004 |. 8B35 64504000 MOV ESI,DWORD PTR DS:[<&KERNEL32.LoadLib>; KERNEL32.LoadLibraryA 0040100A |. 68 50604000 PUSH base.00406050 ; /FileName = "E.DLL" 0040100F |. FFD6 CALL ESI ; \LoadLibraryA 00401011 |. 68 48604000 PUSH base.00406048 ; /FileName = "F.DLL" 00401016 |. FFD6 CALL ESI ; \LoadLibraryA shift + F9, 一直到看到 F.DLL 代码解压为止: 00DF1000 B8 01000000 MOV EAX,1 00DF1005 C2 0C00 RETN 0C 00DF1008 90 NOP 00DF1009 90 NOP 00DF100A 90 NOP 00DF100B 90 NOP 00DF100C 90 NOP 00DF100D 90 NOP 00DF100E 90 NOP 00DF100F 90 NOP 00DF1010 8BC1 MOV EAX,ECX 00DF1012 C700 C0A00010 MOV DWORD PTR DS:[EAX],1000A0C0 00DF1018 C740 04 B0B1001>MOV DWORD PTR DS:[EAX+4],1000B1B0 00DF101F C740 08 20B7001>MOV DWORD PTR DS:[EAX+8],1000B720 00DF1026 C740 0C 80B3001>MOV DWORD PTR DS:[EAX+C],1000B380 00DF102D C740 10 68BE001>MOV DWORD PTR DS:[EAX+10],1000BE68 00DF1034 C740 14 B8B9001>MOV DWORD PTR DS:[EAX+14],1000B9B8 00DF103B C740 18 08BB001>MOV DWORD PTR DS:[EAX+18],1000BB08 00DF1042 C740 1C 30BF001>MOV DWORD PTR DS:[EAX+1C],1000BF30 00DF1049 C740 20 58BC001>MOV DWORD PTR DS:[EAX+20],1000BC58 00DF1050 C3 RETN 很明显这里需要 重定位 处理 ImageBase = DF0000, 对 DF1014 下 Memory on Write 断点, 继续 Shift+F9, 断在 00E53723 00E536D3 2BCA SUB ECX,EDX 00E536D5 890C24 MOV DWORD PTR SS:[ESP],ECX 00E536D8 833C24 00 CMP DWORD PTR SS:[ESP],0 00E536DC 74 5F JE SHORT 00E5373D 00E536DE 8B5C24 04 MOV EBX,DWORD PTR SS:[ESP+4] 00E536E2 03D8 ADD EBX,EAX 00E536E4 EB 51 JMP SHORT 00E53737 00E536E6 8D43 04 LEA EAX,DWORD PTR DS:[EBX+4] ;================================================ 00E536E9 8B00 MOV EAX,DWORD PTR DS:[EAX] // 重定位表的 SizeOfBlock 00E536EB 83E8 08 SUB EAX,8 00E536EE D1E8 SHR EAX,1 00E536F0 8BFA MOV EDI,EDX 00E536F2 037C24 04 ADD EDI,DWORD PTR SS:[ESP+4] 00E536F6 83C3 08 ADD EBX,8 00E536F9 8BF0 MOV ESI,EAX 00E536FB 85F6 TEST ESI,ESI 00E536FD 76 38 JBE SHORT 00E53737 00E536FF 66:8B13 MOV DX,WORD PTR DS:[EBX] ;========================== 00E53702 0FB7C2 MOVZX EAX,DX 00E53705 C1E8 0C SHR EAX,0C 00E53708 66:83E8 01 SUB AX,1 00E5370C 72 23 JB SHORT 00E53731 00E5370E 66:83E8 02 SUB AX,2 00E53712 74 02 JE SHORT 00E53716 00E53714 EB 11 JMP SHORT 00E53727 00E53716 66:81E2 FF0F AND DX,0FFF 00E5371B 0FB7C2 MOVZX EAX,DX 00E5371E 03C7 ADD EAX,EDI 00E53720 8B1424 MOV EDX,DWORD PTR SS:[ESP] 00E53723 0110 ADD DWORD PTR DS:[EAX],EDX ; // 断在这里, 取消断点 00E53725 EB 0A JMP SHORT 00E53731 00E53727 68 6037E500 PUSH 0E53760 00E5372C E8 BBEEFFFF CALL 00E525EC 00E53731 83C3 02 ADD EBX,2 00E53734 4E DEC ESI 00E53735 ^ 75 C8 JNZ SHORT 00E536FF ; // 重定位表一段处理完毕===== 00E53737 8B13 MOV EDX,DWORD PTR DS:[EBX] ; // 重定位表的 VirtualAddress, 第一次 EBX = E01000 00E53739 85D2 TEST EDX,EDX 00E5373B ^ 75 A9 JNZ SHORT 00E536E6 ; // 全部重定位表处理完毕======================== 从上面这段程序, 可以知道重定位表位于 E01000, RVA = E01000-DF0000 = 11000, Size = 9E4, 用 LordPE 打开 Dumped.DLL, 发现重定位数据都在, 改一下 Directory 即可, OK, DLL 脱壳完毕. 脱壳后程序 EFPrc.EXE 我们 Copy EFPrcMan 到 EFPrc, Copy Dumped.DLL 到 EFPMRes.DLL 用 OD 载入 EFPrc.EXE, 对 CreateFileA , GetFilesize, ReadFile 下断, 可以看到有检测文件大小的, 检测文件校验和, 检测 Keyfile (EFPrc.LIC) 00409B79 |> /8D55 F8 /LEA EDX,DWORD PTR SS:[EBP-8] 00409B7C |. |52 |PUSH EDX ; /pFileSizeHigh 00409B7D |. |8B45 F0 |MOV EAX,DWORD PTR SS:[EBP-10] ; | 00409B80 |. |8B08 |MOV ECX,DWORD PTR DS:[EAX] ; | 00409B82 |. |51 |PUSH ECX ; |hFile = EFPrc.EXE 00409B83 |. |FF15 A8A04200 |CALL DWORD PTR DS:[<&kernel32.GetFileSi>; \GetFileSize // 要执行好几次, 原文件 2D200, 脱壳 57000 00409B89 |. |8945 F4 |MOV DWORD PTR SS:[EBP-C],EAX 00409B8C |. |837D F4 FF |CMP DWORD PTR SS:[EBP-C],-1 00409A09 |. 6A 00 PUSH 0 ; /pOverlapped = NULL 00409A0B |. 8D4D F8 LEA ECX,DWORD PTR SS:[EBP-8] ; | 00409A0E |. 51 PUSH ECX ; |pBytesRead 00409A0F |. 8B55 0C MOV EDX,DWORD PTR SS:[EBP+C] ; | 00409A12 |. 52 PUSH EDX ; |BytesToRead = 800h (2048) 00409A13 |. 8B45 08 MOV EAX,DWORD PTR SS:[EBP+8] ; | 00409A16 |. 50 PUSH EAX ; |Buffer = F4F658 00409A17 |. 8B4D F0 MOV ECX,DWORD PTR SS:[EBP-10] ; | 00409A1A |. 8B11 MOV EDX,DWORD PTR DS:[ECX] ; | 00409A1C |. 52 PUSH EDX ; |hFile = EFPrc.EXE 00409A1D |. FF15 74A14200 CALL DWORD PTR DS:[<&kernel32.ReadFile>] ; \ReadFile 00409985 |. 6A 00 PUSH 0 ; /hTemplateFile = NULL 00409987 |. 68 80000000 PUSH 80 ; |Attributes = NORMAL 0040998C |. 6A 03 PUSH 3 ; |Mode = OPEN_EXISTING 0040998E |. 6A 00 PUSH 0 ; |pSecurity = NULL 00409990 |. 6A 03 PUSH 3 ; |ShareMode = FILE_SHARE_READ|FILE_SHARE_WRITE 00409992 |. 68 00000080 PUSH 80000000 ; |Access = GENERIC_READ 00409997 |. 8B4D 08 MOV ECX,DWORD PTR SS:[EBP+8] ; | 0040999A |. 51 PUSH ECX ; |FileName = EFPrc.LIC 0040999B |. FF15 9CA14200 CALL DWORD PTR DS:[<&kernel32.CreateFile>; \CreateFileA 00409A09 |. 6A 00 PUSH 0 ; /pOverlapped = NULL 00409A0B |. 8D4D F8 LEA ECX,DWORD PTR SS:[EBP-8] ; | 00409A0E |. 51 PUSH ECX ; |pBytesRead 00409A0F |. 8B55 0C MOV EDX,DWORD PTR SS:[EBP+C] ; | 00409A12 |. 52 PUSH EDX ; |BytesToRead 00409A13 |. 8B45 08 MOV EAX,DWORD PTR SS:[EBP+8] ; | 00409A16 |. 50 PUSH EAX ; |Buffer = 00E42648 00409A17 |. 8B4D F0 MOV ECX,DWORD PTR SS:[EBP-10] ; | 00409A1A |. 8B11 MOV EDX,DWORD PTR DS:[ECX] ; | 00409A1C |. 52 PUSH EDX ; |hFile = EFPrc.LIC 00409A1D |. FF15 74A14200 CALL DWORD PTR DS:[<&kernel32.ReadFile>] ; \ReadFile 接下来 F7 走, 费了很大工夫, 终于分析出 EFPrc.LIC 的格式如下: Name : Simon Company : Group Serial No.: 654321-54321-87654321 Reg.ID. : ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFFDFJKLMNOPQRSTUVWXYZ98
注意每一行前有一空格, 最后有一空行.
用这个文件去对付未脱壳程序, 未注册字样消失了, 30天后也不过期了,
但有些功能不能用. BTW, 不要去对付脱壳后程序哦.
搞到这里实在是吃不消了, 放弃, 有人搞定了, 通知一声
注册码判断用了多线程, DLL, UserMessage, ...
因为在网上找到一个更好的免费软件:
Process Explorer 8.4
http://www.sysinternals.com/
FileMon, RegMon 听说过吗? hehe