在开机启动应用程序时,可能会碰到权限不够而启动失败或者一些其他问题,所以在开机启动程序时可能会使用SYSTEM权限,但由于后来的操作不需要高权限来完成,就需要降低应用程序的权限。可以通过获取explorer.exe进程ID来实现。
1 DWORD CCommonFun::LaunchAppIntoDifferentSession(LPCTSTR lpszAppPath,
2 LPCTSTR lpszParameters,
3 LPCTSTR lpszDirectory,
4 LPCTSTR lpszRightsProcess,
5 DWORD dwMilliseconds, // wait times INFINITE
6 BOOL bIsWait)
7 {
8 PROCESS_INFORMATION pi;
9 STARTUPINFO si;
10 HANDLE hUserTokenDup = NULL;
11 HANDLE hUserToken = NULL;
12 HANDLE hProcess = NULL;
13 HANDLE hPToken = NULL;
14 DWORD dwCreationFlags = 0;
15 DWORD dwSessionId = 0;
16 DWORD winlogonPid = 0;
17 BOOL bResult = FALSE;
18
19
20 // Log the client on to the local computer.
21 // windows2000系统兼容修改 [4/1/2012 wanghaiguang]
22 typedef DWORD (WINAPI *LoadWTSGetActiveConsoleSessionId)(VOID);
23
24 HMODULE hModKrl = LoadLibrary(TEXT("Kernel32.dll"));
25 if (!hModKrl)
26 {
27 LOG("导入 kernel32.dll 失败");
28 return 1;
29 }
30
31 LoadWTSGetActiveConsoleSessionId fWTSGetActiveConsoleSessionId = (LoadWTSGetActiveConsoleSessionId)GetProcAddress(hModKrl, "WTSGetActiveConsoleSessionId");
32 if (!fWTSGetActiveConsoleSessionId)
33 {
34 LOG("调用WTSGetActiveConsoleSessionId 失败");
35 FreeLibrary(hModKrl);
36 return 1;
37 }
38 dwSessionId = fWTSGetActiveConsoleSessionId();
39
40 if (hModKrl)
41 {
42 FreeLibrary(hModKrl);
43 }
44
45 //////////////////////////////////////////
46 // Find the winlogon process
47 ////////////////////////////////////////
48
49 PROCESSENTRY32 procEntry;
50
51 HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
52 if (hSnap == INVALID_HANDLE_VALUE)
53 {
54 return 1 ;
55 }
56
57 procEntry.dwSize = sizeof(PROCESSENTRY32);
58
59 if (!Process32First(hSnap, &procEntry))
60 {
61 return 1 ;
62 }
63
64 do
65 {
66 if (_stricmp(procEntry.szExeFile, lpszRightsProcess/*"explorer.exe","winlogon.exe"*/) == 0)
67 {
68 // We found a winlogon processmake sure it's running in the console session
69 DWORD winlogonSessId = 0;
70 if (ProcessIdToSessionId(procEntry.th32ProcessID, &winlogonSessId) && winlogonSessId == dwSessionId)
71 {
72 winlogonPid = procEntry.th32ProcessID;
73 break;
74 }
75 }
76
77 } while (Process32Next(hSnap, &procEntry));
78
79 ////////////////////////////////////////////////////////////////////////
80
81 // windows2000系统兼容修改 [4/1/2012 wanghaiguang]
82 typedef BOOL (__stdcall *LoadWTSQueryUserToken)(ULONG, PHANDLE);
83 HMODULE hModwsi = LoadLibrary(TEXT("Wtsapi32.dll"));
84 if (!hModwsi)
85 {
86 LOG("导入Wtsapi32.dll 失败");
87 return 1;
88 }
89
90 LoadWTSQueryUserToken fWTSQueryUserToken = (LoadWTSQueryUserToken)GetProcAddress(hModwsi, "WTSQueryUserToken");
91 if (!fWTSQueryUserToken)
92 {
93 LOG("调用WTSQueryUserToken 失败");
94 FreeLibrary(hModKrl);
95 return 1;
96 }
97 fWTSQueryUserToken(dwSessionId,&hUserToken);
98
99 if (hModwsi)
100 {
101 FreeLibrary(hModKrl);
102 }
103 //WTSQueryUserToken(dwSessionId,&hUserToken);
104 dwCreationFlags = NORMAL_PRIORITY_CLASS|CREATE_NEW_CONSOLE;
105 ZeroMemory(&si, sizeof(STARTUPINFO));
106 si.cb= sizeof(STARTUPINFO);
107 si.lpDesktop = "winsta0\\default";
108 ZeroMemory(&pi, sizeof(pi));
109 TOKEN_PRIVILEGES tp;
110 LUID luid;
111 hProcess = OpenProcess(MAXIMUM_ALLOWED,FALSE,winlogonPid);
112
113 if(!::OpenProcessToken(hProcess,TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY
114 |TOKEN_DUPLICATE|TOKEN_ASSIGN_PRIMARY|TOKEN_ADJUST_SESSIONID
115 |TOKEN_READ|TOKEN_WRITE,&hPToken))
116 {
117 int abcd = GetLastError();
118 printf("Process token open Error: %u\n",GetLastError());
119 }
120
121 if (!LookupPrivilegeValue(NULL,SE_DEBUG_NAME,&luid))
122 {
123 printf("Lookup Privilege value Error: %u\n",GetLastError());
124 }
125 tp.PrivilegeCount =1;
126 tp.Privileges[0].Luid =luid;
127 tp.Privileges[0].Attributes =SE_PRIVILEGE_ENABLED;
128
129 DuplicateTokenEx(hPToken,MAXIMUM_ALLOWED,NULL,SecurityIdentification,TokenPrimary,&hUserTokenDup);
130 int dup = GetLastError();
131
132 //Adjust Token privilege
133 SetTokenInformation(hUserTokenDup,TokenSessionId,(void*)dwSessionId,sizeof(DWORD));
134
135 if (!AdjustTokenPrivileges(hUserTokenDup,FALSE,&tp,sizeof(TOKEN_PRIVILEGES),(PTOKEN_PRIVILEGES)NULL,NULL))
136 {
137 int abc =GetLastError();
138 printf("Adjust Privilege value Error: %u\n",GetLastError());
139 }
140
141 if (GetLastError()== ERROR_NOT_ALL_ASSIGNED)
142 {
143 printf("Token does not have the provilege\n");
144 }
145
146 LPVOID pEnv =NULL;
147
148 if(CreateEnvironmentBlock(&pEnv,hUserTokenDup,TRUE))
149 {
150 dwCreationFlags|=CREATE_UNICODE_ENVIRONMENT;
151 }
152 else
153 pEnv=NULL;
154
155 // Launch the process in the client's logon session.
156 bResult = CreateProcessAsUser(
157 hUserTokenDup, // client's access token
158 lpszAppPath, // file to execute
159 (LPSTR)lpszParameters, // command line
160 NULL, // pointer to process SECURITY_ATTRIBUTES
161 NULL, // pointer to thread SECURITY_ATTRIBUTES
162 FALSE, // handles are not inheritable
163 dwCreationFlags, // creation flags
164 pEnv, // pointer to new environment block
165 lpszDirectory, // name of current directory
166 &si, // pointer to STARTUPINFO structure
167 &pi // receives information about new process
168 );
169 // End impersonation of client.
170
171 //GetLastError Shud be 0
172
173 int iResultOfCreateProcessAsUser = GetLastError();
174
175 //Perform All the Close Handles task
176
177 if (hProcess)
178 {
179 CloseHandle(hProcess);
180 }
181
182 if (hUserToken)
183 {
184 CloseHandle(hUserToken);
185 }
186
187 if (hUserTokenDup)
188 {
189 CloseHandle(hUserTokenDup);
190 }
191
192 if (hPToken)
193 {
194 CloseHandle(hPToken);
195 }
196
197 if ( !bIsWait )
198 return 0;
199
200 if (WaitForSingleObject(pi.hProcess, dwMilliseconds) == WAIT_TIMEOUT)
201 {
202 TerminateProcess(pi.hProcess, 0);
203 return 0;
204 }
205
206 DWORD dwExitCode;
207 BOOL bOK = GetExitCodeProcess(pi.hProcess, &dwExitCode);
208 ASSERT(bOK);
209
210 return 0;
211 }
posted on 2012-09-29 14:22
王海光 阅读(1194)
评论(0) 编辑 收藏 引用 所属分类:
MFC