对目标进程提权、然后打开,提权的目的是为了防止当前进程的权限无法打开目标进程,获取句柄。
BOOL __EnableDebugPrivilege = TRUE; //代表需要提权
BOOL __EnableDebugPrivilege = FALSE;//代表不需提权
BOOL EnableSeDebugPrivilege(const TCHAR* PriviledgeName, BOOL IsEnable)
{
BOOL IsOk = FALSE;
int LastError = 0;
//获取当前进程句柄(伪句柄)
HANDLE ProcessHandle = GetCurrentProcess();
HANDLE TokenHandle = INVALID_HANDLE_VALUE;
TOKEN_PRIVILEGES TokenPrivileges = { 0 };
//通过当前进程句柄获得当前进程中令牌句柄
if (!OpenProcessToken(ProcessHandle, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &TokenHandle))
/*BOOL OpenProcessToken( ** 得到进程的令牌句柄
__in HANDLE ProcessHandle, //要修改访问权限的进程句柄
__in DWORD DesiredAccess, //指定你要进行的操作类型
__out PHANDLE TokenHandle //返回的访问令牌指针
)*/
{
LastError = GetLastError();
goto Exit;
}
LUID Luid; //Locally Unique Identifier
if (!LookupPrivilegeValue(NULL, PriviledgeName, &Luid)) // 通过权限名称查找uID
//函数查看系统权限的特权值,返回信息到一个LUID结构体里
/*BOOL LookupPrivilegeValue(
LPCTSTR lpSystemName, 表示所要查看的系统,本地系统直接用NULL
LPCTSTR lpName, 指向一个以零结尾的字符串,指定特权的名称
PLUID lpLuid); 接收所返回的制定特权名称的信息*/
{
LastError = GetLastError();
goto Exit;
}
TokenPrivileges.PrivilegeCount = 1; // 要提升的权限个数
TokenPrivileges.Privileges[0].Attributes = IsEnable == TRUE ? SE_PRIVILEGE_ENABLED : 0;
TokenPrivileges.Privileges[0].Luid = Luid;
if (!AdjustTokenPrivileges(TokenHandle, FALSE, &TokenPrivileges,
sizeof(TOKEN_PRIVILEGES), NULL, NULL)) // 启用或禁用特权一个有TOKEN_ADJUST_PRIVILEGES访问的访问令牌.
/*BOOL AdjustTokenPrivileges(
HANDLE TokenHandle, //包含特权的句柄 必须有 TOKEN_ADJUST_PRIVILEGES访问令牌
BOOL DisableAllPrivileges,//禁用所有权限标志
PTOKEN_PRIVILEGES NewState,//新特权信息的指针(结构体)
DWORD BufferLength, //缓冲数据大小,以字节为单位的PreviousState的缓存区(sizeof)
PTOKEN_PRIVILEGES PreviousState,//接收被改变特权当前状态的Buffer
PDWORD ReturnLength //接收PreviousState缓存区要求的大小
);*/
{
LastError = GetLastError();
goto Exit;
}
IsOk = TRUE;
Exit:
if (TokenHandle != INVALID_HANDLE_VALUE)
{
CloseHandle(TokenHandle);
TokenHandle = INVALID_HANDLE_VALUE;
}
SetLastError(LastError);
return IsOk;
}
HANDLE OpenProcess(DWORD DesiredAccess, BOOL IsInheritHandle, HANDLE ProcessID)
{
if (__EnableDebugPrivilege)
{
EnableSeDebugPrivilege(_T("SeDebugPrivilege"), TRUE);
}
HANDLE ProcessHandle = ::OpenProcess(DesiredAccess, IsInheritHandle, (DWORD)ProcessID);
DWORD LastError = GetLastError();
if (__EnableDebugPrivilege)
{
EnableSeDebugPrivilege(_T("SeDebugPrivilege"), FALSE);
}
SetLastError(LastError);
return ProcessHandle;
}