text: #include "process_privilege.h"
  
  #include <iostream>
  
  namespace hhunter {
  	namespace util {
  
  		/*
  		based on: https://support.microsoft.com/en-us/help/131065/how-to-obtain-a-handle-to-any-process-with-sedebugprivilege
  		*/
  		BOOL set_privilege(
  			HANDLE hToken,          // token handle
  			LPCTSTR Privilege,      // Privilege to enable/disable
  			BOOL bEnablePrivilege   // TRUE to enable.  FALSE to disable
  		)
  		{
  			TOKEN_PRIVILEGES tp;
  			LUID luid;
  			TOKEN_PRIVILEGES tpPrevious;
  			DWORD cbPrevious = sizeof(TOKEN_PRIVILEGES);
  
  			if (!LookupPrivilegeValueA(nullptr, Privilege, &luid)) {
  				return FALSE;
  			}
  			// get current privilege
  			tp.PrivilegeCount = 1;
  			tp.Privileges[0].Luid = luid;
  			tp.Privileges[0].Attributes = 0;
  
  			AdjustTokenPrivileges(
  				hToken,
  				FALSE,
  				&tp,
  				sizeof(TOKEN_PRIVILEGES),
  				&tpPrevious,
  				&cbPrevious
  			);
  
  			if (GetLastError() != ERROR_SUCCESS) {
  				return FALSE;
  			}
  			// set privilege based on previous setting
  			tpPrevious.PrivilegeCount = 1;
  			tpPrevious.Privileges[0].Luid = luid;
  
  			if (bEnablePrivilege) {
  				tpPrevious.Privileges[0].Attributes |= (SE_PRIVILEGE_ENABLED);
  			}
  			else {
  				tpPrevious.Privileges[0].Attributes ^= (SE_PRIVILEGE_ENABLED & tpPrevious.Privileges[0].Attributes);
  			}
  
  			AdjustTokenPrivileges(
  				hToken,
  				FALSE,
  				&tpPrevious,
  				cbPrevious,
  				NULL,
  				NULL
  			);
  
  			if (GetLastError() != ERROR_SUCCESS) {
  				return FALSE;
  			}
  			return TRUE;
  		}
  
  	};
  };
  
  bool hhunter::util::set_debug_privilege()
  {
  	HANDLE hToken;
  	if (!OpenThreadToken(GetCurrentThread(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, FALSE, &hToken)) {
  		if (GetLastError() == ERROR_NO_TOKEN) {
  			if (!ImpersonateSelf(SecurityImpersonation)) return false;
  			if(!OpenThreadToken(GetCurrentThread(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, FALSE, &hToken)){
  				std::cerr << "Error: cannot open the token" << std::endl;
  				return false;
  			}
  		}
  	}
  	bool is_ok = false;
  	// enable SeDebugPrivilege
  	if (set_privilege(hToken, SE_DEBUG_NAME, TRUE)) {
  		is_ok = true;
  	}
  	// close token handle
  	CloseHandle(hToken);
  	return is_ok;
  }
  
  