diff --git a/kdstinker.sys b/kdstinker.sys index 4e077fd..8c30289 100644 Binary files a/kdstinker.sys and b/kdstinker.sys differ diff --git a/kdstinker/callback.h b/kdstinker/callback.h index fc4beb7..a4ce725 100644 --- a/kdstinker/callback.h +++ b/kdstinker/callback.h @@ -9,14 +9,4 @@ namespace callback HANDLE pid, PIMAGE_INFO image_info ); - - NTSTATUS gh_create_device( - PDRIVER_OBJECT driver_obj, - ULONG device_ext, - PUNICODE_STRING device_name, - DEVICE_TYPE device_type, - ULONG device_char, - BOOLEAN exclusive, - PDEVICE_OBJECT* lpdevice_obj - ); } \ No newline at end of file diff --git a/kdstinker/driver_util.cpp b/kdstinker/driver_util.cpp index bffb952..79665cb 100644 --- a/kdstinker/driver_util.cpp +++ b/kdstinker/driver_util.cpp @@ -150,6 +150,178 @@ namespace driver_util return NULL; } + PDRIVER_OBJECT get_drv_obj(PUNICODE_STRING driver_name) + { + HANDLE handle{}; + OBJECT_ATTRIBUTES attributes{}; + UNICODE_STRING directory_name{}; + PVOID directory{}; + BOOLEAN success = FALSE; + + RtlInitUnicodeString(&directory_name, L"\\Driver"); + InitializeObjectAttributes( + &attributes, + &directory_name, + OBJ_CASE_INSENSITIVE, + NULL, + NULL + ); + + // open OBJECT_DIRECTORY for \\Driver + auto status = ZwOpenDirectoryObject( + &handle, + DIRECTORY_ALL_ACCESS, + &attributes + ); + + if (!NT_SUCCESS(status)) + { + DBG_PRINT("ZwOpenDirectoryObject Failed"); + return NULL; + } + + // Get OBJECT_DIRECTORY pointer from HANDLE + status = ObReferenceObjectByHandle( + handle, + DIRECTORY_ALL_ACCESS, + nullptr, + KernelMode, + &directory, + nullptr + ); + + if (!NT_SUCCESS(status)) + { + DBG_PRINT("ObReferenceObjectByHandle Failed"); + ZwClose(handle); + return NULL; + } + + const auto directory_object = POBJECT_DIRECTORY(directory); + if (!directory_object) + return NULL; + + ExAcquirePushLockExclusiveEx(&directory_object->Lock, 0); + + // traverse hash table with 37 entries + // when a new object is created, the object manager computes a hash value in the range zero to 36 from the object name and creates an OBJECT_DIRECTORY_ENTRY. + // http://www.informit.com/articles/article.aspx?p=22443&seqNum=7 + for (auto entry : directory_object->HashBuckets) + { + if (!entry) + continue; + + while (entry && entry->Object) + { + auto driver = PDRIVER_OBJECT(entry->Object); + if (!driver) + continue; + + if (wcscmp(driver->DriverExtension->ServiceKeyName.Buffer, driver_name->Buffer) == 0) + return driver; + } + } + + ExReleasePushLockExclusiveEx(&directory_object->Lock, 0); + // Release the acquired resources back to the OS + ObDereferenceObject(directory); + ZwClose(handle); + //TODO remove + return NULL; + } + + void copy_driver(PUNICODE_STRING image_path) + { + HANDLE h_file; + OBJECT_ATTRIBUTES attr; + IO_STATUS_BLOCK status_block; + LARGE_INTEGER offset; + UNICODE_STRING name; + FILE_STANDARD_INFORMATION standard_info; + + RtlZeroMemory(&standard_info, sizeof(standard_info)); + InitializeObjectAttributes( + &attr, + image_path, + OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, + NULL, NULL + ); + + NTSTATUS status = ZwCreateFile( + &h_file, + GENERIC_READ, + &attr, + &status_block, + NULL, + FILE_ATTRIBUTE_NORMAL, + NULL, + FILE_OPEN_IF, + FILE_SYNCHRONOUS_IO_NONALERT, + NULL, + NULL + ); + + ZwQueryInformationFile( + h_file, + &status_block, + &standard_info, + sizeof(FILE_STANDARD_INFORMATION), + FileStandardInformation + ); + + void* drv_buffer = ExAllocatePool( + NonPagedPool, + standard_info.AllocationSize.QuadPart + ); + + status = ZwReadFile( + h_file, + NULL, + NULL, + NULL, + &status_block, + drv_buffer, + standard_info.AllocationSize.QuadPart, + &offset, + NULL + ); + + RtlInitUnicodeString(&name, L"\\DosDevices\\C:\\last_load_drv.sys"); + InitializeObjectAttributes(&attr, &name, + OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, + NULL, NULL + ); + + ZwCreateFile( + &h_file, + GENERIC_WRITE, + &attr, + &status_block, + NULL, + FILE_ATTRIBUTE_NORMAL, + NULL, + FILE_OVERWRITE_IF, + FILE_SYNCHRONOUS_IO_NONALERT, + NULL, + NULL + ); + + ZwWriteFile( + h_file, + NULL, + NULL, + NULL, + &status_block, + drv_buffer, + standard_info.AllocationSize.QuadPart, + &offset, + NULL + ); + + ZwClose(h_file); + ExFreePool(drv_buffer); + } + void mem_dump(void* base_addr, unsigned len) { if (!base_addr || !len) diff --git a/kdstinker/driver_util.h b/kdstinker/driver_util.h index 6d4564b..a99e7a1 100644 --- a/kdstinker/driver_util.h +++ b/kdstinker/driver_util.h @@ -7,5 +7,7 @@ namespace driver_util void* iat_hook(void* base_addr, const char* import, void* func_addr); void mem_dump(void* base_addr, unsigned len); void* get_kmode_export(const char* mod_name, const char* proc_name); + void copy_driver(PUNICODE_STRING image_path); + PDRIVER_OBJECT get_drv_obj(PUNICODE_STRING driver_name); PIMAGE_FILE_HEADER get_file_header(void* base_addr); } \ No newline at end of file diff --git a/kdstinker/types.h b/kdstinker/types.h index c73bbf1..7238ef8 100644 --- a/kdstinker/types.h +++ b/kdstinker/types.h @@ -45,6 +45,23 @@ RtlFindExportedRoutineByName( _In_ PCCH RoutineName ); +typedef struct _OBJECT_DIRECTORY_ENTRY +{ + _OBJECT_DIRECTORY_ENTRY* ChainLink; + PVOID Object; + ULONG HashValue; +} OBJECT_DIRECTORY_ENTRY, * POBJECT_DIRECTORY_ENTRY; + +typedef struct _OBJECT_DIRECTORY +{ + POBJECT_DIRECTORY_ENTRY HashBuckets[37]; + EX_PUSH_LOCK Lock; + void* DeviceMap; + ULONG SessionId; + PVOID NamespaceEntry; + ULONG Flags; +} OBJECT_DIRECTORY, * POBJECT_DIRECTORY; + typedef struct _COPY_MEMORY_BUFFER_INFO { uint64_t case_number;