模拟用户的典型方法是调用LogOnUser()获取用户的访问令牌,并将此令牌传递给ImpersonateLoggedOnUser()进行模拟。
但是,这只能模拟用户呼叫线程。有没有办法模拟或更改进程的访问令牌(主令牌)?支持我正在访问网络共享,并且产生了多个线程来访问该网络共享的不同部分。我是否必须在所有这些线程中模拟远程用户(有权访问该共享)?还是有一种方法可以首先“模拟”该进程,以便在生成新线程时通过自动继承该进程的主要令牌已经拥有访问权限?
答案 0 :(得分:2)
不,这是不可能的。 ProcessAccessToken
的形式存在的 NtSetInformationProcess
信息类。它以PROCESS_ACCESS_TOKEN
结构作为输入。它没有记录,但在 ntddk.h
// // Process Security Context Information // NtSetInformationProcess using ProcessAccessToken // PROCESS_SET_ACCESS_TOKEN access to the process is needed // to use this info level. // typedef struct _PROCESS_ACCESS_TOKEN { // // Handle to Primary token to assign to the process. // TOKEN_ASSIGN_PRIMARY access to this token is needed. // HANDLE Token; // // Handle to the initial thread of the process. // A process's access token can only be changed if the process has // no threads or a single thread that has not yet begun execution. // // N.B. This field is unused. // HANDLE Thread; } PROCESS_ACCESS_TOKEN, *PPROCESS_ACCESS_TOKEN;
请注意
仅当进程没有线程或单个线程尚未开始执行时,才可以更改该进程的访问令牌。
实际上在xp / 2003上的条件不太严格:来自wrk中的 PspAssignPrimaryToken
仅当进程没有线程时才可以替换主令牌,或者 有一个线程。
但从Vista开始,此添加的尚未开始执行
如果您将其称为用于自处理(您可能需要 SeAssignPrimaryTokenPrivilege 特权,并且可以不使用它而获得STATUS_PRIVILEGE_NOT_HELD
,具体取决于令牌类型)-您会遇到STATUS_NOT_SUPPORTED
错误。为example
因此,实际上,我们只能在以挂起状态启动进程后才更改进程令牌(例如,查看此answer)。但无论如何还是最好使用CreateProcessAsUserW
函数。
答案 1 :(得分:1)
唯一可行的方法是在主线程中准备令牌,并将相同的令牌传递给新线程以供模拟。这样,新线程本身不必再次调用 Widget _buildDropdownItem(Country country) => Row(
children: <Widget>[
Expanded(child: Container(
margin: EdgeInsets.only(right: 8),
child: CountryPickerUtils.getDefaultFlagImage(country)),),
Expanded(child: Text(
"+${country.phoneCode}(${country.isoCode})",
overflow: Overflow.Eclipse
),)
],
);
。他们只需要模拟(相同的令牌)。