Xikug’s Protecter v0.3外壳完全分析

Xikug’s Protecter v0.3
【目     标】:XiKug’s Protecter v0.3主程序
【工     具】:Olydbg1.1(diy版)、LORDPE、ImportREC1.6F
【任     务】:分析外壳 
【操作平台】:WinXP sp2
【作     者】: LOVEBOOM[DFCG][FCG][US]
【相关链接】: 自己去上网搜搜
【简要说明】: 这个壳看是看过几次,只是以前没有时间去”细细的品味”,今天下定决心看个清楚。
【详细过程】:
设置:去掉忽略int3异常其它全部打勾。
载入前先写一点脚本方便后面分析代码.脚本如下:
repl eip,#E807000000????83C013EB0B58EB02????83C002EB01??50C3??#,#9090909090909090909090909090909090909090909090909090#,1000
repl eip,#E803000000??????58EB01??83C00750C3????#,#90909090909090909090909090909090909090#,1000
repl eip,#E808000000????83C00F50C3??5883C002FFE0??????#,#90909090909090909090909090909090909090909090#,1000
repl eip,#E8160000008B5C240C8BA3C4000000648F050000000083C404EB1464FF35000000006489250000000033C999F7F1??#,#9090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090#,1000
repl eip,#33F6E8100000008B642408648F050000000058EB13????64FF350000000064892500000000AD????#,#90909090909090909090909090909090909090909090909090909090909090909090909090909090#,1000
repl eip,#B904000000E81F000000????E816000000??EBF8????58EB09????E8F2FFFFFF????4975F1EB05EBF9EBF0??#,#9090909090909090909090909090909090909090909090909090909090909090909090909090909090909090#,1000
repl eip,#EB01??31F0EB0C33C8EB03EB09??59740575F851EBF1#,#90909090909090909090909090909090909090909090#,1000
ret
 
写完后用OD载入目标程序。
去掉垃圾代码然后在.Xikug那个段处下内存访问断点,F9运行之.到这里断下:
004A3121    E8 00000000       CALL 004A3126                            ; 这里壳代码开始处,上面的全部是垃圾代码来的
004A3126    5D                POP EBP
004A3127    81ED 26514000     SUB EBP,00405126                         ; 计算EBP的值
004A312D    89AD F6BD4000     MOV DWORD PTR SS:[EBP+40BDF6],EBP        ; 断下在这里
......
004A3149    8D85 60524000    LEA EAX,DWORD PTR SS:[EBP+405260]        ; 要解压的起始地址4a3260
004A314F    8D8D 04BA4000    LEA ECX,DWORD PTR SS:[EBP+40BA04]        ; INT3后面的JMP OEP代码结束地址4a9a04
004A3155    8D95 81974000    LEA EDX,DWORD PTR SS:[EBP+409781]        ; INT3异常后的起始地址4a7781
004A315B    EB 0B            JMP SHORT 004A3168
004A315D    8030 58          XOR BYTE PTR DS:[EAX],58                 ; 很简单的解密方式 opcode xor 58("X")而已
004A3160    3BC2             CMP EAX,EDX                              ; 判断是否为IN3后面的代码,如果是则解密后再 opcode xor 52加密,
004A3162    72 03            JB SHORT 004A3167                        ; 壳后面把自己当成调试器后再xor 52还原代码,这里跳就不会再加密代码
004A3164    8030 52          XOR BYTE PTR DS:[EAX],52
004A3167    40               INC EAX
004A3168    3BC1             CMP EAX,ECX                              ; 判断有没有解密完,没有则跳
004A316A  ^ 72 F1            JB SHORT 004A315D
 
到这里就可以先把4A7781到4a9a04处的代码复制下来:
 
33 C9 8B 9D FE C1 40 00 EB 15 FF 34 8B FF B5 F6 BD 40 00 FF B5 DE BD 40 00 E8 DE 78 FF FF 41 3B
8D FA C1 40 00 72 E3 E8 08 00 00 00 0F 01 83 C0 0F 50 C3 FF 58 83 C0 02 FF E0 0F 01 0C B9 04 00
......
E8 F2 FF FF FF 0F B9 49 75 F1 EB 05 EB F9 EB F0 D6 E8 07 00 00 00 C7 83 83 C0 13 EB 0B 58 EB 02
CD 20 83 C0 02 EB 01 E9 50 C3 E8 E8 08 00 00 00 0F 01 83 C0 0F 50 C3 FF 58 83 C0 02 FF E0 0F 01
0C EB 01 0F 31 F0 EB 0C 33 C8 EB 03 EB 09 0F 59 74 05 75 F8 51 EB F1 B9 04 00 00 00 E8 1F 00 00
00 EB FA E8 16 00 00 00 E9 EB F8 00 00 58 EB 09 0F 25 E8 F2 FF FF FF 0F B9 49 75 F1 EB 05 EB F9
EB F0 D6 C3
......
004A3260    8B4424 18       MOV EAX,DWORD PTR SS:[ESP+18]            ; 准备取KERNEL32.dll的hModule
004A3264    25 0000FFFF     AND EAX,FFFF0000                         ; 去除底位
004A3269    33D2            XOR EDX,EDX
004A326B    48              DEC EAX
004A326C    66:8B50 3C      MOV DX,WORD PTR DS:[EAX+3C]
004A3270    66:F7C2 00F0    TEST DX,0F000
004A3275  ^ 75 F4           JNZ SHORT 004A326B
004A3277    3B4402 34       CMP EAX,DWORD PTR DS:[EDX+EAX+34]
004A327B  ^ 75 EE           JNZ SHORT 004A326B                       ; 循环取出Kernel32.dll的hModule
004A327D    8985 CFBD4000   MOV DWORD PTR SS:[EBP+40BDCF],EAX        ; 取出的hModule入[4A9DCF]处
……
004A3299    8D85 AFBA4000   LEA EAX,DWORD PTR SS:[EBP+40BAAF]        ; 准备获取GetModuleHandleA的地址
004A329F    50              PUSH EAX                               ; /ProcNameOrOrdinal = "GetModuleHandleA"
004A32CC    FFB5 CFBD4000   PUSH DWORD PTR SS:[EBP+40BDCF]           ; |hModule = 7C800000 (kernel32)
004A32EC    E8 0FBDFFFF     CALL 0049F000                          ; /GetProcAddress
……
CALL 0049F000实际上就相当于GetProcAddress函数
进去看看:

0049F000    55              PUSH EBP
0049F001    8BEC            MOV EBP,ESP
0049F003    83C4 E8         ADD ESP,-18
0049F006    53              PUSH EBX
0049F007    51              PUSH ECX
0049F008    56              PUSH ESI
0049F009    57              PUSH EDI
0049F00A    8B45 08         MOV EAX,DWORD PTR SS:[EBP+8]             ; hModule
0049F00D    8B40 3C         MOV EAX,DWORD PTR DS:[EAX+3C]
0049F010    0345 08         ADD EAX,DWORD PTR SS:[EBP+8]             ; 定位PE头
0049F013    8945 FC         MOV DWORD PTR SS:[EBP-4],EAX
0049F016    8B5D 08         MOV EBX,DWORD PTR SS:[EBP+8]
0049F019    0358 78         ADD EBX,DWORD PTR DS:[EAX+78]            ; 定位输出表
0049F01C    895D F8         MOV DWORD PTR SS:[EBP-8],EBX
0049F01F    8BC3            MOV EAX,EBX
0049F021    8B58 1C         MOV EBX,DWORD PTR DS:[EAX+1C]
0049F024    035D 08         ADD EBX,DWORD PTR SS:[EBP+8]             ; 定位AddressOfFunctions
0049F027    895D F4         MOV DWORD PTR SS:[EBP-C],EBX
0049F02A    8B58 18         MOV EBX,DWORD PTR DS:[EAX+18]            ; 定位NumberOfNames
0049F02D    895D F0         MOV DWORD PTR SS:[EBP-10],EBX
0049F030    8B58 20         MOV EBX,DWORD PTR DS:[EAX+20]
0049F033    035D 08         ADD EBX,DWORD PTR SS:[EBP+8]             ; 定位AddressOfNames
0049F036    895D E8         MOV DWORD PTR SS:[EBP-18],EBX
0049F039    8B58 24         MOV EBX,DWORD PTR DS:[EAX+24]
0049F03C    035D 08         ADD EBX,DWORD PTR SS:[EBP+8]             ; AddressofNameOrdinals
0049F03F    895D EC         MOV DWORD PTR SS:[EBP-14],EBX
0049F042    33C9            XOR ECX,ECX
0049F044    33DB            XOR EBX,EBX
0049F046    8B75 0C         MOV ESI,DWORD PTR SS:[EBP+C]             ; 要取的API名字
0049F049    8B7D E8         MOV EDI,DWORD PTR SS:[EBP-18]
0049F04C    8B3C8F          MOV EDI,DWORD PTR DS:[EDI+ECX*4]
0049F04F    037D 08         ADD EDI,DWORD PTR SS:[EBP+8]
0049F052    8A043B          MOV AL,BYTE PTR DS:[EBX+EDI]
0049F055    3A0433          CMP AL,BYTE PTR DS:[EBX+ESI]
0049F058    75 0A           JNZ SHORT 0049F064
0049F05A    43              INC EBX
0049F05B    B0 00           MOV AL,0
0049F05D    3A0433          CMP AL,BYTE PTR DS:[EBX+ESI]
0049F060  ^ 75 F0           JNZ SHORT 0049F052
0049F062    74 08           JE SHORT 0049F06C
0049F064    33DB            XOR EBX,EBX
0049F066    41              INC ECX
0049F067    3B4D F0         CMP ECX,DWORD PTR SS:[EBP-10]
0049F06A  ^ 75 DD           JNZ SHORT 0049F049
0049F06C    8B7D F4         MOV EDI,DWORD PTR SS:[EBP-C]             ; 通过循环取出相关的API
0049F06F    8B048F          MOV EAX,DWORD PTR DS:[EDI+ECX*4]
0049F072    0345 08         ADD EAX,DWORD PTR SS:[EBP+8]             ; 取出的api转为VA
0049F075    5F              POP EDI
0049F076    5E              POP ESI
0049F077    59              POP ECX
0049F078    5B              POP EBX
0049F079    C9              LEAVE
0049F07A    C2 0800         RETN 8
以下是Xikug的MyGetProcAddress源码:
 
