由于这篇文章适应于Windows2000与WinNT操作系统,所以首先给出两个简易的判断当前操作系统,是否为Windows2000系统或WinNT系统的判断函数。
BOOL IsWin2K(void){
OSVERSIONINFO OSVersionInfo;
OSVersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
if(GetVersionEx(&OSVersionInfo)){
return ((OSVersion.dwPlatformId == VER_PLATFORM_WIN32_NT) &&
(OSVersion.dwMajoVersion == 5));
}
else{
return FALSE;
}
}
BOOL IsWinNT(void){
OSVERSIONINFO OSVersionInfo;
OSVersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
if(GetVersionEx(&OSVersionInfo)){
return ((OSVersion.dwPlatformId == VER_PLATFORM_WIN32_NT) &&
(OSVersion.dwMajoVersion == 5));
}
else{
return FALSE;
}
}
由于涉及到调试进程,就必须熟悉TOKEN_PRIVILEGES结构,这个结构中包含了一些access token的权限信息:
typedef struct __TOKEN_PRIVILEGES{
DWORD PrivilegeCount;
LUID_AND_ATTRIBUTES Privileges[];
}TOKEN_PRIVILEGES, *PTOKEN_PRIVILEGES;
第一个参数是Privileges数组的个数,第二个参数是一个LUID_AND_ATTRIBUTES结构数组,显来我们知道其中包含一个LUID(Locally unique identifier)值与一个属性值。再利用OpenProcessToken函数得到当前进程的access token的句柄:
HANDLE hToken;
OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY|TOKEN_ADJUST_PRIVILEGES, &hToken);
接着我们利用LookupPrivilegesValue函数取得LUID值:
TOKEN_PRIVILEGES TokenPrivileges;
LookupPrivilegesValue(NULL, "SeDebugPrivilege", &TokenPrivileges[0].Luid);
第一个参数我们传递一个NULL,即为地本系统,第二个参数我们传递一个特权名SeDebugPrivilege,第三个参数是用来保存LUID的地址。最后我们调用一个AdjustTokenPrivileges函数即可大功告成,以下给出完整的C++代码:
BOOL DebugWinLogon(void)
{
HANDLE hToken;
TOKEN_PRIVILEGES TokenPrivileges, PreviousState;
DWORD dwReturnLength = 0;
if(OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY|TOKEN_ADJUST_PRIVILEGES,
&hToken)){
if(LookupPrivilegesValue(NULL, "SeDebugPrivilege", &TokenPrivileges[0].Luid)){
TokenPrivileges.PrivilegeCount = 1;
TokenPrivileges[0].Attributes = SE_PRIVILEGE_ENABLED;
return (AdjustTokenPrivileges(hToken, FALSE, &TokenPrivileges, sizeof
(TOKEN_PRIVILEGES), &PreviousState, &dwReturnLength));
}
}
return FALSE;
}