From 4b7eebca889040a89f28678fccdbba6bb04f5b85 Mon Sep 17 00:00:00 2001 From: momo5502 Date: Sat, 31 Aug 2024 12:35:16 +0200 Subject: [PATCH] Setup api set mapping --- src/emulator/address_utils.hpp | 12 +++ src/windows_emulator/emulator_utils.hpp | 18 ++--- src/windows_emulator/main.cpp | 102 +++++++++++++++++++++--- src/windows_emulator/memory_utils.hpp | 28 ------- src/windows_emulator/module_mapper.cpp | 7 +- 5 files changed, 112 insertions(+), 55 deletions(-) diff --git a/src/emulator/address_utils.hpp b/src/emulator/address_utils.hpp index a236df4c..84277ec7 100644 --- a/src/emulator/address_utils.hpp +++ b/src/emulator/address_utils.hpp @@ -1,6 +1,18 @@ #pragma once #include +template +T* offset_pointer(void* data, const size_t offset) +{ + return reinterpret_cast(static_cast(data) + offset); +} + +template +const T* offset_pointer(const void* data, const size_t offset) +{ + return reinterpret_cast(static_cast(data) + offset); +} + inline bool is_within_start_and_end(const uint64_t value, const uint64_t start, const uint64_t end) { return value >= start && value < end; diff --git a/src/windows_emulator/emulator_utils.hpp b/src/windows_emulator/emulator_utils.hpp index ec273141..845ba585 100644 --- a/src/windows_emulator/emulator_utils.hpp +++ b/src/windows_emulator/emulator_utils.hpp @@ -45,27 +45,27 @@ public: return this->address_ != 0; } - T read() const + T read(const size_t index = 0) const { T obj{}; - this->emu_->read_memory(this->address_, &obj, sizeof(obj)); + this->emu_->read_memory(this->address_ + index * this->size(), &obj, sizeof(obj)); return obj; } - void write(const T& value) const + void write(const T& value, const size_t index = 0) const { - this->emu_->write_memory(this->address_, &value, sizeof(value)); + this->emu_->write_memory(this->address_ + index * this->size(), &value, sizeof(value)); } template - void access(const F& accessor) const + void access(const F& accessor, const size_t index = 0) const { T obj{}; - this->emu_->read_memory(this->address_, &obj, sizeof(obj)); + this->emu_->read_memory(this->address_ + index * this->size(), &obj, sizeof(obj)); accessor(obj); - this->write(obj); + this->write(obj, index); } private: @@ -103,9 +103,9 @@ public: } template - emulator_object reserve() + emulator_object reserve(const size_t count = 1) { - const auto potential_start = this->reserve(sizeof(T), alignof(T)); + const auto potential_start = this->reserve(sizeof(T) * count, alignof(T)); return emulator_object(*this->emu_, potential_start); } diff --git a/src/windows_emulator/main.cpp b/src/windows_emulator/main.cpp index f1b90bb3..fc42f675 100644 --- a/src/windows_emulator/main.cpp +++ b/src/windows_emulator/main.cpp @@ -13,6 +13,7 @@ #include "gdb_stub.hpp" #include "module_mapper.hpp" +#include #define GS_SEGMENT_ADDR 0x6000000ULL #define GS_SEGMENT_SIZE (20 << 20) // 20 MB @@ -77,6 +78,83 @@ namespace return kusd_object; } + uint64_t copy_string(x64_emulator& emu, emulator_allocator& allocator, const void* base_ptr, const uint64_t offset, + const size_t length) + { + const auto length_to_allocate = length + 2; + const auto str_obj = allocator.reserve(length_to_allocate); + emu.write_memory(str_obj, static_cast(base_ptr) + offset, length); + + return str_obj; + } + + ULONG copy_string_as_relative(x64_emulator& emu, emulator_allocator& allocator, const uint64_t result_base, + const void* base_ptr, const uint64_t offset, + const size_t length) + { + return static_cast(copy_string(emu, allocator, base_ptr, offset, length) - result_base); + } + + emulator_object clone_api_set_map(x64_emulator& emu, emulator_allocator& allocator,const API_SET_NAMESPACE& orig_api_set_map) + { + const auto api_set_map_obj = allocator.reserve(); + const auto ns_entries_obj = allocator.reserve(orig_api_set_map.Count); + const auto hash_entries_obj = allocator.reserve(orig_api_set_map.Count); + + auto api_set_map = orig_api_set_map; + api_set_map.EntryOffset = static_cast(ns_entries_obj.value() - api_set_map_obj.value()); + api_set_map.HashOffset = static_cast(hash_entries_obj.value() - api_set_map_obj.value()); + + + const auto orig_ns_entries = offset_pointer( + &orig_api_set_map, orig_api_set_map.EntryOffset); + const auto orig_hash_entries = offset_pointer( + &orig_api_set_map, orig_api_set_map.HashOffset); + + for (ULONG i = 0; i < orig_api_set_map.Count; ++i) + { + auto ns_entry = orig_ns_entries[i]; + const auto hash_entry = orig_hash_entries[i]; + + ns_entry.NameOffset = copy_string_as_relative(emu, allocator, api_set_map_obj.value(), &orig_api_set_map, + ns_entry.NameOffset, ns_entry.NameLength); + + const auto values_obj = allocator.reserve(ns_entry.ValueCount); + const auto orig_values = offset_pointer( + &orig_api_set_map, ns_entry.ValueOffset); + + for (ULONG j = 0; j < ns_entry.ValueCount; ++j) + { + auto value = orig_values[j]; + + value.ValueOffset = copy_string_as_relative(emu, allocator, api_set_map_obj.value(), &orig_api_set_map, + value.ValueOffset, value.ValueLength); + + if (value.NameLength) + { + value.NameOffset = copy_string_as_relative(emu, allocator, api_set_map_obj.value(), + &orig_api_set_map, + value.NameOffset, value.NameLength); + } + + values_obj.write(value, j); + } + + ns_entries_obj.write(ns_entry, i); + hash_entries_obj.write(hash_entry, i); + } + + api_set_map_obj.write(api_set_map); + + return api_set_map_obj; + } + + emulator_object build_api_set_map(x64_emulator& emu, emulator_allocator& allocator) + { + const auto& orig_api_set_map = *NtCurrentTeb()->ProcessEnvironmentBlock->ApiSetMap; + return clone_api_set_map(emu, allocator, orig_api_set_map); + } + process_context setup_context(x64_emulator& emu) { setup_stack(emu, STACK_ADDRESS, STACK_SIZE); @@ -102,22 +180,22 @@ namespace teb.ProcessEnvironmentBlock = context.peb.ptr(); }); + context.process_params.access([&](RTL_USER_PROCESS_PARAMETERS& proc_params) + { + proc_params.Length = sizeof(proc_params); + proc_params.Flags = 0x6001; + gs.make_unicode_string(proc_params.CurrentDirectory.DosPath, L"C:\\Users\\mauri\\Desktop"); + gs.make_unicode_string(proc_params.ImagePathName, L"C:\\Users\\mauri\\Desktop\\ConsoleApplication6.exe"); + gs.make_unicode_string(proc_params.CommandLine, L"C:\\Users\\mauri\\Desktop\\ConsoleApplication6.exe"); + }); + context.peb.access([&](PEB& peb) { peb.ImageBaseAddress = nullptr; peb.ProcessHeap = nullptr; peb.ProcessHeaps = nullptr; peb.ProcessParameters = context.process_params.ptr(); - peb.ApiSetMap = gs.reserve().ptr(); - }); - - context.process_params.access([&](RTL_USER_PROCESS_PARAMETERS& proc_params) - { - proc_params.Length = sizeof(proc_params); - proc_params.Flags = 0x6001; - gs.make_unicode_string(proc_params.CurrentDirectory.DosPath, L"C:\\Users\\mauri\\Desktop"); - gs.make_unicode_string(proc_params.ImagePathName, L"C:\\Users\\mauri\\Desktop\\ConsoleApplication6.exe"); - gs.make_unicode_string(proc_params.CommandLine, L"C:\\Users\\mauri\\Desktop\\ConsoleApplication6.exe"); + peb.ApiSetMap = build_api_set_map(emu, gs).ptr(); }); return context; @@ -549,9 +627,9 @@ int main(int /*argc*/, char** /*argv*/) return 0; } - catch (std::exception& uce) + catch (std::exception& e) { - puts(uce.what()); + puts(e.what()); #ifdef _WIN32 //MessageBoxA(nullptr, e.what(), "ERROR", MB_ICONERROR); diff --git a/src/windows_emulator/memory_utils.hpp b/src/windows_emulator/memory_utils.hpp index ca9da93e..d6e8d633 100644 --- a/src/windows_emulator/memory_utils.hpp +++ b/src/windows_emulator/memory_utils.hpp @@ -2,34 +2,6 @@ #include #include -/* -inline memory_permission get_memory_protection(emulator& emu, const uint64_t address) -{ - for (const auto& region : emu.get_memory_regions()) - { - if (is_within_start_and_length(address, region.start, region.length)) - { - return region.pemissions; - } - } - - return memory_permission::none; -} - -inline bool is_memory_allocated(emulator& emu, const uint64_t address) -{ - for (const auto& region : emu.get_memory_regions()) - { - if (is_within_start_and_length(address, region.start, region.length)) - { - return true; - } - } - - return false; -} -*/ - inline memory_permission map_nt_to_emulator_protection(const uint32_t nt_protection) { switch (nt_protection) diff --git a/src/windows_emulator/module_mapper.cpp b/src/windows_emulator/module_mapper.cpp index a2abed3a..ee47405b 100644 --- a/src/windows_emulator/module_mapper.cpp +++ b/src/windows_emulator/module_mapper.cpp @@ -1,14 +1,9 @@ #include "std_include.hpp" #include "module_mapper.hpp" +#include namespace { - template - T offset_pointer(const void* data, const size_t offset) - { - return reinterpret_cast(static_cast(data) + offset); - } - void collect_exports(mapped_binary& binary, const unsigned char* ptr, const IMAGE_OPTIONAL_HEADER& optional_header) { auto& export_directory_entry = optional_header.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT];