NtQuerySystemInformationEx in 64bit

1

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;
}
c++
api
windows-10
64-bit
asked on Stack Overflow Aug 25, 2020 by Hnoob • edited Aug 25, 2020 by Remy Lebeau

0 Answers

Nobody has answered this question yet.


User contributions licensed under CC BY-SA 3.0