windows system模拟普通用户执行函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
bool ChangeToken(const std::string &path)
{
#define INFO_BUFFER_SIZE 32767
char infoBuf[INFO_BUFFER_SIZE];
DWORD bufCharCount = INFO_BUFFER_SIZE;
if (!GetUserNameA(infoBuf, &bufCharCount))
{
LOG_ERROR("GetUserName error!");
}
else
{
LOG_INFO("GetUserName %s!", infoBuf);
if (stricmp(("system"), infoBuf))
{
if (SystemParametersInfoA(SPI_SETDESKWALLPAPER, 0, (void*)path.c_str(), SPIF_SENDWININICHANGE | SPIF_UPDATEINIFILE))
{
LOG_INFO("SystemParametersInfoA() OK!");
return true;
}
else
{
LOG_ERROR("SystemParametersInfoA() error! %s", path.c_str());
return false;
}
}
}

HANDLE hToken = 0;
//GetProcessToken();
HANDLE hProcessSnap = 0;
PROCESSENTRY32 pe32 = { 0 };
DWORD sid = WTSGetActiveConsoleSessionId(); // 已激活的桌面会话ID
if (!WTSQueryUserToken(sid, &hToken)) // 查询TOKEN
{
LOG_ERROR("WTSQueryUserToken() error!");
return false;
}
if (ImpersonateLoggedOnUser(hToken)) // 模拟用户登陆
LOG_INFO("ImpersonateLoggedOnUser() is OK.\n");
else
{
LOG_ERROR("ImpersonateLoggedOnUser() failed, error % u.\n", GetLastError());
return false;
}
// 此时已经是用户状态
/////////////////
// TODO: Do other desired tasks
//////////////////
// 调用取用户的函数时正确取得用户名。
if (!GetUserNameA(infoBuf, &bufCharCount))
{
LOG_ERROR("GetUserName error!");
}
else
{
LOG_INFO("GetUserName %s!", infoBuf);
}
// 此时修改用户桌面背景失败,原因暂时未找到
// 执行ShellExecute()时进程仍然在system用户下运行,
// 原因是ShellExecute启动子进程时继承了父进程的token而不是当前线程的token
if (SystemParametersInfoA(SPI_SETDESKWALLPAPER, 0, (void*)path.c_str(), SPIF_SENDWININICHANGE | SPIF_UPDATEINIFILE))
{
LOG_ERROR("SystemParametersInfoA() OK!\n");
}
else
{
LOG_INFO("SystemParametersInfoA() OK! %s", path.c_str());
}
// Terminates the impersonation of a client.
// 终止模拟用户
if (RevertToSelf())
LOG_ERROR("Impersonation was terminated.\n");
// Close the handle
if (CloseHandle(hToken))
LOG_INFO("Handle to an access token was closed.\n");
else
LOG_ERROR("Failed to close the hToken handle!error % u\n", GetLastError());
return true;
}

参考:

https://docs.microsoft.com/en-us/windows/win32/api/securitybaseapi/nf-securitybaseapi-impersonateloggedonuser

https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-systemparametersinfoa