Skip to content

Commit

Permalink
Remove dll injection feature
Browse files Browse the repository at this point in the history
  • Loading branch information
dmex committed Jan 7, 2018
1 parent 0168d9c commit 02b2c0a
Show file tree
Hide file tree
Showing 7 changed files with 4 additions and 244 deletions.
56 changes: 0 additions & 56 deletions ProcessHacker/actions.c
Expand Up @@ -1663,62 +1663,6 @@ BOOLEAN PhUiDetachFromDebuggerProcess(
return TRUE;
}

BOOLEAN PhUiInjectDllProcess(
_In_ HWND hWnd,
_In_ PPH_PROCESS_ITEM Process
)
{
static PH_FILETYPE_FILTER filters[] =
{
{ L"DLL files (*.dll)", L"*.dll" },
{ L"All files (*.*)", L"*.*" }
};

NTSTATUS status;
PVOID fileDialog;
PPH_STRING fileName;
HANDLE processHandle;

fileDialog = PhCreateOpenFileDialog();
PhSetFileDialogFilter(fileDialog, filters, sizeof(filters) / sizeof(PH_FILETYPE_FILTER));

if (!PhShowFileDialog(hWnd, fileDialog))
{
PhFreeFileDialog(fileDialog);
return FALSE;
}

fileName = PH_AUTO(PhGetFileDialogFileName(fileDialog));
PhFreeFileDialog(fileDialog);

if (NT_SUCCESS(status = PhOpenProcess(
&processHandle,
ProcessQueryAccess | PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION |
PROCESS_VM_READ | PROCESS_VM_WRITE,
Process->ProcessId
)))
{
LARGE_INTEGER timeout;

timeout.QuadPart = -5 * PH_TIMEOUT_SEC;
status = PhInjectDllProcess(
processHandle,
fileName->Buffer,
&timeout
);

NtClose(processHandle);
}

if (!NT_SUCCESS(status))
{
PhpShowErrorProcess(hWnd, L"inject the DLL into", Process, status, 0);
return FALSE;
}

return TRUE;
}

