Process Hacker
secdata.c
Go to the documentation of this file.
1 /*
2  * Process Hacker -
3  * object security data
4  *
5  * Copyright (C) 2010-2011 wj32
6  *
7  * This file is part of Process Hacker.
8  *
9  * Process Hacker is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation, either version 3 of the License, or
12  * (at your option) any later version.
13  *
14  * Process Hacker is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with Process Hacker. If not, see <http://www.gnu.org/licenses/>.
21  */
22 
23 #include <phgui.h>
24 #include <secedit.h>
25 
26 #define ACCESS_ENTRIES(Type) static PH_ACCESS_ENTRY Ph##Type##AccessEntries[] =
27 #define ACCESS_ENTRY(Type, HasSynchronize) \
28  { L#Type, Ph##Type##AccessEntries, sizeof(Ph##Type##AccessEntries), HasSynchronize }
29 
30 typedef struct _PH_SPECIFIC_TYPE
31 {
32  PWSTR Type;
33  PPH_ACCESS_ENTRY AccessEntries;
34  ULONG SizeOfAccessEntries;
35  BOOLEAN HasSynchronize;
37 
38 ACCESS_ENTRIES(Standard)
39 {
40  { L"Synchronize", SYNCHRONIZE, FALSE, TRUE },
41  { L"Delete", DELETE, FALSE, TRUE },
42  { L"Read permissions", READ_CONTROL, FALSE, TRUE, L"Read control" },
43  { L"Change permissions", WRITE_DAC, FALSE, TRUE, L"Write DAC" },
44  { L"Take ownership", WRITE_OWNER, FALSE, TRUE, L"Write owner" }
45 };
46 
47 ACCESS_ENTRIES(AlpcPort)
48 {
49  { L"Full control", PORT_ALL_ACCESS, TRUE, TRUE },
50  { L"Connect", PORT_CONNECT, TRUE, TRUE }
51 };
52 
53 ACCESS_ENTRIES(DebugObject)
54 {
55  { L"Full control", DEBUG_ALL_ACCESS, TRUE, TRUE },
56  { L"Read events", DEBUG_READ_EVENT, TRUE, TRUE },
57  { L"Assign processes", DEBUG_PROCESS_ASSIGN, TRUE, TRUE },
58  { L"Query information", DEBUG_QUERY_INFORMATION, TRUE, TRUE },
59  { L"Set information", DEBUG_SET_INFORMATION, TRUE, TRUE }
60 };
61 
63 {
64  { L"Full control", DESKTOP_ALL_ACCESS, TRUE, TRUE },
65  { L"Read", DESKTOP_GENERIC_READ, TRUE, FALSE },
66  { L"Write", DESKTOP_GENERIC_WRITE, TRUE, FALSE },
67  { L"Execute", DESKTOP_GENERIC_EXECUTE, TRUE, FALSE },
68  { L"Enumerate", DESKTOP_ENUMERATE, FALSE, TRUE },
69  { L"Read objects", DESKTOP_READOBJECTS, FALSE, TRUE },
70  { L"Playback journals", DESKTOP_JOURNALPLAYBACK, FALSE, TRUE },
71  { L"Write objects", DESKTOP_WRITEOBJECTS, FALSE, TRUE },
72  { L"Create windows", DESKTOP_CREATEWINDOW, FALSE, TRUE },
73  { L"Create menus", DESKTOP_CREATEMENU, FALSE, TRUE },
74  { L"Create window hooks", DESKTOP_HOOKCONTROL, FALSE, TRUE },
75  { L"Record journals", DESKTOP_JOURNALRECORD, FALSE, TRUE },
76  { L"Switch desktop", DESKTOP_SWITCHDESKTOP, FALSE, TRUE }
77 };
78 
79 ACCESS_ENTRIES(Directory)
80 {
81  { L"Full control", DIRECTORY_ALL_ACCESS, TRUE, TRUE },
82  { L"Query", DIRECTORY_QUERY, TRUE, TRUE},
83  { L"Traverse", DIRECTORY_TRAVERSE, TRUE, TRUE},
84  { L"Create objects", DIRECTORY_CREATE_OBJECT, TRUE, TRUE},
85  { L"Create subdirectories", DIRECTORY_CREATE_SUBDIRECTORY, TRUE, TRUE}
86 };
87 
89 {
90  { L"Full control", EVENT_ALL_ACCESS, TRUE, TRUE },
91  { L"Query", EVENT_QUERY_STATE, TRUE, TRUE },
92  { L"Modify", EVENT_MODIFY_STATE, TRUE, TRUE }
93 };
94 
95 ACCESS_ENTRIES(EventPair)
96 {
97  { L"Full control", EVENT_PAIR_ALL_ACCESS, TRUE, TRUE }
98 };
99 
101 {
102  { L"Full control", FILE_ALL_ACCESS, TRUE, TRUE },
103  { L"Read & execute", FILE_GENERIC_READ | FILE_GENERIC_EXECUTE, TRUE, FALSE },
104  { L"Read", FILE_GENERIC_READ, TRUE, FALSE },
105  { L"Write", FILE_GENERIC_WRITE, TRUE, FALSE },
106  { L"Traverse folder / execute file", FILE_EXECUTE, FALSE, TRUE, L"Execute" },
107  { L"List folder / read data", FILE_READ_DATA, FALSE, TRUE, L"Read data" },
108  { L"Read attributes", FILE_READ_ATTRIBUTES, FALSE, TRUE },
109  { L"Read extended attributes", FILE_READ_EA, FALSE, TRUE, L"Read EA" },
110  { L"Create files / write data", FILE_WRITE_DATA, FALSE, TRUE, L"Write data" },
111  { L"Create folders / append data", FILE_APPEND_DATA, FALSE, TRUE, L"Append data" },
112  { L"Write attributes", FILE_WRITE_ATTRIBUTES, FALSE, TRUE },
113  { L"Write extended attributes", FILE_WRITE_EA, FALSE, TRUE, L"Write EA" },
114  { L"Delete subfolders and files", FILE_DELETE_CHILD, FALSE, TRUE, L"Delete child" }
115 };
116 
117 ACCESS_ENTRIES(FilterConnectionPort)
118 {
119  { L"Full control", FLT_PORT_ALL_ACCESS, TRUE, TRUE },
120  { L"Connect", FLT_PORT_CONNECT, TRUE, TRUE }
121 };
122 
123 ACCESS_ENTRIES(IoCompletion)
124 {
125  { L"Full control", IO_COMPLETION_ALL_ACCESS, TRUE, TRUE },
126  { L"Query", IO_COMPLETION_QUERY_STATE, TRUE, TRUE },
127  { L"Modify", IO_COMPLETION_MODIFY_STATE, TRUE, TRUE }
128 };
129 
131 {
132  { L"Full control", JOB_OBJECT_ALL_ACCESS, TRUE, TRUE },
133  { L"Query", JOB_OBJECT_QUERY, TRUE, TRUE },
134  { L"Assign processes", JOB_OBJECT_ASSIGN_PROCESS, TRUE, TRUE },
135  { L"Set attributes", JOB_OBJECT_SET_ATTRIBUTES, TRUE, TRUE },
136  { L"Set security attributes", JOB_OBJECT_SET_SECURITY_ATTRIBUTES, TRUE, TRUE },
137  { L"Terminate", JOB_OBJECT_TERMINATE, TRUE, TRUE }
138 };
139 
141 {
142  { L"Full control", KEY_ALL_ACCESS, TRUE, TRUE },
143  { L"Read", KEY_READ, TRUE, FALSE },
144  { L"Write", KEY_WRITE, TRUE, FALSE },
145  { L"Execute", KEY_EXECUTE, TRUE, FALSE },
146  { L"Enumerate subkeys", KEY_ENUMERATE_SUB_KEYS, FALSE, TRUE },
147  { L"Query values", KEY_QUERY_VALUE, FALSE, TRUE },
148  { L"Notify", KEY_NOTIFY, FALSE, TRUE },
149  { L"Set values", KEY_SET_VALUE, FALSE, TRUE },
150  { L"Create subkeys", KEY_CREATE_SUB_KEY, FALSE, TRUE },
151  { L"Create links", KEY_CREATE_LINK, FALSE, TRUE }
152 };
153 
154 ACCESS_ENTRIES(KeyedEvent)
155 {
156  { L"Full control", KEYEDEVENT_ALL_ACCESS, TRUE, TRUE },
157  { L"Wait", KEYEDEVENT_WAIT, TRUE, TRUE },
158  { L"Wake", KEYEDEVENT_WAKE, TRUE, TRUE }
159 };
160 
161 ACCESS_ENTRIES(LsaAccount)
162 {
163  { L"Full control", ACCOUNT_ALL_ACCESS, TRUE, TRUE },
164  { L"Read", ACCOUNT_READ, TRUE, FALSE },
165  { L"Write", ACCOUNT_WRITE, TRUE, FALSE },
166  { L"Execute", ACCOUNT_EXECUTE, TRUE, FALSE },
167  { L"View", ACCOUNT_VIEW, FALSE, TRUE },
168  { L"Adjust privileges", ACCOUNT_ADJUST_PRIVILEGES, FALSE, TRUE },
169  { L"Adjust quotas", ACCOUNT_ADJUST_QUOTAS, FALSE, TRUE },
170  { L"Adjust system access", ACCOUNT_ADJUST_SYSTEM_ACCESS, FALSE, TRUE }
171 };
172 
173 ACCESS_ENTRIES(LsaPolicy)
174 {
175  { L"Full control", POLICY_ALL_ACCESS | POLICY_NOTIFICATION, TRUE, TRUE },
176  { L"Read", POLICY_READ, TRUE, FALSE },
177  { L"Write", POLICY_WRITE, TRUE, FALSE },
178  { L"Execute", POLICY_EXECUTE | POLICY_NOTIFICATION, TRUE, FALSE },
179  { L"View local information", POLICY_VIEW_LOCAL_INFORMATION, FALSE, TRUE },
180  { L"View audit information", POLICY_VIEW_AUDIT_INFORMATION, FALSE, TRUE },
181  { L"Get private information", POLICY_GET_PRIVATE_INFORMATION, FALSE, TRUE },
182  { L"Administer trust", POLICY_TRUST_ADMIN, FALSE, TRUE },
183  { L"Create account", POLICY_CREATE_ACCOUNT, FALSE, TRUE },
184  { L"Create secret", POLICY_CREATE_SECRET, FALSE, TRUE },
185  { L"Create privilege", POLICY_CREATE_PRIVILEGE, FALSE, TRUE },
186  { L"Set default quota limits", POLICY_SET_DEFAULT_QUOTA_LIMITS, FALSE, TRUE },
187  { L"Set audit requirements", POLICY_SET_AUDIT_REQUIREMENTS, FALSE, TRUE },
188  { L"Administer audit log", POLICY_AUDIT_LOG_ADMIN, FALSE, TRUE },
189  { L"Administer server", POLICY_SERVER_ADMIN, FALSE, TRUE },
190  { L"Lookup names", POLICY_LOOKUP_NAMES, FALSE, TRUE },
191  { L"Get notifications", POLICY_NOTIFICATION, FALSE, TRUE }
192 };
193 
194 ACCESS_ENTRIES(LsaSecret)
195 {
196  { L"Full control", SECRET_ALL_ACCESS, TRUE, TRUE },
197  { L"Read", SECRET_READ, TRUE, FALSE },
198  { L"Write", SECRET_WRITE, TRUE, FALSE },
199  { L"Execute", SECRET_EXECUTE, TRUE, FALSE },
200  { L"Set value", SECRET_SET_VALUE, FALSE, TRUE },
201  { L"Query value", SECRET_QUERY_VALUE, FALSE, TRUE }
202 };
203 
204 ACCESS_ENTRIES(LsaTrusted)
205 {
206  { L"Full control", TRUSTED_ALL_ACCESS, TRUE, TRUE },
207  { L"Read", TRUSTED_READ, TRUE, FALSE },
208  { L"Write", TRUSTED_WRITE, TRUE, FALSE },
209  { L"Execute", TRUSTED_EXECUTE, TRUE, FALSE },
210  { L"Query domain name", TRUSTED_QUERY_DOMAIN_NAME, FALSE, TRUE },
211  { L"Query controllers", TRUSTED_QUERY_CONTROLLERS, FALSE, TRUE },
212  { L"Set controllers", TRUSTED_SET_CONTROLLERS, FALSE, TRUE },
213  { L"Query POSIX", TRUSTED_QUERY_POSIX, FALSE, TRUE },
214  { L"Set POSIX", TRUSTED_SET_POSIX, FALSE, TRUE },
215  { L"Query authentication", TRUSTED_QUERY_AUTH, FALSE, TRUE },
216  { L"Set authentication", TRUSTED_SET_AUTH, FALSE, TRUE }
217 };
218 
220 {
221  { L"Full control", MUTANT_ALL_ACCESS, TRUE, TRUE },
222  { L"Query", MUTANT_QUERY_STATE, TRUE, TRUE }
223 };
224 
226 {
227  { L"Full control", STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0xfff, TRUE, TRUE },
228  { L"Query information", PROCESS_QUERY_INFORMATION, TRUE, TRUE },
229  { L"Set information", PROCESS_SET_INFORMATION, TRUE, TRUE },
230  { L"Set quotas", PROCESS_SET_QUOTA, TRUE, TRUE },
231  { L"Set session ID", PROCESS_SET_SESSIONID, TRUE, TRUE },
232  { L"Create threads", PROCESS_CREATE_THREAD, TRUE, TRUE },
233  { L"Create processes", PROCESS_CREATE_PROCESS, TRUE, TRUE },
234  { L"Modify memory", PROCESS_VM_OPERATION, TRUE, TRUE, L"VM operation" },
235  { L"Read memory", PROCESS_VM_READ, TRUE, TRUE, L"VM read" },
236  { L"Write memory", PROCESS_VM_WRITE, TRUE, TRUE, L"VM write" },
237  { L"Duplicate handles", PROCESS_DUP_HANDLE, TRUE, TRUE },
238  { L"Suspend / resume / set port", PROCESS_SUSPEND_RESUME, TRUE, TRUE, L"Suspend/resume" },
239  { L"Terminate", PROCESS_TERMINATE, TRUE, TRUE }
240 };
241 
242 ACCESS_ENTRIES(Process60)
243 {
244  { L"Full control", STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0xffff, TRUE, TRUE }, // PROCESS_ALL_ACCESS
245  { L"Query limited information", PROCESS_QUERY_LIMITED_INFORMATION, TRUE, TRUE },
246  { L"Query information", PROCESS_QUERY_INFORMATION | PROCESS_QUERY_LIMITED_INFORMATION, TRUE, TRUE },
247  { L"Set information", PROCESS_SET_INFORMATION, TRUE, TRUE },
248  { L"Set quotas", PROCESS_SET_QUOTA, TRUE, TRUE },
249  { L"Set session ID", PROCESS_SET_SESSIONID, TRUE, TRUE },
250  { L"Create threads", PROCESS_CREATE_THREAD, TRUE, TRUE },
251  { L"Create processes", PROCESS_CREATE_PROCESS, TRUE, TRUE },
252  { L"Modify memory", PROCESS_VM_OPERATION, TRUE, TRUE, L"VM operation" },
253  { L"Read memory", PROCESS_VM_READ, TRUE, TRUE, L"VM read" },
254  { L"Write memory", PROCESS_VM_WRITE, TRUE, TRUE, L"VM write" },
255  { L"Duplicate handles", PROCESS_DUP_HANDLE, TRUE, TRUE },
256  { L"Suspend / resume / set port", PROCESS_SUSPEND_RESUME, TRUE, TRUE, L"Suspend/resume" },
257  { L"Terminate", PROCESS_TERMINATE, TRUE, TRUE }
258 };
259 
261 {
262  { L"Full control", PROFILE_ALL_ACCESS, TRUE, TRUE },
263  { L"Control", PROFILE_CONTROL, TRUE, TRUE }
264 };
265 
266 ACCESS_ENTRIES(SamAlias)
267 {
268  { L"Full control", ALIAS_ALL_ACCESS, TRUE, TRUE },
269  { L"Read", ALIAS_READ, TRUE, FALSE },
270  { L"Write", ALIAS_WRITE, TRUE, FALSE },
271  { L"Execute", ALIAS_EXECUTE, TRUE, FALSE },
272  { L"Read information", ALIAS_READ_INFORMATION, FALSE, TRUE },
273  { L"Write account", ALIAS_WRITE_ACCOUNT, FALSE, TRUE },
274  { L"Add member", ALIAS_ADD_MEMBER, FALSE, TRUE },
275  { L"Remove member", ALIAS_REMOVE_MEMBER, FALSE, TRUE },
276  { L"List members", ALIAS_LIST_MEMBERS, FALSE, TRUE }
277 };
278 
279 ACCESS_ENTRIES(SamDomain)
280 {
281  { L"Full control", DOMAIN_ALL_ACCESS, TRUE, TRUE },
282  { L"Read", DOMAIN_READ, TRUE, FALSE },
283  { L"Write", DOMAIN_WRITE, TRUE, FALSE },
284  { L"Execute", DOMAIN_EXECUTE, TRUE, FALSE },
285  { L"Read password parameters", DOMAIN_READ_PASSWORD_PARAMETERS, FALSE, TRUE },
286  { L"Write password parameters", DOMAIN_WRITE_PASSWORD_PARAMS, FALSE, TRUE },
287  { L"Read other parameters", DOMAIN_READ_OTHER_PARAMETERS, FALSE, TRUE },
288  { L"Write other parameters", DOMAIN_WRITE_OTHER_PARAMETERS, FALSE, TRUE },
289  { L"Create user", DOMAIN_CREATE_USER, FALSE, TRUE },
290  { L"Create group", DOMAIN_CREATE_GROUP, FALSE, TRUE },
291  { L"Create alias", DOMAIN_CREATE_ALIAS, FALSE, TRUE },
292  { L"Get alias membership", DOMAIN_GET_ALIAS_MEMBERSHIP, FALSE, TRUE },
293  { L"List accounts", DOMAIN_LIST_ACCOUNTS, FALSE, TRUE },
294  { L"Lookup", DOMAIN_LOOKUP, FALSE, TRUE },
295  { L"Administer server", DOMAIN_ADMINISTER_SERVER, FALSE, TRUE }
296 };
297 
298 ACCESS_ENTRIES(SamGroup)
299 {
300  { L"Full control", GROUP_ALL_ACCESS, TRUE, TRUE },
301  { L"Read", GROUP_READ, TRUE, FALSE },
302  { L"Write", GROUP_WRITE, TRUE, FALSE },
303  { L"Execute", GROUP_EXECUTE, TRUE, FALSE },
304  { L"Read information", GROUP_READ_INFORMATION, FALSE, TRUE },
305  { L"Write account", GROUP_WRITE_ACCOUNT, FALSE, TRUE },
306  { L"Add member", GROUP_ADD_MEMBER, FALSE, TRUE },
307  { L"Remove member", GROUP_REMOVE_MEMBER, FALSE, TRUE },
308  { L"List members", GROUP_LIST_MEMBERS, FALSE, TRUE }
309 };
310 
311 ACCESS_ENTRIES(SamServer)
312 {
313  { L"Full control", SAM_SERVER_ALL_ACCESS, TRUE, TRUE },
314  { L"Read", SAM_SERVER_READ, TRUE, FALSE },
315  { L"Write", SAM_SERVER_WRITE, TRUE, FALSE },
316  { L"Execute", SAM_SERVER_EXECUTE, TRUE, FALSE },
317  { L"Connect", SAM_SERVER_CONNECT, FALSE, TRUE },
318  { L"Shutdown", SAM_SERVER_SHUTDOWN, FALSE, TRUE },
319  { L"Initialize", SAM_SERVER_INITIALIZE, FALSE, TRUE },
320  { L"Create domain", SAM_SERVER_CREATE_DOMAIN, FALSE, TRUE },
321  { L"Enumerate domains", SAM_SERVER_ENUMERATE_DOMAINS, FALSE, TRUE },
322  { L"Lookup domain", SAM_SERVER_LOOKUP_DOMAIN, FALSE, TRUE }
323 };
324 
326 {
327  { L"Full control", USER_ALL_ACCESS, TRUE, TRUE },
328  { L"Read", USER_READ, TRUE, FALSE },
329  { L"Write", USER_WRITE, TRUE, FALSE },
330  { L"Execute", USER_EXECUTE, TRUE, FALSE },
331  { L"Read general", USER_READ_GENERAL, FALSE, TRUE },
332  { L"Read preferences", USER_READ_PREFERENCES, FALSE, TRUE },
333  { L"Write preferences", USER_WRITE_PREFERENCES, FALSE, TRUE },
334  { L"Read logon", USER_READ_LOGON, FALSE, TRUE },
335  { L"Read account", USER_READ_ACCOUNT, FALSE, TRUE },
336  { L"Write account", USER_WRITE_ACCOUNT, FALSE, TRUE },
337  { L"Change password", USER_CHANGE_PASSWORD, FALSE, TRUE },
338  { L"Force password change", USER_FORCE_PASSWORD_CHANGE, FALSE, TRUE },
339  { L"List groups", USER_LIST_GROUPS, FALSE, TRUE },
340  { L"Read group information", USER_READ_GROUP_INFORMATION, FALSE, TRUE },
341  { L"Write group information", USER_WRITE_GROUP_INFORMATION, FALSE, TRUE }
342 };
343 
345 {
346  { L"Full control", SECTION_ALL_ACCESS, TRUE, TRUE },
347  { L"Query", SECTION_QUERY, TRUE, TRUE },
348  { L"Map for read", SECTION_MAP_READ, TRUE, TRUE, L"Map read" },
349  { L"Map for write", SECTION_MAP_WRITE, TRUE, TRUE, L"Map write" },
350  { L"Map for execute", SECTION_MAP_EXECUTE, TRUE, TRUE, L"Map execute" },
351  { L"Map for execute (explicit)", SECTION_MAP_EXECUTE_EXPLICIT, TRUE, TRUE, L"Map execute explicit" },
352  { L"Extend size", SECTION_EXTEND_SIZE, TRUE, TRUE }
353 };
354 
355 ACCESS_ENTRIES(Semaphore)
356 {
357  { L"Full control", SEMAPHORE_ALL_ACCESS, TRUE, TRUE },
358  { L"Query", SEMAPHORE_QUERY_STATE, TRUE, TRUE },
359  { L"Modify", SEMAPHORE_MODIFY_STATE, TRUE, TRUE }
360 };
361 
363 {
364  { L"Full control", SERVICE_ALL_ACCESS, TRUE, TRUE },
365  { L"Query status", SERVICE_QUERY_STATUS, TRUE, TRUE },
366  { L"Query configuration", SERVICE_QUERY_CONFIG, TRUE, TRUE },
367  { L"Modify configuration", SERVICE_CHANGE_CONFIG, TRUE, TRUE },
368  { L"Enumerate dependents", SERVICE_ENUMERATE_DEPENDENTS, TRUE, TRUE },
369  { L"Start", SERVICE_START, TRUE, TRUE },
370  { L"Stop", SERVICE_STOP, TRUE, TRUE },
371  { L"Pause / continue", SERVICE_PAUSE_CONTINUE, TRUE, TRUE, L"Pause/continue" },
372  { L"Interrogate", SERVICE_INTERROGATE, TRUE, TRUE },
373  { L"User-defined control", SERVICE_USER_DEFINED_CONTROL, TRUE, TRUE }
374 };
375 
377 {
378  { L"Full control", SESSION_ALL_ACCESS, TRUE, TRUE },
379  { L"Query", SESSION_QUERY_ACCESS, TRUE, TRUE },
380  { L"Modify", SESSION_MODIFY_ACCESS, TRUE, TRUE }
381 };
382 
383 ACCESS_ENTRIES(SymbolicLink)
384 {
385  { L"Full control", SYMBOLIC_LINK_ALL_ACCESS, TRUE, TRUE },
386  { L"Query", SYMBOLIC_LINK_QUERY, TRUE, TRUE }
387 };
388 
390 {
391  { L"Full control", STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0x3ff, TRUE, TRUE },
392  { L"Query information", THREAD_QUERY_INFORMATION, TRUE, TRUE },
393  { L"Set information", THREAD_SET_INFORMATION, TRUE, TRUE },
394  { L"Get context", THREAD_GET_CONTEXT, TRUE, TRUE },
395  { L"Set context", THREAD_SET_CONTEXT, TRUE, TRUE },
396  { L"Set token", THREAD_SET_THREAD_TOKEN, TRUE, TRUE },
397  { L"Alert", THREAD_ALERT, TRUE, TRUE },
398  { L"Impersonate", THREAD_IMPERSONATE, TRUE, TRUE },
399  { L"Direct impersonate", THREAD_DIRECT_IMPERSONATION, TRUE, TRUE },
400  { L"Suspend / resume", THREAD_SUSPEND_RESUME, TRUE, TRUE, L"Suspend/resume" },
401  { L"Terminate", THREAD_TERMINATE, TRUE, TRUE },
402 };
403 
404 ACCESS_ENTRIES(Thread60)
405 {
406  { L"Full control", STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0xffff, TRUE, TRUE }, // THREAD_ALL_ACCESS
407  { L"Query limited information", THREAD_QUERY_LIMITED_INFORMATION, TRUE, TRUE },
408  { L"Query information", THREAD_QUERY_INFORMATION | THREAD_QUERY_LIMITED_INFORMATION, TRUE, TRUE },
409  { L"Set limited information", THREAD_SET_LIMITED_INFORMATION, TRUE, TRUE },
410  { L"Set information", THREAD_SET_INFORMATION | THREAD_SET_LIMITED_INFORMATION, TRUE, TRUE },
411  { L"Get context", THREAD_GET_CONTEXT, TRUE, TRUE },
412  { L"Set context", THREAD_SET_CONTEXT, TRUE, TRUE },
413  { L"Set token", THREAD_SET_THREAD_TOKEN, TRUE, TRUE },
414  { L"Alert", THREAD_ALERT, TRUE, TRUE },
415  { L"Impersonate", THREAD_IMPERSONATE, TRUE, TRUE },
416  { L"Direct impersonate", THREAD_DIRECT_IMPERSONATION, TRUE, TRUE },
417  { L"Suspend / resume", THREAD_SUSPEND_RESUME, TRUE, TRUE, L"Suspend/resume" },
418  { L"Terminate", THREAD_TERMINATE, TRUE, TRUE },
419 };
420 
422 {
423  { L"Full control", TIMER_ALL_ACCESS, TRUE, TRUE },
424  { L"Query", TIMER_QUERY_STATE, TRUE, TRUE },
425  { L"Modify", TIMER_MODIFY_STATE, TRUE, TRUE }
426 };
427 
429 {
430  { L"Full control", ENLISTMENT_ALL_ACCESS, TRUE, TRUE },
431  { L"Read", ENLISTMENT_GENERIC_READ, TRUE, FALSE },
432  { L"Write", ENLISTMENT_GENERIC_WRITE, TRUE, FALSE },
433  { L"Execute", ENLISTMENT_GENERIC_EXECUTE, TRUE, FALSE },
434  { L"Query information", ENLISTMENT_QUERY_INFORMATION, FALSE, TRUE },
435  { L"Set information", ENLISTMENT_SET_INFORMATION, FALSE, TRUE },
436  { L"Recover", ENLISTMENT_RECOVER, FALSE, TRUE },
437  { L"Subordinate rights", ENLISTMENT_SUBORDINATE_RIGHTS, FALSE, TRUE },
438  { L"Superior rights", ENLISTMENT_SUPERIOR_RIGHTS, FALSE, TRUE }
439 };
440 
442 {
443  { L"Full control", RESOURCEMANAGER_ALL_ACCESS, TRUE, TRUE },
444  { L"Read", RESOURCEMANAGER_GENERIC_READ, TRUE, FALSE },
445  { L"Write", RESOURCEMANAGER_GENERIC_WRITE, TRUE, FALSE },
446  { L"Execute", RESOURCEMANAGER_GENERIC_EXECUTE, TRUE, FALSE },
447  { L"Query information", RESOURCEMANAGER_QUERY_INFORMATION, FALSE, TRUE },
448  { L"Set information", RESOURCEMANAGER_SET_INFORMATION, FALSE, TRUE },
449  { L"Get notifications", RESOURCEMANAGER_GET_NOTIFICATION, FALSE, TRUE },
450  { L"Enlist", RESOURCEMANAGER_ENLIST, FALSE, TRUE },
451  { L"Recover", RESOURCEMANAGER_RECOVER, FALSE, TRUE },
452  { L"Register protocols", RESOURCEMANAGER_REGISTER_PROTOCOL, FALSE, TRUE },
453  { L"Complete propagation", RESOURCEMANAGER_COMPLETE_PROPAGATION, FALSE, TRUE }
454 };
455 
457 {
458  { L"Full control", TRANSACTIONMANAGER_ALL_ACCESS, TRUE, TRUE },
459  { L"Read", TRANSACTIONMANAGER_GENERIC_READ, TRUE, FALSE },
460  { L"Write", TRANSACTIONMANAGER_GENERIC_WRITE, TRUE, FALSE },
461  { L"Execute", TRANSACTIONMANAGER_GENERIC_EXECUTE, TRUE, FALSE },
462  { L"Query information", TRANSACTIONMANAGER_QUERY_INFORMATION, FALSE, TRUE },
463  { L"Set information", TRANSACTIONMANAGER_SET_INFORMATION, FALSE, TRUE },
464  { L"Recover", TRANSACTIONMANAGER_RECOVER, FALSE, TRUE },
465  { L"Rename", TRANSACTIONMANAGER_RENAME, FALSE, TRUE },
466  { L"Create resource manager", TRANSACTIONMANAGER_CREATE_RM, FALSE, TRUE },
467  { L"Bind transactions", TRANSACTIONMANAGER_BIND_TRANSACTION, FALSE, TRUE }
468 };
469 
471 {
472  { L"Full control", TRANSACTION_ALL_ACCESS, TRUE, TRUE },
473  { L"Read", TRANSACTION_GENERIC_READ, TRUE, FALSE },
474  { L"Write", TRANSACTION_GENERIC_WRITE, TRUE, FALSE },
475  { L"Execute", TRANSACTION_GENERIC_EXECUTE, TRUE, FALSE },
476  { L"Query information", TRANSACTION_QUERY_INFORMATION, FALSE, TRUE },
477  { L"Set information", TRANSACTION_SET_INFORMATION, FALSE, TRUE },
478  { L"Enlist", TRANSACTION_ENLIST, FALSE, TRUE },
479  { L"Commit", TRANSACTION_COMMIT, FALSE, TRUE },
480  { L"Rollback", TRANSACTION_ROLLBACK, FALSE, TRUE },
481  { L"Propagate", TRANSACTION_PROPAGATE, FALSE, TRUE }
482 };
483 
485 {
486  { L"Full control", TOKEN_ALL_ACCESS, TRUE, TRUE },
487  { L"Read", TOKEN_READ, TRUE, FALSE },
488  { L"Write", TOKEN_WRITE, TRUE, FALSE },
489  { L"Execute", TOKEN_EXECUTE, TRUE, FALSE },
490  { L"Adjust privileges", TOKEN_ADJUST_PRIVILEGES, FALSE, TRUE },
491  { L"Adjust groups", TOKEN_ADJUST_GROUPS, FALSE, TRUE },
492  { L"Adjust defaults", TOKEN_ADJUST_DEFAULT, FALSE, TRUE },
493  { L"Adjust session ID", TOKEN_ADJUST_SESSIONID, FALSE, TRUE },
494  { L"Assign as primary token", TOKEN_ASSIGN_PRIMARY, FALSE, TRUE, L"Assign primary" },
495  { L"Duplicate", TOKEN_DUPLICATE, FALSE, TRUE },
496  { L"Impersonate", TOKEN_IMPERSONATE, FALSE, TRUE },
497  { L"Query", TOKEN_QUERY, FALSE, TRUE },
498  { L"Query source", TOKEN_QUERY_SOURCE, FALSE, TRUE }
499 };
500 
501 ACCESS_ENTRIES(TpWorkerFactory)
502 {
503  { L"Full control", WORKER_FACTORY_ALL_ACCESS, TRUE, TRUE },
504  { L"Release worker", WORKER_FACTORY_RELEASE_WORKER, FALSE, TRUE },
505  { L"Ready worker", WORKER_FACTORY_READY_WORKER, FALSE, TRUE },
506  { L"Wait", WORKER_FACTORY_WAIT, FALSE, TRUE },
507  { L"Set information", WORKER_FACTORY_SET_INFORMATION, FALSE, TRUE },
508  { L"Query information", WORKER_FACTORY_QUERY_INFORMATION, FALSE, TRUE },
509  { L"Shutdown", WORKER_FACTORY_SHUTDOWN, FALSE, TRUE }
510 };
511 
512 ACCESS_ENTRIES(Type)
513 {
514  { L"Full control", OBJECT_TYPE_ALL_ACCESS, TRUE, TRUE },
515  { L"Create", OBJECT_TYPE_CREATE, TRUE, TRUE }
516 };
517 
518 ACCESS_ENTRIES(WindowStation)
519 {
520  { L"Full control", WINSTA_ALL_ACCESS | STANDARD_RIGHTS_REQUIRED, TRUE, TRUE },
521  { L"Read", WINSTA_GENERIC_READ, TRUE, FALSE },
522  { L"Write", WINSTA_GENERIC_WRITE, TRUE, FALSE },
523  { L"Execute", WINSTA_GENERIC_EXECUTE, TRUE, FALSE },
524  { L"Enumerate", WINSTA_ENUMERATE, FALSE, TRUE },
525  { L"Enumerate desktops", WINSTA_ENUMDESKTOPS, FALSE, TRUE },
526  { L"Read attributes", WINSTA_READATTRIBUTES, FALSE, TRUE },
527  { L"Read screen", WINSTA_READSCREEN, FALSE, TRUE },
528  { L"Access clipboard", WINSTA_ACCESSCLIPBOARD, FALSE, TRUE },
529  { L"Access global atoms", WINSTA_ACCESSGLOBALATOMS, FALSE, TRUE },
530  { L"Create desktop", WINSTA_CREATEDESKTOP, FALSE, TRUE },
531  { L"Write attributes", WINSTA_WRITEATTRIBUTES, FALSE, TRUE },
532  { L"Exit windows", WINSTA_EXITWINDOWS, FALSE, TRUE }
533 };
534 
536 {
537  { L"Full control", WMIGUID_ALL_ACCESS, TRUE, TRUE },
538  { L"Read", WMIGUID_GENERIC_READ, TRUE, FALSE },
539  { L"Write", WMIGUID_GENERIC_WRITE, TRUE, FALSE },
540  { L"Execute", WMIGUID_GENERIC_EXECUTE, TRUE, FALSE },
541  { L"Query information", WMIGUID_QUERY, FALSE, TRUE },
542  { L"Set information", WMIGUID_SET, FALSE, TRUE },
543  { L"Get notifications", WMIGUID_NOTIFICATION, FALSE, TRUE },
544  { L"Read description", WMIGUID_READ_DESCRIPTION, FALSE, TRUE },
545  { L"Execute", WMIGUID_EXECUTE, FALSE, TRUE },
546  { L"Create real-time logs", TRACELOG_CREATE_REALTIME, FALSE, TRUE, L"Create real-time" },
547  { L"Create on disk logs", TRACELOG_CREATE_ONDISK, FALSE, TRUE, L"Create on disk" },
548  { L"Enable provider GUIDs", TRACELOG_GUID_ENABLE, FALSE, TRUE, L"Enable GUIDs" },
549  { L"Access kernel logger", TRACELOG_ACCESS_KERNEL_LOGGER, FALSE, TRUE },
550  { L"Log events", TRACELOG_LOG_EVENT, FALSE, TRUE },
551  { L"Access real-time events", TRACELOG_ACCESS_REALTIME, FALSE, TRUE, L"Access real-time" },
552  { L"Register provider GUIDs", TRACELOG_REGISTER_GUIDS, FALSE, TRUE, L"Register GUIDs" }
553 };
554 
555 static PH_SPECIFIC_TYPE PhSpecificTypes[] =
556 {
557  ACCESS_ENTRY(AlpcPort, TRUE),
558  ACCESS_ENTRY(DebugObject, TRUE),
559  ACCESS_ENTRY(Desktop, FALSE),
560  ACCESS_ENTRY(Directory, FALSE),
561  ACCESS_ENTRY(Event, TRUE),
562  ACCESS_ENTRY(EventPair, TRUE),
563  ACCESS_ENTRY(File, TRUE),
564  ACCESS_ENTRY(FilterConnectionPort, FALSE),
565  ACCESS_ENTRY(IoCompletion, TRUE),
566  ACCESS_ENTRY(Job, TRUE),
567  ACCESS_ENTRY(Key, FALSE),
568  ACCESS_ENTRY(KeyedEvent, FALSE),
569  ACCESS_ENTRY(LsaAccount, FALSE),
570  ACCESS_ENTRY(LsaPolicy, FALSE),
571  ACCESS_ENTRY(LsaSecret, FALSE),
572  ACCESS_ENTRY(LsaTrusted, FALSE),
573  ACCESS_ENTRY(Mutant, TRUE),
574  ACCESS_ENTRY(Process, TRUE),
575  ACCESS_ENTRY(Process60, TRUE),
576  ACCESS_ENTRY(Profile, FALSE),
577  ACCESS_ENTRY(SamAlias, FALSE),
578  ACCESS_ENTRY(SamDomain, FALSE),
579  ACCESS_ENTRY(SamGroup, FALSE),
580  ACCESS_ENTRY(SamServer, FALSE),
581  ACCESS_ENTRY(SamUser, FALSE),
582  ACCESS_ENTRY(Section, FALSE),
583  ACCESS_ENTRY(Semaphore, TRUE),
584  ACCESS_ENTRY(Service, FALSE),
585  ACCESS_ENTRY(Session, FALSE),
586  ACCESS_ENTRY(SymbolicLink, FALSE),
587  ACCESS_ENTRY(Thread, TRUE),
588  ACCESS_ENTRY(Thread60, TRUE),
589  ACCESS_ENTRY(Timer, TRUE),
590  ACCESS_ENTRY(TmEn, FALSE),
591  ACCESS_ENTRY(TmRm, FALSE),
592  ACCESS_ENTRY(TmTm, FALSE),
593  ACCESS_ENTRY(TmTx, FALSE),
594  ACCESS_ENTRY(Token, FALSE),
595  ACCESS_ENTRY(TpWorkerFactory, FALSE),
596  ACCESS_ENTRY(Type, FALSE),
597  ACCESS_ENTRY(WindowStation, FALSE),
598  ACCESS_ENTRY(WmiGuid, TRUE)
599 };
600 
613  _In_ PWSTR Type,
614  _Out_ PPH_ACCESS_ENTRY *AccessEntries,
615  _Out_ PULONG NumberOfAccessEntries
616  )
617 {
618  ULONG i;
619  PPH_SPECIFIC_TYPE specificType = NULL;
620  PPH_ACCESS_ENTRY accessEntries;
621 
622  if (PhEqualStringZ(Type, L"ALPC Port", TRUE))
623  {
624  Type = L"AlpcPort";
625  }
626  else if (PhEqualStringZ(Type, L"Port", TRUE))
627  {
628  Type = L"AlpcPort";
629  }
630  else if (PhEqualStringZ(Type, L"WaitablePort", TRUE))
631  {
632  Type = L"AlpcPort";
633  }
634  else if (PhEqualStringZ(Type, L"Process", TRUE))
635  {
637  Type = L"Process60";
638  }
639  else if (PhEqualStringZ(Type, L"Thread", TRUE))
640  {
642  Type = L"Thread60";
643  }
644 
645  // Find the specific type.
646  for (i = 0; i < sizeof(PhSpecificTypes) / sizeof(PH_SPECIFIC_TYPE); i++)
647  {
648  if (PhEqualStringZ(PhSpecificTypes[i].Type, Type, TRUE))
649  {
650  specificType = &PhSpecificTypes[i];
651  break;
652  }
653  }
654 
655  if (specificType)
656  {
657  ULONG sizeOfEntries;
658 
659  // Copy the specific access entries and append the standard access entries.
660 
661  if (specificType->HasSynchronize)
662  sizeOfEntries = specificType->SizeOfAccessEntries + sizeof(PhStandardAccessEntries);
663  else
664  sizeOfEntries = specificType->SizeOfAccessEntries + sizeof(PhStandardAccessEntries) - sizeof(PH_ACCESS_ENTRY);
665 
666  accessEntries = PhAllocate(sizeOfEntries);
667  memcpy(accessEntries, specificType->AccessEntries, specificType->SizeOfAccessEntries);
668 
669  if (specificType->HasSynchronize)
670  {
671  memcpy(
672  PTR_ADD_OFFSET(accessEntries, specificType->SizeOfAccessEntries),
673  PhStandardAccessEntries,
674  sizeof(PhStandardAccessEntries)
675  );
676  }
677  else
678  {
679  memcpy(
680  PTR_ADD_OFFSET(accessEntries, specificType->SizeOfAccessEntries),
681  &PhStandardAccessEntries[1],
682  sizeof(PhStandardAccessEntries) - sizeof(PH_ACCESS_ENTRY)
683  );
684  }
685 
686  *AccessEntries = accessEntries;
687  *NumberOfAccessEntries = sizeOfEntries / sizeof(PH_ACCESS_ENTRY);
688  }
689  else
690  {
691  accessEntries = PhAllocate(sizeof(PhStandardAccessEntries));
692  memcpy(accessEntries, PhStandardAccessEntries, sizeof(PhStandardAccessEntries));
693 
694  *AccessEntries = accessEntries;
695  *NumberOfAccessEntries = sizeof(PhStandardAccessEntries) / sizeof(PH_ACCESS_ENTRY);
696  }
697 
698  return TRUE;
699 }
700 
701 static int __cdecl PhpAccessEntryCompare(
702  _In_ const void *elem1,
703  _In_ const void *elem2
704  )
705 {
706  PPH_ACCESS_ENTRY entry1 = (PPH_ACCESS_ENTRY)elem1;
707  PPH_ACCESS_ENTRY entry2 = (PPH_ACCESS_ENTRY)elem2;
708 
709  return intcmp(PhCountBits(entry2->Access), PhCountBits(entry1->Access));
710 }
711 
724  _In_ ACCESS_MASK Access,
725  _In_ PPH_ACCESS_ENTRY AccessEntries,
726  _In_ ULONG NumberOfAccessEntries
727  )
728 {
729  PH_STRING_BUILDER stringBuilder;
730  PPH_ACCESS_ENTRY accessEntries;
731  PBOOLEAN matched;
732  ULONG i;
733  ULONG j;
734 
735  PhInitializeStringBuilder(&stringBuilder, 32);
736 
737  // Sort the access entries according to how many access rights they
738  // include.
739  accessEntries = PhAllocateCopy(AccessEntries, NumberOfAccessEntries * sizeof(PH_ACCESS_ENTRY));
740  qsort(accessEntries, NumberOfAccessEntries, sizeof(PH_ACCESS_ENTRY), PhpAccessEntryCompare);
741 
742  matched = PhAllocate(NumberOfAccessEntries * sizeof(BOOLEAN));
743  memset(matched, 0, NumberOfAccessEntries * sizeof(BOOLEAN));
744 
745  for (i = 0; i < NumberOfAccessEntries; i++)
746  {
747  // We make sure we haven't matched this access entry yet.
748  // This ensures that we won't get duplicates, e.g.
749  // FILE_GENERIC_READ includes FILE_READ_DATA, and we
750  // don't want to display both to the user.
751  if (
752  !matched[i] &&
753  ((Access & accessEntries[i].Access) == accessEntries[i].Access)
754  )
755  {
756  if (accessEntries[i].ShortName)
757  PhAppendStringBuilder2(&stringBuilder, accessEntries[i].ShortName);
758  else
759  PhAppendStringBuilder2(&stringBuilder, accessEntries[i].Name);
760 
761  PhAppendStringBuilder2(&stringBuilder, L", ");
762 
763  // Disable equal or more specific entries.
764  for (j = i; j < NumberOfAccessEntries; j++)
765  {
766  if ((accessEntries[i].Access | accessEntries[j].Access) == accessEntries[i].Access)
767  matched[j] = TRUE;
768  }
769  }
770  }
771 
772  // Remove the trailing ", ".
773  if (PhEndsWithString2(stringBuilder.String, L", ", FALSE))
774  PhRemoveEndStringBuilder(&stringBuilder, 2);
775 
776  PhFree(matched);
777  PhFree(accessEntries);
778 
779  return PhFinalStringBuilderString(&stringBuilder);
780 }