windows hook之隐藏进程

任务管理器隐藏指定进程

minihook使用指南

1、原理

注入dll到任务管理,hook NtQuerySystemInformation API实现进程信息获取忽略,达到进程隐藏

2、dll实现

#include "pch.h"
#include 
#include "../include/minihook/MinHook.h"
#include 


#ifdef _WIN64
    #pragma comment(lib,"../include/minihook/libMinHook.x64.lib")
#else
    #pragma comment(lib,"../include/minihook/libMinHook.x86.lib")
#endif // _WIN64


typedef struct _MY_SYSTEM_PROCESS_INFORMATION
{
    ULONG NextEntryOffset;
    ULONG NumberOfThreads;
    BYTE Reserved1[48];
    UNICODE_STRING ImageName;
    KPRIORITY BasePriority;
    HANDLE UniqueProcessId;
} _MY_SYSTEM_PROCESS_INFORMATION, * MY_SYSTEM_PROCESS_INFORMATION;

// fp for NtQuerySystemInformation
typedef NTSTATUS(WINAPI* OldNtQuerySystemInformation)(
    __in       SYSTEM_INFORMATION_CLASS SystemInformationClass,
    __inout    PVOID SystemInformation,
    __in       ULONG SystemInformationLength,
    __out_opt  PULONG ReturnLength
    );
// old address for NtQuerySystemInformation
OldNtQuerySystemInformation fpNtQuerySystemInformation = NULL;
// hook for NtQuerySystemInformation
NTSTATUS WINAPI HookedNtQuerySystemInformation(
    __in       SYSTEM_INFORMATION_CLASS SystemInformationClass,
    __inout    PVOID                    SystemInformation,
    __in       ULONG                    SystemInformationLength,
    __out_opt  PULONG                   ReturnLength
) {
    // invoke and get the result code
    NTSTATUS status = fpNtQuerySystemInformation(SystemInformationClass,
        SystemInformation,
        SystemInformationLength,
        ReturnLength);
    // check invoke succ
    if (SystemInformationClass == SystemProcessInformation && NT_SUCCESS(status)) {
        MY_SYSTEM_PROCESS_INFORMATION pCurrent = NULL;
        MY_SYSTEM_PROCESS_INFORMATION pNext = (MY_SYSTEM_PROCESS_INFORMATION)SystemInformation;

        // match the target process
        do
        {
            pCurrent = pNext;
            pNext = (MY_SYSTEM_PROCESS_INFORMATION)((PUCHAR)pCurrent + pCurrent->NextEntryOffset);

            if (!_wcsnicmp(pNext->ImageName.Buffer, L"notepad++.exe", pNext->ImageName.Length))
            {
                if (0 == pNext->NextEntryOffset)
                {
                    pCurrent->NextEntryOffset = 0;
                }
                else
                {
                    pCurrent->NextEntryOffset += pNext->NextEntryOffset;
                }
                // skip for target process
                pNext = pCurrent;
            }
        } while (pNext->NextEntryOffset != 0);
    }
    return status;
}

void HookNtQuerySystemInformation() {
    if (MH_Initialize() == MB_OK)
    {
        MH_CreateHookApi(L"ntdll", "NtQuerySystemInformation", HookedNtQuerySystemInformation, reinterpret_cast<void**>(&fpNtQuerySystemInformation));
        MH_EnableHook(MH_ALL_HOOKS);
    }
    else {
        MessageBoxA(NULL, "Hooked opeprocess failed", "Tip", MB_OK);
    }
}

void UnhookNtQuerySystemInformation() {
    if (MH_DisableHook(MH_ALL_HOOKS) == MB_OK)
    {
        MH_Uninitialize();
    }
}

BOOL APIENTRY DllMain(HMODULE hModule,
    DWORD  ul_reason_for_call,
    LPVOID lpReserved
)
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH: {
        HookNtQuerySystemInformation();
        break;
    }
    case DLL_THREAD_ATTACH: {

        break;
    }
    case DLL_THREAD_DETACH: {
        break;
    }
    case DLL_PROCESS_DETACH:
        UnhookNtQuerySystemInformation();
        break;
    }
    return TRUE;
}


3、任务管理器dll注入/卸载

#include 
#include 
#include 


