#include<Windows.h>
#include<tchar.h>
#include<wchar.h>
#include<WtsApi32.h>
#include<sddl.h>
#include"Error.h"
#include"Header.h"
#include"Relaunch.h"
#include"Token.h"

#pragma comment(lib, "wtsapi32")
#pragma	comment(lib, "Advapi32")

int wmain(int argc, wchar_t *argv[], wchar_t *envp[]) {

	if (!EnableDebugAbilityWithChecks()) {
		_tprintf(_T("[-] Insufficient Privileges ... relaunching ...\n"));
		RelaunchSelf();
		ExitProcess(-1);
	}
	else
	{
		_tprintf(_T("[+] Enabled SeDebugPrivilege\n"));
	}

	int pid;

	if (argc < 2) {
		
		_tprintf(_T("Please enter the PID to dump token for: "));
		scanf_s("%d[^\n]", &pid);
	}
	else {
		pid = _wtoi(argv[1]);
	}

	_tprintf(_T("[+] Dumping token information for PID: %d\n"), pid);

	HANDLE processHandle;

	// We need a handle to the process using the PID
	if (NULL == (processHandle = OpenProcess(MAXIMUM_ALLOWED, false, pid))) {

		
		_tprintf(_T("[-] OpenProcess() with MAXIMUM_ALLOWED FAILED! Is this a Protected Process?\n"));
		_tprintf(_T("[+] Trying again with PROCESS_QUERY_LIMITED_INFORMATION request!\n"));
		
		if (NULL == (processHandle = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, false, pid))) {
			ErrorDetails(_T("[-] OpenProcess(): Some Uber Protected Process? exiting ...\n"), TRUE);
			// Protected processes
			// https://msdn.microsoft.com/en-us/library/windows/desktop/dn313124%28v=vs.85%29.aspx
		}
		else {
			_tprintf(_T("[+] Success! we have a Process Handle\n"));
		}
		
	}


	// Lets get access to the token! :) 
	HANDLE processToken;

	if (!OpenProcessToken(processHandle, MAXIMUM_ALLOWED, &processToken)) {

		ErrorDetails(_T("OpenProcessToken()"), TRUE);
	}

	// Let the parsing games begin :) 

	// Dump Token User 
	DumpTokenUser(processToken);

	// Dump Token Owner 
	DumpTokenOwner(processToken);

	// Dump Token Primary Group
	DumpTokenPrimaryGroup(processToken);

	// Dump Token Groups
	DumpTokenGroups(processToken);

	// Dump Privileges
	DumpTokenPrivileges(processToken);

	// Dump Token Source 
	DumpTokenSource(processToken);

	// Dump Token Type
	DumpTokenType(processToken);

	// Dump Token Elevation
	DumpTokenElevation(processToken);


	// Close Handles
	CloseHandle(processToken);
	CloseHandle(processHandle);


	//getchar();
	return 0;
}