C++ 有没有办法为另一个进程设置令牌?

C++ 有没有办法为另一个进程设置令牌?,c++,windows,multithreading,winapi,token,C++,Windows,Multithreading,Winapi,Token,有SetThreadToken()函数,但没有“SetProcessToken()”这样的函数 有没有办法为另一个进程设置令牌?如何写入“SetProcessToken()”?进程只有一个安全令牌,即主安全令牌,它是用户安全令牌的副本 线程还有第二个安全令牌,即模拟令牌。进程没有这些,只有线程。您不能让进程模拟另一个用户的安全令牌。是的,您可以使用未记录的功能,但是一旦进程开始运行,进程令牌将被锁定,并且无法再修改。因此,必须使用CREATE\u SUSPENDED创建标志启动进程,设置进程令牌

有SetThreadToken()函数,但没有“SetProcessToken()”这样的函数


有没有办法为另一个进程设置令牌?如何写入“SetProcessToken()”?

进程只有一个安全令牌,即主安全令牌,它是用户安全令牌的副本


线程还有第二个安全令牌,即模拟令牌。进程没有这些,只有线程。您不能让进程模拟另一个用户的安全令牌。

是的,您可以使用未记录的功能,但是一旦进程开始运行,进程令牌将被锁定,并且无法再修改。因此,必须使用
CREATE\u 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;
//一些必需的typedef
typedef枚举\u进程\u信息\u类
{
工艺基础信息,
加工工艺,
进程计数器,
ProcessVmCounters,
处理时间,
ProcessBasePriority,
进程优先级,
进程调试端口,
进程例外端口,
ProcessAccessToken,
过程信息,
ProcessLdtSize,
ProcessDefaultHardErrorMode,
加工工,
ProcessPooledUsageAndLimits,
ProcessWorkingSetWatch,
ProcessUserModeIOPL,
ProcessEnableAlignmentFaultFixup,
ProcessPriorityClass,
ProcessWx86信息,
进程句柄计数,
处理亲缘关系掩码,
ProcessPriorityBoost,
MaxProcessInfoClass
}流程信息类、*P流程信息类;
typedef结构\u进程\u访问\u令牌
{
处理令牌;
手柄螺纹;
}进程访问令牌,*p进程访问令牌;
typedef NTSTATUS(NTAPI*NtSetInformationProcess)(句柄进程句柄、进程信息类信息类、PVOID信息、ULONG信息长度);
//假设我们有一个现有进程的句柄:targetProcessHandle,在挂起状态下启动,并有一个新令牌:newToken分配给这个进程。
//首先,我们必须启用SeAssignPrimaryTokenPrivilege。
//注意:运行此操作的用户必须已经拥有该权限,这只会启用该权限(默认情况下,该权限最初处于禁用状态)。
路易斯·路易斯;
LookupPrivilegeValue(0,SE_ASSIGNPRIMARYTOKEN_NAME,&luid);
代币特权;
privs.privilegecont=1;
privs.Privileges[0]。Luid=Luid;
privs.Privileges[0]。Attributes=SE_PRIVILEGE_ENABLED;
处理myToken;
if(!OpenProcessToken(GetCurrentProcess()、TOKEN\u ADJUST\u PRIVILEGES和myToken))
{
wprintf(“无法打开自己的进程令牌以启用权限\n”);
返回FALSE;
}
if(!AdjustTokenPrivileges(myToken、FALSE和privs、sizeof(TOKEN\u PRIVILEGES)、0、0))
{
wprintf(“设置令牌权限时出错:0x%08x\n”,GetLastError());
CloseHandle(myToken);
返回FALSE;
}
//即使AdjustTokenPrivileges返回TRUE,也可能未成功,请检查上次错误顶部确认
如果(GetLastError()==未分配所有错误)
{
wprintf(“无法启用所需的权限\n”);
CloseHandle(myToken);
返回FALSE;
}
CloseHandle(myToken);
处理\u访问\u令牌信息;
tokenInfo.Token=newToken;
tokenInfo.Thread=0;
//获取ntdll的句柄
HMODULE ntdll=LoadLibrary(L“ntdll.dll”);
//以及一个指向NtSetInformationProcess函数的指针
NtSetInformationProcess setInfo=(NtSetInformationProcess)GetProcAddress(ntdll,“NtSetInformationProcess”);
NTSTATUS setInfoResult=setInfo(targetProcessHandle、ProcessAccessToken和tokenInfo、sizeof(PROCESS_ACCESS_TOKEN));
如果(设置信息结果<0)
{
wprintf(L“错误设置令牌:0x%08x\n”,setInfoResult);
返回FALSE;
}
免费图书馆(ntdll);
//现在可以使用ResumeThread()在此处恢复目标进程的主线程。
返回TRUE;

是。通过
OpenProcessToken()
获取您的一个令牌,使用
DuplicateTokenEx()
复制令牌,使用
SetTokenInformation()
设置复制的令牌,并通过
CreateProcessAsUser()
使用此令牌创建新进程


为此,您需要
SeTcbPrivilege
SeAssignPrimaryTokenPrivilege
SeIncreaseQuotaPrivilege

@user143233,以便为当前进程或先前使用新进程
OpenProcess()
获得的进程句柄设置权限。您可以使用此令牌创建一个新进程。在DuplicateTokenEx()之后,您有一个与任何进程都不关联的令牌。更改它没有任何效果,但一旦您使用此令牌创建了一个新进程,新进程将获得令牌的设置。由于从超级用户链接到,因此将进行升级投票。这很有效!问题:在Windows 10上,
WHOAMI
没有告诉我是否启用了SeAssignPrimaryTokenPrivilege,所以我不知道。如果我不启用它,代码也可以工作。你知道为什么吗?我想确保这在大多数情况下都有效。我是本地计算机管理员,正在运行提升版。可能LocalAdmin没有允许的SeAssignPrimaryTokenPrivilege权限。这就是为什么启用它仍然不会在
WHOAMI
中显示它的原因。无论如何,这段代码在W10中工作。@Iridium为什么不能使用NtSuspendProcess,然后为已经运行的进程设置令牌process@T.s.Arun-如果我还记得(虽然现在已经将近9年了),它在已经运行的进程上不起作用,因此我假设一旦进程开始运行,令牌就会被锁定,然而,我不认为我曾经尝试过暂停一个正在运行的进程,然后尝试更改令牌,所以也许这确实有效-尝试一下,让我们知道@T.s.Arun-不幸的是,我决不是这方面的专家,我只能发布这个答案,因为我恰好是逆向工程应用程序,在提出问题时使用了这种技术。通过在网站上发布适当的问题,您可能会得到更好的帮助