【脱文作者】 simonzh2000[US][FCG][IPB]
【使用工具】 Ollydbg1.10, ImportREC
【破解平台】 Win2000SP4 English
【软件名称】 xIkUg's PE Protector 0.31 加壳的 unpackme.
【加壳方式】 xIkUg's PE Protector 0.31, 花指令, 异常多的很啊.
【作者声明】 本笔记只用于学习交流, 初学Crack,只是感兴趣技术,没有其他目的, 如有不妥之处, 请 xIkUg 兄弟谅解.
期待兄弟新的更强的壳.
压缩包内有全文, 脱壳产品. 这个壳是一个类似 ARM 的调试壳, 运行后有两个进程, 这类壳的大致流程如下:
1.父进程 CreatePrcess 创建子进程, 再为子进程做个被调试标志
2.子进程在父进程调试下开始运行, 由于标志, 走不同的路线
3.父进程 用 WaitForDebugEvent 接受子进程产生的调试事件, 采取响应的措施(比如 ARM 的 CC)
4.父进程处理好后, 调用 ContinueDebugEvent 继续子进程的运行, 重复3, 直到结束
要脱这类壳, 关键是用 OD 做父进程, 也就是把双进程转换成单进程,
搞清楚以下两点, ARM, EPE2004 你都可以搞定, 哈
1. 被调试标志是如何生成的.
常见的有 Mutex, FileMapping, 标志文件, 命令行参数 等
2. 父进程接受子进程产生的调试事件后, 是如何处理的.
常见的有 SetThreadContext, WriteProcessMemory, VirtualProtect 等 Let's go!!!
OD 载入后, 忽略所有异常, F9 运行, 停在下面, 77F9FFE4 8B0424 MOV EAX,DWORD PTR SS:[ESP] ; Exception C0000008 (INVALID HANDLE)
77F9FFE7 8BE5 MOV ESP,EBP
77F9FFE9 5D POP EBP
77F9FFEA C3 RETN Shift+F9, OD 提示 Debugged program was unable to process exception, 有麻烦了.
ALT+L 打开 Log 窗口, 看到变态多的异常, 我们比较关心后面几个
0042F0A8 Integer division by zero
0042F0D0 Access violation when reading [00000000]
0042F0FF Integer division by zero
0042F127 Access violation when reading [00000000] 去42F0FF看看,
0042F0EE 64:FF35 0000000>PUSH DWORD PTR FS:[0]
0042F0F5 64:8925 0000000>MOV DWORD PTR FS:[0],ESP
0042F0FC 33C9 XOR ECX,ECX
0042F0FE 99 CDQ
0042F0FF F7F1 DIV ECX OD CTRL+F2 重新来过, 命令行输入 HE 42F0FE (下硬件执行断点 ), F9 运行.
中断在 0042F0FE, 取消断点, 取消忽略异常, F9 继续运行 // 除零异常
0042F0D8 8B5C24 0C MOV EBX,DWORD PTR SS:[ESP+C]
0042F0DC 8BA3 C4000000 MOV ESP,DWORD PTR DS:[EBX+C4]
0042F0E2 64:8F05 0000000>POP DWORD PTR FS:[0]
0042F0E9 83C4 04 ADD ESP,4
0042F0EC EB 14 JMP SHORT Keygen.0042F102
0042F0FE 99 CDQ
0042F0FF F7F1 DIV ECX ; 除零异常, Shift+F9 // 内存访问异常
0042F102 33F6 XOR ESI,ESI
0042F104 E8 10000000 CALL Keygen.0042F119
0042F109 8B6424 08 MOV ESP,DWORD PTR SS:[ESP+8] ; shift+f9 到这里, F2 取消断点, F7 继续
0042F10D 64:8F05 0000000>POP DWORD PTR FS:[0]
0042F114 58 POP EAX
0042F115 EB 13 JMP SHORT Keygen.0042F12A
0042F119 64:FF35 0000000>PUSH DWORD PTR FS:[0]
0042F120 64:8925 0000000>MOV DWORD PTR FS:[0],ESP
0042F127 AD LODS DWORD PTR DS:[ESI] ; 内存访问异常, SEH=0042F109, 下断 // SMC 42F269-435AE4 的代码
0042F12A E8 00000000 CALL Keygen.0042F12F
0042F12F 5D POP EBP
0042F130 81ED 2F514000 SUB EBP,Keygen.0040512F ; EBP=2A000
0042F136 89AD D6BE4000 MOV DWORD PTR SS:[EBP+40BED6],EBP ; [435ED6]
0042F152 8D85 69524000 LEA EAX,DWORD PTR SS:[EBP+405269] ; 42F269
0042F158 8D8D E4BA4000 LEA ECX,DWORD PTR SS:[EBP+40BAE4] ; 435AE4
0042F15E 8D95 61984000 LEA EDX,DWORD PTR SS:[EBP+409861] ; 433861
0042F164 /EB 0B JMP SHORT Keygen.0042F171
0042F166 |8030 58 XOR BYTE PTR DS:[EAX],58
0042F169 |3BC2 CMP EAX,EDX
0042F16B |72 03 JB SHORT Keygen.0042F170
0042F16D |8030 52 XOR BYTE PTR DS:[EAX],52
0042F170 |40 INC EAX
0042F171 \3BC1 CMP EAX,ECX
0042F173 ^ 72 F1 JB SHORT Keygen.0042F166
// 下面可以下普通断点了
// GetModuleHandle(kerner32.dll)
0042F269 8B4424 18 MOV EAX,DWORD PTR SS:[ESP+18] ; Kernel32 的一个地址
0042F26D 25 0000FFFF AND EAX,FFFF0000
0042F272 33D2 XOR EDX,EDX
0042F274 48 DEC EAX
0042F275 66:8B50 3C MOV DX,WORD PTR DS:[EAX+3C] ; PE 头
0042F279 66:F7C2 00F0 TEST DX,0F000 ; < 1000h
0042F27E ^ 75 F4 JNZ SHORT Keygen.0042F274
0042F280 3B4402 34 CMP EAX,DWORD PTR DS:[EDX+EAX+34] ; kernel32 总是位于指定的 ImageBase
0042F284 ^ 75 EE JNZ SHORT Keygen.0042F274
0042F286 8985 AFBE4000 MOV DWORD PTR SS:[EBP+40BEAF],EAX ; [435EAF]=7C570000 // 找到壳所用的 API
0042F2A2 8D85 8FBB4000 LEA EAX,DWORD PTR SS:[EBP+40BB8F] ; 435B8F, 见 Note 1
0042F2A8 50 PUSH EAX
0042F2D5 FFB5 AFBE4000 PUSH DWORD PTR SS:[EBP+40BEAF] ; KERNEL32.7C570000
0042F2F5 E8 06BDFFFF CALL Keygen.0042B000 ; MyGetProcAddress(hModule, pAPIName)
0042F2FA 8985 A0BB4000 MOV DWORD PTR SS:[EBP+40BBA0],EAX ; 结果保存在 API 名字字符串后面
...
0042F4CA 8D85 E7BB4000 LEA EAX,DWORD PTR SS:[EBP+40BBE7]
0042F4D0 50 PUSH EAX ; Keygen.00435BE7
0042F4EB FFB5 AFBE4000 PUSH DWORD PTR SS:[EBP+40BEAF] ; KERNEL32.7C570000
0042F507 E8 F4BAFFFF CALL Keygen.0042B000
0042F50C 8985 00BC4000 MOV DWORD PTR SS:[EBP+40BC00],EAX ; KERNEL32.UnhandledExceptionFilter // 一直到 lstrcpy 都调用 42B000 求 Address, 接着跳过 MessageBoxA 这个 API
// 后面几个 API 不再用42B000, 直接用 GetProcAddress
0042F8F1 8D85 A5BC4000 LEA EAX,DWORD PTR SS:[EBP+40BCA5]
0042F8F7 50 PUSH EAX ; Keygen.00435CA5
0042F90E FFB5 AFBE4000 PUSH DWORD PTR SS:[EBP+40BEAF] ; KERNEL32.7C570000
0042F92E FF95 C4BB4000 CALL DWORD PTR SS:[EBP+40BBC4] ; KERNEL32.GetProcAddress
0042F934 8985 B3BC4000 MOV DWORD PTR SS:[EBP+40BCB3],EAX ; ntdll.RtlZeroMemory
...
0042FDE1 FF95 C4BB4000 CALL DWORD PTR SS:[EBP+40BBC4] ; KERNEL32.GetProcAddress
0042FDE7 8985 9EBD4000 MOV DWORD PTR SS:[EBP+40BD9E],EAX ; KERNEL32.FlushInstructionCache // 检查 UnhandledExceptionFilter 是否有断点, ????
0042FE58 8B85 00BC4000 MOV EAX,DWORD PTR SS:[EBP+40BC00] ; KERNEL32.UnhandledExceptionFilter
0042FE5E 8038 CC CMP BYTE PTR DS:[EAX],0CC ; INT3 检查
0042FE61 0F85 C8000000 JNZ Keygen.0042FF2F ; 跳 // 进程快照, 准备遍历, 找出自己
004300CD 6A 00 PUSH 0 ; ProcessID=0
004300CF 6A 02 PUSH 2 ; flags=TH32CS_SNAPPROCESS
004300D1 FF95 D0BC4000 CALL DWORD PTR SS:[EBP+40BCD0] ; KERNEL32.CreateToolhelp32Snapshot
004300D7 8985 DBC34000 MOV DWORD PTR SS:[EBP+40C3DB],EAX ; [4363DB]=handle
004300F9 83F8 FF CMP EAX,-1
004300FC /75 01 JNZ SHORT Keygen.004300FF ; 跳
004300FE C3 RETN 0043016A 8DBD E3C34000 LEA EDI,DWORD PTR SS:[EBP+40C3E3] ; 4363E3=pPROCESSENTRY32
00430170 C707 28010000 MOV DWORD PTR DS:[EDI],128 ; dwSize
typedef struct tagPROCESSENTRY32 {
DWORD dwSize;
DWORD cntUsage;
DWORD th32ProcessID;
DWORD th32DefaultHeapID;
DWORD th32ModuleID;
DWORD cntThreads;
DWORD th32ParentProcessID;
LONG pcPriClassBase;
DWORD dwFlags;
char szExeFile[MAX_PATH];
} PROCESSENTRY32;
00430176 57 PUSH EDI ; pPROCESSENTRY32
004301A3 FFB5 DBC34000 PUSH DWORD PTR SS:[EBP+40C3DB] ; handle
004301A9 FF95 E3BC4000 CALL DWORD PTR SS:[EBP+40BCE3] ; KERNEL32.Process32First
004301CB 0BC0 OR EAX,EAX
004301CD 75 0D JNZ SHORT Keygen.004301DC ; 跳
004301CF FFB5 DBC34000 PUSH DWORD PTR SS:[EBP+40C3DB] ; handle
004301D5 FF95 2DBD4000 CALL DWORD PTR SS:[EBP+40BD2D] ; KERNEL32.CloseHandle
004301DB C3 RETN // 是否是自己?
00430247 FF95 0DBD4000 CALL DWORD PTR SS:[EBP+40BD0D] ; KERNEL32.GetCurrentProcessId
0043024D 3947 08 CMP DWORD PTR DS:[EDI+8],EAX ; pPROCESSENTRY32->th32ProcessID
00430250 /0F85 111A0000 JNZ Keygen.00431C67 ; 不是去 Process32Next
// 找到了自己, 可以得到父进程 ID, handle
00430256 8B47 18 MOV EAX,DWORD PTR DS:[EDI+18] ; pPROCESSENTRY32->th32ParentProcessID
00430259 8985 1EC34000 MOV DWORD PTR SS:[EBP+40C31E],EAX ; [43631E]
0043025F FF77 18 PUSH DWORD PTR DS:[EDI+18] ; 父进程 PID
00430262 6A 00 PUSH 0 ; Inheritable = FALSE
00430264 68 FF0F1F00 PUSH 1F0FFF ; Access = PROCESS_ALL_ACCESS
00430269 FF95 1DBD4000 CALL DWORD PTR SS:[EBP+40BD1D] ; KERNEL32.OpenProcess(父进程)
0043026F 8985 DFC34000 MOV DWORD PTR SS:[EBP+40C3DF],EAX ; [4363DF]= hProcess of 父进程
00430275 0BC0 OR EAX,EAX
00430277 0F84 E6190000 JE Keygen.00431C63 ; 找不到父进程, 跳
0043027D 8D85 B7114000 LEA EAX,DWORD PTR SS:[EBP+4011B7]
00430283 50 PUSH EAX ; Keygen.0042B1B7, 做 SEH handler, 见 Note 2
00430284 64:FF35 0000000>PUSH DWORD PTR FS:[0]
0043028B 64:8925 0000000>MOV DWORD PTR FS:[0],ESP
00430292 55 PUSH EBP
00430293 6A 00 PUSH 0 ; pBytesRead = NULL
00430295 6A 40 PUSH 40 ; BytesToRead
00430297 8D85 0BC54000 LEA EAX,DWORD PTR SS:[EBP+40C50B]
0043029D 50 PUSH EAX ; Buffer = 43650B
0043029E 68 00000010 PUSH 10000000 ; pBaseAddress
004302A3 FFB5 DFC34000 PUSH DWORD PTR SS:[EBP+40C3DF] ; hProcess of 父进程
004302A9 FF95 43BD4000 CALL DWORD PTR SS:[EBP+40BD43] ; KERNEL32.ReadProcessMemory, 这个不会成功????? 004302AF 5D POP EBP
004302B0 33DB XOR EBX,EBX
004302B2 64:8F03 POP DWORD PTR FS:[EBX]
004302B5 83C4 04 ADD ESP,4 ; 恢复 SEH
004302B8 50 PUSH EAX ; ReadProcessMemory 是否成功的标志
004302B9 51 PUSH ECX
//一大段花指令后, 取出自己的文件名, 做一变换
00431C2C 33C9 XOR ECX,ECX
00431C2E 8D47 24 LEA EAX,DWORD PTR DS:[EDI+24] ; pPROCESSENTRY32->szExeFile
00431C31 8A0401 MOV AL,BYTE PTR DS:[ECX+EAX]
00431C34 0AC0 OR AL,AL
00431C36 75 02 JNZ SHORT Keygen.00431C3A
00431C38 EB 13 JMP SHORT Keygen.00431C4D ; 文件名结束了
00431C3A 24 0F AND AL,0F ; 0 - F
00431C3C 8D9D 0EC34000 LEA EBX,DWORD PTR SS:[EBP+40C30E] ; 43630E (ASCII "&ad$.8=CCD[[VTQ")
00431C42 D7 XLAT BYTE PTR DS:[EBX+AL] ; 根据 AL 查上表得到一个字符 -> AL
00431C43 888429 A2BD4000 MOV BYTE PTR DS:[ECX+EBP+40BDA2],AL ; 435DA2 放结果的表
00431C4A 41 INC ECX
00431C4B ^ EB E1 JMP SHORT Keygen.00431C2E
00431C4D 59 POP ECX
00431C4E 58 POP EAX
00431C4F 83F8 01 CMP EAX,1
00431C52 75 0B JNZ SHORT Keygen.00431C5F ; ReadProcessMemory 不成功跳
00431C54 C685 1DC34000 0>MOV BYTE PTR SS:[EBP+40C31D],1 ; 成功, [43631D]=1
00431C5B EB 1F JMP SHORT Keygen.00431C7C ; 跳出循环
00431C5F /EB 1B JMP SHORT Keygen.00431C7C
00431C63 /EB 17 JMP SHORT Keygen.00431C7C // 不是自己, 下一个
00431C67 57 PUSH EDI ; pPROCESSENTRY32
00431C68 FFB5 DBC34000 PUSH DWORD PTR SS:[EBP+40C3DB] ; handle
00431C6E FF95 F5BC4000 CALL DWORD PTR SS:[EBP+40BCF5] ; KERNEL32.Process32Next
00431C74 0BC0 OR EAX,EAX
00431C76 ^ 0F85 CBE5FFFF JNZ Keygen.00430247 00431C7C 花指令 // 关闭 hProcess of 父进程
00431C96 FFB5 DFC34000 PUSH DWORD PTR SS:[EBP+40C3DF] ; hProcess of 父进程
00431CC5 FF95 2DBD4000 CALL DWORD PTR SS:[EBP+40BD2D] ; KERNEL32.CloseHandle // 再次准备遍历, 这次要找出父进程
00431CCB 57 PUSH EDI ; Keygen.004363E3
00431CF8 FFB5 DBC34000 PUSH DWORD PTR SS:[EBP+40C3DB] ; handle
00431CFE FF95 E3BC4000 CALL DWORD PTR SS:[EBP+40BCE3] ; KERNEL32.Process32First
00431D20 0BC0 OR EAX,EAX
00431D22 75 0D JNZ SHORT Keygen.00431D31 ; 必须跳
00431D24 FFB5 DBC34000 PUSH DWORD PTR SS:[EBP+40C3DB]
00431D2A FF95 2DBD4000 CALL DWORD PTR SS:[EBP+40BD2D] ; KERNEL32.CloseHandle
00431D30 C3 RETN ; 出错 // 是否是父进程?
00431D31 8B85 1EC34000 MOV EAX,DWORD PTR SS:[EBP+40C31E] ; PID of Parent
00431D37 3947 08 CMP DWORD PTR DS:[EDI+8],EAX
00431D3A 0F85 A0000000 JNZ Keygen.00431DE0 ; 不是父进程, 直接去 Process32Next // 找到了父进程, 判断父进程名字是否和自己一样
00431D40 BA 00000000 MOV EDX,0 ; 初始值
00431D45 33C9 XOR ECX,ECX
00431D47 8D47 24 LEA EAX,DWORD PTR DS:[EDI+24] ; pPROCESSENTRY32->szExeFile
00431D4A 8A0401 MOV AL,BYTE PTR DS:[ECX+EAX]
00431D4D 0AC0 OR AL,AL
00431D4F 75 02 JNZ SHORT Keygen.00431D53
00431D51 EB 1C JMP SHORT Keygen.00431D6F ; 名字结束了
00431D53 24 0F AND AL,0F
00431D55 8D9D 0EC34000 LEA EBX,DWORD PTR SS:[EBP+40C30E] ; 43630E(ASCII "&ad$.8=CCD[[VTQ"+01)
00431D5B D7 XLAT BYTE PTR DS:[EBX+AL] ; 查表
00431D5C 328429 A2BD4000 XOR AL,BYTE PTR DS:[ECX+EBP+40BDA2] ; Xor 子进程的变换值
00431D63 0AC0 OR AL,AL
00431D65 74 05 JE SHORT Keygen.00431D6C
00431D67 BA 01000000 MOV EDX,1 ; 有一个字母不一样, EDX=1
00431D6C 41 INC ECX
00431D6D ^\EB D8 JMP SHORT Keygen.00431D47 ; 循环 00431D6F 83FA 01 CMP EDX,1
00431D72 75 6C JNZ SHORT Keygen.00431DE0 ; 这里要注意一下
; 当我们用 OD 调试壳的父进程时, 不跳
; 当我们用 OD 调试壳的子进程时, 应该跳 00431D8A BE 7A7D4000 MOV ESI,Keygen.00407D7A
00431DA9 81EE FF000000 SUB ESI,0FF
00431DAF 03F5 ADD ESI,EBP ; ESI=431C7B
00431DC7 C706 C77E4000 MOV DWORD PTR DS:[ESI],Keygen.00407EC7
00431DCD 83C6 1F ADD ESI,1F
00431DD0 8906 MOV DWORD PTR DS:[ESI],EAX ; ESI=431C9A, EAX=431DC7 00431DD2 FFB5 DFC34000 PUSH DWORD PTR SS:[EBP+40C3DF] ; 改成 0, 否则会有异常发生, ????
00431DD8 FF95 2DBD4000 CALL DWORD PTR SS:[EBP+40BD2D] ; KERNEL32.CloseHandle
00431DDE EB 15 JMP SHORT Keygen.00431DF5 // 没找到父进程, 下一个
00431DE0 57 PUSH EDI
00431DE1 FFB5 DBC34000 PUSH DWORD PTR SS:[EBP+40C3DB]
00431DE7 FF95 F5BC4000 CALL DWORD PTR SS:[EBP+40BCF5] ; KERNEL32.Process32Next
00431DED 0BC0 OR EAX,EAX
00431DEF ^ 0F85 3CFFFFFF JNZ Keygen.00431D31 ; 循环 // 关闭 Handle of ProcessSnap
00431E0F FFB5 DBC34000 PUSH DWORD PTR SS:[EBP+40C3DB]
00431E3E FF95 2DBD4000 CALL DWORD PTR SS:[EBP+40BD2D] ; KERNEL32.CloseHandle 00431E5A FF95 79BC4000 CALL DWORD PTR SS:[EBP+40BC79] ; KERNEL32.GetCommandLineA
00431E60 50 PUSH EAX
00431E8D 5A POP EDX ; 00132338
00431E8E 8BF2 MOV ESI,EDX
00431EA6 803E 58 CMP BYTE PTR DS:[ESI],58 ; 'X'
00431EA9 /75 2E JNZ SHORT Keygen.00431ED9 ; 判断被调试标志了, ******************************************** // 父进程走这条路, 子进程走另一条路, 后面再讲
00431EF3 68 00010000 PUSH 100
00431EF8 8D85 A2BD4000 LEA EAX,DWORD PTR SS:[EBP+40BDA2] ; 435DA2
00431EFE 50 PUSH EAX
00431EFF 6A 00 PUSH 0
00431F01 FF95 17BC4000 CALL DWORD PTR SS:[EBP+40BC17] ; KERNEL32.GetModuleFileNameA 00431F1A 8D85 A2BD4000 LEA EAX,DWORD PTR SS:[EBP+40BDA2]
00431F20 50 PUSH EAX
00431F21 E8 3795FFFF CALL Keygen.0042B45D ; F7 0042B45D 55 PUSH EBP
0042B45E 8BEC MOV EBP,ESP
0042B460 60 PUSHAD
0042B461 8B7D 08 MOV EDI,DWORD PTR SS:[EBP+8]
0042B464 E8 00000000 CALL Keygen.0042B469
0042B469 5B POP EBX
0042B46A 81EB 69144000 SUB EBX,Keygen.00401469
0042B470 B8 44000000 MOV EAX,44
0042B475 50 PUSH EAX
0042B476 8D83 22C34000 LEA EAX,DWORD PTR DS:[EBX+40C322]
0042B47C 50 PUSH EAX
0042B47D FF93 B3BC4000 CALL DWORD PTR DS:[EBX+40BCB3] ;RtlZeroMemory
0042B483 B8 10000000 MOV EAX,10
0042B488 50 PUSH EAX
0042B489 8D83 66C34000 LEA EAX,DWORD PTR DS:[EBX+40C366]
0042B48F 50 PUSH EAX
0042B490 FF93 B3BC4000 CALL DWORD PTR DS:[EBX+40BCB3] ;RtlZeroMemory
0042B496 B8 44000000 MOV EAX,44
0042B49B 8983 22C34000 MOV DWORD PTR DS:[EBX+40C322],EAX
0042B4A1 8D83 66C34000 LEA EAX,DWORD PTR DS:[EBX+40C366]
0042B4A7 50 PUSH EAX
0042B4A8 8D83 22C34000 LEA EAX,DWORD PTR DS:[EBX+40C322]
0042B4AE 50 PUSH EAX
0042B4AF 6A 00 PUSH 0
0042B4B1 6A 00 PUSH 0
0042B4B3 B8 01000000 MOV EAX,1
0042B4B8 83C8 02 OR EAX,2
0042B4BB 50 PUSH EAX
0042B4BC 6A 00 PUSH 0
0042B4BE 6A 00 PUSH 0
0042B4C0 6A 00 PUSH 0
0042B4C2 8D83 A2BE4000 LEA EAX,DWORD PTR DS:[EBX+40BEA2]
0042B4C8 50 PUSH EAX
0042B4C9 57 PUSH EDI
0042B4CA FF93 39BC4000 CALL DWORD PTR DS:[EBX+40BC39] ; CreateProcess
0042B4D0 83F8 01 CMP EAX,1
0042B4D3 0F85 87010000 JNZ Keygen.0042B660 0012FF54 0042B4D0 /CALL to CreateProcessA from Keygen.0042B4CA
0012FF58 00435DA2 |ModuleFileName = "E:\xikug\Keygen.exe"
0012FF5C 00435EA2 |CommandLine = "X" ; 这个就是调试标志了
0012FF60 00000000 |pProcessSecurity = NULL
0012FF64 00000000 |pThreadSecurity = NULL
0012FF68 00000000 |InheritHandles = FALSE
0012FF6C 00000003 |CreationFlags = DEBUG_PROCESS|DEBUG_ONLY_THIS_PROCESS
0012FF70 00000000 |pEnvironment = NULL
0012FF74 00000000 |CurrentDir = NULL
0012FF78 00436322 |pStartupInfo = Keygen.00436322
0012FF7C 00436366 \pProcessInfo = Keygen.00436366 ; 这个很有用 0042B4D0 83F8 01 CMP EAX,1 ; 创建成功
0042B4D3 0F85 87010000 JNZ Keygen.0042B660 // 开始调试 WaitForDebugEvent, ContinueDebugEvent
0042B4D9 8DBB 98C64000 LEA EDI,DWORD PTR DS:[EBX+40C698]
0042B4DF C707 07000100 MOV DWORD PTR DS:[EDI],10007
0042B4E5 810F 10000100 OR DWORD PTR DS:[EDI],10010
0042B4EB 8D83 76C34000 LEA EAX,DWORD PTR DS:[EBX+40C376]
0042B4F1 68 A00F0000 PUSH 0FA0
0042B4F6 50 PUSH EAX
0042B4F7 FF93 4FBC4000 CALL DWORD PTR DS:[EBX+40BC4F] ; KERNEL32.WaitForDebugEvent
0012FF74 0042B4FD /CALL to WaitForDebugEvent from Keygen.0042B4F7
0012FF78 00436376 |pDebugEvent = Keygen.00436376
0012FF7C 00000FA0 \Timeout = 4000. ms 0042B4FD 83F8 01 CMP EAX,1
0042B500 0F85 55010000 JNZ Keygen.0042B65B
0042B506 8D93 76C34000 LEA EDX,DWORD PTR DS:[EBX+40C376] ; pDebugEvent
0042B50C 8DB3 66C34000 LEA ESI,DWORD PTR DS:[EBX+40C366] // CREATE_PROCESS_DEBUG_EVENT
0042B512 833A 03 CMP DWORD PTR DS:[EDX],3 ; CREATE_PROCESS_DEBUG_EVENT
0042B515 75 16 JNZ SHORT Keygen.0042B52D
0042B517 68 02000100 PUSH 10002 ; DBG_Continue
0042B51C FF72 08 PUSH DWORD PTR DS:[EDX+8]
0042B51F FF72 04 PUSH DWORD PTR DS:[EDX+4]
0042B522 FF93 66BC4000 CALL DWORD PTR DS:[EBX+40BC66] ; KERNEL32.ContinueDebugEvent
0042B528 /E9 2E010000 JMP Keygen.0042B65B // EXCEPTION_DEBUG_EVENT
0042B52D 833A 01 CMP DWORD PTR DS:[EDX],1 ; EXCEPTION_DEBUG_EVENT
0042B530 0F85 0B010000 JNZ Keygen.0042B641
0042B536 817A 0C 0300008>CMP DWORD PTR DS:[EDX+C],80000003 ; INT3 异常, 调试器只处理 CC
0042B53D 0F85 EB000000 JNZ Keygen.0042B62E
0042B543 83BB D7C34000 0>CMP DWORD PTR DS:[EBX+40C3D7],0 ; 第一次异常的标志, 0 , 系统产生的
0042B54A 75 1C JNZ SHORT Keygen.0042B568
0042B54C FF83 D7C34000 INC DWORD PTR DS:[EBX+40C3D7]
0042B552 68 02000100 PUSH 10002 ; 第一次异常, 必须返回 DBG_Continue, 虽然调试器没处理
0042B557 FF72 08 PUSH DWORD PTR DS:[EDX+8]
0042B55A FF72 04 PUSH DWORD PTR DS:[EDX+4]
0042B55D FF93 66BC4000 CALL DWORD PTR DS:[EBX+40BC66] ; KERNEL32.ContinueDebugEvent
0042B563 /E9 F3000000 JMP Keygen.0042B65B
0042B568 83BB D7C34000 0>CMP DWORD PTR DS:[EBX+40C3D7],1 ; 只有第二次 INT3 异常需要调试器处理
0042B56F 0F85 A6000000 JNZ Keygen.0042B61B ; 第三次以后就不用了, 子进程自己 SEH 处理 // 第二次 INT3 异常, 处理 CC 的代码 , ***************** 就是将子进程 433861 开始到 435AE3 的 2283 字节 Xor 52
0042B575 52 PUSH EDX ; F2 , 下断
0042B576 FF83 D7C34000 INC DWORD PTR DS:[EBX+40C3D7] ; INT3 异常的次数+1
0042B57C 8DBB 98C64000 LEA EDI,DWORD PTR DS:[EBX+40C698] ; 436698
0042B582 57 PUSH EDI ; pContext
0042B583 FF76 04 PUSH DWORD PTR DS:[ESI+4] ; hThread
0042B586 FF93 58BD4000 CALL DWORD PTR DS:[EBX+40BD58] ; KERNEL32.GetThreadContext
0042B58C 8B8F B8000000 MOV ECX,DWORD PTR DS:[EDI+B8] ; regEIP=433861
0042B592 51 PUSH ECX
0042B593 6A 00 PUSH 0
0042B595 6A 01 PUSH 1
0042B597 8D83 D6C34000 LEA EAX,DWORD PTR DS:[EBX+40C3D6]
0042B59D 50 PUSH EAX
0042B59E 51 PUSH ECX
0042B59F FF36 PUSH DWORD PTR DS:[ESI] ; hProcess
0042B5A1 FF93 43BD4000 CALL DWORD PTR DS:[EBX+40BD43] ; KERNEL32.ReadProcessMemory
0012FF60 0042B5A7 /CALL to ReadProcessMemory from Keygen.0042B5A1
0012FF64 00000044 |hProcess = 00000044 (window)
0012FF68 00433861 |pBaseAddress = 433861
0012FF6C 004363D6 |Buffer = Keygen.004363D6
0012FF70 00000001 |BytesToRead = 1
0012FF74 00000000 \pBytesRead = NULL
0042B5A7 59 POP ECX
0042B5A8 8D83 D6C34000 LEA EAX,DWORD PTR DS:[EBX+40C3D6] ; Buffer
0042B5AE 8A00 MOV AL,BYTE PTR DS:[EAX]
0042B5B0 34 52 XOR AL,52
0042B5B2 8883 D6C34000 MOV BYTE PTR DS:[EBX+40C3D6],AL ; Xor 52
0042B5B8 51 PUSH ECX
0042B5B9 6A 00 PUSH 0
0042B5BB 6A 01 PUSH 1
0042B5BD 8D83 D6C34000 LEA EAX,DWORD PTR DS:[EBX+40C3D6]
0042B5C3 50 PUSH EAX
0042B5C4 51 PUSH ECX
0042B5C5 FF36 PUSH DWORD PTR DS:[ESI]
0042B5C7 FF93 84BD4000 CALL DWORD PTR DS:[EBX+40BD84] ; KERNEL32.WriteProcessMemory
0012FF60 0042B5CD /CALL to WriteProcessMemory from Keygen.0042B5C7
0012FF64 00000044 |hProcess = 00000044 (window)
0012FF68 00433861 |Address = 433861
0012FF6C 004363D6 |Buffer = Keygen.004363D6
0012FF70 00000001 |BytesToWrite = 1
0012FF74 00000000 \pBytesWritten = NULL 0042B5CD 59 POP ECX
0042B5CE 8D83 E4BA4000 LEA EAX,DWORD PTR DS:[EBX+40BAE4] ; 435AE4
0042B5D4 41 INC ECX
0042B5D5 3BC8 CMP ECX,EAX
0042B5D7 75 02 JNZ SHORT Keygen.0042B5DB
0042B5D9 EB 02 JMP SHORT Keygen.0042B5DD ; 所有字节都处理完了
0042B5DB ^\EB B5 JMP SHORT Keygen.0042B592 ; 没处理完, 继续
0042B5DD 51 PUSH ECX
0042B5DE 8B87 B8000000 MOV EAX,DWORD PTR DS:[EDI+B8] ; regEIP
0042B5E4 8987 B8000000 MOV DWORD PTR DS:[EDI+B8],EAX ; 没变化
0042B5EA 57 PUSH EDI
0042B5EB FF76 04 PUSH DWORD PTR DS:[ESI+4]
0042B5EE FF93 6DBD4000 CALL DWORD PTR DS:[EBX+40BD6D] ; KERNEL32.SetThreadContext 0042B5F4 8B87 B8000000 MOV EAX,DWORD PTR DS:[EDI+B8]
0042B5FA 59 POP ECX
0042B5FB 2BC8 SUB ECX,EAX
0042B5FD 51 PUSH ECX
0042B5FE 50 PUSH EAX
0042B5FF FF36 PUSH DWORD PTR DS:[ESI]
0042B601 FF93 9EBD4000 CALL DWORD PTR DS:[EBX+40BD9E] ; FlushInstructionCache, 有必要吗?
0012FF6C 0042B607 /CALL to FlushInstructionCache from Keygen.0042B601
0012FF70 00000044 |hProcess = 00000044 (window)
0012FF74 00433861 |RegionBase = Keygen.00433861
0012FF78 00002283 \RegionSize = 2283 0042B607 5A POP EDX
0042B608 68 02000100 PUSH 10002 ; DBG_Continue, 异常处理好了
0042B60D FF72 08 PUSH DWORD PTR DS:[EDX+8]
0042B610 FF72 04 PUSH DWORD PTR DS:[EDX+4]
0042B613 FF93 66BC4000 CALL DWORD PTR DS:[EBX+40BC66] ; KERNEL32.ContinueDebugEvent
0042B619 EB 40 JMP SHORT Keygen.0042B65B 0042B61B 68 01000180 PUSH 80010001 ; DBG_EXCEPTION_NOT_HANDLED, 子进程自己的 SEH 处理
0042B620 FF72 08 PUSH DWORD PTR DS:[EDX+8]
0042B623 FF72 04 PUSH DWORD PTR DS:[EDX+4]
0042B626 FF93 66BC4000 CALL DWORD PTR DS:[EBX+40BC66]
0042B62C EB 2D JMP SHORT Keygen.0042B65B 0042B62E 68 01000180 PUSH 80010001 ; DBG_EXCEPTION_NOT_HANDLED, 子进程自己的 SEH 处理
0042B633 FF72 08 PUSH DWORD PTR DS:[EDX+8]
0042B636 FF72 04 PUSH DWORD PTR DS:[EDX+4]
0042B639 FF93 66BC4000 CALL DWORD PTR DS:[EBX+40BC66] ; KERNEL32.ContinueDebugEvent
0042B63F EB 1A JMP SHORT Keygen.0042B65B // EXIT_PROCESS_DEBUG_EVENT
0042B641 833A 05 CMP DWORD PTR DS:[EDX],5 ; EXIT_PROCESS_DEBUG_EVENT
0042B644 75 04 JNZ SHORT Keygen.0042B64A
0042B646 /EB 18 JMP SHORT Keygen.0042B660 ; 子进程结束了
0042B648 /EB 11 JMP SHORT Keygen.0042B65B
0042B64A 68 02000100 PUSH 10002 ; DBG_Continue
0042B64F FF72 08 PUSH DWORD PTR DS:[EDX+8]
0042B652 FF72 04 PUSH DWORD PTR DS:[EDX+4]
0042B655 FF93 66BC4000 CALL DWORD PTR DS:[EBX+40BC66] ; KERNEL32.ContinueDebugEvent
0042B65B ^ E9 8BFEFFFF JMP Keygen.0042B4EB 0042B65B ^\E9 8BFEFFFF JMP Keygen.0042B4EB
0042B660 61 POPAD
0042B661 C9 LEAVE
0042B662 C2 0400 RETN 4 现在父进程我们清楚了, 可以把双进程转换成单进程.
把 OD 的文件名改成和 壳一样的名字 , 忽略其他异常, 不忽略 INT3
F4 直接到 431D72, 已经跳了, 如果 OD 不改名, 这里不跳, 手动改一下.
再 F4 到 431EA9, 改一下跳转, F9
00433860 CC INT3 ; int3 中断
00433861 61 POPAD 接下来要做的就是写一段程序, 把 433861 开始到 435AE3 的 2283 字节 Xor 52
找一空地:
00870000 60 PUSHAD
00870001 B8 61384300 MOV EAX,433861
00870006 8030 52 XOR BYTE PTR DS:[EAX],52
00870009 40 INC EAX
0087000A 3D E45A4300 CMP EAX,435AE4
0087000F ^ 75 F5 JNZ SHORT 00870006
00870011 61 POPAD 60 B8 61 38 43 00 80 30 52 40 3D E4 5A 43 00 75 F5 61 执行完后, 去掉修改, EIP = 433861
// 处理 IAT
00433861 33C9 XOR ECX,ECX
00433863 8B9D DEC24000 MOV EBX,DWORD PTR SS:[EBP+40C2DE] ; 436A00
00433869 EB 15 JMP SHORT Keygen.00433880
0043386B FF348B PUSH DWORD PTR DS:[EBX+ECX*4]
0043386E FFB5 D6BE4000 PUSH DWORD PTR SS:[EBP+40BED6]
00433874 FFB5 BEBE4000 PUSH DWORD PTR SS:[EBP+40BEBE]
0043387A E8 FE77FFFF CALL Keygen.0042B07D ; 处理 IAT
0043387F 41 INC ECX
00433880 3B8D DAC24000 CMP ECX,DWORD PTR SS:[EBP+40C2DA] ; 4362DA=54 个API
00433886 ^ 72 E3 JB SHORT Keygen.0043386B
.... 接下来是一堆花指令
// 处理 OEP
004343E3 8BC5 MOV EAX,EBP
004343E5 8B95 0AC34000 MOV EDX,DWORD PTR SS:[EBP+40C30A]
004343EB 3395 E2C24000 XOR EDX,DWORD PTR SS:[EBP+40C2E2]
004343F1 8995 E2C24000 MOV DWORD PTR SS:[EBP+40C2E2],EDX
004343F7 5F POP EDI
004343F8 5A POP EDX
004343F9 59 POP ECX
004343FA 5E POP ESI
004343FB 5B POP EBX
004343FC 5D POP EBP
004343FD 05 FD114000 ADD EAX,Keygen.004011FD
00434402 50 PUSH EAX ; 42B1FD, 到 OEP 后的 CC 处理
00434403 64:FF35 0000000>PUSH DWORD PTR FS:[0]
0043440A 64:8925 0000000>MOV DWORD PTR FS:[0],ESP
00434411 2D FD114000 SUB EAX,Keygen.004011FD
00434416 FFB0 E2C24000 PUSH DWORD PTR DS:[EAX+40C2E2] ; [4362E2]=40548D, 这个就是 OEP 了 我们为了看个究竟,慢慢走, 接下来是一堆异常, F9, INT3 中断在 40708C, 过了 OEP.
看看 Log, 最后一个是 4354B2, 和开始时一样处理了. 0043545B Access violation when reading [00000000]
0043548A Integer division by zero
004354B2 Access violation when reading [00000000]
0040708C INT3 command at Keygen.0040708C
重新来过, 处理好 CC, 到 435489 下个硬件执行断点, F9, 取消断点, 取消忽略异常, F9
// 倒数第二个异常
00435463 8B5C24 0C MOV EBX,DWORD PTR SS:[ESP+C] ; SEH handler 这里下断,
00435467 8BA3 C4000000 MOV ESP,DWORD PTR DS:[EBX+C4]
0043546D 64:8F05 0000000>POP DWORD PTR FS:[0]
00435474 83C4 04 ADD ESP,4
00435477 EB 14 JMP SHORT Keygen.0043548D
00435479 64:FF35 0000000>PUSH DWORD PTR FS:[0]
00435480 64:8925 0000000>MOV DWORD PTR FS:[0],ESP
00435487 33C9 XOR ECX,ECX
00435489 99 CDQ
0043548A F7F1 DIV ECX ;除零异常 // 最后一个异常
00435494 8B6424 08 MOV ESP,DWORD PTR SS:[ESP+8] ; SEH handler 这里下断
00435498 64:8F05 0000000>POP DWORD PTR FS:[0]
0043549F 58 POP EAX
004354A0 EB 13 JMP SHORT Keygen.004354B5 004354A4 64:FF35 0000000>PUSH DWORD PTR FS:[0]
004354AB 64:8925 0000000>MOV DWORD PTR FS:[0],ESP
004354B2 AD LODS DWORD PTR DS:[ESI] ; 内存访问异常 接下来又是一堆花指令, F4 到这里,
00435ADB ^\75 F1 JNZ SHORT Keygen.00435ACE
00435ADD EB 05 JMP SHORT Keygen.00435AE4
00435ADF ^ EB F9 JMP SHORT Keygen.00435ADA
00435AE1 ^ EB F0 JMP SHORT Keygen.00435AD3
00435AE3 D6 SALC
00435AE4 C3 RETN ; OEP 到 OEP 后, 有几个 API 被改成了 CC, 还需要处理一下.
如下
0040708C CC INT3
0040708D 2D 7CC04000 SUB EAX,Keygen.0040C07C 异常后去 SEH 42B1FD 下断
0042B1FD 55 PUSH EBP
0042B1FE 8BEC MOV EBP,ESP
0042B200 56 PUSH ESI
0042B201 57 PUSH EDI
0042B202 53 PUSH EBX
0042B203 8B75 08 MOV ESI,DWORD PTR SS:[EBP+8] ; pEXCEPTION_RECORD
0042B206 8B7D 10 MOV EDI,DWORD PTR SS:[EBP+10] ; pContext
0042B209 813E 03000080 CMP DWORD PTR DS:[ESI],80000003 ; INT3
0042B20F 0F85 9E000000 JNZ Keygen.0042B2B3
0042B215 8B46 0C MOV EAX,DWORD PTR DS:[ESI+C] ; ExceptionAddress
0042B218 40 INC EAX
0042B219 40 INC EAX
0042B21A 8B00 MOV EAX,DWORD PTR DS:[EAX] ; [ExceptionAddress+2]=40C07C
0042B21C 60 PUSHAD
0042B21D E8 00000000 CALL Keygen.0042B222
0042B222 5D POP EBP
0042B223 81ED 22124000 SUB EBP,Keygen.00401222
0042B229 50 PUSH EAX ; 40C07C
0042B22A FFB5 D6BE4000 PUSH DWORD PTR SS:[EBP+40BED6] ; 2A000
0042B230 FFB5 BEBE4000 PUSH DWORD PTR SS:[EBP+40BEBE] ; 400000
0042B236 E8 42FEFFFF CALL Keygen.0042B07D ; 修改 [40C07C]
0042B23B 61 POPAD
0042B23C 52 PUSH EDX
0042B23D 51 PUSH ECX
0042B23E E8 00000000 CALL Keygen.0042B243
0042B243 5A POP EDX
0042B244 81EA 43124000 SUB EDX,Keygen.00401243
0042B24A 81C2 FD114000 ADD EDX,Keygen.004011FD ; 42B1FD
0042B250 8B08 MOV ECX,DWORD PTR DS:[EAX] ; API Address
0042B252 64:A1 00000000 MOV EAX,DWORD PTR FS:[0]
0042B258 8B00 MOV EAX,DWORD PTR DS:[EAX]
0042B25A 8950 04 MOV DWORD PTR DS:[EAX+4],EDX ; 修改 SEH
0042B25D 8BC1 MOV EAX,ECX
0042B25F 59 POP ECX
0042B260 5A POP EDX
0042B261 8B7E 0C MOV EDI,DWORD PTR DS:[ESI+C] ; ExceptionAddress
0042B264 83C7 01 ADD EDI,1
0042B267 803F 3D CMP BYTE PTR DS:[EDI],3D
0042B26A 74 15 JE SHORT Keygen.0042B281
0042B26C 803F 2D CMP BYTE PTR DS:[EDI],2D
0042B26F 74 1B JE SHORT Keygen.0042B28C
0042B271 803F 1D CMP BYTE PTR DS:[EDI],1D
0042B274 74 21 JE SHORT Keygen.0042B297
0042B276 8B7D 10 MOV EDI,DWORD PTR SS:[EBP+10] ; pContext
0042B279 8987 A0000000 MOV DWORD PTR DS:[EDI+A0],EAX ; regESI , 其他
0042B27F EB 1F JMP SHORT Keygen.0042B2A0
0042B281 8B7D 10 MOV EDI,DWORD PTR SS:[EBP+10]
0042B284 8987 9C000000 MOV DWORD PTR DS:[EDI+9C],EAX ;regEDI , 3D
0042B28A EB 14 JMP SHORT Keygen.0042B2A0
0042B28C 8B7D 10 MOV EDI,DWORD PTR SS:[EBP+10] ; pContext
0042B28F 8987 B4000000 MOV DWORD PTR DS:[EDI+B4],EAX ; regEBP, 2D
0042B295 EB 09 JMP SHORT Keygen.0042B2A0
0042B297 8B7D 10 MOV EDI,DWORD PTR SS:[EBP+10]
0042B29A 8987 A4000000 MOV DWORD PTR DS:[EDI+A4],EAX ;regEBX , 1D
0042B2A0 8B46 0C MOV EAX,DWORD PTR DS:[ESI+C] ; ExceptionAddress
0042B2A3 83C0 06 ADD EAX,6
0042B2A6 8987 B8000000 MOV DWORD PTR DS:[EDI+B8],EAX ; regEIP
0042B2AC B8 00000000 MOV EAX,0
0042B2B1 EB 05 JMP SHORT Keygen.0042B2B8
0042B2B3 B8 01000000 MOV EAX,1
0042B2B8 5B POP EBX
0042B2B9 5F POP EDI
0042B2BA 5E POP ESI
0042B2BB C9 LEAVE
0042B2BC C3 RETN 00870061 8B35 00C04000 MOV ESI,DWORD PTR DS:[40C000] ; Keygen.0042B2BD
00870067 8B3D 00C04000 MOV EDI,DWORD PTR DS:[40C000] ; Keygen.0042B2BD
0087006D 8B1D 00C04000 MOV EBX,DWORD PTR DS:[40C000] ; Keygen.0042B2BD
00870073 8B2D 00C04000 MOV EBP,DWORD PTR DS:[40C000] ; Keygen.0042B2BD 修复代码
00870000 60 PUSHAD
00870001 B8 00104000 MOV EAX,401000 ; 这一段处理 85 XX
00870006 8038 CC CMP BYTE PTR DS:[EAX],0CC
00870009 75 29 JNZ SHORT 00870034
0087000B 90 NOP
0087000C 8B58 02 MOV EBX,DWORD PTR DS:[EAX+2]
0087000F 81FB 00C04000 CMP EBX,40C000
00870015 7C 1D JL SHORT 00870034
00870017 81FB 9CC14000 CMP EBX,40C19C
0087001D 77 15 JA SHORT 00870034
0087001F 60 PUSHAD
00870020 53 PUSH EBX
00870021 68 00A00200 PUSH 2A000
00870026 68 00004000 PUSH 400000
0087002B E8 4DB0BBFF CALL Keygen.0042B07D
00870030 61 POPAD
00870031 C600 8B MOV BYTE PTR DS:[EAX],8B
00870034 40 INC EAX
00870035 3D 00804100 CMP EAX,418000
0087003A ^ 7C CA JL SHORT 00870006
0087003C 90 NOP
0087003D B8 00104000 MOV EAX,401000 ; 这一段处理 FF 15
00870042 66:8138 FF15 CMP WORD PTR DS:[EAX],15FF
00870047 75 28 JNZ SHORT 00870071
00870049 8B58 02 MOV EBX,DWORD PTR DS:[EAX+2]
0087004C 81FB 00C04000 CMP EBX,40C000
00870052 7C 1D JL SHORT 00870071
00870054 81FB 9CC14000 CMP EBX,40C19C
0087005A 77 15 JA SHORT 00870071
0087005C 60 PUSHAD
0087005D 53 PUSH EBX
0087005E 68 00A00200 PUSH 2A000
00870063 68 00004000 PUSH 400000
00870068 E8 10B0BBFF CALL Keygen.0042B07D
0087006D 61 POPAD
0087006E 83C0 05 ADD EAX,5
00870071 40 INC EAX
00870072 3D 00804100 CMP EAX,418000
00870077 ^ 7C C9 JL SHORT 00870042
00870079 90 NOP
0087007A 61 POPAD 60 B8 00 10 40 00 80 38 CC 75 29 90 8B 58 02 81 FB 00 C0 40 00 7C 1D 81 FB 9C C1 40 00 77 15 60
53 68 00 A0 02 00 68 00 00 40 00 E8 4D B0 BB FF 61 C6 00 8B 40 3D 00 80 41 00 7C CA 90 B8 00 10
40 00 66 81 38 FF 15 75 28 8B 58 02 81 FB 00 C0 40 00 7C 1D 81 FB 9C C1 40 00 77 15 60 53 68 00
A0 02 00 68 00 00 40 00 E8 10 B0 BB FF 61 83 C0 05 40 3D 00 80 41 00 7C C9 90 61 // Note 1
// MyGetProcAddress(hModule, pAPIName)
0042B000 55 PUSH EBP
0042B001 8BEC MOV EBP,ESP
0042B003 83C4 E8 ADD ESP,-18
0042B006 53 PUSH EBX
0042B007 51 PUSH ECX
0042B008 56 PUSH ESI
0042B009 57 PUSH EDI
0042B00A 8B45 08 MOV EAX,DWORD PTR SS:[EBP+8] ; hModule
0042B00D 8B40 3C MOV EAX,DWORD PTR DS:[EAX+3C] ; PE 头 RVA
0042B010 0345 08 ADD EAX,DWORD PTR SS:[EBP+8] ; PE 头 VA
0042B013 8945 FC MOV DWORD PTR SS:[EBP-4],EAX ; var1
0042B016 8B5D 08 MOV EBX,DWORD PTR SS:[EBP+8] ; hModule
0042B019 0358 78 ADD EBX,DWORD PTR DS:[EAX+78] ; Export Table VA
0042B01C 895D F8 MOV DWORD PTR SS:[EBP-8],EBX ; var2
0042B01F 8BC3 MOV EAX,EBX
0042B021 8B58 1C MOV EBX,DWORD PTR DS:[EAX+1C] ; AddressOfFunctions RVA
0042B024 035D 08 ADD EBX,DWORD PTR SS:[EBP+8] ; AddressOfFunctions VA
0042B027 895D F4 MOV DWORD PTR SS:[EBP-C],EBX ; var3
0042B02A 8B58 18 MOV EBX,DWORD PTR DS:[EAX+18] ; NumberOfNames
0042B02D 895D F0 MOV DWORD PTR SS:[EBP-10],EBX ; var4
0042B030 8B58 20 MOV EBX,DWORD PTR DS:[EAX+20] ; AddressOfNames RVA
0042B033 035D 08 ADD EBX,DWORD PTR SS:[EBP+8] ; AddressOfNames VA
0042B036 895D E8 MOV DWORD PTR SS:[EBP-18],EBX ; var6
0042B039 8B58 24 MOV EBX,DWORD PTR DS:[EAX+24] ; AddressOfNameOrdinals RVA
0042B03C 035D 08 ADD EBX,DWORD PTR SS:[EBP+8] ; AddressOfNameOrdinals VA
0042B03F 895D EC MOV DWORD PTR SS:[EBP-14],EBX ; var5
0042B042 33C9 XOR ECX,ECX
0042B044 33DB XOR EBX,EBX
0042B046 8B75 0C MOV ESI,DWORD PTR SS:[EBP+C] ; pAPIName
0042B049 8B7D E8 MOV EDI,DWORD PTR SS:[EBP-18] ; var6
0042B04C 8B3C8F MOV EDI,DWORD PTR DS:[EDI+ECX*4]
0042B04F 037D 08 ADD EDI,DWORD PTR SS:[EBP+8] ; RVA->VA
0042B052 8A043B MOV AL,BYTE PTR DS:[EBX+EDI]
0042B055 3A0433 CMP AL,BYTE PTR DS:[EBX+ESI]
0042B058 75 0A JNZ SHORT Keygen.0042B064 ; 字符不等, 下一个 API
0042B05A 43 INC EBX
0042B05B B0 00 MOV AL,0 ; NULL
0042B05D 3A0433 CMP AL,BYTE PTR DS:[EBX+ESI]
0042B060 ^ 75 F0 JNZ SHORT Keygen.0042B052
0042B062 74 08 JE SHORT Keygen.0042B06C ; 一个 API 找到了
0042B064 33DB XOR EBX,EBX
0042B066 41 INC ECX
0042B067 3B4D F0 CMP ECX,DWORD PTR SS:[EBP-10] ; var4
0042B06A ^ 75 DD JNZ SHORT Keygen.0042B049
0042B06C 8B7D F4 MOV EDI,DWORD PTR SS:[EBP-C] ; var3
0042B06F 8B048F MOV EAX,DWORD PTR DS:[EDI+ECX*4]
0042B072 0345 08 ADD EAX,DWORD PTR SS:[EBP+8] ; API address 结果
0042B075 5F POP EDI
0042B076 5E POP ESI
0042B077 59 POP ECX
0042B078 5B POP EBX
0042B079 C9 LEAVE
0042B07A C2 0800 RETN 8 00435B8F 47 65 74 4D 6F 64 75 6C 65 48 61 6E 64 6C 65 41 GetModuleHandleA
00435B9F 00 00 00 00 00 4C 6F 61 64 4C 69 62 72 61 72 79 .....LoadLibrary
00435BAF 41 00 00 00 00 00 47 65 74 50 72 6F 63 41 64 64 A.....GetProcAdd
00435BBF 72 65 73 73 00 00 00 00 00 47 6C 6F 62 61 6C 41 ress.....GlobalA
00435BCF 6C 6C 6F 63 00 00 00 00 00 47 6C 6F 62 61 6C 46 lloc.....GlobalF
00435BDF 72 65 65 00 00 00 00 00 55 6E 68 61 6E 64 6C 65 ree.....Unhandle
00435BEF 64 45 78 63 65 70 74 69 6F 6E 46 69 6C 74 65 72 dExceptionFilter
00435BFF 00 00 00 00 00 47 65 74 4D 6F 64 75 6C 65 46 69 .....GetModuleFi
00435C0F 6C 65 4E 61 6D 65 41 00 00 00 00 00 45 78 69 74 leNameA.....Exit
00435C1F 50 72 6F 63 65 73 73 00 00 00 00 00 43 72 65 61 Process.....Crea
00435C2F 74 65 50 72 6F 63 65 73 73 00 00 00 00 00 57 61 teProcess.....Wa
00435C3F 69 74 46 6F 72 44 65 62 75 67 45 76 65 6E 74 00 itForDebugEvent.
00435C4F 00 00 00 00 43 6F 6E 74 69 6E 75 65 44 65 62 75 ....ContinueDebu
00435C5F 67 45 76 65 6E 74 00 00 00 00 00 47 65 74 43 6F gEvent.....GetCo
00435C6F 6D 6D 61 6E 64 4C 69 6E 65 00 00 00 00 00 6C 73 mmandLine.....ls
00435C7F 74 72 6C 65 6E 00 00 00 00 00 6C 73 74 72 63 70 trlen.....lstrcp
00435C8F 79 00 00 00 00 00 4D 65 73 73 61 67 65 42 6F 78 y.....MessageBox
00435C9F 41 00 00 00 00 00 52 74 6C 5A 65 72 6F 4D 65 6D A.....RtlZeroMem
00435CAF 6F 72 79 00 00 00 00 00 43 72 65 61 74 65 54 6F ory.....CreateTo
00435CBF 6F 6C 68 65 6C 70 33 32 53 6E 61 70 73 68 6F 74 olhelp32Snapshot
00435CCF 00 00 00 00 00 50 72 6F 63 65 73 73 33 32 46 69 .....Process32Fi
00435CDF 72 73 74 00 00 00 00 00 50 72 6F 63 65 73 73 33 rst.....Process3
00435CEF 32 4E 65 78 74 00 00 00 00 00 47 65 74 43 75 72 2Next.....GetCur
00435CFF 72 65 6E 74 50 72 6F 63 65 73 73 49 64 00 00 00 rentProcessId...
00435D0F 00 00 4F 70 65 6E 50 72 6F 63 65 73 73 00 00 00 ..OpenProcess...
00435D1F 00 00 43 6C 6F 73 65 48 61 6E 64 6C 65 00 00 00 ..CloseHandle...
00435D2F 00 00 52 65 61 64 50 72 6F 63 65 73 73 4D 65 6D ..ReadProcessMem
00435D3F 6F 72 79 00 00 00 00 00 47 65 74 54 68 72 65 61 ory.....GetThrea
00435D4F 64 43 6F 6E 74 65 78 74 00 00 00 00 00 53 65 74 dContext.....Set
00435D5F 54 68 72 65 61 64 43 6F 6E 74 65 78 74 00 00 00 ThreadContext...
00435D6F 00 00 57 72 69 74 65 50 72 6F 63 65 73 73 4D 65 ..WriteProcessMe
00435D7F 6D 6F 72 79 00 00 00 00 00 46 6C 75 73 68 49 6E mory.....FlushIn
00435D8F 73 74 72 75 63 74 69 6F 6E 43 61 63 68 65 00 00 structionCache.. // Note 2
// 42B1B7 , SEHhandler 0042B1B7 55 PUSH EBP
0042B1B8 8BEC MOV EBP,ESP
0042B1BA 56 PUSH ESI
0042B1BB 57 PUSH EDI
0042B1BC 53 PUSH EBX
0042B1BD 8B75 08 MOV ESI,DWORD PTR SS:[EBP+8] ; pEXCEPTION_RECORD
0042B1C0 8B7D 10 MOV EDI,DWORD PTR SS:[EBP+10] ; pContext
0042B1C3 813E 050000C0 CMP DWORD PTR DS:[ESI],C0000005 ; ExceptionCode 读写内存冲突
0042B1C9 75 28 JNZ SHORT Keygen.0042B1F3
0042B1CB 60 PUSHAD
0042B1CC E8 00000000 CALL Keygen.0042B1D1
0042B1D1 5D POP EBP
0042B1D2 81ED D1114000 SUB EBP,Keygen.004011D1 ; 2A000
0042B1D8 8D9D AF624000 LEA EBX,DWORD PTR SS:[EBP+4062AF] ; 4302AF
0042B1DE C787 B0000000 0>MOV DWORD PTR DS:[EDI+B0],0 ; regEAX
0042B1E8 899F B8000000 MOV DWORD PTR DS:[EDI+B8],EBX ; regEIP=4302AF
0042B1EE 61 POPAD
0042B1EF 33C0 XOR EAX,EAX ; 已处理
0042B1F1 EB 05 JMP SHORT Keygen.0042B1F8
0042B1F3 B8 01000000 MOV EAX,1 ; 异常未处理
0042B1F8 5B POP EBX
0042B1F9 5F POP EDI
0042B1FA 5E POP ESI
0042B1FB C9 LEAVE
0042B1FC C3 RETN附件:unpacked.zip
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!