#include <windows.h>
#include <winternl.h>
#include <stdio.h>
#include <wchar.h>
int main(int argc, char **argv) {
int pid;
if (argc <= 1) {
printf_s("usage: %s <pid>", argv[0]);
return 0;
}
pid = atoi(argv[1]);
HMODULE dll = LoadLibrary(L"Ntdll");
typedef NTSTATUS(NTAPI *NtQueryInformationProcess_t)(
IN HANDLE ProcessHandle,
IN PROCESSINFOCLASS ProcessInformationClass,
OUT PVOID ProcessInformation,
IN ULONG ProcessInformationLength,
OUT PULONG ReturnLength OPTIONAL
);
NtQueryInformationProcess_t NtQueryInformationProcess = (NtQueryInformationProcess_t)GetProcAddress(dll, "NtQueryInformationProcess");
PROCESS_BASIC_INFORMATION pbi = {};
RTL_USER_PROCESS_PARAMETERS upp = {};
PEB peb = {};
DWORD len;
HANDLE handle = OpenProcess(PROCESS_ALL_ACCESS, TRUE, pid);
int ret = NtQueryInformationProcess(handle, ProcessBasicInformation, &pbi, sizeof(pbi), &len);
if (ret) {
wprintf_s(L"Failed (%d)\n", ret);
return ret;
}
ReadProcessMemory(handle, pbi.PebBaseAddress, &peb, sizeof(PEB), &len);
ReadProcessMemory(handle, peb.ProcessParameters, &upp, sizeof(RTL_USER_PROCESS_PARAMETERS), &len);
UNICODE_STRING CurrentDirectoryPath = *(UNICODE_STRING*)(upp.Reserved2 + 5);
WCHAR *path = new WCHAR[CurrentDirectoryPath.Length / 2 + 1];
ReadProcessMemory(handle, CurrentDirectoryPath.Buffer, path, CurrentDirectoryPath.Length, &len);
path[CurrentDirectoryPath.Length / 2] = 0;
wprintf_s(L"%ls\n", path);
FreeLibrary(dll);
}