Using the NtQuerySystemInformationEx() API, I made a DLL that hides the Notepad process in 64bit.
But in 64bit, when I inject this DLL, nothing happens. But the DLL injector does not have a problem. Because other 64bit DLLs are injected ok.
What's the problem? I am trying to inject this DLL into the Process Explorer 64bit program. I want to hide the Notepad process from that Process Explorer.
The reason I used this API is that there is no Nt(Zw)QueryInformation() in Process Explorer x64, so I used the most similar Nt(Zw)QueryinformationEx().
#include <Windows.h>
#include <tchar.h>
#define STR_MODULE_NAME                    (L"hide.dll")
#define STR_HIDE_PROCESS_NAME            (L"notepad.exe")
#define STATUS_SUCCESS                    (0x00000000L)
typedef LONG NTSTATUS;
typedef enum _SYSTEM_INFORMATION_CLASS {
    SystemBasicInformation = 0,
    SystemPerformanceInformation = 2,
    SystemTimeOfDayInformation = 3,
    SystemProcessInformation = 5,
    SystemProcessorPerformanceInformation = 8,
    SystemInterruptInformation = 23,
    SystemExceptionInformation = 33,
    SystemRegistryQuotaInformation = 37,
    SystemLookasideInformation = 45
} SYSTEM_INFORMATION_CLASS;
typedef struct _SYSTEM_PROCESS_INFORMATION {
    ULONG NextEntryOffset;
    BYTE Reserved1[52];
    PVOID Reserved2[3];
    HANDLE UniqueProcessId;
} SYSTEM_PROCESS_INFORMATION, * PSYSTEM_PROCESS_INFORMATION;
typedef NTSTATUS(WINAPI* PFNTQUERYSYSTEMINFORMATIONEX)(
    SYSTEM_INFORMATION_CLASS SystemInformationClass,
    PVOID InputBuffer,
    ULONG InputBufferLength,
    PVOID SystemInformation,
    ULONG SystemInformationLength,
    PULONG ReturnLength);
BYTE g_pOrgZwQSI[16] = { 0, };
BOOL hook64_by_code(LPCSTR szDllName, LPCSTR szFuncName, PROC pfnNew, PBYTE pOrgBytes)
{
    FARPROC pFunc;
    DWORD dwOldProtect, dwlowAddress, dwhighAddress, dwmov;
    BYTE pBuf[14] = { 0x68, 0, };
    PBYTE pByte;
    pFunc = (FARPROC)GetProcAddress(GetModuleHandleA(szDllName), szFuncName);
    pByte = (PBYTE)pFunc;
    if (pByte[0] == 0x68)
        return FALSE;
    VirtualProtect((LPVOID)pFunc, 16, PAGE_EXECUTE_READWRITE, &dwOldProtect);
    memcpy(pOrgBytes, pFunc, 16);
    memset(pFunc, 0x90, 16);
    dwlowAddress = (DWORD)((DWORD64)pfnNew & 0xffffffff);
    memcpy(&pBuf[1], &dwlowAddress, 4);
    dwmov = 0x042444C7;
    memcpy(&pBuf[5],&dwmov , 4);
    dwhighAddress = (DWORD64)pfnNew >> 32;
    memcpy(&pBuf[9],&dwhighAddress , 4);
    pBuf[13] = 0xC3;
    memcpy(pFunc, &pBuf, 14);
    VirtualProtect((LPVOID)pFunc, 16, dwOldProtect, &dwOldProtect);
    return TRUE;
}
BOOL unhook64_by_code(LPCSTR szDllName, LPCSTR szFuncName, PBYTE pOrgBytes)
{
    FARPROC pFunc;
    DWORD dwOldProtect;
    PBYTE pByte;
    pFunc = (FARPROC)GetProcAddress(GetModuleHandleA(szDllName), szFuncName);
    pByte = (PBYTE)pFunc;
    if (pByte[0] != 0x68)
        return FALSE;
    VirtualProtect((LPVOID)pFunc, 16, PAGE_EXECUTE_READWRITE, &dwOldProtect);
    memcpy(pFunc, pOrgBytes, 16);
    VirtualProtect((LPVOID)pFunc, 16, dwOldProtect, &dwOldProtect);
    return TRUE;
}
NTSTATUS WINAPI NewNtQuerySystemInformationEx(
    SYSTEM_INFORMATION_CLASS SystemInformationClass,
    PVOID InputBuffer,
    ULONG InputBufferLength,
    PVOID SystemInformation,
    ULONG SystemInformationLength,
    PULONG ReturnLength)
{
    NTSTATUS status;
    FARPROC pFunc;
    PSYSTEM_PROCESS_INFORMATION pCur, pPrev = 0;
    char szProcName[MAX_PATH] = { 0, };
    unhook64_by_code("ntdll.dll", "NtQuerySystemInformationEx", g_pOrgZwQSI);
    pFunc = GetProcAddress(GetModuleHandleA("ntdll.dll"),
        "NtQuerySystemInformationEx");
    status = ((PFNTQUERYSYSTEMINFORMATIONEX)pFunc)
        (SystemInformationClass, InputBuffer,
            InputBufferLength, SystemInformation,
            SystemInformationLength, ReturnLength);
    if (status != STATUS_SUCCESS)
        goto __NTQUERYSYSTEMINFORMATION_END;
    if (SystemInformationClass == SystemProcessInformation)
    {
        pCur = (PSYSTEM_PROCESS_INFORMATION)SystemInformation;
   
        while (TRUE)
        {
            if (pCur->Reserved2[1] != NULL)
            {
                if (!_tcsicmp((PWSTR)pCur->Reserved2[2], STR_HIDE_PROCESS_NAME))
                {
                    if (pCur->NextEntryOffset == 0)
                        pPrev->NextEntryOffset = 0;
                    else
                        pPrev->NextEntryOffset += pCur->NextEntryOffset;
                }
                else
                    pPrev = pCur;    // 원하는 프로세스를 못 찾은 경우만 pPrev 세팅
            }
            if (pCur->NextEntryOffset == 0)
                break;
            pCur = (PSYSTEM_PROCESS_INFORMATION)((uintptr_t)pCur + pCur->NextEntryOffset);
        }
    }
__NTQUERYSYSTEMINFORMATION_END:
    hook64_by_code("ntdll.dll", "NtQuerySystemInformationEx",
        (PROC)NewNtQuerySystemInformationEx, g_pOrgZwQSI);
    return status;
}
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
    switch (fdwReason)
    {
    case DLL_PROCESS_ATTACH:
        hook64_by_code("ntdll.dll", "NtQuerySystemInformationEx",
            (PROC)NewNtQuerySystemInformationEx, g_pOrgZwQSI);
        break;
    case DLL_PROCESS_DETACH:
        unhook64_by_code("ntdll.dll", "NtQuerySystemInformationEx",
            g_pOrgZwQSI);
        break;
    }
    return TRUE;
}
User contributions licensed under CC BY-SA 3.0