#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);
}