Last active
October 21, 2024 07:56
-
-
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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