|
某外挂程序外壳的一点分析(上) 【目 标】:某外挂程序 【工 具】:Olydbg1.1 【操作平台】:WINXP pro sp1 【作 者】:loveboom[DFCG][FCG][US] 【简要说明】: 国庆也过了,自己这段时间也没写什么文章,现趁国庆之余凑上一篇文章,因外壳关系到圈内人士,所以,咱们内部成员看看就是了。没经过本人的同意,请不要随意转载哦:-). 【详细过程】: 也不多说什么了,你慢慢看吧!!… 004C559E > /E9 00000000 JMP 004C55A3 ; 这里伪装成XPR的壳的入口 004C55A3 \60 PUSHAD 004C55A4 E8 14000000 CALL 004C55BD 004C55A9 5D POP EBP 004C55AA 81ED 00000000 SUB EBP,0 004C55B0 6A 45 PUSH 45 004C55B2 E8 A3000000 CALL 004C565A 004C55B7 68 00000000 PUSH 0 004C55BC 90 NOP 004C55BD 58 POP EAX 004C55BE 61 POPAD ; 看一下这里就知道是骗人的东西了 004C55BF ^ E9 0DBBFEFF JMP 004B10D1 004B10D7 5D POP EBP ; mov ebp,5b10d7 004B10D8 81ED D7000000 SUB EBP,0D7 004B10DE 8DB5 EE000000 LEA ESI,DWORD PTR SS:[EBP+EE] 004B10E4 55 PUSH EBP 004B10E5 56 PUSH ESI ; 准备从4B10EE处解压代码 004B10E6 81C5 890B0000 ADD EBP,0B89 004B10EC 55 PUSH EBP ; 转去4B1B89处开始解压代码 004B10ED C3 RETN …… 004B1EA5 45 INC EBP 004B1EA6 25 1C790119 AND EAX,1901791C 004B1EAB B8 A4C0F368 MOV EAX,68F3C0A4 004B1EB0 8132 91D56240 XOR DWORD PTR DS:[EDX],4062D591 ; 很多类似这样的解压代码 004B1EB6 B8 370C2157 MOV EAX,57210C37 004B1EBB 4F DEC EDI 004B1EBC B8 42487B77 MOV EAX,777B4842 004B1EC1 8D85 24ACAE31 LEA EAX,DWORD PTR SS:[EBP+31AEAC24] 004B1EC7 B8 8E336864 MOV EAX,6468338E 004B1ECC 42 INC EDX …… 004B2FE1 81EA 2A812A81 SUB EDX,812A812A 004B2FE7 FF0424 INC DWORD PTR SS:[ESP] 004B2FEA C3 RETN ; 上面的一段解压后到这里,这里返回到4B10F0处,也就是跳去刚开始解压代码的起始处+1. …… 到了这里我就知道快速到这里方法了.在程序一开始的push esi的esp中下硬件访问断点这样一下两次就会到4B2FEA处. 004B10D7 5D POP EBP ; mov ebp,5b10d7 004B10D8 81ED D7000000 SUB EBP,0D7 004B10DE 8DB5 EE000000 LEA ESI,DWORD PTR SS:[EBP+EE] 004B10E4 55 PUSH EBP 004B10E5 56 PUSH ESI ; 准备从4B10EE处解压代码 004B10E6 81C5 890B0000 ADD EBP,0B89 004B10EC 55 PUSH EBP ; 转去4B1B89处开始解压代码 004B10ED C3 RETN 004B10EE EB 5D JMP SHORT 004B114D 004B10F0 8B45 00 MOV EAX,DWORD PTR SS:[EBP] ; 是否已经解压的标志,这个一般是对DLL来说的 004B10F3 0BC0 OR EAX,EAX 004B10F5 74 04 JE SHORT 004B10FB ; 如果没有标志就跳 004B10F7 55 PUSH EBP 004B10F8 FF65 0C JMP DWORD PTR SS:[EBP+C] 004B10FB FF45 00 INC DWORD PTR SS:[EBP] ; 如果是没有解压的话,在4B1000处置一个1的标志 004B10FE 8B4424 24 MOV EAX,DWORD PTR SS:[ESP+24] 004B1102 8945 04 MOV DWORD PTR SS:[EBP+4],EAX 004B1105 8DB5 84000000 LEA ESI,DWORD PTR SS:[EBP+84] ; 哈哈,看看这里保存了什幺东东哦.把dll的名称保存地址放到esi中 004B110B 56 PUSH ESI ; 地址4B1084入栈(KERNEL32.DLL) 004B110C FF55 78 CALL DWORD PTR SS:[EBP+78] ; GetModuleHandleA 004B110F 8D75 1C LEA ESI,DWORD PTR SS:[EBP+1C] ; 把VirtualAlloc名称所在的地址传到esi中 004B1112 56 PUSH ESI 004B1113 50 PUSH EAX ; 传入Kernel32的hmodule,因为windows在运行的话,程序就一定GetModuleHandleA成功的 004B1114 FF55 74 CALL DWORD PTR SS:[EBP+74] ; 获取VirtualAlloc的地址 …… 0012FF9C 004B110F /CALL to GetModuleHandleA from xxx.004B110C 0012FFA0 004B1084 \pModule = "KERNEL32.dll" …… 0012FF98 004B1117 /CALL to GetProcAddress from xxx.004B1114 0012FF9C 77E40000 |hModule = 77E40000 (kernel32) 0012FFA0 004B101C \ProcNameOrOrdinal = "VirtualAlloc" 0012FFA4 0012CD78 …… 004B1117 8945 2C MOV DWORD PTR SS:[EBP+2C],EAX ; 再把取出VirtualAlloc的地址存入4B102C处 004B111A 6A 04 PUSH 4 ; 这幺快就要申请空间了,够直接嘛! 004B111C 68 00100000 PUSH 1000 004B1121 FF75 10 PUSH DWORD PTR SS:[EBP+10] 004B1124 6A 00 PUSH 0 004B1126 FF55 2C CALL DWORD PTR SS:[EBP+2C] ; 申请空间,VirtualAlloc …… 0012FF90 004B1129 /CALL to VirtualAlloc from xxx.004B1126 0012FF94 00000000 |Address = NULL 0012FF98 0001670F |Size = 1670F (91919.) 0012FF9C 00001000 |AllocationType = MEM_COMMIT 0012FFA0 00000004 \Protect = PAGE_READWRITE …… 004B1129 50 PUSH EAX ; 申请到的空间为00370000,入栈先 004B112A 8945 0C MOV DWORD PTR SS:[EBP+C],EAX ; 把申请到的空间保存到4B100C处 004B112D 8B5D 08 MOV EBX,DWORD PTR SS:[EBP+8] ; 译码代码相对偏移1FFE 004B1130 03DD ADD EBX,EBP ; 把RVA转换成VA=4B2FFE 004B1132 50 PUSH EAX ; 刚纔申请的址址00370000,用于存放解压的代码 004B1133 53 PUSH EBX ; 源地址4B2FFE入栈 004B1134 E8 18000000 CALL 004B1151 ;这里解压代码 …… 004B115B 8B7424 20 MOV ESI,DWORD PTR SS:[ESP+20] ; 源地址入esi 004B115F 8B7C24 24 MOV EDI,DWORD PTR SS:[ESP+24] ; 目标地址370000入edi …… 解压完毕,到这里. 004B1139 5A POP EDX ; 解压完毕,把申请的地址370000放到edx中 004B113A 52 PUSH EDX 004B113B 55 PUSH EBP 004B113C 8D85 DE000000 LEA EAX,DWORD PTR SS:[EBP+DE] ; 把4B10DE 放到eax中 004B1142 C600 EB MOV BYTE PTR DS:[EAX],0EB ; [eax]中存放0EB,也就是近距离的跳 004B1145 C640 01 10 MOV BYTE PTR DS:[EAX+1],10 ; 这里还在改代码 004B1149 8B45 30 MOV EAX,DWORD PTR SS:[EBP+30] ; 改完后,把4B1030处的东西保存到[ebp+74]处 004B114C 8945 74 MOV DWORD PTR SS:[EBP+74],EAX ; 4B1074保存00EC6915 004B114F - FFE2 JMP EDX ; 改完后跳去刚才解压的那个地方 00370000 E8 24000000 CALL 00370029 ; JMP EDX到这里 00370005 8B4424 04 MOV EAX,DWORD PTR SS:[ESP+4] …… 00370027 /EB 24 JMP SHORT 0037004D 00370029 |64:FF35 0000000>PUSH DWORD PTR FS:[0] ; 准备异常了 00370030 |EB 12 JMP SHORT 00370044 00370032 |90 NOP 00370033 |9C PUSHFD 00370034 |74 03 JE SHORT 00370039 00370036 |75 01 JNZ SHORT 00370039 00370038 |90 NOP 00370039 |810C24 00010000 OR DWORD PTR SS:[ESP],100 ; 不小心进来了晕,再来 00370040 |9D POPFD …… 00370041 90 NOP 00370042 ^ EB F4 JMP SHORT 00370038 ; 这里单步异常了 …… 00370158 ^\EB E6 JMP SHORT 00370140 0037015A E8 24000000 CALL 00370183 ; 类似这样的代码就要小心了,不要乱要f7哦,这样的代码我的对付方法是:因壳是用的宏,所以我们看到几个后就可以找到规律的,找到了规律就好办嘛。 0037015F 8B4424 04 MOV EAX,DWORD PTR SS:[ESP+4] ; 直接在这里下断,后面类似这样的也可以用这种方法解决 00370163 8B00 MOV EAX,DWORD PTR DS:[EAX] …… 0037313B E8 00000000 CALL 00373140 00373140 5A POP EDX ; EDX=373140过了N个宏之后到了这里,本来想用脚本跑到这里来,但怕后面的CRC,所以还是慢慢的跟到这里 00373141 81EA 9E1B4000 SUB EDX,401B9E …… 0037314D 90 NOP 0037314E 90 NOP 0037314F 5D POP EBP ; POP imageBase,4B1000 00373150 EB 4A JMP SHORT 0037319C 00373152 ^ EB DF JMP SHORT 00373133 00373154 43 INC EBX 00373155 90 NOP 00373156 90 NOP 00373157 90 NOP 00373158 58 POP EAX 00373159 ^ 7D F4 JGE SHORT 0037314F 0037315B EB 01 JMP SHORT 0037315E 0037315D 90 NOP 0037315E ^ 7C EF JL SHORT 0037314F 00373160 90 NOP 00373161 58 POP EAX 00373162 9C PUSHFD 00373163 05 E6FFFFFF ADD EAX,-1A 00373168 9D POPFD 00373169 FFE0 JMP EAX ; JMP 00373158 0037316B 90 NOP …… 00373178 B9 03000000 MOV ECX,3 0037317D EB 4A JMP SHORT 003731C9 …… 003731A8 8D75 74 LEA ESI,DWORD PTR SS:[EBP+74] ; GetProcAddress的地址入esi …… 003731D5 8DBA 020F4100 LEA EDI,DWORD PTR DS:[EDX+410F02] ; EDI=003824A4 这个版本的壳,垃圾代码真多哦。跟的时候千万要小心一点 00373226 50 PUSH EAX ; eax=003730F3又是来这幺一招,晕倒,已经有好几个这样的东西了 …… 00373205 F3:A5 REP MOVS DWORD PTR ES:[EDI],DWORD PTR DS:[ESI] ; 从3824a4处开始替换三次DWORD代码 …… 00373252 56 PUSH ESI ; push 4B1080 …… 0037355E 6A 00 PUSH 0 ; push 0 00373560 FF95 060F4100 CALL DWORD PTR SS:[EBP+410F06] ; GetModuleHandleA 00373566 EB 01 JMP SHORT 00373569 00373568 90 NOP 00373569 68 C2100000 PUSH 10C2 0037356E E8 01000000 CALL 00373574 00373573 90 NOP 00373574 68 24080E68 PUSH 680E0824 00373579 68 90908344 PUSH 44839090 0037357E - FFE4 JMP ESP ; 跳去12ff90处 …… 00373581 8985 120F4100 MOV DWORD PTR SS:[EBP+410F12],EAX ; 把GetModuleHandleA获取到的地址4000000入3824b4处 …… 0037359E 6A 04 PUSH 4 ; 这里再次分配空间 003735A0 68 00100000 PUSH 1000 003735A5 68 00100000 PUSH 1000 003735AA 6A 00 PUSH 0 003735AC FF95 0E0F4100 CALL DWORD PTR SS:[EBP+410F0E] ; VirtualAlloc …… 0012FF8C 003735B2 /CALL to VirtualAlloc from 003735AC 0012FF90 00000000 |Address = NULL 0012FF94 00001000 |Size = 1000 (4096.) 0012FF98 00001000 |AllocationType = MEM_COMMIT 0012FF9C 00000004 \Protect = PAGE_READWRITE …… 003735B2 8985 49184100 MOV DWORD PTR SS:[EBP+411849],EAX ; 分配的空间390000入382DEB 003735B8 68 003C070A PUSH 0A073C00 003735BD 68 9FFC0D75 PUSH 750DFC9F …… 0037445B 8BFE MOV EDI,ESI ; 加载数据到373763 0037445D B9 46040000 MOV ECX,446 ; size 446 00374462 AC LODS BYTE PTR DS:[ESI] ; 把取出的数据放到al中 00374463 90 NOP …… 0037448E 90 NOP 0037448F 90 NOP 00374490 32C1 XOR AL,CL 00374492 90 NOP …… 003744A7 90 NOP 003744A8 90 NOP 003744A9 C0C0 04 ROL AL,4 …… 003744D9 AA STOS BYTE PTR ES:[EDI] ; 从373763处开始译码,大小为446 003744DA ^ E2 86 LOOPD SHORT 00374462 …… 003744DD 33C0 XOR EAX,EAX ; 解压后,又准备异常了 003744DF 64:FF30 PUSH DWORD PTR FS:[EAX] 003744E2 64:8920 MOV DWORD PTR FS:[EAX],ESP 003744E5 0F0B UD2 …… 0012FF9C 0012FFE0 Pointer to next SEH record 0012FFA0 00373712 SE handler …… 出现一次0异常后,连续了1311个INT3异常(Crazy). 好了,终于到了光明的地方 00375347 90 NOP 00375348 880431 MOV BYTE PTR DS:[ECX+ESI],AL 0037534B ^ E2 F6 LOOPD SHORT 00375343 0037534D 64:8F05 0000000>POP DWORD PTR FS:[0] ;直接在这里下断,然后忽略全部异常 00375354 58 POP EAX …… 003754D6 83C4 04 ADD ESP,4 003754D9 8B85 060F4100 MOV EAX,DWORD PTR SS:[EBP+410F06] ; kernel32.GetModuleHandleA …… 00381DF2 6A 00 PUSH 0 ; push 0 00381DF4 50 PUSH EAX ; push GetModuleHandleA 00381DF5 8B85 49184100 MOV EAX,DWORD PTR SS:[EBP+411849] ; 刚才申请的空间地址390000 00381F4A 50 PUSH EAX ; push 390000 00381F4B E8 08000000 CALL 00381F58 ; 这里进去就是检查API,和把API放到390000那个段里去,变成push api,ret的方式 00381F50 8B85 49184100 MOV EAX,DWORD PTR SS:[EBP+411849] 00381F56 FFE0 JMP EAX 00381F58 60 PUSHAD 00381F59 8B7C24 24 MOV EDI,DWORD PTR SS:[ESP+24] 00381F5D 8B7424 28 MOV ESI,DWORD PTR SS:[ESP+28] ; 开始检查API函数 …… 00381F64 3C 50 CMP AL,50 00381F66 E9 55030000 JMP 003822C0 ;改成jmp 就不会检测API了, 00381F6B 90 NOP …… 003822C0 C607 68 MOV BYTE PTR DS:[EDI],68 ; 填成push api 003822C3 8977 01 MOV DWORD PTR DS:[EDI+1],ESI 003822C6 C647 05 C3 MOV BYTE PTR DS:[EDI+5],0C3 ; 这里改成retn 003822CA 83C7 06 ADD EDI,6 003822CD 897C24 FC MOV DWORD PTR SS:[ESP-4],EDI 003822D1 837C24 2C 00 CMP DWORD PTR SS:[ESP+2C],0 003822D6 EB 18 JMP SHORT 003822F0 ;这里再次改成jmp,也就是让它直接push api的方式或者直接跳去相关的DLL中找到API 003822D8 8BCE MOV ECX,ESI …… 00381F50 8B85 49184100 MOV EAX,DWORD PTR SS:[EBP+411849] ; 这里就是跳去刚纔存放API的那个申请空间里 00381F56 FFE0 JMP EAX ; 跳去GetModuleHandleA 00381F58 60 PUSHAD …… 003754EB 8BF0 MOV ESI,EAX ; 获取到的hmodule入esi,第一次取kernel32.dll的 003754ED 8985 3A104100 MOV DWORD PTR SS:[EBP+41103A],EAX ; 把hInstance(77E40000)入3825dc处 003754F3 8D9D 48104100 LEA EBX,DWORD PTR SS:[EBP+411048] …… 00375662 8DBD 26154100 LEA EDI,DWORD PTR SS:[EBP+411526] ; 把"CloseHandle"的地址382ad4传入edi中 00375668 51 PUSH ECX ; push 21 …… 0038232D 60 PUSHAD ; 循环在dll中找到所要找的API 0038232E 8B75 08 MOV ESI,DWORD PTR SS:[EBP+8] …….. 003823E5 61 POPAD 003823E6 8B45 FC MOV EAX,DWORD PTR SS:[EBP-4] 003823E9 C9 LEAVE 003823EA C2 0800 RETN 8 ;找到后返回去 第一次在KERNEL32.DLL中要找的API有: 0012FF9C 00382AC8 ASCII "CloseHandle" 0012FF9C 00382AC8 ASCII "CreateFileA" 0012FF9C 00382AC8 ASCII "CreateFileMappingA" 0012FF9C 00382AC8 ASCII "CreateThread" 0012FF9C 00382AC8 ASCII "DeleteFileA" 0012FF9C 00382AC8 ASCII "DeviceIoControl" 0012FF9C 00382AC8 ASCII "ExitProcess" 0012FF9C 00382AC8 ASCII "FindResourceA" 0012FF9C 00382AC8 ASCII "GetCommandLineA" 0012FF9C 00382AC8 ASCII "GetFileSize" 0012FF9C 00382AC8 ASCII "GetCurrentProcess" 0012FF9C 00382AC8 ASCII "GetCurrentProcessId" 0012FF9C 00382AC8 ASCII "GetCurrentThread" 0012FF9C 00382AC8 ASCII "GetModuleHandleA" 0012FF9C 00382AC8 ASCII "GetModuleFileNameA" 0012FF9C 00382AC8 ASCII "GetTempPathA" 0012FF9C 00382AC8 ASCII "GetVersion" 0012FF9C 00382AC8 ASCII "lstrcmpA" 0012FF9C 00382AC8 ASCII "LoadResource" 0012FF9C 00382AC8 ASCII "MapViewOfFile" 0012FF9C 00382AC8 ASCII "ReadProcessMemory" 0012FF9C 00382AC8 ASCII "ResetEvent" 0012FF9C 00382AC8 ASCII "SetEvent" 0012FF9C 00382AC8 ASCII "SetLastError" 0012FF9C 00382AC8 ASCII "SetThreadPriority" 0012FF9C 00382AC8 ASCII "TerminateThread" 0012FF9C 00382AC8 ASCII "UnmapViewOfFile" 0012FF9C 00382AC8 ASCII "VirtualAllocEx" 0012FF9C 00382AC8 ASCII "VirtualFree" 0012FF9C 00382AC8 ASCII "VirtualProtect" 0012FF9C 00382AC8 ASCII "WaitForSingleObject" 0012FF9C 00382AC8 ASCII "WriteProcessMemory" 0012FF9C 00382AC8 ASCII "WriteFile" …… 0037569D 0FB64B FF MOVZX ECX,BYTE PTR DS:[EBX-1] 003756A1 8903 MOV DWORD PTR DS:[EBX],EAX ; 取出的API入[EBX]中 003756A3 03D9 ADD EBX,ECX 003756A5 43 INC EBX 003756A6 59 POP ECX 003756A7 ^ E2 A2 LOOPD SHORT 0037564B ; 如果没有取完就跳去回去继续 003756A9 8DB5 8A0F4100 LEA ESI,DWORD PTR SS:[EBP+410F8A] ; mov esi,"user32.dll" …….. 003757FE 56 PUSH ESI ; 准备处理USER32。DLL中要取的API了 003757FF 90 NOP ………. 0037581E 90 NOP 0037581F 8B85 060F4100 MOV EAX,DWORD PTR SS:[EBP+410F06] ; 第一次用GetModuleHandleA来判断相关的DLL有没有加载 00375825 90 NOP 00375826 90 NOP 00375827 90 NOP 00375828 90 NOP 00375829 90 NOP 0037582A 90 NOP 0037582B E9 C2C50000 JMP 00381DF2 ; 这里也就是jmp api调用相关的API 00375830 90 NOP 00375831 0BC0 OR EAX,EAX ; 如果GetModuleHandleA失败的话,说明内存中并没有加载相关的DLL 00375833 75 34 JNZ SHORT 00375869 ; 如果已经加载了相关的DLL就跳去下一步取DLL中相关的API 00375835 56 PUSH ESI ; 因为user32.dll并没有加载所以壳用LoadLibrary来加载这个DLL 00375836 90 NOP 00375855 90 NOP 00375856 8B85 0A0F4100 MOV EAX,DWORD PTR SS:[EBP+410F0A] ; LoadLibraryA 0037585C 90 NOP 0037585D 90 NOP 0037585E 90 NOP 0037585F 90 NOP 00375860 90 NOP 00375861 90 NOP 00375862 E9 8BC50000 JMP 00381DF2 ; 看这里又跳去执行API,记住先,JMP 00381DF2就是执行API,我们没必要去跟了 00375867 90 NOP 00375868 90 NOP 00375869 8BF0 MOV ESI,EAX ; 加载后的DLL的hmodule入esi中 0037586B 8D9D 960F4100 LEA EBX,DWORD PTR SS:[EBP+410F96] 00375871 6A 0A PUSH 0A 00375873 59 POP ECX ; mov ecx,0a,又有动作了,这里就是循环取0A个相关的API 00375874 8DBD 26154100 LEA EDI,DWORD PTR SS:[EBP+411526] 0037587A 53 PUSH EBX …… 003758B6 AA STOS BYTE PTR ES:[EDI] ; 又是这一招来取API 003758B7 5B POP EBX 003758B8 8DBD 26154100 LEA EDI,DWORD PTR SS:[EBP+411526] ……… 003758F8 8903 MOV DWORD PTR DS:[EBX],EAX ; 取到的API (eax)入[ebx] 003758FA 03D9 ADD EBX,ECX 003758FC 43 INC EBX 003758FD 59 POP ECX 003758FE 49 DEC ECX 003758FF ^ 0F85 6FFFFFFF JNZ 00375874 ; 如果没有取完就下一步 00375905 8DB5 49124100 LEA ESI,DWORD PTR SS:[EBP+411249] …….. 00375905 8DB5 49124100 LEA ESI,DWORD PTR SS:[EBP+411249] ; 现在取WS2_32.DLL中的API了 0037590B 90 NOP ………… 00375A7B 8B85 060F4100 MOV EAX,DWORD PTR SS:[EBP+410F06] ; GetModuleHandleA 00375A81 90 NOP 00375A82 90 NOP 00375A83 90 NOP 00375A84 90 NOP 00375A85 90 NOP 00375A86 90 NOP 00375A87 E9 66C30000 JMP 00381DF2 00375A8C 90 NOP 00375A8D 0BC0 OR EAX,EAX ; 同样判断有没有加载DLL,没有就先LoadLibraryA 00375A8F 75 34 JNZ SHORT 00375AC5 00375A91 56 PUSH ESI …… 00375ACD B9 04000000 MOV ECX,4 ; 这次取4个API 要取的4 个API分别为: 00375B29 8903 MOV DWORD PTR DS:[EBX],EAX ; WS2_32.WSASend 00375B29 8903 MOV DWORD PTR DS:[EBX],EAX ; WS2_32.WSARecv 00375B29 8903 MOV DWORD PTR DS:[EBX],EAX ; WS2_32.send 00375B29 8903 MOV DWORD PTR DS:[EBX],EAX ; WS2_32.recv …… 00375B31 8DB5 72124100 LEA ESI,DWORD PTR SS:[EBP+411272] ; 好了,现在取ADVAPI32.DLL中的api …….. 00375B31 8DB5 72124100 LEA ESI,DWORD PTR SS:[EBP+411272] ; 好了,现在取ADVAPI32.DLL中的api …… 00375CF9 6A 08 PUSH 8 00375CFB 59 POP ECX ; 在ADVAPI32。DLL里取8个API 这幺八个: 00375D53 8903 MOV DWORD PTR DS:[EBX],EAX ; ADVAPI32.CloseServiceHandle 00375D53 8903 MOV DWORD PTR DS:[EBX],EAX ; ADVAPI32.ControlService 00375D53 8903 MOV DWORD PTR DS:[EBX],EAX ; ADVAPI32.CreateServiceA 00375D53 8903 MOV DWORD PTR DS:[EBX],EAX ; ADVAPI32.DeleteService 00375D53 8903 MOV DWORD PTR DS:[EBX],EAX ; ADVAPI32.OpenSCManagerA 00375D53 8903 MOV DWORD PTR DS:[EBX],EAX ; ADVAPI32.OpenServiceA 00375D53 8903 MOV DWORD PTR DS:[EBX],EAX ; ADVAPI32.QueryServiceStatus 00375D53 8903 MOV DWORD PTR DS:[EBX],EAX ; ADVAPI32.StartServiceA …… 00375D7B 8B85 E60F4100 MOV EAX,DWORD PTR SS:[EBP+410FE6] ; 取完后,开始GetForegroundWindow,一看这个就知道干什幺了吧:-) 00375D81 90 NOP 00375D82 90 NOP …… 00375E3D 8B85 CB0F4100 MOV EAX,DWORD PTR SS:[EBP+410FCB] ; BT用EnableWindow来反跟踪 00375E43 90 NOP 00375E44 90 NOP …… 00375E70 8B85 04114100 MOV EAX,DWORD PTR SS:[EBP+411104] ; kernel32.GetCurrentThread 00375E76 90 NOP 00375E77 90 NOP 00375E78 90 NOP 00375E79 90 NOP 00375E7A 90 NOP 00375E7B 90 NOP 00375E7C E9 71BF0000 JMP 00381DF2 …… 00375EA6 8B85 B4114100 MOV EAX,DWORD PTR SS:[EBP+4111B4] ; kernel32.SetThreadPriority 00375EAC 90 NOP …… 0012FF98 00375EB9 /CALL to SetThreadPriority 0012FF9C FFFFFFFE |hThread = FFFFFFFE 0012FFA0 00000002 \Priority = THREAD_PRIORITY_HIGHEST …… 00375EB9 50 PUSH EAX 00375EBA 52 PUSH EDX 00375EBB 51 PUSH ECX 00375EBC EB 01 JMP SHORT 00375EBF 00375EBE 90 NOP 00375EBF 0F31 RDTSC 00375EC1 8BC8 MOV ECX,EAX ; RDTSC时间反跟踪 …….. 00375ECD 90 NOP 00375ECE E8 38000000 CALL 00375F0B 00375ED3 90 NOP 进去看看有啥东西: 00375F0E 68 C2100000 PUSH 10C2 00375F13 E8 01000000 CALL 00375F19 00375F18 90 NOP 00375F19 68 24080E68 PUSH 680E0824 00375F1E 68 90908344 PUSH 44839090 00375F23 FFE4 JMP ESP 00375F25 90 NOP 00375F26 C3 RETN 0012FF86 834424 08 0E ADD DWORD PTR SS:[ESP+8],0E 0012FF8B 68 185F3700 PUSH 375F18 0012FF90 C2 1000 RETN 10 …… 00375EDB 90 NOP 00375EDC E8 46000000 CALL 00375F27 ; 里面全部是垃圾来的/lh 00375EE1 90 NOP …… 00375EF4 0F31 RDTSC 00375EF6 83C4 04 ADD ESP,4 00375EF9 2BC1 SUB EAX,ECX 00375EFB 3D 00000200 CMP EAX,20000 ; 这里进行比较,如果小于20000就说明程序在跟踪 00375F00 76 04 JBE SHORT 00375F06 ; 这里一定要跳 …… 00375F3B 8B85 120F4100 MOV EAX,DWORD PTR SS:[EBP+410F12] ; IMAGEBASE(40000)入EAX 00375F41 0340 3C ADD EAX,DWORD PTR DS:[EAX+3C] ; 定位PE位置 …… 00376093 8B40 50 MOV EAX,DWORD PTR DS:[EAX+50] ; sizeof image(C5AFA) 入EAX 00376096 3385 260F4100 XOR EAX,DWORD PTR SS:[EBP+410F26] ; [EBP+410F26]=[003824C8]=E033EF 0037609C 90 NOP …… 003761EA 90 NOP 003761EB 8B8D 020F4100 MOV ECX,DWORD PTR SS:[EBP+410F02] ; MOV ECX,EC6915 003761F1 3BC1 CMP EAX,ECX 003761F3 8DB5 29144100 LEA ESI,DWORD PTR SS:[EBP+411429] ; MOV ESI,3829CB 003761F9 46 INC ESI …… 003763A0 56 PUSH ESI ; PUSH \\.NTICE 003763A1 90 NOP 003763A2 90 NOP 003763A3 90 NOP 003763A4 90 NOP 003763A5 90 NOP 003763A6 90 NOP 003763A7 90 NOP 003763A8 90 NOP 003763A9 90 NOP 003763AA 8D85 314E4000 LEA EAX,DWORD PTR SS:[EBP+404E31] ; 准备检查调试器 003763B0 90 NOP …… 003763BF 90 NOP 003763C0 90 NOP 003763C1 8B85 55104100 MOV EAX,DWORD PTR SS:[EBP+411055] ; kernel32.CreateFileA 003763C7 90 NOP …… 003763D9 0F31 RDTSC ; 检查过程还不忘记用RDTSC的方法来反跟踪 003763DB 8BC8 MOV ECX,EAX …… 0037640D 90 NOP 0037640E 0F31 RDTSC 00376410 83C4 04 ADD ESP,4 00376413 2BC1 SUB EAX,ECX 00376415 3D 00000200 CMP EAX,20000 0037641A 76 04 JBE SHORT 00376420 ; 如果检查到就over了 0037641C 83C4 0C ADD ESP,0C 0037641F C3 RETN ; 跳去OVER处 …… 00376455 83F8 FF CMP EAX,-1 00376458 74 05 JE SHORT 0037645F ; 如果通过CreateFileA的方法没有找到的话就跳 0037645A E9 F5CC0000 JMP 00383154 ; 如果检查到调试器就跳去over处 0037645F 56 PUSH ESI 00376461 /EB 06 JMP SHORT 00376469 00376463 |F6D0 NOT AL ; 每执行完一次不忘记把字符给去掉,好样的 00376465 |8846 FF MOV BYTE PTR DS:[ESI-1],AL 00376468 |AC LODS BYTE PTR DS:[ESI] 00376469 \0AC0 OR AL,AL 0037646B ^ 75 F6 JNZ SHORT 00376463 ; 如果没有擦完则继续 0037646D 5E POP ESI 0037647D 0F31 RDTSC ; 还在用时间的方法检测调试器 0037647F 8BC8 MOV ECX,EAX 00376481 90 NOP …… 003764B2 0F31 RDTSC 003764B4 83C4 04 ADD ESP,4 003764B7 2BC1 SUB EAX,ECX 003764B9 3D 00000200 CMP EAX,20000 003764BE 76 04 JBE SHORT 003764C4 ; 这里同上 003764C0 83C4 0C ADD ESP,0C 003764C3 C3 RETN …… 003764F9 0BC9 OR ECX,ECX ; 如果没有检测完还要回去检测, 003764FB ^ 0F85 50FEFFFF JNZ 00376351 检测了八九次 00376501 8CC9 MOV CX,CS 00376503 32C9 XOR CL,CL 00376505 0BC9 OR ECX,ECX 00376507 0F84 01080000 JE 00376D0E ;默认这里跳的,晕,这里又是跳去检测有没有调试器 …… 00376DBE 90 NOP 00376DBF 8B85 060F4100 MOV EAX,DWORD PTR SS:[EBP+410F06] ; kernel32.GetModuleHandleA 00376DC5 90 NOP …… 0012FF9C 00376DD1 /CALL to GetModuleHandleA 0012FFA0 00376D95 \pModule = "ntdll.dll" …… 00376F68 90 NOP 00376F69 E9 84AE0000 JMP 00381DF2 ; 跳去取NTDLL。DLL里所需的API 00376F6E 90 NOP 第一次就是取ZwInformationThread 003770BD 90 NOP 003770BE 8BF8 MOV EDI,EAX ; ntdll.ZwSetInformationThread 003770C0 50 PUSH EAX 003770C1 52 PUSH EDX 003770C2 51 PUSH ECX 003770C3 EB 01 JMP SHORT 003770C6 003770C5 90 NOP 003770C6 0F31 RDTSC 003770C8 8BC8 MOV ECX,EAX ; 很多这样的检测调试器的宏哦 003770CA 90 NOP …… 00377174 6A 00 PUSH 0 ;又是反调试器用的. ……….. 00377162 8B85 0411410>MOV EAX,DWORD PTR SS:[EBP+411104] ; kernel32.GetCurrentThread先获取当前线程信息,然后搞破坏 00377168 90 NOP 00377169 90 NOP 0037716A 90 NOP 0037716B 90 NOP 0037716C 90 NOP 0037716D 90 NOP 0037716E E9 7FAC0000 JMP 00381DF2 00377173 90 NOP 00377176 6A 00 PUSH 0 00377178 6A 11 PUSH 11 0037717A 50 PUSH EAX 0037717B 8D85 E85B4000 LEA EAX,DWORD PTR SS:[EBP+405BE8] 00377181 50 PUSH EAX 00377182 8BC7 MOV EAX,EDI ; ntdll.ZwSetInformationThread 00377184 E9 69AC0000 JMP 00381DF2 …… 0037718A 8D1D C9174100 LEA EBX,DWORD PTR DS:[4117C9] 00377190 833C2B 00 CMP DWORD PTR DS:[EBX+EBP],0 ; Text section vsize …… 003771CC 8D042B LEA EAX,DWORD PTR DS:[EBX+EBP] 003771FA 8B48 08 MOV ECX,DWORD PTR DS:[EAX+8] ;text section vsize 40000 00377225 8B70 04 MOV ESI,DWORD PTR DS:[EAX+4] ;text section voffset 00377255 03B5 120F4100 ADD ESI,DWORD PTR SS:[EBP+410F12] ; text section start address 00377288 8BFE MOV EDI,ESI 003772B4 8D85 E4144100 LEA EAX,DWORD PTR SS:[EBP+4114E4] ;382A86 003772E3 50 PUSH EAX 0037730E 51 PUSH ECX 00377338 56 PUSH ESI 00377366 E8 D19F0000 CALL 0038133C ;对text段解压 00377395 53 PUSH EBX 003773C3 6A 04 PUSH 4 003773EE 68 00100000 PUSH 1000 00377418 FF342B PUSH DWORD PTR DS:[EBX+EBP] 0037741B 6A 00 PUSH 0 0037741D 8D85 FE634000 LEA EAX,DWORD PTR SS:[EBP+4063FE] 00377423 50 PUSH EAX …….. 00377573 8B85 0E0F4100 MOV EAX,DWORD PTR SS:[EBP+410F0E] ; kernel32.VirtualAlloc 00377579 E9 74A80000 JMP 00381DF2 …… 0012FF8C 003779A0 /CALL to VirtualAlloc 0012FF90 00000000 |Address = NULL 0012FF94 000A8000 |Size = A8000 (688128.) 0012FF98 00001000 |AllocationType = MEM_COMMIT 0012FF9C 00000004 \Protect = PAGE_READWRITE 003779D4 8BF0 MOV ESI,EAX ; 申请到的空间9B0000入esi 003779FE 8BC3 MOV EAX,EBX ; 4117c9 00377A2B 03C5 ADD EAX,EBP ; eax==382d68 00377A56 8B78 04 MOV EDI,DWORD PTR DS:[EAX+4] ; mov edi,1000 00377A84 03BD 120F4100 ADD EDI,DWORD PTR SS:[EBP+410F12] ; 转换成VA 401000 00377AB5 56 PUSH ESI ; push 9b0000 00377AE2 57 PUSH EDI ; push 401000 00377B17 8D85 9E654000 LEA EAX,DWORD PTR SS:[EBP+40659E] ; EAX==377b40 00377B21 50 PUSH EAX 00377B2E 8B85 7E0F4100 MOV EAX,DWORD PTR SS:[EBP+410F7E] ; 4b1151 进入4b1151 后发现还是在解压数据. 00377B39 90 NOP 00377B3A E9 B3A20000 JMP 00381DF2 ; 跳去解压数据处,是面是DEPACK(apLib)的代码 00377B3F 90 NOP …… 00377B69 8B0C2B MOV ECX,DWORD PTR DS:[EBX+EBP] ; push size?? A8000 00377B96 56 PUSH ESI ; push 9b0000,这个步骤就是要把相关的数据还原回去 00377BC1 51 PUSH ECX 00377BC2 C1E9 02 SHR ECX,2 ; ecx=2a000把解压出来的东西再施加到401000开始的地方 00377BC5 F3:A5 REP MOVS DWORD PTR ES:[EDI],DWORD PTR DS> ECX=0002A000 (decimal 172032.) DS:[ESI]=[009B0000]=00401004 ES:[EDI]=[00401000]=0609B0A1 …… 00377BC7 59 POP ECX 00377BC8 83E1 03 AND ECX,3 00377BCB F3:A4 REP MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[> ECX=00000000 (decimal 0.) DS:[ESI]=[00A58000]=??? ;这里为什幺会这样??我不知道,请教各位高手了. ES:[EDI]=[004A9000]=00 00377BF6 5E POP ESI ; 009B0000 操作完毕,开始释放原来申请的空间. 00377CF6 90 NOP 00377CF7 8B85 F9114100 MOV EAX,DWORD PTR SS:[EBP+4111F9] ; kernel32.VirtualFree 00377CFD 90 NOP …… 0012FF90 00377D0A /CALL to VirtualFree 0012FF94 009B0000 |Address = 009B0000 0012FF98 00000000 |Size = 0 0012FF9C 00008000 \FreeType = MEM_RELEASE …… 00377D64 83C3 0C ADD EBX,0C ; 4117c9+0c 00377190 833C2B 00 CMP DWORD PTR DS:[EBX+EBP],0 ; [382D77]==7584 003771CC 8D042B LEA EAX,DWORD PTR DS:[EBX+EBP] ; mov eax,382d77 003771FA 8B48 08 MOV ECX,DWORD PTR DS:[EAX+8] ; mov ecx,1e84 00377225 8B70 04 MOV ESI,DWORD PTR DS:[EAX+4] ; mov esi,A9A7C 00377255 03B5 120F4100 ADD ESI,DWORD PTR SS:[EBP+410F12] ; 转成VA 00377288 8BFE MOV EDI,ESI ; 把转成的VA(4A9A7C)入EDI 003772B4 8D85 E4144100 LEA EAX,DWORD PTR SS:[EBP+4114E4] ; mov eax,382a86 00377366 E8 D19F0000 CALL 0038133C ; 4A9A7C进行解压代码: …… 003773EE 68 00100000 PUSH 1000 ; 准备分配空间了 …… 00377573 8B85 0E0F4100 MOV EAX,DWORD PTR SS:[EBP+410F0E] ; kernel32.VirtualAlloc 00377579 E9 74A80000 JMP 00381DF2 ; 进行分配空间 0012FF8C 003779A0 /CALL to VirtualAlloc 0012FF90 00000000 |Address = NULL 0012FF94 00007584 |Size = 7584 (30084.) 0012FF98 00001000 |AllocationType = MEM_COMMIT 0012FF9C 00000004 \Protect = PAGE_READWRITE …… 00377B2C 90 NOP 00377B2D 90 NOP 00377B2E 8B85 7E0F4100 MOV EAX,DWORD PTR SS:[EBP+410F7E] ; xxx.004B1151 00377B34 90 NOP 00377B35 90 NOP 00377B36 90 NOP 00377B37 90 NOP 00377B38 90 NOP 00377B39 90 NOP 00377B3A E9 B3A20000 JMP 00381DF2 ; 再次进去译码 00377B3F 90 NOP …… 00377BC2 C1E9 02 SHR ECX,2 00377BC5 F3:A5 REP MOVS DWORD PTR ES:[EDI],DWORD PTR DS>; 解开4A9A7C处的代码 00377BC7 59 POP ECX ; 作者用了几次这个宏 00377BC8 83E1 03 AND ECX,3 00377BCB F3:A4 REP MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[>; 把代码放到41000处 00377BCD 90 NOP …… 00377CF5 90 NOP 00377CF6 90 NOP 00377CF7 8B85 F9114100 MOV EAX,DWORD PTR SS:[EBP+4111F9] ; kernel32.VirtualFree 00377CFD 90 NOP ; 解压完毕同上,释放空间 00377CFE 90 NOP …… 00377D90 8DB5 BD694000 LEA ESI,DWORD PTR SS:[EBP+4069BD] 00377EE5 87E6 XCHG ESI,ESP ; 从377F5F处解开一段代码 00377EE7 B9 8C7D0000 MOV ECX,7D8C ; 解压大小为7d8c 00377EEC 58 POP EAX 00377EED 90 NOP 00377EF3 F6D0 NOT AL 00377F00 50 PUSH EAX 00377F07 44 INC ESP 00377F0D ^\E2 DD LOOPD SHORT 00377EEC ; 如果没有解压完则跳上去继续 …… 00377F11 6A 04 PUSH 4 00377F13 68 00100000 PUSH 1000 00377F18 68 00200000 PUSH 2000 00377F1D 6A 00 PUSH 0 …… 00377F3F 8B85 0E0F4100 MOV EAX,DWORD PTR SS:[EBP+410F0E] ; kernel32.VirtualAlloc 00377F45 90 NOP ; 又分配一个空间 0012FF90 00377F52 /CALL to VirtualAlloc 0012FF94 00000000 |Address = NULL 0012FF98 00002000 |Size = 2000 (8192.) 0012FF9C 00001000 |AllocationType = MEM_COMMIT 0012FFA0 00000004 \Protect = PAGE_READWRITE …… 00377F52 8985 51184100 MOV DWORD PTR SS:[EBP+411851],EAX ; 分配的空间地址3F0000入[382DF3] 00377F58 83A5 55184100 0>AND DWORD PTR SS:[EBP+411855],0 00377F5F 8B85 420F4100 MOV EAX,DWORD PTR SS:[EBP+410F42] ; mov eax,1 …… 00377F92 0BC0 OR EAX,EAX 00377F94 0F85 AF090000 JNZ 00378949 ; 判断eax是否为0不为0则跳,这里也就是判断IAT有没有加密.因为前面已经是1也就说明IAT是加密了的. …… 0037897C 0395 620F4100 ADD EDX,DWORD PTR SS:[EBP+410F62] 00378982 8B3A MOV EDI,DWORD PTR DS:[EDX] ; 判断IAT? 00378AD3 0BFF OR EDI,EDI 00378AD5 75 05 JNZ SHORT 00378ADC ;没处理完IAT则跳 00378AD7 E9 89370000 JMP 0037C265 ;处理完毕这里跳走 00378ADC 83C2 05 ADD EDX,5 …… 00378C2E 8BF2 MOV ESI,EDX ; DLL名称入esi第一次是ADVAPI32.DLL 00378C30 56 PUSH ESI …… 00378C4F 90 NOP 00378C50 90 NOP 00378C51 8B85 060F4100 MOV EAX,DWORD PTR SS:[EBP+410F06] ; kernel32.GetModuleHandleA 00378C57 90 NOP ; 先用GetModuleHandleA判断目标DLL有没有加载 …… 00378C64 0BC0 OR EAX,EAX 00378C66 75 3D JNZ SHORT 00378CA5 ; 如果已经加载则下一步,否则先用LoadLibraryA加载DLL,前面跟过就发现,这个DLL已经加载了. 00378C68 56 PUSH ESI ; push dll的名字 …….. 00378C89 8B85 0A0F4100 MOV EAX,DWORD PTR SS:[EBP+410F0A] ; LoadLibraryA 00378C8F 90 NOP ; 加载dll …… 00378C9A 90 NOP 00378C9B 90 NOP 00378C9C 0BC0 OR EAX,EAX ; 如果加载成功就下一步 00378C9E 75 05 JNZ SHORT 00378CA5 00378CA0 E9 34A40000 JMP 003830D9 ; 如果加载失败跳去over 处 00378CA5 EB 26 JMP SHORT 00378CCD 00378CDA 68 E8EB6B3C PUSH 3C6BEBE8 …… 00378F0F 8BF0 MOV ESI,EAX ; 获取到的hmodule入esi 00378F11 0BC9 OR ECX,ECX 00378F13 0F85 A5070000 JNZ 003796BE 00378F19 8BCF MOV ECX,EDI …… 0037906A 8B3A MOV EDI,DWORD PTR DS:[EDX] 0037906C 03BD 120F4100 ADD EDI,DWORD PTR SS:[EBP+410F12] ; RVA转换成VA49a210 00379072 83C2 04 ADD EDX,4 00379075 51 PUSH ECX 00379076 0FB602 MOVZX EAX,BYTE PTR DS:[EDX] 00379079 0BC0 OR EAX,EAX …… 003793C8 61 POPAD 003793C9 8D95 26154100 LEA EDX,DWORD PTR SS:[EBP+411526] ; 第一次取RegQueryValueExA入EDX …… 0037951D 90 NOP 0037951E 52 PUSH EDX ; PUSH API NAME 0037951F 56 PUSH ESI ; PUSH hModule 00379520 90 NOP …… 00379540 8B85 FE0E4100 MOV EAX,DWORD PTR SS:[EBP+410EFE] ; 3824a0 00379546 90 NOP 00379547 90 NOP 00379548 90 NOP 00379549 90 NOP 0037954A 90 NOP 0037954B 90 NOP 0037954C E9 A1880000 JMP 00381DF2 ; GetProcAddress 00379551 90 NOP 00379552 90 NOP 00379553 E8 FC8E0000 CALL 00382454 ; 判断相关的api 有没有下断点,只比较一位而已 00379558 90 NOP …….. 003796A7 8907 MOV DWORD PTR DS:[EDI],EAX ; 把api入到相关的位置,第一个就是RegQueryValueExA EAX=77DA2410 (ADVAPI32.RegQueryValueExA) DS:[0049A210]=00000000 003796A9 5A POP EDX 003796AA 0FB642 FF MOVZX EAX,BYTE PTR DS:[EDX-1] 003796AE 03D0 ADD EDX,EAX 003796B0 42 INC EDX 003796B1 59 POP ECX 003796B2 49 DEC ECX 003796B3 ^ 0F85 B1F9FFFF JNZ 0037906A ; 如果没有取完就回去继续 第二次取Oleaut32.dll,因为这个DLL一开始没载加载,所以这次要先加载的。 到了加载这个DLL的时候就要小心了: 0012FF9C 00378C9C /CALL to LoadLibraryA 0012FFA0 00383CE7 \FileName = "wsock32.dll" …… 00378F0F 8BF0 MOV ESI,EAX ; 获取到的hmodule入esi 00378F11 0BC9 OR ECX,ECX 00378F13 0F85 A5070000 JNZ 003796BE ; 加载上面的那个DLL后到这里就会跳了,前面几上DLL都没有跳的 00378F19 8BCF MOV ECX,EDI 00378F1B 68 00FE98C7 PUSH C798FE00 …… 003796BE 8BCF MOV ECX,EDI ; 重新定位iat 003796C0 81E1 FFFFFF7F AND ECX,7FFFFFFF 003796C6 51 PUSH ECX 003796C7 52 PUSH EDX …… 0037981A 6A 04 PUSH 4 ; 准备分配空间 0037981C 68 00100000 PUSH 1000 00379821 51 PUSH ECX 00379822 6A 00 PUSH 0 00379844 8B85 0E0F4100 MOV EAX,DWORD PTR SS:[EBP+410F0E] ; kernel32.VirtualAlloc 0037984A 90 NOP 0037984B 90 NOP 0037984C 90 NOP 0037984D 90 NOP 0037984E 90 NOP 0037984F 90 NOP 00379850 E9 9D850000 JMP 00381DF2 ; 跳去分配空间 00379856 8985 5E0F4100 MOV DWORD PTR SS:[EBP+410F5E],EAX ; 分配好的空间AB0000放到[382500]处 0037985C 5A POP EDX 0037985D 59 POP ECX 0037985E 60 PUSHAD 0037985F 90 NOP …… 003799AE 8BD8 MOV EBX,EAX ; 把分配好的空间在EBX里也放一个 003799B0 EB 17 JMP SHORT 003799C9 003799B2 8B3A MOV EDI,DWORD PTR DS:[EDX] 003799B4 03BD 120F4100 ADD EDI,DWORD PTR SS:[EBP+410F12] ; 把RVA换成VA,第一次是49a818 003799BA 891F MOV DWORD PTR DS:[EDI],EBX ; 晕哦,这里想破坏IAT 003799BC 83C3 20 ADD EBX,20 003799BF 0FB642 04 MOVZX EAX,BYTE PTR DS:[EDX+4] 003799C3 03D0 ADD EDX,EAX 003799C5 83C2 06 ADD EDX,6 003799C8 49 DEC ECX 003799C9 0BC9 OR ECX,ECX 003799CB ^ 75 E5 JNZ SHORT 003799B2 ; 没有破坏完就回去继续破坏 …… 00379A34 66:C707 FF35 MOV WORD PTR DS:[EDI],35FF ; 准备填充真正的API到刚才分配的空间里 00379A39 90 NOP …… 00379B87 90 NOP 00379B88 C747 06 81342400 MOV DWORD PTR DS:[EDI+6],243481 ; XOR DWORD PTR [ESP],XORKEY 00379B8F 90 NOP …… 00379CDE 8947 02 MOV DWORD PTR DS:[EDI+2],EAX ; 准备放入返回字符串 00379CE1 90 NOP 00379D0E C647 0D C3 MOV BYTE PTR DS:[EDI+D],0C3 ;放入RET 00379D12 52 PUSH EDX ; 这里又准备用时间来检查调试器 …… 00379E87 8947 09 MOV DWORD PTR DS:[EDI+9],EAX ; XORKEY 00379E8A 5A POP EDX 00379E8B 83C7 20 ADD EDI,20 00379E |