BOOLEAN PhUiSetIoPriorityProcesses(
_In_ HWND hWnd,
_In_ PPH_PROCESS_ITEM *Processes,
Expand Down
22 changes: 0 additions & 22 deletions ProcessHacker/cmdmode.c
Expand Up @@ -226,28 +226,6 @@ NTSTATUS PhCommandModeStart(
NtClose(processHandle);
}
}
else if (PhEqualString2(PhStartupParameters.CommandAction, L"injectdll", TRUE))
{
if (!PhStartupParameters.CommandValue)
return STATUS_INVALID_PARAMETER;

if (NT_SUCCESS(status = PhOpenProcessPublic(
&processHandle,
ProcessQueryAccess | PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE,
processId
)))
{
LARGE_INTEGER timeout;

timeout.QuadPart = -5 * PH_TIMEOUT_SEC;
status = PhInjectDllProcess(
processHandle,
PhStartupParameters.CommandValue->Buffer,
&timeout
);
NtClose(processHandle);
}
}
else if (PhEqualString2(PhStartupParameters.CommandAction, L"unloaddll", TRUE))
{
if (!PhStartupParameters.CommandValue)
Expand Down
8 changes: 0 additions & 8 deletions ProcessHacker/include/actions.h
Expand Up @@ -188,14 +188,6 @@ PhUiDetachFromDebuggerProcess(
_In_ PPH_PROCESS_ITEM Process
);

PHAPPAPI
BOOLEAN
NTAPI
PhUiInjectDllProcess(
_In_ HWND hWnd,
_In_ PPH_PROCESS_ITEM Process
);

PHAPPAPI
BOOLEAN
NTAPI
Expand Down
20 changes: 4 additions & 16 deletions ProcessHacker/prpgmod.c
Expand Up @@ -690,8 +690,6 @@ INT_PTR CALLBACK PhpProcessModulesDlgProc(
PhInsertEMenuItem(menu, relocatedItem = PhCreateEMenuItem(0, PH_MODULE_FLAGS_HIGHLIGHT_RELOCATED_OPTION, L"Highlight relocated modules", NULL, NULL), -1);
PhInsertEMenuItem(menu, untrustedItem = PhCreateEMenuItem(0, PH_MODULE_FLAGS_HIGHLIGHT_UNSIGNED_OPTION, L"Highlight untrusted modules", NULL, NULL), -1);
PhInsertEMenuItem(menu, PhCreateEMenuSeparator(), -1);
PhInsertEMenuItem(menu, PhCreateEMenuItem(0, PH_MODULE_FLAGS_LOAD_MODULE_OPTION, L"Load module", NULL, NULL), -1);
PhInsertEMenuItem(menu, PhCreateEMenuSeparator(), -1);
PhInsertEMenuItem(menu, stringsItem = PhCreateEMenuItem(0, PH_MODULE_FLAGS_MODULE_STRINGS_OPTION, L"Strings...", NULL, NULL), -1);

if (modulesContext->ListContext.HideDynamicModules)
Expand Down Expand Up @@ -724,20 +722,10 @@ INT_PTR CALLBACK PhpProcessModulesDlgProc(

if (selectedItem && selectedItem->Id)
{
if (selectedItem->Id == PH_MODULE_FLAGS_LOAD_MODULE_OPTION)
{
PhReferenceObject(processItem);
PhUiInjectDllProcess(hwndDlg, processItem);
PhDereferenceObject(processItem);
}
else
{
PhSetOptionsModuleList(&modulesContext->ListContext, selectedItem->Id);

PhSaveSettingsModuleList(&modulesContext->ListContext);

PhApplyTreeNewFilters(&modulesContext->ListContext.TreeFilterSupport);
}
PhSetOptionsModuleList(&modulesContext->ListContext, selectedItem->Id);
PhSaveSettingsModuleList(&modulesContext->ListContext);

PhApplyTreeNewFilters(&modulesContext->ListContext.TreeFilterSupport);
}

PhDestroyEMenu(menu);
Expand Down
1 change: 0 additions & 1 deletion ProcessHacker/resource.h
Expand Up @@ -560,7 +560,6 @@
#define ID_PROCESS_AFFINITY 40035
#define ID_PROCESS_CREATEDUMPFILE 40036
#define ID_MISCELLANEOUS_DETACHFROMDEBUGGER 40039
#define ID_MISCELLANEOUS_INJECTDLL 40041
#define ID_PRIORITY_REALTIME 40048
#define ID_PRIORITY_HIGH 40049
#define ID_WINDOW_BRINGTOFRONT 40055
Expand Down
9 changes: 0 additions & 9 deletions phlib/include/phnative.h
Expand Up @@ -270,15 +270,6 @@ PhGetProcessWsCounters(
_Out_ PPH_PROCESS_WS_COUNTERS WsCounters
);

PHLIBAPI
NTSTATUS
NTAPI
PhInjectDllProcess(
_In_ HANDLE ProcessHandle,
_In_ PWSTR FileName,
_In_opt_ PLARGE_INTEGER Timeout
);

PHLIBAPI
NTSTATUS
NTAPI
Expand Down
132 changes: 0 additions & 132 deletions phlib/native.c
Expand Up @@ -1208,138 +1208,6 @@ NTSTATUS PhGetProcessWsCounters(
return status;
}

/**
* Causes a process to load a DLL.
*
* \param ProcessHandle A handle to a process. The handle must have
* PROCESS_QUERY_LIMITED_INFORMATION, PROCESS_CREATE_THREAD, PROCESS_VM_OPERATION, PROCESS_VM_READ
* and PROCESS_VM_WRITE access.
* \param FileName The file name of the DLL to inject.
* \param Timeout The timeout, in milliseconds, for the process to load the DLL.
*
* \remarks If the process does not load the DLL before the timeout expires it may crash. Choose the
* timeout value carefully.
*/
NTSTATUS PhInjectDllProcess(
_In_ HANDLE ProcessHandle,
_In_ PWSTR FileName,
_In_opt_ PLARGE_INTEGER Timeout
)
{
#ifdef _WIN64
static PVOID loadLibraryW32 = NULL;
#endif

NTSTATUS status;
#ifdef _WIN64
BOOLEAN isWow64 = FALSE;
BOOLEAN isModule32 = FALSE;
PH_MAPPED_IMAGE mappedImage;
#endif
PVOID threadStart;
PH_STRINGREF fileName;
PVOID baseAddress = NULL;
SIZE_T allocSize;
HANDLE threadHandle;

#ifdef _WIN64
PhGetProcessIsWow64(ProcessHandle, &isWow64);

if (isWow64)
{
if (!NT_SUCCESS(status = PhLoadMappedImage(FileName, NULL, TRUE, &mappedImage)))
return status;

isModule32 = mappedImage.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC;
PhUnloadMappedImage(&mappedImage);
}

if (!isModule32)
{
#endif
threadStart = PhGetModuleProcAddress(L"kernel32.dll", "LoadLibraryW");
#ifdef _WIN64
}
else
{
threadStart = loadLibraryW32;

if (!threadStart)
{
PPH_STRING kernel32FileName;

kernel32FileName = PhConcatStrings2(USER_SHARED_DATA->NtSystemRoot, L"\\SysWow64\\kernel32.dll");
status = PhGetProcedureAddressRemote(
ProcessHandle,
kernel32FileName->Buffer,
"LoadLibraryW",
0,
&loadLibraryW32,
NULL
);
PhDereferenceObject(kernel32FileName);

if (!NT_SUCCESS(status))
return status;

threadStart = loadLibraryW32;
}
}
#endif

PhInitializeStringRefLongHint(&fileName, FileName);
allocSize = fileName.Length + sizeof(WCHAR);

if (!NT_SUCCESS(status = NtAllocateVirtualMemory(
ProcessHandle,
&baseAddress,
0,
&allocSize,
MEM_COMMIT,
PAGE_READWRITE
)))
return status;

if (!NT_SUCCESS(status = NtWriteVirtualMemory(
ProcessHandle,
baseAddress,
fileName.Buffer,
fileName.Length + sizeof(WCHAR),
NULL
)))
goto FreeExit;

if (!NT_SUCCESS(status = RtlCreateUserThread(
ProcessHandle,
NULL,
FALSE,
0,
0,
0,
threadStart,
baseAddress,
&threadHandle,
NULL
)))
goto FreeExit;

// Wait for the thread to finish.
status = NtWaitForSingleObject(threadHandle, FALSE, Timeout);
NtClose(threadHandle);

FreeExit:
// Size needs to be zero if we're freeing.
allocSize = 0;
NtFreeVirtualMemory(
ProcessHandle,
&baseAddress,
&allocSize,
MEM_RELEASE
);

return status;
}

/**
* Causes a process to unload a DLL.
*
Expand Down

3 comments on commit 02b2c0a

@stonedreamforest
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add it please 👍

@Syst3mSh0ck
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why has this feature been removed? Could it not be relegated to a UI switch for advanced/debug users? Thanks.

@diversenok
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe it causes a false positive detection..?
I can reestablish this code as an extra plugin for PH so anyone who needs this feature will be able to continue to use it. But first, we should wait for dmex's response.

Please sign in to comment.