如何降低权限启动应用程序
在开机启动应用程序时,可能会碰到权限不够而启动失败或者一些其他问题,所以在开机启动程序时可能会使用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 process make 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 }
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 process make 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 }