Process Hacker
objprp.c
Go to the documentation of this file.
1 /*
2  * Process Hacker Extended Tools -
3  * handle properties extensions
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 "exttools.h"
24 #include "resource.h"
25 #include <symprv.h>
26 
27 typedef struct _COMMON_PAGE_CONTEXT
28 {
29  PPH_HANDLE_ITEM HandleItem;
30  HANDLE ProcessId;
32 
33 HPROPSHEETPAGE EtpCommonCreatePage(
35  _In_ PWSTR Template,
36  _In_ DLGPROC DlgProc
37  );
38 
39 INT CALLBACK EtpCommonPropPageProc(
40  _In_ HWND hwnd,
41  _In_ UINT uMsg,
42  _In_ LPPROPSHEETPAGE ppsp
43  );
44 
45 INT_PTR CALLBACK EtpAlpcPortPageDlgProc(
46  _In_ HWND hwndDlg,
47  _In_ UINT uMsg,
48  _In_ WPARAM wParam,
49  _In_ LPARAM lParam
50  );
51 
52 INT_PTR CALLBACK EtpTpWorkerFactoryPageDlgProc(
53  _In_ HWND hwndDlg,
54  _In_ UINT uMsg,
55  _In_ WPARAM wParam,
56  _In_ LPARAM lParam
57  );
58 
60  _In_ PVOID Parameter
61  )
62 {
63  PPH_PLUGIN_OBJECT_PROPERTIES objectProperties = Parameter;
64  PPH_PLUGIN_HANDLE_PROPERTIES_CONTEXT context = objectProperties->Parameter;
65 
66  if (objectProperties->NumberOfPages < objectProperties->MaximumNumberOfPages)
67  {
68  HPROPSHEETPAGE page = NULL;
69 
70  if (PhEqualString2(context->HandleItem->TypeName, L"ALPC Port", TRUE))
71  {
72  page = EtpCommonCreatePage(
73  context,
74  MAKEINTRESOURCE(IDD_OBJALPCPORT),
76  );
77  }
78  else if (PhEqualString2(context->HandleItem->TypeName, L"TpWorkerFactory", TRUE))
79  {
80  page = EtpCommonCreatePage(
81  context,
82  MAKEINTRESOURCE(IDD_OBJTPWORKERFACTORY),
84  );
85  }
86 
87  // Insert our page into the second slot.
88 
89  if (page)
90  {
91  if (objectProperties->NumberOfPages > 1)
92  {
93  memmove(&objectProperties->Pages[2], &objectProperties->Pages[1],
94  (objectProperties->NumberOfPages - 1) * sizeof(HPROPSHEETPAGE));
95  }
96 
97  objectProperties->Pages[1] = page;
98  objectProperties->NumberOfPages++;
99  }
100  }
101 }
102 
103 static HPROPSHEETPAGE EtpCommonCreatePage(
105  _In_ PWSTR Template,
106  _In_ DLGPROC DlgProc
107  )
108 {
109  HPROPSHEETPAGE propSheetPageHandle;
110  PROPSHEETPAGE propSheetPage;
111  PCOMMON_PAGE_CONTEXT pageContext;
112 
113  pageContext = PhCreateAlloc(sizeof(COMMON_PAGE_CONTEXT));
114  memset(pageContext, 0, sizeof(COMMON_PAGE_CONTEXT));
115  pageContext->HandleItem = Context->HandleItem;
116  pageContext->ProcessId = Context->ProcessId;
117 
118  memset(&propSheetPage, 0, sizeof(PROPSHEETPAGE));
119  propSheetPage.dwSize = sizeof(PROPSHEETPAGE);
120  propSheetPage.dwFlags = PSP_USECALLBACK;
121  propSheetPage.hInstance = PluginInstance->DllBase;
122  propSheetPage.pszTemplate = Template;
123  propSheetPage.pfnDlgProc = DlgProc;
124  propSheetPage.lParam = (LPARAM)pageContext;
125  propSheetPage.pfnCallback = EtpCommonPropPageProc;
126 
127  propSheetPageHandle = CreatePropertySheetPage(&propSheetPage);
128  PhDereferenceObject(pageContext); // already got a ref from above call
129 
130  return propSheetPageHandle;
131 }
132 
134  _In_ HWND hwnd,
135  _In_ UINT uMsg,
136  _In_ LPPROPSHEETPAGE ppsp
137  )
138 {
139  PCOMMON_PAGE_CONTEXT pageContext;
140 
141  pageContext = (PCOMMON_PAGE_CONTEXT)ppsp->lParam;
142 
143  if (uMsg == PSPCB_ADDREF)
144  PhReferenceObject(pageContext);
145  else if (uMsg == PSPCB_RELEASE)
146  PhDereferenceObject(pageContext);
147 
148  return 1;
149 }
150 
151 static NTSTATUS EtpDuplicateHandleFromProcess(
152  _Out_ PHANDLE Handle,
153  _In_ ACCESS_MASK DesiredAccess,
154  _In_ PCOMMON_PAGE_CONTEXT Context
155  )
156 {
157  NTSTATUS status;
158  HANDLE processHandle;
159 
160  if (!NT_SUCCESS(status = PhOpenProcess(
161  &processHandle,
162  PROCESS_DUP_HANDLE,
163  Context->ProcessId
164  )))
165  return status;
166 
167  status = PhDuplicateObject(
168  processHandle,
169  Context->HandleItem->Handle,
170  NtCurrentProcess(),
171  Handle,
172  DesiredAccess,
173  0,
174  0
175  );
176  NtClose(processHandle);
177 
178  return status;
179 }
180 
181 INT_PTR CALLBACK EtpAlpcPortPageDlgProc(
182  _In_ HWND hwndDlg,
183  _In_ UINT uMsg,
184  _In_ WPARAM wParam,
185  _In_ LPARAM lParam
186  )
187 {
188  switch (uMsg)
189  {
190  case WM_INITDIALOG:
191  {
192  LPPROPSHEETPAGE propSheetPage = (LPPROPSHEETPAGE)lParam;
193  PCOMMON_PAGE_CONTEXT context = (PCOMMON_PAGE_CONTEXT)propSheetPage->lParam;
194  HANDLE portHandle;
195 
196  if (NT_SUCCESS(EtpDuplicateHandleFromProcess(&portHandle, READ_CONTROL, context)))
197  {
198  ALPC_BASIC_INFORMATION basicInfo;
199 
201  portHandle,
203  &basicInfo,
204  sizeof(ALPC_BASIC_INFORMATION),
205  NULL
206  )))
207  {
208  PH_FORMAT format[2];
209  PPH_STRING string;
210 
211  PhInitFormatS(&format[0], L"Sequence Number: ");
212  PhInitFormatD(&format[1], basicInfo.SequenceNo);
213  format[1].Type |= FormatGroupDigits;
214 
215  string = PhFormat(format, 2, 128);
216  SetDlgItemText(hwndDlg, IDC_SEQUENCENUMBER, string->Buffer);
217  PhDereferenceObject(string);
218 
219  SetDlgItemText(hwndDlg, IDC_PORTCONTEXT,
220  PhaFormatString(L"Port Context: 0x%Ix", basicInfo.PortContext)->Buffer);
221  }
222 
223  NtClose(portHandle);
224  }
225  }
226  break;
227  }
228 
229  return FALSE;
230 }
231 
232 static BOOLEAN NTAPI EnumGenericModulesCallback(
233  _In_ PPH_MODULE_INFO Module,
234  _In_opt_ PVOID Context
235  )
236 {
237  if (Module->Type == PH_MODULE_TYPE_MODULE || Module->Type == PH_MODULE_TYPE_WOW64_MODULE)
238  {
239  PhLoadModuleSymbolProvider(Context, Module->FileName->Buffer,
240  (ULONG64)Module->BaseAddress, Module->Size);
241  }
242 
243  return TRUE;
244 }
245 
247  _In_ HWND hwndDlg,
248  _In_ UINT uMsg,
249  _In_ WPARAM wParam,
250  _In_ LPARAM lParam
251  )
252 {
253  switch (uMsg)
254  {
255  case WM_INITDIALOG:
256  {
257  LPPROPSHEETPAGE propSheetPage = (LPPROPSHEETPAGE)lParam;
258  PCOMMON_PAGE_CONTEXT context = (PCOMMON_PAGE_CONTEXT)propSheetPage->lParam;
259  HANDLE workerFactoryHandle;
260 
261  if (NT_SUCCESS(EtpDuplicateHandleFromProcess(&workerFactoryHandle, WORKER_FACTORY_QUERY_INFORMATION, context)))
262  {
263  WORKER_FACTORY_BASIC_INFORMATION basicInfo;
264 
265  if (NT_SUCCESS(NtQueryInformationWorkerFactory(
266  workerFactoryHandle,
267  WorkerFactoryBasicInformation,
268  &basicInfo,
269  sizeof(WORKER_FACTORY_BASIC_INFORMATION),
270  NULL
271  )))
272  {
273  PPH_SYMBOL_PROVIDER symbolProvider;
274  PPH_STRING symbol = NULL;
275 
276  symbolProvider = PhCreateSymbolProvider(basicInfo.ProcessId);
277  PhLoadSymbolProviderOptions(symbolProvider);
278 
279  if (symbolProvider->IsRealHandle)
280  {
281  PhEnumGenericModules(basicInfo.ProcessId, symbolProvider->ProcessHandle,
282  0, EnumGenericModulesCallback, symbolProvider);
283 
284  symbol = PhGetSymbolFromAddress(symbolProvider, (ULONG64)basicInfo.StartRoutine,
285  NULL, NULL, NULL, NULL);
286  }
287 
288  PhDereferenceObject(symbolProvider);
289 
290  if (symbol)
291  {
292  SetDlgItemText(hwndDlg, IDC_WORKERTHREADSTART,
293  PhaFormatString(L"Worker Thread Start: %s", symbol->Buffer)->Buffer);
294  PhDereferenceObject(symbol);
295  }
296  else
297  {
298  SetDlgItemText(hwndDlg, IDC_WORKERTHREADSTART,
299  PhaFormatString(L"Worker Thread Start: 0x%Ix", basicInfo.StartRoutine)->Buffer);
300  }
301 
302  SetDlgItemText(hwndDlg, IDC_WORKERTHREADCONTEXT,
303  PhaFormatString(L"Worker Thread Context: 0x%Ix", basicInfo.StartParameter)->Buffer);
304  }
305 
306  NtClose(workerFactoryHandle);
307  }
308  }
309  break;
310  }
311 
312  return FALSE;
313 }