Skip to main content
The module_manager class handles loading, mapping, and managing PE (Portable Executable) modules in the emulated process. It supports both 32-bit and 64-bit modules and handles WOW64 processes.

Overview

This class provides:
  • PE file parsing and memory mapping
  • Module lifetime management
  • Support for both native 64-bit and WOW64 (32-bit on 64-bit) execution
  • Module lookup by address or name
  • KnownDLLs optimization
  • Module load counting and duplicate handling

Enums

execution_mode

Defines the 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
};

Structures

pe_detection_result

Result of PE architecture detection.
struct pe_detection_result
{
    winpe::pe_arch architecture;
    execution_mode suggested_mode;
    std::string error_message;

    bool is_valid() const;
};
architecture
winpe::pe_arch
Detected PE architecture (x86, x64, etc.)
suggested_mode
execution_mode
Recommended execution mode based on architecture
error_message
std::string
Error description if detection failed

callbacks

Callback functions for module lifecycle events.
struct callbacks
{
    utils::callback_list<void(mapped_module& mod)> on_module_load{};
    utils::callback_list<void(mapped_module& mod)> on_module_unload{};
};

wow64_modules

WOW64-specific module references.
struct wow64_modules
{
    mapped_module* ntdll32 = nullptr;       // 32-bit ntdll.dll
    mapped_module* wow64_dll = nullptr;     // wow64.dll
    mapped_module* wow64win_dll = nullptr;  // wow64win.dll
};

Constructor

module_manager(
    memory_manager& memory,
    file_system& file_sys,
    callbacks& cb
)
memory
memory_manager&
Memory manager for module allocations
file_sys
file_system&
Virtual file system for resolving module paths
cb
callbacks&
Callback functions for module events

Methods

map_main_modules

Loads the main executable and core system modules.
void map_main_modules(
    const windows_path& executable_path,
    windows_version_manager& version,
    process_context& context,
    const logger& logger
)
executable_path
const windows_path&
Path to the main executable
version
windows_version_manager&
Windows version manager
context
process_context&
Process context to initialize
logger
const logger&
Logger for diagnostic output
This method:
  • Detects the executable architecture
  • Determines execution mode (native 64-bit or WOW64)
  • Loads ntdll.dll and other core modules
  • Sets up the WOW64 environment if needed

map_module

Maps a module from the virtual file system.
mapped_module* map_module(
    windows_path file,
    const logger& logger,
    bool is_static = false,
    bool allow_duplicate = false
)
file
windows_path
Windows-style path to the module
logger
const logger&
Logger instance
is_static
bool
default:"false"
Whether this is a statically loaded module
allow_duplicate
bool
default:"false"
Allow loading the same module multiple times
Returns: Pointer to the mapped module, or nullptr on failure.

map_local_module

Maps a module from the host file system.
mapped_module* map_local_module(
    const std::filesystem::path& file,
    windows_path module_path,
    const logger& logger,
    bool is_static = false,
    bool allow_duplicate = false
)
file
const std::filesystem::path&
Host filesystem path to the PE file
module_path
windows_path
Virtual Windows path for the module
logger
const logger&
Logger instance
is_static
bool
default:"false"
Static module flag
allow_duplicate
bool
default:"false"
Allow duplicates flag
Returns: Pointer to the mapped module, or nullptr on failure.

map_memory_module

Maps a module that’s already loaded in memory.
mapped_module* map_memory_module(
    uint64_t base_address,
    uint64_t image_size,
    windows_path module_path,
    const logger& logger,
    bool is_static = false,
    bool allow_duplicate = false
)
base_address
uint64_t
Base address of the module in memory
image_size
uint64_t
Size of the module image
module_path
windows_path
Virtual path for the module
logger
const logger&
Logger instance
is_static
bool
default:"false"
Static module flag
allow_duplicate
bool
default:"false"
Allow duplicates flag
Returns: Pointer to the mapped module, or nullptr on failure.

find_by_address

Finds a module containing the specified address.
mapped_module* find_by_address(const uint64_t address)
address
uint64_t
Address to search for
Returns: Pointer to the module, or nullptr if not found.

find_by_name

Finds a module by its name.
mapped_module* find_by_name(const std::string_view name)
name
std::string_view
Module name to search for (e.g., “kernel32.dll”)
Returns: Pointer to the module, or nullptr if not found.

find_name

Retrieves the name of the module at the given address.
const char* find_name(const uint64_t address)
address
uint64_t
Address to look up
Returns: Module name string, or “<N/A>” if not found.

unmap

Unmaps a module from memory.
bool unmap(uint64_t address)
address
uint64_t
Base address of the module to unmap
Returns: true if unmapped successfully, false otherwise.

get_module_load_count_by_path

std::optional<uint64_t> get_module_load_count_by_path(
    const windows_path& path
)
Retrieves the number of times a module has been loaded.
path
const windows_path&
Module path
Returns: Load count if the module has been loaded.

modules

const module_map& modules() const
Returns: Map of all loaded modules (keyed by base address).

Execution Mode

execution_mode get_execution_mode() const
bool is_wow64_process() const
Returns: Current execution mode or WOW64 status.

Serialization

void serialize(utils::buffer_serializer& buffer) const
void deserialize(utils::buffer_deserializer& buffer)
Serialization support for saving/loading module state.

Public Members

executable
mapped_module*
Pointer to the main executable module
ntdll
mapped_module*
Pointer to ntdll.dll
win32u
mapped_module*
Pointer to win32u.dll
wow64_modules_
wow64_modules
WOW64-specific module pointers
modules_load_count
std::map<std::filesystem::path, uint64_t>
Load count for each module path

Helper Classes

pe_architecture_detector

Static methods for detecting PE architecture.
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
)

module_mapping_strategy

Abstract base class for PE mapping strategies.
virtual mapped_module map_from_file(
    memory_manager& memory,
    std::filesystem::path file,
    windows_path module_path
) = 0

virtual mapped_module map_from_memory(
    memory_manager& memory,
    uint64_t base_address,
    uint64_t image_size,
    windows_path module_path
) = 0
Implementations:
  • pe32_mapping_strategy - Maps 32-bit PE files
  • pe64_mapping_strategy - Maps 64-bit PE files

Usage Example

// Create module manager
module_manager::callbacks callbacks;
callbacks.on_module_load.add([](mapped_module& mod) {
    printf("Loaded: %s at 0x%llx\n", mod.name.c_str(), mod.image_base);
});

module_manager modules(memory, file_system, callbacks);

// Load main executable and system modules
modules.map_main_modules(
    windows_path(LR"(C:\Windows\System32\notepad.exe)"),
    version_manager,
    context,
    logger
);

// Load a DLL dynamically
auto* kernel32 = modules.map_module(
    windows_path(LR"(C:\Windows\System32\kernel32.dll)"),
    logger
);

if (kernel32) {
    printf("kernel32.dll loaded at 0x%llx\n", kernel32->image_base);
}

// Find module by address
if (auto* mod = modules.find_by_address(0x7FFF12345678)) {
    printf("Address belongs to: %s\n", mod->name.c_str());
}

// Check execution mode
if (modules.is_wow64_process()) {
    printf("Running in WOW64 mode\n");
}

See Also

Build docs developers (and LLMs) love