lpa*_*ul7 1 c++ windows winapi multithreading token
有SetThreadToken()函数,但没有"SetProcessToken()"这样的函数.
有没有办法为另一个进程设置令牌?如何写"SetProcessToken()"?
是的,您可以使用未记录的NtSetInformationProcess功能,但是一旦进程开始运行,进程令牌就会被锁定,无法再进行修改.因此,您必须使用CREATE_SUSPENDED创建标志启动流程,设置流程令牌,然后使用恢复流程ResumeThread().为了设置进程令牌,调用者必须拥有并启用该SeAssignPrimaryTokenPrivilege权限.
以下代码应该足够:
// A few required typedefs
typedef enum _PROCESS_INFORMATION_CLASS
{
ProcessBasicInformation,
ProcessQuotaLimits,
ProcessIoCounters,
ProcessVmCounters,
ProcessTimes,
ProcessBasePriority,
ProcessRaisePriority,
ProcessDebugPort,
ProcessExceptionPort,
ProcessAccessToken,
ProcessLdtInformation,
ProcessLdtSize,
ProcessDefaultHardErrorMode,
ProcessIoPortHandlers,
ProcessPooledUsageAndLimits,
ProcessWorkingSetWatch,
ProcessUserModeIOPL,
ProcessEnableAlignmentFaultFixup,
ProcessPriorityClass,
ProcessWx86Information,
ProcessHandleCount,
ProcessAffinityMask,
ProcessPriorityBoost,
MaxProcessInfoClass
} PROCESS_INFORMATION_CLASS, *PPROCESS_INFORMATION_CLASS;
typedef struct _PROCESS_ACCESS_TOKEN
{
HANDLE Token;
HANDLE Thread;
} PROCESS_ACCESS_TOKEN, *PPROCESS_ACCESS_TOKEN;
typedef NTSTATUS (NTAPI * NtSetInformationProcess) (HANDLE processHandle, PROCESS_INFORMATION_CLASS infoClass, PVOID info, ULONG infoLength);
// Assume we have a handle to an existing process: targetProcessHandle, started in a suspended state, and a new token: newToken to assign to this process.
// First we must enable SeAssignPrimaryTokenPrivilege.
// Note: The user under which this runs must already hold the privilege, this only enables it (it is initially disabled by default).
LUID luid;
LookupPrivilegeValue(0, SE_ASSIGNPRIMARYTOKEN_NAME, &luid);
TOKEN_PRIVILEGES privs;
privs.PrivilegeCount = 1;
privs.Privileges[0].Luid = luid;
privs.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
HANDLE myToken;
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &myToken))
{
wprintf("Unable to open own process token to enable permissions\n");
return FALSE;
}
if (!AdjustTokenPrivileges(myToken, FALSE, &privs, sizeof(TOKEN_PRIVILEGES), 0, 0))
{
wprintf("Error setting token privileges: 0x%08x\n", GetLastError());
CloseHandle(myToken);
return FALSE;
}
// Even if AdjustTokenPrivileges returns TRUE, it may not have succeeded, check last error top confirm
if (GetLastError() == ERROR_NOT_ALL_ASSIGNED)
{
wprintf("Unable to enable a required privilege\n");
CloseHandle(myToken);
return FALSE;
}
CloseHandle(myToken);
PROCESS_ACCESS_TOKEN tokenInfo;
tokenInfo.Token = newToken;
tokenInfo.Thread = 0;
// Get a handle to ntdll
HMODULE ntdll = LoadLibrary(L"ntdll.dll");
// And a pointer to the NtSetInformationProcess function
NtSetInformationProcess setInfo = (NtSetInformationProcess)GetProcAddress(ntdll,"NtSetInformationProcess");
NTSTATUS setInfoResult = setInfo(targetProcessHandle, ProcessAccessToken, &tokenInfo, sizeof(PROCESS_ACCESS_TOKEN));
if (setInfoResult < 0)
{
wprintf(L"Error setting token: 0x%08x\n", setInfoResult);
return FALSE;
}
FreeLibrary(ntdll);
// You can now resume the target process' main thread here using ResumeThread().
return TRUE;
Run Code Online (Sandbox Code Playgroud)