mirror of
https://github.com/pbatard/rufus.git
synced 2024-08-14 23:57:05 +00:00
[core] handle search improvements
* Fix memory leaks due to not releasing the heap * Also speed up lookups by not reopening the same process twice in a row * Also make the usb_debug variable global so we can use uuprintf everywhere
This commit is contained in:
parent
fec0813073
commit
d1927ac1ef
7 changed files with 304 additions and 66 deletions
|
@ -61,7 +61,7 @@ static int task_number = 0;
|
||||||
extern const int nb_steps[FS_MAX];
|
extern const int nb_steps[FS_MAX];
|
||||||
extern uint32_t dur_mins, dur_secs;
|
extern uint32_t dur_mins, dur_secs;
|
||||||
static int fs_index = 0, wintogo_index = -1;
|
static int fs_index = 0, wintogo_index = -1;
|
||||||
extern BOOL force_large_fat32, enable_ntfs_compression, lock_drive, zero_drive, disable_file_indexing, usb_debug;
|
extern BOOL force_large_fat32, enable_ntfs_compression, lock_drive, zero_drive, disable_file_indexing;
|
||||||
uint8_t *grub2_buf = NULL;
|
uint8_t *grub2_buf = NULL;
|
||||||
long grub2_len;
|
long grub2_len;
|
||||||
static BOOL WritePBR(HANDLE hLogicalDrive);
|
static BOOL WritePBR(HANDLE hLogicalDrive);
|
||||||
|
|
|
@ -2170,8 +2170,9 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA
|
||||||
case WM_COMMAND:
|
case WM_COMMAND:
|
||||||
#ifdef RUFUS_TEST
|
#ifdef RUFUS_TEST
|
||||||
if (LOWORD(wParam) == IDC_TEST) {
|
if (LOWORD(wParam) == IDC_TEST) {
|
||||||
char* choices[] = { "Choice 1", "Choice 2", "Choice 3" };
|
SearchProcess("\\Device\\Harddisk5\\DR5", TRUE, TRUE);
|
||||||
SelectionDyn("Test Choice", "Unused", choices, ARRAYSIZE(choices));
|
// char* choices[] = { "Choice 1", "Choice 2", "Choice 3" };
|
||||||
|
// SelectionDyn("Test Choice", "Unused", choices, ARRAYSIZE(choices));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -392,7 +392,7 @@ extern BOOL PromptOnError;
|
||||||
extern unsigned long syslinux_ldlinux_len[2];
|
extern unsigned long syslinux_ldlinux_len[2];
|
||||||
extern const int nb_steps[FS_MAX];
|
extern const int nb_steps[FS_MAX];
|
||||||
extern BOOL use_own_c32[NB_OLD_C32], detect_fakes, iso_op_in_progress, format_op_in_progress, right_to_left_mode;
|
extern BOOL use_own_c32[NB_OLD_C32], detect_fakes, iso_op_in_progress, format_op_in_progress, right_to_left_mode;
|
||||||
extern BOOL allow_dual_uefi_bios, togo_mode, large_drive;
|
extern BOOL allow_dual_uefi_bios, togo_mode, large_drive, usb_debug;
|
||||||
extern RUFUS_IMG_REPORT img_report;
|
extern RUFUS_IMG_REPORT img_report;
|
||||||
extern int64_t iso_blocking_status;
|
extern int64_t iso_blocking_status;
|
||||||
extern uint16_t rufus_version[3], embedded_sl_version[2];
|
extern uint16_t rufus_version[3], embedded_sl_version[2];
|
||||||
|
|
10
src/rufus.rc
10
src/rufus.rc
|
@ -33,7 +33,7 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
|
||||||
IDD_DIALOG DIALOGEX 12, 12, 242, 376
|
IDD_DIALOG DIALOGEX 12, 12, 242, 376
|
||||||
STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||||
EXSTYLE WS_EX_ACCEPTFILES
|
EXSTYLE WS_EX_ACCEPTFILES
|
||||||
CAPTION "Rufus 2.15.1096"
|
CAPTION "Rufus 2.15.1097"
|
||||||
FONT 8, "Segoe UI Symbol", 400, 0, 0x0
|
FONT 8, "Segoe UI Symbol", 400, 0, 0x0
|
||||||
BEGIN
|
BEGIN
|
||||||
LTEXT "Device",IDS_DEVICE_TXT,9,6,200,8
|
LTEXT "Device",IDS_DEVICE_TXT,9,6,200,8
|
||||||
|
@ -334,8 +334,8 @@ END
|
||||||
//
|
//
|
||||||
|
|
||||||
VS_VERSION_INFO VERSIONINFO
|
VS_VERSION_INFO VERSIONINFO
|
||||||
FILEVERSION 2,15,1096,0
|
FILEVERSION 2,15,1097,0
|
||||||
PRODUCTVERSION 2,15,1096,0
|
PRODUCTVERSION 2,15,1097,0
|
||||||
FILEFLAGSMASK 0x3fL
|
FILEFLAGSMASK 0x3fL
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
FILEFLAGS 0x1L
|
FILEFLAGS 0x1L
|
||||||
|
@ -352,13 +352,13 @@ BEGIN
|
||||||
BEGIN
|
BEGIN
|
||||||
VALUE "CompanyName", "Akeo Consulting (http://akeo.ie)"
|
VALUE "CompanyName", "Akeo Consulting (http://akeo.ie)"
|
||||||
VALUE "FileDescription", "Rufus"
|
VALUE "FileDescription", "Rufus"
|
||||||
VALUE "FileVersion", "2.15.1096"
|
VALUE "FileVersion", "2.15.1097"
|
||||||
VALUE "InternalName", "Rufus"
|
VALUE "InternalName", "Rufus"
|
||||||
VALUE "LegalCopyright", "© 2011-2017 Pete Batard (GPL v3)"
|
VALUE "LegalCopyright", "© 2011-2017 Pete Batard (GPL v3)"
|
||||||
VALUE "LegalTrademarks", "http://www.gnu.org/copyleft/gpl.html"
|
VALUE "LegalTrademarks", "http://www.gnu.org/copyleft/gpl.html"
|
||||||
VALUE "OriginalFilename", "rufus.exe"
|
VALUE "OriginalFilename", "rufus.exe"
|
||||||
VALUE "ProductName", "Rufus"
|
VALUE "ProductName", "Rufus"
|
||||||
VALUE "ProductVersion", "2.15.1096"
|
VALUE "ProductVersion", "2.15.1097"
|
||||||
END
|
END
|
||||||
END
|
END
|
||||||
BLOCK "VarFileInfo"
|
BLOCK "VarFileInfo"
|
||||||
|
|
290
src/search.c
290
src/search.c
|
@ -34,9 +34,18 @@
|
||||||
#include "missing.h"
|
#include "missing.h"
|
||||||
#include "msapi_utf8.h"
|
#include "msapi_utf8.h"
|
||||||
|
|
||||||
|
// Process Hacker does some filtering using Object Types, but this doesn't help us.
|
||||||
|
// Keep this option, just in case.
|
||||||
|
// #define USE_OBJECT_TYPES
|
||||||
|
|
||||||
PF_TYPE_DECL(NTAPI, PVOID, RtlCreateHeap, (ULONG, PVOID, SIZE_T, SIZE_T, PVOID, PRTL_HEAP_PARAMETERS));
|
PF_TYPE_DECL(NTAPI, PVOID, RtlCreateHeap, (ULONG, PVOID, SIZE_T, SIZE_T, PVOID, PRTL_HEAP_PARAMETERS));
|
||||||
|
PF_TYPE_DECL(NTAPI, PVOID, RtlDestroyHeap, (PVOID));
|
||||||
PF_TYPE_DECL(NTAPI, PVOID, RtlAllocateHeap, (PVOID, ULONG, SIZE_T));
|
PF_TYPE_DECL(NTAPI, PVOID, RtlAllocateHeap, (PVOID, ULONG, SIZE_T));
|
||||||
PF_TYPE_DECL(NTAPI, BOOLEAN, RtlFreeHeap, (PVOID, ULONG, PVOID));
|
PF_TYPE_DECL(NTAPI, BOOLEAN, RtlFreeHeap, (PVOID, ULONG, PVOID));
|
||||||
|
#ifdef USE_OBJECT_TYPES
|
||||||
|
PF_TYPE_DECL(NTAPI, VOID, RtlInitUnicodeString, (PUNICODE_STRING, PCWSTR));
|
||||||
|
PF_TYPE_DECL(NTAPI, BOOLEAN, RtlEqualUnicodeString, (PCUNICODE_STRING, PCUNICODE_STRING, BOOLEAN));
|
||||||
|
#endif
|
||||||
|
|
||||||
PF_TYPE_DECL(NTAPI, NTSTATUS, NtQuerySystemInformation, (SYSTEM_INFORMATION_CLASS, PVOID, ULONG, PULONG));
|
PF_TYPE_DECL(NTAPI, NTSTATUS, NtQuerySystemInformation, (SYSTEM_INFORMATION_CLASS, PVOID, ULONG, PULONG));
|
||||||
PF_TYPE_DECL(NTAPI, NTSTATUS, NtQueryObject, (HANDLE, OBJECT_INFORMATION_CLASS, PVOID, ULONG, PULONG));
|
PF_TYPE_DECL(NTAPI, NTSTATUS, NtQueryObject, (HANDLE, OBJECT_INFORMATION_CLASS, PVOID, ULONG, PULONG));
|
||||||
|
@ -60,10 +69,12 @@ static char* NtStatusError(NTSTATUS Status) {
|
||||||
switch (Status) {
|
switch (Status) {
|
||||||
case STATUS_UNSUCCESSFUL:
|
case STATUS_UNSUCCESSFUL:
|
||||||
return "Operation Failed";
|
return "Operation Failed";
|
||||||
case STATUS_NOT_IMPLEMENTED:
|
|
||||||
return "Not Implemented";
|
|
||||||
case STATUS_BUFFER_OVERFLOW:
|
case STATUS_BUFFER_OVERFLOW:
|
||||||
return "Buffer Overflow";
|
return "Buffer Overflow";
|
||||||
|
case STATUS_NOT_IMPLEMENTED:
|
||||||
|
return "Not Implemented";
|
||||||
|
case STATUS_INFO_LENGTH_MISMATCH:
|
||||||
|
return "Info Length Mismatch";
|
||||||
case STATUS_INVALID_HANDLE:
|
case STATUS_INVALID_HANDLE:
|
||||||
return "Invalid Handle.";
|
return "Invalid Handle.";
|
||||||
case STATUS_INVALID_PARAMETER:
|
case STATUS_INVALID_PARAMETER:
|
||||||
|
@ -77,9 +88,11 @@ static char* NtStatusError(NTSTATUS Status) {
|
||||||
case STATUS_OBJECT_TYPE_MISMATCH:
|
case STATUS_OBJECT_TYPE_MISMATCH:
|
||||||
return "Wrong Type";
|
return "Wrong Type";
|
||||||
case STATUS_OBJECT_NAME_INVALID:
|
case STATUS_OBJECT_NAME_INVALID:
|
||||||
return "Object Name invalid";
|
return "Object Name Invalid";
|
||||||
case STATUS_OBJECT_NAME_NOT_FOUND:
|
case STATUS_OBJECT_NAME_NOT_FOUND:
|
||||||
return "Object Name not found";
|
return "Object Name not found";
|
||||||
|
case STATUS_OBJECT_PATH_INVALID:
|
||||||
|
return "Object Path Invalid";
|
||||||
case STATUS_SHARING_VIOLATION:
|
case STATUS_SHARING_VIOLATION:
|
||||||
return "Sharing Violation";
|
return "Sharing Violation";
|
||||||
case STATUS_INSUFFICIENT_RESOURCES:
|
case STATUS_INSUFFICIENT_RESOURCES:
|
||||||
|
@ -92,6 +105,45 @@ static char* NtStatusError(NTSTATUS Status) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static NTSTATUS PhCreateHeap(VOID)
|
||||||
|
{
|
||||||
|
NTSTATUS status = STATUS_SUCCESS;
|
||||||
|
|
||||||
|
if (PhHeapHandle != NULL)
|
||||||
|
return STATUS_ALREADY_COMPLETE;
|
||||||
|
|
||||||
|
PF_INIT_OR_SET_STATUS(RtlCreateHeap, Ntdll);
|
||||||
|
|
||||||
|
if (NT_SUCCESS(status)) {
|
||||||
|
PhHeapHandle = pfRtlCreateHeap(HEAP_NO_SERIALIZE | HEAP_GROWABLE, NULL, 2 * MB, 1 * MB, NULL, NULL);
|
||||||
|
if (PhHeapHandle == NULL)
|
||||||
|
status = STATUS_UNSUCCESSFUL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
static NTSTATUS PhDestroyHeap(VOID)
|
||||||
|
{
|
||||||
|
NTSTATUS status = STATUS_SUCCESS;
|
||||||
|
|
||||||
|
if (PhHeapHandle == NULL)
|
||||||
|
return STATUS_ALREADY_COMPLETE;
|
||||||
|
|
||||||
|
PF_INIT_OR_SET_STATUS(RtlDestroyHeap, Ntdll);
|
||||||
|
|
||||||
|
if (NT_SUCCESS(status)) {
|
||||||
|
if (pfRtlDestroyHeap(PhHeapHandle) == NULL) {
|
||||||
|
PhHeapHandle = NULL;
|
||||||
|
} else {
|
||||||
|
status = STATUS_UNSUCCESSFUL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allocates a block of memory.
|
* Allocates a block of memory.
|
||||||
*
|
*
|
||||||
|
@ -102,15 +154,11 @@ static char* NtStatusError(NTSTATUS Status) {
|
||||||
*/
|
*/
|
||||||
static PVOID PhAllocate(SIZE_T Size)
|
static PVOID PhAllocate(SIZE_T Size)
|
||||||
{
|
{
|
||||||
PF_INIT_OR_OUT(RtlCreateHeap, Ntdll);
|
PF_INIT(RtlAllocateHeap, Ntdll);
|
||||||
PF_INIT_OR_OUT(RtlAllocateHeap, Ntdll);
|
if (pfRtlAllocateHeap == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
if (PhHeapHandle == NULL) {
|
|
||||||
PhHeapHandle = pfRtlCreateHeap(HEAP_GROWABLE, NULL, 2 * MB, 1 * MB, NULL, NULL);
|
|
||||||
}
|
|
||||||
return pfRtlAllocateHeap(PhHeapHandle, 0, Size);
|
return pfRtlAllocateHeap(PhHeapHandle, 0, Size);
|
||||||
out:
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -122,6 +170,7 @@ out:
|
||||||
static VOID PhFree(PVOID Memory)
|
static VOID PhFree(PVOID Memory)
|
||||||
{
|
{
|
||||||
PF_INIT(RtlFreeHeap, Ntdll);
|
PF_INIT(RtlFreeHeap, Ntdll);
|
||||||
|
|
||||||
if (pfRtlFreeHeap != NULL)
|
if (pfRtlFreeHeap != NULL)
|
||||||
pfRtlFreeHeap(PhHeapHandle, 0, Memory);
|
pfRtlFreeHeap(PhHeapHandle, 0, Memory);
|
||||||
}
|
}
|
||||||
|
@ -137,13 +186,13 @@ static VOID PhFree(PVOID Memory)
|
||||||
NTSTATUS PhEnumHandlesEx(PSYSTEM_HANDLE_INFORMATION_EX *Handles)
|
NTSTATUS PhEnumHandlesEx(PSYSTEM_HANDLE_INFORMATION_EX *Handles)
|
||||||
{
|
{
|
||||||
static ULONG initialBufferSize = 0x10000;
|
static ULONG initialBufferSize = 0x10000;
|
||||||
NTSTATUS status;
|
NTSTATUS status = STATUS_SUCCESS;
|
||||||
PVOID buffer;
|
PVOID buffer;
|
||||||
ULONG bufferSize;
|
ULONG bufferSize;
|
||||||
|
|
||||||
PF_INIT(NtQuerySystemInformation, Ntdll);
|
PF_INIT_OR_SET_STATUS(NtQuerySystemInformation, Ntdll);
|
||||||
if (pfNtQuerySystemInformation == NULL)
|
if (!NT_SUCCESS(status))
|
||||||
return STATUS_NOT_IMPLEMENTED;
|
return status;
|
||||||
|
|
||||||
bufferSize = initialBufferSize;
|
bufferSize = initialBufferSize;
|
||||||
buffer = PhAllocate(bufferSize);
|
buffer = PhAllocate(bufferSize);
|
||||||
|
@ -187,7 +236,7 @@ NTSTATUS PhEnumHandlesEx(PSYSTEM_HANDLE_INFORMATION_EX *Handles)
|
||||||
*/
|
*/
|
||||||
NTSTATUS PhOpenProcess(PHANDLE ProcessHandle, ACCESS_MASK DesiredAccess, HANDLE ProcessId)
|
NTSTATUS PhOpenProcess(PHANDLE ProcessHandle, ACCESS_MASK DesiredAccess, HANDLE ProcessId)
|
||||||
{
|
{
|
||||||
NTSTATUS status = STATUS_NOT_IMPLEMENTED;
|
NTSTATUS status = STATUS_SUCCESS;
|
||||||
OBJECT_ATTRIBUTES objectAttributes;
|
OBJECT_ATTRIBUTES objectAttributes;
|
||||||
CLIENT_ID clientId;
|
CLIENT_ID clientId;
|
||||||
|
|
||||||
|
@ -196,7 +245,9 @@ NTSTATUS PhOpenProcess(PHANDLE ProcessHandle, ACCESS_MASK DesiredAccess, HANDLE
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
PF_INIT_OR_OUT(NtOpenProcess, Ntdll);
|
PF_INIT_OR_SET_STATUS(NtOpenProcess, Ntdll);
|
||||||
|
if (!NT_SUCCESS(status))
|
||||||
|
return status;
|
||||||
|
|
||||||
clientId.UniqueProcess = ProcessId;
|
clientId.UniqueProcess = ProcessId;
|
||||||
clientId.UniqueThread = NULL;
|
clientId.UniqueThread = NULL;
|
||||||
|
@ -204,10 +255,85 @@ NTSTATUS PhOpenProcess(PHANDLE ProcessHandle, ACCESS_MASK DesiredAccess, HANDLE
|
||||||
InitializeObjectAttributes(&objectAttributes, NULL, 0, NULL, NULL);
|
InitializeObjectAttributes(&objectAttributes, NULL, 0, NULL, NULL);
|
||||||
status = pfNtOpenProcess(ProcessHandle, DesiredAccess, &objectAttributes, &clientId);
|
status = pfNtOpenProcess(ProcessHandle, DesiredAccess, &objectAttributes, &clientId);
|
||||||
|
|
||||||
out:
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef USE_OBJECT_TYPES
|
||||||
|
NTSTATUS PhEnumObjectTypes(POBJECT_TYPES_INFORMATION *ObjectTypes)
|
||||||
|
{
|
||||||
|
NTSTATUS status = STATUS_SUCCESS;
|
||||||
|
PVOID buffer;
|
||||||
|
ULONG bufferSize;
|
||||||
|
ULONG returnLength;
|
||||||
|
|
||||||
|
PF_INIT_OR_SET_STATUS(NtQueryObject, Ntdll);
|
||||||
|
if (!NT_SUCCESS(status))
|
||||||
|
return status;
|
||||||
|
|
||||||
|
bufferSize = 0x1000;
|
||||||
|
buffer = PhAllocate(bufferSize);
|
||||||
|
|
||||||
|
while ((status = pfNtQueryObject(NULL, ObjectTypesInformation, buffer, bufferSize, &returnLength)) == STATUS_INFO_LENGTH_MISMATCH) {
|
||||||
|
PhFree(buffer);
|
||||||
|
bufferSize *= 2;
|
||||||
|
|
||||||
|
// Fail if we're resizing the buffer to something very large.
|
||||||
|
if (bufferSize > PH_LARGE_BUFFER_SIZE)
|
||||||
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
|
||||||
|
buffer = PhAllocate(bufferSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(status)) {
|
||||||
|
PhFree(buffer);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
*ObjectTypes = (POBJECT_TYPES_INFORMATION)buffer;
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
ULONG PhGetObjectTypeNumber(PUNICODE_STRING TypeName)
|
||||||
|
{
|
||||||
|
NTSTATUS status = STATUS_SUCCESS;
|
||||||
|
POBJECT_TYPES_INFORMATION objectTypes;
|
||||||
|
POBJECT_TYPE_INFORMATION objectType;
|
||||||
|
ULONG objectIndex = -1;
|
||||||
|
ULONG i;
|
||||||
|
|
||||||
|
PF_INIT_OR_SET_STATUS(RtlEqualUnicodeString, NtDll);
|
||||||
|
if (!NT_SUCCESS(status))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
status = PhEnumObjectTypes(&objectTypes);
|
||||||
|
if (NT_SUCCESS(status)) {
|
||||||
|
objectType = PH_FIRST_OBJECT_TYPE(objectTypes);
|
||||||
|
|
||||||
|
for (i = 0; i < objectTypes->NumberOfTypes; i++) {
|
||||||
|
if (pfRtlEqualUnicodeString(&objectType->TypeName, TypeName, TRUE)) {
|
||||||
|
if (nWindowsVersion >= WINDOWS_8_1) {
|
||||||
|
objectIndex = objectType->TypeIndex;
|
||||||
|
break;
|
||||||
|
} else if (nWindowsVersion >= WINDOWS_7) {
|
||||||
|
objectIndex = i + 2;
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
objectIndex = i + 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
objectType = PH_NEXT_OBJECT_TYPE(objectType);
|
||||||
|
}
|
||||||
|
|
||||||
|
PhFree(objectTypes);
|
||||||
|
}
|
||||||
|
|
||||||
|
return objectIndex;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Search all the processes and list the ones that have a specific handle open.
|
* Search all the processes and list the ones that have a specific handle open.
|
||||||
*
|
*
|
||||||
|
@ -219,42 +345,63 @@ out:
|
||||||
*/
|
*/
|
||||||
BOOL SearchProcess(char* HandleName, BOOL bPartialMatch, BOOL bIgnoreSelf)
|
BOOL SearchProcess(char* HandleName, BOOL bPartialMatch, BOOL bIgnoreSelf)
|
||||||
{
|
{
|
||||||
NTSTATUS status;
|
NTSTATUS status = STATUS_SUCCESS;
|
||||||
PSYSTEM_HANDLE_INFORMATION_EX handles;
|
PSYSTEM_HANDLE_INFORMATION_EX handles = NULL;
|
||||||
POBJECT_NAME_INFORMATION buffer;
|
POBJECT_NAME_INFORMATION buffer = NULL;
|
||||||
|
#ifdef USE_OBJECT_TYPES
|
||||||
|
UNICODE_STRING fileTypeName;
|
||||||
|
ULONG fileObjectTypeIndex = -1;
|
||||||
|
#endif
|
||||||
ULONG_PTR i;
|
ULONG_PTR i;
|
||||||
|
ULONG_PTR pid[2];
|
||||||
|
ULONG_PTR last_access_denied_pid = 0;
|
||||||
ULONG bufferSize;
|
ULONG bufferSize;
|
||||||
USHORT wHandleNameLen;
|
USHORT wHandleNameLen;
|
||||||
WCHAR *wHandleName;
|
WCHAR *wHandleName = NULL;
|
||||||
HANDLE dupHandle = NULL;
|
HANDLE dupHandle = NULL;
|
||||||
HANDLE processHandle = NULL;
|
HANDLE processHandle = NULL;
|
||||||
BOOLEAN bFound = FALSE;
|
BOOLEAN bFound = FALSE;
|
||||||
char exe_path[2][MAX_PATH];
|
char exe[2][MAX_PATH];
|
||||||
int cur;
|
int cur_exe, cur_pid;
|
||||||
|
|
||||||
status = STATUS_NOT_IMPLEMENTED;
|
PF_INIT_OR_SET_STATUS(NtQueryObject, Ntdll);
|
||||||
PF_INIT(NtQueryObject, Ntdll);
|
PF_INIT_OR_SET_STATUS(NtDuplicateObject, NtDll);
|
||||||
PF_INIT(NtDuplicateObject, NtDll);
|
PF_INIT_OR_SET_STATUS(NtClose, NtDll);
|
||||||
PF_INIT(NtClose, NtDll);
|
#ifdef USE_OBJECT_TYPES
|
||||||
if ((pfNtQueryObject != NULL) && (pfNtClose != NULL) && (pfNtDuplicateObject != NULL))
|
PF_INIT(RtlInitUnicodeString, NtDll);
|
||||||
status = 0;
|
#endif
|
||||||
|
|
||||||
|
if (NT_SUCCESS(status))
|
||||||
|
status = PhCreateHeap();
|
||||||
|
|
||||||
if (NT_SUCCESS(status))
|
if (NT_SUCCESS(status))
|
||||||
status = PhEnumHandlesEx(&handles);
|
status = PhEnumHandlesEx(&handles);
|
||||||
|
|
||||||
if (!NT_SUCCESS(status)) {
|
if (!NT_SUCCESS(status)) {
|
||||||
uprintf("Could not enumerate handles: %s", NtStatusError(status));
|
uprintf("Warning: Could not enumerate process handles: %s", NtStatusError(status));
|
||||||
return FALSE;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pid[0] = (ULONG_PTR)NULL;
|
||||||
exe_path[0][0] = 0;
|
cur_pid = 1;
|
||||||
cur = 1;
|
exe[0][0] = 0;
|
||||||
|
cur_exe = 1;
|
||||||
|
|
||||||
wHandleName = utf8_to_wchar(HandleName);
|
wHandleName = utf8_to_wchar(HandleName);
|
||||||
wHandleNameLen = (USHORT) wcslen(wHandleName);
|
wHandleNameLen = (USHORT)wcslen(wHandleName);
|
||||||
|
|
||||||
bufferSize = 0x200;
|
bufferSize = 0x200;
|
||||||
buffer = PhAllocate(bufferSize);
|
buffer = PhAllocate(bufferSize);
|
||||||
|
if (buffer == NULL)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
#ifdef USE_OBJECT_TYPES
|
||||||
|
pfRtlInitUnicodeString(&fileTypeName, L"File");
|
||||||
|
fileObjectTypeIndex = PhGetObjectTypeNumber(&fileTypeName);
|
||||||
|
if (fileObjectTypeIndex < 0)
|
||||||
|
uprintf("Warning: Could not get Object Index for file types");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
for (i = 0; ; i++) {
|
for (i = 0; ; i++) {
|
||||||
ULONG attempts = 8;
|
ULONG attempts = 8;
|
||||||
|
@ -264,28 +411,53 @@ BOOL SearchProcess(char* HandleName, BOOL bPartialMatch, BOOL bIgnoreSelf)
|
||||||
pfNtClose(dupHandle);
|
pfNtClose(dupHandle);
|
||||||
dupHandle = NULL;
|
dupHandle = NULL;
|
||||||
}
|
}
|
||||||
if (processHandle != NULL) {
|
|
||||||
if (processHandle != NtCurrentProcess())
|
#ifdef USE_OBJECT_TYPES
|
||||||
pfNtClose(processHandle);
|
// Only look for File objects type
|
||||||
processHandle = NULL;
|
if ((fileObjectTypeIndex >= 0 ) && (handleInfo->ObjectTypeIndex != (USHORT)fileObjectTypeIndex))
|
||||||
|
continue;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Update the current handle's process PID and compare against last
|
||||||
|
pid[cur_pid] = handleInfo->UniqueProcessId;
|
||||||
|
|
||||||
|
if (pid[0] != pid[1]) {
|
||||||
|
cur_pid = (cur_pid + 1) % 2;
|
||||||
|
// Close the previous handle
|
||||||
|
if (processHandle != NULL) {
|
||||||
|
if (processHandle != NtCurrentProcess())
|
||||||
|
pfNtClose(processHandle);
|
||||||
|
processHandle = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CHECK_FOR_USER_CANCEL;
|
CHECK_FOR_USER_CANCEL;
|
||||||
|
|
||||||
|
// Don't bother with processes we can't access
|
||||||
|
if (handleInfo->UniqueProcessId == last_access_denied_pid)
|
||||||
|
continue;
|
||||||
|
|
||||||
// Exit loop condition
|
// Exit loop condition
|
||||||
if (i >= handles->NumberOfHandles)
|
if (i >= handles->NumberOfHandles)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Get the process that created the handle we are after
|
// Open the process to which the handle we are after belongs, if not already opened
|
||||||
// TODO: We probably should keep a list of the most recent processes and perform a lookup
|
if (pid[0] != pid[1]) {
|
||||||
// instead of Opening the process every time
|
status = PhOpenProcess(&processHandle, PROCESS_DUP_HANDLE | PROCESS_QUERY_INFORMATION,
|
||||||
status = PhOpenProcess(&processHandle, PROCESS_DUP_HANDLE | PROCESS_QUERY_INFORMATION,
|
(HANDLE)handleInfo->UniqueProcessId);
|
||||||
(HANDLE)handleInfo->UniqueProcessId);
|
// There exists some processes we can't access
|
||||||
// There exists some processes we can't access
|
if (!NT_SUCCESS(status)) {
|
||||||
if (!NT_SUCCESS(status))
|
uuprintf("SearchProcess: Could not open process %ld: %s",
|
||||||
continue;
|
handleInfo->UniqueProcessId, NtStatusError(status));
|
||||||
|
processHandle = NULL;
|
||||||
|
if (status == STATUS_ACCESS_DENIED) {
|
||||||
|
last_access_denied_pid = handleInfo->UniqueProcessId;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Must duplicate the handle onto our own process, before we can access its properties
|
// Now duplicate this handle onto our own process, so that we can access its properties
|
||||||
if (processHandle == NtCurrentProcess()) {
|
if (processHandle == NtCurrentProcess()) {
|
||||||
if (bIgnoreSelf)
|
if (bIgnoreSelf)
|
||||||
continue;
|
continue;
|
||||||
|
@ -293,7 +465,6 @@ BOOL SearchProcess(char* HandleName, BOOL bPartialMatch, BOOL bIgnoreSelf)
|
||||||
} else {
|
} else {
|
||||||
status = pfNtDuplicateObject(processHandle, (HANDLE)handleInfo->HandleValue,
|
status = pfNtDuplicateObject(processHandle, (HANDLE)handleInfo->HandleValue,
|
||||||
NtCurrentProcess(), &dupHandle, 0, 0, 0);
|
NtCurrentProcess(), &dupHandle, 0, 0, 0);
|
||||||
// Why does it always work for Process Hacker and not me???
|
|
||||||
if (!NT_SUCCESS(status))
|
if (!NT_SUCCESS(status))
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -304,18 +475,23 @@ BOOL SearchProcess(char* HandleName, BOOL bPartialMatch, BOOL bIgnoreSelf)
|
||||||
|
|
||||||
// A loop is needed because the I/O subsystem likes to give us the wrong return lengths...
|
// A loop is needed because the I/O subsystem likes to give us the wrong return lengths...
|
||||||
do {
|
do {
|
||||||
status = pfNtQueryObject(dupHandle, ObjectBasicInformation + 1,
|
ULONG returnSize;
|
||||||
buffer, bufferSize, &bufferSize);
|
status = pfNtQueryObject(dupHandle, ObjectNameInformation, buffer, bufferSize, &returnSize);
|
||||||
if (status == STATUS_BUFFER_OVERFLOW || status == STATUS_INFO_LENGTH_MISMATCH ||
|
if (status == STATUS_BUFFER_OVERFLOW || status == STATUS_INFO_LENGTH_MISMATCH ||
|
||||||
status == STATUS_BUFFER_TOO_SMALL) {
|
status == STATUS_BUFFER_TOO_SMALL) {
|
||||||
|
uuprintf("SearchProcess: Realloc from %d to %d", bufferSize, returnSize);
|
||||||
|
bufferSize = returnSize;
|
||||||
PhFree(buffer);
|
PhFree(buffer);
|
||||||
buffer = PhAllocate(bufferSize);
|
buffer = PhAllocate(bufferSize);
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} while (--attempts);
|
} while (--attempts);
|
||||||
if (!NT_SUCCESS(status))
|
if (!NT_SUCCESS(status)) {
|
||||||
|
uuprintf("SearchProcess: NtQueryObject failed for handle %X of process %ld: %s",
|
||||||
|
handleInfo->HandleValue, handleInfo->UniqueProcessId, NtStatusError(status));
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// Don't bother comparing if we are looking for full match and the length is different
|
// Don't bother comparing if we are looking for full match and the length is different
|
||||||
if ((!bPartialMatch) && (wHandleNameLen != buffer->Name.Length))
|
if ((!bPartialMatch) && (wHandleNameLen != buffer->Name.Length))
|
||||||
|
@ -335,11 +511,11 @@ BOOL SearchProcess(char* HandleName, BOOL bPartialMatch, BOOL bIgnoreSelf)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: only list processes with conflicting access rights (ignore "Read attributes" or "Synchronize")
|
// TODO: only list processes with conflicting access rights (ignore "Read attributes" or "Synchronize")
|
||||||
if (GetModuleFileNameExU(processHandle, 0, exe_path[cur], MAX_PATH - 1)) {
|
if (GetModuleFileNameExU(processHandle, 0, exe[cur_exe], MAX_PATH - 1)) {
|
||||||
// Avoid printing the same path repeatedly
|
// Avoid printing the same path repeatedly
|
||||||
if (strcmp(exe_path[0], exe_path[1]) != 0) {
|
if (strcmp(exe[0], exe[1]) != 0) {
|
||||||
uprintf("o %s", exe_path[cur]);
|
uprintf("o %s", exe[cur_exe]);
|
||||||
cur = (cur + 1) % 2;
|
cur_exe = (cur_exe + 1) % 2;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
uprintf("o Unknown (Process ID %d)", GetProcessId(processHandle));
|
uprintf("o Unknown (Process ID %d)", GetProcessId(processHandle));
|
||||||
|
@ -354,5 +530,7 @@ out:
|
||||||
|
|
||||||
free(wHandleName);
|
free(wHandleName);
|
||||||
PhFree(buffer);
|
PhFree(buffer);
|
||||||
|
PhFree(handles);
|
||||||
|
PhDestroyHeap();
|
||||||
return bFound;
|
return bFound;
|
||||||
}
|
}
|
||||||
|
|
60
src/search.h
60
src/search.h
|
@ -30,6 +30,8 @@
|
||||||
|
|
||||||
#define PH_LARGE_BUFFER_SIZE (256 * 1024 * 1024)
|
#define PH_LARGE_BUFFER_SIZE (256 * 1024 * 1024)
|
||||||
|
|
||||||
|
#define STATUS_SUCCESS ((NTSTATUS)0x00000000L)
|
||||||
|
#define STATUS_ALREADY_COMPLETE ((NTSTATUS)0x000000FFL)
|
||||||
#define STATUS_UNSUCCESSFUL ((NTSTATUS)0x80000001L)
|
#define STATUS_UNSUCCESSFUL ((NTSTATUS)0x80000001L)
|
||||||
#define STATUS_BUFFER_OVERFLOW ((NTSTATUS)0x80000005L)
|
#define STATUS_BUFFER_OVERFLOW ((NTSTATUS)0x80000005L)
|
||||||
#define STATUS_NOT_IMPLEMENTED ((NTSTATUS)0xC0000002L)
|
#define STATUS_NOT_IMPLEMENTED ((NTSTATUS)0xC0000002L)
|
||||||
|
@ -40,6 +42,7 @@
|
||||||
#define STATUS_OBJECT_TYPE_MISMATCH ((NTSTATUS)0xC0000024L)
|
#define STATUS_OBJECT_TYPE_MISMATCH ((NTSTATUS)0xC0000024L)
|
||||||
#define STATUS_OBJECT_NAME_INVALID ((NTSTATUS)0xC0000033L)
|
#define STATUS_OBJECT_NAME_INVALID ((NTSTATUS)0xC0000033L)
|
||||||
#define STATUS_OBJECT_NAME_NOT_FOUND ((NTSTATUS)0xC0000034L)
|
#define STATUS_OBJECT_NAME_NOT_FOUND ((NTSTATUS)0xC0000034L)
|
||||||
|
#define STATUS_OBJECT_PATH_INVALID ((NTSTATUS)0xC0000039L)
|
||||||
#define STATUS_SHARING_VIOLATION ((NTSTATUS)0xC0000043L)
|
#define STATUS_SHARING_VIOLATION ((NTSTATUS)0xC0000043L)
|
||||||
#define STATUS_INSUFFICIENT_RESOURCES ((NTSTATUS)0xC000009AL)
|
#define STATUS_INSUFFICIENT_RESOURCES ((NTSTATUS)0xC000009AL)
|
||||||
#define STATUS_NOT_SUPPORTED ((NTSTATUS)0xC00000BBL)
|
#define STATUS_NOT_SUPPORTED ((NTSTATUS)0xC00000BBL)
|
||||||
|
@ -78,8 +81,62 @@ typedef struct _CLIENT_ID
|
||||||
HANDLE UniqueProcess;
|
HANDLE UniqueProcess;
|
||||||
HANDLE UniqueThread;
|
HANDLE UniqueThread;
|
||||||
} CLIENT_ID, *PCLIENT_ID;
|
} CLIENT_ID, *PCLIENT_ID;
|
||||||
|
|
||||||
|
typedef struct _OBJECT_TYPE_INFORMATION
|
||||||
|
{
|
||||||
|
UNICODE_STRING TypeName;
|
||||||
|
ULONG TotalNumberOfObjects;
|
||||||
|
ULONG TotalNumberOfHandles;
|
||||||
|
ULONG TotalPagedPoolUsage;
|
||||||
|
ULONG TotalNonPagedPoolUsage;
|
||||||
|
ULONG TotalNamePoolUsage;
|
||||||
|
ULONG TotalHandleTableUsage;
|
||||||
|
ULONG HighWaterNumberOfObjects;
|
||||||
|
ULONG HighWaterNumberOfHandles;
|
||||||
|
ULONG HighWaterPagedPoolUsage;
|
||||||
|
ULONG HighWaterNonPagedPoolUsage;
|
||||||
|
ULONG HighWaterNamePoolUsage;
|
||||||
|
ULONG HighWaterHandleTableUsage;
|
||||||
|
ULONG InvalidAttributes;
|
||||||
|
GENERIC_MAPPING GenericMapping;
|
||||||
|
ULONG ValidAccessMask;
|
||||||
|
BOOLEAN SecurityRequired;
|
||||||
|
BOOLEAN MaintainHandleCount;
|
||||||
|
UCHAR TypeIndex; // since WINBLUE
|
||||||
|
CHAR ReservedByte;
|
||||||
|
ULONG PoolType;
|
||||||
|
ULONG DefaultPagedPoolCharge;
|
||||||
|
ULONG DefaultNonPagedPoolCharge;
|
||||||
|
} OBJECT_TYPE_INFORMATION, *POBJECT_TYPE_INFORMATION;
|
||||||
|
|
||||||
|
typedef enum _MY_OBJECT_INFORMATION_CLASS
|
||||||
|
{
|
||||||
|
_ObjectBasicInformation, // OBJECT_BASIC_INFORMATION
|
||||||
|
ObjectNameInformation, // OBJECT_NAME_INFORMATION
|
||||||
|
_ObjectTypeInformation, // OBJECT_TYPE_INFORMATION
|
||||||
|
ObjectTypesInformation, // OBJECT_TYPES_INFORMATION
|
||||||
|
ObjectHandleFlagInformation, // OBJECT_HANDLE_FLAG_INFORMATION
|
||||||
|
ObjectSessionInformation,
|
||||||
|
ObjectSessionObjectInformation,
|
||||||
|
MaxObjectInfoClass
|
||||||
|
} MY_OBJECT_INFORMATION_CLASS;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
typedef struct _OBJECT_TYPES_INFORMATION
|
||||||
|
{
|
||||||
|
ULONG NumberOfTypes;
|
||||||
|
} OBJECT_TYPES_INFORMATION, *POBJECT_TYPES_INFORMATION;
|
||||||
|
|
||||||
|
#define ALIGN_UP_BY(Address, Align) (((ULONG_PTR)(Address) + (Align) - 1) & ~((Align) - 1))
|
||||||
|
#define ALIGN_UP(Address, Type) ALIGN_UP_BY(Address, sizeof(Type))
|
||||||
|
|
||||||
|
#define PH_FIRST_OBJECT_TYPE(ObjectTypes) \
|
||||||
|
(POBJECT_TYPE_INFORMATION)((PCHAR)(ObjectTypes) + ALIGN_UP(sizeof(OBJECT_TYPES_INFORMATION), ULONG_PTR))
|
||||||
|
|
||||||
|
#define PH_NEXT_OBJECT_TYPE(ObjectType) \
|
||||||
|
(POBJECT_TYPE_INFORMATION)((PCHAR)(ObjectType) + sizeof(OBJECT_TYPE_INFORMATION) + \
|
||||||
|
ALIGN_UP(ObjectType->TypeName.MaximumLength, ULONG_PTR))
|
||||||
|
|
||||||
// Heaps
|
// Heaps
|
||||||
|
|
||||||
typedef struct _RTL_HEAP_ENTRY
|
typedef struct _RTL_HEAP_ENTRY
|
||||||
|
@ -184,3 +241,6 @@ typedef struct _RTL_HEAP_PARAMETERS
|
||||||
#define HEAP_CLASS_7 0x00007000 // CSR shared heap
|
#define HEAP_CLASS_7 0x00007000 // CSR shared heap
|
||||||
#define HEAP_CLASS_8 0x00008000 // CSR port heap
|
#define HEAP_CLASS_8 0x00008000 // CSR port heap
|
||||||
#define HEAP_CLASS_MASK 0x0000f000
|
#define HEAP_CLASS_MASK 0x0000f000
|
||||||
|
|
||||||
|
#define PF_INIT_OR_SET_STATUS(proc, name) do {PF_INIT(proc, name); \
|
||||||
|
if (pf##proc == NULL) status = STATUS_NOT_IMPLEMENTED; } while(0)
|
||||||
|
|
|
@ -32,7 +32,6 @@
|
||||||
|
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
|
|
||||||
extern BOOL usb_debug; // For uuprintf
|
|
||||||
int nWindowsVersion = WINDOWS_UNDEFINED;
|
int nWindowsVersion = WINDOWS_UNDEFINED;
|
||||||
int nWindowsBuildNumber = -1;
|
int nWindowsBuildNumber = -1;
|
||||||
char WindowsVersionStr[128] = "Windows ";
|
char WindowsVersionStr[128] = "Windows ";
|
||||||
|
|
Loading…
Reference in a new issue