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#,1000repl eip,#E803000000??????58EB01??83C00750C3????#,#90909090909090909090909090909090909090#,1000repl eip,#E808000000????83C00F50C3??5883C002FFE0??????#,#90909090909090909090909090909090909090909090#,1000repl eip,#E8160000008B5C240C8BA3C4000000648F050000000083C404EB1464FF35000000006489250000000033C999F7F1??#,#9090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090#,1000repl eip,#33F6E8100000008B642408648F050000000058EB13????64FF350000000064892500000000AD????#,#90909090909090909090909090909090909090909090909090909090909090909090909090909090#,1000repl eip,#B904000000E81F000000????E816000000??EBF8????58EB09????E8F2FFFFFF????4975F1EB05EBF9EBF0??#,#9090909090909090909090909090909090909090909090909090909090909090909090909090909090909090#,1000repl eip,#EB01??31F0EB0C33C8EB03EB09??59740575F851EBF1#,#90909090909090909090909090909090909090909090#,1000ret 写完后用OD载入目标程序。去掉垃圾代码然后在.Xikug那个段处下内存访问断点,F9运行之.到这里断下:004A3121 E8 00000000 CALL 004A3126 ; 这里壳代码开始处,上面的全部是垃圾代码来的004A3126 5D POP EBP004A3127 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] ; 要解压的起始地址4a3260004A314F 8D8D 04BA4000 LEA ECX,DWORD PTR SS:[EBP+40BA04] ; INT3后面的JMP OEP代码结束地址4a9a04004A3155 8D95 81974000 LEA EDX,DWORD PTR SS:[EBP+409781] ; INT3异常后的起始地址4a7781004A315B EB 0B JMP SHORT 004A3168004A315D 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],52004A3167 40 INC EAX004A3168 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 3B8D 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 02CD 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 010C 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 0000 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 F9EB F0 D6 C3......004A3260 8B4424 18 MOV EAX,DWORD PTR SS:[ESP+18] ; 准备取KERNEL32.dll的hModule004A3264 25 0000FFFF AND EAX,FFFF0000 ; 去除底位004A3269 33D2 XOR EDX,EDX004A326B 48 DEC EAX004A326C 66:8B50 3C MOV DX,WORD PTR DS:[EAX+3C]004A3270 66:F7C2 00F0 TEST DX,0F000004A3275 ^ 75 F4 JNZ SHORT 004A326B004A3277 3B4402 34 CMP EAX,DWORD PTR DS:[EDX+EAX+34]004A327B ^ 75 EE JNZ SHORT 004A326B ; 循环取出Kernel32.dll的hModule004A327D 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 EBP0049F001 8BEC MOV EBP,ESP0049F003 83C4 E8 ADD ESP,-180049F006 53 PUSH EBX0049F007 51 PUSH ECX0049F008 56 PUSH ESI0049F009 57 PUSH EDI0049F00A 8B45 08 MOV EAX,DWORD PTR SS:[EBP+8] ; hModule0049F00D 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],EAX0049F016 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],EBX0049F01F 8BC3 MOV EAX,EBX0049F021 8B58 1C MOV EBX,DWORD PTR DS:[EAX+1C]0049F024 035D 08 ADD EBX,DWORD PTR SS:[EBP+8] ; 定位AddressOfFunctions0049F027 895D F4 MOV DWORD PTR SS:[EBP-C],EBX0049F02A 8B58 18 MOV EBX,DWORD PTR DS:[EAX+18] ; 定位NumberOfNames0049F02D 895D F0 MOV DWORD PTR SS:[EBP-10],EBX0049F030 8B58 20 MOV EBX,DWORD PTR DS:[EAX+20]0049F033 035D 08 ADD EBX,DWORD PTR SS:[EBP+8] ; 定位AddressOfNames0049F036 895D E8 MOV DWORD PTR SS:[EBP-18],EBX0049F039 8B58 24 MOV EBX,DWORD PTR DS:[EAX+24]0049F03C 035D 08 ADD EBX,DWORD PTR SS:[EBP+8] ; AddressofNameOrdinals0049F03F 895D EC MOV DWORD PTR SS:[EBP-14],EBX0049F042 33C9 XOR ECX,ECX0049F044 33DB XOR EBX,EBX0049F046 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 0049F0640049F05A 43 INC EBX0049F05B B0 00 MOV AL,00049F05D 3A0433 CMP AL,BYTE PTR DS:[EBX+ESI]0049F060 ^ 75 F0 JNZ SHORT 0049F0520049F062 74 08 JE SHORT 0049F06C0049F064 33DB XOR EBX,EBX0049F066 41 INC ECX0049F067 3B4D F0 CMP ECX,DWORD PTR SS:[EBP-10]0049F06A ^ 75 DD JNZ SHORT 0049F0490049F06C 8B7D F4 MOV EDI,DWORD PTR SS:[EBP-C] ; 通过循环取出相关的API0049F06F 8B048F MOV EAX,DWORD PTR DS:[EDI+ECX*4]0049F072 0345 08 ADD EAX,DWORD PTR SS:[EBP+8] ; 取出的api转为VA0049F075 5F POP EDI0049F076 5E POP ESI0049F077 59 POP ECX0049F078 5B POP EBX0049F079 C9 LEAVE0049F07A 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 GetOKGetNext: 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 ...UnhandledExce004A9B14 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 GetModuleFileNam004A9B34 65 41 00 00 00 00 00 45 78 69 74 50 72 6F 63 65 eA.....ExitProce004A9B44 73 73 00 00 00 00 00 43 72 65 61 74 65 50 72 6F ss.....CreatePro004A9B54 63 65 73 73 00 00 00 00 00 57 61 69 74 46 6F 72 cess.....WaitFor004A9B64 44 65 62 75 67 45 76 65 6E 74 00 00 00 00 00 43 DebugEvent.....C004A9B74 6F 6E 74 69 6E 75 65 44 65 62 75 67 45 76 65 6E ontinueDebugEven004A9B84 74 00 00 00 00 00 47 65 74 43 6F 6D 6D 61 6E 64 t.....GetCommand004A9B94 4C 69 6E 65 00 00 00 00 00 6C 73 74 72 6C 65 6E Line.....lstrlen004A9BA4 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 ...CreateToolhel004A9BE4 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 ...Process32Next004A9C14 00 00 00 00 00 47 65 74 43 75 72 72 65 6E 74 50 .....GetCurrentP004A9C24 72 6F 63 65 73 73 49 64 00 00 00 00 00 4F 70 65 rocessId.....Ope004A9C34 6E 50 72 6F 63 65 73 73 00 00 00 00 00 43 6C 6F nProcess.....Clo004A9C44 73 65 48 61 6E 64 6C 65 00 00 00 00 00 52 65 61 seHandle.....Rea004A9C54 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 ...GetThreadCont004A9C74 65 78 74 00 00 00 00 00 53 65 74 54 68 72 65 61 ext.....SetThrea004A9C84 64 43 6F 6E 74 65 78 74 00 00 00 00 00 57 72 69 dContext.....Wri004A9C94 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 ....FlushInstruc004A9CB4 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.GetProcAddress004A3B95 8985 4DBC4000 MOV DWORD PTR SS:[EBP+40BC4D],EAX……004A3FED 6A 00 PUSH 0 ; /ProcessID = 0004A3FEF 6A 02 PUSH 2 ; |Flags = TH32CS_SNAPPROCESS004A3FF1 FF95 F0BB4000 CALL DWORD PTR SS:[EBP+40BBF0] ; \CreateToolhelp32Snapshot004A3FF7 8985 FBC24000 MOV DWORD PTR SS:[EBP+40C2FB],EAX ; HANDLE(10)保存到[4aa2fb]004A3FFD 50 PUSH EAX……004A4018 58 POP EAX004A4019 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 =004AA303004A40C3 PUSH DWORD PTR SS:[EBP+40C2FB] ; |hSnapshot = 00000010004A40C9 CALL DWORD PTR SS:[EBP+40BC03] ; \Call Process32First……004A40EB 0BC0 OR EAX,EAX004A40ED 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获取当前进程ID004A416D 3947 08 CMP DWORD PTR DS:[EDI+8],EAX004A4170 0F85 111A0000 JNZ 004A5B87 ; 如果不是没有找到当前进程则跳004A4176 8B47 18 MOV EAX,DWORD PTR DS:[EDI+18] ; 获取父进程的ID004A4179 8985 3EC24000 MOV DWORD PTR SS:[EBP+40C23E],EAX ; 父进程ID保存到[4AA23E处004A417F FF77 18 PUSH DWORD PTR DS:[EDI+18] ; /ProcessId = 3E0004A4182 6A 00 PUSH 0 ; |Inheritable = FALSE004A4184 68 FF0F1F00 PUSH 1F0FFF ; |Access = PROCESS_ALL_ACCESS004A4189 FF95 3DBC4000 CALL DWORD PTR SS:[EBP+40BC3D] ; \CALL OpenProcess004A418F 8985 FFC24000 MOV DWORD PTR SS:[EBP+40C2FF],EAX ; openProcHandle 保存到[4AA2FF]处004A4195 0BC0 OR EAX,EAX004A4197 0F84 E6190000 JE 004A5B83 ; 如果打开进程失败则跳下去004A419D 8D85 B4114000 LEA EAX,DWORD PTR SS:[EBP+4011B4] ; 这里开始利用SEH处理读内存可能产生的异常004A41A3 50 PUSH EAX ; 这里是一个Anti-Deubg004A41A4 64:FF35 0000000>PUSH DWORD PTR FS:[0]004A41AB 64:8925 0000000>MOV DWORD PTR FS:[0],ESP004A41B2 55 PUSH EBP004A41B3 6A 00 PUSH 0 ; /pBytesRead = NULL004A41B5 6A 40 PUSH 40 ; |BytesToRead = 40 (64.)004A41B7 8D85 2BC44000 LEA EAX,DWORD PTR SS:[EBP+40C42B] ; |004A41BD 50 PUSH EAX ; |Buffer = Explorer.004AA42B004A41BE 68 00000010 PUSH 10000000 ; |pBaseAddress = 10000000004A41C3 FFB5 FFC24000 PUSH DWORD PTR SS:[EBP+40C2FF] ; |hProcess = 0000001C004A41C9 FF95 63BC4000 CALL DWORD PTR SS:[EBP+40BC63] ; \ReadProcessMemory004A41CF 5D POP EBP ; UnSeh004A41D0 33DB XOR EBX,EBX004A41D2 64:8F03 POP DWORD PTR FS:[EBX]004A41D5 83C4 04 ADD ESP,4004A41D8 50 PUSH EAX ; 如果读取成功则EAX为1004A41D9 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,AL004A5B56 75 02 JNZ SHORT 004A5B5A ; 如果没有获取完则跳004A5B58 EB 13 JMP SHORT 004A5B6D004A5B5A 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 ECX004A5B6B ^ EB E1 JMP SHORT 004A5B4E ; 没有取完则继续上去计算加密值004A5B6D 59 POP ECX004A5B6E 58 POP EAX004A5B6F 83F8 01 CMP EAX,1 ; 这里判断读取内存是否成功,不成功则跳004A5B72 75 0B JNZ SHORT 004A5B7F004A5B74 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 004A5B87004A5B7F |EB 1B JMP SHORT 004A5B9C004A5B81 |EB 04 JMP SHORT 004A5B87004A5B83 |EB 17 JMP SHORT 004A5B9C004A5B85 |EB 00 JMP SHORT 004A5B87004A5B87 \57 PUSH EDI ; /pProcessentry = Explorer.004AA303004A5B88 FFB5 FBC24000 PUSH DWORD PTR SS:[EBP+40C2FB] ; |hSnapshot = 00000010004A5B8E FF95 15BC4000 CALL DWORD PTR SS:[EBP+40BC15] ; \CALL Process32Next004A5B94 0BC0 OR EAX,EAX004A5B96 ^ 0F85 CBE5FFFF JNZ 004A4167 ; 如果没有枚举完进程则跳回去继续……第一次计算加密的方法就是取出进程名的每一位,然后把取出的字符and 0F后的值就是在&ad$.8=CCD[[VTQ中的第几位.第一次计算后的值为:8C&V.d8dQ8C8……004A5BEB 57 PUSH EDI ; /pProcessentry = Explorer.004AA303004A5C18 FFB5 FBC24000 PUSH DWORD PTR SS:[EBP+40C2FB] ; |hSnapshot = 00000010004A5C1E FF95 03BC4000 CALL DWORD PTR SS:[EBP+40BC03] ; \Process32First……004A5C40 0BC0 OR EAX,EAX004A5C42 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 RETN004A5C51 8B85 3EC24000 MOV EAX,DWORD PTR SS:[EBP+40C23E] ; 父进程ID入EAX004A5C57 3947 08 CMP DWORD PTR DS:[EDI+8],EAX004A5C5A 0F85 A0000000 JNZ 004A5D00 ; 如果不是父进程ID则跳下去继续004A5C60 BA 00000000 MOV EDX,0004A5C65 33C9 XOR ECX,ECX004A5C67 8D47 24 LEA EAX,DWORD PTR DS:[EDI+24] ; 获取父进程的进程名004A5C6A 8A0401 MOV AL,BYTE PTR DS:[ECX+EAX] ; 依次取出父进程的每一位004A5C6D 0AC0 OR AL,AL004A5C6F 75 02 JNZ SHORT 004A5C73 ; 如果没有取完则跳004A5C71 EB 1C JMP SHORT 004A5C8F004A5C73 24 0F AND AL,0F004A5C75 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] ; 查表后的值和上面计算自己进程名的值xor004A5C83 0AC0 OR AL,AL ; 其中有一位不同004A5C85 74 05 JE SHORT 004A5C8C ; 如果相等就跳004A5C87 BA 01000000 MOV EDX,1 ; 不同则edx设置为1004A5C8C 41 INC ECX004A5C8D ^ EB D8 JMP SHORT 004A5C67004A5C8F 83FA 01 CMP EDX,1 ; 比较如果不相同的话就不跳004A5C92 75 6C JNZ SHORT 004A5D00 ; 如果用OD来调试的子进程话这里就一定要跳,否则后面不会跳去正确的OEP处……004A5CAA BE 9A7C4000 MOV ESI,00407C9A004A5CC9 81EE FF000000 SUB ESI,0FF004A5CCF 03F5 ADD ESI,EBP……004A5CE7 C706 E77D4000 MOV DWORD PTR DS:[ESI],00407DE7 ; 这几句不知道是什么意思:-(004A5CED 83C6 1F ADD ESI,1F004A5CF0 8906 MOV DWORD PTR DS:[ESI],EAX004A5CF2 FFB5 FFC24000 PUSH DWORD PTR SS:[EBP+40C2FF] ; /hObject = 0000001C004A5CF8 FF95 4DBC4000 CALL DWORD PTR SS:[EBP+40BC4D] ; \CloseHandle004A5CFE EB 15 JMP SHORT 004A5D15004A5D00 57 PUSH EDI ; /pProcessentry = Explorer.004AA303004A5D01 FFB5 FBC24000 PUSH DWORD PTR SS:[EBP+40C2FB] ; |hSnapshot = 00000010004A5D07 FF95 15BC4000 CALL DWORD PTR SS:[EBP+40BC15] ; \Process32Next004A5D0D 0BC0 OR EAX,EAX004A5D0F ^ 0F85 3CFFFFFF JNZ 004A5C51 ; 如果没有枚举完则继续……004A5D2F FFB5 FBC24000 PUSH DWORD PTR SS:[EBP+40C2FB] ; /hObject = 00000010004A5D5E FF95 4DBC4000 CALL DWORD PTR SS:[EBP+40BC4D] ; \CloseHandle关闭对象
到这里为些壳的ANTI-Debug就结束了。 ……004A5D7A FF95 99BB4000 CALL DWORD PTR SS:[EBP+40BB99] ; 获取命令行004A5D80 50 PUSH EAX004A5D81 90 NOP004A5D82 90 NOP……004A5DAD 5A POP EDX ; 00141EE0004A5DAE 8BF2 MOV ESI,EDX004A5DB0 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 NOP004A5E10 90 NOP ; 准备获取程序的完整路径名004A5E11 90 NOP004A5E12 90 NOP004A5E13 68 00010000 PUSH 100 ; /BufSize = 100 (256.)004A5E18 8D85 C2BC4000 LEA EAX,DWORD PTR SS:[EBP+40BCC2] ; |004A5E1E 50 PUSH EAX ; |PathBuffer = Explorer.004A9CC2004A5E1F 6A 00 PUSH 0 ; |hModule = NULL004A5E21 FF95 37BB4000 CALL DWORD PTR SS:[EBP+40BB37] ; \GetModuleFileNameA004A5E27 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,ESP0049F45A 60 PUSHAD0049F45B 8B7D 08 MOV EDI,DWORD PTR SS:[EBP+8] ; 程序完整路径存放地址入edi0049F45E E8 00000000 CALL 0049F4630049F463 5B POP EBX0049F464 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.004AA2420049F477 FF93 D3BB4000 CALL DWORD PTR DS:[EBX+40BBD3] ; \RtlZeroMemory0049F47D B8 10000000 MOV EAX,100049F482 50 PUSH EAX ; /Length = 10 (16.)0049F483 8D83 86C24000 LEA EAX,DWORD PTR DS:[EBX+40C286] ; |0049F489 50 PUSH EAX ; |Destination = Explorer.004AA2860049F48A FF93 D3BB4000 CALL DWORD PTR DS:[EBX+40BBD3] ; \RtlZeroMemory0049F490 B8 44000000 MOV EAX,44 ; 准备CreateProcessA调试子进程0049F495 8983 42C24000 MOV DWORD PTR DS:[EBX+40C242],EAX0049F49B 8D83 86C24000 LEA EAX,DWORD PTR DS:[EBX+40C286]0049F4A1 50 PUSH EAX ; /pProcessInfo = Explorer.004AA2860049F4A2 8D83 42C24000 LEA EAX,DWORD PTR DS:[EBX+40C242] ; |0049F4A8 50 PUSH EAX ; |pStartupInfo = Explorer.004AA2420049F4A9 6A 00 PUSH 0 ; |CurrentDir = NULL0049F4AB 6A 00 PUSH 0 ; |pEnvironment = NULL0049F4AD B8 01000000 MOV EAX,1 ; |0049F4B2 83C8 02 OR EAX,2 ; |0049F4B5 50 PUSH EAX ; |CreationFlags = DEBUG_PROCESS|DEBUG_ONLY_THIS_PROCESS0049F4B6 6A 00 PUSH 0 ; |InheritHandles = FALSE0049F4B8 6A 00 PUSH 0 ; |pThreadSecurity = NULL0049F4BA 6A 00 PUSH 0 ; |pProcessSecurity = NULL0049F4BC 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] ; \CreateProcessA0049F4CA 83F8 01 CMP EAX,10049F4CD 0F85 87010000 JNZ 0049F65A ; 如果创建进程失败则退出程序0049F4D3 8DBB 64C54000 LEA EDI,DWORD PTR DS:[EBX+40C564]0049F4D9 C707 07000100 MOV DWORD PTR DS:[EDI],100070049F4DF 810F 10000100 OR DWORD PTR DS:[EDI],100100049F4E5 8D83 96C24000 LEA EAX,DWORD PTR DS:[EBX+40C296]0049F4EB 68 A00F0000 PUSH 0FA0 ; /Timeout = 4000. ms0049F4F0 50 PUSH EAX ; |pDebugEvent = Explorer.004AA2960049F4F1 FF93 6FBB4000 CALL DWORD PTR DS:[EBX+40BB6F] ; \WaitForDebugEvent0049F4F7 83F8 01 CMP EAX,10049F4FA 0F85 55010000 JNZ 0049F655 ; 如果 EAX ==FALSE则跳下一步0049F500 8D93 96C24000 LEA EDX,DWORD PTR DS:[EBX+40C296] ; DebugEvent0049F506 8DB3 86C24000 LEA ESI,DWORD PTR DS:[EBX+40C286] ; pi0049F50C 833A 03 CMP DWORD PTR DS:[EDX],3 ; CREATE_PROCESS_DEBUG_EVENT0049F50F 75 16 JNZ SHORT 0049F527 ; 如果调试动作不为CREATE_PROCESS_DEBUG_EVENT则跳0049F511 68 02000100 PUSH 10002 ; /ContinueStatus = DBG_CONTINUE0049F516 FF72 08 PUSH DWORD PTR DS:[EDX+8] ; |ThreadId = 2140049F519 FF72 04 PUSH DWORD PTR DS:[EDX+4] ; |ProcessId = 57C0049F51C FF93 86BB4000 CALL DWORD PTR DS:[EBX+40BB86] ; \ContinueDebugEvent0049F522 E9 2E010000 JMP 0049F6550049F527 833A 01 CMP DWORD PTR DS:[EDX],1 ; 判断有没有发生异常EXCEPTION_DEBUG_EVENT0049F52A 0F85 0B010000 JNZ 0049F63B ; 如果没有则跳0049F530 817A 0C 0300008>CMP DWORD PTR DS:[EDX+C],80000003 ; 判断是否为int3断点异常,如果不是则跳去继续0049F537 0F85 EB000000 JNZ 0049F6280049F53D 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+10049F54C 68 02000100 PUSH 10002 ; /ContinueStatus = DBG_CONTINUE0049F551 FF72 08 PUSH DWORD PTR DS:[EDX+8] ; |ThreadId = 2140049F554 FF72 04 PUSH DWORD PTR DS:[EDX+4] ; |ProcessId = 57C0049F557 FF93 86BB4000 CALL DWORD PTR DS:[EBX+40BB86] ; \ContinueDebugEvent0049F55D E9 F3000000 JMP 0049F655 ; 跳去ContinueDebugEvent0049F562 83BB F7C24000 0>CMP DWORD PTR DS:[EBX+40C2F7],1 ; 第二次int3异常0049F569 0F85 A6000000 JNZ 0049F6150049F56F 52 PUSH EDX0049F570 FF83 F7C24000 INC DWORD PTR DS:[EBX+40C2F7] ; debug step+10049F576 8DBB 64C54000 LEA EDI,DWORD PTR DS:[EBX+40C564]0049F57C 57 PUSH EDI ; /pContext = Explorer.004AA5640049F57D FF76 04 PUSH DWORD PTR DS:[ESI+4] ; |hThread = 00000038 (window)0049F580 FF93 78BC4000 CALL DWORD PTR DS:[EBX+40BC78] ; \GetThreadContext0049F586 8B8F B8000000 MOV ECX,DWORD PTR DS:[EDI+B8] ; 获取异常地址(4A7781)0049F58C 51 PUSH ECX0049F58D 6A 00 PUSH 0 ; /pBytesRead = NULL0049F58F 6A 01 PUSH 1 ; |BytesToRead = 10049F591 8D83 F6C24000 LEA EAX,DWORD PTR DS:[EBX+40C2F6] ; |0049F597 50 PUSH EAX ; |Buffer = Explorer.004AA2F60049F598 51 PUSH ECX ; |pBaseAddress = 4A77810049F599 FF36 PUSH DWORD PTR DS:[ESI] ; |hProcess = 000000340049F59B FF93 63BC4000 CALL DWORD PTR DS:[EBX+40BC63] ; \ReadProcessMemory0049F5A1 59 POP ECX0049F5A2 8D83 F6C24000 LEA EAX,DWORD PTR DS:[EBX+40C2F6]0049F5A8 8A00 MOV AL,BYTE PTR DS:[EAX]0049F5AA 34 52 XOR AL,520049F5AC 8883 F6C24000 MOV BYTE PTR DS:[EBX+40C2F6],AL0049F5B2 51 PUSH ECX0049F5B3 6A 00 PUSH 0 ; /pBytesWritten = NULL0049F5B5 6A 01 PUSH 1 ; |BytesToWrite = 10049F5B7 8D83 F6C24000 LEA EAX,DWORD PTR DS:[EBX+40C2F6] ; |0049F5BD 50 PUSH EAX ; |Buffer = Explorer.004AA2F60049F5BE 51 PUSH ECX ; |Address = 4A77810049F5BF FF36 PUSH DWORD PTR DS:[ESI] ; |hProcess = 000000340049F5C1 FF93 A4BC4000 CALL DWORD PTR DS:[EBX+40BCA4] ; \WriteProcessMemory0049F5C7 59 POP ECX0049F5C8 8D83 04BA4000 LEA EAX,DWORD PTR DS:[EBX+40BA04] ; 结束地址4A9A040049F5CE 41 INC ECX0049F5CF 3BC8 CMP ECX,EAX0049F5D1 75 02 JNZ SHORT 0049F5D5 ; 判断有没有结束,没有结束则跳回去继续0049F5D3 EB 02 JMP SHORT 0049F5D70049F5D5 ^ EB B5 JMP SHORT 0049F58C0049F5D7 51 PUSH ECX0049F5D8 8B87 B8000000 MOV EAX,DWORD PTR DS:[EDI+B8]0049F5DE 8987 B8000000 MOV DWORD PTR DS:[EDI+B8],EAX0049F5E4 57 PUSH EDI ; /pContext = Explorer.004AA5640049F5E5 FF76 04 PUSH DWORD PTR DS:[ESI+4] ; |hThread = 00000038 (window)0049F5E8 FF93 8DBC4000 CALL DWORD PTR DS:[EBX+40BC8D] ; \SetThreadContext0049F5EE 8B87 B8000000 MOV EAX,DWORD PTR DS:[EDI+B8]0049F5F4 59 POP ECX0049F5F5 2BC8 SUB ECX,EAX0049F5F7 51 PUSH ECX ; /RegionSize = 22830049F5F8 50 PUSH EAX ; |RegionBase = Explorer.004A77810049F5F9 FF36 PUSH DWORD PTR DS:[ESI] ; |hProcess = 000000340049F5FB FF93 BEBC4000 CALL DWORD PTR DS:[EBX+40BCBE] ; \FlushInstructionCache0049F601 5A POP EDX0049F602 68 02000100 PUSH 10002 ; /ContinueStatus = DBG_CONTINUE0049F607 FF72 08 PUSH DWORD PTR DS:[EDX+8] ; |ThreadId = 2140049F60A FF72 04 PUSH DWORD PTR DS:[EDX+4] ; |ProcessId = 57C0049F60D FF93 86BB4000 CALL DWORD PTR DS:[EBX+40BB86] ; \ContinueDebugEvent0049F613 EB 40 JMP SHORT 0049F6550049F615 68 01000180 PUSH 80010001 ; /DBG_EXCEPTION_NOT_HANDLED0049F61A FF72 08 PUSH DWORD PTR DS:[EDX+8] ; |dwThreadId0049F61D FF72 04 PUSH DWORD PTR DS:[EDX+4] ; |dwProcessId0049F620 FF93 86BB4000 CALL DWORD PTR DS:[EBX+40BB86] ; \ContinueDebugEvent0049F626 EB 2D JMP SHORT 0049F6550049F628 68 01000180 PUSH 80010001 ; /DBG_EXCEPTION_NOT_HANDLED0049F62D FF72 08 PUSH DWORD PTR DS:[EDX+8] ; |dwThreadId0049F630 FF72 04 PUSH DWORD PTR DS:[EDX+4] ; |dwProcessId0049F633 FF93 86BB4000 CALL DWORD PTR DS:[EBX+40BB86] ; \ContinueDebugEvent0049F639 EB 1A JMP SHORT 0049F6550049F63B 833A 05 CMP DWORD PTR DS:[EDX],50049F63E 75 04 JNZ SHORT 0049F6440049F640 EB 18 JMP SHORT 0049F65A0049F642 EB 11 JMP SHORT 0049F6550049F644 68 02000100 PUSH 10002 ; /ContinueStatus = DBG_CONTINUE0049F649 FF72 08 PUSH DWORD PTR DS:[EDX+8] ; |dwThreadId0049F64C FF72 04 PUSH DWORD PTR DS:[EDX+4] ; |dwProcessId0049F64F FF93 86BB4000 CALL DWORD PTR DS:[EBX+40BB86] ; \ContinueDebugEvent0049F655 ^ E9 8BFEFFFF JMP 0049F4E50049F65A 61 POPAD0049F65B C9 LEAVE0049F65C C2 0400 RETN 4004A5E5B 90 NOP ; 调试完程序结束004A5E5C 6A 00 PUSH 0 ; /Exit Code = 0004A5E5E FF95 47BB4000 CALL DWORD PTR SS:[EBP+40BB47] ; \ExitProcess
到这里我们可以总结一下:壳只用了一个anti-debug,然后通过调试标志’X’判断是否为子进程。壳只处理INT3异常,异常时把从4A7781到4A9A04处的代码xor 52还原出正确代码。现在再写一段脚本用于直接跳为单进程的方式:var addrstart: 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 PUSHAD0049F69E E8 00000000 CALL 0049F6A30049F6A3 5B POP EBX0049F6A4 81EB A3164000 SUB EBX,004016A3 ; 计算重定位值0049F6AA B9 00010000 MOV ECX,1000049F6AF BA 2083B8ED MOV EDX,EDB883200049F6B4 8D41 FF LEA EAX,DWORD PTR DS:[ECX-1]0049F6B7 51 PUSH ECX0049F6B8 B9 08000000 MOV ECX,80049F6BD D1E8 SHR EAX,10049F6BF 73 02 JNB SHORT 0049F6C30049F6C1 33C2 XOR EAX,EDX0049F6C3 49 DEC ECX0049F6C4 ^ 75 F7 JNZ SHORT 0049F6BD0049F6C6 59 POP ECX0049F6C7 8DBB FABD4000 LEA EDI,DWORD PTR DS:[EBX+40BDFA]0049F6CD 89448F FC MOV DWORD PTR DS:[EDI+ECX*4-4],EAX 0049F6D1 49 DEC ECX0049F6D2 ^ 75 E0 JNZ SHORT 0049F6B40049F6D4 61 POPAD0049F6D5 C3 RETN……004A5E99 E8 00000000 CALL 004A5E9E004A5E9E 90 NOP004A5E9F 90 NOP004A5EA0 90 NOP004A5EA1 90 NOP004A5EA2 59 POP ECX004A5EA3 81E9 9E7E4000 SUB ECX,00407E9E004A5EA9 BB 0B174000 MOV EBX,0040170B004A5EAE 03D9 ADD EBX,ECX ; 计算出壳的EP004A5EB0 B9 93670000 MOV ECX,6793004A5EB5 E8 1C98FFFF CALL 0049F6D6 ; 这里进去计算crc值004A5EBA 8985 2AC24000 MOV DWORD PTR SS:[EBP+40C22A],EAX ; CRC值保存到[4AA22A处……004A5F1C 6A 00 PUSH 0 ; /phModule = 0004A5F1E FF95 C0BA4000 CALL DWORD PTR SS:[EBP+40BAC0] ; \GetModuleHandleA004A5F24 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],EBX004A5F39 8B85 E2BD4000 MOV EAX,DWORD PTR SS:[EBP+40BDE2]004A5F3F 05 F8000000 ADD EAX,0F8004A5F44 8985 E6BD4000 MOV DWORD PTR SS:[EBP+40BDE6],EAX ; 定位Section name004A5F4A 8B58 0C MOV EBX,DWORD PTR DS:[EAX+C] ; Section Voffset=1000004A5F4D 039D DEBD4000 ADD EBX,DWORD PTR SS:[EBP+40BDDE]004A5F53 899D EABD4000 MOV DWORD PTR SS:[EBP+40BDEA],EBX004A5F59 8B58 08 MOV EBX,DWORD PTR DS:[EAX+8] ; Vsize=73000004A5F5C 899D EEBD4000 MOV DWORD PTR SS:[EBP+40BDEE],EBX004A5F62 8B58 10 MOV EBX,DWORD PTR DS:[EAX+10] ; Rsize=31c00004A5F65 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 = GPTR004A5F73 FF95 F4BA4000 CALL DWORD PTR SS:[EBP+40BAF4] ; \GlobalAlloc004A5F79 0BC0 OR EAX,EAX004A5F7B 75 05 JNZ SHORT 004A5F82 ; 如果分配成功则跳004A5F7D E9 2C3B0000 JMP 004A9AAE004A5F82 8BF8 MOV EDI,EAX ; mov edi,hmem……004A5FC3 8B85 EABD4000 MOV EAX,DWORD PTR SS:[EBP+40BDEA]004A5FC9 57 PUSH EDI ; /hmem =00142AB8004A5FCA 50 PUSH EAX ; |Uzip address = 401000004A5FCB E8 353A0000 CALL 004A9A05 ; \ApLib_Unpack004A5FD0 58 POP EAX004A5FD1 5F POP EDI……004A6032 FC CLD004A6033 8B8D EEBD4000 MOV ECX,DWORD PTR SS:[EBP+40BDEE]004A6039 8BF7 MOV ESI,EDI004A603B 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] ; 重定位值9E000004A60FA FFB5 DEBD4000 PUSH DWORD PTR SS:[EBP+40BDDE] ; imagebase004A6100 E8 EF92FFFF CALL 0049F3F4 ; 这里进去就是输入表还原0049F3F4 55 PUSH EBP0049F3F5 8BEC MOV EBP,ESP0049F3F7 83C4 F8 ADD ESP,-80049F3FA 60 PUSHAD0049F3FB 8B45 08 MOV EAX,DWORD PTR SS:[EBP+8]0049F3FE 8B50 3C MOV EDX,DWORD PTR DS:[EAX+3C] ; 定位pe头0049F401 03C2 ADD EAX,EDX0049F403 8B90 80000000 MOV EDX,DWORD PTR DS:[EAX+80] ; 定位输入表0049F409 0355 08 ADD EDX,DWORD PTR SS:[EBP+8]0049F40C 8BFA MOV EDI,EDX0049F40E 8B5F 0C MOV EBX,DWORD PTR DS:[EDI+C]0049F411 83FB 00 CMP EBX,00049F414 74 3C JE SHORT 0049F452 ; 如果输入表处理完就跳去结束处0049F416 035D 08 ADD EBX,DWORD PTR SS:[EBP+8]0049F419 895D FC MOV DWORD PTR SS:[EBP-4],EBX0049F41C 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],EBX0049F424 33C9 XOR ECX,ECX0049F426 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 0049F4340049F431 89048B MOV DWORD PTR DS:[EBX+ECX*4],EAX0049F434 8B5D FC MOV EBX,DWORD PTR SS:[EBP-4]0049F437 8B45 0C MOV EAX,DWORD PTR SS:[EBP+C]0049F43A 05 BA124000 ADD EAX,004012BA0049F43F 89048B MOV DWORD PTR DS:[EBX+ECX*4],EAX0049F442 41 INC ECX0049F443 8B048B MOV EAX,DWORD PTR DS:[EBX+ECX*4]0049F446 83F8 00 CMP EAX,00049F449 74 02 JE SHORT 0049F44D ; 如果当前DLL处理完则跳去处理下一个DLL的相关API0049F44B ^ EB D9 JMP SHORT 0049F426 ; 循环回去还原输入表0049F44D 83C7 14 ADD EDI,140049F450 ^ EB BC JMP SHORT 0049F40E0049F452 61 POPAD0049F453 C9 LEAVE0049F454 C2 0800 RETN 8……004A61B9 FFB5 F6BD4000 PUSH DWORD PTR SS:[EBP+40BDF6] ; 重定位值004A61BF FFB5 DEBD4000 PUSH DWORD PTR SS:[EBP+40BDDE] ; hmodule004A61C5 E8 9594FFFF CALL 0049F65F ; 这里进去就是Load All Library0049F65F 55 PUSH EBP0049F660 8BEC MOV EBP,ESP0049F662 60 PUSHAD0049F663 8B45 08 MOV EAX,DWORD PTR SS:[EBP+8]0049F666 8B50 3C MOV EDX,DWORD PTR DS:[EAX+3C] ; 定位PE头0049F669 03C2 ADD EAX,EDX0049F66B 8B90 80000000 MOV EDX,DWORD PTR DS:[EAX+80] ; 定位输入表0049F671 0355 08 ADD EDX,DWORD PTR SS:[EBP+8]0049F674 8BFA MOV EDI,EDX0049F676 8B5F 0C MOV EBX,DWORD PTR DS:[EDI+C]0049F679 83FB 00 CMP EBX,00049F67C 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,EBX0049F689 56 PUSH ESI ; /push FileName0049F68A 8B5D 0C MOV EBX,DWORD PTR SS:[EBP+C] ; |0049F68D FF93 D1BA4000 CALL DWORD PTR DS:[EBX+40BAD1] ; \LoadLibraryA0049F693 83C7 14 ADD EDI,140049F696 ^ EB DE JMP SHORT 0049F676 ; 跳去取下一个dll名0049F698 61 POPAD0049F699 C9 LEAVE0049F69A C2 0800 RETN 8……004A7780 CC INT3 ; 再下来这里就异常了,记得上面我们保存下来的代码吗?是了,把从4A7781处到4A9A04处的代码还原正确的回去。004A7781 33C9 XOR ECX,ECX004A7783 8B9D FEC14000 MOV EBX,DWORD PTR SS:[EBP+40C1FE] ; 还原API的地址[4AA1FE]=004AAA00004A7789 EB 15 JMP SHORT 004A77A0004A778B FF348B PUSH DWORD PTR DS:[EBX+ECX*4] ; 471cec004A778E FFB5 F6BD4000 PUSH DWORD PTR SS:[EBP+40BDF6] ; relo =9e000004A7794 FFB5 DEBD4000 PUSH DWORD PTR SS:[EBP+40BDDE] ; pe header =400000004A779A E8 DE78FFFF CALL 0049F07D ; Fill Api Function0049F07D 55 PUSH EBP0049F07E 8BEC MOV EBP,ESP0049F080 83C4 EC ADD ESP,-140049F083 60 PUSHAD0049F084 8B45 08 MOV EAX,DWORD PTR SS:[EBP+8]0049F087 8B50 3C MOV EDX,DWORD PTR DS:[EAX+3C]0049F08A 03C2 ADD EAX,EDX0049F08C 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],EDX0049F098 8BFA MOV EDI,EDX0049F09A 8B5F 10 MOV EBX,DWORD PTR DS:[EDI+10]0049F09D 83FB 00 CMP EBX,00049F0A0 0F84 09010000 JE 0049F1AF ; 如果输入表处理完则啵0049F0A6 035D 08 ADD EBX,DWORD PTR SS:[EBP+8]0049F0A9 895D F0 MOV DWORD PTR SS:[EBP-10],EBX0049F0AC FF75 F0 PUSH DWORD PTR SS:[EBP-10] ; push DLL name0049F0AF 8B5D 0C MOV EBX,DWORD PTR SS:[EBP+C]0049F0B2 FF93 C0BA4000 CALL DWORD PTR DS:[EBX+40BAC0] ; GetModuleHandleA获取dll的句柄0049F0B8 8BD0 MOV EDX,EAX0049F0BA 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],EBX0049F0C3 8B1F MOV EBX,DWORD PTR DS:[EDI] ; OfirstThunk0049F0C5 83FB 00 CMP EBX,00049F0C8 0F84 8B000000 JE 0049F159 ; 如果OriginalFirstThunk为空则跳0049F0CE 035D 08 ADD EBX,DWORD PTR SS:[EBP+8]0049F0D1 895D F4 MOV DWORD PTR SS:[EBP-C],EBX0049F0D4 33C9 XOR ECX,ECX0049F0D6 8B75 F4 MOV ESI,DWORD PTR SS:[EBP-C]0049F0D9 8B048E MOV EAX,DWORD PTR DS:[ESI+ECX*4]0049F0DC 83F8 00 CMP EAX,00049F0DF 0F84 C2000000 JE 0049F1A7 ; 比较当前DLL的API函数是否已经处理完了0049F0E5 25 00000080 AND EAX,800000000049F0EA 83F8 00 CMP EAX,00049F0ED 74 32 JE SHORT 0049F121 ; 判断是否为序号方式获取,如果是认名字则啵0049F0EF 8B048E MOV EAX,DWORD PTR DS:[ESI+ECX*4]0049F0F2 25 FFFFFF7F AND EAX,7FFFFFFF0049F0F7 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 0049F11E0049F102 51 PUSH ECX0049F103 52 PUSH EDX0049F104 50 PUSH EAX0049F105 52 PUSH EDX0049F106 8B5D 0C MOV EBX,DWORD PTR SS:[EBP+C]0049F109 FF93 E4BA4000 CALL DWORD PTR DS:[EBX+40BAE4]0049F10F 5A POP EDX0049F110 59 POP ECX0049F111 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],EAX0049F119 E9 91000000 JMP 0049F1AF0049F11E 41 INC ECX0049F11F ^ EB B5 JMP SHORT 0049F0D60049F121 8B75 F4 MOV ESI,DWORD PTR SS:[EBP-C] ; OriginalFirstThunk0049F124 8B048E MOV EAX,DWORD PTR DS:[ESI+ECX*4]0049F127 83F8 00 CMP EAX,00049F12A 74 7B JE SHORT 0049F1A70049F12C 0345 08 ADD EAX,DWORD PTR SS:[EBP+8]0049F12F 83C0 02 ADD EAX,20049F132 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 0049F1560049F13D 51 PUSH ECX0049F13E 52 PUSH EDX0049F13F 50 PUSH EAX ; /ProcNameOrOrdinal0049F140 52 PUSH EDX ; |hModule0049F141 8B5D 0C MOV EBX,DWORD PTR SS:[EBP+C] ; |0049F144 FF93 E4BA4000 CALL DWORD PTR DS:[EBX+40BAE4] ; \GetProcAddress0049F14A 5A POP EDX0049F14B 59 POP ECX0049F14C 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],EAX0049F154 EB 59 JMP SHORT 0049F1AF0049F156 41 INC ECX0049F157 ^ EB C8 JMP SHORT 0049F1210049F159 33C9 XOR ECX,ECX0049F15B 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],EBX0049F164 8B75 F0 MOV ESI,DWORD PTR SS:[EBP-10]0049F167 803E 00 CMP BYTE PTR DS:[ESI],00049F16A 74 03 JE SHORT 0049F16F0049F16C 46 INC ESI0049F16D ^ EB F8 JMP SHORT 0049F1670049F16F 46 INC ESI0049F170 3B75 EC CMP ESI,DWORD PTR SS:[EBP-14]0049F173 74 32 JE SHORT 0049F1A70049F175 803E 00 CMP BYTE PTR DS:[ESI],00049F178 ^ 74 F5 JE SHORT 0049F16F0049F17A 837E 01 00 CMP DWORD PTR DS:[ESI+1],00049F17E 74 2F JE SHORT 0049F1AF0049F180 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 0049F1A40049F18B 51 PUSH ECX0049F18C 52 PUSH EDX0049F18D 56 PUSH ESI0049F18E 52 PUSH EDX0049F18F 8B5D 0C MOV EBX,DWORD PTR SS:[EBP+C]0049F192 FF93 E4BA4000 CALL DWORD PTR DS:[EBX+40BAE4]0049F198 5A POP EDX0049F199 59 POP ECX0049F19A 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],EAX0049F1A2 EB 0B JMP SHORT 0049F1AF0049F1A4 41 INC ECX0049F1A5 ^ EB C0 JMP SHORT 0049F1670049F1A7 83C7 14 ADD EDI,140049F1AA ^ E9 EBFEFFFF JMP 0049F09A0049F1AF 61 POPAD0049F1B0 C9 LEAVE0049F1B1 C2 0C00 RETN 0C 004A779F 41 INC ECX004A77A0 3B8D FAC14000 CMP ECX,DWORD PTR SS:[EBP+40C1FA]004A77A6 ^ 72 E3 JB SHORT 004A778B ; 循环处理输入表……004A8303 8BC5 MOV EAX,EBP004A8305 8B95 2AC24000 MOV EDX,DWORD PTR SS:[EBP+40C22A] ; 校验值2cd76ec4004A830B 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 EDI004A8318 5A POP EDX004A8319 59 POP ECX004A831A 5E POP ESI004A831B 5B POP EBX004A831C 5D POP EBP004A831D 05 FA114000 ADD EAX,004011FA004A8322 50 PUSH EAX004A8323 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,004011FA004A8336 FFB0 02C24000 PUSH DWORD PTR DS:[EAX+40C202] ; push oep……004A9A04 C3 RETN ; 终于到光明顶了:-)下面看看API的处理:0049F2BA E8 00000000 CALL 0049F2BF0049F2BF 58 POP EAX0049F2C0 2D BF124000 SUB EAX,004012BF0049F2C5 C780 22C24000 0>MOV DWORD PTR DS:[EAX+40C222],00049F2CF 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 EAX0049F2DE 8B40 FC MOV EAX,DWORD PTR DS:[EAX-4]0049F2E1 EB 7D JMP SHORT 0049F3600049F2E3 8038 EB CMP BYTE PTR DS:[EAX],0EB ; 判断是否为BC的程序jmp xxxx0049F2E6 75 06 JNZ SHORT 0049F2EE ; 如果不是则跳0049F2E8 58 POP EAX0049F2E9 8B40 FC MOV EAX,DWORD PTR DS:[EAX-4] ; 获取要保存输入表的地址iat0049F2EC EB 72 JMP SHORT 0049F360 ; 然后跳去获取api函数0049F2EE 8B0424 MOV EAX,DWORD PTR SS:[ESP]0049F2F1 817C24 04 00000>CMP DWORD PTR SS:[ESP+4],800000000049F2F9 73 06 JNB SHORT 0049F3010049F2FB 334424 04 XOR EAX,DWORD PTR SS:[ESP+4]0049F2FF EB 08 JMP SHORT 0049F3090049F301 8B0424 MOV EAX,DWORD PTR SS:[ESP]0049F304 8B40 FC MOV EAX,DWORD PTR DS:[EAX-4]0049F307 EB 57 JMP SHORT 0049F3600049F309 3D 00001000 CMP EAX,1000000049F30E 73 06 JNB SHORT 0049F3160049F310 58 POP EAX0049F311 8B40 FC MOV EAX,DWORD PTR DS:[EAX-4]0049F314 EB 4A JMP SHORT 0049F3600049F316 3D 00000070 CMP EAX,700000000049F31B 73 08 JNB SHORT 0049F3250049F31D 8B0424 MOV EAX,DWORD PTR SS:[ESP]0049F320 8B40 FC MOV EAX,DWORD PTR DS:[EAX-4]0049F323 EB 3B JMP SHORT 0049F3600049F325 813C24 00000070 CMP DWORD PTR SS:[ESP],700000000049F32C 73 01 JNB SHORT 0049F32F0049F32E 58 POP EAX0049F32F E8 00000000 CALL 0049F3340049F334 58 POP EAX0049F335 2D 34134000 SUB EAX,004013340049F33A C780 22C24000 0>MOV DWORD PTR DS:[EAX+40C222],10049F344 8B8424 E4000000 MOV EAX,DWORD PTR SS:[ESP+E4]0049F34B 3D 03000080 CMP EAX,800000030049F350 0F85 98000000 JNZ 0049F3EE0049F356 8B8424 F0000000 MOV EAX,DWORD PTR SS:[ESP+F0]0049F35D 8B40 02 MOV EAX,DWORD PTR DS:[EAX+2]0049F360 60 PUSHAD ; 下面准备填充iat0049F361 E8 00000000 CALL 0049F3660049F366 5D POP EBP0049F367 81ED 66134000 SUB EBP,00401366 ; 计算重定位值0049F36D 50 PUSH EAX ; push iat address0049F36E FFB5 F6BD4000 PUSH DWORD PTR SS:[EBP+40BDF6] ; push relo(9E000)0049F374 FFB5 DEBD4000 PUSH DWORD PTR SS:[EBP+40BDDE] ; push hmodule0049F37A E8 FEFCFFFF CALL 0049F07D ; GetProcAddress获取填充api0049F37F 61 POPAD0049F380 52 PUSH EDX0049F381 51 PUSH ECX0049F382 E8 00000000 CALL 0049F3870049F387 5A POP EDX0049F388 81EA 87134000 SUB EDX,004013870049F38E 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,ECX0049F39A 59 POP ECX0049F39B 5A POP EDX0049F39C 52 PUSH EDX0049F39D E8 00000000 CALL 0049F3A20049F3A2 5A POP EDX0049F3A3 81EA A2134000 SUB EDX,004013A2 ; 计算reloc0049F3A9 83BA 22C24000 0>CMP DWORD PTR DS:[EDX+40C222],00049F3B0 75 05 JNZ SHORT 0049F3B70049F3B2 5A POP EDX0049F3B3 FFE0 JMP EAX ; 跳去执行api函数0049F3B5 EB 37 JMP SHORT 0049F3EE0049F3B7 5A POP EDX0049F3B8 8BBC24 F0000000 MOV EDI,DWORD PTR SS:[ESP+F0]0049F3BF 83C7 01 ADD EDI,10049F3C2 803F 3D CMP BYTE PTR DS:[EDI],3D0049F3C5 74 0B JE SHORT 0049F3D20049F3C7 8B7D 10 MOV EDI,DWORD PTR SS:[EBP+10]0049F3CA 8987 A0000000 MOV DWORD PTR DS:[EDI+A0],EAX0049F3D0 EB 09 JMP SHORT 0049F3DB0049F3D2 8B7D 10 MOV EDI,DWORD PTR SS:[EBP+10]0049F3D5 8987 9C000000 MOV DWORD PTR DS:[EDI+9C],EAX0049F3DB 8B8424 F0000000 MOV EAX,DWORD PTR SS:[ESP+F0]0049F3E2 83C0 06 ADD EAX,60049F3E5 8987 B8000000 MOV DWORD PTR DS:[EDI+B8],EAX0049F3EB 33C0 XOR EAX,EAX0049F3ED C3 RETN分析完api的处理后,写上一段修复程序: 00473601 60 PUSHAD00473602 B8 24EE4500 MOV EAX,0045EE24 ; JMP to BORLNDMM.GetAllocMemCount00473607 66:8138 FF15 CMP WORD PTR DS:[EAX],15FF0047360C 75 33 JNZ SHORT 004736410047360E 8B50 02 MOV EDX,DWORD PTR DS:[EAX+2]00473611 81FA 00000008 CMP EDX,800000000473617 73 28 JNB SHORT 0047364100473619 81FA 00004000 CMP EDX,00400000 ; ASCII "MZP"0047361F 72 20 JB SHORT 0047364100473621 813A BAF24900 CMP DWORD PTR DS:[EDX],0049F2BA00473627 75 15 JNZ SHORT 0047363E00473629 52 PUSH EDX ;将要保存的地址0047362A 68 00E00900 PUSH 9E000 ;重定位值0047362F 68 00004000 PUSH 00400000 ; ASCII "MZP"00473634 E8 44BA0200 CALL 0049F07D ;填充api00473639 66:C700 FF25 MOV WORD PTR DS:[EAX],25FF0047363E 83C0 05 ADD EAX,500473641 40 INC EAX00473642 3D 58F74500 CMP EAX,0045F75800473647 ^ 72 BE JB SHORT 0047360700473649 61 POPAD0047364A ^ 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 2081 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 0540 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.comDate:2005-02-25 12:24
本文地址:http://com.8s8s.com/it/it22388.htm