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后面的JMPOEP代码结束地址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