Comprehensive WOW64 subsystem implementation

This commit is contained in:
brian
2025-10-13 19:53:14 +08:00
parent 9453123db0
commit 65eecf1cfd
51 changed files with 3772 additions and 283 deletions

View File

@@ -4,9 +4,80 @@
#include "mapped_module.hpp"
#include "../file_system.hpp"
#include <utils/function.hpp>
#include "platform/win_pefile.hpp"
class logger;
// Execution mode for the emulated process
enum class execution_mode
{
native_64bit, // Native 64-bit execution
wow64_32bit, // WOW64 mode for 32-bit applications
unknown // Detection failed or unsupported
};
// PE architecture detection result
struct pe_detection_result
{
winpe::pe_arch architecture;
execution_mode suggested_mode;
std::string error_message;
bool is_valid() const
{
return error_message.empty();
}
};
// Strategy interface for module mapping
class module_mapping_strategy
{
public:
virtual ~module_mapping_strategy() = default;
virtual mapped_module map_from_file(memory_manager& memory, std::filesystem::path file) = 0;
virtual mapped_module map_from_memory(memory_manager& memory, uint64_t base_address, uint64_t image_size,
const std::string& module_name) = 0;
};
// PE32 mapping strategy implementation
class pe32_mapping_strategy : public module_mapping_strategy
{
public:
mapped_module map_from_file(memory_manager& memory, std::filesystem::path file) override;
mapped_module map_from_memory(memory_manager& memory, uint64_t base_address, uint64_t image_size,
const std::string& module_name) override;
};
// PE64 mapping strategy implementation
class pe64_mapping_strategy : public module_mapping_strategy
{
public:
mapped_module map_from_file(memory_manager& memory, std::filesystem::path file) override;
mapped_module map_from_memory(memory_manager& memory, uint64_t base_address, uint64_t image_size,
const std::string& module_name) override;
};
// Factory for creating mapping strategies
class mapping_strategy_factory
{
private:
std::unique_ptr<pe32_mapping_strategy> pe32_strategy_;
std::unique_ptr<pe64_mapping_strategy> pe64_strategy_;
public:
mapping_strategy_factory();
module_mapping_strategy& get_strategy(winpe::pe_arch arch);
};
// PE architecture detector utility class
class pe_architecture_detector
{
public:
static pe_detection_result detect_from_file(const std::filesystem::path& file);
static pe_detection_result detect_from_memory(uint64_t base_address, uint64_t image_size);
static execution_mode determine_execution_mode(winpe::pe_arch executable_arch);
};
class module_manager
{
public:
@@ -20,7 +91,7 @@ class module_manager
module_manager(memory_manager& memory, file_system& file_sys, callbacks& cb);
void map_main_modules(const windows_path& executable_path, const windows_path& ntdll_path, const windows_path& win32u_path,
void map_main_modules(const windows_path& executable_path, const windows_path& system32_path, const windows_path& syswow64_path,
const logger& logger);
mapped_module* map_module(const windows_path& file, const logger& logger, bool is_static = false);
@@ -72,11 +143,30 @@ class module_manager
return modules_;
}
// TODO: These is wrong here. A good mechanism for quick module access is needed.
// Execution mode accessors
execution_mode get_execution_mode() const
{
return current_execution_mode_;
}
bool is_wow64_process() const
{
return current_execution_mode_ == execution_mode::wow64_32bit;
}
// TODO: These should be properly encapsulated. A good mechanism for quick module access is needed.
mapped_module* executable{};
mapped_module* ntdll{};
mapped_module* win32u{};
// WOW64-specific modules (for validation and future use)
struct wow64_modules
{
mapped_module* ntdll32 = nullptr; // 32-bit ntdll.dll
mapped_module* wow64_dll = nullptr; // wow64.dll (loaded by system)
mapped_module* wow64win_dll = nullptr; // wow64win.dll (loaded by system)
// Note: wow64cpu.dll is loaded by ntdll via registry lookup, not managed here
} wow64_modules_;
private:
memory_manager* memory_{};
file_system* file_sys_{};
@@ -84,6 +174,28 @@ class module_manager
module_map modules_{};
// Strategy pattern components
mapping_strategy_factory strategy_factory_;
execution_mode current_execution_mode_ = execution_mode::unknown;
// Core mapping logic to eliminate code duplication
mapped_module* map_module_core(const pe_detection_result& detection_result, const std::function<mapped_module()>& mapper,
const logger& logger, bool is_static);
// Shell32.dll entry point patching to prevent TLS storage issues
void patch_shell32_entry_point_if_needed(mapped_module& mod);
// Execution mode detection
execution_mode detect_execution_mode(const windows_path& executable_path, const logger& logger);
// Module loading helpers
void load_native_64bit_modules(const windows_path& executable_path, const windows_path& ntdll_path, const windows_path& win32u_path,
const logger& logger);
void load_wow64_modules(const windows_path& executable_path, const windows_path& ntdll_path, const windows_path& win32u_path,
const windows_path& ntdll32_path, const logger& logger);
void install_wow64_heaven_gate(const logger& logger);
module_map::iterator get_module(const uint64_t address)
{
if (this->modules_.empty())