c++winapireverse-engineeringdll-injection

is there a way to add process_query_information to existing process handle?


i'm absolute beginner to this, i've been trying to collect handle on my system using ntquerysysteminformation and now i get the handle that i want(i know this by using processhacker) but the problem coming when i try to collect the pid from that handle in order to determine which handle that is correct to inject my dll(my function returns array of handle), i know it can be simply use getprocessid() from msdn but it returns 0x6 errorcode.

is there another graceful way to do this without using openprocess? *duplicatehandle() doesn't seems to work as well

or is there a way to simply add process_query_information access right to this handle?


Solution

  • Since we are in an external process, so it makes no sense to distribute the handle provided by NtQuerySystemInformation, you need to copy the handle into our own process.

    source process for testing:

    #include <Windows.h>
    #include <iostream>
    #include <fstream>
    int main()
    {
       
        HANDLE hprocess = OpenProcess(PROCESS_VM_READ,false,10924);//any access without PROCESS_QUERY_INFORMATION or PROCESS_QUERY_LIMITED_INFORMATION
        printf("pid: %d\n", GetCurrentProcessId());
        printf("handle:  0x%x\nwait...\n", hprocess);
        getchar();
        CloseHandle(hprocess);
        return 0;
    }
    

    Result:

    pid: 11972
    handle:  0x108
    wait...
    

    main process:

    #include <Windows.h>
    #include <iostream>
    using namespace std;
    
    typedef struct _SYSTEM_HANDLE_INFORMATION
    {
        ULONG ProcessId;
        UCHAR ObjectTypeNumber;
        UCHAR Flags;
        USHORT Handle;
        PVOID Object;
        ACCESS_MASK GrantedAccess;
    }SYSTEM_HANDLE_INFORMATION, * PSYSTEM_HANDLE_INFORMATION;
    
    typedef struct _SYSTEM_HANDLE_INFORMATION_EX
    {
        ULONG NumberOfHandles;
        SYSTEM_HANDLE_INFORMATION Information[655360];//This is the size I defined myself
    }SYSTEM_HANDLE_INFORMATION_EX, * PSYSTEM_HANDLE_INFORMATION_EX;
    
    #define SystemHandleInformation 0x10
    
    typedef NTSTATUS(WINAPI* NTQUERYSYSTEMINFORMATION)(DWORD, PVOID, DWORD, PDWORD);
    
    int main()
    {
        HMODULE hNtDll = LoadLibraryW(L"ntdll.dll");
        NTQUERYSYSTEMINFORMATION NtQuerySystemInformation = (NTQUERYSYSTEMINFORMATION)GetProcAddress(hNtDll, "NtQuerySystemInformation");
        ULONG cbBuffer = sizeof(SYSTEM_HANDLE_INFORMATION_EX);
        LPVOID pBuffer = (LPVOID)malloc(cbBuffer);
        if (pBuffer)
        {
            NTSTATUS  status = NtQuerySystemInformation(SystemHandleInformation, pBuffer, cbBuffer, NULL);
            PSYSTEM_HANDLE_INFORMATION_EX pInfo = (PSYSTEM_HANDLE_INFORMATION_EX)pBuffer;
            DWORD pid = 0;
            int err = 0;
            for (ULONG r = 0; r < pInfo->NumberOfHandles; r++)
            {
                if (pInfo->Information[r].ProcessId == 11972 && pInfo->Information[r].Handle == 0x108)//hard code to test
                {
                    if ((pid = GetProcessId((HANDLE)pInfo->Information[r].Handle)) == 0)
                    {
                        err = GetLastError();
                        cout << "The 1st GetProcessId error : " << err << endl;
                    }
                    HANDLE hProcess = OpenProcess(PROCESS_DUP_HANDLE, false, pInfo->Information[r].ProcessId);
                    HANDLE hTarget;
                    if (!DuplicateHandle(hProcess, (HANDLE)pInfo->Information[r].Handle, ::GetCurrentProcess(), &hTarget, PROCESS_QUERY_LIMITED_INFORMATION, FALSE, 0))
                    {
                        err = GetLastError();
                        cout << "DuplicateHandle error : " << err << endl;
                        return -1;
                    }
                    if ((pid = GetProcessId(hTarget)) == 0)
                    {
                        err = GetLastError();
                        cout << "GetProcessId error : " << err << endl;
                        return -1;
                    }
                    cout << "The 2nd GetProcessId succeed, " << "ProcessId =  " << pid << endl;
                }
    
            }
    
            free(pBuffer);
        }
        FreeModule(hNtDll);
        getchar();
    }
    

    Result:

    The 1st GetProcessId error : 6
    The 2nd GetProcessId succeed, ProcessId =  10924