前言
因为IDA F5伪码编译不过, 才手工翻译.   手工翻译时, 发现有个函数, IDA翻译的逻辑都错了(一定会调用的函数都漏掉了), 渣啊. 这多大一个坑啊…, 最基本的信任都没了.   即时是F5有优化, 那也应该是函数级别的优化, 哪能将函数调用搞没了.   用的IDA6.8正版.
记录
反汇编代码
.text:00011086 HookPRoc_ZwQueryDirectoryFile_11086 proc near.text:00011086                                         ; DATA XREF: MainProc_114D2+15Eo.text:00011086.text:00011086 var_28          = dWord ptr -28h.text:00011086 var_24          = dword ptr -24h.text:00011086 var_20          = dword ptr -20h.text:00011086 var_1C          = dword ptr -1Ch.text:00011086 szSystemProcessName= byte ptr -18h.text:00011086 var_4           = dword ptr -4.text:00011086 arg_0           = dword ptr  8.text:00011086 arg_4           = dword ptr  0Ch.text:00011086 arg_8           = dword ptr  10h.text:00011086 arg_C           = dword ptr  14h.text:00011086 arg_10          = dword ptr  18h.text:00011086 arg_14          = dword ptr  1Ch.text:00011086 arg_18          = dword ptr  20h.text:00011086 arg_1C          = dword ptr  24h.text:00011086 arg_20          = dword ptr  28h.text:00011086 arg_24          = dword ptr  2Ch.text:00011086 arg_28          = dword ptr  30h.text:00011086.text:00011086                 mov     edi, edi.text:00011088                 push    ebp.text:00011089                 mov     ebp, esp.text:0001108B                 sub     esp, 28h.text:0001108E                 mov     eax, BugCheckParameter2.text:00011093                 xor     eax, ebp.text:00011095                 mov     [ebp+var_4], eax.text:00011098                 mov     eax, [ebp+arg_C].text:0001109B                 mov     [ebp+var_20], eax.text:0001109E                 mov     eax, [ebp+arg_10].text:000110A1                 mov     [ebp+var_1C], eax.text:000110A4                 mov     eax, [ebp+arg_14].text:000110A7                 push    ebx.text:000110A8                 mov     ebx, [ebp+arg_8].text:000110AB                 mov     [ebp+var_28], eax.text:000110AE                 mov     eax, [ebp+arg_24].text:000110B1                 push    esi.text:000110B2                 mov     esi, [ebp+arg_0].text:000110B5                 push    edi.text:000110B6                 mov     edi, [ebp+arg_4].text:000110B9                 mov     [ebp+var_24], eax.text:000110BC                 lea     eax, [ebp+szSystemProcessName].text:000110BF                 push    eax             ; char *.text:000110C0                 call    GetSystemProcessName_11044.text:000110C5                 lea     eax, [ebp+szSystemProcessName].text:000110C8                 push    eax.text:000110C9                 push    offset Format   ; "Rootkit: NewZwQueryDirectoryFile() from"....text:000110CE                 call    DbgPrint.text:000110D3                 pop     ecx.text:000110D4                 pop     ecx.text:000110D5                 push    [ebp+arg_28]    ; _DWORD.text:000110D8                 push    [ebp+var_24]    ; _DWORD.text:000110DB                 push    [ebp+arg_20]    ; _DWORD.text:000110DE                 push    [ebp+arg_1C]    ; _DWORD.text:000110E1                 push    [ebp+arg_18]    ; _DWORD.text:000110E4                 push    [ebp+var_28]    ; _DWORD.text:000110E7                 push    [ebp+var_1C]    ; _DWORD.text:000110EA                 push    [ebp+var_20]    ; _DWORD.text:000110ED                 push    ebx             ; _DWORD.text:000110EE                 push    edi             ; _DWORD.text:000110EF                 push    esi             ; _DWORD.text:000110F0                 call    g_dwOrgZwQueryDirectoryFile_dword_13090.text:000110F6                 mov     ebx, eax.text:000110F8                 test    ebx, ebx.text:000110FA                 jl      short loc_11142.text:000110FC                 mov     eax, [ebp+arg_1C].text:000110FF                 cmp     eax, 1.text:00011102                 jz      short loc_1111D.text:00011104                 cmp     eax, 2.text:00011107                 jz      short loc_1111D.text:00011109                 cmp     eax, 26h.text:0001110C                 jz      short loc_1111D.text:0001110E                 cmp     eax, 3.text:00011111                 jz      short loc_1111D.text:00011113                 cmp     eax, 25h.text:00011116                 jz      short loc_1111D.text:00011118                 cmp     eax, 0Ch.text:0001111B                 jnz     short loc_11142.text:0001111D.text:0001111D loc_1111D:                              ; CODE XREF: HookProc_ZwQueryDirectoryFile_11086+7Cj.text:0001111D                                         ; HookProc_ZwQueryDirectoryFile_11086+81j ....text:0001111D                 push    9.text:0001111F                 pop     ecx.text:00011120                 mov     edi, offset aCdpassssp ; "cdPassssp".text:00011125                 lea     esi, [ebp+szSystemProcessName].text:00011128                 xor     eax, eax.text:0001112A                 repe cmpsb.text:0001112C                 jz      short loc_11133.text:0001112E                 sbb     eax, eax.text:00011130                 sbb     eax, 0FFFFFFFFh.text:00011133.text:00011133 loc_11133:                              ; CODE XREF: HookProc_ZwQueryDirectoryFile_11086+A6j.text:00011133                 test    eax, eax.text:00011135                 jnz     short loc_11142.text:00011137                 push    offset aRootkitDetecte ; "Rootkit: detected file/directory query "....text:0001113C                 call    DbgPrint.text:00011141                 pop     ecx.text:00011142.text:00011142 loc_11142:                              ; CODE XREF: HookProc_ZwQueryDirectoryFile_11086+74j.text:00011142                                         ; HookProc_ZwQueryDirectoryFile_11086+95j ....text:00011142                 mov     ecx, [ebp+var_4].text:00011145                 pop     edi.text:00011146                 pop     esi.text:00011147                 mov     eax, ebx.text:00011149                 xor     ecx, ebp.text:0001114B                 pop     ebx.text:0001114C                 call    MakeBSOD.text:00011151                 leave.text:00011152                 retn    2Ch.text:00011152 HookProc_ZwQueryDirectoryFile_11086 endpIDA F5结果
目标函数最后会调用MakeBSOD, 但是调用MakeBSOD的2个函数, IDA都搞错了. 我有点明白了, MakeBSOD函数写法不是标准写法, 是经过壳处理的, IDA分析错了. MakeBSOD直接F5, 结果是对的. 但是调用MakeBSOD的函数, IDA分析错了, 将MakeBSOD的调用直接拿掉了, 而且逻辑完全不对. 那以后用IDA F5分析脱壳后的程序时, 要注意了.
.text:0001165B ; =============== S U B R O U T I N E =======================================.text:0001165B.text:0001165B.text:0001165B MakeBSOD        proc near               ; CODE XREF: HookProc_ZwQueryDirectoryFile_11086+C6p.text:0001165B                                         ; fnProc_IRP_MJ_DEVICE_CONTROL_113EA+DAp.text:0001165B                 cmp     ecx, BugCheckParameter2.text:00011661                 jnz     short loc_11665.text:00011663                 rep retn.text:00011665 ; ---------------------------------------------------------------------------.text:00011665.text:00011665 loc_11665:                              ; CODE XREF: MakeBSOD+6j.text:00011665                 jmp     loc_1166F.text:00011665 ; ---------------------------------------------------------------------------.text:0001166A                 db 5 dup(0CCh).text:0001166F ; ---------------------------------------------------------------------------.text:0001166F.text:0001166F loc_1166F:                              ; CODE XREF: MakeBSOD:loc_11665j.text:0001166F                 mov     edi, edi.text:00011671                 push    ebp.text:00011672                 mov     ebp, esp.text:00011674                 push    ecx.text:00011675                 mov     [ebp-4], ecx.text:00011678                 push    0               ; BugCheckParameter4.text:0001167A                 push    BugCheckParameter3 ; BugCheckParameter3.text:00011680                 push    BugCheckParameter2 ; BugCheckParameter2.text:00011686                 push    dword ptr [ebp-4] ; BugCheckParameter1.text:00011689                 push    0F7h            ; BugCheckCode.text:0001168E                 call    ds:KeBugCheckEx.text:0001168E MakeBSOD        endp.text:0001168E.text:0001168E ; ---------------------------------------------------------------------------void __thiscall MakeBSOD(void *this){  if ( this != (void *)BugCheckParameter2 )    KeBugCheckEx(0xF7u, (ULONG_PTR)this, BugCheckParameter2, BugCheckParameter3, 0);}HookProc_ZwQueryDirectoryFile_11086里面的MakeBSOD调用没了…
int __stdcall HookProc_ZwQueryDirectoryFile_11086(int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8, int a9, int a10, int a11){  int v11; // ebx@1  char szSystemProcessName; // [sp+1Ch] [bp-18h]@1  GetSystemProcessName_11044(&szSystemProcessName);  DbgPrint("Rootkit: NewZwQueryDirectoryFile() from %s/n", &szSystemProcessName);  v11 = g_dwOrgZwQueryDirectoryFile_dword_13090(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11);  if ( v11 >= 0    && (a8 == 1 || a8 == 2 || a8 == 38 || a8 == 3 || a8 == 37 || a8 == 12)    && !memcmp(&szSystemProcessName, "cdPassssp", 9) )  {    DbgPrint("Rootkit: detected file/directory query from virvir process/n");  }  return v11;}手工翻译的正确等价结果
int __stdcall HookProc_ZwQueryDirectoryFile_11086(int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8, int a9, int a10, int a11){    NTSTATUS status = STATUS_SUCCESS;    WCHAR szSystemProcessName[0x14] = {L'0'};    ULONG_PTR ulBugCheckValue = 0;    // ebp    // ret addr => ebp + 4    // arg0     => ebp + 8    ULONG_PTR ulEbp = (ULONG_PTR)&a1 - 8; // get ebp addr    ulBugCheckValue = ulEbp ^ g_ulBugCheckParameter2;    ZeroMemory(szSystemProcessName, sizeof(szSystemProcessName));    GetSystemProcessName_11044(szSystemProcessName);    DbgPrint("Rootkit: NewZwQueryDirectoryFile() from %s", szSystemProcessName);    // 11 parameters    status = g_dwOrgZwQueryDirectoryFile_dword_13090(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11);    if (status >= 0) {        /*        arg_8 is param1        arg_c is param2        arg_10 is param3        arg_14 is param4        arg_18 is param5        arg_1c is param6 // ...        */        // IDA F5将arg_1c翻译成a8, 实际上应该是a6..., 最基本的信任呢...        // a6 is FileInformation        if ((FileDirectoryInformation == a6)                || (FileFullDirectoryInformation == a6)                || (FileIdFullDirectoryInformation == a6)                || (FileBothDirectoryInformation == a6)                || (FileIdBothDirectoryInformation == a6)                || (FileNamesInformation == a6)) {            if (0 != memcmp(szSystemProcessName, "cdPassssp", 9)) {                DbgPrint("Rootkit: detected file/directory query from virvir process/n");            }        }    }    MakeBSOD(ulBugCheckValue ^ ulEbp);    return status;}