‘----------------------------------Xikug的GetAPIAddress Proc--------------------------
GetApiAddress PROC k32Base: DWORD, ApiName: DWORD
    LOCAL          baseImageNtHeaders: DWORD        ;ImageNtHeader基地址
       LOCAL          baseExportTable: DWORD                     ;Export表基地址
      
       ;;;;;;;;;;;;;IMAGE_EXPORT_DIRECTORY 的数据保存在下面的变量中;;;;;;;;;;;;;;;;
       LOCAL          AddressOfFunctions: DWORD
       LOCAL          NumberOfNames: DWORD
       LOCAL          AddressOfNameOrdinals: DWORD
       LOCAL          AddressOfNames: DWORD
      
       push              ebx
       push              ecx
       push              esi
       push              edi
      
       mov               eax, k32Base
       mov               eax, [eax + 3cH]                            ;Kernel32.dll 的 IMAGE_NT_HEADERS
       add                eax, k32Base
       mov               baseImageNtHeaders, eax     
     
    assume           eax: ptr IMAGE_NT_HEADERS
    mov               ebx, k32Base
    add                ebx, [eax].OptionalHeader.DataDirectory.VirtualAddress   
    assume           eax: nothing
    mov               baseExportTable, ebx
 
       mov               eax, ebx
       assume           eax: ptr IMAGE_EXPORT_DIRECTORY
       mov               ebx, [eax].AddressOfFunctions
       add                ebx, k32Base
       mov               AddressOfFunctions, ebx
       mov               ebx, [eax].NumberOfNames
       mov               NumberOfNames, ebx
       mov               ebx, [eax].AddressOfNames
       add                ebx, k32Base 
       mov               AddressOfNames, ebx
       mov               ebx, [eax].AddressOfNameOrdinals
       add                ebx, k32Base
       mov               AddressOfNameOrdinals, ebx      
       assume           eax: nothing             
 
 
       xor                ecx, ecx
       xor                ebx, ebx
 
       mov               esi, ApiName
                          
GetAPIName:
       mov               edi, AddressOfNames
       mov               edi, [edi + ecx * 4]
       add                edi, k32Base
 
CmpAPI:
    mov               al, [edi + ebx]
    cmp               al, [esi + ebx]
    jne                 GetNext
    inc                 ebx
    mov               al, 0
    cmp               al, [esi + ebx]
    jne                 CmpAPI
    je                   GetOK
GetNext:
    xor                ebx, ebx
    inc                 ecx
    cmp               ecx, NumberOfNames
    jne                 GetAPIName
         
GetOK:
 
;;;;;;;;;取得Api地址的Index;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;      xor                edx, edx
;      mov               ebx, AddressOfNameOrdinals
;      mov               dx, word ptr [ebx + ecx * 4]
 
 
       ;ecx为AddressOfFunctions中的索引
       ;在AddressOfFunctions中找到函数地址
       mov               edi, AddressOfFunctions
       mov               eax, [edi + ecx * 4]
       add                eax, k32Base
      
       ;平衡堆栈
       pop                edi
       pop                esi
       pop                ecx
       pop                ebx 
         
    ret
 
