From c4164f460a76073cac36e55d512c75d77e5092fa Mon Sep 17 00:00:00 2001 From: momo5502 Date: Tue, 10 Sep 2024 09:39:05 +0200 Subject: [PATCH] Some progress --- src/common/utils/nt_handle.hpp | 73 ++++++++++++++++++++++++ src/windows_emulator/main.cpp | 12 ++-- src/windows_emulator/process_context.hpp | 2 + src/windows_emulator/syscalls.cpp | 54 ++++++++++++------ src/windows_emulator/syscalls.hpp | 8 ++- 5 files changed, 127 insertions(+), 22 deletions(-) create mode 100644 src/common/utils/nt_handle.hpp diff --git a/src/common/utils/nt_handle.hpp b/src/common/utils/nt_handle.hpp new file mode 100644 index 00000000..5ed9ceec --- /dev/null +++ b/src/common/utils/nt_handle.hpp @@ -0,0 +1,73 @@ +#pragma once + +#define NOMINMAX +#define WIN32_LEAN_AND_MEAN +#include + +#include + +namespace utils::nt +{ + template + class handle + { + public: + handle() = default; + + handle(const HANDLE h) + : handle_(h) + { + } + + ~handle() + { + if (*this) + { + CloseHandle(this->handle_); + this->handle_ = InvalidHandle; + } + } + + handle(const handle&) = delete; + handle& operator=(const handle&) = delete; + + handle(handle&& obj) noexcept + : handle() + { + this->operator=(std::move(obj)); + } + + handle& operator=(handle&& obj) noexcept + { + if (this != &obj) + { + this->~handle(); + this->handle_ = obj.handle_; + obj.handle_ = InvalidHandle; + } + + return *this; + } + + handle& operator=(HANDLE h) noexcept + { + this->~handle(); + this->handle_ = h; + + return *this; + } + + [[nodiscard]] operator bool() const + { + return this->handle_ != InvalidHandle; + } + + [[nodiscard]] operator HANDLE() const + { + return this->handle_; + } + + private: + HANDLE handle_{InvalidHandle}; + }; +} diff --git a/src/windows_emulator/main.cpp b/src/windows_emulator/main.cpp index 3af46db7..5e8ea86f 100644 --- a/src/windows_emulator/main.cpp +++ b/src/windows_emulator/main.cpp @@ -30,7 +30,7 @@ #define GDT_LIMIT 0x1000 #define GDT_ENTRY_SIZE 0x8 -bool use_gdb = false; +bool use_gdb = true; namespace { @@ -589,9 +589,9 @@ namespace { ++context.executed_instructions; - /*const auto* binary = context.module_manager.find_by_address(address); + const auto* binary = context.module_manager.find_by_address(address); - if (binary) + if (binary && binary->name != "ntdll.dll") { const auto export_entry = binary->address_names.find(address); if (export_entry != binary->address_names.end()) @@ -599,7 +599,11 @@ namespace printf("Executing function: %s - %s (%llX)\n", binary->name.c_str(), export_entry->second.c_str(), address); } - }*/ + else if (address == binary->entry_point) + { + printf("Executing entry point: %s (%llX)\n", binary->name.c_str(), address); + } + } if (!context.verbose) { diff --git a/src/windows_emulator/process_context.hpp b/src/windows_emulator/process_context.hpp index a0ffd10c..d370a770 100644 --- a/src/windows_emulator/process_context.hpp +++ b/src/windows_emulator/process_context.hpp @@ -3,6 +3,7 @@ #include "handles.hpp" #include "module/module_manager.hpp" +#include struct event { @@ -24,6 +25,7 @@ struct event struct file { + utils::nt::handle handle{}; std::wstring name{}; }; diff --git a/src/windows_emulator/syscalls.cpp b/src/windows_emulator/syscalls.cpp index fc615054..1f1c98d0 100644 --- a/src/windows_emulator/syscalls.cpp +++ b/src/windows_emulator/syscalls.cpp @@ -319,21 +319,36 @@ namespace NTSTATUS handle_NtOpenFile(const syscall_context& c, const emulator_object file_handle, - const ACCESS_MASK /*desired_access*/, + const ACCESS_MASK desired_access, const emulator_object object_attributes, const emulator_object /*io_status_block*/, - const ULONG /*share_access*/, - const ULONG /*open_options*/) + const ULONG share_access, + const ULONG open_options) { file f{}; const auto attributes = object_attributes.read(); f.name = read_unicode_string(c.emu, attributes.ObjectName); - if (!std::filesystem::exists(f.name)) + UNICODE_STRING string{}; + string.Buffer = f.name.data(); + string.Length = static_cast(f.name.size() * 2); + string.MaximumLength = string.Length; + + OBJECT_ATTRIBUTES new_attributes{}; + new_attributes.ObjectName = &string; + new_attributes.Length = sizeof(new_attributes); + + HANDLE h{}; + IO_STATUS_BLOCK status_block{}; + + const auto res = NtOpenFile(&h, desired_access, &new_attributes, &status_block, share_access, open_options); + if (res != STATUS_SUCCESS) { - return STATUS_FILE_INVALID; + return res; } + f.handle = h; + const auto handle = c.proc.files.store(std::move(f)); file_handle.write(handle.bits); @@ -376,7 +391,7 @@ namespace return STATUS_FILE_INVALID; } - const auto handle = c.proc.files.store({std::move(filename)}); + const auto handle = c.proc.files.store(file{{}, std::move(filename)}); section_handle.write(handle.bits); return STATUS_SUCCESS; @@ -1120,7 +1135,7 @@ namespace return STATUS_SUCCESS; } - puts("NtCreateSection not supported"); + puts("NtWriteFile not supported"); c.emu.stop(); return STATUS_NOT_SUPPORTED; } @@ -1195,14 +1210,19 @@ syscall_dispatcher::syscall_dispatcher(const exported_symbols& ntdll_exports) { const auto syscalls = find_syscalls(ntdll_exports); -#define add_handler(syscall) do \ - { \ - const auto id = get_syscall_id(syscalls, #syscall); \ - auto handler = +[](const syscall_context& c) \ - { \ - forward(c, handle_ ## syscall); \ - }; \ - this->handlers_[id] = handler; \ +#define add_handler(syscall) do \ + { \ + std::string name = #syscall; \ + const auto id = get_syscall_id(syscalls, name); \ + auto handler = +[](const syscall_context& c) \ + { \ + forward(c, handle_ ## syscall); \ + }; \ + \ + syscall_handler_entry entry{}; \ + entry.handler = handler; \ + entry.name = std::move(name); \ + this->handlers_[id] = std::move(entry); \ } while(0) add_handler(NtSetInformationThread); @@ -1257,7 +1277,6 @@ void syscall_dispatcher::dispatch(x64_emulator& emu, process_context& context) const auto address = emu.read_instruction_pointer(); const auto syscall_id = emu.reg(x64_register::eax); - printf("Handling syscall: %X (%llX)\n", syscall_id, address); const syscall_context c{emu, context, true}; @@ -1272,7 +1291,8 @@ void syscall_dispatcher::dispatch(x64_emulator& emu, process_context& context) } else { - entry->second(c); + printf("Handling syscall: %s with id %X at %llX \n", entry->second.name.c_str(), syscall_id, address); + entry->second.handler(c); } } catch (std::exception& e) diff --git a/src/windows_emulator/syscalls.hpp b/src/windows_emulator/syscalls.hpp index f2c20447..daf0fff9 100644 --- a/src/windows_emulator/syscalls.hpp +++ b/src/windows_emulator/syscalls.hpp @@ -7,6 +7,12 @@ struct syscall_context; using syscall_handler = void(*)(const syscall_context& c); +struct syscall_handler_entry +{ + syscall_handler handler{}; + std::string name{}; +}; + class syscall_dispatcher { public: @@ -15,5 +21,5 @@ public: void dispatch(x64_emulator& emu, process_context& context); private: - std::unordered_map handlers_{}; + std::unordered_map handlers_{}; };