Process Hacker
hndlprp.c
Go to the documentation of this file.
1 /*
2  * Process Hacker -
3  * handle properties
4  *
5  * Copyright (C) 2010-2013 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 <phapp.h>
24 #include <kphuser.h>
25 #include <secedit.h>
26 #include <phplug.h>
27 
28 typedef struct _HANDLE_PROPERTIES_CONTEXT
29 {
30  HANDLE ProcessId;
31  PPH_HANDLE_ITEM HandleItem;
33 
34 INT_PTR CALLBACK PhpHandleGeneralDlgProc(
35  _In_ HWND hwndDlg,
36  _In_ UINT uMsg,
37  _In_ WPARAM wParam,
38  _In_ LPARAM lParam
39  );
40 
41 static NTSTATUS PhpDuplicateHandleFromProcess(
42  _Out_ PHANDLE Handle,
43  _In_ ACCESS_MASK DesiredAccess,
44  _In_opt_ PVOID Context
45  )
46 {
47  NTSTATUS status;
48  PHANDLE_PROPERTIES_CONTEXT context = Context;
49  HANDLE processHandle;
50 
51  if (!NT_SUCCESS(status = PhOpenProcess(
52  &processHandle,
53  PROCESS_DUP_HANDLE,
54  context->ProcessId
55  )))
56  return status;
57 
58  if (KphIsConnected() && PhEqualString2(context->HandleItem->TypeName, L"File", TRUE))
59  {
61  processHandle,
62  context->HandleItem->Handle,
63  NtCurrentProcess(),
64  Handle,
65  DesiredAccess,
66  0,
67  0
68  );
69  }
70  else
71  {
72  status = PhDuplicateObject(
73  processHandle,
74  context->HandleItem->Handle,
75  NtCurrentProcess(),
76  Handle,
77  DesiredAccess,
78  0,
79  0
80  );
81  }
82 
83  NtClose(processHandle);
84 
85  return status;
86 }
87 
89  _In_ HWND ParentWindowHandle,
90  _In_ HANDLE ProcessId,
91  _In_ PPH_HANDLE_ITEM HandleItem
92  )
93 {
94  PROPSHEETHEADER propSheetHeader = { sizeof(propSheetHeader) };
95  PROPSHEETPAGE propSheetPage;
96  HPROPSHEETPAGE pages[16];
98  PH_STD_OBJECT_SECURITY stdObjectSecurity;
99  PPH_ACCESS_ENTRY accessEntries;
100  ULONG numberOfAccessEntries;
101 
102  context.ProcessId = ProcessId;
103  context.HandleItem = HandleItem;
104 
105  propSheetHeader.dwFlags =
106  PSH_NOAPPLYNOW |
107  PSH_NOCONTEXTHELP |
108  PSH_PROPTITLE;
109  propSheetHeader.hwndParent = ParentWindowHandle;
110  propSheetHeader.pszCaption = L"Handle";
111  propSheetHeader.nPages = 0;
112  propSheetHeader.nStartPage = 0;
113  propSheetHeader.phpage = pages;
114 
115  // General page
116  memset(&propSheetPage, 0, sizeof(PROPSHEETPAGE));
117  propSheetPage.dwSize = sizeof(PROPSHEETPAGE);
118  propSheetPage.pszTemplate = MAKEINTRESOURCE(IDD_HNDLGENERAL);
119  propSheetPage.pfnDlgProc = PhpHandleGeneralDlgProc;
120  propSheetPage.lParam = (LPARAM)&context;
121  pages[propSheetHeader.nPages++] = CreatePropertySheetPage(&propSheetPage);
122 
123  // Object-specific page
124  if (!HandleItem->TypeName)
125  {
126  // Dummy
127  }
128  else if (PhEqualString2(HandleItem->TypeName, L"Event", TRUE))
129  {
130  pages[propSheetHeader.nPages++] = PhCreateEventPage(
131  PhpDuplicateHandleFromProcess,
132  &context
133  );
134  }
135  else if (PhEqualString2(HandleItem->TypeName, L"EventPair", TRUE))
136  {
137  pages[propSheetHeader.nPages++] = PhCreateEventPairPage(
138  PhpDuplicateHandleFromProcess,
139  &context
140  );
141  }
142  else if (PhEqualString2(HandleItem->TypeName, L"Job", TRUE))
143  {
144  pages[propSheetHeader.nPages++] = PhCreateJobPage(
145  PhpDuplicateHandleFromProcess,
146  &context,
147  NULL
148  );
149  }
150  else if (PhEqualString2(HandleItem->TypeName, L"Mutant", TRUE))
151  {
152  pages[propSheetHeader.nPages++] = PhCreateMutantPage(
153  PhpDuplicateHandleFromProcess,
154  &context
155  );
156  }
157  else if (PhEqualString2(HandleItem->TypeName, L"Section", TRUE))
158  {
159  pages[propSheetHeader.nPages++] = PhCreateSectionPage(
160  PhpDuplicateHandleFromProcess,
161  &context
162  );
163  }
164  else if (PhEqualString2(HandleItem->TypeName, L"Semaphore", TRUE))
165  {
166  pages[propSheetHeader.nPages++] = PhCreateSemaphorePage(
167  PhpDuplicateHandleFromProcess,
168  &context
169  );
170  }
171  else if (PhEqualString2(HandleItem->TypeName, L"Timer", TRUE))
172  {
173  pages[propSheetHeader.nPages++] = PhCreateTimerPage(
174  PhpDuplicateHandleFromProcess,
175  &context
176  );
177  }
178  else if (PhEqualString2(HandleItem->TypeName, L"Token", TRUE))
179  {
180  pages[propSheetHeader.nPages++] = PhCreateTokenPage(
181  PhpDuplicateHandleFromProcess,
182  &context,
183  NULL
184  );
185  }
186 
187  // Security page
188  stdObjectSecurity.OpenObject = PhpDuplicateHandleFromProcess;
189  stdObjectSecurity.ObjectType = HandleItem->TypeName->Buffer;
190  stdObjectSecurity.Context = &context;
191 
192  if (PhGetAccessEntries(HandleItem->TypeName->Buffer, &accessEntries, &numberOfAccessEntries))
193  {
194  pages[propSheetHeader.nPages++] = PhCreateSecurityPage(
195  PhGetStringOrEmpty(HandleItem->BestObjectName),
198  &stdObjectSecurity,
199  accessEntries,
200  numberOfAccessEntries
201  );
202  PhFree(accessEntries);
203  }
204 
205  if (PhPluginsEnabled)
206  {
207  PH_PLUGIN_OBJECT_PROPERTIES objectProperties;
208  PH_PLUGIN_HANDLE_PROPERTIES_CONTEXT propertiesContext;
209 
210  propertiesContext.ProcessId = ProcessId;
211  propertiesContext.HandleItem = HandleItem;
212 
213  objectProperties.Parameter = &propertiesContext;
214  objectProperties.NumberOfPages = propSheetHeader.nPages;
215  objectProperties.MaximumNumberOfPages = sizeof(pages) / sizeof(HPROPSHEETPAGE);
216  objectProperties.Pages = pages;
217 
219 
220  propSheetHeader.nPages = objectProperties.NumberOfPages;
221  }
222 
223  PropertySheet(&propSheetHeader);
224 }
225 
226 INT_PTR CALLBACK PhpHandleGeneralDlgProc(
227  _In_ HWND hwndDlg,
228  _In_ UINT uMsg,
229  _In_ WPARAM wParam,
230  _In_ LPARAM lParam
231  )
232 {
233  switch (uMsg)
234  {
235  case WM_INITDIALOG:
236  {
237  LPPROPSHEETPAGE propSheetPage = (LPPROPSHEETPAGE)lParam;
238  PHANDLE_PROPERTIES_CONTEXT context = (PHANDLE_PROPERTIES_CONTEXT)propSheetPage->lParam;
239  PPH_ACCESS_ENTRY accessEntries;
240  ULONG numberOfAccessEntries;
241  HANDLE processHandle;
242  OBJECT_BASIC_INFORMATION basicInfo;
243  BOOLEAN haveBasicInfo = FALSE;
244 
245  SetProp(hwndDlg, PhMakeContextAtom(), (HANDLE)context);
246 
247  SetDlgItemText(hwndDlg, IDC_NAME, PhGetString(context->HandleItem->BestObjectName));
248  SetDlgItemText(hwndDlg, IDC_TYPE, context->HandleItem->TypeName->Buffer);
249  SetDlgItemText(hwndDlg, IDC_ADDRESS, context->HandleItem->ObjectString);
250 
251  if (PhGetAccessEntries(
252  context->HandleItem->TypeName->Buffer,
253  &accessEntries,
254  &numberOfAccessEntries
255  ))
256  {
257  PPH_STRING accessString;
258  PPH_STRING grantedAccessString;
259 
260  accessString = PhGetAccessString(
261  context->HandleItem->GrantedAccess,
262  accessEntries,
263  numberOfAccessEntries
264  );
265 
266  if (accessString->Length != 0)
267  {
268  grantedAccessString = PhFormatString(
269  L"%s (%s)",
270  context->HandleItem->GrantedAccessString,
271  accessString->Buffer
272  );
273  SetDlgItemText(hwndDlg, IDC_GRANTED_ACCESS, grantedAccessString->Buffer);
274  PhDereferenceObject(grantedAccessString);
275  }
276  else
277  {
278  SetDlgItemText(hwndDlg, IDC_GRANTED_ACCESS, context->HandleItem->GrantedAccessString);
279  }
280 
281  PhDereferenceObject(accessString);
282 
283  PhFree(accessEntries);
284  }
285  else
286  {
287  SetDlgItemText(hwndDlg, IDC_GRANTED_ACCESS, context->HandleItem->GrantedAccessString);
288  }
289 
291  &processHandle,
292  PROCESS_DUP_HANDLE,
293  context->ProcessId
294  )))
295  {
297  processHandle,
298  context->HandleItem->Handle,
299  -1,
300  &basicInfo,
301  NULL,
302  NULL,
303  NULL
304  )))
305  {
306  SetDlgItemInt(hwndDlg, IDC_REFERENCES, basicInfo.PointerCount, FALSE);
307  SetDlgItemInt(hwndDlg, IDC_HANDLES, basicInfo.HandleCount, FALSE);
308  SetDlgItemInt(hwndDlg, IDC_PAGED, basicInfo.PagedPoolCharge, FALSE);
309  SetDlgItemInt(hwndDlg, IDC_NONPAGED, basicInfo.NonPagedPoolCharge, FALSE);
310 
311  haveBasicInfo = TRUE;
312  }
313 
314  NtClose(processHandle);
315  }
316 
317  if (!haveBasicInfo)
318  {
319  SetDlgItemText(hwndDlg, IDC_REFERENCES, L"Unknown");
320  SetDlgItemText(hwndDlg, IDC_HANDLES, L"Unknown");
321  SetDlgItemText(hwndDlg, IDC_PAGED, L"Unknown");
322  SetDlgItemText(hwndDlg, IDC_NONPAGED, L"Unknown");
323  }
324  }
325  break;
326  case WM_DESTROY:
327  {
328  RemoveProp(hwndDlg, PhMakeContextAtom());
329  }
330  break;
331  case WM_NOTIFY:
332  {
333  LPNMHDR header = (LPNMHDR)lParam;
334 
335  switch (header->code)
336  {
337  case PSN_QUERYINITIALFOCUS:
338  {
339  SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (LONG_PTR)GetDlgItem(hwndDlg, IDC_BASICINFORMATION));
340  }
341  return TRUE;
342  }
343  }
344  break;
345  }
346 
347  return FALSE;
348 }