DWORD nPid = 0;
DWORD GetTaskMgrPid()
{
    DWORD nPid = 0;
    std::wstring wstrProcessName(L"TaskMgr.exe");
    PROCESSENTRY32 pe32;
    HANDLE hSnapshot = NULL;

    pe32.dwSize = sizeof(PROCESSENTRY32);
    hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if (hSnapshot == INVALID_HANDLE_VALUE) return -1;
    if (Process32First(hSnapshot, &pe32)) {
        do {
            // wcsicmp: ignore case; wcscmp: case sensitive
            if (_wcsicmp(pe32.szExeFile, wstrProcessName.c_str()) == 0) {
                nPid = pe32.th32ProcessID;
                break;
            }
        } while (Process32Next(hSnapshot, &pe32));
    }

    if (hSnapshot != INVALID_HANDLE_VALUE)
        CloseHandle(hSnapshot);

    return nPid;
}


void ejectDll() {
    wchar_t szDll[] = L"HookNtQuerySystemInformation.dll";
    BOOL bMore = FALSE, bFound = FALSE;
    HANDLE hSnapshot, hProcess, hThread;
    HMODULE hModule = NULL;
    MODULEENTRY32 me = { sizeof(me) };
    LPTHREAD_START_ROUTINE pThreadProc;

    hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, nPid);
    if (INVALID_HANDLE_VALUE == hSnapshot) {
        std::cout << "Create snapshot failed: " << GetLastError() << ", pid: " << nPid << "\n";
        return;
    }

    bMore = Module32First(hSnapshot, &me);
    for (; bMore; bMore = Module32Next(hSnapshot, &me))
    {
        if (!_wcsicmp((LPCTSTR)me.szModule, szDll) ||
            !_wcsicmp((LPCTSTR)me.szExePath, szDll))
        {
            bFound = TRUE;
            break;
        }
    }

    if (!bFound)
    {
        std::cout << "Not found\n";
        CloseHandle(hSnapshot);
        return ;
    }

    if (!(hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, nPid)))
    {
        //_tprintf(L"OpenProcess(%d) failed!!! [%d]\n", dwPID, GetLastError());
        return ;
    }

    hModule = GetModuleHandle(L"kernel32.dll");
    // free library with manual
    pThreadProc = (LPTHREAD_START_ROUTINE)GetProcAddress(hModule, "FreeLibrary");
    hThread = CreateRemoteThread(hProcess, NULL, 0,
        pThreadProc, me.modBaseAddr,
        0, NULL);
    WaitForSingleObject(hThread, INFINITE);

    CloseHandle(hThread);
    CloseHandle(hProcess);
    CloseHandle(hSnapshot);
    std::cout << "Eject completed.\n";
}

void injectDll()
{
    char szDll[] = "D:/Demo/include/HookNtQuerySystemInformation.dll";

    HANDLE hTaskMgr = OpenProcess(PROCESS_ALL_ACCESS, FALSE, nPid);
    if (NULL == hTaskMgr) {
        std::cout << "Open process failed: " << GetLastError() << "\n";
        return;
    }

    SIZE_T pathSize = strlen(szDll) + 1;
    LPVOID pDllAddr = VirtualAllocEx(hTaskMgr, NULL, pathSize, MEM_COMMIT, PAGE_READWRITE);
    BOOL bSucc = WriteProcessMemory(hTaskMgr, pDllAddr, szDll, pathSize, NULL);
    LPTHREAD_START_ROUTINE fun = (LPTHREAD_START_ROUTINE)LoadLibraryA;
    auto hThread = CreateRemoteThread(hTaskMgr, NULL, 0, fun, pDllAddr, 0, NULL);

    WaitForSingleObject(hThread, INFINITE);
    // do clean
    CloseHandle(hThread);

    VirtualFreeEx(hTaskMgr, pDllAddr, 0, MEM_RELEASE);
    CloseHandle(hTaskMgr);
    std::cout << "Inject completed.\n";
}

int main()
{
    nPid = GetTaskMgrPid();
    if (nPid <= 0) {
        std::cout << "TaskMgr.exe not running, try it later\n";
        return 0;
    }
#if 1
    injectDll();
#else
    ejectDll();
#endif

    getchar();
    return 0;
}

注意事项

1、dll编译和待注入程序位数保持一致(待注入程序是64位,dll必须是64位)
2、注入程序必须和待注入程序位数保持一致(待注入程序是64位,注入必须是64位)

你可能感兴趣的:(windows,dll注入/卸载,进程隐藏)