GetApiAddress endp
‘----------------------------------结束--------------------------
壳取以下些API的地址:
004A9AB4  64 75 6C 65 48 61 6E 64 6C 65 41 00 29 B5 80 7C  duleHandleA.)祤|
004A9AC4  4C 6F 61 64 4C 69 62 72 61 72 79 41 00 00 00 00  LoadLibraryA....
004A9AD4  00 47 65 74 50 72 6F 63 41 64 64 72 65 73 73 00  .GetProcAddress.
004A9AE4  00 00 00 00 47 6C 6F 62 61 6C 41 6C 6C 6F 63 00  ....GlobalAlloc.
004A9AF4  00 00 00 00 47 6C 6F 62 61 6C 46 72 65 65 00 00  ....GlobalFree..
004A9B04  00 00 00 55 6E 68 61 6E 64 6C 65 64 45 78 63 65  ...UnhandledExce
004A9B14  70 74 69 6F 6E 46 69 6C 74 65 72 00 00 00 00 00  ptionFilter.....
004A9B24  47 65 74 4D 6F 64 75 6C 65 46 69 6C 65 4E 61 6D  GetModuleFileNam
004A9B34  65 41 00 00 00 00 00 45 78 69 74 50 72 6F 63 65  eA.....ExitProce
004A9B44  73 73 00 00 00 00 00 43 72 65 61 74 65 50 72 6F  ss.....CreatePro
004A9B54  63 65 73 73 00 00 00 00 00 57 61 69 74 46 6F 72  cess.....WaitFor
004A9B64  44 65 62 75 67 45 76 65 6E 74 00 00 00 00 00 43  DebugEvent.....C
004A9B74  6F 6E 74 69 6E 75 65 44 65 62 75 67 45 76 65 6E  ontinueDebugEven
004A9B84  74 00 00 00 00 00 47 65 74 43 6F 6D 6D 61 6E 64  t.....GetCommand
004A9B94  4C 69 6E 65 00 00 00 00 00 6C 73 74 72 6C 65 6E  Line.....lstrlen
004A9BA4  00 00 00 00 00 6C 73 74 72 63 70 79 00 00 00 00  .....lstrcpy....
004A9BB4  00 4D 65 73 73 61 67 65 42 6F 78 41 00 00 00 00  .MessageBoxA....
004A9BC4  00 52 74 6C 5A 65 72 6F 4D 65 6D 6F 72 79 00 00  .RtlZeroMemory..
004A9BD4  00 00 00 43 72 65 61 74 65 54 6F 6F 6C 68 65 6C  ...CreateToolhel
004A9BE4  70 33 32 53 6E 61 70 73 68 6F 74 00 00 00 00 00  p32Snapshot.....
004A9BF4  50 72 6F 63 65 73 73 33 32 46 69 72 73 74 00 00  Process32First..
004A9C04  00 00 00 50 72 6F 63 65 73 73 33 32 4E 65 78 74  ...Process32Next
004A9C14  00 00 00 00 00 47 65 74 43 75 72 72 65 6E 74 50  .....GetCurrentP
004A9C24  72 6F 63 65 73 73 49 64 00 00 00 00 00 4F 70 65  rocessId.....Ope
004A9C34  6E 50 72 6F 63 65 73 73 00 00 00 00 00 43 6C 6F  nProcess.....Clo
004A9C44  73 65 48 61 6E 64 6C 65 00 00 00 00 00 52 65 61  seHandle.....Rea
004A9C54  64 50 72 6F 63 65 73 73 4D 65 6D 6F 72 79 00 00  dProcessMemory..
004A9C64  00 00 00 47 65 74 54 68 72 65 61 64 43 6F 6E 74  ...GetThreadCont
004A9C74  65 78 74 00 00 00 00 00 53 65 74 54 68 72 65 61  ext.....SetThrea
004A9C84  64 43 6F 6E 74 65 78 74 00 00 00 00 00 57 72 69  dContext.....Wri
004A9C94  74 65 50 72 6F 63 65 73 73 4D 65 6D 6F 72 79 00  teProcessMemory.
004A9CA4  00 00 00 00 46 6C 75 73 68 49 6E 73 74 72 75 63  ....FlushInstruc
004A9CB4  74 69 6F 6E 43 61 63 68 65 00 00                 tionCache..
获取到GetProcAddress的地址后,直接用GetProcAddress函数获取相关API:
……
004A3B8F    FF95 E4BA4000   CALL DWORD PTR SS:[EBP+40BAE4]           ; kernel32.GetProcAddress
004A3B95    8985 4DBC4000   MOV DWORD PTR SS:[EBP+40BC4D],EAX
……
004A3FED    6A 00           PUSH 0                                   ; /ProcessID = 0
004A3FEF    6A 02           PUSH 2                                   ; |Flags = TH32CS_SNAPPROCESS
004A3FF1    FF95 F0BB4000   CALL DWORD PTR SS:[EBP+40BBF0]           ; /CreateToolhelp32Snapshot
004A3FF7    8985 FBC24000   MOV DWORD PTR SS:[EBP+40C2FB],EAX        ; HANDLE(10)保存到[4aa2fb]
004A3FFD    50              PUSH EAX
……
004A4018    58              POP EAX
004A4019    83F8 FF         CMP EAX,-1                               ; 如果CreateToolhelp32Snapshot失败则退出程序
004A401C    75 01           JNZ SHORT 004A401F                       ; 成功则跳
……
004A408A    8DBD 03C34000   LEA EDI,DWORD PTR SS:[EBP+40C303]        ; 填充PROCESSENTRY32 结构
004A4090    C707 28010000   MOV DWORD PTR DS:[EDI],128               ; 结构大小
004A4096  PUSH EDI                               ; /pProcessentry =004AA303
004A40C3  PUSH DWORD PTR SS:[EBP+40C2FB]      ; |hSnapshot = 00000010
004A40C9  CALL DWORD PTR SS:[EBP+40BC03]      ; /Call Process32First
……
004A40EB    0BC0            OR EAX,EAX
004A40ED    75 0D           JNZ SHORT 004A40FC                       ; 如果函数成功则跳
004A40EF    FFB5 FBC24000   PUSH DWORD PTR SS:[EBP+40C2FB]           ; 不成功就CloseHandle并结束程序
004A40F5    FF95 4DBC4000   CALL DWORD PTR SS:[EBP+40BC4D]
004A40FB    C3              RETN
……
004A4167    FF95 2DBC4000   CALL DWORD PTR SS:[EBP+40BC2D]           ; GetCurrentProcessId获取当前进程ID
004A416D    3947 08         CMP DWORD PTR DS:[EDI+8],EAX
004A4170    0F85 111A0000   JNZ 004A5B87                             ; 如果不是没有找到当前进程则跳
004A4176    8B47 18         MOV EAX,DWORD PTR DS:[EDI+18]            ; 获取父进程的ID
004A4179    8985 3EC24000   MOV DWORD PTR SS:[EBP+40C23E],EAX        ; 父进程ID保存到[4AA23E处
004A417F    FF77 18         PUSH DWORD PTR DS:[EDI+18]               ; /ProcessId = 3E0
004A4182    6A 00           PUSH 0                                   ; |Inheritable = FALSE
004A4184    68 FF0F1F00     PUSH 1F0FFF                              ; |Access = PROCESS_ALL_ACCESS
004A4189    FF95 3DBC4000   CALL DWORD PTR SS:[EBP+40BC3D]           ; /CALL OpenProcess
004A418F    8985 FFC24000   MOV DWORD PTR SS:[EBP+40C2FF],EAX        ; openProcHandle 保存到[4AA2FF]处
004A4195    0BC0            OR EAX,EAX
004A4197    0F84 E6190000   JE 004A5B83                              ; 如果打开进程失败则跳下去
004A419D    8D85 B4114000   LEA EAX,DWORD PTR SS:[EBP+4011B4]        ; 这里开始利用SEH处理读内存可能产生的异常
004A41A3    50              PUSH EAX                                 ; 这里是一个Anti-Deubg
004A41A4    64:FF35 0000000>PUSH DWORD PTR FS:[0]
004A41AB    64:8925 0000000>MOV DWORD PTR FS:[0],ESP
004A41B2    55              PUSH EBP
004A41B3    6A 00           PUSH 0                                   ; /pBytesRead = NULL
004A41B5    6A 40           PUSH 40                                  ; |BytesToRead = 40 (64.)
004A41B7    8D85 2BC44000   LEA EAX,DWORD PTR SS:[EBP+40C42B]        ; |
004A41BD    50              PUSH EAX                                 ; |Buffer = Explorer.004AA42B
004A41BE    68 00000010     PUSH 10000000                            ; |pBaseAddress = 10000000
004A41C3    FFB5 FFC24000   PUSH DWORD PTR SS:[EBP+40C2FF]           ; |hProcess = 0000001C
004A41C9    FF95 63BC4000   CALL DWORD PTR SS:[EBP+40BC63]           ; /ReadProcessMemory
004A41CF    5D              POP EBP                                  ; UnSeh
004A41D0    33DB            XOR EBX,EBX
004A41D2    64:8F03         POP DWORD PTR FS:[EBX]
004A41D5    83C4 04         ADD ESP,4
004A41D8    50              PUSH EAX                                 ; 如果读取成功则EAX为1
004A41D9    51              PUSH ECX
……
004A5B4E    8D47 24         LEA EAX,DWORD PTR DS:[EDI+24]            ; ;获取程序本身的进程名
004A5B51    8A0401          MOV AL,BYTE PTR DS:[ECX+EAX]             ; 依次取出每一位字符
004A5B54    0AC0            OR AL,AL
004A5B56    75 02           JNZ SHORT 004A5B5A                       ; 如果没有获取完则跳
004A5B58    EB 13           JMP SHORT 004A5B6D
004A5B5A    24 0F           AND AL,0F                                ; 取出的每一位and 0F后查表
004A5B5C    8D9D 2EC24000   LEA EBX,DWORD PTR SS:[EBP+40C22E]
004A5B62    D7              XLAT BYTE PTR DS:[EBX+AL]
004A5B63    888429 C2BC4000 MOV BYTE PTR DS:[ECX+EBP+40BCC2],AL      ; 查到后保存到[4a9cc2]处
004A5B6A    41              INC ECX
004A5B6B  ^ EB E1           JMP SHORT 004A5B4E                       ; 没有取完则继续上去计算加密值
004A5B6D    59              POP ECX
004A5B6E    58              POP EAX
004A5B6F    83F8 01         CMP EAX,1                                ; 这里判断读取内存是否成功,不成功则跳
004A5B72    75 0B           JNZ SHORT 004A5B7F
004A5B74    C685 3DC24000 0>MOV BYTE PTR SS:[EBP+40C23D],1           ; 成功则在[4AA23D]处做个标记
004A5B7B   /EB 1F           JMP SHORT 004A5B9C                       ; 如果读取内存成功则利用CloseHandle(xx)使调试器异常
‘-----------------------------------------------------
004A5BB6    FFB5 FFC24000   PUSH DWORD PTR SS:[EBP+40C2FF]           ; /hObject = 0000001C                    ; 这里改成 0, 否则异常
004A5BE5    FF95 4DBC4000   CALL DWORD PTR SS:[EBP+40BC4D]           ; /CloseHandle
‘--------------------------------------------------------
004A5B7D   /EB 08           JMP SHORT 004A5B87
004A5B7F   |EB 1B           JMP SHORT 004A5B9C
004A5B81   |EB 04           JMP SHORT 004A5B87
004A5B83   |EB 17           JMP SHORT 004A5B9C
004A5B85   |EB 00           JMP SHORT 004A5B87
004A5B87   /57              PUSH EDI                                 ; /pProcessentry = Explorer.004AA303
004A5B88    FFB5 FBC24000   PUSH DWORD PTR SS:[EBP+40C2FB]           ; |hSnapshot = 00000010
004A5B8E    FF95 15BC4000   CALL DWORD PTR SS:[EBP+40BC15]           ; /CALL Process32Next
004A5B94    0BC0            OR EAX,EAX
004A5B96  ^ 0F85 CBE5FFFF   JNZ 004A4167                             ; 如果没有枚举完进程则跳回去继续
……
第一次计算加密的方法就是取出进程名的每一位,然后把取出的字符and 0F后的值就是在
&ad$.8=CCD[[VTQ中的第几位.
第一次计算后的值为:8C&V.d8dQ8C8
……
004A5BEB    57              PUSH EDI                                 ; /pProcessentry = Explorer.004AA303
004A5C18    FFB5 FBC24000   PUSH DWORD PTR SS:[EBP+40C2FB]           ; |hSnapshot = 00000010
004A5C1E    FF95 03BC4000   CALL DWORD PTR SS:[EBP+40BC03]           ; /Process32First
……
004A5C40    0BC0            OR EAX,EAX
004A5C42    75 0D           JNZ SHORT 004A5C51                       ; 如果函数成功则跳
004A5C44    FFB5 FBC24000   PUSH DWORD PTR SS:[EBP+40C2FB]           ; 否则关闭对象然后退出程序
004A5C4A    FF95 4DBC4000   CALL DWORD PTR SS:[EBP+40BC4D]
004A5C50    C3              RETN
004A5C51    8B85 3EC24000   MOV EAX,DWORD PTR SS:[EBP+40C23E]        ; 父进程ID入EAX
004A5C57    3947 08         CMP DWORD PTR DS:[EDI+8],EAX
004A5C5A    0F85 A0000000   JNZ 004A5D00                             ; 如果不是父进程ID则跳下去继续
004A5C60    BA 00000000     MOV EDX,0
004A5C65    33C9            XOR ECX,ECX
004A5C67    8D47 24         LEA EAX,DWORD PTR DS:[EDI+24]            ; 获取父进程的进程名
004A5C6A    8A0401          MOV AL,BYTE PTR DS:[ECX+EAX]             ; 依次取出父进程的每一位
004A5C6D    0AC0            OR AL,AL
004A5C6F    75 02           JNZ SHORT 004A5C73                       ; 如果没有取完则跳
004A5C71    EB 1C           JMP SHORT 004A5C8F
004A5C73    24 0F           AND AL,0F
004A5C75    8D9D 2EC24000   LEA EBX,DWORD PTR SS:[EBP+40C22E]
004A5C7B    D7              XLAT BYTE PTR DS:[EBX+AL]                ; 查表
004A5C7C    328429 C2BC4000 XOR AL,BYTE PTR DS:[ECX+EBP+40BCC2]      ; 查表后的值和上面计算自己进程名的值xor
004A5C83    0AC0            OR AL,AL                                 ; 其中有一位不同
004A5C85    74 05           JE SHORT 004A5C8C                        ; 如果相等就跳
004A5C87    BA 01000000     MOV EDX,1                                ; 不同则edx设置为1
004A5C8C    41              INC ECX
004A5C8D  ^ EB D8           JMP SHORT 004A5C67
004A5C8F    83FA 01         CMP EDX,1                                ; 比较如果不相同的话就不跳
004A5C92    75 6C           JNZ SHORT 004A5D00                       ; 如果用OD来调试的子进程话这里就一定要跳,否则后面不会跳去正确的OEP处
……
004A5CAA    BE 9A7C4000     MOV ESI,00407C9A
004A5CC9    81EE FF000000   SUB ESI,0FF
004A5CCF    03F5            ADD ESI,EBP
……
004A5CE7    C706 E77D4000   MOV DWORD PTR DS:[ESI],00407DE7          ; 这几句不知道是什么意思:-(
004A5CED    83C6 1F         ADD ESI,1F
004A5CF0    8906            MOV DWORD PTR DS:[ESI],EAX
004A5CF2    FFB5 FFC24000   PUSH DWORD PTR SS:[EBP+40C2FF]           ; /hObject = 0000001C
004A5CF8    FF95 4DBC4000   CALL DWORD PTR SS:[EBP+40BC4D]           ; /CloseHandle
004A5CFE    EB 15           JMP SHORT 004A5D15
004A5D00    57              PUSH EDI                                 ; /pProcessentry = Explorer.004AA303
004A5D01    FFB5 FBC24000   PUSH DWORD PTR SS:[EBP+40C2FB]           ; |hSnapshot = 00000010
004A5D07    FF95 15BC4000   CALL DWORD PTR SS:[EBP+40BC15]           ; /Process32Next
004A5D0D    0BC0            OR EAX,EAX
004A5D0F  ^ 0F85 3CFFFFFF   JNZ 004A5C51                             ; 如果没有枚举完则继续
……
004A5D2F    FFB5 FBC24000   PUSH DWORD PTR SS:[EBP+40C2FB]           ; /hObject = 00000010
004A5D5E    FF95 4DBC4000   CALL DWORD PTR SS:[EBP+40BC4D]           ; /CloseHandle关闭对象
 
到这里为些壳的 ANTI-Debug 就结束了。
 
……
004A5D7A    FF95 99BB4000   CALL DWORD PTR SS:[EBP+40BB99]           ; 获取命令行
004A5D80    50              PUSH EAX
004A5D81    90              NOP
004A5D82    90              NOP
……
004A5DAD    5A              POP EDX                                  ; 00141EE0
004A5DAE    8BF2            MOV ESI,EDX
004A5DB0    90              NOP
……
004A5DC6    803E 58         CMP BYTE PTR DS:[ESI],58                 ; 比较命令行第一个字符是否为"X",调试标志
004A5DC9    75 2E           JNZ SHORT 004A5DF9                       ; 不是则跳
……
004A5DF7   /EB 6B           JMP SHORT 004A5E64                       ; 如果是子进程则跳去解壳部分
……
004A5E0F    90              NOP
004A5E10    90              NOP                                      ; 准备获取程序的完整路径名
004A5E11    90              NOP
004A5E12    90              NOP
004A5E13    68 00010000     PUSH 100                                 ; /BufSize = 100 (256.)
004A5E18    8D85 C2BC4000   LEA EAX,DWORD PTR SS:[EBP+40BCC2]        ; |
004A5E1E    50              PUSH EAX                                 ; |PathBuffer = Explorer.004A9CC2
004A5E1F    6A 00           PUSH 0                                   ; |hModule = NULL
004A5E21    FF95 37BB4000   CALL DWORD PTR SS:[EBP+40BB37]           ; /GetModuleFileNameA
004A5E27    90              NOP
……
004A5E3A    8D85 C2BC4000   LEA EAX,DWORD PTR SS:[EBP+40BCC2]
004A5E40    50              PUSH EAX                                 ; 获取到的程序完整路径名入栈
004A5E41    E8 1196FFFF     CALL 0049F457                            ; 这里跟进就是Shell Application(debug process)
跟进去看看:
0049F457    55              PUSH EBP                                 ; 进来CreateProcess部分
0049F458    8BEC            MOV EBP,ESP
0049F45A    60              PUSHAD
0049F45B    8B7D 08         MOV EDI,DWORD PTR SS:[EBP+8]             ; 程序完整路径存放地址入edi
0049F45E    E8 00000000     CALL 0049F463
0049F463    5B              POP EBX
0049F464    81EB 63144000   SUB EBX,00401463                         ; 获取重定位地址
0049F46A    B8 44000000     MOV EAX,44                               ; 准备申请内存空间
0049F46F    50              PUSH EAX                                 ; /Length = 44 (68.)
0049F470    8D83 42C24000   LEA EAX,DWORD PTR DS:[EBX+40C242]        ; |
0049F476    50              PUSH EAX                                 ; |Destination = Explorer.004AA242
0049F477    FF93 D3BB4000   CALL DWORD PTR DS:[EBX+40BBD3]           ; /RtlZeroMemory
0049F47D    B8 10000000     MOV EAX,10
0049F482    50              PUSH EAX                                 ; /Length = 10 (16.)
0049F483    8D83 86C24000   LEA EAX,DWORD PTR DS:[EBX+40C286]        ; |
0049F489    50              PUSH EAX                                 ; |Destination = Explorer.004AA286
0049F48A    FF93 D3BB4000   CALL DWORD PTR DS:[EBX+40BBD3]           ; /RtlZeroMemory
0049F490    B8 44000000     MOV EAX,44                               ; 准备CreateProcessA调试子进程
0049F495    8983 42C24000   MOV DWORD PTR DS:[EBX+40C242],EAX
0049F49B    8D83 86C24000   LEA EAX,DWORD PTR DS:[EBX+40C286]
0049F4A1    50              PUSH EAX                                 ; /pProcessInfo = Explorer.004AA286
0049F4A2    8D83 42C24000   LEA EAX,DWORD PTR DS:[EBX+40C242]        ; |
0049F4A8    50              PUSH EAX                                 ; |pStartupInfo = Explorer.004AA242
0049F4A9    6A 00           PUSH 0                                   ; |CurrentDir = NULL
0049F4AB    6A 00           PUSH 0                                   ; |pEnvironment = NULL
0049F4AD    B8 01000000     MOV EAX,1                                ; |
0049F4B2    83C8 02         OR EAX,2                                 ; |
0049F4B5    50              PUSH EAX                                 ; |CreationFlags = DEBUG_PROCESS|DEBUG_ONLY_THIS_PROCESS
0049F4B6    6A 00           PUSH 0                                   ; |InheritHandles = FALSE
0049F4B8    6A 00           PUSH 0                                   ; |pThreadSecurity = NULL
0049F4BA    6A 00           PUSH 0                                   ; |pProcessSecurity = NULL
0049F4BC    8D83 C2BD4000   LEA EAX,DWORD PTR DS:[EBX+40BDC2]        ; |
0049F4C2    50              PUSH EAX                                 ; |CommandLine = "X"
0049F4C3    57              PUSH EDI                                 ; |ModuleFileName = "D:/Explorer.exe"
0049F4C4    FF93 59BB4000   CALL DWORD PTR DS:[EBX+40BB59]           ; /CreateProcessA
0049F4CA    83F8 01         CMP EAX,1
0049F4CD    0F85 87010000   JNZ 0049F65A                             ; 如果创建进程失败则退出程序
0049F4D3    8DBB 64C54000   LEA EDI,DWORD PTR DS:[EBX+40C564]
0049F4D9    C707 07000100   MOV DWORD PTR DS:[EDI],10007
0049F4DF    810F 10000100   OR DWORD PTR DS:[EDI],10010
0049F4E5    8D83 96C24000   LEA EAX,DWORD PTR DS:[EBX+40C296]
0049F4EB    68 A00F0000     PUSH 0FA0                                ; /Timeout = 4000. ms
0049F4F0    50              PUSH EAX                                 ; |pDebugEvent = Explorer.004AA296
0049F4F1    FF93 6FBB4000   CALL DWORD PTR DS:[EBX+40BB6F]           ; /WaitForDebugEvent
0049F4F7    83F8 01         CMP EAX,1
0049F4FA    0F85 55010000   JNZ 0049F655                             ; 如果 EAX ==FALSE则跳下一步
0049F500    8D93 96C24000   LEA EDX,DWORD PTR DS:[EBX+40C296]        ; DebugEvent
0049F506    8DB3 86C24000   LEA ESI,DWORD PTR DS:[EBX+40C286]        ; pi
0049F50C    833A 03         CMP DWORD PTR DS:[EDX],3                 ; CREATE_PROCESS_DEBUG_EVENT
0049F50F    75 16           JNZ SHORT 0049F527                       ; 如果调试动作不为CREATE_PROCESS_DEBUG_EVENT则跳
0049F511    68 02000100     PUSH 10002                               ; /ContinueStatus = DBG_CONTINUE
0049F516    FF72 08         PUSH DWORD PTR DS:[EDX+8]                ; |ThreadId = 214
0049F519    FF72 04         PUSH DWORD PTR DS:[EDX+4]                ; |ProcessId = 57C
0049F51C    FF93 86BB4000   CALL DWORD PTR DS:[EBX+40BB86]           ; /ContinueDebugEvent
0049F522    E9 2E010000     JMP 0049F655
0049F527    833A 01         CMP DWORD PTR DS:[EDX],1                 ;  判断有没有发生异常EXCEPTION_DEBUG_EVENT
0049F52A    0F85 0B010000   JNZ 0049F63B                             ; 如果没有则跳
0049F530    817A 0C 0300008>CMP DWORD PTR DS:[EDX+C],80000003        ; 判断是否为int3断点异常,如果不是则跳去继续
0049F537    0F85 EB000000   JNZ 0049F628
0049F53D    83BB F7C24000 0>CMP DWORD PTR DS:[EBX+40C2F7],0          ; 判断是否为调试入口异常
0049F544    75 1C           JNZ SHORT 0049F562                       ; 也就是说壳的第一次断点异常为入口断点异常,忽略
0049F546    FF83 F7C24000   INC DWORD PTR DS:[EBX+40C2F7]            ; Debug Step+1
0049F54C    68 02000100     PUSH 10002                               ; /ContinueStatus = DBG_CONTINUE
0049F551    FF72 08         PUSH DWORD PTR DS:[EDX+8]                ; |ThreadId = 214
0049F554    FF72 04         PUSH DWORD PTR DS:[EDX+4]                ; |ProcessId = 57C
0049F557    FF93 86BB4000   CALL DWORD PTR DS:[EBX+40BB86]           ; /ContinueDebugEvent
0049F55D    E9 F3000000     JMP 0049F655                             ; 跳去ContinueDebugEvent
0049F562    83BB F7C24000 0>CMP DWORD PTR DS:[EBX+40C2F7],1          ; 第二次int3异常
0049F569    0F85 A6000000   JNZ 0049F615
0049F56F    52              PUSH EDX
0049F570    FF83 F7C24000   INC DWORD PTR DS:[EBX+40C2F7]            ; debug step+1
0049F576    8DBB 64C54000   LEA EDI,DWORD PTR DS:[EBX+40C564]
0049F57C    57              PUSH EDI                                 ; /pContext = Explorer.004AA564
0049F57D    FF76 04         PUSH DWORD PTR DS:[ESI+4]                ; |hThread = 00000038 (window)
0049F580    FF93 78BC4000   CALL DWORD PTR DS:[EBX+40BC78]           ; /GetThreadContext
0049F586    8B8F B8000000   MOV ECX,DWORD PTR DS:[EDI+B8]            ; 获取异常地址(4A7781)
0049F58C    51              PUSH ECX
0049F58D    6A 00           PUSH 0                                   ; /pBytesRead = NULL
0049F58F    6A 01           PUSH 1                                   ; |BytesToRead = 1
0049F591    8D83 F6C24000   LEA EAX,DWORD PTR DS:[EBX+40C2F6]        ; |
0049F597    50              PUSH EAX                                 ; |Buffer = Explorer.004AA2F6
0049F598    51              PUSH ECX                                 ; |pBaseAddress = 4A7781
0049F599    FF36            PUSH DWORD PTR DS:[ESI]                  ; |hProcess = 00000034
0049F59B    FF93 63BC4000   CALL DWORD PTR DS:[EBX+40BC63]           ; /ReadProcessMemory
0049F5A1    59              POP ECX
0049F5A2    8D83 F6C24000   LEA EAX,DWORD PTR DS:[EBX+40C2F6]
0049F5A8    8A00            MOV AL,BYTE PTR DS:[EAX]
0049F5AA    34 52           XOR AL,52
0049F5AC    8883 F6C24000   MOV BYTE PTR DS:[EBX+40C2F6],AL
0049F5B2    51              PUSH ECX
0049F5B3    6A 00           PUSH 0                                   ; /pBytesWritten = NULL
0049F5B5    6A 01           PUSH 1                                   ; |BytesToWrite = 1
0049F5B7    8D83 F6C24000   LEA EAX,DWORD PTR DS:[EBX+40C2F6]        ; |
0049F5BD    50              PUSH EAX                                 ; |Buffer = Explorer.004AA2F6
0049F5BE    51              PUSH ECX                                 ; |Address = 4A7781
0049F5BF    FF36            PUSH DWORD PTR DS:[ESI]                  ; |hProcess = 00000034
0049F5C1    FF93 A4BC4000   CALL DWORD PTR DS:[EBX+40BCA4]           ; /WriteProcessMemory
0049F5C7    59              POP ECX
0049F5C8    8D83 04BA4000   LEA EAX,DWORD PTR DS:[EBX+40BA04]        ; 结束地址4A9A04
0049F5CE    41              INC ECX
0049F5CF    3BC8            CMP ECX,EAX
0049F5D1    75 02           JNZ SHORT 0049F5D5                       ; 判断有没有结束,没有结束则跳回去继续
0049F5D3    EB 02           JMP SHORT 0049F5D7
0049F5D5  ^ EB B5           JMP SHORT 0049F58C
0049F5D7    51              PUSH ECX
0049F5D8    8B87 B8000000   MOV EAX,DWORD PTR DS:[EDI+B8]
0049F5DE    8987 B8000000   MOV DWORD PTR DS:[EDI+B8],EAX
0049F5E4    57              PUSH EDI                                 ; /pContext = Explorer.004AA564
0049F5E5    FF76 04         PUSH DWORD PTR DS:[ESI+4]                ; |hThread = 00000038 (window)
0049F5E8    FF93 8DBC4000   CALL DWORD PTR DS:[EBX+40BC8D]           ; /SetThreadContext
0049F5EE    8B87 B8000000   MOV EAX,DWORD PTR DS:[EDI+B8]
0049F5F4    59              POP ECX
0049F5F5    2BC8            SUB ECX,EAX
0049F5F7    51              PUSH ECX                                 ; /RegionSize = 2283
0049F5F8    50              PUSH EAX                                 ; |RegionBase = Explorer.004A7781
0049F5F9    FF36            PUSH DWORD PTR DS:[ESI]                  ; |hProcess = 00000034
0049F5FB    FF93 BEBC4000   CALL DWORD PTR DS:[EBX+40BCBE]           ; /FlushInstructionCache
0049F601    5A              POP EDX
0049F602    68 02000100     PUSH 10002                               ; /ContinueStatus = DBG_CONTINUE
0049F607    FF72 08         PUSH DWORD PTR DS:[EDX+8]                ; |ThreadId = 214
0049F60A    FF72 04         PUSH DWORD PTR DS:[EDX+4]                ; |ProcessId = 57C
0049F60D    FF93 86BB4000   CALL DWORD PTR DS:[EBX+40BB86]           ; /ContinueDebugEvent
0049F613    EB 40           JMP SHORT 0049F655
0049F615    68 01000180     PUSH 80010001                            ; /DBG_EXCEPTION_NOT_HANDLED
0049F61A    FF72 08         PUSH DWORD PTR DS:[EDX+8]                ; |dwThreadId
0049F61D    FF72 04         PUSH DWORD PTR DS:[EDX+4]                ; |dwProcessId
0049F620    FF93 86BB4000   CALL DWORD PTR DS:[EBX+40BB86]           ; /ContinueDebugEvent
0049F626    EB 2D           JMP SHORT 0049F655
0049F628    68 01000180     PUSH 80010001                            ; /DBG_EXCEPTION_NOT_HANDLED
0049F62D    FF72 08         PUSH DWORD PTR DS:[EDX+8]                ; |dwThreadId
0049F630    FF72 04         PUSH DWORD PTR DS:[EDX+4]                ; |dwProcessId
0049F633    FF93 86BB4000   CALL DWORD PTR DS:[EBX+40BB86]           ; /ContinueDebugEvent
0049F639    EB 1A           JMP SHORT 0049F655
0049F63B    833A 05         CMP DWORD PTR DS:[EDX],5
0049F63E    75 04           JNZ SHORT 0049F644
0049F640    EB 18           JMP SHORT 0049F65A
0049F642    EB 11           JMP SHORT 0049F655
0049F644    68 02000100     PUSH 10002                               ; /ContinueStatus = DBG_CONTINUE
0049F649    FF72 08         PUSH DWORD PTR DS:[EDX+8]                ; |dwThreadId
0049F64C    FF72 04         PUSH DWORD PTR DS:[EDX+4]                ; |dwProcessId
0049F64F    FF93 86BB4000   CALL DWORD PTR DS:[EBX+40BB86]           ; /ContinueDebugEvent
0049F655  ^ E9 8BFEFFFF     JMP 0049F4E5
0049F65A    61              POPAD
0049F65B    C9              LEAVE
0049F65C    C2 0400         RETN 4
004A5E5B    90              NOP                                      ; 调试完程序结束
004A5E5C    6A 00           PUSH 0                                   ; /Exit Code = 0
004A5E5E    FF95 47BB4000   CALL DWORD PTR SS:[EBP+40BB47]           ; /ExitProcess
 
到这里我们可以总结一下 : 壳只用了一个 anti-debug, 然后通过调试标志 ’X’ 判断是否为子进程。壳只处理 INT3 异常,异常时把从 4A7781 4A9A04 处的代码 xor 52 还原出正确代码。
现在再写一段脚本用于直接跳为单进程的方式:
var addr
start:
  gpa "GetProcAddress","kernel32.dll"
  bp $RESULT
 
 
lbl1:
  run
 
lbl2:
  mov addr,esp
  add addr,8
  mov addr,[addr]
  mov addr,[addr]
  cmp addr,73756c46
  jne lbl1
  bc $RESULT
  rtu
 
lbl3:
  mov addr,eip
  add addr,6
  asm addr,"jmp 004A5D7A"
  sto
  sto
  mov [addr],#E803000000#
  sto
  mov [eax],#58#
  run
  ret
重新来过,并运行上面的脚本,然后到这里:
004A5E7A    E8 1E98FFFF     CALL 0049F69D                            ; ;初始化CRC32表
跟进看看:
0049F69D    60              PUSHAD
0049F69E    E8 00000000     CALL 0049F6A3
0049F6A3    5B              POP EBX
0049F6A4    81EB A3164000   SUB EBX,004016A3                         ; 计算重定位值
0049F6AA    B9 00010000     MOV ECX,100
0049F6AF    BA 2083B8ED     MOV EDX,EDB88320
0049F6B4    8D41 FF         LEA EAX,DWORD PTR DS:[ECX-1]
0049F6B7    51              PUSH ECX
0049F6B8    B9 08000000     MOV ECX,8
0049F6BD    D1E8            SHR EAX,1
0049F6BF    73 02           JNB SHORT 0049F6C3
0049F6C1    33C2            XOR EAX,EDX
0049F6C3    49              DEC ECX
0049F6C4  ^ 75 F7           JNZ SHORT 0049F6BD
0049F6C6    59              POP ECX
0049F6C7    8DBB FABD4000   LEA EDI,DWORD PTR DS:[EBX+40BDFA]
0049F6CD    89448F FC       MOV DWORD PTR DS:[EDI+ECX*4-4],EAX       0049F6D1    49              DEC ECX
0049F6D2  ^ 75 E0           JNZ SHORT 0049F6B4
0049F6D4    61              POPAD
0049F6D5    C3              RETN
……
004A5E99    E8 00000000     CALL 004A5E9E
004A5E9E    90              NOP
004A5E9F    90              NOP
004A5EA0    90              NOP
004A5EA1    90              NOP
004A5EA2    59              POP ECX
004A5EA3    81E9 9E7E4000   SUB ECX,00407E9E
004A5EA9    BB 0B174000     MOV EBX,0040170B
004A5EAE    03D9            ADD EBX,ECX                              ; 计算出壳的EP
004A5EB0    B9 93670000     MOV ECX,6793
004A5EB5    E8 1C98FFFF     CALL 0049F6D6                            ; 这里进去计算crc值
004A5EBA    8985 2AC24000   MOV DWORD PTR SS:[EBP+40C22A],EAX        ; CRC值保存到[4AA22A处
……
004A5F1C    6A 00              PUSH 0                                   ; /phModule = 0
004A5F1E    FF95 C0BA4000      CALL DWORD PTR SS:[EBP+40BAC0]           ; /GetModuleHandleA
004A5F24    8985 DEBD4000      MOV DWORD PTR SS:[EBP+40BDDE],EAX        ; phModule保存到[004A9DDE]处
004A5F2A    8B58 3C            MOV EBX,DWORD PTR DS:[EAX+3C]            ; 定位pe头
004A5F2D    039D DEBD4000      ADD EBX,DWORD PTR SS:[EBP+40BDDE]
004A5F33    899D E2BD4000      MOV DWORD PTR SS:[EBP+40BDE2],EBX
004A5F39    8B85 E2BD4000      MOV EAX,DWORD PTR SS:[EBP+40BDE2]
004A5F3F    05 F8000000        ADD EAX,0F8
004A5F44    8985 E6BD4000      MOV DWORD PTR SS:[EBP+40BDE6],EAX        ; 定位Section name
004A5F4A    8B58 0C            MOV EBX,DWORD PTR DS:[EAX+C]             ; Section Voffset=1000
004A5F4D    039D DEBD4000      ADD EBX,DWORD PTR SS:[EBP+40BDDE]
004A5F53    899D EABD4000      MOV DWORD PTR SS:[EBP+40BDEA],EBX
004A5F59    8B58 08            MOV EBX,DWORD PTR DS:[EAX+8]             ; Vsize=73000
004A5F5C    899D EEBD4000      MOV DWORD PTR SS:[EBP+40BDEE],EBX
004A5F62    8B58 10            MOV EBX,DWORD PTR DS:[EAX+10]            ; Rsize=31c00
004A5F65    899D F2BD4000      MOV DWORD PTR SS:[EBP+40BDF2],EBX        ; 下面准备分配空间
004A5F6B    FFB5 EEBD4000      PUSH DWORD PTR SS:[EBP+40BDEE]           ; /MemSize = 73000 (Push Visze)
004A5F71    6A 40              PUSH 40                                  ; |Flags = GPTR
004A5F73    FF95 F4BA4000      CALL DWORD PTR SS:[EBP+40BAF4]           ; /GlobalAlloc
004A5F79    0BC0               OR EAX,EAX
004A5F7B    75 05              JNZ SHORT 004A5F82                       ; 如果分配成功则跳
004A5F7D    E9 2C3B0000        JMP 004A9AAE
004A5F82    8BF8               MOV EDI,EAX                              ; mov edi,hmem
……
004A5FC3    8B85 EABD4000       MOV EAX,DWORD PTR SS:[EBP+40BDEA]
004A5FC9    57                  PUSH EDI                                 ; /hmem =00142AB8
004A5FCA    50                  PUSH EAX                                 ; |Uzip address = 401000
004A5FCB    E8 353A0000         CALL 004A9A05                            ; /ApLib_Unpack
004A5FD0    58                  POP EAX
004A5FD1    5F                  POP EDI
……
004A6032    FC                  CLD
004A6033    8B8D EEBD4000       MOV ECX,DWORD PTR SS:[EBP+40BDEE]
004A6039    8BF7                MOV ESI,EDI
004A603B    8BBD EABD4000       MOV EDI,DWORD PTR SS:[EBP+40BDEA]
004A6041    F3:A4               REP MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[>; 还原代码
……
004A60F4    FFB5 F6BD4000       PUSH DWORD PTR SS:[EBP+40BDF6]           ; 重定位值9E000
004A60FA    FFB5 DEBD4000       PUSH DWORD PTR SS:[EBP+40BDDE]           ; imagebase
004A6100    E8 EF92FFFF         CALL 0049F3F4                            ; 这里进去就是输入表还原
0049F3F4    55                  PUSH EBP
0049F3F5    8BEC                MOV EBP,ESP
0049F3F7    83C4 F8             ADD ESP,-8
0049F3FA    60                  PUSHAD
0049F3FB    8B45 08             MOV EAX,DWORD PTR SS:[EBP+8]
0049F3FE    8B50 3C             MOV EDX,DWORD PTR DS:[EAX+3C]            ; 定位pe头
0049F401    03C2                ADD EAX,EDX
0049F403    8B90 80000000       MOV EDX,DWORD PTR DS:[EAX+80]            ; 定位输入表
0049F409    0355 08             ADD EDX,DWORD PTR SS:[EBP+8]
0049F40C    8BFA                MOV EDI,EDX
0049F40E    8B5F 0C             MOV EBX,DWORD PTR DS:[EDI+C]
0049F411    83FB 00             CMP EBX,0
0049F414    74 3C               JE SHORT 0049F452                        ; 如果输入表处理完就跳去结束处
0049F416    035D 08             ADD EBX,DWORD PTR SS:[EBP+8]
0049F419    895D FC             MOV DWORD PTR SS:[EBP-4],EBX
0049F41C    8B1F                MOV EBX,DWORD PTR DS:[EDI]
0049F41E    035D 08             ADD EBX,DWORD PTR SS:[EBP+8]
0049F421    895D F8             MOV DWORD PTR SS:[EBP-8],EBX
0049F424    33C9                XOR ECX,ECX
0049F426    8B048B              MOV EAX,DWORD PTR DS:[EBX+ECX*4]
0049F429    8B5D F8             MOV EBX,DWORD PTR SS:[EBP-8]
0049F42C    3B5D 08             CMP EBX,DWORD PTR SS:[EBP+8]
0049F42F    74 03               JE SHORT 0049F434
0049F431    89048B              MOV DWORD PTR DS:[EBX+ECX*4],EAX
0049F434    8B5D FC             MOV EBX,DWORD PTR SS:[EBP-4]
0049F437    8B45 0C             MOV EAX,DWORD PTR SS:[EBP+C]
0049F43A    05 BA124000         ADD EAX,004012BA
0049F43F    89048B              MOV DWORD PTR DS:[EBX+ECX*4],EAX
0049F442    41                  INC ECX
0049F443    8B048B              MOV EAX,DWORD PTR DS:[EBX+ECX*4]
0049F446    83F8 00             CMP EAX,0
0049F449    74 02               JE SHORT 0049F44D                        ; 如果当前DLL处理完则跳去处理下一个DLL的相关API
0049F44B  ^ EB D9               JMP SHORT 0049F426                       ; 循环回去还原输入表
0049F44D    83C7 14             ADD EDI,14
0049F450  ^ EB BC               JMP SHORT 0049F40E
0049F452    61                  POPAD
0049F453    C9                  LEAVE
0049F454    C2 0800             RETN 8
……
004A61B9    FFB5 F6BD4000       PUSH DWORD PTR SS:[EBP+40BDF6]           ; 重定位值
004A61BF    FFB5 DEBD4000       PUSH DWORD PTR SS:[EBP+40BDDE]           ; hmodule
004A61C5    E8 9594FFFF         CALL 0049F65F                            ; 这里进去就是Load All Library
0049F65F    55                  PUSH EBP
0049F660    8BEC                MOV EBP,ESP
0049F662    60                  PUSHAD
0049F663    8B45 08             MOV EAX,DWORD PTR SS:[EBP+8]
0049F666    8B50 3C             MOV EDX,DWORD PTR DS:[EAX+3C]            ; 定位PE头
0049F669    03C2                ADD EAX,EDX
0049F66B    8B90 80000000       MOV EDX,DWORD PTR DS:[EAX+80]            ; 定位输入表
0049F671    0355 08             ADD EDX,DWORD PTR SS:[EBP+8]
0049F674    8BFA                MOV EDI,EDX
0049F676    8B5F 0C             MOV EBX,DWORD PTR DS:[EDI+C]
0049F679    83FB 00             CMP EBX,0
0049F67C    74 1A               JE SHORT 0049F698                        ; 如果全部DLL加载完则跳去结束处
0049F67E    035D 08             ADD EBX,DWORD PTR SS:[EBP+8]
0049F681    8B5F 10             MOV EBX,DWORD PTR DS:[EDI+10]
0049F684    035D 08             ADD EBX,DWORD PTR SS:[EBP+8]             ; 获取DLL的名称
0049F687    8BF3                MOV ESI,EBX
0049F689    56                  PUSH ESI                                 ; /push FileName
0049F68A    8B5D 0C             MOV EBX,DWORD PTR SS:[EBP+C]             ; |
0049F68D    FF93 D1BA4000       CALL DWORD PTR DS:[EBX+40BAD1]           ; /LoadLibraryA
0049F693    83C7 14             ADD EDI,14
0049F696  ^ EB DE               JMP SHORT 0049F676                       ; 跳去取下一个dll名
0049F698    61                  POPAD
0049F699    C9                  LEAVE
0049F69A    C2 0800             RETN 8
……
004A7780    CC                  INT3                                     ; 再下来这里就异常了,记得上面我们保存下来的代码吗?
是了,把从4A7781处到4A9A04处的代码还原正确的回去。
004A7781    33C9                XOR ECX,ECX
004A7783    8B9D FEC14000       MOV EBX,DWORD PTR SS:[EBP+40C1FE]        ; 还原API的地址[4AA1FE]=004AAA00
004A7789    EB 15               JMP SHORT 004A77A0
004A778B    FF348B              PUSH DWORD PTR DS:[EBX+ECX*4]            ; 471cec
004A778E    FFB5 F6BD4000       PUSH DWORD PTR SS:[EBP+40BDF6]           ; relo =9e000
004A7794    FFB5 DEBD4000       PUSH DWORD PTR SS:[EBP+40BDDE]           ; pe header =400000
004A779A    E8 DE78FFFF         CALL 0049F07D                            ; Fill Api Function
0049F07D    55                  PUSH EBP
0049F07E    8BEC                MOV EBP,ESP
0049F080    83C4 EC             ADD ESP,-14
0049F083    60                  PUSHAD
0049F084    8B45 08             MOV EAX,DWORD PTR SS:[EBP+8]
0049F087    8B50 3C             MOV EDX,DWORD PTR DS:[EAX+3C]
0049F08A    03C2                ADD EAX,EDX
0049F08C    8B90 80000000       MOV EDX,DWORD PTR DS:[EAX+80]
0049F092    0355 08             ADD EDX,DWORD PTR SS:[EBP+8]
0049F095    8955 FC             MOV DWORD PTR SS:[EBP-4],EDX
0049F098    8BFA                MOV EDI,EDX
0049F09A    8B5F 10             MOV EBX,DWORD PTR DS:[EDI+10]
0049F09D    83FB 00             CMP EBX,0
0049F0A0    0F84 09010000       JE 0049F1AF                              ; 如果输入表处理完则啵
0049F0A6    035D 08             ADD EBX,DWORD PTR SS:[EBP+8]
0049F0A9    895D F0             MOV DWORD PTR SS:[EBP-10],EBX
0049F0AC    FF75 F0             PUSH DWORD PTR SS:[EBP-10]               ; push DLL name
0049F0AF    8B5D 0C             MOV EBX,DWORD PTR SS:[EBP+C]
0049F0B2    FF93 C0BA4000       CALL DWORD PTR DS:[EBX+40BAC0]           ; GetModuleHandleA获取dll的句柄
0049F0B8    8BD0                MOV EDX,EAX
0049F0BA    8B5F 0C             MOV EBX,DWORD PTR DS:[EDI+C]
0049F0BD    035D 08             ADD EBX,DWORD PTR SS:[EBP+8]
0049F0C0    895D F8             MOV DWORD PTR SS:[EBP-8],EBX
0049F0C3    8B1F                MOV EBX,DWORD PTR DS:[EDI]               ; OfirstThunk
0049F0C5    83FB 00             CMP EBX,0
0049F0C8    0F84 8B000000       JE 0049F159                              ; 如果OriginalFirstThunk为空则跳
0049F0CE    035D 08             ADD EBX,DWORD PTR SS:[EBP+8]
0049F0D1    895D F4             MOV DWORD PTR SS:[EBP-C],EBX
0049F0D4    33C9                XOR ECX,ECX
0049F0D6    8B75 F4             MOV ESI,DWORD PTR SS:[EBP-C]
0049F0D9    8B048E              MOV EAX,DWORD PTR DS:[ESI+ECX*4]
0049F0DC    83F8 00             CMP EAX,0
0049F0DF    0F84 C2000000       JE 0049F1A7                              ; 比较当前DLL的API函数是否已经处理完了
0049F0E5    25 00000080         AND EAX,80000000
0049F0EA    83F8 00             CMP EAX,0
0049F0ED    74 32               JE SHORT 0049F121                        ; 判断是否为序号方式获取,如果是认名字则啵
0049F0EF    8B048E              MOV EAX,DWORD PTR DS:[ESI+ECX*4]
0049F0F2    25 FFFFFF7F         AND EAX,7FFFFFFF
0049F0F7    8B5D F8             MOV EBX,DWORD PTR SS:[EBP-8]
0049F0FA    8D1C8B              LEA EBX,DWORD PTR DS:[EBX+ECX*4]
0049F0FD    3B5D 10             CMP EBX,DWORD PTR SS:[EBP+10]
0049F100    75 1C               JNZ SHORT 0049F11E
0049F102    51                  PUSH ECX
0049F103    52                  PUSH EDX
0049F104    50                  PUSH EAX
0049F105    52                  PUSH EDX
0049F106    8B5D 0C             MOV EBX,DWORD PTR SS:[EBP+C]
0049F109    FF93 E4BA4000       CALL DWORD PTR DS:[EBX+40BAE4]
0049F10F    5A                  POP EDX
0049F110    59                  POP ECX
0049F111    8B5D F8             MOV EBX,DWORD PTR SS:[EBP-8]
0049F114    8D1C8B              LEA EBX,DWORD PTR DS:[EBX+ECX*4]
0049F117    8903                MOV DWORD PTR DS:[EBX],EAX
0049F119    E9 91000000         JMP 0049F1AF
0049F11E    41                  INC ECX
0049F11F  ^ EB B5               JMP SHORT 0049F0D6
0049F121    8B75 F4             MOV ESI,DWORD PTR SS:[EBP-C]             ; OriginalFirstThunk
0049F124    8B048E              MOV EAX,DWORD PTR DS:[ESI+ECX*4]
0049F127    83F8 00             CMP EAX,0
0049F12A    74 7B               JE SHORT 0049F1A7
0049F12C    0345 08             ADD EAX,DWORD PTR SS:[EBP+8]
0049F12F    83C0 02             ADD EAX,2
0049F132    8B5D F8             MOV EBX,DWORD PTR SS:[EBP-8]
0049F135    8D1C8B              LEA EBX,DWORD PTR DS:[EBX+ECX*4]
0049F138    3B5D 10             CMP EBX,DWORD PTR SS:[EBP+10]
0049F13B    75 19               JNZ SHORT 0049F156
0049F13D    51                  PUSH ECX
0049F13E    52                  PUSH EDX
0049F13F    50                  PUSH EAX                                 ; /ProcNameOrOrdinal
0049F140    52                  PUSH EDX                                 ; |hModule
0049F141    8B5D 0C             MOV EBX,DWORD PTR SS:[EBP+C]             ; |
0049F144    FF93 E4BA4000       CALL DWORD PTR DS:[EBX+40BAE4]           ; /GetProcAddress
0049F14A    5A                  POP EDX
0049F14B    59                  POP ECX
0049F14C    8B5D F8             MOV EBX,DWORD PTR SS:[EBP-8]
0049F14F    8D1C8B              LEA EBX,DWORD PTR DS:[EBX+ECX*4]
0049F152    8903                MOV DWORD PTR DS:[EBX],EAX
0049F154    EB 59               JMP SHORT 0049F1AF
0049F156    41                  INC ECX
0049F157  ^ EB C8               JMP SHORT 0049F121
0049F159    33C9                XOR ECX,ECX
0049F15B    8B5F 24             MOV EBX,DWORD PTR DS:[EDI+24]
0049F15E    035D 08             ADD EBX,DWORD PTR SS:[EBP+8]
0049F161    895D EC             MOV DWORD PTR SS:[EBP-14],EBX
0049F164    8B75 F0             MOV ESI,DWORD PTR SS:[EBP-10]
0049F167    803E 00             CMP BYTE PTR DS:[ESI],0
0049F16A    74 03               JE SHORT 0049F16F
0049F16C    46                  INC ESI
0049F16D  ^ EB F8               JMP SHORT 0049F167
0049F16F    46                  INC ESI
0049F170    3B75 EC             CMP ESI,DWORD PTR SS:[EBP-14]
0049F173    74 32               JE SHORT 0049F1A7
0049F175    803E 00             CMP BYTE PTR DS:[ESI],0
0049F178  ^ 74 F5               JE SHORT 0049F16F
0049F17A    837E 01 00          CMP DWORD PTR DS:[ESI+1],0
0049F17E    74 2F               JE SHORT 0049F1AF
0049F180    8B5D F8             MOV EBX,DWORD PTR SS:[EBP-8]
0049F183    8D1C8B              LEA EBX,DWORD PTR DS:[EBX+ECX*4]
0049F186    3B5D 10             CMP EBX,DWORD PTR SS:[EBP+10]
0049F189    75 19               JNZ SHORT 0049F1A4
0049F18B    51                  PUSH ECX
0049F18C    52                  PUSH EDX
0049F18D    56                  PUSH ESI
0049F18E    52                  PUSH EDX
0049F18F    8B5D 0C             MOV EBX,DWORD PTR SS:[EBP+C]
0049F192    FF93 E4BA4000       CALL DWORD PTR DS:[EBX+40BAE4]
0049F198    5A                  POP EDX
0049F199    59                  POP ECX
0049F19A    8B5D F8             MOV EBX,DWORD PTR SS:[EBP-8]
0049F19D    8D1C8B              LEA EBX,DWORD PTR DS:[EBX+ECX*4]
0049F1A0    8903                MOV DWORD PTR DS:[EBX],EAX
0049F1A2    EB 0B               JMP SHORT 0049F1AF
0049F1A4    41                  INC ECX
0049F1A5  ^ EB C0               JMP SHORT 0049F167
0049F1A7    83C7 14             ADD EDI,14
0049F1AA  ^ E9 EBFEFFFF         JMP 0049F09A
0049F1AF    61                  POPAD
0049F1B0    C9                  LEAVE
0049F1B1    C2 0C00             RETN 0C
 
004A779F    41                  INC ECX
004A77A0    3B8D FAC14000       CMP ECX,DWORD PTR SS:[EBP+40C1FA]
004A77A6  ^ 72 E3               JB SHORT 004A778B                        ; 循环处理输入表
……
004A8303    8BC5            MOV EAX,EBP
004A8305    8B95 2AC24000   MOV EDX,DWORD PTR SS:[EBP+40C22A]        ; 校验值2cd76ec4
004A830B    3395 02C24000   XOR EDX,DWORD PTR SS:[EBP+40C202]        ; 如果前面改过,程序算出的oep地址就会出错
004A8311    8995 02C24000   MOV DWORD PTR SS:[EBP+40C202],EDX        ; OEP地址保存到4aa202处
004A8317    5F              POP EDI
004A8318    5A              POP EDX
004A8319    59              POP ECX
004A831A    5E              POP ESI
004A831B    5B              POP EBX
004A831C    5D              POP EBP
004A831D    05 FA114000     ADD EAX,004011FA
004A8322    50              PUSH EAX
004A8323    64:FF35 0000000>PUSH DWORD PTR FS:[0]
004A832A    64:8925 0000000>MOV DWORD PTR FS:[0],ESP                 ; install hook安装she,( 0049F1FA)
004A8331    2D FA114000     SUB EAX,004011FA
004A8336    FFB0 02C24000   PUSH DWORD PTR DS:[EAX+40C202]           ; push oep
……
004A9A04    C3              RETN                                     ; 终于到光明顶了:-)
下面看看API的处理:
0049F2BA    E8 00000000     CALL 0049F2BF
0049F2BF    58              POP EAX
0049F2C0    2D BF124000     SUB EAX,004012BF
0049F2C5    C780 22C24000 0>MOV DWORD PTR DS:[EAX+40C222],0
0049F2CF    8B80 02C24000   MOV EAX,DWORD PTR DS:[EAX+40C202]        ; 程序OEP地址入eax中
0049F2D5    8138 558BEC83   CMP DWORD PTR DS:[EAX],83EC8B55          ; 判断是否为push ebp mov ebp,esp add esp,xx方式的程序
0049F2DB    75 06           JNZ SHORT 0049F2E3                       ; 如果不是则跳
0049F2DD    58              POP EAX
0049F2DE    8B40 FC         MOV EAX,DWORD PTR DS:[EAX-4]
0049F2E1    EB 7D           JMP SHORT 0049F360
0049F2E3    8038 EB         CMP BYTE PTR DS:[EAX],0EB                ; 判断是否为BC的程序jmp xxxx
0049F2E6    75 06           JNZ SHORT 0049F2EE                       ; 如果不是则跳
0049F2E8    58              POP EAX
0049F2E9    8B40 FC         MOV EAX,DWORD PTR DS:[EAX-4]             ; 获取要保存输入表的地址iat
0049F2EC    EB 72           JMP SHORT 0049F360                       ; 然后跳去获取api函数
0049F2EE    8B0424          MOV EAX,DWORD PTR SS:[ESP]
0049F2F1    817C24 04 00000>CMP DWORD PTR SS:[ESP+4],80000000
0049F2F9    73 06           JNB SHORT 0049F301
0049F2FB    334424 04       XOR EAX,DWORD PTR SS:[ESP+4]
0049F2FF    EB 08           JMP SHORT 0049F309
0049F301    8B0424          MOV EAX,DWORD PTR SS:[ESP]
0049F304    8B40 FC         MOV EAX,DWORD PTR DS:[EAX-4]
0049F307    EB 57           JMP SHORT 0049F360
0049F309    3D 00001000     CMP EAX,100000
0049F30E    73 06           JNB SHORT 0049F316
0049F310    58              POP EAX
0049F311    8B40 FC         MOV EAX,DWORD PTR DS:[EAX-4]
0049F314    EB 4A           JMP SHORT 0049F360
0049F316    3D 00000070     CMP EAX,70000000
0049F31B    73 08           JNB SHORT 0049F325
0049F31D    8B0424          MOV EAX,DWORD PTR SS:[ESP]
0049F320    8B40 FC         MOV EAX,DWORD PTR DS:[EAX-4]
0049F323    EB 3B           JMP SHORT 0049F360
0049F325    813C24 00000070 CMP DWORD PTR SS:[ESP],70000000
0049F32C    73 01           JNB SHORT 0049F32F
0049F32E    58              POP EAX
0049F32F    E8 00000000     CALL 0049F334
0049F334    58              POP EAX
0049F335    2D 34134000     SUB EAX,00401334
0049F33A    C780 22C24000 0>MOV DWORD PTR DS:[EAX+40C222],1
0049F344    8B8424 E4000000 MOV EAX,DWORD PTR SS:[ESP+E4]
0049F34B    3D 03000080     CMP EAX,80000003
0049F350    0F85 98000000   JNZ 0049F3EE
0049F356    8B8424 F0000000 MOV EAX,DWORD PTR SS:[ESP+F0]
0049F35D    8B40 02         MOV EAX,DWORD PTR DS:[EAX+2]
0049F360    60              PUSHAD                                   ; 下面准备填充iat
0049F361    E8 00000000     CALL 0049F366
0049F366    5D              POP EBP
0049F367    81ED 66134000   SUB EBP,00401366                         ; 计算重定位值
0049F36D    50              PUSH EAX                                 ; push iat address
0049F36E    FFB5 F6BD4000   PUSH DWORD PTR SS:[EBP+40BDF6]           ; push relo(9E000)
0049F374    FFB5 DEBD4000   PUSH DWORD PTR SS:[EBP+40BDDE]           ; push hmodule
0049F37A    E8 FEFCFFFF     CALL 0049F07D                            ; GetProcAddress获取填充api
0049F37F    61              POPAD
0049F380    52              PUSH EDX
0049F381    51              PUSH ECX
0049F382    E8 00000000     CALL 0049F387
0049F387    5A              POP EDX
0049F388    81EA 87134000   SUB EDX,00401387
0049F38E    81C2 BA124000   ADD EDX,004012BA                         ; 计算还原值
0049F394    8B08            MOV ECX,DWORD PTR DS:[EAX]               ; 把api函数地址放到ECX中
0049F396    8910            MOV DWORD PTR DS:[EAX],EDX               ;  取出API函数地址后还原"现场"
0049F398    8BC1            MOV EAX,ECX
0049F39A    59              POP ECX
0049F39B    5A              POP EDX
0049F39C    52              PUSH EDX
0049F39D    E8 00000000     CALL 0049F3A2
0049F3A2    5A              POP EDX
0049F3A3    81EA A2134000   SUB EDX,004013A2                         ; 计算reloc
0049F3A9    83BA 22C24000 0>CMP DWORD PTR DS:[EDX+40C222],0
0049F3B0    75 05           JNZ SHORT 0049F3B7
0049F3B2    5A              POP EDX
0049F3B3    FFE0            JMP EAX                                  ; 跳去执行api函数
0049F3B5    EB 37           JMP SHORT 0049F3EE
0049F3B7    5A              POP EDX
0049F3B8    8BBC24 F0000000 MOV EDI,DWORD PTR SS:[ESP+F0]
0049F3BF    83C7 01         ADD EDI,1
0049F3C2    803F 3D         CMP BYTE PTR DS:[EDI],3D
0049F3C5    74 0B           JE SHORT 0049F3D2
0049F3C7    8B7D 10         MOV EDI,DWORD PTR SS:[EBP+10]
0049F3CA    8987 A0000000   MOV DWORD PTR DS:[EDI+A0],EAX
0049F3D0    EB 09           JMP SHORT 0049F3DB
0049F3D2    8B7D 10         MOV EDI,DWORD PTR SS:[EBP+10]
0049F3D5    8987 9C000000   MOV DWORD PTR DS:[EDI+9C],EAX
0049F3DB    8B8424 F0000000 MOV EAX,DWORD PTR SS:[ESP+F0]
0049F3E2    83C0 06         ADD EAX,6
0049F3E5    8987 B8000000   MOV DWORD PTR DS:[EDI+B8],EAX
0049F3EB    33C0            XOR EAX,EAX
0049F3ED    C3              RETN
分析完api的处理后,写上一段修复程序:
 
00473601    60               PUSHAD
00473602    B8 24EE4500      MOV EAX,0045EE24                         ; JMP to BORLNDMM.GetAllocMemCount
00473607    66:8138 FF15     CMP WORD PTR DS:[EAX],15FF
0047360C    75 33            JNZ SHORT 00473641
0047360E    8B50 02          MOV EDX,DWORD PTR DS:[EAX+2]
00473611    81FA 00000008    CMP EDX,8000000
00473617    73 28            JNB SHORT 00473641
00473619    81FA 00004000    CMP EDX,00400000                         ; ASCII "MZP"
0047361F    72 20            JB SHORT 00473641
00473621    813A BAF24900    CMP DWORD PTR DS:[EDX],0049F2BA
00473627    75 15            JNZ SHORT 0047363E
00473629    52               PUSH EDX                                ;将要保存的地址
0047362A    68 00E00900      PUSH 9E000                              ;重定位值
0047362F    68 00004000      PUSH 00400000                            ; ASCII "MZP"
00473634    E8 44BA0200      CALL 0049F07D                           ;填充api
00473639    66:C700 FF25     MOV WORD PTR DS:[EAX],25FF
0047363E    83C0 05          ADD EAX,5
00473641    40               INC EAX
00473642    3D 58F74500      CMP EAX,0045F758
00473647  ^ 72 BE            JB SHORT 00473607
00473649    61               POPAD
0047364A  ^ E9 EDDBF8FF      JMP 0040123C
‘-----------------------------Binary code---------------------------
60 B8 24 EE 45 00 66 81 38 FF 15 75 33 8B 50 02 81 FA 00 00 00 08 73 28 81 FA 00 00 40 00 72 20
81 3A BA F2 49 00 75 15 52 68 00 E0 09 00 68 00 00 40 00 E8 44 BA 02 00 66 C7 00 FF 25 83 C0 05
40 3D 58 F7 45 00 72 BE 61 E9 ED DB F8 FF
‘------------------------------------END----------------------------------------
完成后,用IMPrec 写入OEP:123C  RVA:000710C8  SIZE:00000C74,用lordpe dump,最后修复。OK!
这个壳去年就想好好看一下了,因时间比较紧,所以一直拖到今年才有空看,壳完全搞明白加文章用了几天的时间L。
Greetz:
 Fly.Jingulong,yock,tDasm.David.hexer,hmimys,ahao.UFO(brother).alan(sister).all of my friends and you!
 
By loveboom[DFCG][FCG][US]
Email:loveboom#163.com
Date:2005-02-25 12:24
 
一.脱壳机名字的由来 skylly's CoolDumpper,借用了看雪论坛里高人某个让人流口水的工具的名字 界面也是盗的CoolDumpper,不过本人盗技术不高,做成了个四不像~~ 二.脱壳机的原理 由以下几大要部分组成, 1.侦壳功能. 完全拷贝自看雪论坛“任平生”的代码 2.Dummpper(进程转存) 初期,完全拷贝自lenus的lenus's Dummper代码, 现在为了适应脱壳的需要,发现原来的代码对非标准格式的PE文件的处理有些小问题, 所以代码基本都重写过了,但是基本处理步骤还是一致的,外表上看不出来 3.cooldebugger plugin(调试插件) 完全自主开发的插件,说是调试器其实没有用调试,而是注入,然后进行一些最简单的内存操作,没有 什么技术含量,可以完美躲过调试器检测的壳,对于内存检验比较强的壳可能不是很好用。 4.真正意义上的调试器 用最简单的调试API做的一个具有基本功能的调试器,目前还不能用于脱壳,只是一个玩具,为了将来扩展用的。 但是hook api始终不是很妥当,总会让壳有机可乘,以后可能会考虑加入驱动,驱动最让我不放心的是它的稳定性。 三,关于源码 由于还在开发中,暂不开源(主要是怕被人拿去篡改,反而让人以为他是正宗,我是盗) 等到我不再开发时,会开放全部源代码,技术这东西,共享才是王道。 四。使用说明。 我想不用说太多了吧,选择目标文件后(支持拖放),再选择对应的插件,再点击脱壳按钮就可以了。可以说是接近傻瓜化了... 几个子功能说明: 详细日志:是调试器用的 PE标准化:是对某些被改得乱七八糟的壳(如upack)进行简单的PE修复 移除自校验:这个功能可以说是没有设计好,不同的壳自检验的地方不一样, 所以处理也应该不一样,可按照现有的工作模式又不可能把它做到plugin(插件)里面去, 但是,总之我会加进去的。 第x次调用API中断:这个功能是从CoolDumpper那儿抄袭界面遗留下来的,光有界面,未实现功能,将来如果有自动脱壳搞不定 的壳时,可能可以把这个地方扩展成手动脱壳。 OEP输入框和IAT输入框:功能已经弱化,由脱壳插件自动完成。 纠正映象大小:功能已经弱化,已经由dumpper自动完成。 五。关于private本. 由于种种原因,不再发布public本,仅作为私下交流之用。 所谓私下交流,可以算一种"精华"门槛吧. 1.看雪论坛或者一蓑烟雨,30精以上的朋友(高手)或者500帖以上的朋友(超级水牛),或者30贴以内且精华率在1/3以上的(超级高手)随时可以向我索要最新。不过我相信高手们只会把我这个东西当玩具玩玩而已。 2.在使用这个脱壳机过程中遇到比较严重的问题或者不能脱的壳,可以来E-mail和我交流,欢迎技术交流,谢绝任何形式的脱壳请求, 因为我只是个菜鸟。对于有价值的来信,我会酌情回复最新脱壳机。 得到这个脱壳机的人,任由其处置。 六。开发目标 开发常见压缩壳和加密壳的插件并实现自动脱壳。 压缩壳插件做十个左右,加密壳插件做二十个左右。 压缩壳插件: upx, upack, aspack, nspack, mew, hmimys, pecompact, expressor, fsg, kbys, packman, PEncrypt (已经基本完成。) 加密壳插件:(还没想好,暂定, 刚刚开始开发) pe-armor, armadillo, aspr, acpr, telcok, execrypt, pelock, pc-guard, morphine, safedisc, themida, enigma, obsidium, starforce, yoda_s_cryptor, epe, pespin, svkp, sdp.............. 预估主程序最终本号:2.0 预估所有插件最终本号:0.3 已知bug: 1.由于修复输入表是用的ImpRec.dll这个动态链接,我没有源码,它在处理某些IAT不连续的程序时,获取的IAT的大小有问题,所以暂时还没 有解决方案来对付,等我复习好输入表结构,以后脱壳机就自己来重建输入表了,呵呵。 2.无法对付多层壳. 3.处理自校验有问题,请不要随便选中,否则后果自负 现在发布的这个本仅仅代表了一个脱壳机的起步阶段,当玩具吧。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值