From d8d809f93b50d5d3e49eb99a2e737bc16813bd5a Mon Sep 17 00:00:00 2001 From: xerox Date: Wed, 27 May 2020 22:14:05 -0700 Subject: [PATCH] v1.0 --- kdstinker.sln | 51 ++++++ kdstinker.sys | Bin 0 -> 11528 bytes kdstinker/callback.cpp | 62 +++++++ kdstinker/callback.h | 22 +++ kdstinker/driver_util.cpp | 197 ++++++++++++++++++++++ kdstinker/driver_util.h | 11 ++ kdstinker/hooks.cpp | 53 ++++++ kdstinker/hooks.h | 12 ++ kdstinker/kdstinker.vcxproj | 240 ++++++++++++++++++++++++++ kdstinker/kdstinker.vcxproj.filters | 41 +++++ kdstinker/main.cpp | 39 +++++ kdstinker/types.h | 250 ++++++++++++++++++++++++++++ 12 files changed, 978 insertions(+) create mode 100644 kdstinker.sln create mode 100644 kdstinker.sys create mode 100644 kdstinker/callback.cpp create mode 100644 kdstinker/callback.h create mode 100644 kdstinker/driver_util.cpp create mode 100644 kdstinker/driver_util.h create mode 100644 kdstinker/hooks.cpp create mode 100644 kdstinker/hooks.h create mode 100644 kdstinker/kdstinker.vcxproj create mode 100644 kdstinker/kdstinker.vcxproj.filters create mode 100644 kdstinker/main.cpp create mode 100644 kdstinker/types.h diff --git a/kdstinker.sln b/kdstinker.sln new file mode 100644 index 0000000..22f18cf --- /dev/null +++ b/kdstinker.sln @@ -0,0 +1,51 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30011.22 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "kdstinker", "kdstinker\kdstinker.vcxproj", "{30E2F686-FC9D-4A2E-8AD2-FD8E9E5229E1}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|ARM = Debug|ARM + Debug|ARM64 = Debug|ARM64 + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|ARM = Release|ARM + Release|ARM64 = Release|ARM64 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {30E2F686-FC9D-4A2E-8AD2-FD8E9E5229E1}.Debug|ARM.ActiveCfg = Debug|ARM + {30E2F686-FC9D-4A2E-8AD2-FD8E9E5229E1}.Debug|ARM.Build.0 = Debug|ARM + {30E2F686-FC9D-4A2E-8AD2-FD8E9E5229E1}.Debug|ARM.Deploy.0 = Debug|ARM + {30E2F686-FC9D-4A2E-8AD2-FD8E9E5229E1}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {30E2F686-FC9D-4A2E-8AD2-FD8E9E5229E1}.Debug|ARM64.Build.0 = Debug|ARM64 + {30E2F686-FC9D-4A2E-8AD2-FD8E9E5229E1}.Debug|ARM64.Deploy.0 = Debug|ARM64 + {30E2F686-FC9D-4A2E-8AD2-FD8E9E5229E1}.Debug|x64.ActiveCfg = Debug|x64 + {30E2F686-FC9D-4A2E-8AD2-FD8E9E5229E1}.Debug|x64.Build.0 = Debug|x64 + {30E2F686-FC9D-4A2E-8AD2-FD8E9E5229E1}.Debug|x64.Deploy.0 = Debug|x64 + {30E2F686-FC9D-4A2E-8AD2-FD8E9E5229E1}.Debug|x86.ActiveCfg = Debug|Win32 + {30E2F686-FC9D-4A2E-8AD2-FD8E9E5229E1}.Debug|x86.Build.0 = Debug|Win32 + {30E2F686-FC9D-4A2E-8AD2-FD8E9E5229E1}.Debug|x86.Deploy.0 = Debug|Win32 + {30E2F686-FC9D-4A2E-8AD2-FD8E9E5229E1}.Release|ARM.ActiveCfg = Release|ARM + {30E2F686-FC9D-4A2E-8AD2-FD8E9E5229E1}.Release|ARM.Build.0 = Release|ARM + {30E2F686-FC9D-4A2E-8AD2-FD8E9E5229E1}.Release|ARM.Deploy.0 = Release|ARM + {30E2F686-FC9D-4A2E-8AD2-FD8E9E5229E1}.Release|ARM64.ActiveCfg = Release|ARM64 + {30E2F686-FC9D-4A2E-8AD2-FD8E9E5229E1}.Release|ARM64.Build.0 = Release|ARM64 + {30E2F686-FC9D-4A2E-8AD2-FD8E9E5229E1}.Release|ARM64.Deploy.0 = Release|ARM64 + {30E2F686-FC9D-4A2E-8AD2-FD8E9E5229E1}.Release|x64.ActiveCfg = Release|x64 + {30E2F686-FC9D-4A2E-8AD2-FD8E9E5229E1}.Release|x64.Build.0 = Release|x64 + {30E2F686-FC9D-4A2E-8AD2-FD8E9E5229E1}.Release|x64.Deploy.0 = Release|x64 + {30E2F686-FC9D-4A2E-8AD2-FD8E9E5229E1}.Release|x86.ActiveCfg = Release|Win32 + {30E2F686-FC9D-4A2E-8AD2-FD8E9E5229E1}.Release|x86.Build.0 = Release|Win32 + {30E2F686-FC9D-4A2E-8AD2-FD8E9E5229E1}.Release|x86.Deploy.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {7DEC848B-E4D5-4C7F-A4B8-55379682BBDE} + EndGlobalSection +EndGlobal diff --git a/kdstinker.sys b/kdstinker.sys new file mode 100644 index 0000000000000000000000000000000000000000..4e077fd72e925cc4556c1cbe1a85978b2712c888 GIT binary patch literal 11528 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 QWQg=;r>Uo-_G8R{0Rrs7k^lez literal 0 HcmV?d00001 diff --git a/kdstinker/callback.cpp b/kdstinker/callback.cpp new file mode 100644 index 0000000..509dc8b --- /dev/null +++ b/kdstinker/callback.cpp @@ -0,0 +1,62 @@ +#include "callback.h" +#include "hooks.h" + +namespace callback +{ + 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 + ) + { + DBG_PRINT("=============== IoCreateDevice Called ==============="); + DBG_PRINT(" - driver object: 0x%p", driver_obj); + + // + // swap ioctl pointer + // + hooks::orig_device_control = driver_obj->MajorFunction[IRP_MJ_DEVICE_CONTROL]; + driver_obj->MajorFunction[IRP_MJ_DEVICE_CONTROL] = &hooks::device_control; + + DBG_PRINT(" - swapped ioctl function from 0x%p to 0x%p", driver_obj->MajorFunction[IRP_MJ_DEVICE_CONTROL], &hooks::device_control); + return IoCreateDevice( + driver_obj, + device_ext, + device_name, + device_type, + device_char, + exclusive, + lpdevice_obj + ); + } + + void on_image_load( + PUNICODE_STRING image_path, + HANDLE pid, + PIMAGE_INFO image_info + ) + { + if (!pid) + { + DBG_PRINT("driver loaded from: %ws", image_path->Buffer); + DBG_PRINT(" - driver timestamp: 0x%p", driver_util::get_file_header(image_info->ImageBase)->TimeDateStamp); + + // + // if its intel lan driver then we hook IoCreateDevice and swap ioctl pointer. + // + if (driver_util::get_file_header(image_info->ImageBase)->TimeDateStamp == INTEL_LAN_DRIVER_TIMESTAMP) + { + DBG_PRINT("=============== Intel Lan Driver Loaded ==============="); + driver_util::iat_hook( + image_info->ImageBase, + "IoCreateDevice", + &gh_create_device + ); + } + } + } +} \ No newline at end of file diff --git a/kdstinker/callback.h b/kdstinker/callback.h new file mode 100644 index 0000000..fc4beb7 --- /dev/null +++ b/kdstinker/callback.h @@ -0,0 +1,22 @@ +#pragma once +#include "types.h" +#include "driver_util.h" + +namespace callback +{ + void on_image_load( + PUNICODE_STRING image_path, + 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 new file mode 100644 index 0000000..bffb952 --- /dev/null +++ b/kdstinker/driver_util.cpp @@ -0,0 +1,197 @@ +#include "driver_util.h" + +namespace driver_util +{ + void* get_driver_base(const char* module_name) + { + ULONG bytes{}; + NTSTATUS status = ZwQuerySystemInformation( + SystemModuleInformation, + NULL, + bytes, + &bytes + ); + + if (!bytes) + return NULL; + PRTL_PROCESS_MODULES modules = + (PRTL_PROCESS_MODULES)ExAllocatePool(NonPagedPool, bytes); + + if (modules) + { + status = ZwQuerySystemInformation( + SystemModuleInformation, + modules, + bytes, + &bytes + ); + + if (!NT_SUCCESS(status)) + { + ExFreePool(modules); + return NULL; + } + + PRTL_PROCESS_MODULE_INFORMATION module = modules->Modules; + PVOID module_base{}, module_size{}; + for (ULONG i = 0; i < modules->NumberOfModules; i++) + { + if (strcmp(reinterpret_cast(module[i].FullPathName + module[i].OffsetToFileName), module_name) == 0) + { + module_base = module[i].ImageBase; + module_size = (PVOID)module[i].ImageSize; + break; + } + } + ExFreePool(modules); + return module_base; + } + return NULL; + } + + void* get_kmode_export(const char* mod_name, const char* proc_name) + { + if (!mod_name || !proc_name) + return NULL; + + void* result = get_driver_base(mod_name); + if (!result) + return NULL; + return RtlFindExportedRoutineByName(result, proc_name); + } + + PIMAGE_FILE_HEADER get_file_header(void* base_addr) + { + if (!base_addr || *(short*)base_addr != 0x5A4D) + return NULL; + + PIMAGE_DOS_HEADER dos_headers = + reinterpret_cast(base_addr); + + PIMAGE_NT_HEADERS nt_headers = + reinterpret_cast( + reinterpret_cast(base_addr) + dos_headers->e_lfanew); + + return &nt_headers->FileHeader; + } + + void* iat_hook(void* base_addr, const char* import, void* func_addr) + { + if (!base_addr || *(short*)base_addr != 0x5A4D || !import || !func_addr) + return NULL; + + PIMAGE_DOS_HEADER dos_headers = + reinterpret_cast(base_addr); + + PIMAGE_NT_HEADERS nt_headers = + reinterpret_cast( + reinterpret_cast(base_addr) + dos_headers->e_lfanew); + + IMAGE_DATA_DIRECTORY import_dir = + nt_headers->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT]; + + PIMAGE_IMPORT_DESCRIPTOR import_des = + reinterpret_cast(import_dir.VirtualAddress + (DWORD_PTR)base_addr); + + LPCSTR lib_name = NULL; + PVOID result = NULL; + PIMAGE_IMPORT_BY_NAME func_name = NULL; + + if (!import_des) + return NULL; + + while (import_des->Name != NULL) + { + lib_name = (LPCSTR)import_des->Name + (DWORD_PTR)base_addr; + + if (get_driver_base(lib_name)) + { + PIMAGE_THUNK_DATA org_first_thunk = NULL, first_thunk = NULL; + org_first_thunk = (PIMAGE_THUNK_DATA)((DWORD_PTR)base_addr + import_des->OriginalFirstThunk); + first_thunk = (PIMAGE_THUNK_DATA)((DWORD_PTR)base_addr + import_des->FirstThunk); + while (org_first_thunk->u1.AddressOfData != NULL) + { + func_name = (PIMAGE_IMPORT_BY_NAME)((DWORD_PTR)base_addr + org_first_thunk->u1.AddressOfData); + if (strcmp(func_name->Name, import) == 0) + { + // save old function pointer + result = reinterpret_cast(first_thunk->u1.Function); + + { + // + // disable write protection + // + auto cr0 = __readcr0(); + cr0 &= 0xfffffffffffeffff; + __writecr0(cr0); + _disable(); + } + + // swap address + first_thunk->u1.Function = reinterpret_cast(func_addr); + + { + // + // enable write protection + // + auto cr0 = __readcr0(); + cr0 |= 0x10000; + _enable(); + __writecr0(cr0); + } + return result; + } + ++org_first_thunk; + ++first_thunk; + } + } + ++import_des; + } + return NULL; + } + + void mem_dump(void* base_addr, unsigned len) + { + if (!base_addr || !len) + return; + + HANDLE h_file; + UNICODE_STRING name; + OBJECT_ATTRIBUTES attr; + IO_STATUS_BLOCK status_block; + LARGE_INTEGER offset{ NULL }; + + RtlInitUnicodeString(&name, L"\\DosDevices\\C:\\dump.bin"); + InitializeObjectAttributes(&attr, &name, + OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, + NULL, NULL + ); + + auto status = ZwCreateFile( + &h_file, + GENERIC_WRITE, + &attr, + &status_block, + NULL, + FILE_ATTRIBUTE_NORMAL, + NULL, + FILE_OVERWRITE_IF, + FILE_SYNCHRONOUS_IO_NONALERT, + NULL, + NULL + ); + + status = ZwWriteFile( + h_file, + NULL, + NULL, + NULL, + &status_block, + base_addr, + len, + &offset, + NULL + ); + ZwClose(h_file); + } +} \ No newline at end of file diff --git a/kdstinker/driver_util.h b/kdstinker/driver_util.h new file mode 100644 index 0000000..6d4564b --- /dev/null +++ b/kdstinker/driver_util.h @@ -0,0 +1,11 @@ +#pragma once +#include "types.h" + +namespace driver_util +{ + void* get_driver_base(const char* module_name); + 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); + PIMAGE_FILE_HEADER get_file_header(void* base_addr); +} \ No newline at end of file diff --git a/kdstinker/hooks.cpp b/kdstinker/hooks.cpp new file mode 100644 index 0000000..97a5e4f --- /dev/null +++ b/kdstinker/hooks.cpp @@ -0,0 +1,53 @@ +#include "hooks.h" + +namespace hooks +{ + NTSTATUS device_control( + PDEVICE_OBJECT device_obj, + PIRP irp + ) + { + UNREFERENCED_PARAMETER(device_obj); + PIO_STACK_LOCATION stack_location = IoGetCurrentIrpStackLocation(irp); + + if (stack_location->Parameters.DeviceIoControl.IoControlCode == INTEL_LAN_DRIVER_IOCTL) + { + if (stack_location->Parameters.DeviceIoControl.InputBufferLength) + { + PCOPY_MEMORY_BUFFER_INFO copy_memory_buffer = reinterpret_cast(stack_location->Parameters.SetFile.DeleteHandle); + + // + // if case is memmove and the destination is in the kernel (pml4 index is > 255) + // + if (copy_memory_buffer->case_number == INTEL_LAN_COPY_CASE_NUMBER) + { + if (virt_addr_t{ copy_memory_buffer->destination }.pml4_index > 255) + { + // + // there are a few writes of size 0xC (inline jump code) we can skip those. + // + if (copy_memory_buffer->length > 0x20) + { + DBG_PRINT("=============== Dumping Memory =============="); + DBG_PRINT( + "Copying memory from 0x%p to 0x%p of size 0x%x", + copy_memory_buffer->source, + copy_memory_buffer->destination, + copy_memory_buffer->length + ); + + // + // dump memory from inside of the PE to disk. + // + driver_util::mem_dump( + copy_memory_buffer->source, + copy_memory_buffer->length + ); + } + } + } + } + } + return reinterpret_cast(orig_device_control)(device_obj, irp); + } +} \ No newline at end of file diff --git a/kdstinker/hooks.h b/kdstinker/hooks.h new file mode 100644 index 0000000..c151e23 --- /dev/null +++ b/kdstinker/hooks.h @@ -0,0 +1,12 @@ +#pragma once +#include "types.h" +#include "driver_util.h" + +namespace hooks +{ + inline void* orig_device_control = NULL; + NTSTATUS device_control( + PDEVICE_OBJECT device_obj, + PIRP irp + ); +} \ No newline at end of file diff --git a/kdstinker/kdstinker.vcxproj b/kdstinker/kdstinker.vcxproj new file mode 100644 index 0000000..9084ab7 --- /dev/null +++ b/kdstinker/kdstinker.vcxproj @@ -0,0 +1,240 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + Debug + ARM + + + Release + ARM + + + Debug + ARM64 + + + Release + ARM64 + + + + {30E2F686-FC9D-4A2E-8AD2-FD8E9E5229E1} + {1bc93793-694f-48fe-9372-81e2b05556fd} + v4.5 + 12.0 + Debug + Win32 + kdstinker + $(LatestTargetPlatformVersion) + + + + Windows10 + true + WindowsKernelModeDriver10.0 + Driver + KMDF + Universal + false + + + Windows10 + false + WindowsKernelModeDriver10.0 + Driver + KMDF + Universal + false + + + Windows10 + true + WindowsKernelModeDriver10.0 + Driver + KMDF + Universal + false + + + Windows10 + false + WindowsKernelModeDriver10.0 + Driver + KMDF + Universal + false + + + Windows10 + true + WindowsKernelModeDriver10.0 + Driver + KMDF + Universal + false + + + Windows10 + false + WindowsKernelModeDriver10.0 + Driver + KMDF + Universal + false + + + Windows10 + true + WindowsKernelModeDriver10.0 + Driver + KMDF + Universal + + + Windows10 + false + WindowsKernelModeDriver10.0 + Driver + KMDF + Universal + + + + + + + + + + + DbgengKernelDebugger + + + DbgengKernelDebugger + + + DbgengKernelDebugger + + + DbgengKernelDebugger + + + DbgengKernelDebugger + + + DbgengKernelDebugger + + + DbgengKernelDebugger + + + DbgengKernelDebugger + + + + driver_entry + + + stdcpp17 + false + + + + + driver_entry + + + stdcpp17 + false + + + + + driver_entry + + + stdcpp17 + false + + + + + driver_entry + + + stdcpp17 + false + + + + + driver_entry + + + stdcpp17 + false + + + + + driver_entry + + + stdcpp17 + false + + + + + driver_entry + + + stdcpp17 + false + + + + + driver_entry + + + stdcpp17 + false + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/kdstinker/kdstinker.vcxproj.filters b/kdstinker/kdstinker.vcxproj.filters new file mode 100644 index 0000000..65f626e --- /dev/null +++ b/kdstinker/kdstinker.vcxproj.filters @@ -0,0 +1,41 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + \ No newline at end of file diff --git a/kdstinker/main.cpp b/kdstinker/main.cpp new file mode 100644 index 0000000..738f193 --- /dev/null +++ b/kdstinker/main.cpp @@ -0,0 +1,39 @@ +#include "types.h" +#include "callback.h" + +void driver_unload( + DRIVER_OBJECT* driver_obj +) +{ + UNREFERENCED_PARAMETER(driver_obj); + PsRemoveLoadImageNotifyRoutine(&callback::on_image_load); +} + +NTSTATUS driver_close( + IN PDEVICE_OBJECT device_obj, + IN PIRP lp_irp +) +{ + UNREFERENCED_PARAMETER(device_obj); + lp_irp->IoStatus.Status = STATUS_SUCCESS; + lp_irp->IoStatus.Information = NULL; + IoCompleteRequest(lp_irp, IO_NO_INCREMENT); + return STATUS_SUCCESS; +} + +// +// This driver is not to be manually mapped in its current form. +// If you choose to manually map this driver please remove "driver_close" and "driver_unload". +// +NTSTATUS __cdecl driver_entry( + _In_ PDRIVER_OBJECT driver_obj, + _In_ PUNICODE_STRING reg_path +) +{ + UNREFERENCED_PARAMETER(reg_path); + driver_obj->MajorFunction[IRP_MJ_CLOSE] = &driver_close; + driver_obj->DriverUnload = &driver_unload; + + DBG_PRINT("callbacks registered, waiting for intel lan driver...."); + return PsSetLoadImageNotifyRoutine(&callback::on_image_load); +} \ No newline at end of file diff --git a/kdstinker/types.h b/kdstinker/types.h new file mode 100644 index 0000000..c73bbf1 --- /dev/null +++ b/kdstinker/types.h @@ -0,0 +1,250 @@ +#pragma once +#include +#include + +#if true +#define DBG_PRINT(...) DbgPrintEx( DPFLTR_SYSTEM_ID, DPFLTR_ERROR_LEVEL, "[kdstinker]" __VA_ARGS__); +#else +#define DBG_PRINT(...) +#endif + +#ifndef DWORD +#define DWORD unsigned +#endif + +#ifndef WORD +#define WORD unsigned short +#endif + +#ifndef uint64_t +#define uint64_t ULONGLONG +#endif + +#ifndef uint32_t +#define uint32_t DWORD +#endif + +#define IMAGE_DIRECTORY_ENTRY_IMPORT 1 // Import Directory + +#define INTEL_LAN_DRIVER_TIMESTAMP 0x5284EAC3 +#define INTEL_LAN_DRIVER_IOCTL 0x80862007 +#define INTEL_LAN_COPY_CASE_NUMBER 0x33 + +extern "C" NTSTATUS ZwQuerySystemInformation( + ULONG InfoClass, + PVOID Buffer, + ULONG Length, + PULONG ReturnLength +); + +extern "C" NTKERNELAPI +PVOID +NTAPI +RtlFindExportedRoutineByName( + _In_ PVOID ImageBase, + _In_ PCCH RoutineName +); + +typedef struct _COPY_MEMORY_BUFFER_INFO +{ + uint64_t case_number; + uint64_t reserved; + void* source; + void* destination; + uint64_t length; +}COPY_MEMORY_BUFFER_INFO, * PCOPY_MEMORY_BUFFER_INFO; + +typedef struct _FILL_MEMORY_BUFFER_INFO +{ + uint64_t case_number; + uint64_t reserved1; + uint32_t value; + uint32_t reserved2; + uint64_t destination; + uint64_t length; +}FILL_MEMORY_BUFFER_INFO, * PFILL_MEMORY_BUFFER_INFO; + +typedef struct _GET_PHYS_ADDRESS_BUFFER_INFO +{ + uint64_t case_number; + uint64_t reserved; + uint64_t return_physical_address; + uint64_t address_to_translate; +}GET_PHYS_ADDRESS_BUFFER_INFO, * PGET_PHYS_ADDRESS_BUFFER_INFO; + +typedef struct _MAP_IO_SPACE_BUFFER_INFO +{ + uint64_t case_number; + uint64_t reserved; + uint64_t return_value; + uint64_t return_virtual_address; + uint64_t physical_address_to_map; + uint32_t size; +}MAP_IO_SPACE_BUFFER_INFO, * PMAP_IO_SPACE_BUFFER_INFO; + +typedef struct _UNMAP_IO_SPACE_BUFFER_INFO +{ + uint64_t case_number; + uint64_t reserved1; + uint64_t reserved2; + uint64_t virt_address; + uint64_t reserved3; + uint32_t number_of_bytes; +}UNMAP_IO_SPACE_BUFFER_INFO, * PUNMAP_IO_SPACE_BUFFER_INFO; + +typedef struct _RTL_PROCESS_MODULE_INFORMATION +{ + HANDLE Section; + PVOID MappedBase; + PVOID ImageBase; + ULONG ImageSize; + ULONG Flags; + USHORT LoadOrderIndex; + USHORT InitOrderIndex; + USHORT LoadCount; + USHORT OffsetToFileName; + UCHAR FullPathName[256]; +} RTL_PROCESS_MODULE_INFORMATION, * PRTL_PROCESS_MODULE_INFORMATION; + +typedef struct _RTL_PROCESS_MODULES +{ + ULONG NumberOfModules; + RTL_PROCESS_MODULE_INFORMATION Modules[1]; +} RTL_PROCESS_MODULES, * PRTL_PROCESS_MODULES; + +typedef enum _SYSTEM_INFORMATION_CLASS +{ + SystemBasicInformation, + SystemProcessorInformation, + SystemPerformanceInformation, + SystemTimeOfDayInformation, + SystemPathInformation, + SystemProcessInformation, + SystemCallCountInformation, + SystemDeviceInformation, + SystemProcessorPerformanceInformation, + SystemFlagsInformation, + SystemCallTimeInformation, + SystemModuleInformation = 0x0B +} SYSTEM_INFORMATION_CLASS, * PSYSTEM_INFORMATION_CLASS; + +typedef struct _IMAGE_DOS_HEADER { // DOS .EXE header + USHORT e_magic; // Magic number + USHORT e_cblp; // Bytes on last page of file + USHORT e_cp; // Pages in file + USHORT e_crlc; // Relocations + USHORT e_cparhdr; // Size of header in paragraphs + USHORT e_minalloc; // Minimum extra paragraphs needed + USHORT e_maxalloc; // Maximum extra paragraphs needed + USHORT e_ss; // Initial (relative) SS value + USHORT e_sp; // Initial SP value + USHORT e_csum; // Checksum + USHORT e_ip; // Initial IP value + USHORT e_cs; // Initial (relative) CS value + USHORT e_lfarlc; // File address of relocation table + USHORT e_ovno; // Overlay number + USHORT e_res[4]; // Reserved words + USHORT e_oemid; // OEM identifier (for e_oeminfo) + USHORT e_oeminfo; // OEM information; e_oemid specific + USHORT e_res2[10]; // Reserved words + LONG e_lfanew; // File address of new exe header +} IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER; + +typedef struct _IMAGE_FILE_HEADER { + short Machine; + short NumberOfSections; + unsigned TimeDateStamp; + unsigned PointerToSymbolTable; + unsigned NumberOfSymbols; + short SizeOfOptionalHeader; + short Characteristics; +} IMAGE_FILE_HEADER, * PIMAGE_FILE_HEADER; + +typedef struct _IMAGE_DATA_DIRECTORY { + unsigned VirtualAddress; + unsigned Size; +} IMAGE_DATA_DIRECTORY, * PIMAGE_DATA_DIRECTORY; + +typedef struct _IMAGE_OPTIONAL_HEADER64 { + short Magic; + unsigned char MajorLinkerVersion; + unsigned char MinorLinkerVersion; + unsigned SizeOfCode; + unsigned SizeOfInitializedData; + unsigned SizeOfUninitializedData; + unsigned AddressOfEntryPoint; + unsigned BaseOfCode; + ULONGLONG ImageBase; + unsigned SectionAlignment; + unsigned FileAlignment; + short MajorOperatingSystemVersion; + short MinorOperatingSystemVersion; + short MajorImageVersion; + short MinorImageVersion; + short MajorSubsystemVersion; + short MinorSubsystemVersion; + unsigned Win32VersionValue; + unsigned SizeOfImage; + unsigned SizeOfHeaders; + unsigned CheckSum; + short Subsystem; + short DllCharacteristics; + ULONGLONG SizeOfStackReserve; + ULONGLONG SizeOfStackCommit; + ULONGLONG SizeOfHeapReserve; + ULONGLONG SizeOfHeapCommit; + unsigned LoaderFlags; + unsigned NumberOfRvaAndSizes; + IMAGE_DATA_DIRECTORY DataDirectory[16]; +} IMAGE_OPTIONAL_HEADER64, * PIMAGE_OPTIONAL_HEADER64; + +typedef struct _IMAGE_NT_HEADERS64 { + unsigned Signature; + IMAGE_FILE_HEADER FileHeader; + IMAGE_OPTIONAL_HEADER64 OptionalHeader; +} IMAGE_NT_HEADERS64, * PIMAGE_NT_HEADERS64; + +typedef struct _IMAGE_IMPORT_DESCRIPTOR { + union { + DWORD Characteristics; // 0 for terminating null import descriptor + DWORD OriginalFirstThunk; // RVA to original unbound IAT (PIMAGE_THUNK_DATA) + } DUMMYUNIONNAME; + DWORD TimeDateStamp; // 0 if not bound, + // -1 if bound, and real date\time stamp + // in IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT (new BIND) + // O.W. date/time stamp of DLL bound to (Old BIND) + + DWORD ForwarderChain; // -1 if no forwarders + DWORD Name; + DWORD FirstThunk; // RVA to IAT (if bound this IAT has actual addresses) +} IMAGE_IMPORT_DESCRIPTOR; +typedef IMAGE_IMPORT_DESCRIPTOR UNALIGNED* PIMAGE_IMPORT_DESCRIPTOR; + +typedef struct _IMAGE_IMPORT_BY_NAME { + WORD Hint; + CHAR Name[1]; +} IMAGE_IMPORT_BY_NAME, * PIMAGE_IMPORT_BY_NAME; + +typedef struct _IMAGE_THUNK_DATA64 { + union { + ULONGLONG ForwarderString; // PBYTE + ULONGLONG Function; // PDWORD + ULONGLONG Ordinal; + ULONGLONG AddressOfData; // PIMAGE_IMPORT_BY_NAME + } u1; +} IMAGE_THUNK_DATA64, * PIMAGE_THUNK_DATA64; +typedef PIMAGE_THUNK_DATA64 PIMAGE_THUNK_DATA; + +typedef union _virt_addr_t +{ + void* value; + struct + { + ULONG64 offset : 12; + ULONG64 pt_index : 9; + ULONG64 pd_index : 9; + ULONG64 pdpt_index : 9; + ULONG64 pml4_index : 9; + ULONG64 reserved : 16; + }; +} virt_addr_t, * pvirt_addr_t; \ No newline at end of file