Skip to content

Instantly share code, notes, and snippets.

@TheWover
Last active May 27, 2024 16:27
Show Gist options
  • Save TheWover/242b6037056f9e11281fc11dc1d4cc5b to your computer and use it in GitHub Desktop.
Save TheWover/242b6037056f9e11281fc11dc1d4cc5b to your computer and use it in GitHub Desktop.
Demonstrates use of NtQuerySystemInformation and SystemProcessIdInformation to get the image name of a process without opening a process handle
// Demonstrates use of NtQuerySystemInformation and SystemProcessIdInformation to get the image name of a process without opening a process handle
// Author: TheWover
//
#include <iostream>
#include <string>
#include "ntdefs.h"
typedef struct SYSTEM_PROCESS_ID_INFORMATION
{
ULONGLONG ProcessId;
UNICODE_STRING ImageName;
} *PSYSTEM_PROCESS_ID_INFORMATION;
bool demoNtQuerySystemInformation(ULONGLONG PID)
{
NTSTATUS status;
//Resolve the address of NtQuerySystemInformation
HMODULE ntdll = GetModuleHandleA("ntdll.dll");
_NtQuerySystemInformation NtQuerySystemInformation = (_NtQuerySystemInformation)GetProcAddress(ntdll, "NtQuerySystemInformation");
// Allocate enough memory
// 254 is the maximum length in bytes of the image path
void *allocBuffer = LocalAlloc(LMEM_FIXED | LMEM_ZEROINIT, 254);
if (!allocBuffer)
return false;
// We will query the SystemProcessIdInformation class, which provides the Image Name of a process given its PID.
// It is also possible to enumerate all processes and get their PID and Image name using this class, but for simplicity's sake we are requesting just one process's info.
// The SystemProcessIdInformation class requires us to pass in a struct of the type SYSTEM_PROCESS_ID_INFORMATION
// Now we create that strcut type and add our PID and buffer info
SYSTEM_PROCESS_ID_INFORMATION outputSPII = { 0 };
outputSPII.ProcessId = PID;
outputSPII.ImageName.MaximumLength = 254;
outputSPII.ImageName.Buffer = (PWSTR) allocBuffer;
// Run the query and capture the NTSTATUS result in case there is an error.
status = NtQuerySystemInformation(SystemProcessIdInformation, &outputSPII, sizeof(outputSPII), 0);
printf("NTSTATUS: %ld \n", status);
if (status == 0)
printf("Process %lld has an image path of: %wZ\n", PID, &outputSPII.ImageName);
else
{
LocalFree(allocBuffer);
return false;
}
LocalFree(allocBuffer);
}
int main(int argc, char* argv[])
{
if (argc > 1)
{
if (demoNtQuerySystemInformation(std::stoll(argv[1])) == false)
printf("Error: Failed to query process %s", argv[1]);
}
else
printf("Error: Please provide a PID as an argument.\n");
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment