【脱文作者】 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

  • 标 题: 答复
  • 作 者:xIkUg
  • 时 间:2005-01-23 09:42

赞...我把你的笔记仔细看了一遍...分析得不错...;) ;) ;) 

ReadProcessMemory是种Anti手段, 不过对OD不起作用

真正对OD起作用的是取父进程名后, 变换名字, 跟自身进程名 xor 
如果结果不为零就乱跳

这个壳还可以更简单的改成单进程...在Loader第1次解码的时候...嘿嘿...;) ;) ;)

  • 标 题: 答复
  • 作 者:jingulong
  • 时 间:2005-01-23 23:54

引用:
最初由 simonzh2000 发布
对父进程 ReadProcessMemory 是一种 Anti 手段吗?
xIKug 兄弟, 能进来讨论一下吗? 
我感觉不能对付 OD, 但能对付 VC 的 Debugger. 



只要有dll 在10000000处加载,就anti,对OD也一样

  • 标 题: 答复
  • 作 者:simonzh2000
  • 时 间:2005-01-24 00:50

引用:
最初由 jingulong 发布


只要有dll 在10000000处加载,就anti,对OD也一样 



个人感觉这不是重点, 每个人情况不一样, 读到读不到很难掌握.

重点应该是下面的 CloseHandle(XX), XX 是不存在的句柄,  
不调试的时候, 系统默认处理了,什么事都没有, 但 OD, VC会异常.
(其实 OD 只要按 f9 就过去了, 按 shift+f9 反而过不去)

  • 标 题: 答复
  • 作 者:simonzh2000
  • 时 间:2005-01-24 16:13

引用:
最初由 jingulong 发布


脱过Armadillo主程序吗?它很早的版本就是这样了 



原来如此. 

  • 标 题: 答复
  • 作 者:总统
  • 时 间:2005-01-24 20:09

请问是在什么地方开始转换成单线成的,对不起没看明白
指点一下
多谢

  • 标 题: 答复
  • 作 者:simonzh2000
  • 时 间:2005-01-24 21:48

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

就是这里, 走不同的路线了