【脱文作者】 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
[培训]二进制漏洞攻防(第3期);满10人开班;模糊测试与工具使用二次开发;网络协议漏洞挖掘;Linux内核漏洞挖掘与利用;AOSP漏洞挖掘与利用;代码审计。