313 lines
9.2 KiB
C
313 lines
9.2 KiB
C
/*
|
|
* Process Hacker Extended Tools -
|
|
* handle properties extensions
|
|
*
|
|
* Copyright (C) 2010-2011 wj32
|
|
*
|
|
* This file is part of Process Hacker.
|
|
*
|
|
* Process Hacker is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* Process Hacker is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with Process Hacker. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include "exttools.h"
|
|
#include <symprv.h>
|
|
|
|
typedef struct _COMMON_PAGE_CONTEXT
|
|
{
|
|
PPH_HANDLE_ITEM HandleItem;
|
|
HANDLE ProcessId;
|
|
} COMMON_PAGE_CONTEXT, *PCOMMON_PAGE_CONTEXT;
|
|
|
|
HPROPSHEETPAGE EtpCommonCreatePage(
|
|
_In_ PPH_PLUGIN_HANDLE_PROPERTIES_CONTEXT Context,
|
|
_In_ PWSTR Template,
|
|
_In_ DLGPROC DlgProc
|
|
);
|
|
|
|
INT CALLBACK EtpCommonPropPageProc(
|
|
_In_ HWND hwnd,
|
|
_In_ UINT uMsg,
|
|
_In_ LPPROPSHEETPAGE ppsp
|
|
);
|
|
|
|
INT_PTR CALLBACK EtpAlpcPortPageDlgProc(
|
|
_In_ HWND hwndDlg,
|
|
_In_ UINT uMsg,
|
|
_In_ WPARAM wParam,
|
|
_In_ LPARAM lParam
|
|
);
|
|
|
|
INT_PTR CALLBACK EtpTpWorkerFactoryPageDlgProc(
|
|
_In_ HWND hwndDlg,
|
|
_In_ UINT uMsg,
|
|
_In_ WPARAM wParam,
|
|
_In_ LPARAM lParam
|
|
);
|
|
|
|
VOID EtHandlePropertiesInitializing(
|
|
_In_ PVOID Parameter
|
|
)
|
|
{
|
|
PPH_PLUGIN_OBJECT_PROPERTIES objectProperties = Parameter;
|
|
PPH_PLUGIN_HANDLE_PROPERTIES_CONTEXT context = objectProperties->Parameter;
|
|
|
|
if (objectProperties->NumberOfPages < objectProperties->MaximumNumberOfPages)
|
|
{
|
|
HPROPSHEETPAGE page = NULL;
|
|
|
|
if (PhEqualString2(context->HandleItem->TypeName, L"ALPC Port", TRUE))
|
|
{
|
|
page = EtpCommonCreatePage(
|
|
context,
|
|
MAKEINTRESOURCE(IDD_OBJALPCPORT),
|
|
EtpAlpcPortPageDlgProc
|
|
);
|
|
}
|
|
else if (PhEqualString2(context->HandleItem->TypeName, L"TpWorkerFactory", TRUE))
|
|
{
|
|
page = EtpCommonCreatePage(
|
|
context,
|
|
MAKEINTRESOURCE(IDD_OBJTPWORKERFACTORY),
|
|
EtpTpWorkerFactoryPageDlgProc
|
|
);
|
|
}
|
|
|
|
// Insert our page into the second slot.
|
|
|
|
if (page)
|
|
{
|
|
if (objectProperties->NumberOfPages > 1)
|
|
{
|
|
memmove(&objectProperties->Pages[2], &objectProperties->Pages[1],
|
|
(objectProperties->NumberOfPages - 1) * sizeof(HPROPSHEETPAGE));
|
|
}
|
|
|
|
objectProperties->Pages[1] = page;
|
|
objectProperties->NumberOfPages++;
|
|
}
|
|
}
|
|
}
|
|
|
|
static HPROPSHEETPAGE EtpCommonCreatePage(
|
|
_In_ PPH_PLUGIN_HANDLE_PROPERTIES_CONTEXT Context,
|
|
_In_ PWSTR Template,
|
|
_In_ DLGPROC DlgProc
|
|
)
|
|
{
|
|
HPROPSHEETPAGE propSheetPageHandle;
|
|
PROPSHEETPAGE propSheetPage;
|
|
PCOMMON_PAGE_CONTEXT pageContext;
|
|
|
|
pageContext = PhCreateAlloc(sizeof(COMMON_PAGE_CONTEXT));
|
|
memset(pageContext, 0, sizeof(COMMON_PAGE_CONTEXT));
|
|
pageContext->HandleItem = Context->HandleItem;
|
|
pageContext->ProcessId = Context->ProcessId;
|
|
|
|
memset(&propSheetPage, 0, sizeof(PROPSHEETPAGE));
|
|
propSheetPage.dwSize = sizeof(PROPSHEETPAGE);
|
|
propSheetPage.dwFlags = PSP_USECALLBACK;
|
|
propSheetPage.hInstance = PluginInstance->DllBase;
|
|
propSheetPage.pszTemplate = Template;
|
|
propSheetPage.pfnDlgProc = DlgProc;
|
|
propSheetPage.lParam = (LPARAM)pageContext;
|
|
propSheetPage.pfnCallback = EtpCommonPropPageProc;
|
|
|
|
propSheetPageHandle = CreatePropertySheetPage(&propSheetPage);
|
|
PhDereferenceObject(pageContext); // already got a ref from above call
|
|
|
|
return propSheetPageHandle;
|
|
}
|
|
|
|
INT CALLBACK EtpCommonPropPageProc(
|
|
_In_ HWND hwnd,
|
|
_In_ UINT uMsg,
|
|
_In_ LPPROPSHEETPAGE ppsp
|
|
)
|
|
{
|
|
PCOMMON_PAGE_CONTEXT pageContext;
|
|
|
|
pageContext = (PCOMMON_PAGE_CONTEXT)ppsp->lParam;
|
|
|
|
if (uMsg == PSPCB_ADDREF)
|
|
PhReferenceObject(pageContext);
|
|
else if (uMsg == PSPCB_RELEASE)
|
|
PhDereferenceObject(pageContext);
|
|
|
|
return 1;
|
|
}
|
|
|
|
static NTSTATUS EtpDuplicateHandleFromProcess(
|
|
_Out_ PHANDLE Handle,
|
|
_In_ ACCESS_MASK DesiredAccess,
|
|
_In_ PCOMMON_PAGE_CONTEXT Context
|
|
)
|
|
{
|
|
NTSTATUS status;
|
|
HANDLE processHandle;
|
|
|
|
if (!NT_SUCCESS(status = PhOpenProcess(
|
|
&processHandle,
|
|
PROCESS_DUP_HANDLE,
|
|
Context->ProcessId
|
|
)))
|
|
return status;
|
|
|
|
status = NtDuplicateObject(
|
|
processHandle,
|
|
Context->HandleItem->Handle,
|
|
NtCurrentProcess(),
|
|
Handle,
|
|
DesiredAccess,
|
|
0,
|
|
0
|
|
);
|
|
NtClose(processHandle);
|
|
|
|
return status;
|
|
}
|
|
|
|
INT_PTR CALLBACK EtpAlpcPortPageDlgProc(
|
|
_In_ HWND hwndDlg,
|
|
_In_ UINT uMsg,
|
|
_In_ WPARAM wParam,
|
|
_In_ LPARAM lParam
|
|
)
|
|
{
|
|
switch (uMsg)
|
|
{
|
|
case WM_INITDIALOG:
|
|
{
|
|
LPPROPSHEETPAGE propSheetPage = (LPPROPSHEETPAGE)lParam;
|
|
PCOMMON_PAGE_CONTEXT context = (PCOMMON_PAGE_CONTEXT)propSheetPage->lParam;
|
|
HANDLE portHandle;
|
|
|
|
if (NT_SUCCESS(EtpDuplicateHandleFromProcess(&portHandle, READ_CONTROL, context)))
|
|
{
|
|
ALPC_BASIC_INFORMATION basicInfo;
|
|
|
|
if (NT_SUCCESS(NtAlpcQueryInformation(
|
|
portHandle,
|
|
AlpcBasicInformation,
|
|
&basicInfo,
|
|
sizeof(ALPC_BASIC_INFORMATION),
|
|
NULL
|
|
)))
|
|
{
|
|
PH_FORMAT format[2];
|
|
PPH_STRING string;
|
|
|
|
PhInitFormatS(&format[0], L"Sequence Number: ");
|
|
PhInitFormatD(&format[1], basicInfo.SequenceNo);
|
|
format[1].Type |= FormatGroupDigits;
|
|
|
|
string = PhFormat(format, 2, 128);
|
|
SetDlgItemText(hwndDlg, IDC_SEQUENCENUMBER, string->Buffer);
|
|
PhDereferenceObject(string);
|
|
|
|
SetDlgItemText(hwndDlg, IDC_PORTCONTEXT,
|
|
PhaFormatString(L"Port Context: 0x%Ix", basicInfo.PortContext)->Buffer);
|
|
}
|
|
|
|
NtClose(portHandle);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
static BOOLEAN NTAPI EnumGenericModulesCallback(
|
|
_In_ PPH_MODULE_INFO Module,
|
|
_In_opt_ PVOID Context
|
|
)
|
|
{
|
|
if (Module->Type == PH_MODULE_TYPE_MODULE || Module->Type == PH_MODULE_TYPE_WOW64_MODULE)
|
|
{
|
|
PhLoadModuleSymbolProvider(Context, Module->FileName->Buffer,
|
|
(ULONG64)Module->BaseAddress, Module->Size);
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
INT_PTR CALLBACK EtpTpWorkerFactoryPageDlgProc(
|
|
_In_ HWND hwndDlg,
|
|
_In_ UINT uMsg,
|
|
_In_ WPARAM wParam,
|
|
_In_ LPARAM lParam
|
|
)
|
|
{
|
|
switch (uMsg)
|
|
{
|
|
case WM_INITDIALOG:
|
|
{
|
|
LPPROPSHEETPAGE propSheetPage = (LPPROPSHEETPAGE)lParam;
|
|
PCOMMON_PAGE_CONTEXT context = (PCOMMON_PAGE_CONTEXT)propSheetPage->lParam;
|
|
HANDLE workerFactoryHandle;
|
|
|
|
if (NT_SUCCESS(EtpDuplicateHandleFromProcess(&workerFactoryHandle, WORKER_FACTORY_QUERY_INFORMATION, context)))
|
|
{
|
|
WORKER_FACTORY_BASIC_INFORMATION basicInfo;
|
|
|
|
if (NT_SUCCESS(NtQueryInformationWorkerFactory(
|
|
workerFactoryHandle,
|
|
WorkerFactoryBasicInformation,
|
|
&basicInfo,
|
|
sizeof(WORKER_FACTORY_BASIC_INFORMATION),
|
|
NULL
|
|
)))
|
|
{
|
|
PPH_SYMBOL_PROVIDER symbolProvider;
|
|
PPH_STRING symbol = NULL;
|
|
|
|
symbolProvider = PhCreateSymbolProvider(basicInfo.ProcessId);
|
|
PhLoadSymbolProviderOptions(symbolProvider);
|
|
|
|
if (symbolProvider->IsRealHandle)
|
|
{
|
|
PhEnumGenericModules(basicInfo.ProcessId, symbolProvider->ProcessHandle,
|
|
0, EnumGenericModulesCallback, symbolProvider);
|
|
|
|
symbol = PhGetSymbolFromAddress(symbolProvider, (ULONG64)basicInfo.StartRoutine,
|
|
NULL, NULL, NULL, NULL);
|
|
}
|
|
|
|
PhDereferenceObject(symbolProvider);
|
|
|
|
if (symbol)
|
|
{
|
|
SetDlgItemText(hwndDlg, IDC_WORKERTHREADSTART,
|
|
PhaFormatString(L"Worker Thread Start: %s", symbol->Buffer)->Buffer);
|
|
PhDereferenceObject(symbol);
|
|
}
|
|
else
|
|
{
|
|
SetDlgItemText(hwndDlg, IDC_WORKERTHREADSTART,
|
|
PhaFormatString(L"Worker Thread Start: 0x%Ix", basicInfo.StartRoutine)->Buffer);
|
|
}
|
|
|
|
SetDlgItemText(hwndDlg, IDC_WORKERTHREADCONTEXT,
|
|
PhaFormatString(L"Worker Thread Context: 0x%Ix", basicInfo.StartParameter)->Buffer);
|
|
}
|
|
|
|
NtClose(workerFactoryHandle);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|