NtQuerySystemInformation / WinAPI的

时间:2017-07-27 14:41:31

标签: c++ winapi

我正在尝试挂钩NtQuerySystemInformation以隐藏简单的进程(没有恶意)只是想弄清楚挂钩系统是如何工作的。

此代码编译为DLL,并且使用MinHook应该能够在任务管理器中隐藏进程列表中的“calc.exe”。它没有这样做,我真的无法弄清楚为什么。

#include "Windows.h"
#include "Winternl.h"
#include "MinHook.h"
#pragma comment(lib, "ntdll.lib")
#define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0)
typedef struct _SYSTEM_PROCESS_INFO
{
    ULONG                   NextEntryOffset;
    ULONG                   NumberOfThreads;
    LARGE_INTEGER           Reserved[3];
    LARGE_INTEGER           CreateTime;
    LARGE_INTEGER           UserTime;
    LARGE_INTEGER           KernelTime;
    UNICODE_STRING          ImageName;
    ULONG                   BasePriority;
    HANDLE                  ProcessId;
    HANDLE                  InheritedFromProcessId;
}SYSTEM_PROCESS_INFO, *PSYSTEM_PROCESS_INFO;

typedef NTSTATUS LONG;

typedef NTSTATUS(NTAPI * PNtQuerySystemInformation)(
    SYSTEM_INFORMATION_CLASS,
    PVOID,
    ULONG,
    PULONG);

PNtQuerySystemInformation pOriginalNtQuerySystemInformation = (PNtQuerySystemInformation)GetProcAddress(GetModuleHandle(L"ntdll.dll"), "NtQuerySystemInformation");


NTSTATUS NTAPI Detour_NtQuerySystemInformation(SYSTEM_INFORMATION_CLASS SystemInformationClass, PVOID SystemInformation, ULONG SystemInformationLength, PULONG ReturnLength)
{
    NTSTATUS status;

    PSYSTEM_PROCESS_INFO pCurrent, pNext;
    char *pname = NULL;

    status = pOriginalNtQuerySystemInformation(SystemInformationClass, SystemInformation, SystemInformationLength, ReturnLength);
        if (SystemInformationClass == SystemProcessInformation && NT_SUCCESS(status))
        {


            pCurrent = (PSYSTEM_PROCESS_INFO)SystemInformation;
            PWSTR g_targetProc = L"calc.exe";
            pNext = (PSYSTEM_PROCESS_INFO)((LPBYTE)pCurrent + pCurrent->NextEntryOffset);
            while (pNext->NextEntryOffset != 0)
            {
                pname = (char *)GlobalAlloc(GMEM_ZEROINIT,
                    pCurrent->ImageName.Length + 2);
                WideCharToMultiByte(CP_ACP, 0,
                    pCurrent->ImageName.Buffer,
                    pCurrent->ImageName.Length + 1,
                    pname, pCurrent->ImageName.Length + 1,
                    NULL, NULL);


                if (!_strnicmp((char *)pname, "calc.exe", strlen("calc.exe")))
                {
                    pCurrent->NextEntryOffset += pNext->NextEntryOffset;
                }
                pCurrent = pNext;
                pNext = (PSYSTEM_PROCESS_INFO)((LPBYTE)pCurrent + pCurrent->NextEntryOffset);
                GlobalFree(pname);
            }
    }

    return status;
}


void SetHook()
{
    MH_Initialize();
    MH_CreateHookApi(L"ntdll.dll", "NtQuerySystemInformation", &Detour_NtQuerySystemInformation, reinterpret_cast<PVOID*>(&pOriginalNtQuerySystemInformation));
    MH_EnableHook(MH_ALL_HOOKS);
}

void Unhook()
{
    MH_DisableHook(MH_ALL_HOOKS);
    MH_Uninitialize();
}

1 个答案:

答案 0 :(得分:0)

好的,我发现了什么问题。

我使用LoadLibraryA方法注入dll,看起来像这样:

switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: SetHook(); break; case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: case DLL_PROCESS_DETACH: Unhook(); break; }

在放置挂钩后直接调用取钩功能,然后挂钩停止工作。 删除取消挂钩功能解决了这个问题。