Extend clang-format column limit to 140

This commit is contained in:
momo5502
2025-08-16 14:52:38 +02:00
parent f3de9697d6
commit 7d6648ade0
84 changed files with 5072 additions and 5951 deletions

View File

@@ -14,6 +14,7 @@ SortIncludes: false
AlignEscapedNewlines: Left AlignEscapedNewlines: Left
PackConstructorInitializers: Never PackConstructorInitializers: Never
IndentPPDirectives: None IndentPPDirectives: None
ColumnLimit: 140
AlignConsecutiveMacros: AlignConsecutiveMacros:
Enabled: true Enabled: true
AcrossEmptyLines: true AcrossEmptyLines: true

View File

@@ -22,8 +22,7 @@ namespace
} }
template <typename Return, typename... Args> template <typename Return, typename... Args>
std::function<Return(Args...)> make_callback(analysis_context& c, std::function<Return(Args...)> make_callback(analysis_context& c, Return (*callback)(const analysis_context&, Args...))
Return (*callback)(const analysis_context&, Args...))
{ {
return [&c, callback](Args... args) { return [&c, callback](Args... args) {
return callback(c, std::forward<Args>(args)...); // return callback(c, std::forward<Args>(args)...); //
@@ -33,8 +32,8 @@ namespace
void handle_suspicious_activity(const analysis_context& c, const std::string_view details) void handle_suspicious_activity(const analysis_context& c, const std::string_view details)
{ {
const auto rip = c.win_emu->emu().read_instruction_pointer(); const auto rip = c.win_emu->emu().read_instruction_pointer();
c.win_emu->log.print(color::pink, "Suspicious: %.*s at 0x%" PRIx64 " (via 0x%" PRIx64 ")\n", c.win_emu->log.print(color::pink, "Suspicious: %.*s at 0x%" PRIx64 " (via 0x%" PRIx64 ")\n", STR_VIEW_VA(details), rip,
STR_VIEW_VA(details), rip, c.win_emu->process.previous_ip); c.win_emu->process.previous_ip);
} }
void handle_debug_string(const analysis_context& c, const std::string_view details) void handle_debug_string(const analysis_context& c, const std::string_view details)
@@ -57,20 +56,18 @@ namespace
{ {
const auto* action = commit ? "Committed" : "Allocating"; const auto* action = commit ? "Committed" : "Allocating";
c.win_emu->log.print(is_executable(permission) ? color::gray : color::dark_gray, c.win_emu->log.print(is_executable(permission) ? color::gray : color::dark_gray, "--> %s 0x%" PRIx64 " - 0x%" PRIx64 " (%s)\n",
"--> %s 0x%" PRIx64 " - 0x%" PRIx64 " (%s)\n", action, address, address + length, action, address, address + length, get_permission_string(permission).c_str());
}
void handle_memory_protect(const analysis_context& c, const uint64_t address, const uint64_t length, const memory_permission permission)
{
c.win_emu->log.print(color::dark_gray, "--> Changing protection at 0x%" PRIx64 "-0x%" PRIx64 " to %s\n", address, address + length,
get_permission_string(permission).c_str()); get_permission_string(permission).c_str());
} }
void handle_memory_protect(const analysis_context& c, const uint64_t address, const uint64_t length, void handle_memory_violate(const analysis_context& c, const uint64_t address, const uint64_t size, const memory_operation operation,
const memory_permission permission) const memory_violation_type type)
{
c.win_emu->log.print(color::dark_gray, "--> Changing protection at 0x%" PRIx64 "-0x%" PRIx64 " to %s\n",
address, address + length, get_permission_string(permission).c_str());
}
void handle_memory_violate(const analysis_context& c, const uint64_t address, const uint64_t size,
const memory_operation operation, const memory_violation_type type)
{ {
const auto permission = get_permission_string(operation); const auto permission = get_permission_string(operation);
const auto ip = c.win_emu->emu().read_instruction_pointer(); const auto ip = c.win_emu->emu().read_instruction_pointer();
@@ -78,23 +75,19 @@ namespace
if (type == memory_violation_type::protection) if (type == memory_violation_type::protection)
{ {
c.win_emu->log.print(color::gray, c.win_emu->log.print(color::gray, "Protection violation: 0x%" PRIx64 " (%" PRIx64 ") - %s at 0x%" PRIx64 " (%s)\n", address,
"Protection violation: 0x%" PRIx64 " (%" PRIx64 ") - %s at 0x%" PRIx64 " (%s)\n", size, permission.c_str(), ip, name);
address, size, permission.c_str(), ip, name);
} }
else if (type == memory_violation_type::unmapped) else if (type == memory_violation_type::unmapped)
{ {
c.win_emu->log.print(color::gray, c.win_emu->log.print(color::gray, "Mapping violation: 0x%" PRIx64 " (%" PRIx64 ") - %s at 0x%" PRIx64 " (%s)\n", address, size,
"Mapping violation: 0x%" PRIx64 " (%" PRIx64 ") - %s at 0x%" PRIx64 " (%s)\n", address, permission.c_str(), ip, name);
size, permission.c_str(), ip, name);
} }
} }
void handle_ioctrl(const analysis_context& c, const io_device&, const std::u16string_view device_name, void handle_ioctrl(const analysis_context& c, const io_device&, const std::u16string_view device_name, const ULONG code)
const ULONG code)
{ {
c.win_emu->log.print(color::dark_gray, "--> %s: 0x%X\n", u16_to_u8(device_name).c_str(), c.win_emu->log.print(color::dark_gray, "--> %s: 0x%X\n", u16_to_u8(device_name).c_str(), static_cast<uint32_t>(code));
static_cast<uint32_t>(code));
} }
void handle_thread_set_name(const analysis_context& c, const emulator_thread& t) void handle_thread_set_name(const analysis_context& c, const emulator_thread& t)
@@ -102,11 +95,9 @@ namespace
c.win_emu->log.print(color::blue, "Setting thread (%u) name: %s\n", t.id, u16_to_u8(t.name).c_str()); c.win_emu->log.print(color::blue, "Setting thread (%u) name: %s\n", t.id, u16_to_u8(t.name).c_str());
} }
void handle_thread_switch(const analysis_context& c, const emulator_thread& current_thread, void handle_thread_switch(const analysis_context& c, const emulator_thread& current_thread, const emulator_thread& new_thread)
const emulator_thread& new_thread)
{ {
c.win_emu->log.print(color::dark_gray, "Performing thread switch: %X -> %X\n", current_thread.id, c.win_emu->log.print(color::dark_gray, "Performing thread switch: %X -> %X\n", current_thread.id, new_thread.id);
new_thread.id);
} }
void handle_module_load(const analysis_context& c, const mapped_module& mod) void handle_module_load(const analysis_context& c, const mapped_module& mod)
@@ -218,8 +209,7 @@ namespace
} }
constexpr auto inst_delay = 100u; constexpr auto inst_delay = 100u;
const auto execution_delay_reached = const auto execution_delay_reached = is_same_thread && a.access_inst_count + inst_delay <= t.executed_instructions;
is_same_thread && a.access_inst_count + inst_delay <= t.executed_instructions;
if (!execution_delay_reached && is_thread_alive(c, a.thread_id)) if (!execution_delay_reached && is_thread_alive(c, a.thread_id))
{ {
@@ -228,8 +218,7 @@ namespace
} }
c.win_emu->log.print(color::green, "Import read access without execution: %s (%s) at 0x%" PRIx64 " (%s)\n", c.win_emu->log.print(color::green, "Import read access without execution: %s (%s) at 0x%" PRIx64 " (%s)\n",
a.import_name.c_str(), a.import_module.c_str(), a.access_rip, a.import_name.c_str(), a.import_module.c_str(), a.access_rip, a.accessor_module.c_str());
a.accessor_module.c_str());
entry = c.accessed_imports.erase(entry); entry = c.accessed_imports.erase(entry);
} }
@@ -320,9 +309,8 @@ namespace
if (!c.settings->ignored_functions.contains(export_entry->second)) if (!c.settings->ignored_functions.contains(export_entry->second))
{ {
win_emu.log.print(is_interesting_call ? color::yellow : color::dark_gray, win_emu.log.print(is_interesting_call ? color::yellow : color::dark_gray,
"Executing function: %s (%s) (0x%" PRIx64 ") via (0x%" PRIx64 ") %s\n", "Executing function: %s (%s) (0x%" PRIx64 ") via (0x%" PRIx64 ") %s\n", export_entry->second.c_str(),
export_entry->second.c_str(), binary->name.c_str(), address, binary->name.c_str(), address, win_emu.process.previous_ip,
win_emu.process.previous_ip,
previous_binary ? previous_binary->name.c_str() : "<N/A>"); previous_binary ? previous_binary->name.c_str() : "<N/A>");
if (is_interesting_call) if (is_interesting_call)
@@ -333,11 +321,10 @@ namespace
} }
else if (address == binary->entry_point) else if (address == binary->entry_point)
{ {
win_emu.log.print(is_interesting_call ? color::yellow : color::gray, win_emu.log.print(is_interesting_call ? color::yellow : color::gray, "Executing entry point: %s (0x%" PRIx64 ")\n",
"Executing entry point: %s (0x%" PRIx64 ")\n", binary->name.c_str(), address); binary->name.c_str(), address);
} }
else if (is_previous_main_exe && binary != previous_binary && else if (is_previous_main_exe && binary != previous_binary && !is_return(c.win_emu->emu(), win_emu.process.previous_ip))
!is_return(c.win_emu->emu(), win_emu.process.previous_ip))
{ {
auto nearest_entry = binary->address_names.upper_bound(address); auto nearest_entry = binary->address_names.upper_bound(address);
if (nearest_entry == binary->address_names.begin()) if (nearest_entry == binary->address_names.begin())
@@ -347,11 +334,10 @@ namespace
--nearest_entry; --nearest_entry;
win_emu.log.print( win_emu.log.print(is_interesting_call ? color::yellow : color::dark_gray,
is_interesting_call ? color::yellow : color::dark_gray, "Transition to foreign code: %s+0x%" PRIx64 " (%s) (0x%" PRIx64 ") via (0x%" PRIx64 ") %s\n",
"Transition to foreign code: %s+0x%" PRIx64 " (%s) (0x%" PRIx64 ") via (0x%" PRIx64 ") %s\n", nearest_entry->second.c_str(), address - nearest_entry->first, binary->name.c_str(), address,
nearest_entry->second.c_str(), address - nearest_entry->first, binary->name.c_str(), address, win_emu.process.previous_ip, previous_binary ? previous_binary->name.c_str() : "<N/A>");
win_emu.process.previous_ip, previous_binary ? previous_binary->name.c_str() : "<N/A>");
} }
} }
@@ -368,8 +354,7 @@ namespace
return; return;
} }
win_emu.log.print(color::blue, "Executing RDTSC instruction at 0x%" PRIx64 " (%s)\n", rip, win_emu.log.print(color::blue, "Executing RDTSC instruction at 0x%" PRIx64 " (%s)\n", rip, (*mod) ? (*mod)->name.c_str() : "<N/A>");
(*mod) ? (*mod)->name.c_str() : "<N/A>");
} }
void handle_rdtscp(const analysis_context& c) void handle_rdtscp(const analysis_context& c)
@@ -401,8 +386,8 @@ namespace
if (is_sus_module) if (is_sus_module)
{ {
win_emu.log.print(color::blue, "Executing inline syscall: %.*s (0x%X) at 0x%" PRIx64 " (%s)\n", win_emu.log.print(color::blue, "Executing inline syscall: %.*s (0x%X) at 0x%" PRIx64 " (%s)\n", STR_VIEW_VA(syscall_name),
STR_VIEW_VA(syscall_name), syscall_id, address, mod ? mod->name.c_str() : "<N/A>"); syscall_id, address, mod ? mod->name.c_str() : "<N/A>");
} }
else if (mod->is_within(win_emu.process.previous_ip)) else if (mod->is_within(win_emu.process.previous_ip))
{ {
@@ -413,16 +398,14 @@ namespace
const auto* caller_mod_name = win_emu.mod_manager.find_name(return_address); const auto* caller_mod_name = win_emu.mod_manager.find_name(return_address);
win_emu.log.print(color::dark_gray, win_emu.log.print(color::dark_gray, "Executing syscall: %.*s (0x%X) at 0x%" PRIx64 " via 0x%" PRIx64 " (%s)\n",
"Executing syscall: %.*s (0x%X) at 0x%" PRIx64 " via 0x%" PRIx64 " (%s)\n",
STR_VIEW_VA(syscall_name), syscall_id, address, return_address, caller_mod_name); STR_VIEW_VA(syscall_name), syscall_id, address, return_address, caller_mod_name);
} }
else else
{ {
const auto* previous_mod = win_emu.mod_manager.find_by_address(win_emu.process.previous_ip); const auto* previous_mod = win_emu.mod_manager.find_by_address(win_emu.process.previous_ip);
win_emu.log.print(color::blue, win_emu.log.print(color::blue, "Crafted out-of-line syscall: %.*s (0x%X) at 0x%" PRIx64 " (%s) via 0x%" PRIx64 " (%s)\n",
"Crafted out-of-line syscall: %.*s (0x%X) at 0x%" PRIx64 " (%s) via 0x%" PRIx64 " (%s)\n",
STR_VIEW_VA(syscall_name), syscall_id, address, mod ? mod->name.c_str() : "<N/A>", STR_VIEW_VA(syscall_name), syscall_id, address, mod ? mod->name.c_str() : "<N/A>",
win_emu.process.previous_ip, previous_mod ? previous_mod->name.c_str() : "<N/A>"); win_emu.process.previous_ip, previous_mod ? previous_mod->name.c_str() : "<N/A>");
} }
@@ -538,8 +521,7 @@ void register_analysis_callbacks(analysis_context& c)
watch_import_table(c); watch_import_table(c);
} }
std::optional<mapped_module*> get_module_if_interesting(module_manager& manager, const string_set& modules, std::optional<mapped_module*> get_module_if_interesting(module_manager& manager, const string_set& modules, const uint64_t address)
const uint64_t address)
{ {
if (manager.executable->is_within(address)) if (manager.executable->is_within(address))
{ {

View File

@@ -43,5 +43,4 @@ struct analysis_context
}; };
void register_analysis_callbacks(analysis_context& c); void register_analysis_callbacks(analysis_context& c);
std::optional<mapped_module*> get_module_if_interesting(module_manager& manager, const string_set& modules, std::optional<mapped_module*> get_module_if_interesting(module_manager& manager, const string_set& modules, uint64_t address);
uint64_t address);

View File

@@ -33,8 +33,7 @@ namespace
std::unordered_map<windows_path, std::filesystem::path> path_mappings{}; std::unordered_map<windows_path, std::filesystem::path> path_mappings{};
}; };
void split_and_insert(std::set<std::string, std::less<>>& container, const std::string_view str, void split_and_insert(std::set<std::string, std::less<>>& container, const std::string_view str, const char splitter = ',')
const char splitter = ',')
{ {
size_t current_start = 0; size_t current_start = 0;
for (size_t i = 0; i < str.size(); ++i) for (size_t i = 0; i < str.size(); ++i)
@@ -131,8 +130,7 @@ namespace
auto hook_handler = [state, env_ptr](const uint64_t address, const void*, const size_t size) { auto hook_handler = [state, env_ptr](const uint64_t address, const void*, const size_t size) {
const auto rip = state->win_emu_.emu().read_instruction_pointer(); const auto rip = state->win_emu_.emu().read_instruction_pointer();
const auto* mod = state->win_emu_.mod_manager.find_by_address(rip); const auto* mod = state->win_emu_.mod_manager.find_by_address(rip);
const auto is_main_access = const auto is_main_access = !mod || (mod == state->win_emu_.mod_manager.executable || state->modules_.contains(mod->name));
!mod || (mod == state->win_emu_.mod_manager.executable || state->modules_.contains(mod->name));
if (!is_main_access && !state->verbose_) if (!is_main_access && !state->verbose_)
{ {
@@ -142,8 +140,7 @@ namespace
const auto offset = address - env_ptr; const auto offset = address - env_ptr;
const auto* mod_name = mod ? mod->name.c_str() : "<N/A>"; const auto* mod_name = mod ? mod->name.c_str() : "<N/A>";
state->win_emu_.log.print(is_main_access ? color::green : color::dark_gray, state->win_emu_.log.print(is_main_access ? color::green : color::dark_gray,
"Environment access: 0x%" PRIx64 " (0x%zX) at 0x%" PRIx64 " (%s)\n", offset, "Environment access: 0x%" PRIx64 " (0x%zX) at 0x%" PRIx64 " (%s)\n", offset, size, rip, mod_name);
size, rip, mod_name);
}; };
state->env_data_hook_ = state->win_emu_.emu().hook_memory_read(env_ptr, env_size, std::move(hook_handler)); state->env_data_hook_ = state->win_emu_.emu().hook_memory_read(env_ptr, env_size, std::move(hook_handler));
@@ -157,8 +154,7 @@ namespace
[&win_emu, install = std::move(install_env_access_hook)](const uint64_t address, const void*, size_t) { [&win_emu, install = std::move(install_env_access_hook)](const uint64_t address, const void*, size_t) {
const auto new_process_params = get_process_params(win_emu); const auto new_process_params = get_process_params(win_emu);
const auto target_address = const auto target_address = new_process_params.value() + offsetof(RTL_USER_PROCESS_PARAMETERS64, Environment);
new_process_params.value() + offsetof(RTL_USER_PROCESS_PARAMETERS64, Environment);
if (address == target_address) if (address == target_address)
{ {
@@ -168,8 +164,7 @@ namespace
} }
#endif #endif
void watch_system_objects(windows_emulator& win_emu, const std::set<std::string, std::less<>>& modules, void watch_system_objects(windows_emulator& win_emu, const std::set<std::string, std::less<>>& modules, const bool verbose)
const bool verbose)
{ {
win_emu.setup_process_if_necessary(); win_emu.setup_process_if_necessary();
@@ -193,20 +188,18 @@ namespace
update_env_hook(); update_env_hook();
win_emu.emu().hook_memory_write( win_emu.emu().hook_memory_write(win_emu.process.peb.value() + offsetof(PEB64, ProcessParameters), 0x8,
win_emu.process.peb.value() + offsetof(PEB64, ProcessParameters), 0x8, [state, update_env = std::move(update_env_hook)](const uint64_t, const void*, size_t) {
[state, update_env = std::move(update_env_hook)](const uint64_t, const void*, size_t) { const auto new_ptr = state->win_emu_.process.peb.read().ProcessParameters;
const auto new_ptr = state->win_emu_.process.peb.read().ProcessParameters; state->params_hook_ = watch_object<RTL_USER_PROCESS_PARAMETERS64>(
state->params_hook_ = watch_object<RTL_USER_PROCESS_PARAMETERS64>(state->win_emu_, state->modules_, state->win_emu_, state->modules_, new_ptr, state->verbose_);
new_ptr, state->verbose_); update_env();
update_env(); });
});
win_emu.emu().hook_memory_write( win_emu.emu().hook_memory_write(
win_emu.process.peb.value() + offsetof(PEB64, Ldr), 0x8, [state](const uint64_t, const void*, size_t) { win_emu.process.peb.value() + offsetof(PEB64, Ldr), 0x8, [state](const uint64_t, const void*, size_t) {
const auto new_ptr = state->win_emu_.process.peb.read().Ldr; const auto new_ptr = state->win_emu_.process.peb.read().Ldr;
state->ldr_hook_ = state->ldr_hook_ = watch_object<PEB_LDR_DATA64>(state->win_emu_, state->modules_, new_ptr, state->verbose_);
watch_object<PEB_LDR_DATA64>(state->win_emu_, state->modules_, new_ptr, state->verbose_);
}); });
#endif #endif
} }
@@ -232,8 +225,7 @@ namespace
{ {
if (c.settings->buffer_stdout) if (c.settings->buffer_stdout)
{ {
c.win_emu->log.info("%.*s%s", static_cast<int>(c.output.size()), c.output.data(), c.win_emu->log.info("%.*s%s", static_cast<int>(c.output.size()), c.output.data(), c.output.ends_with("\n") ? "" : "\n");
c.output.ends_with("\n") ? "" : "\n");
} }
} }
@@ -302,8 +294,7 @@ namespace
catch (const std::exception& e) catch (const std::exception& e)
{ {
do_post_emulation_work(c); do_post_emulation_work(c);
win_emu.log.error("Emulation failed at: 0x%" PRIx64 " - %s\n", win_emu.emu().read_instruction_pointer(), win_emu.log.error("Emulation failed at: 0x%" PRIx64 " - %s\n", win_emu.emu().read_instruction_pointer(), e.what());
e.what());
throw; throw;
} }
catch (...) catch (...)
@@ -327,8 +318,7 @@ namespace
{ {
do_post_emulation_work(c); do_post_emulation_work(c);
win_emu.log.disable_output(false); win_emu.log.disable_output(false);
win_emu.log.print(success ? color::green : color::red, "Emulation terminated with status: %X\n", win_emu.log.print(success ? color::green : color::red, "Emulation terminated with status: %X\n", *exit_status);
*exit_status);
} }
return success; return success;
@@ -380,8 +370,7 @@ namespace
return std::make_unique<windows_emulator>(create_x86_64_emulator(), std::move(app_settings), settings); return std::make_unique<windows_emulator>(create_x86_64_emulator(), std::move(app_settings), settings);
} }
std::unique_ptr<windows_emulator> setup_emulator(const analysis_options& options, std::unique_ptr<windows_emulator> setup_emulator(const analysis_options& options, const std::span<const std::string_view> args)
const std::span<const std::string_view> args)
{ {
if (!options.dump.empty()) if (!options.dump.empty())
{ {
@@ -462,8 +451,8 @@ namespace
if (mod.has_value()) if (mod.has_value())
{ {
const auto leaf = win_emu->emu().reg<uint32_t>(x86_register::eax); const auto leaf = win_emu->emu().reg<uint32_t>(x86_register::eax);
win_emu->log.print(color::blue, "Executing CPUID instruction with leaf 0x%X at 0x%" PRIx64 " (%s)\n", win_emu->log.print(color::blue, "Executing CPUID instruction with leaf 0x%X at 0x%" PRIx64 " (%s)\n", leaf, rip,
leaf, rip, (*mod) ? (*mod)->name.c_str() : "<N/A>"); (*mod) ? (*mod)->name.c_str() : "<N/A>");
} }
return instruction_hook_continuation::run_instruction; return instruction_hook_continuation::run_instruction;
@@ -473,8 +462,7 @@ namespace
{ {
auto module_cache = std::make_shared<std::map<std::string, uint64_t>>(); auto module_cache = std::make_shared<std::map<std::string, uint64_t>>();
win_emu->emu().hook_memory_read( win_emu->emu().hook_memory_read(
0, std::numeric_limits<uint64_t>::max(), 0, std::numeric_limits<uint64_t>::max(), [&, module_cache](const uint64_t address, const void*, size_t) {
[&, module_cache](const uint64_t address, const void*, size_t) {
const auto rip = win_emu->emu().read_instruction_pointer(); const auto rip = win_emu->emu().read_instruction_pointer();
const auto accessor = get_module_if_interesting(win_emu->mod_manager, options.modules, rip); const auto accessor = get_module_if_interesting(win_emu->mod_manager, options.modules, rip);
@@ -500,10 +488,8 @@ namespace
const auto* region_name = get_module_memory_region_name(*mod, address); const auto* region_name = get_module_memory_region_name(*mod, address);
win_emu->log.print(color::pink, win_emu->log.print(color::pink, "Reading from module %s at 0x%" PRIx64 " (%s) via 0x%" PRIx64 " (%s)\n",
"Reading from module %s at 0x%" PRIx64 " (%s) via 0x%" PRIx64 " (%s)\n", mod->name.c_str(), address, region_name, rip, (*accessor) ? (*accessor)->name.c_str() : "<N/A>");
mod->name.c_str(), address, region_name, rip,
(*accessor) ? (*accessor)->name.c_str() : "<N/A>");
}); });
} }
@@ -533,8 +519,7 @@ namespace
} }
} }
win_emu->log.print(color::green, win_emu->log.print(color::green, "Reading from executable section %s at 0x%" PRIx64 " via 0x%" PRIx64 "\n",
"Reading from executable section %s at 0x%" PRIx64 " via 0x%" PRIx64 "\n",
section.name.c_str(), address, rip); section.name.c_str(), address, rip);
}; };
@@ -555,8 +540,7 @@ namespace
} }
} }
win_emu->log.print(color::blue, win_emu->log.print(color::blue, "Writing to executable section %s at 0x%" PRIx64 " via 0x%" PRIx64 "\n",
"Writing to executable section %s at 0x%" PRIx64 " via 0x%" PRIx64 "\n",
section.name.c_str(), address, rip); section.name.c_str(), address, rip);
}; };

View File

@@ -5,8 +5,8 @@
#include <cinttypes> #include <cinttypes>
template <typename T> template <typename T>
emulator_hook* watch_object(windows_emulator& emu, const std::set<std::string, std::less<>>& modules, emulator_hook* watch_object(windows_emulator& emu, const std::set<std::string, std::less<>>& modules, emulator_object<T> object,
emulator_object<T> object, const auto verbose) const auto verbose)
{ {
const reflect_type_info<T> info{}; const reflect_type_info<T> info{};
@@ -37,14 +37,14 @@ emulator_hook* watch_object(windows_emulator& emu, const std::set<std::string, s
const auto member_name = i.get_member_name(static_cast<size_t>(offset)); const auto member_name = i.get_member_name(static_cast<size_t>(offset));
emu.log.print(is_main_access ? color::green : color::dark_gray, emu.log.print(is_main_access ? color::green : color::dark_gray,
"Object access: %s - 0x%" PRIx64 " 0x%zx (%s) at 0x%" PRIx64 " (%s)\n", type_name.c_str(), "Object access: %s - 0x%" PRIx64 " 0x%zx (%s) at 0x%" PRIx64 " (%s)\n", type_name.c_str(), offset, size,
offset, size, member_name.c_str(), rip, mod_name); member_name.c_str(), rip, mod_name);
}); });
} }
template <typename T> template <typename T>
emulator_hook* watch_object(windows_emulator& emu, const std::set<std::string, std::less<>>& modules, emulator_hook* watch_object(windows_emulator& emu, const std::set<std::string, std::less<>>& modules, const uint64_t address,
const uint64_t address, const auto verbose) const auto verbose)
{ {
return watch_object<T>(emu, modules, emulator_object<T>{emu.emu(), address}, verbose); return watch_object<T>(emu, modules, emulator_object<T>{emu.emu(), address}, verbose);
} }

File diff suppressed because it is too large Load Diff

View File

@@ -85,8 +85,7 @@ namespace snapshot
std::filesystem::path write_emulator_snapshot(const windows_emulator& win_emu, const bool log) std::filesystem::path write_emulator_snapshot(const windows_emulator& win_emu, const bool log)
{ {
std::filesystem::path snapshot_file = std::filesystem::path snapshot_file = get_main_executable_name(win_emu) + "-" + std::to_string(time(nullptr)) + ".snap";
get_main_executable_name(win_emu) + "-" + std::to_string(time(nullptr)) + ".snap";
if (log) if (log)
{ {

View File

@@ -23,8 +23,8 @@ extern "C"
icicle_emulator* icicle_create_emulator(); icicle_emulator* icicle_create_emulator();
int32_t icicle_protect_memory(icicle_emulator*, uint64_t address, uint64_t length, uint8_t permissions); int32_t icicle_protect_memory(icicle_emulator*, uint64_t address, uint64_t length, uint8_t permissions);
int32_t icicle_map_memory(icicle_emulator*, uint64_t address, uint64_t length, uint8_t permissions); int32_t icicle_map_memory(icicle_emulator*, uint64_t address, uint64_t length, uint8_t permissions);
int32_t icicle_map_mmio(icicle_emulator*, uint64_t address, uint64_t length, icicle_mmio_read_func* read_callback, int32_t icicle_map_mmio(icicle_emulator*, uint64_t address, uint64_t length, icicle_mmio_read_func* read_callback, void* read_data,
void* read_data, icicle_mmio_write_func* write_callback, void* write_data); icicle_mmio_write_func* write_callback, void* write_data);
int32_t icicle_unmap_memory(icicle_emulator*, uint64_t address, uint64_t length); int32_t icicle_unmap_memory(icicle_emulator*, uint64_t address, uint64_t length);
int32_t icicle_read_memory(icicle_emulator*, uint64_t address, void* data, size_t length); int32_t icicle_read_memory(icicle_emulator*, uint64_t address, void* data, size_t length);
int32_t icicle_write_memory(icicle_emulator*, uint64_t address, const void* data, size_t length); int32_t icicle_write_memory(icicle_emulator*, uint64_t address, const void* data, size_t length);
@@ -188,8 +188,7 @@ namespace icicle
return icicle_read_register(this->emu_, reg, value, size); return icicle_read_register(this->emu_, reg, value, size);
} }
void map_mmio(const uint64_t address, const size_t size, mmio_read_callback read_cb, void map_mmio(const uint64_t address, const size_t size, mmio_read_callback read_cb, mmio_write_callback write_cb) override
mmio_write_callback write_cb) override
{ {
struct mmio_wrapper : utils::object struct mmio_wrapper : utils::object
{ {
@@ -314,8 +313,7 @@ namespace icicle
{ {
auto obj = make_function_object(std::move(callback), this->is_in_hook_); auto obj = make_function_object(std::move(callback), this->is_in_hook_);
auto* ptr = obj.get(); auto* ptr = obj.get();
auto* wrapper = auto* wrapper = +[](void* user, const uint64_t address, const uint8_t operation, const int32_t unmapped) -> int32_t {
+[](void* user, const uint64_t address, const uint8_t operation, const int32_t unmapped) -> int32_t {
const auto violation_type = unmapped // const auto violation_type = unmapped //
? memory_violation_type::unmapped ? memory_violation_type::unmapped
: memory_violation_type::protection; : memory_violation_type::protection;
@@ -361,8 +359,7 @@ namespace icicle
return wrap_hook(id); return wrap_hook(id);
} }
emulator_hook* hook_memory_read(const uint64_t address, const uint64_t size, emulator_hook* hook_memory_read(const uint64_t address, const uint64_t size, memory_access_hook_callback callback) override
memory_access_hook_callback callback) override
{ {
return this->try_install_memory_access_hook(memory_access_hook{ return this->try_install_memory_access_hook(memory_access_hook{
.address = address, .address = address,
@@ -372,8 +369,7 @@ namespace icicle
}); });
} }
emulator_hook* hook_memory_write(const uint64_t address, const uint64_t size, emulator_hook* hook_memory_write(const uint64_t address, const uint64_t size, memory_access_hook_callback callback) override
memory_access_hook_callback callback) override
{ {
return this->try_install_memory_access_hook(memory_access_hook{ return this->try_install_memory_access_hook(memory_access_hook{
.address = address, .address = address,

View File

@@ -286,8 +286,7 @@ namespace unicorn
if (size < result_size) if (size < result_size)
{ {
throw std::runtime_error("Register size mismatch: " + std::to_string(size) + throw std::runtime_error("Register size mismatch: " + std::to_string(size) + " != " + std::to_string(result_size));
" != " + std::to_string(result_size));
} }
return result_size; return result_size;
@@ -301,15 +300,13 @@ namespace unicorn
if (size < result_size) if (size < result_size)
{ {
throw std::runtime_error("Register size mismatch: " + std::to_string(size) + throw std::runtime_error("Register size mismatch: " + std::to_string(size) + " != " + std::to_string(result_size));
" != " + std::to_string(result_size));
} }
return result_size; return result_size;
} }
void map_mmio(const uint64_t address, const size_t size, mmio_read_callback read_cb, void map_mmio(const uint64_t address, const size_t size, mmio_read_callback read_cb, mmio_write_callback write_cb) override
mmio_write_callback write_cb) override
{ {
auto read_wrapper = [c = std::move(read_cb)](uc_engine*, const uint64_t addr, const uint32_t s) { auto read_wrapper = [c = std::move(read_cb)](uc_engine*, const uint64_t addr, const uint32_t s) {
assert_64bit_limit(s); assert_64bit_limit(s);
@@ -318,8 +315,7 @@ namespace unicorn
return value; return value;
}; };
auto write_wrapper = [c = std::move(write_cb)](uc_engine*, const uint64_t addr, const uint32_t s, auto write_wrapper = [c = std::move(write_cb)](uc_engine*, const uint64_t addr, const uint32_t s, const uint64_t value) {
const uint64_t value) {
assert_64bit_limit(s); assert_64bit_limit(s);
c(addr, &value, s); c(addr, &value, s);
}; };
@@ -329,8 +325,8 @@ namespace unicorn
.write = mmio_callbacks::write_wrapper(std::move(write_wrapper)), .write = mmio_callbacks::write_wrapper(std::move(write_wrapper)),
}; };
uce(uc_mmio_map(*this, address, size, cb.read.get_c_function(), cb.read.get_user_data(), uce(uc_mmio_map(*this, address, size, cb.read.get_c_function(), cb.read.get_user_data(), cb.write.get_c_function(),
cb.write.get_c_function(), cb.write.get_user_data())); cb.write.get_user_data()));
this->mmio_[address] = std::move(cb); this->mmio_[address] = std::move(cb);
} }
@@ -366,8 +362,7 @@ namespace unicorn
uce(uc_mem_write(*this, address, data, size)); uce(uc_mem_write(*this, address, data, size));
} }
void apply_memory_protection(const uint64_t address, const size_t size, void apply_memory_protection(const uint64_t address, const size_t size, memory_permission permissions) override
memory_permission permissions) override
{ {
uce(uc_mem_protect(*this, address, size, static_cast<uint32_t>(permissions))); uce(uc_mem_protect(*this, address, size, static_cast<uint32_t>(permissions)));
} }
@@ -381,12 +376,11 @@ namespace unicorn
if (inst_type == x86_hookable_instructions::invalid) if (inst_type == x86_hookable_instructions::invalid)
{ {
function_wrapper<int, uc_engine*> wrapper([c = std::move(callback)](uc_engine*) { function_wrapper<int, uc_engine*> wrapper(
return (c() == instruction_hook_continuation::skip_instruction) ? 1 : 0; [c = std::move(callback)](uc_engine*) { return (c() == instruction_hook_continuation::skip_instruction) ? 1 : 0; });
});
uce(uc_hook_add(*this, hook.make_reference(), UC_HOOK_INSN_INVALID, wrapper.get_function(), uce(uc_hook_add(*this, hook.make_reference(), UC_HOOK_INSN_INVALID, wrapper.get_function(), wrapper.get_user_data(), 0,
wrapper.get_user_data(), 0, std::numeric_limits<pointer_type>::max())); std::numeric_limits<pointer_type>::max()));
container->add(std::move(wrapper), std::move(hook)); container->add(std::move(wrapper), std::move(hook));
} }
else if (inst_type == x86_hookable_instructions::syscall) else if (inst_type == x86_hookable_instructions::syscall)
@@ -394,22 +388,19 @@ namespace unicorn
function_wrapper<void, uc_engine*> wrapper([c = std::move(callback)](uc_engine*) { c(); }); function_wrapper<void, uc_engine*> wrapper([c = std::move(callback)](uc_engine*) { c(); });
const auto uc_instruction = map_hookable_instruction(inst_type); const auto uc_instruction = map_hookable_instruction(inst_type);
uce(uc_hook_add(*this, hook.make_reference(), UC_HOOK_INSN, wrapper.get_function(), uce(uc_hook_add(*this, hook.make_reference(), UC_HOOK_INSN, wrapper.get_function(), wrapper.get_user_data(), 0,
wrapper.get_user_data(), 0, std::numeric_limits<pointer_type>::max(), std::numeric_limits<pointer_type>::max(), uc_instruction));
uc_instruction));
container->add(std::move(wrapper), std::move(hook)); container->add(std::move(wrapper), std::move(hook));
} }
else else
{ {
function_wrapper<int, uc_engine*> wrapper([c = std::move(callback)](uc_engine*) { function_wrapper<int, uc_engine*> wrapper(
return (c() == instruction_hook_continuation::skip_instruction) ? 1 : 0; [c = std::move(callback)](uc_engine*) { return (c() == instruction_hook_continuation::skip_instruction) ? 1 : 0; });
});
const auto uc_instruction = map_hookable_instruction(inst_type); const auto uc_instruction = map_hookable_instruction(inst_type);
uce(uc_hook_add(*this, hook.make_reference(), UC_HOOK_INSN, wrapper.get_function(), uce(uc_hook_add(*this, hook.make_reference(), UC_HOOK_INSN, wrapper.get_function(), wrapper.get_user_data(), 0,
wrapper.get_user_data(), 0, std::numeric_limits<pointer_type>::max(), std::numeric_limits<pointer_type>::max(), uc_instruction));
uc_instruction));
container->add(std::move(wrapper), std::move(hook)); container->add(std::move(wrapper), std::move(hook));
} }
@@ -435,8 +426,8 @@ namespace unicorn
unicorn_hook hook{*this}; unicorn_hook hook{*this};
auto container = std::make_unique<hook_container>(); auto container = std::make_unique<hook_container>();
uce(uc_hook_add(*this, hook.make_reference(), UC_HOOK_BLOCK, wrapper.get_function(), uce(uc_hook_add(*this, hook.make_reference(), UC_HOOK_BLOCK, wrapper.get_function(), wrapper.get_user_data(), 0,
wrapper.get_user_data(), 0, std::numeric_limits<pointer_type>::max())); std::numeric_limits<pointer_type>::max()));
container->add(std::move(wrapper), std::move(hook)); container->add(std::move(wrapper), std::move(hook));
@@ -453,8 +444,8 @@ namespace unicorn
unicorn_hook hook{*this}; unicorn_hook hook{*this};
auto container = std::make_unique<hook_container>(); auto container = std::make_unique<hook_container>();
uce(uc_hook_add(*this, hook.make_reference(), UC_HOOK_INTR, wrapper.get_function(), uce(uc_hook_add(*this, hook.make_reference(), UC_HOOK_INTR, wrapper.get_function(), wrapper.get_user_data(), 0,
wrapper.get_user_data(), 0, std::numeric_limits<pointer_type>::max())); std::numeric_limits<pointer_type>::max()));
container->add(std::move(wrapper), std::move(hook)); container->add(std::move(wrapper), std::move(hook));
@@ -466,16 +457,16 @@ namespace unicorn
emulator_hook* hook_memory_violation(memory_violation_hook_callback callback) override emulator_hook* hook_memory_violation(memory_violation_hook_callback callback) override
{ {
function_wrapper<bool, uc_engine*, uc_mem_type, uint64_t, int, int64_t> wrapper( function_wrapper<bool, uc_engine*, uc_mem_type, uint64_t, int, int64_t> wrapper(
[c = std::move(callback), this](uc_engine*, const uc_mem_type type, const uint64_t address, [c = std::move(callback), this](uc_engine*, const uc_mem_type type, const uint64_t address, const int size,
const int size, const int64_t) { const int64_t) {
const auto ip = this->read_instruction_pointer(); const auto ip = this->read_instruction_pointer();
assert(size >= 0); assert(size >= 0);
const auto operation = map_memory_operation(type); const auto operation = map_memory_operation(type);
const auto violation = map_memory_violation_type(type); const auto violation = map_memory_violation_type(type);
const auto resume = c(address, static_cast<uint64_t>(size), operation, violation) == const auto resume =
memory_violation_continuation::resume; c(address, static_cast<uint64_t>(size), operation, violation) == memory_violation_continuation::resume;
const auto has_ip_changed = ip != this->read_instruction_pointer(); const auto has_ip_changed = ip != this->read_instruction_pointer();
@@ -497,8 +488,8 @@ namespace unicorn
unicorn_hook hook{*this}; unicorn_hook hook{*this};
auto container = std::make_unique<hook_container>(); auto container = std::make_unique<hook_container>();
uce(uc_hook_add(*this, hook.make_reference(), UC_HOOK_MEM_INVALID, wrapper.get_function(), uce(uc_hook_add(*this, hook.make_reference(), UC_HOOK_MEM_INVALID, wrapper.get_function(), wrapper.get_user_data(), 0,
wrapper.get_user_data(), 0, std::numeric_limits<uint64_t>::max())); std::numeric_limits<uint64_t>::max()));
container->add(std::move(wrapper), std::move(hook)); container->add(std::move(wrapper), std::move(hook));
@@ -507,11 +498,9 @@ namespace unicorn
return result; return result;
} }
emulator_hook* hook_memory_execution(const uint64_t address, const uint64_t size, emulator_hook* hook_memory_execution(const uint64_t address, const uint64_t size, memory_execution_hook_callback callback)
memory_execution_hook_callback callback)
{ {
auto exec_wrapper = [c = std::move(callback)](uc_engine*, const uint64_t address, auto exec_wrapper = [c = std::move(callback)](uc_engine*, const uint64_t address, const uint32_t /*size*/) {
const uint32_t /*size*/) {
c(address); // c(address); //
}; };
@@ -519,8 +508,8 @@ namespace unicorn
unicorn_hook hook{*this}; unicorn_hook hook{*this};
uce(uc_hook_add(*this, hook.make_reference(), UC_HOOK_CODE, wrapper.get_function(), uce(uc_hook_add(*this, hook.make_reference(), UC_HOOK_CODE, wrapper.get_function(), wrapper.get_user_data(), address,
wrapper.get_user_data(), address, address + size)); address + size));
auto* container = this->create_hook_container(); auto* container = this->create_hook_container();
container->add(std::move(wrapper), std::move(hook)); container->add(std::move(wrapper), std::move(hook));
@@ -532,17 +521,14 @@ namespace unicorn
return this->hook_memory_execution(0, std::numeric_limits<uint64_t>::max(), std::move(callback)); return this->hook_memory_execution(0, std::numeric_limits<uint64_t>::max(), std::move(callback));
} }
emulator_hook* hook_memory_execution(const uint64_t address, emulator_hook* hook_memory_execution(const uint64_t address, memory_execution_hook_callback callback) override
memory_execution_hook_callback callback) override
{ {
return this->hook_memory_execution(address, 1, std::move(callback)); return this->hook_memory_execution(address, 1, std::move(callback));
} }
emulator_hook* hook_memory_read(const uint64_t address, const uint64_t size, emulator_hook* hook_memory_read(const uint64_t address, const uint64_t size, memory_access_hook_callback callback) override
memory_access_hook_callback callback) override
{ {
auto read_wrapper = [c = std::move(callback)](uc_engine*, const uc_mem_type type, auto read_wrapper = [c = std::move(callback)](uc_engine*, const uc_mem_type type, const uint64_t address, const int length,
const uint64_t address, const int length,
const uint64_t value) { const uint64_t value) {
const auto operation = map_memory_operation(type); const auto operation = map_memory_operation(type);
if (operation == memory_operation::read && length > 0) if (operation == memory_operation::read && length > 0)
@@ -551,23 +537,21 @@ namespace unicorn
} }
}; };
function_wrapper<void, uc_engine*, uc_mem_type, uint64_t, int, int64_t> wrapper( function_wrapper<void, uc_engine*, uc_mem_type, uint64_t, int, int64_t> wrapper(std::move(read_wrapper));
std::move(read_wrapper));
unicorn_hook hook{*this}; unicorn_hook hook{*this};
uce(uc_hook_add(*this, hook.make_reference(), UC_HOOK_MEM_READ_AFTER, wrapper.get_function(), uce(uc_hook_add(*this, hook.make_reference(), UC_HOOK_MEM_READ_AFTER, wrapper.get_function(), wrapper.get_user_data(),
wrapper.get_user_data(), address, address + size)); address, address + size));
auto* container = this->create_hook_container(); auto* container = this->create_hook_container();
container->add(std::move(wrapper), std::move(hook)); container->add(std::move(wrapper), std::move(hook));
return container->as_opaque_hook(); return container->as_opaque_hook();
} }
emulator_hook* hook_memory_write(const uint64_t address, const uint64_t size, emulator_hook* hook_memory_write(const uint64_t address, const uint64_t size, memory_access_hook_callback callback) override
memory_access_hook_callback callback) override
{ {
auto write_wrapper = [c = std::move(callback)](uc_engine*, const uc_mem_type type, const uint64_t addr, auto write_wrapper = [c = std::move(callback)](uc_engine*, const uc_mem_type type, const uint64_t addr, const int length,
const int length, const uint64_t value) { const uint64_t value) {
const auto operation = map_memory_operation(type); const auto operation = map_memory_operation(type);
if (operation == memory_operation::write && length > 0) if (operation == memory_operation::write && length > 0)
{ {
@@ -575,13 +559,12 @@ namespace unicorn
} }
}; };
function_wrapper<void, uc_engine*, uc_mem_type, uint64_t, int, int64_t> wrapper( function_wrapper<void, uc_engine*, uc_mem_type, uint64_t, int, int64_t> wrapper(std::move(write_wrapper));
std::move(write_wrapper));
unicorn_hook hook{*this}; unicorn_hook hook{*this};
uce(uc_hook_add(*this, hook.make_reference(), UC_HOOK_MEM_WRITE, wrapper.get_function(), uce(uc_hook_add(*this, hook.make_reference(), UC_HOOK_MEM_WRITE, wrapper.get_function(), wrapper.get_user_data(), address,
wrapper.get_user_data(), address, address + size)); address + size));
auto* container = this->create_hook_container(); auto* container = this->create_hook_container();
container->add(std::move(wrapper), std::move(hook)); container->add(std::move(wrapper), std::move(hook));
@@ -598,10 +581,8 @@ namespace unicorn
void delete_hook(emulator_hook* hook) override void delete_hook(emulator_hook* hook) override
{ {
const auto entry = const auto entry = std::ranges::find_if(
std::ranges::find_if(this->hooks_, [&](const std::unique_ptr<hook_object>& hook_ptr) { this->hooks_, [&](const std::unique_ptr<hook_object>& hook_ptr) { return hook_ptr->as_opaque_hook() == hook; });
return hook_ptr->as_opaque_hook() == hook;
});
if (entry != this->hooks_.end()) if (entry != this->hooks_.end())
{ {

View File

@@ -89,8 +89,7 @@ namespace network
if (this->is_ipv6()) if (this->is_ipv6())
{ {
return !memcmp(this->address6_.sin6_addr.s6_addr, obj.address6_.sin6_addr.s6_addr, return !memcmp(this->address6_.sin6_addr.s6_addr, obj.address6_.sin6_addr.s6_addr, sizeof(obj.address6_.sin6_addr.s6_addr));
sizeof(obj.address6_.sin6_addr.s6_addr));
} }
return false; return false;
@@ -369,9 +368,8 @@ std::size_t std::hash<network::address>::operator()(const network::address& a) c
hash ^= std::hash<decltype(a.get_in_addr().sin_addr.s_addr)>{}(a.get_in_addr().sin_addr.s_addr); hash ^= std::hash<decltype(a.get_in_addr().sin_addr.s_addr)>{}(a.get_in_addr().sin_addr.s_addr);
break; break;
case AF_INET6: case AF_INET6:
hash ^= std::hash<std::string_view>{}( hash ^= std::hash<std::string_view>{}(std::string_view{reinterpret_cast<const char*>(a.get_in6_addr().sin6_addr.s6_addr),
std::string_view{reinterpret_cast<const char*>(a.get_in6_addr().sin6_addr.s6_addr), sizeof(a.get_in6_addr().sin6_addr.s6_addr)});
sizeof(a.get_in6_addr().sin6_addr.s6_addr)});
break; break;
default: default:
break; break;

View File

@@ -20,13 +20,11 @@ namespace network
if (af == AF_INET6) if (af == AF_INET6)
{ {
int i = 1; int i = 1;
setsockopt(this->socket_, IPPROTO_IPV6, IPV6_V6ONLY, reinterpret_cast<char*>(&i), setsockopt(this->socket_, IPPROTO_IPV6, IPV6_V6ONLY, reinterpret_cast<char*>(&i), static_cast<int>(sizeof(i)));
static_cast<int>(sizeof(i)));
} }
int optval = 1; int optval = 1;
setsockopt(this->socket_, SOL_SOCKET, SO_REUSEADDR, reinterpret_cast<char*>(&optval), setsockopt(this->socket_, SOL_SOCKET, SO_REUSEADDR, reinterpret_cast<char*>(&optval), static_cast<int>(sizeof(optval)));
static_cast<int>(sizeof(optval)));
} }
socket::~socket() socket::~socket()
@@ -158,8 +156,7 @@ namespace network
return this->is_valid() && is_socket_ready(this->socket_, in_poll); return this->is_valid() && is_socket_ready(this->socket_, in_poll);
} }
bool socket::sleep_sockets(const std::span<const socket*>& sockets, const std::chrono::milliseconds timeout, bool socket::sleep_sockets(const std::span<const socket*>& sockets, const std::chrono::milliseconds timeout, const bool in_poll)
const bool in_poll)
{ {
std::vector<pollfd> pfds{}; std::vector<pollfd> pfds{};
pfds.resize(sockets.size()); pfds.resize(sockets.size());
@@ -215,8 +212,7 @@ namespace network
} }
bool socket::sleep_sockets_until(const std::span<const socket*>& sockets, bool socket::sleep_sockets_until(const std::span<const socket*>& sockets,
const std::chrono::high_resolution_clock::time_point time_point, const std::chrono::high_resolution_clock::time_point time_point, const bool in_poll)
const bool in_poll)
{ {
const auto duration = time_point - std::chrono::high_resolution_clock::now(); const auto duration = time_point - std::chrono::high_resolution_clock::now();
return sleep_sockets(sockets, std::chrono::duration_cast<std::chrono::milliseconds>(duration), in_poll); return sleep_sockets(sockets, std::chrono::duration_cast<std::chrono::milliseconds>(duration), in_poll);

View File

@@ -63,10 +63,9 @@ namespace network
bool is_ready(bool in_poll) const; bool is_ready(bool in_poll) const;
static bool sleep_sockets(const std::span<const socket*>& sockets, std::chrono::milliseconds timeout, static bool sleep_sockets(const std::span<const socket*>& sockets, std::chrono::milliseconds timeout, bool in_poll);
bool in_poll); static bool sleep_sockets_until(const std::span<const socket*>& sockets, std::chrono::high_resolution_clock::time_point time_point,
static bool sleep_sockets_until(const std::span<const socket*>& sockets, bool in_poll);
std::chrono::high_resolution_clock::time_point time_point, bool in_poll);
static bool is_socket_ready(SOCKET s, bool in_poll); static bool is_socket_ready(SOCKET s, bool in_poll);

View File

@@ -17,8 +17,8 @@ namespace network
{ {
while (true) while (true)
{ {
const auto res = sendto(this->get_socket(), data.data(), static_cast<send_size>(data.size()), 0, const auto res =
&target.get_addr(), target.get_size()); sendto(this->get_socket(), data.data(), static_cast<send_size>(data.size()), 0, &target.get_addr(), target.get_size());
if (res < 0 && GET_SOCKET_ERROR() == SERR(EWOULDBLOCK)) if (res < 0 && GET_SOCKET_ERROR() == SERR(EWOULDBLOCK))
{ {
@@ -36,8 +36,7 @@ namespace network
address source{}; address source{};
auto len = source.get_max_size(); auto len = source.get_max_size();
const auto result = const auto result = recvfrom(this->get_socket(), buffer.data(), static_cast<int>(buffer.size()), 0, &source.get_addr(), &len);
recvfrom(this->get_socket(), buffer.data(), static_cast<int>(buffer.size()), 0, &source.get_addr(), &len);
if (result == SOCKET_ERROR) if (result == SOCKET_ERROR)
{ {
return std::nullopt; return std::nullopt;

View File

@@ -77,14 +77,13 @@
#define SEC_RESERVE 0x04000000 #define SEC_RESERVE 0x04000000
#endif #endif
#define CTL_CODE(DeviceType, Function, Method, Access) \ #define CTL_CODE(DeviceType, Function, Method, Access) (((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method))
(((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method))
#define METHOD_BUFFERED 0 #define METHOD_BUFFERED 0
#define FILE_ANY_ACCESS 0 #define FILE_ANY_ACCESS 0
#define FILE_READ_ACCESS (0x0001) // file & pipe #define FILE_READ_ACCESS (0x0001) // file & pipe
#define FILE_WRITE_ACCESS (0x0002) // file & pipe #define FILE_WRITE_ACCESS (0x0002) // file & pipe
typedef enum _FSINFOCLASS typedef enum _FSINFOCLASS
{ {
@@ -147,10 +146,10 @@ typedef enum _FILE_INFORMATION_CLASS
FileMailslotQueryInformation, // q: FILE_MAILSLOT_QUERY_INFORMATION FileMailslotQueryInformation, // q: FILE_MAILSLOT_QUERY_INFORMATION
FileMailslotSetInformation, // s: FILE_MAILSLOT_SET_INFORMATION FileMailslotSetInformation, // s: FILE_MAILSLOT_SET_INFORMATION
FileCompressionInformation, // q: FILE_COMPRESSION_INFORMATION FileCompressionInformation, // q: FILE_COMPRESSION_INFORMATION
FileObjectIdInformation, // q: FILE_OBJECTID_INFORMATION (requires FILE_LIST_DIRECTORY) (NtQueryDirectoryFile[Ex]) FileObjectIdInformation, // q: FILE_OBJECTID_INFORMATION (requires FILE_LIST_DIRECTORY) (NtQueryDirectoryFile[Ex])
FileCompletionInformation, // s: FILE_COMPLETION_INFORMATION // 30 FileCompletionInformation, // s: FILE_COMPLETION_INFORMATION // 30
FileMoveClusterInformation, // s: FILE_MOVE_CLUSTER_INFORMATION (requires FILE_WRITE_DATA) FileMoveClusterInformation, // s: FILE_MOVE_CLUSTER_INFORMATION (requires FILE_WRITE_DATA)
FileQuotaInformation, // q: FILE_QUOTA_INFORMATION (requires FILE_LIST_DIRECTORY) (NtQueryDirectoryFile[Ex]) FileQuotaInformation, // q: FILE_QUOTA_INFORMATION (requires FILE_LIST_DIRECTORY) (NtQueryDirectoryFile[Ex])
FileReparsePointInformation, FileReparsePointInformation,
// q: FILE_REPARSE_POINT_INFORMATION (requires FILE_LIST_DIRECTORY) (NtQueryDirectoryFile[Ex]) // q: FILE_REPARSE_POINT_INFORMATION (requires FILE_LIST_DIRECTORY) (NtQueryDirectoryFile[Ex])
FileNetworkOpenInformation, // q: FILE_NETWORK_OPEN_INFORMATION (requires FILE_READ_ATTRIBUTES) FileNetworkOpenInformation, // q: FILE_NETWORK_OPEN_INFORMATION (requires FILE_READ_ATTRIBUTES)

View File

@@ -21,9 +21,8 @@
#define CONTEXT_XSTATE_32 (CONTEXT_X86_MAIN | 0x20L) #define CONTEXT_XSTATE_32 (CONTEXT_X86_MAIN | 0x20L)
#define CONTEXT_XSTATE_64 (CONTEXT_AMD64_MAIN | 0x20L) #define CONTEXT_XSTATE_64 (CONTEXT_AMD64_MAIN | 0x20L)
#define CONTEXT64_ALL \ #define CONTEXT64_ALL \
(CONTEXT_CONTROL_64 | CONTEXT_INTEGER_64 | CONTEXT_SEGMENTS_64 | CONTEXT_FLOATING_POINT_64 | \ (CONTEXT_CONTROL_64 | CONTEXT_INTEGER_64 | CONTEXT_SEGMENTS_64 | CONTEXT_FLOATING_POINT_64 | CONTEXT_DEBUG_REGISTERS_64)
CONTEXT_DEBUG_REGISTERS_64)
using SYSTEM_INFORMATION_CLASS = enum _SYSTEM_INFORMATION_CLASS using SYSTEM_INFORMATION_CLASS = enum _SYSTEM_INFORMATION_CLASS
{ {
@@ -62,16 +61,16 @@ using SYSTEM_INFORMATION_CLASS = enum _SYSTEM_INFORMATION_CLASS
SystemSummaryMemoryInformation, // not implemented // SYSTEM_MEMORY_USAGE_INFORMATION SystemSummaryMemoryInformation, // not implemented // SYSTEM_MEMORY_USAGE_INFORMATION
SystemMirrorMemoryInformation, SystemMirrorMemoryInformation,
// s (requires license value "Kernel-MemoryMirroringSupported") (requires SeShutdownPrivilege) // 30 // s (requires license value "Kernel-MemoryMirroringSupported") (requires SeShutdownPrivilege) // 30
SystemPerformanceTraceInformation, // q; s: (type depends on EVENT_TRACE_INFORMATION_CLASS) SystemPerformanceTraceInformation, // q; s: (type depends on EVENT_TRACE_INFORMATION_CLASS)
SystemObsolete0, // not implemented SystemObsolete0, // not implemented
SystemExceptionInformation, // q: SYSTEM_EXCEPTION_INFORMATION SystemExceptionInformation, // q: SYSTEM_EXCEPTION_INFORMATION
SystemCrashDumpStateInformation, // s: SYSTEM_CRASH_DUMP_STATE_INFORMATION (requires SeDebugPrivilege) SystemCrashDumpStateInformation, // s: SYSTEM_CRASH_DUMP_STATE_INFORMATION (requires SeDebugPrivilege)
SystemKernelDebuggerInformation, // q: SYSTEM_KERNEL_DEBUGGER_INFORMATION SystemKernelDebuggerInformation, // q: SYSTEM_KERNEL_DEBUGGER_INFORMATION
SystemContextSwitchInformation, // q: SYSTEM_CONTEXT_SWITCH_INFORMATION SystemContextSwitchInformation, // q: SYSTEM_CONTEXT_SWITCH_INFORMATION
SystemRegistryQuotaInformation, // q: SYSTEM_REGISTRY_QUOTA_INFORMATION; s (requires SeIncreaseQuotaPrivilege) SystemRegistryQuotaInformation, // q: SYSTEM_REGISTRY_QUOTA_INFORMATION; s (requires SeIncreaseQuotaPrivilege)
SystemExtendServiceTableInformation, // s (requires SeLoadDriverPrivilege) // loads win32k only SystemExtendServiceTableInformation, // s (requires SeLoadDriverPrivilege) // loads win32k only
SystemPrioritySeperation, // s (requires SeTcbPrivilege) SystemPrioritySeperation, // s (requires SeTcbPrivilege)
SystemVerifierAddDriverInformation, // s (requires SeDebugPrivilege) // 40 SystemVerifierAddDriverInformation, // s (requires SeDebugPrivilege) // 40
SystemVerifierRemoveDriverInformation, // s (requires SeDebugPrivilege) SystemVerifierRemoveDriverInformation, // s (requires SeDebugPrivilege)
SystemProcessorIdleInformation, // q: SYSTEM_PROCESSOR_IDLE_INFORMATION (EX in: USHORT ProcessorGroup) SystemProcessorIdleInformation, // q: SYSTEM_PROCESSOR_IDLE_INFORMATION (EX in: USHORT ProcessorGroup)
SystemLegacyDriverInformation, // q: SYSTEM_LEGACY_DRIVER_INFORMATION SystemLegacyDriverInformation, // q: SYSTEM_LEGACY_DRIVER_INFORMATION
@@ -87,26 +86,26 @@ using SYSTEM_INFORMATION_CLASS = enum _SYSTEM_INFORMATION_CLASS
SystemSessionProcessInformation, // q: SYSTEM_SESSION_PROCESS_INFORMATION SystemSessionProcessInformation, // q: SYSTEM_SESSION_PROCESS_INFORMATION
SystemLoadGdiDriverInSystemSpace, SystemLoadGdiDriverInSystemSpace,
// s: SYSTEM_GDI_DRIVER_INFORMATION (kernel-mode only) (same as SystemLoadGdiDriverInformation) // s: SYSTEM_GDI_DRIVER_INFORMATION (kernel-mode only) (same as SystemLoadGdiDriverInformation)
SystemNumaProcessorMap, // q: SYSTEM_NUMA_INFORMATION SystemNumaProcessorMap, // q: SYSTEM_NUMA_INFORMATION
SystemPrefetcherInformation, // q; s: PREFETCHER_INFORMATION // PfSnQueryPrefetcherInformation SystemPrefetcherInformation, // q; s: PREFETCHER_INFORMATION // PfSnQueryPrefetcherInformation
SystemExtendedProcessInformation, // q: SYSTEM_PROCESS_INFORMATION SystemExtendedProcessInformation, // q: SYSTEM_PROCESS_INFORMATION
SystemRecommendedSharedDataAlignment, // q: ULONG // KeGetRecommendedSharedDataAlignment SystemRecommendedSharedDataAlignment, // q: ULONG // KeGetRecommendedSharedDataAlignment
SystemComPlusPackage, // q; s: ULONG SystemComPlusPackage, // q; s: ULONG
SystemNumaAvailableMemory, // q: SYSTEM_NUMA_INFORMATION // 60 SystemNumaAvailableMemory, // q: SYSTEM_NUMA_INFORMATION // 60
SystemProcessorPowerInformation, // q: SYSTEM_PROCESSOR_POWER_INFORMATION (EX in: USHORT ProcessorGroup) SystemProcessorPowerInformation, // q: SYSTEM_PROCESSOR_POWER_INFORMATION (EX in: USHORT ProcessorGroup)
SystemEmulationBasicInformation, // q: SYSTEM_BASIC_INFORMATION SystemEmulationBasicInformation, // q: SYSTEM_BASIC_INFORMATION
SystemEmulationProcessorInformation, // q: SYSTEM_PROCESSOR_INFORMATION SystemEmulationProcessorInformation, // q: SYSTEM_PROCESSOR_INFORMATION
SystemExtendedHandleInformation, // q: SYSTEM_HANDLE_INFORMATION_EX SystemExtendedHandleInformation, // q: SYSTEM_HANDLE_INFORMATION_EX
SystemLostDelayedWriteInformation, // q: ULONG SystemLostDelayedWriteInformation, // q: ULONG
SystemBigPoolInformation, // q: SYSTEM_BIGPOOL_INFORMATION SystemBigPoolInformation, // q: SYSTEM_BIGPOOL_INFORMATION
SystemSessionPoolTagInformation, // q: SYSTEM_SESSION_POOLTAG_INFORMATION SystemSessionPoolTagInformation, // q: SYSTEM_SESSION_POOLTAG_INFORMATION
SystemSessionMappedViewInformation, // q: SYSTEM_SESSION_MAPPED_VIEW_INFORMATION SystemSessionMappedViewInformation, // q: SYSTEM_SESSION_MAPPED_VIEW_INFORMATION
SystemHotpatchInformation, // q; s: SYSTEM_HOTPATCH_CODE_INFORMATION SystemHotpatchInformation, // q; s: SYSTEM_HOTPATCH_CODE_INFORMATION
SystemObjectSecurityMode, // q: ULONG // 70 SystemObjectSecurityMode, // q: ULONG // 70
SystemWatchdogTimerHandler, // s: SYSTEM_WATCHDOG_HANDLER_INFORMATION // (kernel-mode only) SystemWatchdogTimerHandler, // s: SYSTEM_WATCHDOG_HANDLER_INFORMATION // (kernel-mode only)
SystemWatchdogTimerInformation, // q: SYSTEM_WATCHDOG_TIMER_INFORMATION // (kernel-mode only) SystemWatchdogTimerInformation, // q: SYSTEM_WATCHDOG_TIMER_INFORMATION // (kernel-mode only)
SystemLogicalProcessorInformation, // q: SYSTEM_LOGICAL_PROCESSOR_INFORMATION (EX in: USHORT ProcessorGroup) SystemLogicalProcessorInformation, // q: SYSTEM_LOGICAL_PROCESSOR_INFORMATION (EX in: USHORT ProcessorGroup)
SystemWow64SharedInformationObsolete, // not implemented SystemWow64SharedInformationObsolete, // not implemented
SystemRegisterFirmwareTableInformationHandler, // s: SYSTEM_FIRMWARE_TABLE_HANDLER // (kernel-mode only) SystemRegisterFirmwareTableInformationHandler, // s: SYSTEM_FIRMWARE_TABLE_HANDLER // (kernel-mode only)
SystemFirmwareTableInformation, // SYSTEM_FIRMWARE_TABLE_INFORMATION SystemFirmwareTableInformation, // SYSTEM_FIRMWARE_TABLE_INFORMATION
SystemModuleInformationEx, // q: RTL_PROCESS_MODULE_INFORMATION_EX SystemModuleInformationEx, // q: RTL_PROCESS_MODULE_INFORMATION_EX
@@ -147,7 +146,7 @@ using SYSTEM_INFORMATION_CLASS = enum _SYSTEM_INFORMATION_CLASS
SystemDynamicTimeZoneInformation, // q; s: RTL_DYNAMIC_TIME_ZONE_INFORMATION (requires SeTimeZonePrivilege) SystemDynamicTimeZoneInformation, // q; s: RTL_DYNAMIC_TIME_ZONE_INFORMATION (requires SeTimeZonePrivilege)
SystemCodeIntegrityInformation, // q: SYSTEM_CODEINTEGRITY_INFORMATION // SeCodeIntegrityQueryInformation SystemCodeIntegrityInformation, // q: SYSTEM_CODEINTEGRITY_INFORMATION // SeCodeIntegrityQueryInformation
SystemProcessorMicrocodeUpdateInformation, // s: SYSTEM_PROCESSOR_MICROCODE_UPDATE_INFORMATION SystemProcessorMicrocodeUpdateInformation, // s: SYSTEM_PROCESSOR_MICROCODE_UPDATE_INFORMATION
SystemProcessorBrandString, // q: CHAR[] // HaliQuerySystemInformation -> HalpGetProcessorBrandString, info class 23 SystemProcessorBrandString, // q: CHAR[] // HaliQuerySystemInformation -> HalpGetProcessorBrandString, info class 23
SystemVirtualAddressInformation, SystemVirtualAddressInformation,
// q: SYSTEM_VA_LIST_INFORMATION[]; s: SYSTEM_VA_LIST_INFORMATION[] (requires SeIncreaseQuotaPrivilege) // // q: SYSTEM_VA_LIST_INFORMATION[]; s: SYSTEM_VA_LIST_INFORMATION[] (requires SeIncreaseQuotaPrivilege) //
// MmQuerySystemVaInformation // MmQuerySystemVaInformation
@@ -223,9 +222,9 @@ using SYSTEM_INFORMATION_CLASS = enum _SYSTEM_INFORMATION_CLASS
SystemCodeIntegrityPolicyInformation, // q; s: SYSTEM_CODEINTEGRITYPOLICY_INFORMATION SystemCodeIntegrityPolicyInformation, // q; s: SYSTEM_CODEINTEGRITYPOLICY_INFORMATION
SystemIsolatedUserModeInformation, // q: SYSTEM_ISOLATED_USER_MODE_INFORMATION SystemIsolatedUserModeInformation, // q: SYSTEM_ISOLATED_USER_MODE_INFORMATION
SystemHardwareSecurityTestInterfaceResultsInformation, SystemHardwareSecurityTestInterfaceResultsInformation,
SystemSingleModuleInformation, // q: SYSTEM_SINGLE_MODULE_INFORMATION SystemSingleModuleInformation, // q: SYSTEM_SINGLE_MODULE_INFORMATION
SystemAllowedCpuSetsInformation, // s: SYSTEM_WORKLOAD_ALLOWED_CPU_SET_INFORMATION SystemAllowedCpuSetsInformation, // s: SYSTEM_WORKLOAD_ALLOWED_CPU_SET_INFORMATION
SystemVsmProtectionInformation, // q: SYSTEM_VSM_PROTECTION_INFORMATION (previously SystemDmaProtectionInformation) SystemVsmProtectionInformation, // q: SYSTEM_VSM_PROTECTION_INFORMATION (previously SystemDmaProtectionInformation)
SystemInterruptCpuSetsInformation, // q: SYSTEM_INTERRUPT_CPU_SET_INFORMATION // 170 SystemInterruptCpuSetsInformation, // q: SYSTEM_INTERRUPT_CPU_SET_INFORMATION // 170
SystemSecureBootPolicyFullInformation, // q: SYSTEM_SECUREBOOT_POLICY_FULL_INFORMATION SystemSecureBootPolicyFullInformation, // q: SYSTEM_SECUREBOOT_POLICY_FULL_INFORMATION
SystemCodeIntegrityPolicyFullInformation, SystemCodeIntegrityPolicyFullInformation,
@@ -366,18 +365,18 @@ typedef enum _TOKEN_INFORMATION_CLASS
TokenRestrictedDeviceClaimAttributes, // q: CLAIM_SECURITY_ATTRIBUTES_INFORMATION TokenRestrictedDeviceClaimAttributes, // q: CLAIM_SECURITY_ATTRIBUTES_INFORMATION
TokenDeviceGroups, // q: TOKEN_GROUPS TokenDeviceGroups, // q: TOKEN_GROUPS
TokenRestrictedDeviceGroups, // q: TOKEN_GROUPS TokenRestrictedDeviceGroups, // q: TOKEN_GROUPS
TokenSecurityAttributes, // q; s: TOKEN_SECURITY_ATTRIBUTES_[AND_OPERATION_]INFORMATION (requires SeTcbPrivilege) TokenSecurityAttributes, // q; s: TOKEN_SECURITY_ATTRIBUTES_[AND_OPERATION_]INFORMATION (requires SeTcbPrivilege)
TokenIsRestricted, // q: ULONG // 40 TokenIsRestricted, // q: ULONG // 40
TokenProcessTrustLevel, // q: TOKEN_PROCESS_TRUST_LEVEL // since WINBLUE TokenProcessTrustLevel, // q: TOKEN_PROCESS_TRUST_LEVEL // since WINBLUE
TokenPrivateNameSpace, // q; s: ULONG (requires SeTcbPrivilege) // since THRESHOLD TokenPrivateNameSpace, // q; s: ULONG (requires SeTcbPrivilege) // since THRESHOLD
TokenSingletonAttributes, // q: TOKEN_SECURITY_ATTRIBUTES_INFORMATION // since REDSTONE TokenSingletonAttributes, // q: TOKEN_SECURITY_ATTRIBUTES_INFORMATION // since REDSTONE
TokenBnoIsolation, // q: TOKEN_BNO_ISOLATION_INFORMATION // since REDSTONE2 TokenBnoIsolation, // q: TOKEN_BNO_ISOLATION_INFORMATION // since REDSTONE2
TokenChildProcessFlags, // s: ULONG (requires SeTcbPrivilege) // since REDSTONE3 TokenChildProcessFlags, // s: ULONG (requires SeTcbPrivilege) // since REDSTONE3
TokenIsLessPrivilegedAppContainer, // q: ULONG // since REDSTONE5 TokenIsLessPrivilegedAppContainer, // q: ULONG // since REDSTONE5
TokenIsSandboxed, // q: ULONG // since 19H1 TokenIsSandboxed, // q: ULONG // since 19H1
TokenIsAppSilo, // q: ULONG // since WIN11 22H2 // previously TokenOriginatingProcessTrustLevel // q: TokenIsAppSilo, // q: ULONG // since WIN11 22H2 // previously TokenOriginatingProcessTrustLevel // q:
// TOKEN_PROCESS_TRUST_LEVEL // TOKEN_PROCESS_TRUST_LEVEL
TokenLoggingInformation, // TOKEN_LOGGING_INFORMATION // since 24H2 TokenLoggingInformation, // TOKEN_LOGGING_INFORMATION // since 24H2
MaxTokenInfoClass MaxTokenInfoClass
} TOKEN_INFORMATION_CLASS, *PTOKEN_INFORMATION_CLASS; } TOKEN_INFORMATION_CLASS, *PTOKEN_INFORMATION_CLASS;
@@ -385,54 +384,54 @@ typedef enum _TOKEN_INFORMATION_CLASS
using PROCESSINFOCLASS = enum _PROCESSINFOCLASS using PROCESSINFOCLASS = enum _PROCESSINFOCLASS
{ {
ProcessBasicInformation, // q: PROCESS_BASIC_INFORMATION, PROCESS_EXTENDED_BASIC_INFORMATION ProcessBasicInformation, // q: PROCESS_BASIC_INFORMATION, PROCESS_EXTENDED_BASIC_INFORMATION
ProcessQuotaLimits, // qs: QUOTA_LIMITS, QUOTA_LIMITS_EX ProcessQuotaLimits, // qs: QUOTA_LIMITS, QUOTA_LIMITS_EX
ProcessIoCounters, // q: IO_COUNTERS ProcessIoCounters, // q: IO_COUNTERS
ProcessVmCounters, // q: VM_COUNTERS, VM_COUNTERS_EX, VM_COUNTERS_EX2 ProcessVmCounters, // q: VM_COUNTERS, VM_COUNTERS_EX, VM_COUNTERS_EX2
ProcessTimes, // q: KERNEL_USER_TIMES ProcessTimes, // q: KERNEL_USER_TIMES
ProcessBasePriority, // s: KPRIORITY ProcessBasePriority, // s: KPRIORITY
ProcessRaisePriority, // s: ULONG ProcessRaisePriority, // s: ULONG
ProcessDebugPort, // q: HANDLE ProcessDebugPort, // q: HANDLE
ProcessExceptionPort, // s: PROCESS_EXCEPTION_PORT (requires SeTcbPrivilege) ProcessExceptionPort, // s: PROCESS_EXCEPTION_PORT (requires SeTcbPrivilege)
ProcessAccessToken, // s: PROCESS_ACCESS_TOKEN ProcessAccessToken, // s: PROCESS_ACCESS_TOKEN
ProcessLdtInformation, // qs: PROCESS_LDT_INFORMATION // 10 ProcessLdtInformation, // qs: PROCESS_LDT_INFORMATION // 10
ProcessLdtSize, // s: PROCESS_LDT_SIZE ProcessLdtSize, // s: PROCESS_LDT_SIZE
ProcessDefaultHardErrorMode, // qs: ULONG ProcessDefaultHardErrorMode, // qs: ULONG
ProcessIoPortHandlers, // (kernel-mode only) // s: PROCESS_IO_PORT_HANDLER_INFORMATION ProcessIoPortHandlers, // (kernel-mode only) // s: PROCESS_IO_PORT_HANDLER_INFORMATION
ProcessPooledUsageAndLimits, // q: POOLED_USAGE_AND_LIMITS ProcessPooledUsageAndLimits, // q: POOLED_USAGE_AND_LIMITS
ProcessWorkingSetWatch, // q: PROCESS_WS_WATCH_INFORMATION[]; s: void ProcessWorkingSetWatch, // q: PROCESS_WS_WATCH_INFORMATION[]; s: void
ProcessUserModeIOPL, // qs: ULONG (requires SeTcbPrivilege) ProcessUserModeIOPL, // qs: ULONG (requires SeTcbPrivilege)
ProcessEnableAlignmentFaultFixup, // s: BOOLEAN ProcessEnableAlignmentFaultFixup, // s: BOOLEAN
ProcessPriorityClass, // qs: PROCESS_PRIORITY_CLASS ProcessPriorityClass, // qs: PROCESS_PRIORITY_CLASS
ProcessWx86Information, // qs: ULONG (requires SeTcbPrivilege) (VdmAllowed) ProcessWx86Information, // qs: ULONG (requires SeTcbPrivilege) (VdmAllowed)
ProcessHandleCount, // q: ULONG, PROCESS_HANDLE_INFORMATION // 20 ProcessHandleCount, // q: ULONG, PROCESS_HANDLE_INFORMATION // 20
ProcessAffinityMask, // (q >WIN7)s: KAFFINITY, qs: GROUP_AFFINITY ProcessAffinityMask, // (q >WIN7)s: KAFFINITY, qs: GROUP_AFFINITY
ProcessPriorityBoost, // qs: ULONG ProcessPriorityBoost, // qs: ULONG
ProcessDeviceMap, // qs: PROCESS_DEVICEMAP_INFORMATION, PROCESS_DEVICEMAP_INFORMATION_EX ProcessDeviceMap, // qs: PROCESS_DEVICEMAP_INFORMATION, PROCESS_DEVICEMAP_INFORMATION_EX
ProcessSessionInformation, // q: PROCESS_SESSION_INFORMATION ProcessSessionInformation, // q: PROCESS_SESSION_INFORMATION
ProcessForegroundInformation, // s: PROCESS_FOREGROUND_BACKGROUND ProcessForegroundInformation, // s: PROCESS_FOREGROUND_BACKGROUND
ProcessWow64Information, // q: ULONG_PTR ProcessWow64Information, // q: ULONG_PTR
ProcessImageFileName, // q: UNICODE_STRING ProcessImageFileName, // q: UNICODE_STRING
ProcessLUIDDeviceMapsEnabled, // q: ULONG ProcessLUIDDeviceMapsEnabled, // q: ULONG
ProcessBreakOnTermination, // qs: ULONG ProcessBreakOnTermination, // qs: ULONG
ProcessDebugObjectHandle, // q: HANDLE // 30 ProcessDebugObjectHandle, // q: HANDLE // 30
ProcessDebugFlags, // qs: ULONG ProcessDebugFlags, // qs: ULONG
ProcessHandleTracing, // q: PROCESS_HANDLE_TRACING_QUERY; s: PROCESS_HANDLE_TRACING_ENABLE[_EX] or void to disable ProcessHandleTracing, // q: PROCESS_HANDLE_TRACING_QUERY; s: PROCESS_HANDLE_TRACING_ENABLE[_EX] or void to disable
ProcessIoPriority, // qs: IO_PRIORITY_HINT ProcessIoPriority, // qs: IO_PRIORITY_HINT
ProcessExecuteFlags, // qs: ULONG (MEM_EXECUTE_OPTION_*) ProcessExecuteFlags, // qs: ULONG (MEM_EXECUTE_OPTION_*)
ProcessTlsInformation, // PROCESS_TLS_INFORMATION // ProcessResourceManagement ProcessTlsInformation, // PROCESS_TLS_INFORMATION // ProcessResourceManagement
ProcessCookie, // q: ULONG ProcessCookie, // q: ULONG
ProcessImageInformation, // q: SECTION_IMAGE_INFORMATION ProcessImageInformation, // q: SECTION_IMAGE_INFORMATION
ProcessCycleTime, // q: PROCESS_CYCLE_TIME_INFORMATION // since VISTA ProcessCycleTime, // q: PROCESS_CYCLE_TIME_INFORMATION // since VISTA
ProcessPagePriority, // qs: PAGE_PRIORITY_INFORMATION ProcessPagePriority, // qs: PAGE_PRIORITY_INFORMATION
ProcessInstrumentationCallback, // s: PVOID or PROCESS_INSTRUMENTATION_CALLBACK_INFORMATION // 40 ProcessInstrumentationCallback, // s: PVOID or PROCESS_INSTRUMENTATION_CALLBACK_INFORMATION // 40
ProcessThreadStackAllocation, // s: PROCESS_STACK_ALLOCATION_INFORMATION, PROCESS_STACK_ALLOCATION_INFORMATION_EX ProcessThreadStackAllocation, // s: PROCESS_STACK_ALLOCATION_INFORMATION, PROCESS_STACK_ALLOCATION_INFORMATION_EX
ProcessWorkingSetWatchEx, // q: PROCESS_WS_WATCH_INFORMATION_EX[]; s: void ProcessWorkingSetWatchEx, // q: PROCESS_WS_WATCH_INFORMATION_EX[]; s: void
ProcessImageFileNameWin32, // q: UNICODE_STRING ProcessImageFileNameWin32, // q: UNICODE_STRING
ProcessImageFileMapping, // q: HANDLE (input) ProcessImageFileMapping, // q: HANDLE (input)
ProcessAffinityUpdateMode, // qs: PROCESS_AFFINITY_UPDATE_MODE ProcessAffinityUpdateMode, // qs: PROCESS_AFFINITY_UPDATE_MODE
ProcessMemoryAllocationMode, // qs: PROCESS_MEMORY_ALLOCATION_MODE ProcessMemoryAllocationMode, // qs: PROCESS_MEMORY_ALLOCATION_MODE
ProcessGroupInformation, // q: USHORT[] ProcessGroupInformation, // q: USHORT[]
ProcessTokenVirtualizationEnabled, // s: ULONG ProcessTokenVirtualizationEnabled, // s: ULONG
ProcessConsoleHostProcess, // qs: ULONG_PTR // ProcessOwnerInformation ProcessConsoleHostProcess, // qs: ULONG_PTR // ProcessOwnerInformation
ProcessWindowInformation, // q: PROCESS_WINDOW_INFORMATION // 50 ProcessWindowInformation, // q: PROCESS_WINDOW_INFORMATION // 50

View File

@@ -6,8 +6,8 @@
namespace utils namespace utils
{ {
template <typename Type, typename SpanElement = const std::byte> template <typename Type, typename SpanElement = const std::byte>
requires(std::is_trivially_copyable_v<Type> && (std::is_same_v<uint8_t, std::remove_cv_t<SpanElement>> || requires(std::is_trivially_copyable_v<Type> &&
std::is_same_v<std::byte, std::remove_cv_t<SpanElement>>)) (std::is_same_v<uint8_t, std::remove_cv_t<SpanElement>> || std::is_same_v<std::byte, std::remove_cv_t<SpanElement>>))
class safe_object_accessor class safe_object_accessor
{ {
public: public:
@@ -54,8 +54,7 @@ namespace utils
}; };
template <typename SpanElement> template <typename SpanElement>
requires(std::is_same_v<uint8_t, std::remove_cv_t<SpanElement>> || requires(std::is_same_v<uint8_t, std::remove_cv_t<SpanElement>> || std::is_same_v<std::byte, std::remove_cv_t<SpanElement>>)
std::is_same_v<std::byte, std::remove_cv_t<SpanElement>>)
class safe_buffer_accessor class safe_buffer_accessor
{ {
public: public:

View File

@@ -42,8 +42,7 @@ namespace utils
{ {
using is_transparent = void; using is_transparent = void;
bool operator()(const std::basic_string_view<Elem, Traits> lhs, bool operator()(const std::basic_string_view<Elem, Traits> lhs, const std::basic_string_view<Elem, Traits> rhs) const
const std::basic_string_view<Elem, Traits> rhs) const
{ {
return string::equals_ignore_case(lhs, rhs); return string::equals_ignore_case(lhs, rhs);
} }
@@ -64,8 +63,7 @@ namespace utils
using unordered_u16string_map = std::unordered_map<std::u16string, T, u16string_hash, std::equal_to<>>; using unordered_u16string_map = std::unordered_map<std::u16string, T, u16string_hash, std::equal_to<>>;
template <typename T> template <typename T>
using unordered_insensitive_string_map = using unordered_insensitive_string_map = std::unordered_map<std::string, T, insensitive_string_hash, insensitive_string_equal>;
std::unordered_map<std::string, T, insensitive_string_hash, insensitive_string_equal>;
template <typename T> template <typename T>
using unordered_insensitive_u16string_map = using unordered_insensitive_u16string_map =
std::unordered_map<std::u16string, T, insensitive_u16string_hash, insensitive_u16string_equal>; std::unordered_map<std::u16string, T, insensitive_u16string_hash, insensitive_u16string_equal>;

View File

@@ -28,8 +28,7 @@ namespace utils::io
io::create_directory(file.parent_path()); io::create_directory(file.parent_path());
} }
std::ofstream stream(file, std::ios::binary | std::ofstream::out | std::ofstream stream(file, std::ios::binary | std::ofstream::out | (append ? std::ofstream::app : std::ofstream::out));
(append ? std::ofstream::app : std::ofstream::out));
if (stream.is_open()) if (stream.is_open())
{ {
@@ -114,9 +113,8 @@ namespace utils::io
void copy_folder(const std::filesystem::path& src, const std::filesystem::path& target) void copy_folder(const std::filesystem::path& src, const std::filesystem::path& target)
{ {
std::error_code ec{}; std::error_code ec{};
std::filesystem::copy( std::filesystem::copy(src, target, std::filesystem::copy_options::overwrite_existing | std::filesystem::copy_options::recursive,
src, target, std::filesystem::copy_options::overwrite_existing | std::filesystem::copy_options::recursive, ec);
ec);
} }
std::vector<std::filesystem::path> list_files(const std::filesystem::path& directory, const bool recursive) std::vector<std::filesystem::path> list_files(const std::filesystem::path& directory, const bool recursive)

View File

@@ -180,18 +180,14 @@ namespace utils::string
} }
template <class Elem, class Traits, class Alloc> template <class Elem, class Traits, class Alloc>
bool equals_ignore_case(const std::basic_string<Elem, Traits, Alloc>& lhs, bool equals_ignore_case(const std::basic_string<Elem, Traits, Alloc>& lhs, const std::basic_string<Elem, Traits, Alloc>& rhs)
const std::basic_string<Elem, Traits, Alloc>& rhs)
{ {
return std::ranges::equal(lhs, rhs, return std::ranges::equal(lhs, rhs, [](const auto c1, const auto c2) { return char_to_lower(c1) == char_to_lower(c2); });
[](const auto c1, const auto c2) { return char_to_lower(c1) == char_to_lower(c2); });
} }
template <class Elem, class Traits> template <class Elem, class Traits>
bool equals_ignore_case(const std::basic_string_view<Elem, Traits>& lhs, bool equals_ignore_case(const std::basic_string_view<Elem, Traits>& lhs, const std::basic_string_view<Elem, Traits>& rhs)
const std::basic_string_view<Elem, Traits>& rhs)
{ {
return std::ranges::equal(lhs, rhs, return std::ranges::equal(lhs, rhs, [](const auto c1, const auto c2) { return char_to_lower(c1) == char_to_lower(c2); });
[](const auto c1, const auto c2) { return char_to_lower(c1) == char_to_lower(c2); });
} }
} }

View File

@@ -3,16 +3,14 @@
namespace utils namespace utils
{ {
std::chrono::steady_clock::time_point convert_delay_interval_to_time_point(clock& c, std::chrono::steady_clock::time_point convert_delay_interval_to_time_point(clock& c, const LARGE_INTEGER delay_interval)
const LARGE_INTEGER delay_interval)
{ {
if (delay_interval.QuadPart <= 0) if (delay_interval.QuadPart <= 0)
{ {
const auto relative_time = -delay_interval.QuadPart; const auto relative_time = -delay_interval.QuadPart;
const auto relative_ticks_in_ms = relative_time / 10; const auto relative_ticks_in_ms = relative_time / 10;
const auto relative_fraction_ns = (relative_time % 10) * 100; const auto relative_fraction_ns = (relative_time % 10) * 100;
const auto relative_duration = const auto relative_duration = std::chrono::microseconds(relative_ticks_in_ms) + std::chrono::nanoseconds(relative_fraction_ns);
std::chrono::microseconds(relative_ticks_in_ms) + std::chrono::nanoseconds(relative_fraction_ns);
return c.steady_now() + relative_duration; return c.steady_now() + relative_duration;
} }
@@ -22,13 +20,12 @@ namespace utils
const auto delay_seconds_since_1970 = delay_seconds_since_1601 - EPOCH_DIFFERENCE_1601_TO_1970_SECONDS; const auto delay_seconds_since_1970 = delay_seconds_since_1601 - EPOCH_DIFFERENCE_1601_TO_1970_SECONDS;
const auto target_time = std::chrono::system_clock::from_time_t(delay_seconds_since_1970) + const auto target_time =
std::chrono::nanoseconds(delay_fraction_ns); std::chrono::system_clock::from_time_t(delay_seconds_since_1970) + std::chrono::nanoseconds(delay_fraction_ns);
const auto now_system = c.system_now(); const auto now_system = c.system_now();
const auto duration_until_target = const auto duration_until_target = std::chrono::duration_cast<std::chrono::microseconds>(target_time - now_system);
std::chrono::duration_cast<std::chrono::microseconds>(target_time - now_system);
return c.steady_now() + duration_until_target; return c.steady_now() + duration_until_target;
} }

View File

@@ -40,8 +40,7 @@ namespace utils
/// TODO: find better solution for ARM and Figure out better CPU base frequency heuristics /// TODO: find better solution for ARM and Figure out better CPU base frequency heuristics
virtual uint64_t timestamp_counter() virtual uint64_t timestamp_counter()
{ {
#if defined(_M_X64) || defined(_M_AMD64) || defined(_M_IX86) || defined(__x86_64__) || defined(__i386__) || \ #if defined(_M_X64) || defined(_M_AMD64) || defined(_M_IX86) || defined(__x86_64__) || defined(__i386__) || defined(__amd64__)
defined(__amd64__)
return __rdtsc(); // any x86 system will have this instrinsic return __rdtsc(); // any x86 system will have this instrinsic
#else #else
const auto count = std::chrono::high_resolution_clock::now().time_since_epoch().count(); const auto count = std::chrono::high_resolution_clock::now().time_since_epoch().count();
@@ -53,8 +52,7 @@ namespace utils
class tick_clock : public clock class tick_clock : public clock
{ {
public: public:
tick_clock(const uint64_t frequency = 1, const system_time_point system_start = {}, tick_clock(const uint64_t frequency = 1, const system_time_point system_start = {}, const steady_time_point steady_start = {})
const steady_time_point steady_start = {})
: frequency_(frequency), : frequency_(frequency),
system_start_(system_start), system_start_(system_start),
steady_start_(steady_start) steady_start_(steady_start)

View File

@@ -127,8 +127,7 @@ namespace debugger
void handle_read_register(const event_context& c, const Debugger::ReadRegisterRequestT& request) void handle_read_register(const event_context& c, const Debugger::ReadRegisterRequestT& request)
{ {
std::array<uint8_t, 512> buffer{}; std::array<uint8_t, 512> buffer{};
const auto res = c.win_emu.emu().read_register(static_cast<x86_register>(request.register_), buffer.data(), const auto res = c.win_emu.emu().read_register(static_cast<x86_register>(request.register_), buffer.data(), buffer.size());
buffer.size());
const auto size = std::min(buffer.size(), res); const auto size = std::min(buffer.size(), res);
@@ -146,8 +145,8 @@ namespace debugger
try try
{ {
size = c.win_emu.emu().write_register(static_cast<x86_register>(request.register_), request.data.data(), size =
request.data.size()); c.win_emu.emu().write_register(static_cast<x86_register>(request.register_), request.data.data(), request.data.size());
success = true; success = true;
} }
catch (...) catch (...)

View File

@@ -28,8 +28,7 @@ constexpr bool regions_intersect(const uint64_t start1, const uint64_t end1, con
return start1 < end2 && start2 < end1; return start1 < end2 && start2 < end1;
} }
constexpr bool regions_with_length_intersect(const uint64_t start1, const uint64_t length1, const uint64_t start2, constexpr bool regions_with_length_intersect(const uint64_t start1, const uint64_t length1, const uint64_t start2, const uint64_t length2)
const uint64_t length2)
{ {
return regions_intersect(start1, start1 + length1, start2, start2 + length2); return regions_intersect(start1, start1 + length1, start2, start2 + length2);
} }

View File

@@ -35,8 +35,7 @@ struct basic_block
size_t size; size_t size;
}; };
using edge_generation_hook_callback = using edge_generation_hook_callback = std::function<void(const basic_block& current_block, const basic_block& previous_block)>;
std::function<void(const basic_block& current_block, const basic_block& previous_block)>;
using basic_block_hook_callback = std::function<void(const basic_block& block)>; using basic_block_hook_callback = std::function<void(const basic_block& block)>;
using instruction_hook_callback = std::function<instruction_hook_continuation()>; using instruction_hook_callback = std::function<instruction_hook_continuation()>;
@@ -45,8 +44,8 @@ using interrupt_hook_callback = std::function<void(int interrupt)>;
using memory_access_hook_callback = std::function<void(uint64_t address, const void* data, size_t size)>; using memory_access_hook_callback = std::function<void(uint64_t address, const void* data, size_t size)>;
using memory_execution_hook_callback = std::function<void(uint64_t address)>; using memory_execution_hook_callback = std::function<void(uint64_t address)>;
using memory_violation_hook_callback = std::function<memory_violation_continuation( using memory_violation_hook_callback =
uint64_t address, size_t size, memory_operation operation, memory_violation_type type)>; std::function<memory_violation_continuation(uint64_t address, size_t size, memory_operation operation, memory_violation_type type)>;
class hook_interface class hook_interface
{ {

View File

@@ -40,9 +40,8 @@ namespace utils
}; };
template <typename T> template <typename T>
struct has_serialize_function<T, struct has_serialize_function<
std::void_t<decltype(serialize(std::declval<buffer_serializer&>(), T, std::void_t<decltype(serialize(std::declval<buffer_serializer&>(), std::declval<const std::remove_cvref_t<T>&>()))>>
std::declval<const std::remove_cvref_t<T>&>()))>>
: std::true_type : std::true_type
{ {
}; };
@@ -53,8 +52,8 @@ namespace utils
}; };
template <typename T> template <typename T>
struct has_deserialize_function<T, std::void_t<decltype(deserialize(std::declval<buffer_deserializer&>(), struct has_deserialize_function<
std::declval<std::remove_cvref_t<T>&>()))>> T, std::void_t<decltype(deserialize(std::declval<buffer_deserializer&>(), std::declval<std::remove_cvref_t<T>&>()))>>
: std::true_type : std::true_type
{ {
}; };
@@ -506,8 +505,7 @@ namespace utils
const auto factory = this->factories_.find(std::type_index(typeid(T))); const auto factory = this->factories_.find(std::type_index(typeid(T)));
if (factory == this->factories_.end()) if (factory == this->factories_.end())
{ {
throw std::runtime_error("Object construction failed. Missing factory for type: " + throw std::runtime_error("Object construction failed. Missing factory for type: " + std::string(typeid(T).name()));
std::string(typeid(T).name()));
} }
auto* object = static_cast<T*>(factory->second()); auto* object = static_cast<T*>(factory->second());

View File

@@ -112,8 +112,7 @@ namespace
restore_emulator(); restore_emulator();
const auto memory = emu.memory.allocate_memory( const auto memory = emu.memory.allocate_memory(
static_cast<size_t>(page_align_up(std::max(data.size(), static_cast<size_t>(1)))), static_cast<size_t>(page_align_up(std::max(data.size(), static_cast<size_t>(1)))), memory_permission::read_write);
memory_permission::read_write);
emu.emu().write_memory(memory, data.data(), data.size()); emu.emu().write_memory(memory, data.data(), data.size());
emu.emu().reg(x86_register::rcx, memory); emu.emu().reg(x86_register::rcx, memory);

View File

@@ -177,8 +177,7 @@ namespace fuzzer
const auto executions = context.executions.exchange(0); const auto executions = context.executions.exchange(0);
const auto highest_scorer = context.generator.get_highest_scorer(); const auto highest_scorer = context.generator.get_highest_scorer();
const auto avg_score = context.generator.get_average_score(); const auto avg_score = context.generator.get_average_score();
printf("Executions/s: %" PRIu64 " - Score: %" PRIx64 " - Avg: %.3f\n", executions, highest_scorer.score, printf("Executions/s: %" PRIu64 " - Score: %" PRIx64 " - Avg: %.3f\n", executions, highest_scorer.score, avg_score);
avg_score);
} }
const auto duration = t.elapsed(); const auto duration = t.elapsed();

View File

@@ -19,8 +19,7 @@ namespace fuzzer
{ {
virtual ~executer() = default; virtual ~executer() = default;
virtual execution_result execute(std::span<const uint8_t> data, virtual execution_result execute(std::span<const uint8_t> data, const std::function<coverage_functor>& coverage_handler) = 0;
const std::function<coverage_functor>& coverage_handler) = 0;
}; };
struct fuzzing_handler struct fuzzing_handler

View File

@@ -106,8 +106,7 @@ namespace fuzzer
} }
const auto insert_at_random = this->rng.get(10) == 0; const auto insert_at_random = this->rng.get(10) == 0;
const auto index = const auto index = insert_at_random ? (this->rng.get<size_t>() % this->top_scorer_.size()) : this->lowest_scorer;
insert_at_random ? (this->rng.get<size_t>() % this->top_scorer_.size()) : this->lowest_scorer;
this->top_scorer_[index] = std::move(entry); this->top_scorer_[index] = std::move(entry);

View File

@@ -23,8 +23,7 @@ namespace gdb_stub
} }
} }
connection_handler::connection_handler(network::tcp_client_socket& client, connection_handler::connection_handler(network::tcp_client_socket& client, utils::optional_function<bool()> should_stop)
utils::optional_function<bool()> should_stop)
: should_stop_(std::move(should_stop)), : should_stop_(std::move(should_stop)),
client_(client) client_(client)
{ {

View File

@@ -35,8 +35,7 @@ namespace gdb_stub
async_handler& async; async_handler& async;
}; };
network::tcp_client_socket accept_client(const network::address& bind_address, network::tcp_client_socket accept_client(const network::address& bind_address, const utils::optional_function<bool()>& should_stop)
const utils::optional_function<bool()>& should_stop)
{ {
network::tcp_server_socket server{bind_address.get_family()}; network::tcp_server_socket server{bind_address.get_family()};
if (!server.bind(bind_address)) if (!server.bind(bind_address))
@@ -194,8 +193,8 @@ namespace gdb_stub
return static_cast<breakpoint_type>(type); return static_cast<breakpoint_type>(type);
} }
bool change_breakpoint(debugging_handler& handler, const bool set, const breakpoint_type type, bool change_breakpoint(debugging_handler& handler, const bool set, const breakpoint_type type, const uint64_t address,
const uint64_t address, const size_t size) const size_t size)
{ {
if (set) if (set)
{ {

View File

@@ -295,8 +295,7 @@ namespace
for (DWORD i = 0;; ++i) for (DWORD i = 0;; ++i)
{ {
auto name_buffer_len = static_cast<DWORD>(name_buffer.size()); auto name_buffer_len = static_cast<DWORD>(name_buffer.size());
const LSTATUS status = const LSTATUS status = RegEnumKeyExA(key, i, name_buffer.data(), &name_buffer_len, nullptr, nullptr, nullptr, nullptr);
RegEnumKeyExA(key, i, name_buffer.data(), &name_buffer_len, nullptr, nullptr, nullptr, nullptr);
if (status == ERROR_SUCCESS) if (status == ERROR_SUCCESS)
{ {
keys.emplace_back(name_buffer.data(), name_buffer_len); keys.emplace_back(name_buffer.data(), name_buffer_len);
@@ -340,8 +339,7 @@ namespace
for (DWORD i = 0;; ++i) for (DWORD i = 0;; ++i)
{ {
auto name_buffer_len = static_cast<DWORD>(name_buffer.size()); auto name_buffer_len = static_cast<DWORD>(name_buffer.size());
const auto status = const auto status = RegEnumValueA(key, i, name_buffer.data(), &name_buffer_len, nullptr, nullptr, nullptr, nullptr);
RegEnumValueA(key, i, name_buffer.data(), &name_buffer_len, nullptr, nullptr, nullptr, nullptr);
if (status == ERROR_SUCCESS) if (status == ERROR_SUCCESS)
{ {
values.emplace_back(name_buffer.data(), name_buffer_len); values.emplace_back(name_buffer.data(), name_buffer_len);
@@ -383,16 +381,14 @@ namespace
// WOW64 Redirection Test // WOW64 Redirection Test
const auto pst_display = read_registry_string( const auto pst_display = read_registry_string(
HKEY_LOCAL_MACHINE, HKEY_LOCAL_MACHINE, R"(SOFTWARE\WOW6432Node\Microsoft\Windows NT\CurrentVersion\Time Zones\Pacific Standard Time)", "Display");
R"(SOFTWARE\WOW6432Node\Microsoft\Windows NT\CurrentVersion\Time Zones\Pacific Standard Time)", "Display");
if (!pst_display || pst_display->empty()) if (!pst_display || pst_display->empty())
{ {
return false; return false;
} }
// Key Sub-keys Enumeration Test // Key Sub-keys Enumeration Test
const auto subkeys_opt = const auto subkeys_opt = get_all_registry_keys(HKEY_LOCAL_MACHINE, R"(SOFTWARE\Microsoft\Windows NT\CurrentVersion)");
get_all_registry_keys(HKEY_LOCAL_MACHINE, R"(SOFTWARE\Microsoft\Windows NT\CurrentVersion)");
if (!subkeys_opt) if (!subkeys_opt)
{ {
return false; return false;
@@ -413,8 +409,7 @@ namespace
} }
// Key Values Enumeration Test // Key Values Enumeration Test
const auto values_opt = const auto values_opt = get_all_registry_values(HKEY_LOCAL_MACHINE, R"(SOFTWARE\Microsoft\Windows NT\CurrentVersion)");
get_all_registry_values(HKEY_LOCAL_MACHINE, R"(SOFTWARE\Microsoft\Windows NT\CurrentVersion)");
if (!values_opt) if (!values_opt)
{ {
return false; return false;
@@ -489,17 +484,15 @@ namespace
return false; return false;
} }
if (current_dtzi.StandardDate.wYear != 0 || current_dtzi.StandardDate.wMonth != 10 || if (current_dtzi.StandardDate.wYear != 0 || current_dtzi.StandardDate.wMonth != 10 || current_dtzi.StandardDate.wDayOfWeek != 0 ||
current_dtzi.StandardDate.wDayOfWeek != 0 || current_dtzi.StandardDate.wDay != 5 || current_dtzi.StandardDate.wDay != 5 || current_dtzi.StandardDate.wHour != 3 || current_dtzi.StandardDate.wMinute != 0 ||
current_dtzi.StandardDate.wHour != 3 || current_dtzi.StandardDate.wMinute != 0 ||
current_dtzi.StandardDate.wSecond != 0 || current_dtzi.StandardDate.wMilliseconds != 0) current_dtzi.StandardDate.wSecond != 0 || current_dtzi.StandardDate.wMilliseconds != 0)
{ {
return false; return false;
} }
if (current_dtzi.DaylightDate.wYear != 0 || current_dtzi.DaylightDate.wMonth != 3 || if (current_dtzi.DaylightDate.wYear != 0 || current_dtzi.DaylightDate.wMonth != 3 || current_dtzi.DaylightDate.wDayOfWeek != 0 ||
current_dtzi.DaylightDate.wDayOfWeek != 0 || current_dtzi.DaylightDate.wDay != 5 || current_dtzi.DaylightDate.wDay != 5 || current_dtzi.DaylightDate.wHour != 2 || current_dtzi.DaylightDate.wMinute != 0 ||
current_dtzi.DaylightDate.wHour != 2 || current_dtzi.DaylightDate.wMinute != 0 ||
current_dtzi.DaylightDate.wSecond != 0 || current_dtzi.DaylightDate.wMilliseconds != 0) current_dtzi.DaylightDate.wSecond != 0 || current_dtzi.DaylightDate.wMilliseconds != 0)
{ {
return false; return false;
@@ -583,8 +576,7 @@ namespace
sockaddr_in sender_addr{}; sockaddr_in sender_addr{};
int sender_length = sizeof(sender_addr); int sender_length = sizeof(sender_addr);
const auto len = const auto len = recvfrom(receiver, buffer, sizeof(buffer), 0, reinterpret_cast<sockaddr*>(&sender_addr), &sender_length);
recvfrom(receiver, buffer, sizeof(buffer), 0, reinterpret_cast<sockaddr*>(&sender_addr), &sender_length);
if (len != send_data.size()) if (len != send_data.size())
{ {
@@ -691,8 +683,7 @@ namespace
// Allocate a guarded memory region with the length of the system page // Allocate a guarded memory region with the length of the system page
// size. // size.
auto* addr = static_cast<LPBYTE>( auto* addr = static_cast<LPBYTE>(VirtualAlloc(nullptr, sys_info.dwPageSize, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE | PAGE_GUARD));
VirtualAlloc(nullptr, sys_info.dwPageSize, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE | PAGE_GUARD));
if (addr == nullptr) if (addr == nullptr)
{ {
puts("Failed to allocate guard page"); puts("Failed to allocate guard page");

View File

@@ -56,8 +56,8 @@ void print_apiset(PAPI_SET_NAMESPACE api_set_map)
{ {
for (ULONG i = 0; i < api_set_map->Count; i++) for (ULONG i = 0; i < api_set_map->Count; i++)
{ {
const auto entry = reinterpret_cast<PAPI_SET_NAMESPACE_ENTRY>( const auto entry = reinterpret_cast<PAPI_SET_NAMESPACE_ENTRY>(reinterpret_cast<ULONG_PTR>(api_set_map) + api_set_map->EntryOffset +
reinterpret_cast<ULONG_PTR>(api_set_map) + api_set_map->EntryOffset + i * sizeof(API_SET_NAMESPACE_ENTRY)); i * sizeof(API_SET_NAMESPACE_ENTRY));
// printf(" Flags: %08X\n", entry->Flags); // printf(" Flags: %08X\n", entry->Flags);
// printf(" NameOffset: %08X\n", entry->NameOffset); // printf(" NameOffset: %08X\n", entry->NameOffset);
@@ -72,8 +72,8 @@ void print_apiset(PAPI_SET_NAMESPACE api_set_map)
for (ULONG x = 0; x < entry->ValueCount; x++) for (ULONG x = 0; x < entry->ValueCount; x++)
{ {
const auto value = reinterpret_cast<PAPI_SET_VALUE_ENTRY>( const auto value = reinterpret_cast<PAPI_SET_VALUE_ENTRY>(reinterpret_cast<ULONG_PTR>(api_set_map) + entry->ValueOffset +
reinterpret_cast<ULONG_PTR>(api_set_map) + entry->ValueOffset + x * sizeof(API_SET_VALUE_ENTRY)); x * sizeof(API_SET_VALUE_ENTRY));
// printf(" Value %d\n", x); // printf(" Value %d\n", x);
// printf(" Flags: %08X\n", value->Flags); // printf(" Flags: %08X\n", value->Flags);
// printf(" NameOffset: %08X\n", value->NameOffset); // printf(" NameOffset: %08X\n", value->NameOffset);
@@ -81,12 +81,10 @@ void print_apiset(PAPI_SET_NAMESPACE api_set_map)
// printf(" ValueOffset: %08X\n", value->ValueOffset); // printf(" ValueOffset: %08X\n", value->ValueOffset);
// printf(" ValueLength: %08X\n", value->ValueLength); // printf(" ValueLength: %08X\n", value->ValueLength);
std::wstring hostName( std::wstring hostName(reinterpret_cast<wchar_t*>(reinterpret_cast<ULONG_PTR>(api_set_map) + value->NameOffset),
reinterpret_cast<wchar_t*>(reinterpret_cast<ULONG_PTR>(api_set_map) + value->NameOffset), value->NameLength / sizeof(wchar_t));
value->NameLength / sizeof(wchar_t)); std::wstring altName(reinterpret_cast<wchar_t*>(reinterpret_cast<ULONG_PTR>(api_set_map) + value->ValueOffset),
std::wstring altName( value->ValueLength / sizeof(wchar_t));
reinterpret_cast<wchar_t*>(reinterpret_cast<ULONG_PTR>(api_set_map) + value->ValueOffset),
value->ValueLength / sizeof(wchar_t));
printf(" HostName: %ls - AltName: %ls\n", hostName.empty() ? L"<none>" : hostName.data(), printf(" HostName: %ls - AltName: %ls\n", hostName.empty() ? L"<none>" : hostName.data(),
altName.empty() ? L"<none>" : altName.data()); altName.empty() ? L"<none>" : altName.data());
} }

View File

@@ -190,7 +190,6 @@ namespace test
const auto rip = emu.emu().read_instruction_pointer(); const auto rip = emu.emu().read_instruction_pointer();
printf("Diff detected after 0x%" PRIx64 " instructions at 0x%" PRIx64 " (%s)\n", lower_bound, rip, printf("Diff detected after 0x%" PRIx64 " instructions at 0x%" PRIx64 " (%s)\n", lower_bound, rip, emu.mod_manager.find_name(rip));
emu.mod_manager.find_name(rip));
} }
} }

View File

@@ -14,8 +14,8 @@ namespace apiset
{ {
namespace namespace
{ {
uint64_t copy_string(x86_64_emulator& emu, emulator_allocator& allocator, const void* base_ptr, uint64_t copy_string(x86_64_emulator& emu, emulator_allocator& allocator, const void* base_ptr, const uint64_t offset,
const uint64_t offset, const size_t length) const size_t length)
{ {
if (!length) if (!length)
{ {
@@ -29,8 +29,8 @@ namespace apiset
return str_obj; return str_obj;
} }
ULONG copy_string_as_relative(x86_64_emulator& emu, emulator_allocator& allocator, const uint64_t result_base, ULONG copy_string_as_relative(x86_64_emulator& emu, emulator_allocator& allocator, const uint64_t result_base, const void* base_ptr,
const void* base_ptr, const uint64_t offset, const size_t length) const uint64_t offset, const size_t length)
{ {
const auto address = copy_string(emu, allocator, base_ptr, offset, length); const auto address = copy_string(emu, allocator, base_ptr, offset, length);
if (!address) if (!address)
@@ -115,14 +115,12 @@ namespace apiset
return obtain(apiset_loc, root); return obtain(apiset_loc, root);
} }
emulator_object<API_SET_NAMESPACE> clone(x86_64_emulator& emu, emulator_allocator& allocator, emulator_object<API_SET_NAMESPACE> clone(x86_64_emulator& emu, emulator_allocator& allocator, const container& container)
const container& container)
{ {
return clone(emu, allocator, container.get()); return clone(emu, allocator, container.get());
} }
emulator_object<API_SET_NAMESPACE> clone(x86_64_emulator& emu, emulator_allocator& allocator, emulator_object<API_SET_NAMESPACE> clone(x86_64_emulator& emu, emulator_allocator& allocator, const API_SET_NAMESPACE& orig_api_set_map)
const API_SET_NAMESPACE& orig_api_set_map)
{ {
const auto api_set_map_obj = allocator.reserve<API_SET_NAMESPACE>(); const auto api_set_map_obj = allocator.reserve<API_SET_NAMESPACE>();
const auto ns_entries_obj = allocator.reserve<API_SET_NAMESPACE_ENTRY>(orig_api_set_map.Count); const auto ns_entries_obj = allocator.reserve<API_SET_NAMESPACE_ENTRY>(orig_api_set_map.Count);
@@ -134,18 +132,16 @@ namespace apiset
api_set.HashOffset = static_cast<ULONG>(hash_entries_obj.value() - api_set_map_obj.value()); api_set.HashOffset = static_cast<ULONG>(hash_entries_obj.value() - api_set_map_obj.value());
}); });
const auto* orig_ns_entries = const auto* orig_ns_entries = offset_pointer<API_SET_NAMESPACE_ENTRY>(&orig_api_set_map, orig_api_set_map.EntryOffset);
offset_pointer<API_SET_NAMESPACE_ENTRY>(&orig_api_set_map, orig_api_set_map.EntryOffset); const auto* orig_hash_entries = offset_pointer<API_SET_HASH_ENTRY>(&orig_api_set_map, orig_api_set_map.HashOffset);
const auto* orig_hash_entries =
offset_pointer<API_SET_HASH_ENTRY>(&orig_api_set_map, orig_api_set_map.HashOffset);
for (ULONG i = 0; i < orig_api_set_map.Count; ++i) for (ULONG i = 0; i < orig_api_set_map.Count; ++i)
{ {
auto ns_entry = orig_ns_entries[i]; auto ns_entry = orig_ns_entries[i];
const auto hash_entry = orig_hash_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 = copy_string_as_relative(emu, allocator, api_set_map_obj.value(), &orig_api_set_map, ns_entry.NameOffset,
ns_entry.NameOffset, ns_entry.NameLength); ns_entry.NameLength);
if (!ns_entry.ValueCount) if (!ns_entry.ValueCount)
{ {
@@ -161,13 +157,13 @@ namespace apiset
{ {
auto value = orig_values[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 = copy_string_as_relative(emu, allocator, api_set_map_obj.value(), &orig_api_set_map, value.ValueOffset,
value.ValueOffset, value.ValueLength); value.ValueLength);
if (value.NameLength) if (value.NameLength)
{ {
value.NameOffset = copy_string_as_relative(emu, allocator, api_set_map_obj.value(), value.NameOffset = copy_string_as_relative(emu, allocator, api_set_map_obj.value(), &orig_api_set_map, value.NameOffset,
&orig_api_set_map, value.NameOffset, value.NameLength); value.NameLength);
} }
values_obj.write(value, j); values_obj.write(value, j);

View File

@@ -32,6 +32,5 @@ namespace apiset
emulator_object<API_SET_NAMESPACE> clone(x86_64_emulator& emu, emulator_allocator& allocator, emulator_object<API_SET_NAMESPACE> clone(x86_64_emulator& emu, emulator_allocator& allocator,
const API_SET_NAMESPACE& orig_api_set_map); const API_SET_NAMESPACE& orig_api_set_map);
emulator_object<API_SET_NAMESPACE> clone(x86_64_emulator& emu, emulator_allocator& allocator, emulator_object<API_SET_NAMESPACE> clone(x86_64_emulator& emu, emulator_allocator& allocator, const container& container);
const container& container);
} }

File diff suppressed because it is too large Load Diff

View File

@@ -221,8 +221,7 @@ namespace
return win_emu.emu().read_memory<afd_creation_data>(data.buffer); return win_emu.emu().read_memory<afd_creation_data>(data.buffer);
} }
std::pair<AFD_POLL_INFO64, std::vector<AFD_POLL_HANDLE_INFO64>> get_poll_info(windows_emulator& win_emu, std::pair<AFD_POLL_INFO64, std::vector<AFD_POLL_HANDLE_INFO64>> get_poll_info(windows_emulator& win_emu, const io_device_context& c)
const io_device_context& c)
{ {
constexpr auto info_size = offsetof(AFD_POLL_INFO64, Handles); constexpr auto info_size = offsetof(AFD_POLL_INFO64, Handles);
if (!c.input_buffer || c.input_buffer_length < info_size || c.input_buffer != c.output_buffer) if (!c.input_buffer || c.input_buffer_length < info_size || c.input_buffer != c.output_buffer)
@@ -272,8 +271,8 @@ namespace
return socket_events; return socket_events;
} }
ULONG map_socket_response_events_to_afd(const int16_t socket_events, const ULONG afd_poll_events, ULONG map_socket_response_events_to_afd(const int16_t socket_events, const ULONG afd_poll_events, const bool is_listening,
const bool is_listening, const bool is_connecting) const bool is_connecting)
{ {
ULONG afd_events = 0; ULONG afd_events = 0;
@@ -306,8 +305,7 @@ namespace
} }
} }
if ((socket_events & (POLLHUP | POLLERR)) == (POLLHUP | POLLERR) && if ((socket_events & (POLLHUP | POLLERR)) == (POLLHUP | POLLERR) && afd_poll_events & (AFD_POLL_CONNECT_FAIL | AFD_POLL_ABORT))
afd_poll_events & (AFD_POLL_CONNECT_FAIL | AFD_POLL_ABORT))
{ {
afd_events |= (AFD_POLL_CONNECT_FAIL | AFD_POLL_ABORT); afd_events |= (AFD_POLL_CONNECT_FAIL | AFD_POLL_ABORT);
} }
@@ -388,8 +386,7 @@ namespace
void delay_ioctrl(const io_device_context& c, const std::optional<bool> require_poll = {}, void delay_ioctrl(const io_device_context& c, const std::optional<bool> require_poll = {},
const std::optional<std::chrono::steady_clock::time_point> timeout = {}, const std::optional<std::chrono::steady_clock::time_point> timeout = {},
const std::optional<std::function<void(windows_emulator&, const io_device_context&)>>& const std::optional<std::function<void(windows_emulator&, const io_device_context&)>>& timeout_callback = {})
timeout_callback = {})
{ {
if (this->executing_delayed_ioctl_) if (this->executing_delayed_ioctl_)
{ {
@@ -426,8 +423,7 @@ namespace
} }
if (this->event_select_mask_) if (this->event_select_mask_)
{ {
pfd.events = pfd.events = static_cast<int16_t>(pfd.events | map_afd_request_events_to_socket(this->event_select_mask_));
static_cast<int16_t>(pfd.events | map_afd_request_events_to_socket(this->event_select_mask_));
} }
pfd.revents = pfd.events; pfd.revents = pfd.events;
@@ -440,10 +436,9 @@ namespace
if (socket_events && this->event_select_mask_) if (socket_events && this->event_select_mask_)
{ {
const bool is_connecting = const bool is_connecting = this->delayed_ioctl_ && _AFD_REQUEST(this->delayed_ioctl_->io_control_code) == AFD_CONNECT;
this->delayed_ioctl_ && _AFD_REQUEST(this->delayed_ioctl_->io_control_code) == AFD_CONNECT; ULONG current_events =
ULONG current_events = map_socket_response_events_to_afd(socket_events, this->event_select_mask_, map_socket_response_events_to_afd(socket_events, this->event_select_mask_, pfd.s->is_listening(), is_connecting);
pfd.s->is_listening(), is_connecting);
if ((current_events & ~this->triggered_events_) != 0) if ((current_events & ~this->triggered_events_) != 0)
{ {
@@ -463,8 +458,7 @@ namespace
if (this->require_poll_.has_value()) if (this->require_poll_.has_value())
{ {
const auto is_ready = const auto is_ready = socket_events & ((*this->require_poll_ ? POLLIN : POLLOUT) | POLLHUP | POLLERR);
socket_events & ((*this->require_poll_ ? POLLIN : POLLOUT) | POLLHUP | POLLERR);
if (!is_ready) if (!is_ready)
{ {
return; return;
@@ -955,8 +949,7 @@ namespace
endpoint->delayed_ioctl_ && _AFD_REQUEST(endpoint->delayed_ioctl_->io_control_code) == AFD_CONNECT; endpoint->delayed_ioctl_ && _AFD_REQUEST(endpoint->delayed_ioctl_->io_control_code) == AFD_CONNECT;
auto entry = handle_info_obj.read(i); auto entry = handle_info_obj.read(i);
entry.PollEvents = map_socket_response_events_to_afd(pfd.revents, handle.PollEvents, entry.PollEvents = map_socket_response_events_to_afd(pfd.revents, handle.PollEvents, pfd.s->is_listening(), is_connecting);
pfd.s->is_listening(), is_connecting);
entry.Status = STATUS_SUCCESS; entry.Status = STATUS_SUCCESS;
handle_info_obj.write(entry, current_index++); handle_info_obj.write(entry, current_index++);
@@ -1102,8 +1095,8 @@ namespace
const auto send_info = emu.read_memory<AFD_SEND_DATAGRAM_INFO<EmulatorTraits<Emu64>>>(c.input_buffer); const auto send_info = emu.read_memory<AFD_SEND_DATAGRAM_INFO<EmulatorTraits<Emu64>>>(c.input_buffer);
const auto buffer = emu.read_memory<EMU_WSABUF<EmulatorTraits<Emu64>>>(send_info.BufferArray); const auto buffer = emu.read_memory<EMU_WSABUF<EmulatorTraits<Emu64>>>(send_info.BufferArray);
auto address_buffer = emu.read_memory(send_info.TdiConnInfo.RemoteAddress, auto address_buffer =
static_cast<size_t>(send_info.TdiConnInfo.RemoteAddressLength)); emu.read_memory(send_info.TdiConnInfo.RemoteAddress, static_cast<size_t>(send_info.TdiConnInfo.RemoteAddressLength));
const auto target = convert_to_host_address(win_emu, address_buffer); const auto target = convert_to_host_address(win_emu, address_buffer);
const auto data = emu.read_memory(buffer.buf, buffer.len); const auto data = emu.read_memory(buffer.buf, buffer.len);

View File

@@ -76,8 +76,7 @@ namespace
MOUNTMGR_MOUNT_POINT point{}; MOUNTMGR_MOUNT_POINT point{};
const auto symlink = write_string<char16_t>(buffer, make_volume(drive, 0)); const auto symlink = write_string<char16_t>(buffer, make_volume(drive, 0));
const auto id = write_string<char>(buffer, make_drive_id(drive, 0)); const auto id = write_string<char>(buffer, make_drive_id(drive, 0));
const auto name = write_string<char16_t>(buffer, u"\\Device\\HarddiskVolume" + const auto name = write_string<char16_t>(buffer, u"\\Device\\HarddiskVolume" + u8_to_u16(std::to_string(drive - 'a' + 1)));
u8_to_u16(std::to_string(drive - 'a' + 1)));
point.SymbolicLinkNameOffset = symlink.first; point.SymbolicLinkNameOffset = symlink.first;
point.SymbolicLinkNameLength = symlink.second; point.SymbolicLinkNameLength = symlink.second;

View File

@@ -2,45 +2,33 @@
// NOLINTBEGIN(modernize-use-using,cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) // NOLINTBEGIN(modernize-use-using,cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
#define MOUNTMGRCONTROLTYPE 0x0000006D // 'm' #define MOUNTMGRCONTROLTYPE 0x0000006D // 'm'
#define MOUNTDEVCONTROLTYPE 0x0000004D // 'M' #define MOUNTDEVCONTROLTYPE 0x0000004D // 'M'
#define IOCTL_MOUNTMGR_CREATE_POINT \ #define IOCTL_MOUNTMGR_CREATE_POINT CTL_CODE(MOUNTMGRCONTROLTYPE, 0, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
CTL_CODE(MOUNTMGRCONTROLTYPE, 0, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS) #define IOCTL_MOUNTMGR_DELETE_POINTS CTL_CODE(MOUNTMGRCONTROLTYPE, 1, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
#define IOCTL_MOUNTMGR_DELETE_POINTS \ #define IOCTL_MOUNTMGR_QUERY_POINTS CTL_CODE(MOUNTMGRCONTROLTYPE, 2, METHOD_BUFFERED, FILE_ANY_ACCESS)
CTL_CODE(MOUNTMGRCONTROLTYPE, 1, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS) #define IOCTL_MOUNTMGR_DELETE_POINTS_DBONLY CTL_CODE(MOUNTMGRCONTROLTYPE, 3, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
#define IOCTL_MOUNTMGR_QUERY_POINTS CTL_CODE(MOUNTMGRCONTROLTYPE, 2, METHOD_BUFFERED, FILE_ANY_ACCESS) #define IOCTL_MOUNTMGR_NEXT_DRIVE_LETTER CTL_CODE(MOUNTMGRCONTROLTYPE, 4, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
#define IOCTL_MOUNTMGR_DELETE_POINTS_DBONLY \ #define IOCTL_MOUNTMGR_AUTO_DL_ASSIGNMENTS CTL_CODE(MOUNTMGRCONTROLTYPE, 5, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
CTL_CODE(MOUNTMGRCONTROLTYPE, 3, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS) #define IOCTL_MOUNTMGR_VOLUME_MOUNT_POINT_CREATED CTL_CODE(MOUNTMGRCONTROLTYPE, 6, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
#define IOCTL_MOUNTMGR_NEXT_DRIVE_LETTER \ #define IOCTL_MOUNTMGR_VOLUME_MOUNT_POINT_DELETED CTL_CODE(MOUNTMGRCONTROLTYPE, 7, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
CTL_CODE(MOUNTMGRCONTROLTYPE, 4, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS) #define IOCTL_MOUNTMGR_CHANGE_NOTIFY CTL_CODE(MOUNTMGRCONTROLTYPE, 8, METHOD_BUFFERED, FILE_READ_ACCESS)
#define IOCTL_MOUNTMGR_AUTO_DL_ASSIGNMENTS \ #define IOCTL_MOUNTMGR_KEEP_LINKS_WHEN_OFFLINE CTL_CODE(MOUNTMGRCONTROLTYPE, 9, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
CTL_CODE(MOUNTMGRCONTROLTYPE, 5, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
#define IOCTL_MOUNTMGR_VOLUME_MOUNT_POINT_CREATED \
CTL_CODE(MOUNTMGRCONTROLTYPE, 6, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
#define IOCTL_MOUNTMGR_VOLUME_MOUNT_POINT_DELETED \
CTL_CODE(MOUNTMGRCONTROLTYPE, 7, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
#define IOCTL_MOUNTMGR_CHANGE_NOTIFY CTL_CODE(MOUNTMGRCONTROLTYPE, 8, METHOD_BUFFERED, FILE_READ_ACCESS)
#define IOCTL_MOUNTMGR_KEEP_LINKS_WHEN_OFFLINE \
CTL_CODE(MOUNTMGRCONTROLTYPE, 9, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
#define IOCTL_MOUNTMGR_CHECK_UNPROCESSED_VOLUMES CTL_CODE(MOUNTMGRCONTROLTYPE, 10, METHOD_BUFFERED, FILE_READ_ACCESS) #define IOCTL_MOUNTMGR_CHECK_UNPROCESSED_VOLUMES CTL_CODE(MOUNTMGRCONTROLTYPE, 10, METHOD_BUFFERED, FILE_READ_ACCESS)
#define IOCTL_MOUNTMGR_VOLUME_ARRIVAL_NOTIFICATION CTL_CODE(MOUNTMGRCONTROLTYPE, 11, METHOD_BUFFERED, FILE_READ_ACCESS) #define IOCTL_MOUNTMGR_VOLUME_ARRIVAL_NOTIFICATION CTL_CODE(MOUNTMGRCONTROLTYPE, 11, METHOD_BUFFERED, FILE_READ_ACCESS)
#define IOCTL_MOUNTMGR_QUERY_DOS_VOLUME_PATH CTL_CODE(MOUNTMGRCONTROLTYPE, 12, METHOD_BUFFERED, FILE_ANY_ACCESS) #define IOCTL_MOUNTMGR_QUERY_DOS_VOLUME_PATH CTL_CODE(MOUNTMGRCONTROLTYPE, 12, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_MOUNTMGR_QUERY_DOS_VOLUME_PATHS CTL_CODE(MOUNTMGRCONTROLTYPE, 13, METHOD_BUFFERED, FILE_ANY_ACCESS) #define IOCTL_MOUNTMGR_QUERY_DOS_VOLUME_PATHS CTL_CODE(MOUNTMGRCONTROLTYPE, 13, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_MOUNTMGR_SCRUB_REGISTRY \ #define IOCTL_MOUNTMGR_SCRUB_REGISTRY CTL_CODE(MOUNTMGRCONTROLTYPE, 14, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
CTL_CODE(MOUNTMGRCONTROLTYPE, 14, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS) #define IOCTL_MOUNTMGR_QUERY_AUTO_MOUNT CTL_CODE(MOUNTMGRCONTROLTYPE, 15, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_MOUNTMGR_QUERY_AUTO_MOUNT CTL_CODE(MOUNTMGRCONTROLTYPE, 15, METHOD_BUFFERED, FILE_ANY_ACCESS) #define IOCTL_MOUNTMGR_SET_AUTO_MOUNT CTL_CODE(MOUNTMGRCONTROLTYPE, 16, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
#define IOCTL_MOUNTMGR_SET_AUTO_MOUNT \
CTL_CODE(MOUNTMGRCONTROLTYPE, 16, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
#define IOCTL_MOUNTMGR_BOOT_DL_ASSIGNMENT \ #define IOCTL_MOUNTMGR_BOOT_DL_ASSIGNMENT \
CTL_CODE(MOUNTMGRCONTROLTYPE, 17, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS) // since WIN7 CTL_CODE(MOUNTMGRCONTROLTYPE, 17, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS) // since WIN7
#define IOCTL_MOUNTMGR_TRACELOG_CACHE CTL_CODE(MOUNTMGRCONTROLTYPE, 18, METHOD_BUFFERED, FILE_READ_ACCESS) #define IOCTL_MOUNTMGR_TRACELOG_CACHE CTL_CODE(MOUNTMGRCONTROLTYPE, 18, METHOD_BUFFERED, FILE_READ_ACCESS)
#define IOCTL_MOUNTMGR_PREPARE_VOLUME_DELETE \ #define IOCTL_MOUNTMGR_PREPARE_VOLUME_DELETE CTL_CODE(MOUNTMGRCONTROLTYPE, 19, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
CTL_CODE(MOUNTMGRCONTROLTYPE, 19, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
#define IOCTL_MOUNTMGR_CANCEL_VOLUME_DELETE \ #define IOCTL_MOUNTMGR_CANCEL_VOLUME_DELETE \
CTL_CODE(MOUNTMGRCONTROLTYPE, 20, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS) // since WIN8 CTL_CODE(MOUNTMGRCONTROLTYPE, 20, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS) // since WIN8
#define IOCTL_MOUNTMGR_SILO_ARRIVAL \ #define IOCTL_MOUNTMGR_SILO_ARRIVAL CTL_CODE(MOUNTMGRCONTROLTYPE, 21, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS) // since RS1
CTL_CODE(MOUNTMGRCONTROLTYPE, 21, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS) // since RS1
#define IOCTL_MOUNTDEV_QUERY_DEVICE_NAME CTL_CODE(MOUNTDEVCONTROLTYPE, 2, METHOD_BUFFERED, FILE_ANY_ACCESS) #define IOCTL_MOUNTDEV_QUERY_DEVICE_NAME CTL_CODE(MOUNTDEVCONTROLTYPE, 2, METHOD_BUFFERED, FILE_ANY_ACCESS)

View File

@@ -10,19 +10,17 @@ namespace
// RNG Microsoft Primitive Provider // RNG Microsoft Primitive Provider
// NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
std::uint8_t output_data[216] = // std::uint8_t output_data[216] = //
{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x98, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x98, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x52, 0x00, 0x4E, 0x00, 0x47, 0x52, 0x00, 0x4E, 0x00, 0x47, 0x00, 0x00, 0x00, 0x4D, 0x00, 0x69, 0x00, 0x63, 0x00, 0x72, 0x00, 0x6F, 0x00, 0x73, 0x00,
0x00, 0x00, 0x00, 0x4D, 0x00, 0x69, 0x00, 0x63, 0x00, 0x72, 0x00, 0x6F, 0x00, 0x73, 0x00, 0x6F, 0x00, 0x6F, 0x00, 0x66, 0x00, 0x74, 0x00, 0x20, 0x00, 0x50, 0x00, 0x72, 0x00, 0x69, 0x00, 0x6D, 0x00, 0x69, 0x00, 0x74, 0x00,
0x66, 0x00, 0x74, 0x00, 0x20, 0x00, 0x50, 0x00, 0x72, 0x00, 0x69, 0x00, 0x6D, 0x00, 0x69, 0x00, 0x74, 0x69, 0x00, 0x76, 0x00, 0x65, 0x00, 0x20, 0x00, 0x50, 0x00, 0x72, 0x00, 0x6F, 0x00, 0x76, 0x00, 0x69, 0x00, 0x64, 0x00,
0x00, 0x69, 0x00, 0x76, 0x00, 0x65, 0x00, 0x20, 0x00, 0x50, 0x00, 0x72, 0x00, 0x6F, 0x00, 0x76, 0x00, 0x65, 0x00, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x69, 0x00, 0x64, 0x00, 0x65, 0x00, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x62, 0x00, 0x63, 0x00, 0x72, 0x00, 0x79, 0x00, 0x70, 0x00, 0x74, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x62, 0x00, 0x70, 0x00, 0x72, 0x00, 0x69, 0x00, 0x6D, 0x00, 0x69, 0x00, 0x74, 0x00, 0x69, 0x00, 0x76, 0x00, 0x65, 0x00, 0x73, 0x00,
0x63, 0x00, 0x72, 0x00, 0x79, 0x00, 0x70, 0x00, 0x74, 0x00, 0x70, 0x00, 0x72, 0x00, 0x69, 0x00, 0x6D, 0x2E, 0x00, 0x64, 0x00, 0x6C, 0x00, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
0x00, 0x69, 0x00, 0x74, 0x00, 0x69, 0x00, 0x76, 0x00, 0x65, 0x00, 0x73, 0x00, 0x2E, 0x00, 0x64, 0x00,
0x6C, 0x00, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
NTSTATUS io_control(windows_emulator& win_emu, const io_device_context& c) override NTSTATUS io_control(windows_emulator& win_emu, const io_device_context& c) override
{ {

View File

@@ -10,8 +10,7 @@ namespace
emulator_object<T> allocate_object_on_stack(x86_64_emulator& emu) emulator_object<T> allocate_object_on_stack(x86_64_emulator& emu)
{ {
const auto old_sp = emu.reg(x86_register::rsp); const auto old_sp = emu.reg(x86_register::rsp);
const auto new_sp = const auto new_sp = align_down(old_sp - sizeof(T), std::max(alignof(T), alignof(x86_64_emulator::pointer_type)));
align_down(old_sp - sizeof(T), std::max(alignof(T), alignof(x86_64_emulator::pointer_type)));
emu.reg(x86_register::rsp, new_sp); emu.reg(x86_register::rsp, new_sp);
return {emu, new_sp}; return {emu, new_sp};
} }
@@ -88,8 +87,7 @@ namespace
} }
emulator_thread::emulator_thread(memory_manager& memory, const process_context& context, const uint64_t start_address, emulator_thread::emulator_thread(memory_manager& memory, const process_context& context, const uint64_t start_address,
const uint64_t argument, const uint64_t stack_size, const bool suspended, const uint64_t argument, const uint64_t stack_size, const bool suspended, const uint32_t id)
const uint32_t id)
: memory_ptr(&memory), : memory_ptr(&memory),
stack_size(page_align_up(std::max(stack_size, static_cast<uint64_t>(STACK_SIZE)))), stack_size(page_align_up(std::max(stack_size, static_cast<uint64_t>(STACK_SIZE)))),
start_address(start_address), start_address(start_address),

View File

@@ -48,8 +48,8 @@ class emulator_thread : public ref_counted_object
{ {
} }
emulator_thread(memory_manager& memory, const process_context& context, uint64_t start_address, uint64_t argument, emulator_thread(memory_manager& memory, const process_context& context, uint64_t start_address, uint64_t argument, uint64_t stack_size,
uint64_t stack_size, bool suspended, uint32_t id); bool suspended, uint32_t id);
emulator_thread(const emulator_thread&) = delete; emulator_thread(const emulator_thread&) = delete;
emulator_thread& operator=(const emulator_thread&) = delete; emulator_thread& operator=(const emulator_thread&) = delete;

View File

@@ -251,8 +251,8 @@ class emulator_allocator
result.MaximumLength = static_cast<USHORT>(max_length); result.MaximumLength = static_cast<USHORT>(max_length);
} }
emulator_object<UNICODE_STRING<EmulatorTraits<Emu64>>> make_unicode_string( emulator_object<UNICODE_STRING<EmulatorTraits<Emu64>>> make_unicode_string(const std::u16string_view str,
const std::u16string_view str, const std::optional<size_t> maximum_length = std::nullopt) const std::optional<size_t> maximum_length = std::nullopt)
{ {
const auto unicode_string = this->reserve<UNICODE_STRING<EmulatorTraits<Emu64>>>(); const auto unicode_string = this->reserve<UNICODE_STRING<EmulatorTraits<Emu64>>>();
@@ -316,8 +316,7 @@ class emulator_allocator
}; };
template <typename Element> template <typename Element>
std::basic_string<Element> read_string(memory_interface& mem, const uint64_t address, std::basic_string<Element> read_string(memory_interface& mem, const uint64_t address, const std::optional<size_t> size = {})
const std::optional<size_t> size = {})
{ {
std::basic_string<Element> result{}; std::basic_string<Element> result{};
@@ -357,8 +356,7 @@ inline std::u16string read_unicode_string(const emulator& emu, const UNICODE_STR
return result; return result;
} }
inline std::u16string read_unicode_string(const emulator& emu, inline std::u16string read_unicode_string(const emulator& emu, const emulator_object<UNICODE_STRING<EmulatorTraits<Emu64>>> uc_string)
const emulator_object<UNICODE_STRING<EmulatorTraits<Emu64>>> uc_string)
{ {
const auto ucs = uc_string.read(); const auto ucs = uc_string.read();
return read_unicode_string(emu, ucs); return read_unicode_string(emu, ucs);

View File

@@ -8,8 +8,7 @@ namespace
using exception_record = EMU_EXCEPTION_RECORD<EmulatorTraits<Emu64>>; using exception_record = EMU_EXCEPTION_RECORD<EmulatorTraits<Emu64>>;
using exception_record_map = std::unordered_map<const exception_record*, emulator_object<exception_record>>; using exception_record_map = std::unordered_map<const exception_record*, emulator_object<exception_record>>;
emulator_object<exception_record> save_exception_record(emulator_allocator& allocator, emulator_object<exception_record> save_exception_record(emulator_allocator& allocator, const exception_record& record,
const exception_record& record,
exception_record_map& record_mapping) exception_record_map& record_mapping)
{ {
const auto record_obj = allocator.reserve<exception_record>(); const auto record_obj = allocator.reserve<exception_record>();
@@ -28,8 +27,8 @@ namespace
} }
else else
{ {
nested_record_obj = save_exception_record( nested_record_obj =
allocator, *reinterpret_cast<exception_record*>(record.ExceptionRecord), record_mapping); save_exception_record(allocator, *reinterpret_cast<exception_record*>(record.ExceptionRecord), record_mapping);
} }
record_obj.access([&](exception_record& r) { record_obj.access([&](exception_record& r) {
@@ -40,8 +39,7 @@ namespace
return record_obj; return record_obj;
} }
emulator_object<exception_record> save_exception_record(emulator_allocator& allocator, emulator_object<exception_record> save_exception_record(emulator_allocator& allocator, const exception_record& record)
const exception_record& record)
{ {
exception_record_map record_mapping{}; exception_record_map record_mapping{};
return save_exception_record(allocator, record, record_mapping); return save_exception_record(allocator, record, record_mapping);
@@ -94,8 +92,7 @@ namespace
{ {
constexpr auto mach_frame_size = 0x40; constexpr auto mach_frame_size = 0x40;
constexpr auto context_record_size = 0x4F0; constexpr auto context_record_size = 0x4F0;
const auto exception_record_size = const auto exception_record_size = calculate_exception_record_size(*reinterpret_cast<exception_record*>(pointers.ExceptionRecord));
calculate_exception_record_size(*reinterpret_cast<exception_record*>(pointers.ExceptionRecord));
const auto combined_size = align_up(exception_record_size + context_record_size, 0x10); const auto combined_size = align_up(exception_record_size + context_record_size, 0x10);
assert(combined_size == 0x590); assert(combined_size == 0x590);
@@ -120,8 +117,7 @@ namespace
context_record_obj.write(*reinterpret_cast<CONTEXT64*>(pointers.ContextRecord)); context_record_obj.write(*reinterpret_cast<CONTEXT64*>(pointers.ContextRecord));
emulator_allocator allocator{emu, new_sp + context_record_size, exception_record_size}; emulator_allocator allocator{emu, new_sp + context_record_size, exception_record_size};
const auto exception_record_obj = const auto exception_record_obj = save_exception_record(allocator, *reinterpret_cast<exception_record*>(pointers.ExceptionRecord));
save_exception_record(allocator, *reinterpret_cast<exception_record*>(pointers.ExceptionRecord));
if (exception_record_obj.value() != allocator.get_base()) if (exception_record_obj.value() != allocator.get_base())
{ {
@@ -172,8 +168,7 @@ void dispatch_exception(x86_64_emulator& emu, const process_context& proc, const
dispatch_exception_pointers(emu, proc.ki_user_exception_dispatcher, pointers); dispatch_exception_pointers(emu, proc.ki_user_exception_dispatcher, pointers);
} }
void dispatch_access_violation(x86_64_emulator& emu, const process_context& proc, const uint64_t address, void dispatch_access_violation(x86_64_emulator& emu, const process_context& proc, const uint64_t address, const memory_operation operation)
const memory_operation operation)
{ {
dispatch_exception(emu, proc, STATUS_ACCESS_VIOLATION, dispatch_exception(emu, proc, STATUS_ACCESS_VIOLATION,
{ {

View File

@@ -17,10 +17,8 @@ void dispatch_exception(x86_64_emulator& emu, const process_context& proc, const
dispatch_exception(emu, proc, static_cast<DWORD>(status), parameters); dispatch_exception(emu, proc, static_cast<DWORD>(status), parameters);
} }
void dispatch_access_violation(x86_64_emulator& emu, const process_context& proc, uint64_t address, void dispatch_access_violation(x86_64_emulator& emu, const process_context& proc, uint64_t address, memory_operation operation);
memory_operation operation); void dispatch_guard_page_violation(x86_64_emulator& emu, const process_context& proc, uint64_t address, memory_operation operation);
void dispatch_guard_page_violation(x86_64_emulator& emu, const process_context& proc, uint64_t address,
memory_operation operation);
void dispatch_illegal_instruction_violation(x86_64_emulator& emu, const process_context& proc); void dispatch_illegal_instruction_violation(x86_64_emulator& emu, const process_context& proc);
void dispatch_integer_division_by_zero(x86_64_emulator& emu, const process_context& proc); void dispatch_integer_division_by_zero(x86_64_emulator& emu, const process_context& proc);
void dispatch_single_step(x86_64_emulator& emu, const process_context& proc); void dispatch_single_step(x86_64_emulator& emu, const process_context& proc);

View File

@@ -65,8 +65,8 @@ struct io_device_creation_data
uint32_t length; uint32_t length;
}; };
inline NTSTATUS write_io_status(const emulator_object<IO_STATUS_BLOCK<EmulatorTraits<Emu64>>> io_status_block, inline NTSTATUS write_io_status(const emulator_object<IO_STATUS_BLOCK<EmulatorTraits<Emu64>>> io_status_block, const NTSTATUS status,
const NTSTATUS status, const bool clear_struct = false) const bool clear_struct = false)
{ {
io_status_block.access([=](IO_STATUS_BLOCK<EmulatorTraits<Emu64>>& status_block) { io_status_block.access([=](IO_STATUS_BLOCK<EmulatorTraits<Emu64>>& status_block) {
if (clear_struct) if (clear_struct)

View File

@@ -25,8 +25,7 @@ namespace
i->second.length = static_cast<size_t>(first_length); i->second.length = static_cast<size_t>(first_length);
regions[split_point] = regions[split_point] = memory_manager::committed_region{static_cast<size_t>(second_length), i->second.permissions};
memory_manager::committed_region{static_cast<size_t>(second_length), i->second.permissions};
} }
} }
} }
@@ -244,8 +243,7 @@ bool memory_manager::protect_memory(const uint64_t address, const size_t size, c
return true; return true;
} }
bool memory_manager::allocate_mmio(const uint64_t address, const size_t size, mmio_read_callback read_cb, bool memory_manager::allocate_mmio(const uint64_t address, const size_t size, mmio_read_callback read_cb, mmio_write_callback write_cb)
mmio_write_callback write_cb)
{ {
if (this->overlaps_reserved_region(address, size)) if (this->overlaps_reserved_region(address, size))
{ {
@@ -475,8 +473,7 @@ void memory_manager::unmap_all_memory()
this->reserved_regions_.clear(); this->reserved_regions_.clear();
} }
uint64_t memory_manager::allocate_memory(const size_t size, const nt_memory_permission permissions, uint64_t memory_manager::allocate_memory(const size_t size, const nt_memory_permission permissions, const bool reserve_only)
const bool reserve_only)
{ {
const auto allocation_base = this->find_free_allocation_base(size); const auto allocation_base = this->find_free_allocation_base(size);
if (!allocate_memory(allocation_base, size, permissions, reserve_only)) if (!allocate_memory(allocation_base, size, permissions, reserve_only))
@@ -639,8 +636,7 @@ void memory_manager::write_memory(const uint64_t address, const void* data, cons
this->memory_->write_memory(address, data, size); this->memory_->write_memory(address, data, size);
} }
void memory_manager::map_mmio(const uint64_t address, const size_t size, mmio_read_callback read_cb, void memory_manager::map_mmio(const uint64_t address, const size_t size, mmio_read_callback read_cb, mmio_write_callback write_cb)
mmio_write_callback write_cb)
{ {
this->memory_->map_mmio(address, size, std::move(read_cb), std::move(write_cb)); this->memory_->map_mmio(address, size, std::move(read_cb), std::move(write_cb));
} }
@@ -655,8 +651,7 @@ void memory_manager::unmap_memory(const uint64_t address, const size_t size)
this->memory_->unmap_memory(address, size); this->memory_->unmap_memory(address, size);
} }
void memory_manager::apply_memory_protection(const uint64_t address, const size_t size, void memory_manager::apply_memory_protection(const uint64_t address, const size_t size, const memory_permission permissions)
const memory_permission permissions)
{ {
this->memory_->apply_memory_protection(address, size, permissions); this->memory_->apply_memory_protection(address, size, permissions);
} }

View File

@@ -63,8 +63,7 @@ class memory_manager : public memory_interface
bool try_read_memory(uint64_t address, void* data, size_t size) const final; bool try_read_memory(uint64_t address, void* data, size_t size) const final;
void write_memory(uint64_t address, const void* data, size_t size) final; void write_memory(uint64_t address, const void* data, size_t size) final;
bool protect_memory(uint64_t address, size_t size, nt_memory_permission permissions, bool protect_memory(uint64_t address, size_t size, nt_memory_permission permissions, nt_memory_permission* old_permissions = nullptr);
nt_memory_permission* old_permissions = nullptr);
bool allocate_mmio(uint64_t address, size_t size, mmio_read_callback read_cb, mmio_write_callback write_cb); bool allocate_mmio(uint64_t address, size_t size, mmio_read_callback read_cb, mmio_write_callback write_cb);
bool allocate_memory(uint64_t address, size_t size, nt_memory_permission permissions, bool reserve_only = false); bool allocate_memory(uint64_t address, size_t size, nt_memory_permission permissions, bool reserve_only = false);

View File

@@ -51,8 +51,7 @@ namespace minidump_loader
} }
bool parse_minidump_file(windows_emulator& win_emu, const std::filesystem::path& minidump_path, bool parse_minidump_file(windows_emulator& win_emu, const std::filesystem::path& minidump_path,
std::unique_ptr<minidump::minidump_file>& dump_file, std::unique_ptr<minidump::minidump_file>& dump_file, std::unique_ptr<minidump::minidump_reader>& dump_reader)
std::unique_ptr<minidump::minidump_reader>& dump_reader)
{ {
win_emu.log.info("Parsing minidump file\n"); win_emu.log.info("Parsing minidump file\n");
@@ -160,10 +159,9 @@ namespace minidump_loader
stats.total_memory_size += segment.size; stats.total_memory_size += segment.size;
} }
win_emu.log.info( win_emu.log.info("Summary: %s, %zu threads, %zu modules, %zu regions, %zu segments, %zu handles, %" PRIu64 " bytes memory\n",
"Summary: %s, %zu threads, %zu modules, %zu regions, %zu segments, %zu handles, %" PRIu64 " bytes memory\n", get_architecture_string(dump_file).c_str(), stats.thread_count, stats.module_count, stats.memory_region_count,
get_architecture_string(dump_file).c_str(), stats.thread_count, stats.module_count, stats.memory_segment_count, stats.handle_count, stats.total_memory_size);
stats.memory_region_count, stats.memory_segment_count, stats.handle_count, stats.total_memory_size);
} }
void process_streams(windows_emulator& win_emu, const minidump::minidump_file* dump_file) void process_streams(windows_emulator& win_emu, const minidump::minidump_file* dump_file)
@@ -177,9 +175,8 @@ namespace minidump_loader
const auto* sys_info = dump_file->get_system_info(); const auto* sys_info = dump_file->get_system_info();
if (sys_info) if (sys_info)
{ {
win_emu.log.info("System: OS %u.%u.%u, %u processors, type %u, platform %u\n", sys_info->major_version, win_emu.log.info("System: OS %u.%u.%u, %u processors, type %u, platform %u\n", sys_info->major_version, sys_info->minor_version,
sys_info->minor_version, sys_info->build_number, sys_info->number_of_processors, sys_info->build_number, sys_info->number_of_processors, sys_info->product_type, sys_info->platform_id);
sys_info->product_type, sys_info->platform_id);
} }
// Process memory info // Process memory info
@@ -199,8 +196,7 @@ namespace minidump_loader
guard_pages++; guard_pages++;
} }
} }
win_emu.log.info("Memory: %zu regions, %" PRIu64 " bytes reserved, %" PRIu64 win_emu.log.info("Memory: %zu regions, %" PRIu64 " bytes reserved, %" PRIu64 " bytes committed, %zu guard pages\n",
" bytes committed, %zu guard pages\n",
memory_regions.size(), total_reserved, total_committed, guard_pages); memory_regions.size(), total_reserved, total_committed, guard_pages);
// Process memory content // Process memory content
@@ -214,25 +210,23 @@ namespace minidump_loader
} }
if (!memory_segments.empty()) if (!memory_segments.empty())
{ {
win_emu.log.info("Content: %zu segments, range 0x%" PRIx64 "-0x%" PRIx64 " (%" PRIu64 " bytes span)\n", win_emu.log.info("Content: %zu segments, range 0x%" PRIx64 "-0x%" PRIx64 " (%" PRIu64 " bytes span)\n", memory_segments.size(),
memory_segments.size(), min_addr, max_addr, max_addr - min_addr); min_addr, max_addr, max_addr - min_addr);
} }
// Process modules // Process modules
const auto& modules = dump_file->modules(); const auto& modules = dump_file->modules();
for (const auto& mod : modules) for (const auto& mod : modules)
{ {
win_emu.log.info("Module: %s at 0x%" PRIx64 " (%u bytes)\n", mod.module_name.c_str(), mod.base_of_image, win_emu.log.info("Module: %s at 0x%" PRIx64 " (%u bytes)\n", mod.module_name.c_str(), mod.base_of_image, mod.size_of_image);
mod.size_of_image);
} }
// Process threads // Process threads
const auto& threads = dump_file->threads(); const auto& threads = dump_file->threads();
for (const auto& thread : threads) for (const auto& thread : threads)
{ {
win_emu.log.info("Thread %u: TEB 0x%" PRIx64 ", stack 0x%" PRIx64 " (%u bytes), context %u bytes\n", win_emu.log.info("Thread %u: TEB 0x%" PRIx64 ", stack 0x%" PRIx64 " (%u bytes), context %u bytes\n", thread.thread_id,
thread.thread_id, thread.teb, thread.stack_start_of_memory_range, thread.stack_data_size, thread.teb, thread.stack_start_of_memory_range, thread.stack_data_size, thread.context_data_size);
thread.context_data_size);
} }
// Process handles // Process handles
@@ -272,8 +266,7 @@ namespace minidump_loader
const auto& memory_regions = dump_file->memory_regions(); const auto& memory_regions = dump_file->memory_regions();
const auto& memory_segments = dump_file->memory_segments(); const auto& memory_segments = dump_file->memory_segments();
win_emu.log.info("Reconstructing memory: %zu regions, %zu data segments\n", memory_regions.size(), win_emu.log.info("Reconstructing memory: %zu regions, %zu data segments\n", memory_regions.size(), memory_segments.size());
memory_segments.size());
size_t reserved_count = 0; size_t reserved_count = 0;
size_t committed_count = 0; size_t committed_count = 0;
size_t failed_count = 0; size_t failed_count = 0;
@@ -281,8 +274,8 @@ namespace minidump_loader
for (const auto& region : memory_regions) for (const auto& region : memory_regions)
{ {
// Log the memory region details // Log the memory region details
win_emu.log.info("Region: 0x%" PRIx64 ", size=%" PRIu64 ", state=0x%08X, protect=0x%08X\n", win_emu.log.info("Region: 0x%" PRIx64 ", size=%" PRIu64 ", state=0x%08X, protect=0x%08X\n", region.base_address,
region.base_address, region.region_size, region.state, region.protect); region.region_size, region.state, region.protect);
const bool is_reserved = (region.state & MEM_RESERVE) != 0; const bool is_reserved = (region.state & MEM_RESERVE) != 0;
const bool is_committed = (region.state & MEM_COMMIT) != 0; const bool is_committed = (region.state & MEM_COMMIT) != 0;
@@ -297,8 +290,7 @@ namespace minidump_loader
if (protect_value == 0) if (protect_value == 0)
{ {
protect_value = PAGE_READONLY; protect_value = PAGE_READONLY;
win_emu.log.warn(" Region 0x%" PRIx64 " has zero protection, using PAGE_READONLY\n", win_emu.log.warn(" Region 0x%" PRIx64 " has zero protection, using PAGE_READONLY\n", region.base_address);
region.base_address);
} }
memory_permission perms = map_nt_to_emulator_protection(protect_value); memory_permission perms = map_nt_to_emulator_protection(protect_value);
@@ -307,35 +299,31 @@ namespace minidump_loader
{ {
if (is_committed) if (is_committed)
{ {
if (win_emu.memory.allocate_memory(region.base_address, static_cast<size_t>(region.region_size), if (win_emu.memory.allocate_memory(region.base_address, static_cast<size_t>(region.region_size), perms, false))
perms, false))
{ {
committed_count++; committed_count++;
win_emu.log.info(" Allocated committed 0x%" PRIx64 ": size=%" PRIu64 win_emu.log.info(" Allocated committed 0x%" PRIx64 ": size=%" PRIu64 ", state=0x%08X, protect=0x%08X\n",
", state=0x%08X, protect=0x%08X\n",
region.base_address, region.region_size, region.state, region.protect); region.base_address, region.region_size, region.state, region.protect);
} }
else else
{ {
failed_count++; failed_count++;
win_emu.log.warn(" Failed to allocate committed 0x%" PRIx64 ": size=%" PRIu64 "\n", win_emu.log.warn(" Failed to allocate committed 0x%" PRIx64 ": size=%" PRIu64 "\n", region.base_address,
region.base_address, region.region_size); region.region_size);
} }
} }
else if (is_reserved) else if (is_reserved)
{ {
if (win_emu.memory.allocate_memory(region.base_address, static_cast<size_t>(region.region_size), if (win_emu.memory.allocate_memory(region.base_address, static_cast<size_t>(region.region_size), perms, true))
perms, true))
{ {
reserved_count++; reserved_count++;
win_emu.log.info(" Reserved 0x%" PRIx64 ": size=%" PRIu64 ", state=0x%08X, protect=0x%08X\n", win_emu.log.info(" Reserved 0x%" PRIx64 ": size=%" PRIu64 ", state=0x%08X, protect=0x%08X\n", region.base_address,
region.base_address, region.region_size, region.state, region.protect); region.region_size, region.state, region.protect);
} }
else else
{ {
failed_count++; failed_count++;
win_emu.log.warn(" Failed to reserve 0x%" PRIx64 ": size=%" PRIu64 "\n", region.base_address, win_emu.log.warn(" Failed to reserve 0x%" PRIx64 ": size=%" PRIu64 "\n", region.base_address, region.region_size);
region.region_size);
} }
} }
} }
@@ -346,8 +334,7 @@ namespace minidump_loader
} }
} }
win_emu.log.info("Regions: %zu reserved, %zu committed, %zu failed\n", reserved_count, committed_count, win_emu.log.info("Regions: %zu reserved, %zu committed, %zu failed\n", reserved_count, committed_count, failed_count);
failed_count);
size_t written_count = 0; size_t written_count = 0;
size_t write_failed_count = 0; size_t write_failed_count = 0;
uint64_t total_bytes_written = 0; uint64_t total_bytes_written = 0;
@@ -356,25 +343,21 @@ namespace minidump_loader
{ {
try try
{ {
auto memory_data = auto memory_data = dump_reader->read_memory(segment.start_virtual_address, static_cast<size_t>(segment.size));
dump_reader->read_memory(segment.start_virtual_address, static_cast<size_t>(segment.size)); win_emu.memory.write_memory(segment.start_virtual_address, memory_data.data(), static_cast<size_t>(memory_data.size()));
win_emu.memory.write_memory(segment.start_virtual_address, memory_data.data(),
static_cast<size_t>(memory_data.size()));
written_count++; written_count++;
total_bytes_written += memory_data.size(); total_bytes_written += memory_data.size();
win_emu.log.info(" Written segment 0x%" PRIx64 ": %zu bytes\n", segment.start_virtual_address, win_emu.log.info(" Written segment 0x%" PRIx64 ": %zu bytes\n", segment.start_virtual_address, memory_data.size());
memory_data.size());
} }
catch (const std::exception& e) catch (const std::exception& e)
{ {
write_failed_count++; write_failed_count++;
win_emu.log.error(" Failed to write segment 0x%" PRIx64 ": %s\n", segment.start_virtual_address, win_emu.log.error(" Failed to write segment 0x%" PRIx64 ": %s\n", segment.start_virtual_address, e.what());
e.what());
} }
} }
win_emu.log.info("Content: %zu segments written (%" PRIu64 " bytes), %zu failed\n", written_count, win_emu.log.info("Content: %zu segments written (%" PRIu64 " bytes), %zu failed\n", written_count, total_bytes_written,
total_bytes_written, write_failed_count); write_failed_count);
} }
bool is_main_executable(const minidump::module_info& mod) bool is_main_executable(const minidump::module_info& mod)
@@ -414,15 +397,14 @@ namespace minidump_loader
{ {
try try
{ {
auto* mapped_module = win_emu.mod_manager.map_memory_module(mod.base_of_image, mod.size_of_image, auto* mapped_module =
mod.module_name, win_emu.log); win_emu.mod_manager.map_memory_module(mod.base_of_image, mod.size_of_image, mod.module_name, win_emu.log);
if (mapped_module) if (mapped_module)
{ {
mapped_count++; mapped_count++;
win_emu.log.info(" Mapped %s at 0x%" PRIx64 " (%u bytes, %zu sections, %zu exports)\n", win_emu.log.info(" Mapped %s at 0x%" PRIx64 " (%u bytes, %zu sections, %zu exports)\n", mod.module_name.c_str(),
mod.module_name.c_str(), mod.base_of_image, mod.size_of_image, mod.base_of_image, mod.size_of_image, mapped_module->sections.size(), mapped_module->exports.size());
mapped_module->sections.size(), mapped_module->exports.size());
if (is_main_executable(mod)) if (is_main_executable(mod))
{ {
@@ -446,8 +428,7 @@ namespace minidump_loader
else else
{ {
failed_count++; failed_count++;
win_emu.log.warn(" Failed to map %s at 0x%" PRIx64 "\n", mod.module_name.c_str(), win_emu.log.warn(" Failed to map %s at 0x%" PRIx64 "\n", mod.module_name.c_str(), mod.base_of_image);
mod.base_of_image);
} }
} }
catch (const std::exception& e) catch (const std::exception& e)
@@ -457,8 +438,8 @@ namespace minidump_loader
} }
} }
win_emu.log.info("Module reconstruction: %zu mapped, %zu failed, %zu system modules identified\n", mapped_count, win_emu.log.info("Module reconstruction: %zu mapped, %zu failed, %zu system modules identified\n", mapped_count, failed_count,
failed_count, identified_count); identified_count);
} }
void setup_kusd_from_dump(windows_emulator& win_emu, const minidump::minidump_file* dump_file) void setup_kusd_from_dump(windows_emulator& win_emu, const minidump::minidump_file* dump_file)
@@ -483,8 +464,7 @@ namespace minidump_loader
kusd.ProductTypeIsValid = 1; kusd.ProductTypeIsValid = 1;
win_emu.log.info("KUSD updated: Windows %u.%u.%u, %u processors, product type %u\n", sys_info->major_version, win_emu.log.info("KUSD updated: Windows %u.%u.%u, %u processors, product type %u\n", sys_info->major_version,
sys_info->minor_version, sys_info->build_number, sys_info->number_of_processors, sys_info->minor_version, sys_info->build_number, sys_info->number_of_processors, sys_info->product_type);
sys_info->product_type);
} }
bool load_thread_context(const std::filesystem::path& minidump_path, const minidump::thread_info& thread_info, bool load_thread_context(const std::filesystem::path& minidump_path, const minidump::thread_info& thread_info,
@@ -546,8 +526,8 @@ namespace minidump_loader
thread.teb->set_address(thread_info.teb); thread.teb->set_address(thread_info.teb);
} }
win_emu.log.info(" Thread %u: TEB=0x%" PRIx64 ", stack=0x%" PRIx64 " (%u bytes), context=%s\n", win_emu.log.info(" Thread %u: TEB=0x%" PRIx64 ", stack=0x%" PRIx64 " (%u bytes), context=%s\n", thread_info.thread_id,
thread_info.thread_id, thread_info.teb, thread.stack_base, thread_info.stack_data_size, thread_info.teb, thread.stack_base, thread_info.stack_data_size,
context_loaded ? "loaded" : "unavailable"); context_loaded ? "loaded" : "unavailable");
win_emu.process.threads.store(std::move(thread)); win_emu.process.threads.store(std::move(thread));
@@ -566,8 +546,8 @@ namespace minidump_loader
win_emu.process.active_thread = &first_thread; win_emu.process.active_thread = &first_thread;
} }
win_emu.log.info("Thread reconstruction: %zu/%zu threads created, %zu with context\n", success_count, win_emu.log.info("Thread reconstruction: %zu/%zu threads created, %zu with context\n", success_count, threads.size(),
threads.size(), context_loaded_count); context_loaded_count);
} }
void setup_peb_from_teb(windows_emulator& win_emu, const minidump::minidump_file* dump_file) void setup_peb_from_teb(windows_emulator& win_emu, const minidump::minidump_file* dump_file)
@@ -652,8 +632,8 @@ namespace minidump_loader
} }
catch (const std::exception& e) catch (const std::exception& e)
{ {
win_emu.log.error(" Failed to create %s handle '%s': %s\n", handle_info.type_name.c_str(), win_emu.log.error(" Failed to create %s handle '%s': %s\n", handle_info.type_name.c_str(), handle_info.object_name.c_str(),
handle_info.object_name.c_str(), e.what()); e.what());
} }
} }
@@ -676,8 +656,8 @@ namespace minidump_loader
win_emu.process.current_ip = exception_info->exception_record.exception_address; win_emu.process.current_ip = exception_info->exception_record.exception_address;
win_emu.log.info("Exception context: address=0x%" PRIx64 ", code=0x%08X, thread=%u\n", win_emu.log.info("Exception context: address=0x%" PRIx64 ", code=0x%08X, thread=%u\n",
exception_info->exception_record.exception_address, exception_info->exception_record.exception_address, exception_info->exception_record.exception_code,
exception_info->exception_record.exception_code, exception_info->thread_id); exception_info->thread_id);
} }
void load_minidump_into_emulator(windows_emulator& win_emu, const std::filesystem::path& minidump_path) void load_minidump_into_emulator(windows_emulator& win_emu, const std::filesystem::path& minidump_path)

View File

@@ -91,8 +91,8 @@ module_manager::module_manager(memory_manager& memory, file_system& file_sys, ca
{ {
} }
void module_manager::map_main_modules(const windows_path& executable_path, const windows_path& ntdll_path, void module_manager::map_main_modules(const windows_path& executable_path, const windows_path& ntdll_path, const windows_path& win32u_path,
const windows_path& win32u_path, const logger& logger) const logger& logger)
{ {
this->executable = this->map_module(executable_path, logger, true); this->executable = this->map_module(executable_path, logger, true);
this->ntdll = this->map_module(ntdll_path, logger, true); this->ntdll = this->map_module(ntdll_path, logger, true);
@@ -104,8 +104,7 @@ mapped_module* module_manager::map_module(const windows_path& file, const logger
return this->map_local_module(this->file_sys_->translate(file), logger, is_static); return this->map_local_module(this->file_sys_->translate(file), logger, is_static);
} }
mapped_module* module_manager::map_local_module(const std::filesystem::path& file, const logger& logger, mapped_module* module_manager::map_local_module(const std::filesystem::path& file, const logger& logger, const bool is_static)
const bool is_static)
{ {
auto local_file = weakly_canonical(absolute(file)); auto local_file = weakly_canonical(absolute(file));
@@ -139,8 +138,8 @@ mapped_module* module_manager::map_local_module(const std::filesystem::path& fil
} }
} }
mapped_module* module_manager::map_memory_module(uint64_t base_address, uint64_t image_size, mapped_module* module_manager::map_memory_module(uint64_t base_address, uint64_t image_size, const std::string& module_name,
const std::string& module_name, const logger& logger, bool is_static) const logger& logger, bool is_static)
{ {
for (auto& mod : this->modules_ | std::views::values) for (auto& mod : this->modules_ | std::views::values)
{ {
@@ -162,14 +161,12 @@ mapped_module* module_manager::map_memory_module(uint64_t base_address, uint64_t
} }
catch (const std::exception& e) catch (const std::exception& e)
{ {
logger.error("Failed to map module from memory %s at 0x%016" PRIx64 ": %s\n", module_name.c_str(), base_address, logger.error("Failed to map module from memory %s at 0x%016" PRIx64 ": %s\n", module_name.c_str(), base_address, e.what());
e.what());
return nullptr; return nullptr;
} }
catch (...) catch (...)
{ {
logger.error("Failed to map module from memory %s at 0x%016" PRIx64 ": Unknown error\n", module_name.c_str(), logger.error("Failed to map module from memory %s at 0x%016" PRIx64 ": Unknown error\n", module_name.c_str(), base_address);
base_address);
return nullptr; return nullptr;
} }
} }

View File

@@ -20,13 +20,13 @@ class module_manager
module_manager(memory_manager& memory, file_system& file_sys, callbacks& cb); 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, void map_main_modules(const windows_path& executable_path, const windows_path& ntdll_path, const windows_path& win32u_path,
const windows_path& win32u_path, const logger& logger); const logger& logger);
mapped_module* map_module(const windows_path& file, const logger& logger, bool is_static = false); mapped_module* map_module(const windows_path& file, const logger& logger, bool is_static = false);
mapped_module* map_local_module(const std::filesystem::path& file, const logger& logger, bool is_static = false); mapped_module* map_local_module(const std::filesystem::path& file, const logger& logger, bool is_static = false);
mapped_module* map_memory_module(uint64_t base_address, uint64_t image_size, const std::string& module_name, mapped_module* map_memory_module(uint64_t base_address, uint64_t image_size, const std::string& module_name, const logger& logger,
const logger& logger, bool is_static = false); bool is_static = false);
mapped_module* find_by_address(const uint64_t address) mapped_module* find_by_address(const uint64_t address)
{ {

View File

@@ -77,8 +77,8 @@ namespace
} }
else else
{ {
sym.name = buffer.as_string( sym.name =
static_cast<size_t>(original_thunk.u1.AddressOfData + offsetof(IMAGE_IMPORT_BY_NAME, Name))); buffer.as_string(static_cast<size_t>(original_thunk.u1.AddressOfData + offsetof(IMAGE_IMPORT_BY_NAME, Name)));
} }
imports.push_back(std::move(sym)); imports.push_back(std::move(sym));
@@ -127,8 +127,7 @@ namespace
template <typename T> template <typename T>
requires(std::is_integral_v<T>) requires(std::is_integral_v<T>)
void apply_relocation(const utils::safe_buffer_accessor<std::byte> buffer, const uint64_t offset, void apply_relocation(const utils::safe_buffer_accessor<std::byte> buffer, const uint64_t offset, const uint64_t delta)
const uint64_t delta)
{ {
const auto obj = buffer.as<T>(static_cast<size_t>(offset)); const auto obj = buffer.as<T>(static_cast<size_t>(offset));
const auto value = obj.get(); const auto value = obj.get();
@@ -198,8 +197,7 @@ namespace
} }
} }
void map_sections(memory_manager& memory, mapped_module& binary, void map_sections(memory_manager& memory, mapped_module& binary, const utils::safe_buffer_accessor<const std::byte> buffer,
const utils::safe_buffer_accessor<const std::byte> buffer,
const PENTHeaders_t<std::uint64_t>& nt_headers, const uint64_t nt_headers_offset) const PENTHeaders_t<std::uint64_t>& nt_headers, const uint64_t nt_headers_offset)
{ {
const auto first_section_offset = get_first_section_offset(nt_headers, nt_headers_offset); const auto first_section_offset = get_first_section_offset(nt_headers, nt_headers_offset);
@@ -253,8 +251,7 @@ namespace
} }
} }
mapped_module map_module_from_data(memory_manager& memory, const std::span<const std::byte> data, mapped_module map_module_from_data(memory_manager& memory, const std::span<const std::byte> data, std::filesystem::path file)
std::filesystem::path file)
{ {
mapped_module binary{}; mapped_module binary{};
binary.path = std::move(file); binary.path = std::move(file);
@@ -283,8 +280,8 @@ mapped_module map_module_from_data(memory_manager& memory, const std::span<const
const auto has_dynamic_base = optional_header.DllCharacteristics & IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE; const auto has_dynamic_base = optional_header.DllCharacteristics & IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE;
const auto is_relocatable = is_dll || has_dynamic_base; const auto is_relocatable = is_dll || has_dynamic_base;
if (!is_relocatable || !memory.allocate_memory(binary.image_base, static_cast<size_t>(binary.size_of_image), if (!is_relocatable ||
memory_permission::all)) !memory.allocate_memory(binary.image_base, static_cast<size_t>(binary.size_of_image), memory_permission::all))
{ {
throw std::runtime_error("Memory range not allocatable"); throw std::runtime_error("Memory range not allocatable");
} }
@@ -323,8 +320,7 @@ mapped_module map_module_from_file(memory_manager& memory, std::filesystem::path
return map_module_from_data(memory, data, std::move(file)); return map_module_from_data(memory, data, std::move(file));
} }
mapped_module map_module_from_memory(memory_manager& memory, uint64_t base_address, uint64_t image_size, mapped_module map_module_from_memory(memory_manager& memory, uint64_t base_address, uint64_t image_size, const std::string& module_name)
const std::string& module_name)
{ {
mapped_module binary{}; mapped_module binary{};
binary.name = module_name; binary.name = module_name;
@@ -353,8 +349,7 @@ mapped_module map_module_from_memory(memory_manager& memory, uint64_t base_addre
mapped_section section_info{}; mapped_section section_info{};
section_info.region.start = binary.image_base + section.VirtualAddress; section_info.region.start = binary.image_base + section.VirtualAddress;
section_info.region.length = section_info.region.length = static_cast<size_t>(page_align_up(std::max(section.SizeOfRawData, section.Misc.VirtualSize)));
static_cast<size_t>(page_align_up(std::max(section.SizeOfRawData, section.Misc.VirtualSize)));
auto permissions = memory_permission::none; auto permissions = memory_permission::none;
if (section.Characteristics & IMAGE_SCN_MEM_EXECUTE) if (section.Characteristics & IMAGE_SCN_MEM_EXECUTE)

View File

@@ -5,7 +5,6 @@
mapped_module map_module_from_data(memory_manager& memory, std::span<const uint8_t> data, std::filesystem::path file); mapped_module map_module_from_data(memory_manager& memory, std::span<const uint8_t> data, std::filesystem::path file);
mapped_module map_module_from_file(memory_manager& memory, std::filesystem::path file); mapped_module map_module_from_file(memory_manager& memory, std::filesystem::path file);
mapped_module map_module_from_memory(memory_manager& memory, uint64_t base_address, uint64_t image_size, mapped_module map_module_from_memory(memory_manager& memory, uint64_t base_address, uint64_t image_size, const std::string& module_name);
const std::string& module_name);
bool unmap_module(memory_manager& memory, const mapped_module& mod); bool unmap_module(memory_manager& memory, const mapped_module& mod);

View File

@@ -37,8 +37,7 @@ namespace network
int val{}; int val{};
socklen_t len = sizeof(val); socklen_t len = sizeof(val);
const auto res = const auto res = getsockopt(this->socket_.get_socket(), SOL_SOCKET, SO_ACCEPTCONN, reinterpret_cast<char*>(&val), &len);
getsockopt(this->socket_.get_socket(), SOL_SOCKET, SO_ACCEPTCONN, reinterpret_cast<char*>(&val), &len);
return res != SOCKET_ERROR && val == 1; return res != SOCKET_ERROR && val == 1;
} }
@@ -92,27 +91,25 @@ namespace network
sent_size socket_wrapper::send(const std::span<const std::byte> data) sent_size socket_wrapper::send(const std::span<const std::byte> data)
{ {
return ::send(this->socket_.get_socket(), reinterpret_cast<const char*>(data.data()), return ::send(this->socket_.get_socket(), reinterpret_cast<const char*>(data.data()), static_cast<send_size>(data.size()), 0);
static_cast<send_size>(data.size()), 0);
} }
sent_size socket_wrapper::sendto(const address& destination, const std::span<const std::byte> data) sent_size socket_wrapper::sendto(const address& destination, const std::span<const std::byte> data)
{ {
return ::sendto(this->socket_.get_socket(), reinterpret_cast<const char*>(data.data()), return ::sendto(this->socket_.get_socket(), reinterpret_cast<const char*>(data.data()), static_cast<send_size>(data.size()), 0,
static_cast<send_size>(data.size()), 0, &destination.get_addr(), destination.get_size()); &destination.get_addr(), destination.get_size());
} }
sent_size socket_wrapper::recv(std::span<std::byte> data) sent_size socket_wrapper::recv(std::span<std::byte> data)
{ {
return ::recv(this->socket_.get_socket(), reinterpret_cast<char*>(data.data()), return ::recv(this->socket_.get_socket(), reinterpret_cast<char*>(data.data()), static_cast<send_size>(data.size()), 0);
static_cast<send_size>(data.size()), 0);
} }
sent_size socket_wrapper::recvfrom(address& source, std::span<std::byte> data) sent_size socket_wrapper::recvfrom(address& source, std::span<std::byte> data)
{ {
auto source_length = source.get_max_size(); auto source_length = source.get_max_size();
const auto res = ::recvfrom(this->socket_.get_socket(), reinterpret_cast<char*>(data.data()), const auto res = ::recvfrom(this->socket_.get_socket(), reinterpret_cast<char*>(data.data()), static_cast<send_size>(data.size()),
static_cast<send_size>(data.size()), 0, &source.get_addr(), &source_length); 0, &source.get_addr(), &source_length);
assert(source.get_size() == source_length); assert(source.get_size() == source_length);

View File

@@ -73,8 +73,7 @@ namespace
utils::unordered_insensitive_u16string_map<std::u16string> env_map; utils::unordered_insensitive_u16string_map<std::u16string> env_map;
std::unordered_set<std::u16string_view> keys_to_expand; std::unordered_set<std::u16string_view> keys_to_expand;
const auto env_key = const auto env_key = registry.get_key({R"(\Registry\Machine\System\CurrentControlSet\Control\Session Manager\Environment)"});
registry.get_key({R"(\Registry\Machine\System\CurrentControlSet\Control\Session Manager\Environment)"});
if (env_key) if (env_key)
{ {
for (size_t i = 0; const auto value_opt = registry.get_value(*env_key, i); i++) for (size_t i = 0; const auto value_opt = registry.get_value(*env_key, i); i++)
@@ -98,8 +97,7 @@ namespace
continue; continue;
} }
const auto [it, inserted] = const auto [it, inserted] = env_map.emplace(u8_to_u16(value.name), std::u16string(data_ptr, char_count - 1));
env_map.emplace(u8_to_u16(value.name), std::u16string(data_ptr, char_count - 1));
if (inserted && value.type == REG_EXPAND_SZ) if (inserted && value.type == REG_EXPAND_SZ)
{ {
keys_to_expand.insert(it->first); keys_to_expand.insert(it->first);
@@ -142,8 +140,8 @@ namespace
} }
void process_context::setup(x86_64_emulator& emu, memory_manager& memory, registry_manager& registry, void process_context::setup(x86_64_emulator& emu, memory_manager& memory, registry_manager& registry,
const application_settings& app_settings, const mapped_module& executable, const application_settings& app_settings, const mapped_module& executable, const mapped_module& ntdll,
const mapped_module& ntdll, const apiset::container& apiset_container) const apiset::container& apiset_container)
{ {
setup_gdt(emu, memory); setup_gdt(emu, memory);
@@ -204,8 +202,7 @@ void process_context::setup(x86_64_emulator& emu, memory_manager& memory, regist
} }
allocator.make_unicode_string(proc_params.CommandLine, command_line); allocator.make_unicode_string(proc_params.CommandLine, command_line);
allocator.make_unicode_string(proc_params.CurrentDirectory.DosPath, allocator.make_unicode_string(proc_params.CurrentDirectory.DosPath, app_settings.working_directory.u16string() + u"\\", 1024);
app_settings.working_directory.u16string() + u"\\", 1024);
allocator.make_unicode_string(proc_params.ImagePathName, application_str); allocator.make_unicode_string(proc_params.ImagePathName, application_str);
const auto total_length = allocator.get_next_address() - this->process_params.value(); const auto total_length = allocator.get_next_address() - this->process_params.value();

View File

@@ -65,12 +65,10 @@ struct process_context
{ {
} }
void setup(x86_64_emulator& emu, memory_manager& memory, registry_manager& registry, void setup(x86_64_emulator& emu, memory_manager& memory, registry_manager& registry, const application_settings& app_settings,
const application_settings& app_settings, const mapped_module& executable, const mapped_module& ntdll, const mapped_module& executable, const mapped_module& ntdll, const apiset::container& apiset_container);
const apiset::container& apiset_container);
handle create_thread(memory_manager& memory, uint64_t start_address, uint64_t argument, uint64_t stack_size, handle create_thread(memory_manager& memory, uint64_t start_address, uint64_t argument, uint64_t stack_size, bool suspended);
bool suspended);
std::optional<uint16_t> find_atom(std::u16string_view name); std::optional<uint16_t> find_atom(std::u16string_view name);
uint16_t add_or_find_atom(std::u16string name); uint16_t add_or_find_atom(std::u16string name);

View File

@@ -228,8 +228,8 @@ void hive_key::parse(std::ifstream& file)
std::string subkey_name(subkey.name, std::min(subkey.len, static_cast<int16_t>(sizeof(subkey.name)))); std::string subkey_name(subkey.name, std::min(subkey.len, static_cast<int16_t>(sizeof(subkey.name))));
const auto [it, inserted] = this->sub_keys_.emplace( const auto [it, inserted] =
std::move(subkey_name), hive_key{subkey.subkeys, subkey.value_count, subkey.offsets}); this->sub_keys_.emplace(std::move(subkey_name), hive_key{subkey.subkeys, subkey.value_count, subkey.offsets});
if (inserted) if (inserted)
{ {
this->sub_keys_by_index_.emplace_back(it->first); this->sub_keys_by_index_.emplace_back(it->first);

View File

@@ -28,8 +28,8 @@ namespace
hives[key] = std::make_unique<hive_parser>(file); hives[key] = std::make_unique<hive_parser>(file);
} }
std::pair<utils::path_key, bool> perform_path_substitution( std::pair<utils::path_key, bool> perform_path_substitution(const std::unordered_map<utils::path_key, utils::path_key>& path_mapping,
const std::unordered_map<utils::path_key, utils::path_key>& path_mapping, utils::path_key path) utils::path_key path)
{ {
for (const auto& mapping : path_mapping) for (const auto& mapping : path_mapping)
{ {

View File

@@ -115,10 +115,8 @@ void syscall_dispatcher::dispatch(windows_emulator& win_emu)
} }
} }
syscall_dispatcher::syscall_dispatcher(const exported_symbols& ntdll_exports, syscall_dispatcher::syscall_dispatcher(const exported_symbols& ntdll_exports, const std::span<const std::byte> ntdll_data,
const std::span<const std::byte> ntdll_data, const exported_symbols& win32u_exports, const std::span<const std::byte> win32u_data)
const exported_symbols& win32u_exports,
const std::span<const std::byte> win32u_data)
{ {
this->setup(ntdll_exports, ntdll_data, win32u_exports, win32u_data); this->setup(ntdll_exports, ntdll_data, win32u_exports, win32u_data);
} }

View File

@@ -17,16 +17,16 @@ class syscall_dispatcher
{ {
public: public:
syscall_dispatcher() = default; syscall_dispatcher() = default;
syscall_dispatcher(const exported_symbols& ntdll_exports, std::span<const std::byte> ntdll_data, syscall_dispatcher(const exported_symbols& ntdll_exports, std::span<const std::byte> ntdll_data, const exported_symbols& win32u_exports,
const exported_symbols& win32u_exports, std::span<const std::byte> win32u_data); std::span<const std::byte> win32u_data);
void dispatch(windows_emulator& win_emu); void dispatch(windows_emulator& win_emu);
void serialize(utils::buffer_serializer& buffer) const; void serialize(utils::buffer_serializer& buffer) const;
void deserialize(utils::buffer_deserializer& buffer); void deserialize(utils::buffer_deserializer& buffer);
void setup(const exported_symbols& ntdll_exports, std::span<const std::byte> ntdll_data, void setup(const exported_symbols& ntdll_exports, std::span<const std::byte> ntdll_data, const exported_symbols& win32u_exports,
const exported_symbols& win32u_exports, std::span<const std::byte> win32u_data); std::span<const std::byte> win32u_data);
std::string get_syscall_name(const uint64_t id) std::string get_syscall_name(const uint64_t id)
{ {

View File

@@ -48,8 +48,7 @@ inline std::optional<uint32_t> extract_syscall_id(const exported_symbol& symbol,
const auto instruction_rva = symbol.rva + instruction_offset; const auto instruction_rva = symbol.rva + instruction_offset;
if (data.size() < (instruction_rva + instruction_size) || if (data.size() < (instruction_rva + instruction_size) || data[static_cast<size_t>(instruction_rva)] != instruction_opcode)
data[static_cast<size_t>(instruction_rva)] != instruction_opcode)
{ {
return std::nullopt; return std::nullopt;
} }
@@ -74,8 +73,8 @@ inline std::map<uint64_t, std::string> find_syscalls(const exported_symbols& exp
if (!entry.empty()) if (!entry.empty())
{ {
throw std::runtime_error("Syscall with id " + std::to_string(*id) + ", which is mapping to " + throw std::runtime_error("Syscall with id " + std::to_string(*id) + ", which is mapping to " + symbol.name +
symbol.name + ", was already mapped to " + entry); ", was already mapped to " + entry);
} }
entry = symbol.name; entry = symbol.name;
@@ -227,8 +226,8 @@ NTSTATUS handle_query_internal(x86_64_emulator& emu, const uint64_t buffer, cons
template <typename ResponseType, typename Action, typename LengthType> template <typename ResponseType, typename Action, typename LengthType>
requires(std::is_integral_v<LengthType>) requires(std::is_integral_v<LengthType>)
NTSTATUS handle_query(x86_64_emulator& emu, const uint64_t buffer, const uint32_t length, NTSTATUS handle_query(x86_64_emulator& emu, const uint64_t buffer, const uint32_t length, const emulator_object<LengthType> return_length,
const emulator_object<LengthType> return_length, const Action& action) const Action& action)
{ {
const auto length_setter = [&](const size_t required_size) { const auto length_setter = [&](const size_t required_size) {
if (return_length) if (return_length)
@@ -242,8 +241,7 @@ NTSTATUS handle_query(x86_64_emulator& emu, const uint64_t buffer, const uint32_
template <typename ResponseType, typename Action> template <typename ResponseType, typename Action>
NTSTATUS handle_query(x86_64_emulator& emu, const uint64_t buffer, const uint32_t length, NTSTATUS handle_query(x86_64_emulator& emu, const uint64_t buffer, const uint32_t length,
const emulator_object<IO_STATUS_BLOCK<EmulatorTraits<Emu64>>> io_status_block, const emulator_object<IO_STATUS_BLOCK<EmulatorTraits<Emu64>>> io_status_block, const Action& action)
const Action& action)
{ {
IO_STATUS_BLOCK<EmulatorTraits<Emu64>> status_block{}; IO_STATUS_BLOCK<EmulatorTraits<Emu64>> status_block{};

View File

@@ -18,104 +18,85 @@ namespace syscalls
NTSTATUS handle_NtTraceEvent(); NTSTATUS handle_NtTraceEvent();
NTSTATUS handle_NtQueryEvent(); NTSTATUS handle_NtQueryEvent();
NTSTATUS handle_NtClearEvent(const syscall_context& c, handle event_handle); NTSTATUS handle_NtClearEvent(const syscall_context& c, handle event_handle);
NTSTATUS handle_NtCreateEvent(const syscall_context& c, emulator_object<handle> event_handle, NTSTATUS handle_NtCreateEvent(const syscall_context& c, emulator_object<handle> event_handle, ACCESS_MASK desired_access,
ACCESS_MASK desired_access, emulator_object<OBJECT_ATTRIBUTES<EmulatorTraits<Emu64>>> object_attributes, EVENT_TYPE event_type,
emulator_object<OBJECT_ATTRIBUTES<EmulatorTraits<Emu64>>> object_attributes, BOOLEAN initial_state);
EVENT_TYPE event_type, BOOLEAN initial_state); NTSTATUS handle_NtOpenEvent(const syscall_context& c, emulator_object<uint64_t> event_handle, ACCESS_MASK desired_access,
NTSTATUS handle_NtOpenEvent(const syscall_context& c, emulator_object<uint64_t> event_handle,
ACCESS_MASK desired_access,
emulator_object<OBJECT_ATTRIBUTES<EmulatorTraits<Emu64>>> object_attributes); emulator_object<OBJECT_ATTRIBUTES<EmulatorTraits<Emu64>>> object_attributes);
// syscalls/exception.cpp // syscalls/exception.cpp
NTSTATUS handle_NtRaiseHardError( NTSTATUS handle_NtRaiseHardError(const syscall_context& c, NTSTATUS error_status, ULONG number_of_parameters,
const syscall_context& c, NTSTATUS error_status, ULONG number_of_parameters, emulator_object<UNICODE_STRING<EmulatorTraits<Emu64>>> unicode_string_parameter_mask,
emulator_object<UNICODE_STRING<EmulatorTraits<Emu64>>> unicode_string_parameter_mask, emulator_object<DWORD> parameters, HARDERROR_RESPONSE_OPTION valid_response_option,
emulator_object<DWORD> parameters, HARDERROR_RESPONSE_OPTION valid_response_option, emulator_object<HARDERROR_RESPONSE> response);
emulator_object<HARDERROR_RESPONSE> response);
NTSTATUS handle_NtRaiseException(const syscall_context& c, NTSTATUS handle_NtRaiseException(const syscall_context& c,
emulator_object<EMU_EXCEPTION_RECORD<EmulatorTraits<Emu64>>> exception_record, emulator_object<EMU_EXCEPTION_RECORD<EmulatorTraits<Emu64>>> exception_record,
emulator_object<CONTEXT64> thread_context, BOOLEAN handle_exception); emulator_object<CONTEXT64> thread_context, BOOLEAN handle_exception);
// syscalls/file.cpp // syscalls/file.cpp
NTSTATUS handle_NtSetInformationFile(const syscall_context& c, handle file_handle, NTSTATUS handle_NtSetInformationFile(const syscall_context& c, handle file_handle,
emulator_object<IO_STATUS_BLOCK<EmulatorTraits<Emu64>>> io_status_block, emulator_object<IO_STATUS_BLOCK<EmulatorTraits<Emu64>>> io_status_block, uint64_t file_information,
uint64_t file_information, ULONG length, FILE_INFORMATION_CLASS info_class); ULONG length, FILE_INFORMATION_CLASS info_class);
NTSTATUS handle_NtQueryVolumeInformationFile( NTSTATUS handle_NtQueryVolumeInformationFile(const syscall_context& c, handle file_handle,
const syscall_context& c, handle file_handle, emulator_object<IO_STATUS_BLOCK<EmulatorTraits<Emu64>>> io_status_block,
emulator_object<IO_STATUS_BLOCK<EmulatorTraits<Emu64>>> io_status_block, uint64_t fs_information, ULONG length, uint64_t fs_information, ULONG length, FS_INFORMATION_CLASS fs_information_class);
FS_INFORMATION_CLASS fs_information_class);
NTSTATUS handle_NtQueryDirectoryFileEx(const syscall_context& c, handle file_handle, handle event_handle, NTSTATUS handle_NtQueryDirectoryFileEx(const syscall_context& c, handle file_handle, handle event_handle,
EMULATOR_CAST(emulator_pointer, PIO_APC_ROUTINE) apc_routine, EMULATOR_CAST(emulator_pointer, PIO_APC_ROUTINE) apc_routine, emulator_pointer apc_context,
emulator_pointer apc_context,
emulator_object<IO_STATUS_BLOCK<EmulatorTraits<Emu64>>> io_status_block, emulator_object<IO_STATUS_BLOCK<EmulatorTraits<Emu64>>> io_status_block,
uint64_t file_information, uint32_t length, uint32_t info_class, uint64_t file_information, uint32_t length, uint32_t info_class, ULONG query_flags,
ULONG query_flags,
emulator_object<UNICODE_STRING<EmulatorTraits<Emu64>>> file_name); emulator_object<UNICODE_STRING<EmulatorTraits<Emu64>>> file_name);
NTSTATUS handle_NtQueryDirectoryFile(const syscall_context& c, handle file_handle, handle event_handle, NTSTATUS handle_NtQueryDirectoryFile(const syscall_context& c, handle file_handle, handle event_handle,
EMULATOR_CAST(emulator_pointer, PIO_APC_ROUTINE) apc_routine, EMULATOR_CAST(emulator_pointer, PIO_APC_ROUTINE) apc_routine, emulator_pointer apc_context,
emulator_pointer apc_context, emulator_object<IO_STATUS_BLOCK<EmulatorTraits<Emu64>>> io_status_block, uint64_t file_information,
emulator_object<IO_STATUS_BLOCK<EmulatorTraits<Emu64>>> io_status_block, uint32_t length, uint32_t info_class, BOOLEAN return_single_entry,
uint64_t file_information, uint32_t length, uint32_t info_class, emulator_object<UNICODE_STRING<EmulatorTraits<Emu64>>> file_name, BOOLEAN restart_scan);
BOOLEAN return_single_entry,
emulator_object<UNICODE_STRING<EmulatorTraits<Emu64>>> file_name,
BOOLEAN restart_scan);
NTSTATUS handle_NtQueryInformationFile(const syscall_context& c, handle file_handle, NTSTATUS handle_NtQueryInformationFile(const syscall_context& c, handle file_handle,
emulator_object<IO_STATUS_BLOCK<EmulatorTraits<Emu64>>> io_status_block, emulator_object<IO_STATUS_BLOCK<EmulatorTraits<Emu64>>> io_status_block,
uint64_t file_information, uint32_t length, uint32_t info_class); uint64_t file_information, uint32_t length, uint32_t info_class);
NTSTATUS handle_NtQueryInformationByName( NTSTATUS handle_NtQueryInformationByName(const syscall_context& c,
const syscall_context& c, emulator_object<OBJECT_ATTRIBUTES<EmulatorTraits<Emu64>>> object_attributes, emulator_object<OBJECT_ATTRIBUTES<EmulatorTraits<Emu64>>> object_attributes,
emulator_object<IO_STATUS_BLOCK<EmulatorTraits<Emu64>>> io_status_block, uint64_t file_information, emulator_object<IO_STATUS_BLOCK<EmulatorTraits<Emu64>>> io_status_block,
uint32_t length, uint32_t info_class); uint64_t file_information, uint32_t length, uint32_t info_class);
NTSTATUS handle_NtReadFile(const syscall_context& c, handle file_handle, uint64_t /*event*/, NTSTATUS handle_NtReadFile(const syscall_context& c, handle file_handle, uint64_t /*event*/, uint64_t /*apc_routine*/,
uint64_t /*apc_routine*/, uint64_t /*apc_context*/, uint64_t /*apc_context*/, emulator_object<IO_STATUS_BLOCK<EmulatorTraits<Emu64>>> io_status_block,
emulator_object<IO_STATUS_BLOCK<EmulatorTraits<Emu64>>> io_status_block, uint64_t buffer, uint64_t buffer, ULONG length, emulator_object<LARGE_INTEGER> /*byte_offset*/,
ULONG length, emulator_object<LARGE_INTEGER> /*byte_offset*/,
emulator_object<ULONG> /*key*/); emulator_object<ULONG> /*key*/);
NTSTATUS handle_NtWriteFile(const syscall_context& c, handle file_handle, uint64_t /*event*/, NTSTATUS handle_NtWriteFile(const syscall_context& c, handle file_handle, uint64_t /*event*/, uint64_t /*apc_routine*/,
uint64_t /*apc_routine*/, uint64_t /*apc_context*/, uint64_t /*apc_context*/, emulator_object<IO_STATUS_BLOCK<EmulatorTraits<Emu64>>> io_status_block,
emulator_object<IO_STATUS_BLOCK<EmulatorTraits<Emu64>>> io_status_block,
uint64_t buffer, ULONG length, emulator_object<LARGE_INTEGER> /*byte_offset*/, uint64_t buffer, ULONG length, emulator_object<LARGE_INTEGER> /*byte_offset*/,
emulator_object<ULONG> /*key*/); emulator_object<ULONG> /*key*/);
NTSTATUS handle_NtCreateFile(const syscall_context& c, emulator_object<handle> file_handle, NTSTATUS handle_NtCreateFile(const syscall_context& c, emulator_object<handle> file_handle, ACCESS_MASK desired_access,
ACCESS_MASK desired_access,
emulator_object<OBJECT_ATTRIBUTES<EmulatorTraits<Emu64>>> object_attributes, emulator_object<OBJECT_ATTRIBUTES<EmulatorTraits<Emu64>>> object_attributes,
emulator_object<IO_STATUS_BLOCK<EmulatorTraits<Emu64>>> /*io_status_block*/, emulator_object<IO_STATUS_BLOCK<EmulatorTraits<Emu64>>> /*io_status_block*/,
emulator_object<LARGE_INTEGER> /*allocation_size*/, ULONG /*file_attributes*/, emulator_object<LARGE_INTEGER> /*allocation_size*/, ULONG /*file_attributes*/, ULONG /*share_access*/,
ULONG /*share_access*/, ULONG create_disposition, ULONG create_options, ULONG create_disposition, ULONG create_options, uint64_t ea_buffer, ULONG ea_length);
uint64_t ea_buffer, ULONG ea_length);
NTSTATUS handle_NtQueryAttributesFile(const syscall_context& c, NTSTATUS handle_NtQueryAttributesFile(const syscall_context& c,
emulator_object<OBJECT_ATTRIBUTES<EmulatorTraits<Emu64>>> object_attributes, emulator_object<OBJECT_ATTRIBUTES<EmulatorTraits<Emu64>>> object_attributes,
emulator_object<FILE_BASIC_INFORMATION> file_information); emulator_object<FILE_BASIC_INFORMATION> file_information);
NTSTATUS handle_NtQueryFullAttributesFile( NTSTATUS handle_NtQueryFullAttributesFile(const syscall_context& c,
const syscall_context& c, emulator_object<OBJECT_ATTRIBUTES<EmulatorTraits<Emu64>>> object_attributes, emulator_object<OBJECT_ATTRIBUTES<EmulatorTraits<Emu64>>> object_attributes,
emulator_object<FILE_NETWORK_OPEN_INFORMATION> file_information); emulator_object<FILE_NETWORK_OPEN_INFORMATION> file_information);
NTSTATUS handle_NtOpenFile(const syscall_context& c, emulator_object<handle> file_handle, NTSTATUS handle_NtOpenFile(const syscall_context& c, emulator_object<handle> file_handle, ACCESS_MASK desired_access,
ACCESS_MASK desired_access,
emulator_object<OBJECT_ATTRIBUTES<EmulatorTraits<Emu64>>> object_attributes, emulator_object<OBJECT_ATTRIBUTES<EmulatorTraits<Emu64>>> object_attributes,
emulator_object<IO_STATUS_BLOCK<EmulatorTraits<Emu64>>> io_status_block, emulator_object<IO_STATUS_BLOCK<EmulatorTraits<Emu64>>> io_status_block, ULONG share_access,
ULONG share_access, ULONG open_options); ULONG open_options);
NTSTATUS handle_NtOpenDirectoryObject(const syscall_context& c, emulator_object<handle> directory_handle, NTSTATUS handle_NtOpenDirectoryObject(const syscall_context& c, emulator_object<handle> directory_handle,
ACCESS_MASK /*desired_access*/, ACCESS_MASK /*desired_access*/,
emulator_object<OBJECT_ATTRIBUTES<EmulatorTraits<Emu64>>> object_attributes); emulator_object<OBJECT_ATTRIBUTES<EmulatorTraits<Emu64>>> object_attributes);
NTSTATUS handle_NtOpenSymbolicLinkObject( NTSTATUS handle_NtOpenSymbolicLinkObject(const syscall_context& c, emulator_object<handle> link_handle, ACCESS_MASK /*desired_access*/,
const syscall_context& c, emulator_object<handle> link_handle, ACCESS_MASK /*desired_access*/, emulator_object<OBJECT_ATTRIBUTES<EmulatorTraits<Emu64>>> object_attributes);
emulator_object<OBJECT_ATTRIBUTES<EmulatorTraits<Emu64>>> object_attributes);
NTSTATUS handle_NtQuerySymbolicLinkObject(const syscall_context& c, handle link_handle, NTSTATUS handle_NtQuerySymbolicLinkObject(const syscall_context& c, handle link_handle,
emulator_object<UNICODE_STRING<EmulatorTraits<Emu64>>> link_target, emulator_object<UNICODE_STRING<EmulatorTraits<Emu64>>> link_target,
emulator_object<ULONG> returned_length); emulator_object<ULONG> returned_length);
NTSTATUS handle_NtCreateNamedPipeFile(const syscall_context& c, emulator_object<handle> file_handle, NTSTATUS handle_NtCreateNamedPipeFile(const syscall_context& c, emulator_object<handle> file_handle, ULONG desired_access,
ULONG desired_access,
emulator_object<OBJECT_ATTRIBUTES<EmulatorTraits<Emu64>>> object_attributes, emulator_object<OBJECT_ATTRIBUTES<EmulatorTraits<Emu64>>> object_attributes,
emulator_object<IO_STATUS_BLOCK<EmulatorTraits<Emu64>>> io_status_block, emulator_object<IO_STATUS_BLOCK<EmulatorTraits<Emu64>>> io_status_block, ULONG share_access,
ULONG share_access, ULONG create_disposition, ULONG create_options, ULONG create_disposition, ULONG create_options, ULONG named_pipe_type, ULONG read_mode,
ULONG named_pipe_type, ULONG read_mode, ULONG completion_mode, ULONG completion_mode, ULONG maximum_instances, ULONG inbound_quota, ULONG outbound_quota,
ULONG maximum_instances, ULONG inbound_quota, ULONG outbound_quota,
emulator_object<LARGE_INTEGER> default_timeout); emulator_object<LARGE_INTEGER> default_timeout);
NTSTATUS handle_NtFsControlFile(const syscall_context& c, handle event_handle, uint64_t apc_routine, NTSTATUS handle_NtFsControlFile(const syscall_context& c, handle event_handle, uint64_t apc_routine, uint64_t app_context,
uint64_t app_context, emulator_object<IO_STATUS_BLOCK<EmulatorTraits<Emu64>>> io_status_block, ULONG fs_control_code,
emulator_object<IO_STATUS_BLOCK<EmulatorTraits<Emu64>>> io_status_block, uint64_t input_buffer, ULONG input_buffer_length, uint64_t output_buffer, ULONG output_buffer_length);
ULONG fs_control_code, uint64_t input_buffer, ULONG input_buffer_length,
uint64_t output_buffer, ULONG output_buffer_length);
NTSTATUS handle_NtFlushBuffersFile(const syscall_context& c, handle file_handle, NTSTATUS handle_NtFlushBuffersFile(const syscall_context& c, handle file_handle,
emulator_object<IO_STATUS_BLOCK<EmulatorTraits<Emu64>>> /*io_status_block*/); emulator_object<IO_STATUS_BLOCK<EmulatorTraits<Emu64>>> /*io_status_block*/);
@@ -123,11 +104,9 @@ namespace syscalls
NTSTATUS handle_NtInitializeNlsFiles(const syscall_context& c, emulator_object<uint64_t> base_address, NTSTATUS handle_NtInitializeNlsFiles(const syscall_context& c, emulator_object<uint64_t> base_address,
emulator_object<LCID> default_locale_id, emulator_object<LCID> default_locale_id,
emulator_object<LARGE_INTEGER> /*default_casing_table_size*/); emulator_object<LARGE_INTEGER> /*default_casing_table_size*/);
NTSTATUS handle_NtQueryDefaultLocale(const syscall_context&, BOOLEAN /*user_profile*/, NTSTATUS handle_NtQueryDefaultLocale(const syscall_context&, BOOLEAN /*user_profile*/, emulator_object<LCID> default_locale_id);
emulator_object<LCID> default_locale_id); NTSTATUS handle_NtGetNlsSectionPtr(const syscall_context& c, ULONG section_type, ULONG section_data, emulator_pointer /*context_data*/,
NTSTATUS handle_NtGetNlsSectionPtr(const syscall_context& c, ULONG section_type, ULONG section_data, emulator_object<uint64_t> section_pointer, emulator_object<ULONG> section_size);
emulator_pointer /*context_data*/, emulator_object<uint64_t> section_pointer,
emulator_object<ULONG> section_size);
NTSTATUS handle_NtGetMUIRegistryInfo(); NTSTATUS handle_NtGetMUIRegistryInfo();
NTSTATUS handle_NtIsUILanguageComitted(); NTSTATUS handle_NtIsUILanguageComitted();
NTSTATUS handle_NtUserGetKeyboardLayout(); NTSTATUS handle_NtUserGetKeyboardLayout();
@@ -135,23 +114,19 @@ namespace syscalls
NTSTATUS handle_NtQueryInstallUILanguage(const syscall_context&, emulator_object<LANGID> language_id); NTSTATUS handle_NtQueryInstallUILanguage(const syscall_context&, emulator_object<LANGID> language_id);
// syscalls/memory.cpp: // syscalls/memory.cpp:
NTSTATUS handle_NtQueryVirtualMemory(const syscall_context& c, handle process_handle, uint64_t base_address, NTSTATUS handle_NtQueryVirtualMemory(const syscall_context& c, handle process_handle, uint64_t base_address, uint32_t info_class,
uint32_t info_class, uint64_t memory_information, uint64_t memory_information, uint64_t memory_information_length,
uint64_t memory_information_length, emulator_object<uint64_t> return_length); emulator_object<uint64_t> return_length);
NTSTATUS handle_NtProtectVirtualMemory(const syscall_context& c, handle process_handle, NTSTATUS handle_NtProtectVirtualMemory(const syscall_context& c, handle process_handle, emulator_object<uint64_t> base_address,
emulator_object<uint64_t> base_address,
emulator_object<uint32_t> bytes_to_protect, uint32_t protection, emulator_object<uint32_t> bytes_to_protect, uint32_t protection,
emulator_object<uint32_t> old_protection); emulator_object<uint32_t> old_protection);
NTSTATUS handle_NtAllocateVirtualMemoryEx(const syscall_context& c, handle process_handle, NTSTATUS handle_NtAllocateVirtualMemoryEx(const syscall_context& c, handle process_handle, emulator_object<uint64_t> base_address,
emulator_object<uint64_t> base_address,
emulator_object<uint64_t> bytes_to_allocate, uint32_t allocation_type, emulator_object<uint64_t> bytes_to_allocate, uint32_t allocation_type,
uint32_t page_protection); uint32_t page_protection);
NTSTATUS handle_NtAllocateVirtualMemory(const syscall_context& c, handle process_handle, NTSTATUS handle_NtAllocateVirtualMemory(const syscall_context& c, handle process_handle, emulator_object<uint64_t> base_address,
emulator_object<uint64_t> base_address, uint64_t zero_bits, uint64_t zero_bits, emulator_object<uint64_t> bytes_to_allocate, uint32_t allocation_type,
emulator_object<uint64_t> bytes_to_allocate, uint32_t allocation_type,
uint32_t page_protection); uint32_t page_protection);
NTSTATUS handle_NtFreeVirtualMemory(const syscall_context& c, handle process_handle, NTSTATUS handle_NtFreeVirtualMemory(const syscall_context& c, handle process_handle, emulator_object<uint64_t> base_address,
emulator_object<uint64_t> base_address,
emulator_object<uint64_t> bytes_to_allocate, uint32_t free_type); emulator_object<uint64_t> bytes_to_allocate, uint32_t free_type);
NTSTATUS handle_NtReadVirtualMemory(const syscall_context& c, handle process_handle, emulator_pointer base_address, NTSTATUS handle_NtReadVirtualMemory(const syscall_context& c, handle process_handle, emulator_pointer base_address,
emulator_pointer buffer, ULONG number_of_bytes_to_read, emulator_pointer buffer, ULONG number_of_bytes_to_read,
@@ -159,35 +134,26 @@ namespace syscalls
NTSTATUS handle_NtSetInformationVirtualMemory(); NTSTATUS handle_NtSetInformationVirtualMemory();
// syscalls/mutant.cpp: // syscalls/mutant.cpp:
NTSTATUS handle_NtReleaseMutant(const syscall_context& c, handle mutant_handle, NTSTATUS handle_NtReleaseMutant(const syscall_context& c, handle mutant_handle, emulator_object<LONG> previous_count);
emulator_object<LONG> previous_count); NTSTATUS handle_NtOpenMutant(const syscall_context& c, emulator_object<handle> mutant_handle, ACCESS_MASK desired_access,
NTSTATUS handle_NtOpenMutant(const syscall_context& c, emulator_object<handle> mutant_handle,
ACCESS_MASK desired_access,
emulator_object<OBJECT_ATTRIBUTES<EmulatorTraits<Emu64>>> object_attributes); emulator_object<OBJECT_ATTRIBUTES<EmulatorTraits<Emu64>>> object_attributes);
NTSTATUS handle_NtCreateMutant(const syscall_context& c, emulator_object<handle> mutant_handle, NTSTATUS handle_NtCreateMutant(const syscall_context& c, emulator_object<handle> mutant_handle, ACCESS_MASK desired_access,
ACCESS_MASK desired_access, emulator_object<OBJECT_ATTRIBUTES<EmulatorTraits<Emu64>>> object_attributes, BOOLEAN initial_owner);
emulator_object<OBJECT_ATTRIBUTES<EmulatorTraits<Emu64>>> object_attributes,
BOOLEAN initial_owner);
// syscalls/object.cpp: // syscalls/object.cpp:
NTSTATUS handle_NtClose(const syscall_context& c, handle h); NTSTATUS handle_NtClose(const syscall_context& c, handle h);
NTSTATUS handle_NtDuplicateObject(const syscall_context& c, handle source_process_handle, handle source_handle, NTSTATUS handle_NtDuplicateObject(const syscall_context& c, handle source_process_handle, handle source_handle,
handle target_process_handle, emulator_object<handle> target_handle, handle target_process_handle, emulator_object<handle> target_handle, ACCESS_MASK desired_access,
ACCESS_MASK desired_access, ULONG handle_attributes, ULONG options); ULONG handle_attributes, ULONG options);
NTSTATUS handle_NtQueryObject(const syscall_context& c, handle handle, NTSTATUS handle_NtQueryObject(const syscall_context& c, handle handle, OBJECT_INFORMATION_CLASS object_information_class,
OBJECT_INFORMATION_CLASS object_information_class,
emulator_pointer object_information, ULONG object_information_length, emulator_pointer object_information, ULONG object_information_length,
emulator_object<ULONG> return_length); emulator_object<ULONG> return_length);
NTSTATUS handle_NtWaitForMultipleObjects(const syscall_context& c, ULONG count, emulator_object<handle> handles, NTSTATUS handle_NtWaitForMultipleObjects(const syscall_context& c, ULONG count, emulator_object<handle> handles, WAIT_TYPE wait_type,
WAIT_TYPE wait_type, BOOLEAN alertable, BOOLEAN alertable, emulator_object<LARGE_INTEGER> timeout);
emulator_object<LARGE_INTEGER> timeout); NTSTATUS handle_NtWaitForSingleObject(const syscall_context& c, handle h, BOOLEAN alertable, emulator_object<LARGE_INTEGER> timeout);
NTSTATUS handle_NtWaitForSingleObject(const syscall_context& c, handle h, BOOLEAN alertable,
emulator_object<LARGE_INTEGER> timeout);
NTSTATUS handle_NtSetInformationObject(); NTSTATUS handle_NtSetInformationObject();
NTSTATUS handle_NtQuerySecurityObject(const syscall_context& c, handle /*h*/, NTSTATUS handle_NtQuerySecurityObject(const syscall_context& c, handle /*h*/, SECURITY_INFORMATION /*security_information*/,
SECURITY_INFORMATION /*security_information*/, emulator_pointer security_descriptor, ULONG length, emulator_object<ULONG> length_needed);
emulator_pointer security_descriptor, ULONG length,
emulator_object<ULONG> length_needed);
// syscalls/port.cpp: // syscalls/port.cpp:
NTSTATUS handle_NtConnectPort(const syscall_context& c, emulator_object<handle> client_port_handle, NTSTATUS handle_NtConnectPort(const syscall_context& c, emulator_object<handle> client_port_handle,
@@ -200,8 +166,7 @@ namespace syscalls
NTSTATUS handle_NtSecureConnectPort(const syscall_context& c, emulator_object<handle> client_port_handle, NTSTATUS handle_NtSecureConnectPort(const syscall_context& c, emulator_object<handle> client_port_handle,
emulator_object<UNICODE_STRING<EmulatorTraits<Emu64>>> server_port_name, emulator_object<UNICODE_STRING<EmulatorTraits<Emu64>>> server_port_name,
emulator_object<SECURITY_QUALITY_OF_SERVICE> security_qos, emulator_object<SECURITY_QUALITY_OF_SERVICE> security_qos,
emulator_object<PORT_VIEW64> client_shared_memory, emulator_object<PORT_VIEW64> client_shared_memory, emulator_pointer /*server_sid*/,
emulator_pointer /*server_sid*/,
emulator_object<REMOTE_PORT_VIEW64> server_shared_memory, emulator_object<REMOTE_PORT_VIEW64> server_shared_memory,
emulator_object<ULONG> maximum_message_length, emulator_pointer connection_info, emulator_object<ULONG> maximum_message_length, emulator_pointer connection_info,
emulator_object<ULONG> connection_info_length); emulator_object<ULONG> connection_info_length);
@@ -230,42 +195,34 @@ namespace syscalls
NTSTATUS handle_NtTerminateProcess(const syscall_context& c, handle process_handle, NTSTATUS exit_status); NTSTATUS handle_NtTerminateProcess(const syscall_context& c, handle process_handle, NTSTATUS exit_status);
// syscalls/registry.cpp: // syscalls/registry.cpp:
NTSTATUS handle_NtOpenKey(const syscall_context& c, emulator_object<handle> key_handle, NTSTATUS handle_NtOpenKey(const syscall_context& c, emulator_object<handle> key_handle, ACCESS_MASK /*desired_access*/,
ACCESS_MASK /*desired_access*/,
emulator_object<OBJECT_ATTRIBUTES<EmulatorTraits<Emu64>>> object_attributes); emulator_object<OBJECT_ATTRIBUTES<EmulatorTraits<Emu64>>> object_attributes);
NTSTATUS handle_NtOpenKeyEx(const syscall_context& c, emulator_object<handle> key_handle, NTSTATUS handle_NtOpenKeyEx(const syscall_context& c, emulator_object<handle> key_handle, ACCESS_MASK desired_access,
ACCESS_MASK desired_access, emulator_object<OBJECT_ATTRIBUTES<EmulatorTraits<Emu64>>> object_attributes, ULONG /*open_options*/);
emulator_object<OBJECT_ATTRIBUTES<EmulatorTraits<Emu64>>> object_attributes,
ULONG /*open_options*/);
NTSTATUS handle_NtQueryKey(const syscall_context& c, handle key_handle, KEY_INFORMATION_CLASS key_information_class, NTSTATUS handle_NtQueryKey(const syscall_context& c, handle key_handle, KEY_INFORMATION_CLASS key_information_class,
uint64_t key_information, ULONG length, emulator_object<ULONG> result_length); uint64_t key_information, ULONG length, emulator_object<ULONG> result_length);
NTSTATUS handle_NtQueryValueKey(const syscall_context& c, handle key_handle, NTSTATUS handle_NtQueryValueKey(const syscall_context& c, handle key_handle,
emulator_object<UNICODE_STRING<EmulatorTraits<Emu64>>> value_name, emulator_object<UNICODE_STRING<EmulatorTraits<Emu64>>> value_name,
KEY_VALUE_INFORMATION_CLASS key_value_information_class, KEY_VALUE_INFORMATION_CLASS key_value_information_class, uint64_t key_value_information, ULONG length,
uint64_t key_value_information, ULONG length, emulator_object<ULONG> result_length); emulator_object<ULONG> result_length);
NTSTATUS handle_NtCreateKey(const syscall_context& c, emulator_object<handle> key_handle, NTSTATUS handle_NtCreateKey(const syscall_context& c, emulator_object<handle> key_handle, ACCESS_MASK desired_access,
ACCESS_MASK desired_access, emulator_object<OBJECT_ATTRIBUTES<EmulatorTraits<Emu64>>> object_attributes, ULONG /*title_index*/,
emulator_object<OBJECT_ATTRIBUTES<EmulatorTraits<Emu64>>> object_attributes, emulator_object<UNICODE_STRING<EmulatorTraits<Emu64>>> /*class*/, ULONG /*create_options*/,
ULONG /*title_index*/, emulator_object<UNICODE_STRING<EmulatorTraits<Emu64>>> /*class*/, emulator_object<ULONG> /*disposition*/);
ULONG /*create_options*/, emulator_object<ULONG> /*disposition*/);
NTSTATUS handle_NtNotifyChangeKey(); NTSTATUS handle_NtNotifyChangeKey();
NTSTATUS handle_NtSetInformationKey(); NTSTATUS handle_NtSetInformationKey();
NTSTATUS handle_NtEnumerateKey(const syscall_context& c, handle key_handle, ULONG index, NTSTATUS handle_NtEnumerateKey(const syscall_context& c, handle key_handle, ULONG index, KEY_INFORMATION_CLASS key_information_class,
KEY_INFORMATION_CLASS key_information_class, uint64_t key_information, ULONG length, uint64_t key_information, ULONG length, emulator_object<ULONG> result_length);
emulator_object<ULONG> result_length);
NTSTATUS handle_NtEnumerateValueKey(const syscall_context& c, handle key_handle, ULONG index, NTSTATUS handle_NtEnumerateValueKey(const syscall_context& c, handle key_handle, ULONG index,
KEY_VALUE_INFORMATION_CLASS key_value_information_class, KEY_VALUE_INFORMATION_CLASS key_value_information_class, uint64_t key_value_information,
uint64_t key_value_information, ULONG length, ULONG length, emulator_object<ULONG> result_length);
emulator_object<ULONG> result_length);
// syscalls/section.cpp: // syscalls/section.cpp:
NTSTATUS handle_NtCreateSection(const syscall_context& c, emulator_object<handle> section_handle, NTSTATUS handle_NtCreateSection(const syscall_context& c, emulator_object<handle> section_handle, ACCESS_MASK /*desired_access*/,
ACCESS_MASK /*desired_access*/,
emulator_object<OBJECT_ATTRIBUTES<EmulatorTraits<Emu64>>> object_attributes, emulator_object<OBJECT_ATTRIBUTES<EmulatorTraits<Emu64>>> object_attributes,
emulator_object<ULARGE_INTEGER> maximum_size, ULONG section_page_protection, emulator_object<ULARGE_INTEGER> maximum_size, ULONG section_page_protection,
ULONG allocation_attributes, handle file_handle); ULONG allocation_attributes, handle file_handle);
NTSTATUS handle_NtOpenSection(const syscall_context& c, emulator_object<handle> section_handle, NTSTATUS handle_NtOpenSection(const syscall_context& c, emulator_object<handle> section_handle, ACCESS_MASK /*desired_access*/,
ACCESS_MASK /*desired_access*/,
emulator_object<OBJECT_ATTRIBUTES<EmulatorTraits<Emu64>>> object_attributes); emulator_object<OBJECT_ATTRIBUTES<EmulatorTraits<Emu64>>> object_attributes);
NTSTATUS handle_NtMapViewOfSection(const syscall_context& c, handle section_handle, handle process_handle, NTSTATUS handle_NtMapViewOfSection(const syscall_context& c, handle section_handle, handle process_handle,
emulator_object<uint64_t> base_address, emulator_object<uint64_t> base_address,
@@ -273,32 +230,26 @@ namespace syscalls
EMULATOR_CAST(EmulatorTraits<Emu64>::SIZE_T, SIZE_T) /*commit_size*/, EMULATOR_CAST(EmulatorTraits<Emu64>::SIZE_T, SIZE_T) /*commit_size*/,
emulator_object<LARGE_INTEGER> /*section_offset*/, emulator_object<LARGE_INTEGER> /*section_offset*/,
emulator_object<EMULATOR_CAST(EmulatorTraits<Emu64>::SIZE_T, SIZE_T)> view_size, emulator_object<EMULATOR_CAST(EmulatorTraits<Emu64>::SIZE_T, SIZE_T)> view_size,
SECTION_INHERIT /*inherit_disposition*/, ULONG /*allocation_type*/, SECTION_INHERIT /*inherit_disposition*/, ULONG /*allocation_type*/, ULONG /*win32_protect*/);
ULONG /*win32_protect*/);
NTSTATUS handle_NtUnmapViewOfSection(const syscall_context& c, handle process_handle, uint64_t base_address); NTSTATUS handle_NtUnmapViewOfSection(const syscall_context& c, handle process_handle, uint64_t base_address);
NTSTATUS handle_NtUnmapViewOfSectionEx(const syscall_context& c, handle process_handle, uint64_t base_address, NTSTATUS handle_NtUnmapViewOfSectionEx(const syscall_context& c, handle process_handle, uint64_t base_address, ULONG /*flags*/);
ULONG /*flags*/);
NTSTATUS handle_NtAreMappedFilesTheSame(); NTSTATUS handle_NtAreMappedFilesTheSame();
// syscalls/semaphore.cpp: // syscalls/semaphore.cpp:
NTSTATUS handle_NtOpenSemaphore(const syscall_context& c, emulator_object<handle> semaphore_handle, NTSTATUS handle_NtOpenSemaphore(const syscall_context& c, emulator_object<handle> semaphore_handle, ACCESS_MASK /*desired_access*/,
ACCESS_MASK /*desired_access*/,
emulator_object<OBJECT_ATTRIBUTES<EmulatorTraits<Emu64>>> object_attributes); emulator_object<OBJECT_ATTRIBUTES<EmulatorTraits<Emu64>>> object_attributes);
NTSTATUS handle_NtReleaseSemaphore(const syscall_context& c, handle semaphore_handle, ULONG release_count, NTSTATUS handle_NtReleaseSemaphore(const syscall_context& c, handle semaphore_handle, ULONG release_count,
emulator_object<LONG> previous_count); emulator_object<LONG> previous_count);
NTSTATUS handle_NtCreateSemaphore(const syscall_context& c, emulator_object<handle> semaphore_handle, NTSTATUS handle_NtCreateSemaphore(const syscall_context& c, emulator_object<handle> semaphore_handle, ACCESS_MASK /*desired_access*/,
ACCESS_MASK /*desired_access*/, emulator_object<OBJECT_ATTRIBUTES<EmulatorTraits<Emu64>>> object_attributes, ULONG initial_count,
emulator_object<OBJECT_ATTRIBUTES<EmulatorTraits<Emu64>>> object_attributes, ULONG maximum_count);
ULONG initial_count, ULONG maximum_count);
// syscalls/system.cpp: // syscalls/system.cpp:
NTSTATUS handle_NtQuerySystemInformation(const syscall_context& c, uint32_t info_class, uint64_t system_information, NTSTATUS handle_NtQuerySystemInformation(const syscall_context& c, uint32_t info_class, uint64_t system_information,
uint32_t system_information_length, uint32_t system_information_length, emulator_object<uint32_t> return_length);
emulator_object<uint32_t> return_length);
NTSTATUS handle_NtQuerySystemInformationEx(const syscall_context& c, uint32_t info_class, uint64_t input_buffer, NTSTATUS handle_NtQuerySystemInformationEx(const syscall_context& c, uint32_t info_class, uint64_t input_buffer,
uint32_t input_buffer_length, uint64_t system_information, uint32_t input_buffer_length, uint64_t system_information,
uint32_t system_information_length, uint32_t system_information_length, emulator_object<uint32_t> return_length);
emulator_object<uint32_t> return_length);
NTSTATUS handle_NtSetSystemInformation(); NTSTATUS handle_NtSetSystemInformation();
// syscalls/thread.cpp: // syscalls/thread.cpp:
@@ -313,64 +264,48 @@ namespace syscalls
emulator_pointer /*client_id*/); emulator_pointer /*client_id*/);
NTSTATUS handle_NtOpenThreadToken(const syscall_context&, handle thread_handle, ACCESS_MASK /*desired_access*/, NTSTATUS handle_NtOpenThreadToken(const syscall_context&, handle thread_handle, ACCESS_MASK /*desired_access*/,
BOOLEAN /*open_as_self*/, emulator_object<handle> token_handle); BOOLEAN /*open_as_self*/, emulator_object<handle> token_handle);
NTSTATUS handle_NtOpenThreadTokenEx(const syscall_context& c, handle thread_handle, ACCESS_MASK desired_access, NTSTATUS handle_NtOpenThreadTokenEx(const syscall_context& c, handle thread_handle, ACCESS_MASK desired_access, BOOLEAN open_as_self,
BOOLEAN open_as_self, ULONG /*handle_attributes*/, ULONG /*handle_attributes*/, emulator_object<handle> token_handle);
emulator_object<handle> token_handle);
NTSTATUS handle_NtTerminateThread(const syscall_context& c, handle thread_handle, NTSTATUS exit_status); NTSTATUS handle_NtTerminateThread(const syscall_context& c, handle thread_handle, NTSTATUS exit_status);
NTSTATUS handle_NtDelayExecution(const syscall_context& c, BOOLEAN alertable, NTSTATUS handle_NtDelayExecution(const syscall_context& c, BOOLEAN alertable, emulator_object<LARGE_INTEGER> delay_interval);
emulator_object<LARGE_INTEGER> delay_interval);
NTSTATUS handle_NtAlertThreadByThreadId(const syscall_context& c, uint64_t thread_id); NTSTATUS handle_NtAlertThreadByThreadId(const syscall_context& c, uint64_t thread_id);
NTSTATUS handle_NtAlertThreadByThreadIdEx(const syscall_context& c, uint64_t thread_id, NTSTATUS handle_NtAlertThreadByThreadIdEx(const syscall_context& c, uint64_t thread_id,
emulator_object<EMU_RTL_SRWLOCK<EmulatorTraits<Emu64>>> lock); emulator_object<EMU_RTL_SRWLOCK<EmulatorTraits<Emu64>>> lock);
NTSTATUS handle_NtWaitForAlertByThreadId(const syscall_context& c, uint64_t, NTSTATUS handle_NtWaitForAlertByThreadId(const syscall_context& c, uint64_t, emulator_object<LARGE_INTEGER> timeout);
emulator_object<LARGE_INTEGER> timeout);
NTSTATUS handle_NtYieldExecution(const syscall_context& c); NTSTATUS handle_NtYieldExecution(const syscall_context& c);
NTSTATUS handle_NtResumeThread(const syscall_context& c, handle thread_handle, NTSTATUS handle_NtResumeThread(const syscall_context& c, handle thread_handle, emulator_object<ULONG> previous_suspend_count);
emulator_object<ULONG> previous_suspend_count); NTSTATUS handle_NtContinue(const syscall_context& c, emulator_object<CONTEXT64> thread_context, BOOLEAN raise_alert);
NTSTATUS handle_NtContinue(const syscall_context& c, emulator_object<CONTEXT64> thread_context, NTSTATUS handle_NtContinueEx(const syscall_context& c, emulator_object<CONTEXT64> thread_context, uint64_t continue_argument);
BOOLEAN raise_alert); NTSTATUS handle_NtGetNextThread(const syscall_context& c, handle process_handle, handle thread_handle, ACCESS_MASK /*desired_access*/,
NTSTATUS handle_NtContinueEx(const syscall_context& c, emulator_object<CONTEXT64> thread_context, ULONG /*handle_attributes*/, ULONG flags, emulator_object<handle> new_thread_handle);
uint64_t continue_argument); NTSTATUS handle_NtGetContextThread(const syscall_context& c, handle thread_handle, emulator_object<CONTEXT64> thread_context);
NTSTATUS handle_NtGetNextThread(const syscall_context& c, handle process_handle, handle thread_handle, NTSTATUS handle_NtSetContextThread(const syscall_context& c, handle thread_handle, emulator_object<CONTEXT64> thread_context);
ACCESS_MASK /*desired_access*/, ULONG /*handle_attributes*/, ULONG flags, NTSTATUS handle_NtCreateThreadEx(const syscall_context& c, emulator_object<handle> thread_handle, ACCESS_MASK /*desired_access*/,
emulator_object<handle> new_thread_handle);
NTSTATUS handle_NtGetContextThread(const syscall_context& c, handle thread_handle,
emulator_object<CONTEXT64> thread_context);
NTSTATUS handle_NtSetContextThread(const syscall_context& c, handle thread_handle,
emulator_object<CONTEXT64> thread_context);
NTSTATUS handle_NtCreateThreadEx(const syscall_context& c, emulator_object<handle> thread_handle,
ACCESS_MASK /*desired_access*/,
emulator_object<OBJECT_ATTRIBUTES<EmulatorTraits<Emu64>>> emulator_object<OBJECT_ATTRIBUTES<EmulatorTraits<Emu64>>>
/*object_attributes*/, /*object_attributes*/,
handle process_handle, uint64_t start_routine, uint64_t argument, handle process_handle, uint64_t start_routine, uint64_t argument, ULONG create_flags,
ULONG create_flags, EmulatorTraits<Emu64>::SIZE_T /*zero_bits*/, EmulatorTraits<Emu64>::SIZE_T /*zero_bits*/, EmulatorTraits<Emu64>::SIZE_T stack_size,
EmulatorTraits<Emu64>::SIZE_T stack_size,
EmulatorTraits<Emu64>::SIZE_T /*maximum_stack_size*/, EmulatorTraits<Emu64>::SIZE_T /*maximum_stack_size*/,
emulator_object<PS_ATTRIBUTE_LIST<EmulatorTraits<Emu64>>> attribute_list); emulator_object<PS_ATTRIBUTE_LIST<EmulatorTraits<Emu64>>> attribute_list);
NTSTATUS handle_NtGetCurrentProcessorNumberEx(const syscall_context&, NTSTATUS handle_NtGetCurrentProcessorNumberEx(const syscall_context&, emulator_object<PROCESSOR_NUMBER> processor_number);
emulator_object<PROCESSOR_NUMBER> processor_number);
ULONG handle_NtGetCurrentProcessorNumber(); ULONG handle_NtGetCurrentProcessorNumber();
NTSTATUS handle_NtQueueApcThreadEx2(const syscall_context& c, handle thread_handle, handle reserve_handle, NTSTATUS handle_NtQueueApcThreadEx2(const syscall_context& c, handle thread_handle, handle reserve_handle, uint32_t apc_flags,
uint32_t apc_flags, uint64_t apc_routine, uint64_t apc_argument1, uint64_t apc_routine, uint64_t apc_argument1, uint64_t apc_argument2, uint64_t apc_argument3);
uint64_t apc_argument2, uint64_t apc_argument3); NTSTATUS handle_NtQueueApcThreadEx(const syscall_context& c, handle thread_handle, handle reserve_handle, uint64_t apc_routine,
NTSTATUS handle_NtQueueApcThreadEx(const syscall_context& c, handle thread_handle, handle reserve_handle, uint64_t apc_argument1, uint64_t apc_argument2, uint64_t apc_argument3);
uint64_t apc_routine, uint64_t apc_argument1, uint64_t apc_argument2, NTSTATUS handle_NtQueueApcThread(const syscall_context& c, handle thread_handle, uint64_t apc_routine, uint64_t apc_argument1,
uint64_t apc_argument3); uint64_t apc_argument2, uint64_t apc_argument3);
NTSTATUS handle_NtQueueApcThread(const syscall_context& c, handle thread_handle, uint64_t apc_routine,
uint64_t apc_argument1, uint64_t apc_argument2, uint64_t apc_argument3);
// syscalls/timer.cpp: // syscalls/timer.cpp:
NTSTATUS handle_NtQueryTimerResolution(const syscall_context&, emulator_object<ULONG> maximum_time, NTSTATUS handle_NtQueryTimerResolution(const syscall_context&, emulator_object<ULONG> maximum_time, emulator_object<ULONG> minimum_time,
emulator_object<ULONG> minimum_time, emulator_object<ULONG> current_time); emulator_object<ULONG> current_time);
NTSTATUS handle_NtSetTimerResolution(const syscall_context&, ULONG /*desired_resolution*/, BOOLEAN set_resolution, NTSTATUS handle_NtSetTimerResolution(const syscall_context&, ULONG /*desired_resolution*/, BOOLEAN set_resolution,
emulator_object<ULONG> current_resolution); emulator_object<ULONG> current_resolution);
NTSTATUS handle_NtCreateTimer2(const syscall_context& c, emulator_object<handle> timer_handle, uint64_t reserved, NTSTATUS handle_NtCreateTimer2(const syscall_context& c, emulator_object<handle> timer_handle, uint64_t reserved,
emulator_object<OBJECT_ATTRIBUTES<EmulatorTraits<Emu64>>> object_attributes, emulator_object<OBJECT_ATTRIBUTES<EmulatorTraits<Emu64>>> object_attributes, ULONG attributes,
ULONG attributes, ACCESS_MASK desired_access); ACCESS_MASK desired_access);
NTSTATUS handle_NtCreateTimer(const syscall_context& c, emulator_object<handle> timer_handle, NTSTATUS handle_NtCreateTimer(const syscall_context& c, emulator_object<handle> timer_handle, ACCESS_MASK desired_access,
ACCESS_MASK desired_access, emulator_object<OBJECT_ATTRIBUTES<EmulatorTraits<Emu64>>> object_attributes, ULONG timer_type);
emulator_object<OBJECT_ATTRIBUTES<EmulatorTraits<Emu64>>> object_attributes,
ULONG timer_type);
NTSTATUS handle_NtSetTimer(); NTSTATUS handle_NtSetTimer();
NTSTATUS handle_NtSetTimer2(); NTSTATUS handle_NtSetTimer2();
NTSTATUS handle_NtSetTimerEx(const syscall_context& c, handle timer_handle, uint32_t timer_set_info_class, NTSTATUS handle_NtSetTimerEx(const syscall_context& c, handle timer_handle, uint32_t timer_set_info_class,
@@ -383,22 +318,20 @@ namespace syscalls
emulator_object<OBJECT_ATTRIBUTES<EmulatorTraits<Emu64>>> emulator_object<OBJECT_ATTRIBUTES<EmulatorTraits<Emu64>>>
/*object_attributes*/, /*object_attributes*/,
BOOLEAN /*effective_only*/, TOKEN_TYPE type, emulator_object<handle> new_token_handle); BOOLEAN /*effective_only*/, TOKEN_TYPE type, emulator_object<handle> new_token_handle);
NTSTATUS handle_NtQueryInformationToken(const syscall_context& c, handle token_handle, NTSTATUS handle_NtQueryInformationToken(const syscall_context& c, handle token_handle, TOKEN_INFORMATION_CLASS token_information_class,
TOKEN_INFORMATION_CLASS token_information_class, uint64_t token_information, uint64_t token_information, ULONG token_information_length,
ULONG token_information_length, emulator_object<ULONG> return_length); emulator_object<ULONG> return_length);
NTSTATUS handle_NtQuerySecurityAttributesToken(); NTSTATUS handle_NtQuerySecurityAttributesToken();
NTSTATUS handle_NtQueryPerformanceCounter(const syscall_context& c, NTSTATUS handle_NtQueryPerformanceCounter(const syscall_context& c, const emulator_object<LARGE_INTEGER> performance_counter,
const emulator_object<LARGE_INTEGER> performance_counter,
const emulator_object<LARGE_INTEGER> performance_frequency) const emulator_object<LARGE_INTEGER> performance_frequency)
{ {
try try
{ {
if (performance_counter) if (performance_counter)
{ {
performance_counter.access([&](LARGE_INTEGER& value) { performance_counter.access(
value.QuadPart = c.win_emu.clock().steady_now().time_since_epoch().count(); [&](LARGE_INTEGER& value) { value.QuadPart = c.win_emu.clock().steady_now().time_since_epoch().count(); });
});
} }
if (performance_frequency) if (performance_frequency)
@@ -441,10 +374,10 @@ namespace syscalls
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
NTSTATUS handle_NtCreateIoCompletion( NTSTATUS handle_NtCreateIoCompletion(const syscall_context& c, const emulator_object<handle> event_handle,
const syscall_context& c, const emulator_object<handle> event_handle, const ACCESS_MASK desired_access, const ACCESS_MASK desired_access,
const emulator_object<OBJECT_ATTRIBUTES<EmulatorTraits<Emu64>>> object_attributes, const emulator_object<OBJECT_ATTRIBUTES<EmulatorTraits<Emu64>>> object_attributes,
const uint32_t /*number_of_concurrent_threads*/) const uint32_t /*number_of_concurrent_threads*/)
{ {
return handle_NtCreateEvent(c, event_handle, desired_access, object_attributes, NotificationEvent, FALSE); return handle_NtCreateEvent(c, event_handle, desired_access, object_attributes, NotificationEvent, FALSE);
} }
@@ -454,11 +387,10 @@ namespace syscalls
return STATUS_NOT_SUPPORTED; return STATUS_NOT_SUPPORTED;
} }
NTSTATUS handle_NtRemoveIoCompletion( NTSTATUS handle_NtRemoveIoCompletion(const syscall_context&, const emulator_object<handle> /*io_completion__handle*/,
const syscall_context&, const emulator_object<handle> /*io_completion__handle*/, const emulator_object<int64_t> key_context, const emulator_pointer /*apc_context*/,
const emulator_object<int64_t> key_context, const emulator_pointer /*apc_context*/, const emulator_object<IO_STATUS_BLOCK<EmulatorTraits<Emu64>>> /*io_status_block*/,
const emulator_object<IO_STATUS_BLOCK<EmulatorTraits<Emu64>>> /*io_status_block*/, const emulator_object<LARGE_INTEGER> timeout)
const emulator_object<LARGE_INTEGER> timeout)
{ {
if (timeout && timeout.read().QuadPart == 0) if (timeout && timeout.read().QuadPart == 0)
{ {
@@ -474,9 +406,9 @@ namespace syscalls
return STATUS_NOT_SUPPORTED; return STATUS_NOT_SUPPORTED;
} }
NTSTATUS handle_NtCreateWaitCompletionPacket( NTSTATUS handle_NtCreateWaitCompletionPacket(const syscall_context& c, const emulator_object<handle> event_handle,
const syscall_context& c, const emulator_object<handle> event_handle, const ACCESS_MASK desired_access, const ACCESS_MASK desired_access,
const emulator_object<OBJECT_ATTRIBUTES<EmulatorTraits<Emu64>>> object_attributes) const emulator_object<OBJECT_ATTRIBUTES<EmulatorTraits<Emu64>>> object_attributes)
{ {
return handle_NtCreateEvent(c, event_handle, desired_access, object_attributes, NotificationEvent, FALSE); return handle_NtCreateEvent(c, event_handle, desired_access, object_attributes, NotificationEvent, FALSE);
} }
@@ -487,12 +419,10 @@ namespace syscalls
} }
NTSTATUS handle_NtDeviceIoControlFile(const syscall_context& c, const handle file_handle, const handle event, NTSTATUS handle_NtDeviceIoControlFile(const syscall_context& c, const handle file_handle, const handle event,
const emulator_pointer /*PIO_APC_ROUTINE*/ apc_routine, const emulator_pointer /*PIO_APC_ROUTINE*/ apc_routine, const emulator_pointer apc_context,
const emulator_pointer apc_context,
const emulator_object<IO_STATUS_BLOCK<EmulatorTraits<Emu64>>> io_status_block, const emulator_object<IO_STATUS_BLOCK<EmulatorTraits<Emu64>>> io_status_block,
const ULONG io_control_code, const emulator_pointer input_buffer, const ULONG io_control_code, const emulator_pointer input_buffer, const ULONG input_buffer_length,
const ULONG input_buffer_length, const emulator_pointer output_buffer, const emulator_pointer output_buffer, const ULONG output_buffer_length)
const ULONG output_buffer_length)
{ {
auto* device = c.proc.devices.get(file_handle); auto* device = c.proc.devices.get(file_handle);
if (!device) if (!device)
@@ -635,8 +565,7 @@ namespace syscalls
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
NTSTATUS handle_NtAddAtom(const syscall_context& c, const uint64_t atom_name, const ULONG length, NTSTATUS handle_NtAddAtom(const syscall_context& c, const uint64_t atom_name, const ULONG length, const emulator_object<RTL_ATOM> atom)
const emulator_object<RTL_ATOM> atom)
{ {
return handle_NtAddAtomEx(c, atom_name, length, atom, 0); return handle_NtAddAtomEx(c, atom_name, length, atom, 0);
} }
@@ -647,8 +576,7 @@ namespace syscalls
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
NTSTATUS handle_NtFindAtom(const syscall_context& c, const uint64_t atom_name, const ULONG length, NTSTATUS handle_NtFindAtom(const syscall_context& c, const uint64_t atom_name, const ULONG length, const emulator_object<uint16_t> atom)
const emulator_object<uint16_t> atom)
{ {
const auto name = read_string<char16_t>(c.emu, atom_name, length / 2); const auto name = read_string<char16_t>(c.emu, atom_name, length / 2);
const auto index = c.proc.find_atom(name); const auto index = c.proc.find_atom(name);
@@ -702,8 +630,7 @@ namespace syscalls
return 96; return 96;
} }
hdc handle_NtUserGetDCEx(const syscall_context& /*c*/, const hwnd window, const uint64_t /*clip_region*/, hdc handle_NtUserGetDCEx(const syscall_context& /*c*/, const hwnd window, const uint64_t /*clip_region*/, const ULONG /*flags*/)
const ULONG /*flags*/)
{ {
return window; return window;
} }
@@ -786,19 +713,17 @@ namespace syscalls
EMULATOR_CAST(typename Traits::PVOID, UNICODE_STRING*) pusMenuName; EMULATOR_CAST(typename Traits::PVOID, UNICODE_STRING*) pusMenuName;
}; };
NTSTATUS handle_NtUserRegisterClassExWOW( NTSTATUS handle_NtUserRegisterClassExWOW(const syscall_context& c, const emulator_pointer /*wnd_class_ex*/,
const syscall_context& c, const emulator_pointer /*wnd_class_ex*/, const emulator_object<UNICODE_STRING<EmulatorTraits<Emu64>>> class_name,
const emulator_object<UNICODE_STRING<EmulatorTraits<Emu64>>> class_name, const emulator_object<UNICODE_STRING<EmulatorTraits<Emu64>>> /*class_version*/,
const emulator_object<UNICODE_STRING<EmulatorTraits<Emu64>>> /*class_version*/, const emulator_object<CLSMENUNAME<EmulatorTraits<Emu64>>> /*class_menu_name*/,
const emulator_object<CLSMENUNAME<EmulatorTraits<Emu64>>> /*class_menu_name*/, const DWORD /*function_id*/, const DWORD /*function_id*/, const DWORD /*flags*/, const emulator_pointer /*wow*/)
const DWORD /*flags*/, const emulator_pointer /*wow*/)
{ {
uint16_t index = c.proc.add_or_find_atom(read_unicode_string(c.emu, class_name)); uint16_t index = c.proc.add_or_find_atom(read_unicode_string(c.emu, class_name));
return index; return index;
} }
NTSTATUS handle_NtUserUnregisterClass(const syscall_context& c, NTSTATUS handle_NtUserUnregisterClass(const syscall_context& c, const emulator_object<UNICODE_STRING<EmulatorTraits<Emu64>>> class_name,
const emulator_object<UNICODE_STRING<EmulatorTraits<Emu64>>> class_name,
const emulator_pointer /*instance*/, const emulator_pointer /*instance*/,
const emulator_object<CLSMENUNAME<EmulatorTraits<Emu64>>> /*class_menu_name*/) const emulator_object<CLSMENUNAME<EmulatorTraits<Emu64>>> /*class_menu_name*/)
{ {
@@ -847,12 +772,10 @@ namespace syscalls
return u8_to_u16(ansi_string); return u8_to_u16(ansi_string);
} }
hwnd handle_NtUserCreateWindowEx(const syscall_context& c, const DWORD /*ex_style*/, hwnd handle_NtUserCreateWindowEx(const syscall_context& c, const DWORD /*ex_style*/, const emulator_object<LARGE_STRING> class_name,
const emulator_object<LARGE_STRING> class_name, const emulator_object<LARGE_STRING> /*cls_version*/, const emulator_object<LARGE_STRING> window_name,
const emulator_object<LARGE_STRING> /*cls_version*/, const DWORD /*style*/, const int x, const int y, const int width, const int height,
const emulator_object<LARGE_STRING> window_name, const DWORD /*style*/, const hwnd /*parent*/, const hmenu /*menu*/, const hinstance /*instance*/, const pointer /*l_param*/,
const int x, const int y, const int width, const int height, const hwnd /*parent*/,
const hmenu /*menu*/, const hinstance /*instance*/, const pointer /*l_param*/,
const DWORD /*flags*/, const pointer /*acbi_buffer*/) const DWORD /*flags*/, const pointer /*acbi_buffer*/)
{ {
window win{}; window win{};
@@ -925,8 +848,8 @@ namespace syscalls
return TRUE; return TRUE;
} }
BOOL handle_NtUserGetMessage(const syscall_context& c, const emulator_object<msg> message, const hwnd hwnd, BOOL handle_NtUserGetMessage(const syscall_context& c, const emulator_object<msg> message, const hwnd hwnd, const UINT msg_filter_min,
const UINT msg_filter_min, const UINT msg_filter_max) const UINT msg_filter_max)
{ {
(void)c; (void)c;
(void)message; (void)message;
@@ -937,8 +860,8 @@ namespace syscalls
return TRUE; return TRUE;
} }
BOOL handle_NtUserPeekMessage(const syscall_context& c, const emulator_object<msg> message, const hwnd hwnd, BOOL handle_NtUserPeekMessage(const syscall_context& c, const emulator_object<msg> message, const hwnd hwnd, const UINT msg_filter_min,
const UINT msg_filter_min, const UINT msg_filter_max, const UINT remove_message) const UINT msg_filter_max, const UINT remove_message)
{ {
(void)c; (void)c;
(void)message; (void)message;
@@ -951,10 +874,8 @@ namespace syscalls
} }
NTSTATUS handle_NtUserEnumDisplayDevices(const syscall_context& /*c*/, NTSTATUS handle_NtUserEnumDisplayDevices(const syscall_context& /*c*/,
const emulator_object<UNICODE_STRING<EmulatorTraits<Emu64>>> str_device, const emulator_object<UNICODE_STRING<EmulatorTraits<Emu64>>> str_device, const DWORD dev_num,
const DWORD dev_num, const emulator_object<EMU_DISPLAY_DEVICEW> display_device, const DWORD /*flags*/)
const emulator_object<EMU_DISPLAY_DEVICEW> display_device,
const DWORD /*flags*/)
{ {
if (str_device && dev_num != 0) if (str_device && dev_num != 0)
{ {
@@ -971,9 +892,8 @@ namespace syscalls
utils::string::copy(dev.DeviceName, u"\\\\.\\DISPLAY1"); utils::string::copy(dev.DeviceName, u"\\\\.\\DISPLAY1");
utils::string::copy(dev.DeviceID, u"PCI\\VEN_10DE&DEV_0000&SUBSYS_00000000&REV_A1"); utils::string::copy(dev.DeviceID, u"PCI\\VEN_10DE&DEV_0000&SUBSYS_00000000&REV_A1");
utils::string::copy(dev.DeviceString, u"Emulator Display"); utils::string::copy(dev.DeviceString, u"Emulator Display");
utils::string::copy(dev.DeviceKey, utils::string::copy(dev.DeviceKey, u"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Video\\{00000001-"
u"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Video\\{00000001-" u"0002-0003-0004-000000000005}\\0001");
u"0002-0003-0004-000000000005}\\0001");
}); });
return STATUS_SUCCESS; return STATUS_SUCCESS;

View File

@@ -4,8 +4,7 @@
namespace syscalls namespace syscalls
{ {
NTSTATUS handle_NtSetEvent(const syscall_context& c, const uint64_t handle, NTSTATUS handle_NtSetEvent(const syscall_context& c, const uint64_t handle, const emulator_object<LONG> previous_state)
const emulator_object<LONG> previous_state)
{ {
if (handle == DBWIN_DATA_READY) if (handle == DBWIN_DATA_READY)
{ {

View File

@@ -4,12 +4,10 @@
namespace syscalls namespace syscalls
{ {
NTSTATUS handle_NtRaiseHardError(const syscall_context& c, const NTSTATUS error_status, NTSTATUS handle_NtRaiseHardError(const syscall_context& c, const NTSTATUS error_status, const ULONG /*number_of_parameters*/,
const ULONG /*number_of_parameters*/,
const emulator_object<UNICODE_STRING<EmulatorTraits<Emu64>>> const emulator_object<UNICODE_STRING<EmulatorTraits<Emu64>>>
/*unicode_string_parameter_mask*/, /*unicode_string_parameter_mask*/,
const emulator_object<DWORD> /*parameters*/, const emulator_object<DWORD> /*parameters*/, const HARDERROR_RESPONSE_OPTION /*valid_response_option*/,
const HARDERROR_RESPONSE_OPTION /*valid_response_option*/,
const emulator_object<HARDERROR_RESPONSE> response) const emulator_object<HARDERROR_RESPONSE> response)
{ {
if (response) if (response)
@@ -24,10 +22,9 @@ namespace syscalls
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
NTSTATUS handle_NtRaiseException( NTSTATUS handle_NtRaiseException(const syscall_context& c,
const syscall_context& c, const emulator_object<EMU_EXCEPTION_RECORD<EmulatorTraits<Emu64>>> /*exception_record*/,
const emulator_object<EMU_EXCEPTION_RECORD<EmulatorTraits<Emu64>>> /*exception_record*/, const emulator_object<CONTEXT64> /*thread_context*/, const BOOLEAN handle_exception)
const emulator_object<CONTEXT64> /*thread_context*/, const BOOLEAN handle_exception)
{ {
if (handle_exception) if (handle_exception)
{ {

View File

@@ -21,8 +21,7 @@ namespace syscalls
{ {
namespace namespace
{ {
std::pair<utils::file_handle, NTSTATUS> open_file(const file_system& file_sys, const windows_path& path, std::pair<utils::file_handle, NTSTATUS> open_file(const file_system& file_sys, const windows_path& path, const std::u16string& mode)
const std::u16string& mode)
{ {
FILE* file{}; FILE* file{};
const auto error = open_unicode(&file, file_sys.translate(path), mode); const auto error = open_unicode(&file, file_sys.translate(path), mode);
@@ -50,8 +49,7 @@ namespace syscalls
NTSTATUS handle_NtSetInformationFile(const syscall_context& c, const handle file_handle, NTSTATUS handle_NtSetInformationFile(const syscall_context& c, const handle file_handle,
const emulator_object<IO_STATUS_BLOCK<EmulatorTraits<Emu64>>> io_status_block, const emulator_object<IO_STATUS_BLOCK<EmulatorTraits<Emu64>>> io_status_block,
const uint64_t file_information, const ULONG length, const uint64_t file_information, const ULONG length, const FILE_INFORMATION_CLASS info_class)
const FILE_INFORMATION_CLASS info_class)
{ {
const auto* f = c.proc.files.get(file_handle); const auto* f = c.proc.files.get(file_handle);
if (!f) if (!f)
@@ -73,8 +71,8 @@ namespace syscalls
} }
const auto info = c.emu.read_memory<FILE_RENAME_INFORMATION>(file_information); const auto info = c.emu.read_memory<FILE_RENAME_INFORMATION>(file_information);
auto new_name = read_string<char16_t>(c.emu, file_information + offsetof(FILE_RENAME_INFORMATION, FileName), auto new_name =
info.FileNameLength / 2); read_string<char16_t>(c.emu, file_information + offsetof(FILE_RENAME_INFORMATION, FileName), info.FileNameLength / 2);
if (info.RootDirectory) if (info.RootDirectory)
{ {
@@ -88,8 +86,7 @@ namespace syscalls
new_name = root->name + (has_separator ? u"" : u"\\") + new_name; new_name = root->name + (has_separator ? u"" : u"\\") + new_name;
} }
c.win_emu.log.warn("--> File rename requested: %s --> %s\n", u16_to_u8(f->name).c_str(), c.win_emu.log.warn("--> File rename requested: %s --> %s\n", u16_to_u8(f->name).c_str(), u16_to_u8(new_name).c_str());
u16_to_u8(new_name).c_str());
return STATUS_ACCESS_DENIED; return STATUS_ACCESS_DENIED;
} }
@@ -135,10 +132,10 @@ namespace syscalls
return STATUS_NOT_SUPPORTED; return STATUS_NOT_SUPPORTED;
} }
NTSTATUS handle_NtQueryVolumeInformationFile( NTSTATUS handle_NtQueryVolumeInformationFile(const syscall_context& c, const handle file_handle,
const syscall_context& c, const handle file_handle, const emulator_object<IO_STATUS_BLOCK<EmulatorTraits<Emu64>>> io_status_block,
const emulator_object<IO_STATUS_BLOCK<EmulatorTraits<Emu64>>> io_status_block, const uint64_t fs_information, const uint64_t fs_information, const ULONG length,
const ULONG length, const FS_INFORMATION_CLASS fs_information_class) const FS_INFORMATION_CLASS fs_information_class)
{ {
switch (fs_information_class) switch (fs_information_class)
{ {
@@ -177,8 +174,7 @@ namespace syscalls
} }
} }
std::vector<file_entry> scan_directory(const file_system& file_sys, const windows_path& win_path, std::vector<file_entry> scan_directory(const file_system& file_sys, const windows_path& win_path, const std::u16string_view file_mask)
const std::u16string_view file_mask)
{ {
std::vector<file_entry> files{}; std::vector<file_entry> files{};
@@ -319,12 +315,12 @@ namespace syscalls
return current_index <= enum_state.files.size() ? STATUS_SUCCESS : STATUS_NO_MORE_FILES; return current_index <= enum_state.files.size() ? STATUS_SUCCESS : STATUS_NO_MORE_FILES;
} }
NTSTATUS handle_NtQueryDirectoryFileEx( NTSTATUS handle_NtQueryDirectoryFileEx(const syscall_context& c, const handle file_handle, const handle /*event_handle*/,
const syscall_context& c, const handle file_handle, const handle /*event_handle*/, const EMULATOR_CAST(emulator_pointer, PIO_APC_ROUTINE) /*apc_routine*/,
const EMULATOR_CAST(emulator_pointer, PIO_APC_ROUTINE) /*apc_routine*/, const emulator_pointer /*apc_context*/, const emulator_pointer /*apc_context*/,
const emulator_object<IO_STATUS_BLOCK<EmulatorTraits<Emu64>>> io_status_block, const uint64_t file_information, const emulator_object<IO_STATUS_BLOCK<EmulatorTraits<Emu64>>> io_status_block,
const uint32_t length, const uint32_t info_class, const ULONG query_flags, const uint64_t file_information, const uint32_t length, const uint32_t info_class,
const emulator_object<UNICODE_STRING<EmulatorTraits<Emu64>>> file_name) const ULONG query_flags, const emulator_object<UNICODE_STRING<EmulatorTraits<Emu64>>> file_name)
{ {
auto* f = c.proc.files.get(file_handle); auto* f = c.proc.files.get(file_handle);
if (!f || !f->is_directory()) if (!f || !f->is_directory())
@@ -334,20 +330,20 @@ namespace syscalls
if (info_class == FileDirectoryInformation) if (info_class == FileDirectoryInformation)
{ {
return handle_file_enumeration<FILE_DIRECTORY_INFORMATION>(c, io_status_block, file_information, length, return handle_file_enumeration<FILE_DIRECTORY_INFORMATION>(c, io_status_block, file_information, length, query_flags, file_name,
query_flags, file_name, f); f);
} }
if (info_class == FileFullDirectoryInformation) if (info_class == FileFullDirectoryInformation)
{ {
return handle_file_enumeration<FILE_FULL_DIR_INFORMATION>(c, io_status_block, file_information, length, return handle_file_enumeration<FILE_FULL_DIR_INFORMATION>(c, io_status_block, file_information, length, query_flags, file_name,
query_flags, file_name, f); f);
} }
if (info_class == FileBothDirectoryInformation) if (info_class == FileBothDirectoryInformation)
{ {
return handle_file_enumeration<FILE_BOTH_DIR_INFORMATION>(c, io_status_block, file_information, length, return handle_file_enumeration<FILE_BOTH_DIR_INFORMATION>(c, io_status_block, file_information, length, query_flags, file_name,
query_flags, file_name, f); f);
} }
c.win_emu.log.error("Unsupported query directory file info class: %X\n", info_class); c.win_emu.log.error("Unsupported query directory file info class: %X\n", info_class);
@@ -360,10 +356,9 @@ namespace syscalls
const EMULATOR_CAST(emulator_pointer, PIO_APC_ROUTINE) apc_routine, const EMULATOR_CAST(emulator_pointer, PIO_APC_ROUTINE) apc_routine,
const emulator_pointer apc_context, const emulator_pointer apc_context,
const emulator_object<IO_STATUS_BLOCK<EmulatorTraits<Emu64>>> io_status_block, const emulator_object<IO_STATUS_BLOCK<EmulatorTraits<Emu64>>> io_status_block,
const uint64_t file_information, const uint32_t length, const uint64_t file_information, const uint32_t length, const uint32_t info_class,
const uint32_t info_class, const BOOLEAN return_single_entry, const BOOLEAN return_single_entry,
const emulator_object<UNICODE_STRING<EmulatorTraits<Emu64>>> file_name, const emulator_object<UNICODE_STRING<EmulatorTraits<Emu64>>> file_name, const BOOLEAN restart_scan)
const BOOLEAN restart_scan)
{ {
ULONG query_flags = 0; ULONG query_flags = 0;
if (return_single_entry) if (return_single_entry)
@@ -374,14 +369,13 @@ namespace syscalls
{ {
query_flags |= SL_RESTART_SCAN; query_flags |= SL_RESTART_SCAN;
} }
return handle_NtQueryDirectoryFileEx(c, file_handle, event_handle, apc_routine, apc_context, io_status_block, return handle_NtQueryDirectoryFileEx(c, file_handle, event_handle, apc_routine, apc_context, io_status_block, file_information,
file_information, length, info_class, query_flags, file_name); length, info_class, query_flags, file_name);
} }
NTSTATUS handle_NtQueryInformationFile( NTSTATUS handle_NtQueryInformationFile(const syscall_context& c, const handle file_handle,
const syscall_context& c, const handle file_handle, const emulator_object<IO_STATUS_BLOCK<EmulatorTraits<Emu64>>> io_status_block,
const emulator_object<IO_STATUS_BLOCK<EmulatorTraits<Emu64>>> io_status_block, const uint64_t file_information, const uint64_t file_information, const uint32_t length, const uint32_t info_class)
const uint32_t length, const uint32_t info_class)
{ {
IO_STATUS_BLOCK<EmulatorTraits<Emu64>> block{}; IO_STATUS_BLOCK<EmulatorTraits<Emu64>> block{};
block.Status = STATUS_SUCCESS; block.Status = STATUS_SUCCESS;
@@ -539,10 +533,10 @@ namespace syscalls
return ret(STATUS_NOT_SUPPORTED); return ret(STATUS_NOT_SUPPORTED);
} }
NTSTATUS handle_NtQueryInformationByName( NTSTATUS handle_NtQueryInformationByName(const syscall_context& c,
const syscall_context& c, const emulator_object<OBJECT_ATTRIBUTES<EmulatorTraits<Emu64>>> object_attributes, const emulator_object<OBJECT_ATTRIBUTES<EmulatorTraits<Emu64>>> object_attributes,
const emulator_object<IO_STATUS_BLOCK<EmulatorTraits<Emu64>>> io_status_block, const uint64_t file_information, const emulator_object<IO_STATUS_BLOCK<EmulatorTraits<Emu64>>> io_status_block,
const uint32_t length, const uint32_t info_class) const uint64_t file_information, const uint32_t length, const uint32_t info_class)
{ {
IO_STATUS_BLOCK<EmulatorTraits<Emu64>> block{}; IO_STATUS_BLOCK<EmulatorTraits<Emu64>> block{};
block.Status = STATUS_SUCCESS; block.Status = STATUS_SUCCESS;
@@ -606,8 +600,7 @@ namespace syscalls
} }
void commit_file_data(const std::string_view data, emulator& emu, void commit_file_data(const std::string_view data, emulator& emu,
const emulator_object<IO_STATUS_BLOCK<EmulatorTraits<Emu64>>> io_status_block, const emulator_object<IO_STATUS_BLOCK<EmulatorTraits<Emu64>>> io_status_block, const uint64_t buffer)
const uint64_t buffer)
{ {
if (io_status_block) if (io_status_block)
{ {
@@ -619,11 +612,10 @@ namespace syscalls
emu.write_memory(buffer, data.data(), data.size()); emu.write_memory(buffer, data.data(), data.size());
} }
NTSTATUS handle_NtReadFile(const syscall_context& c, const handle file_handle, const uint64_t /*event*/, NTSTATUS handle_NtReadFile(const syscall_context& c, const handle file_handle, const uint64_t /*event*/, const uint64_t /*apc_routine*/,
const uint64_t /*apc_routine*/, const uint64_t /*apc_context*/, const uint64_t /*apc_context*/,
const emulator_object<IO_STATUS_BLOCK<EmulatorTraits<Emu64>>> io_status_block, const emulator_object<IO_STATUS_BLOCK<EmulatorTraits<Emu64>>> io_status_block, const uint64_t buffer,
const uint64_t buffer, const ULONG length, const ULONG length, const emulator_object<LARGE_INTEGER> /*byte_offset*/,
const emulator_object<LARGE_INTEGER> /*byte_offset*/,
const emulator_object<ULONG> /*key*/) const emulator_object<ULONG> /*key*/)
{ {
std::string temp_buffer{}; std::string temp_buffer{};
@@ -639,12 +631,10 @@ namespace syscalls
std::cin.putback(chr); std::cin.putback(chr);
const auto read_count = const auto read_count = std::cin.readsome(temp_buffer.data(), static_cast<std::streamsize>(temp_buffer.size()));
std::cin.readsome(temp_buffer.data(), static_cast<std::streamsize>(temp_buffer.size()));
const auto count = std::max(read_count, static_cast<std::streamsize>(0)); const auto count = std::max(read_count, static_cast<std::streamsize>(0));
commit_file_data(std::string_view(temp_buffer.data(), static_cast<size_t>(count)), c.emu, io_status_block, commit_file_data(std::string_view(temp_buffer.data(), static_cast<size_t>(count)), c.emu, io_status_block, buffer);
buffer);
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
@@ -690,9 +680,8 @@ namespace syscalls
NTSTATUS handle_NtWriteFile(const syscall_context& c, const handle file_handle, const uint64_t /*event*/, NTSTATUS handle_NtWriteFile(const syscall_context& c, const handle file_handle, const uint64_t /*event*/,
const uint64_t /*apc_routine*/, const uint64_t /*apc_context*/, const uint64_t /*apc_routine*/, const uint64_t /*apc_context*/,
const emulator_object<IO_STATUS_BLOCK<EmulatorTraits<Emu64>>> io_status_block, const emulator_object<IO_STATUS_BLOCK<EmulatorTraits<Emu64>>> io_status_block, const uint64_t buffer,
const uint64_t buffer, const ULONG length, const ULONG length, const emulator_object<LARGE_INTEGER> /*byte_offset*/,
const emulator_object<LARGE_INTEGER> /*byte_offset*/,
const emulator_object<ULONG> /*key*/) const emulator_object<ULONG> /*key*/)
{ {
std::string temp_buffer{}; std::string temp_buffer{};
@@ -829,8 +818,7 @@ namespace syscalls
} }
NTSTATUS handle_named_pipe_create(const syscall_context& c, const emulator_object<handle>& out_handle, NTSTATUS handle_named_pipe_create(const syscall_context& c, const emulator_object<handle>& out_handle,
const std::u16string_view filename, const std::u16string_view filename, const OBJECT_ATTRIBUTES<EmulatorTraits<Emu64>>& attributes,
const OBJECT_ATTRIBUTES<EmulatorTraits<Emu64>>& attributes,
ACCESS_MASK desired_access) ACCESS_MASK desired_access)
{ {
(void)attributes; // This isn't being consumed atm, suppressing errors (void)attributes; // This isn't being consumed atm, suppressing errors
@@ -855,13 +843,12 @@ namespace syscalls
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
NTSTATUS handle_NtCreateFile(const syscall_context& c, const emulator_object<handle> file_handle, NTSTATUS handle_NtCreateFile(const syscall_context& c, const emulator_object<handle> file_handle, ACCESS_MASK desired_access,
ACCESS_MASK desired_access,
const emulator_object<OBJECT_ATTRIBUTES<EmulatorTraits<Emu64>>> object_attributes, const emulator_object<OBJECT_ATTRIBUTES<EmulatorTraits<Emu64>>> object_attributes,
const emulator_object<IO_STATUS_BLOCK<EmulatorTraits<Emu64>>> /*io_status_block*/, const emulator_object<IO_STATUS_BLOCK<EmulatorTraits<Emu64>>> /*io_status_block*/,
const emulator_object<LARGE_INTEGER> /*allocation_size*/, ULONG /*file_attributes*/, const emulator_object<LARGE_INTEGER> /*allocation_size*/, ULONG /*file_attributes*/,
ULONG /*share_access*/, ULONG create_disposition, ULONG create_options, ULONG /*share_access*/, ULONG create_disposition, ULONG create_options, uint64_t ea_buffer,
uint64_t ea_buffer, ULONG ea_length) ULONG ea_length)
{ {
const auto attributes = object_attributes.read(); const auto attributes = object_attributes.read();
auto filename = read_unicode_string(c.emu, attributes.ObjectName); auto filename = read_unicode_string(c.emu, attributes.ObjectName);
@@ -968,9 +955,9 @@ namespace syscalls
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
NTSTATUS handle_NtQueryFullAttributesFile( NTSTATUS handle_NtQueryFullAttributesFile(const syscall_context& c,
const syscall_context& c, const emulator_object<OBJECT_ATTRIBUTES<EmulatorTraits<Emu64>>> object_attributes, const emulator_object<OBJECT_ATTRIBUTES<EmulatorTraits<Emu64>>> object_attributes,
const emulator_object<FILE_NETWORK_OPEN_INFORMATION> file_information) const emulator_object<FILE_NETWORK_OPEN_INFORMATION> file_information)
{ {
if (!object_attributes) if (!object_attributes)
{ {
@@ -983,8 +970,7 @@ namespace syscalls
return STATUS_INVALID_PARAMETER; return STATUS_INVALID_PARAMETER;
} }
auto filename = read_unicode_string( auto filename = read_unicode_string(c.emu, emulator_object<UNICODE_STRING<EmulatorTraits<Emu64>>>{c.emu, attributes.ObjectName});
c.emu, emulator_object<UNICODE_STRING<EmulatorTraits<Emu64>>>{c.emu, attributes.ObjectName});
if (attributes.RootDirectory) if (attributes.RootDirectory)
{ {
@@ -1021,9 +1007,9 @@ namespace syscalls
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
NTSTATUS handle_NtQueryAttributesFile( NTSTATUS handle_NtQueryAttributesFile(const syscall_context& c,
const syscall_context& c, const emulator_object<OBJECT_ATTRIBUTES<EmulatorTraits<Emu64>>> object_attributes, const emulator_object<OBJECT_ATTRIBUTES<EmulatorTraits<Emu64>>> object_attributes,
const emulator_object<FILE_BASIC_INFORMATION> file_information) const emulator_object<FILE_BASIC_INFORMATION> file_information)
{ {
if (!object_attributes) if (!object_attributes)
{ {
@@ -1036,8 +1022,8 @@ namespace syscalls
return STATUS_INVALID_PARAMETER; return STATUS_INVALID_PARAMETER;
} }
const auto filename = read_unicode_string( const auto filename =
c.emu, emulator_object<UNICODE_STRING<EmulatorTraits<Emu64>>>{c.emu, attributes.ObjectName}); read_unicode_string(c.emu, emulator_object<UNICODE_STRING<EmulatorTraits<Emu64>>>{c.emu, attributes.ObjectName});
c.win_emu.callbacks.on_generic_access("Querying file attributes", filename); c.win_emu.callbacks.on_generic_access("Querying file attributes", filename);
@@ -1066,19 +1052,18 @@ namespace syscalls
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
NTSTATUS handle_NtOpenFile(const syscall_context& c, const emulator_object<handle> file_handle, NTSTATUS handle_NtOpenFile(const syscall_context& c, const emulator_object<handle> file_handle, const ACCESS_MASK desired_access,
const ACCESS_MASK desired_access,
const emulator_object<OBJECT_ATTRIBUTES<EmulatorTraits<Emu64>>> object_attributes, const emulator_object<OBJECT_ATTRIBUTES<EmulatorTraits<Emu64>>> object_attributes,
const emulator_object<IO_STATUS_BLOCK<EmulatorTraits<Emu64>>> io_status_block, const emulator_object<IO_STATUS_BLOCK<EmulatorTraits<Emu64>>> io_status_block, const ULONG share_access,
const ULONG share_access, const ULONG open_options) const ULONG open_options)
{ {
return handle_NtCreateFile(c, file_handle, desired_access, object_attributes, io_status_block, {c.emu}, 0, return handle_NtCreateFile(c, file_handle, desired_access, object_attributes, io_status_block, {c.emu}, 0, share_access, FILE_OPEN,
share_access, FILE_OPEN, open_options, 0, 0); open_options, 0, 0);
} }
NTSTATUS handle_NtOpenDirectoryObject( NTSTATUS handle_NtOpenDirectoryObject(const syscall_context& c, const emulator_object<handle> directory_handle,
const syscall_context& c, const emulator_object<handle> directory_handle, const ACCESS_MASK /*desired_access*/, const ACCESS_MASK /*desired_access*/,
const emulator_object<OBJECT_ATTRIBUTES<EmulatorTraits<Emu64>>> object_attributes) const emulator_object<OBJECT_ATTRIBUTES<EmulatorTraits<Emu64>>> object_attributes)
{ {
const auto attributes = object_attributes.read(); const auto attributes = object_attributes.read();
const auto object_name = read_unicode_string(c.emu, attributes.ObjectName); const auto object_name = read_unicode_string(c.emu, attributes.ObjectName);
@@ -1104,9 +1089,9 @@ namespace syscalls
return STATUS_NOT_SUPPORTED; return STATUS_NOT_SUPPORTED;
} }
NTSTATUS handle_NtOpenSymbolicLinkObject( NTSTATUS handle_NtOpenSymbolicLinkObject(const syscall_context& c, const emulator_object<handle> link_handle,
const syscall_context& c, const emulator_object<handle> link_handle, ACCESS_MASK /*desired_access*/, ACCESS_MASK /*desired_access*/,
const emulator_object<OBJECT_ATTRIBUTES<EmulatorTraits<Emu64>>> object_attributes) const emulator_object<OBJECT_ATTRIBUTES<EmulatorTraits<Emu64>>> object_attributes)
{ {
const auto attributes = object_attributes.read(); const auto attributes = object_attributes.read();
const auto object_name = read_unicode_string(c.emu, attributes.ObjectName); const auto object_name = read_unicode_string(c.emu, attributes.ObjectName);
@@ -1150,13 +1135,11 @@ namespace syscalls
return STATUS_NOT_SUPPORTED; return STATUS_NOT_SUPPORTED;
} }
NTSTATUS handle_NtCreateNamedPipeFile(const syscall_context& c, emulator_object<handle> file_handle, NTSTATUS handle_NtCreateNamedPipeFile(const syscall_context& c, emulator_object<handle> file_handle, ULONG desired_access,
ULONG desired_access,
emulator_object<OBJECT_ATTRIBUTES<EmulatorTraits<Emu64>>> object_attributes, emulator_object<OBJECT_ATTRIBUTES<EmulatorTraits<Emu64>>> object_attributes,
emulator_object<IO_STATUS_BLOCK<EmulatorTraits<Emu64>>> io_status_block, emulator_object<IO_STATUS_BLOCK<EmulatorTraits<Emu64>>> io_status_block, ULONG share_access,
ULONG share_access, ULONG create_disposition, ULONG create_options, ULONG create_disposition, ULONG create_options, ULONG named_pipe_type, ULONG read_mode,
ULONG named_pipe_type, ULONG read_mode, ULONG completion_mode, ULONG completion_mode, ULONG maximum_instances, ULONG inbound_quota, ULONG outbound_quota,
ULONG maximum_instances, ULONG inbound_quota, ULONG outbound_quota,
emulator_object<LARGE_INTEGER> default_timeout) emulator_object<LARGE_INTEGER> default_timeout)
{ {
(void)desired_access; (void)desired_access;
@@ -1204,12 +1187,11 @@ namespace syscalls
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
NTSTATUS handle_NtFsControlFile(const syscall_context& c, const handle /*event_handle*/, NTSTATUS handle_NtFsControlFile(const syscall_context& c, const handle /*event_handle*/, const uint64_t /*apc_routine*/,
const uint64_t /*apc_routine*/, const uint64_t /*app_context*/, const uint64_t /*app_context*/,
const emulator_object<IO_STATUS_BLOCK<EmulatorTraits<Emu64>>> /*io_status_block*/, const emulator_object<IO_STATUS_BLOCK<EmulatorTraits<Emu64>>> /*io_status_block*/,
const ULONG /*fs_control_code*/, const uint64_t /*input_buffer*/, const ULONG /*fs_control_code*/, const uint64_t /*input_buffer*/, const ULONG /*input_buffer_length*/,
const ULONG /*input_buffer_length*/, const uint64_t /*output_buffer*/, const uint64_t /*output_buffer*/, const ULONG /*output_buffer_length*/)
const ULONG /*output_buffer_length*/)
{ {
c.win_emu.log.error("Unimplemented syscall NtFsControlFile!"); c.win_emu.log.error("Unimplemented syscall NtFsControlFile!");
c.emu.stop(); c.emu.stop();
@@ -1217,9 +1199,8 @@ namespace syscalls
return STATUS_NOT_SUPPORTED; return STATUS_NOT_SUPPORTED;
} }
NTSTATUS handle_NtFlushBuffersFile( NTSTATUS handle_NtFlushBuffersFile(const syscall_context& c, const handle file_handle,
const syscall_context& c, const handle file_handle, const emulator_object<IO_STATUS_BLOCK<EmulatorTraits<Emu64>>> /*io_status_block*/)
const emulator_object<IO_STATUS_BLOCK<EmulatorTraits<Emu64>>> /*io_status_block*/)
{ {
if (file_handle == STDOUT_HANDLE) if (file_handle == STDOUT_HANDLE)
{ {

View File

@@ -10,8 +10,7 @@ namespace syscalls
const emulator_object<LCID> default_locale_id, const emulator_object<LCID> default_locale_id,
const emulator_object<LARGE_INTEGER> /*default_casing_table_size*/) const emulator_object<LARGE_INTEGER> /*default_casing_table_size*/)
{ {
const auto locale_file = const auto locale_file = utils::io::read_file(c.win_emu.file_sys.translate(R"(C:\Windows\System32\locale.nls)"));
utils::io::read_file(c.win_emu.file_sys.translate(R"(C:\Windows\System32\locale.nls)"));
if (locale_file.empty()) if (locale_file.empty())
{ {
return STATUS_FILE_INVALID; return STATUS_FILE_INVALID;
@@ -27,16 +26,14 @@ namespace syscalls
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
NTSTATUS handle_NtQueryDefaultLocale(const syscall_context&, BOOLEAN /*user_profile*/, NTSTATUS handle_NtQueryDefaultLocale(const syscall_context&, BOOLEAN /*user_profile*/, const emulator_object<LCID> default_locale_id)
const emulator_object<LCID> default_locale_id)
{ {
default_locale_id.write(0x407); default_locale_id.write(0x407);
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
NTSTATUS handle_NtGetNlsSectionPtr(const syscall_context& c, const ULONG section_type, const ULONG section_data, NTSTATUS handle_NtGetNlsSectionPtr(const syscall_context& c, const ULONG section_type, const ULONG section_data,
emulator_pointer /*context_data*/, emulator_pointer /*context_data*/, const emulator_object<uint64_t> section_pointer,
const emulator_object<uint64_t> section_pointer,
const emulator_object<ULONG> section_size) const emulator_object<ULONG> section_size)
{ {
if (section_type == 11) if (section_type == 11)

View File

@@ -6,10 +6,9 @@
namespace syscalls namespace syscalls
{ {
NTSTATUS handle_NtQueryVirtualMemory(const syscall_context& c, const handle process_handle, NTSTATUS handle_NtQueryVirtualMemory(const syscall_context& c, const handle process_handle, const uint64_t base_address,
const uint64_t base_address, const uint32_t info_class, const uint32_t info_class, const uint64_t memory_information,
const uint64_t memory_information, const uint64_t memory_information_length, const uint64_t memory_information_length, const emulator_object<uint64_t> return_length)
const emulator_object<uint64_t> return_length)
{ {
if (process_handle != CURRENT_PROCESS) if (process_handle != CURRENT_PROCESS)
{ {
@@ -126,9 +125,8 @@ namespace syscalls
} }
NTSTATUS handle_NtProtectVirtualMemory(const syscall_context& c, const handle process_handle, NTSTATUS handle_NtProtectVirtualMemory(const syscall_context& c, const handle process_handle,
const emulator_object<uint64_t> base_address, const emulator_object<uint64_t> base_address, const emulator_object<uint32_t> bytes_to_protect,
const emulator_object<uint32_t> bytes_to_protect, const uint32_t protection, const uint32_t protection, const emulator_object<uint32_t> old_protection)
const emulator_object<uint32_t> old_protection)
{ {
if (process_handle != CURRENT_PROCESS) if (process_handle != CURRENT_PROCESS)
{ {
@@ -172,8 +170,8 @@ namespace syscalls
NTSTATUS handle_NtAllocateVirtualMemoryEx(const syscall_context& c, const handle process_handle, NTSTATUS handle_NtAllocateVirtualMemoryEx(const syscall_context& c, const handle process_handle,
const emulator_object<uint64_t> base_address, const emulator_object<uint64_t> base_address,
const emulator_object<uint64_t> bytes_to_allocate, const emulator_object<uint64_t> bytes_to_allocate, const uint32_t allocation_type,
const uint32_t allocation_type, const uint32_t page_protection) const uint32_t page_protection)
{ {
if (process_handle != CURRENT_PROCESS) if (process_handle != CURRENT_PROCESS)
{ {
@@ -217,8 +215,7 @@ namespace syscalls
throw std::runtime_error("Unsupported allocation type!"); throw std::runtime_error("Unsupported allocation type!");
} }
if (commit && !reserve && if (commit && !reserve && c.win_emu.memory.commit_memory(potential_base, static_cast<size_t>(allocation_bytes), *protection))
c.win_emu.memory.commit_memory(potential_base, static_cast<size_t>(allocation_bytes), *protection))
{ {
c.win_emu.callbacks.on_memory_allocate(potential_base, allocation_bytes, *protection, true); c.win_emu.callbacks.on_memory_allocate(potential_base, allocation_bytes, *protection, true);
return STATUS_SUCCESS; return STATUS_SUCCESS;
@@ -226,23 +223,20 @@ namespace syscalls
c.win_emu.callbacks.on_memory_allocate(potential_base, allocation_bytes, *protection, false); c.win_emu.callbacks.on_memory_allocate(potential_base, allocation_bytes, *protection, false);
return c.win_emu.memory.allocate_memory(potential_base, static_cast<size_t>(allocation_bytes), *protection, return c.win_emu.memory.allocate_memory(potential_base, static_cast<size_t>(allocation_bytes), *protection, !commit)
!commit)
? STATUS_SUCCESS ? STATUS_SUCCESS
: STATUS_MEMORY_NOT_ALLOCATED; : STATUS_MEMORY_NOT_ALLOCATED;
} }
NTSTATUS handle_NtAllocateVirtualMemory(const syscall_context& c, const handle process_handle, NTSTATUS handle_NtAllocateVirtualMemory(const syscall_context& c, const handle process_handle,
const emulator_object<uint64_t> base_address, const uint64_t /*zero_bits*/, const emulator_object<uint64_t> base_address, const uint64_t /*zero_bits*/,
const emulator_object<uint64_t> bytes_to_allocate, const emulator_object<uint64_t> bytes_to_allocate, const uint32_t allocation_type,
const uint32_t allocation_type, const uint32_t page_protection) const uint32_t page_protection)
{ {
return handle_NtAllocateVirtualMemoryEx(c, process_handle, base_address, bytes_to_allocate, allocation_type, return handle_NtAllocateVirtualMemoryEx(c, process_handle, base_address, bytes_to_allocate, allocation_type, page_protection);
page_protection);
} }
NTSTATUS handle_NtFreeVirtualMemory(const syscall_context& c, const handle process_handle, NTSTATUS handle_NtFreeVirtualMemory(const syscall_context& c, const handle process_handle, const emulator_object<uint64_t> base_address,
const emulator_object<uint64_t> base_address,
const emulator_object<uint64_t> bytes_to_allocate, const uint32_t free_type) const emulator_object<uint64_t> bytes_to_allocate, const uint32_t free_type)
{ {
if (process_handle != CURRENT_PROCESS) if (process_handle != CURRENT_PROCESS)
@@ -260,24 +254,21 @@ namespace syscalls
if (free_type & MEM_RELEASE) if (free_type & MEM_RELEASE)
{ {
return c.win_emu.memory.release_memory(allocation_base, static_cast<size_t>(allocation_size)) return c.win_emu.memory.release_memory(allocation_base, static_cast<size_t>(allocation_size)) ? STATUS_SUCCESS
? STATUS_SUCCESS : STATUS_MEMORY_NOT_ALLOCATED;
: STATUS_MEMORY_NOT_ALLOCATED;
} }
if (free_type & MEM_DECOMMIT) if (free_type & MEM_DECOMMIT)
{ {
return c.win_emu.memory.decommit_memory(allocation_base, static_cast<size_t>(allocation_size)) return c.win_emu.memory.decommit_memory(allocation_base, static_cast<size_t>(allocation_size)) ? STATUS_SUCCESS
? STATUS_SUCCESS : STATUS_MEMORY_NOT_ALLOCATED;
: STATUS_MEMORY_NOT_ALLOCATED;
} }
throw std::runtime_error("Bad free type"); throw std::runtime_error("Bad free type");
} }
NTSTATUS handle_NtReadVirtualMemory(const syscall_context& c, const handle process_handle, NTSTATUS handle_NtReadVirtualMemory(const syscall_context& c, const handle process_handle, const emulator_pointer base_address,
const emulator_pointer base_address, const emulator_pointer buffer, const emulator_pointer buffer, const ULONG number_of_bytes_to_read,
const ULONG number_of_bytes_to_read,
const emulator_object<ULONG> number_of_bytes_read) const emulator_object<ULONG> number_of_bytes_read)
{ {
number_of_bytes_read.write(0); number_of_bytes_read.write(0);

View File

@@ -6,8 +6,7 @@
namespace syscalls namespace syscalls
{ {
NTSTATUS handle_NtReleaseMutant(const syscall_context& c, const handle mutant_handle, NTSTATUS handle_NtReleaseMutant(const syscall_context& c, const handle mutant_handle, const emulator_object<LONG> previous_count)
const emulator_object<LONG> previous_count)
{ {
if (mutant_handle.value.type != handle_types::mutant) if (mutant_handle.value.type != handle_types::mutant)
{ {
@@ -42,8 +41,7 @@ namespace syscalls
const auto attributes = object_attributes.read(); const auto attributes = object_attributes.read();
if (attributes.ObjectName) if (attributes.ObjectName)
{ {
name = read_unicode_string( name = read_unicode_string(c.emu, emulator_object<UNICODE_STRING<EmulatorTraits<Emu64>>>{c.emu, attributes.ObjectName});
c.emu, emulator_object<UNICODE_STRING<EmulatorTraits<Emu64>>>{c.emu, attributes.ObjectName});
c.win_emu.callbacks.on_generic_access("Opening mutant", name); c.win_emu.callbacks.on_generic_access("Opening mutant", name);
} }
} }

View File

@@ -21,10 +21,9 @@ namespace syscalls
return STATUS_INVALID_HANDLE; return STATUS_INVALID_HANDLE;
} }
NTSTATUS handle_NtDuplicateObject(const syscall_context& c, const handle source_process_handle, NTSTATUS handle_NtDuplicateObject(const syscall_context& c, const handle source_process_handle, const handle source_handle,
const handle source_handle, const handle target_process_handle, const handle target_process_handle, const emulator_object<handle> target_handle,
const emulator_object<handle> target_handle, const ACCESS_MASK /*desired_access*/, const ACCESS_MASK /*desired_access*/, const ULONG /*handle_attributes*/, const ULONG /*options*/)
const ULONG /*handle_attributes*/, const ULONG /*options*/)
{ {
if (source_process_handle != CURRENT_PROCESS || target_process_handle != CURRENT_PROCESS) if (source_process_handle != CURRENT_PROCESS || target_process_handle != CURRENT_PROCESS)
{ {
@@ -90,8 +89,7 @@ namespace syscalls
} }
} }
NTSTATUS handle_NtQueryObject(const syscall_context& c, const handle handle, NTSTATUS handle_NtQueryObject(const syscall_context& c, const handle handle, const OBJECT_INFORMATION_CLASS object_information_class,
const OBJECT_INFORMATION_CLASS object_information_class,
const emulator_pointer object_information, const ULONG object_information_length, const emulator_pointer object_information, const ULONG object_information_length,
const emulator_object<ULONG> return_length) const emulator_object<ULONG> return_length)
{ {
@@ -163,8 +161,7 @@ namespace syscalls
if (object_information_class == ObjectHandleFlagInformation) if (object_information_class == ObjectHandleFlagInformation)
{ {
return handle_query<OBJECT_HANDLE_FLAG_INFORMATION>(c.emu, object_information, object_information_length, return handle_query<OBJECT_HANDLE_FLAG_INFORMATION>(c.emu, object_information, object_information_length, return_length,
return_length,
[&](OBJECT_HANDLE_FLAG_INFORMATION& info) { [&](OBJECT_HANDLE_FLAG_INFORMATION& info) {
info.Inherit = 0; info.Inherit = 0;
info.ProtectFromClose = 0; info.ProtectFromClose = 0;
@@ -185,9 +182,9 @@ namespace syscalls
|| h.value.type == handle_types::event; || h.value.type == handle_types::event;
} }
NTSTATUS handle_NtWaitForMultipleObjects(const syscall_context& c, const ULONG count, NTSTATUS handle_NtWaitForMultipleObjects(const syscall_context& c, const ULONG count, const emulator_object<handle> handles,
const emulator_object<handle> handles, const WAIT_TYPE wait_type, const WAIT_TYPE wait_type, const BOOLEAN alertable,
const BOOLEAN alertable, const emulator_object<LARGE_INTEGER> timeout) const emulator_object<LARGE_INTEGER> timeout)
{ {
if (wait_type != WaitAny && wait_type != WaitAll) if (wait_type != WaitAny && wait_type != WaitAll)
{ {
@@ -249,21 +246,19 @@ namespace syscalls
return STATUS_NOT_SUPPORTED; return STATUS_NOT_SUPPORTED;
} }
NTSTATUS handle_NtQuerySecurityObject(const syscall_context& c, const handle /*h*/, NTSTATUS handle_NtQuerySecurityObject(const syscall_context& c, const handle /*h*/, const SECURITY_INFORMATION security_information,
const SECURITY_INFORMATION security_information,
const emulator_pointer security_descriptor, const ULONG length, const emulator_pointer security_descriptor, const ULONG length,
const emulator_object<ULONG> length_needed) const emulator_object<ULONG> length_needed)
{ {
if ((security_information & (OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | if ((security_information &
DACL_SECURITY_INFORMATION | LABEL_SECURITY_INFORMATION)) == 0) (OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION | LABEL_SECURITY_INFORMATION)) == 0)
{ {
return STATUS_INVALID_PARAMETER; return STATUS_INVALID_PARAMETER;
} }
// Owner SID: S-1-5-32-544 (Administrators) // Owner SID: S-1-5-32-544 (Administrators)
// NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
const uint8_t owner_sid[] = {0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, const uint8_t owner_sid[] = {0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x20, 0x00, 0x00, 0x00, 0x20, 0x02, 0x00, 0x00};
0x20, 0x00, 0x00, 0x00, 0x20, 0x02, 0x00, 0x00};
// Group SID: S-1-5-18 (Local System) // Group SID: S-1-5-18 (Local System)
// NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
@@ -272,21 +267,19 @@ namespace syscalls
// DACL structure // DACL structure
// NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
const uint8_t dacl_data[] = { const uint8_t dacl_data[] = {
0x02, 0x00, 0x9C, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x0F, 0x00, 0x02, 0x00, 0x01, 0x01, 0x02, 0x00, 0x9C, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x0F, 0x00, 0x02, 0x00, 0x01, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x0F, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x0F, 0x00, 0x02, 0x00, 0x01, 0x01, 0x00, 0x00,
0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x0F, 0x00, 0x0F, 0x00, 0x01, 0x02, 0x00, 0x00,
0x0F, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x20, 0x00, 0x00, 0x00, 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x20, 0x00, 0x00, 0x00, 0x20, 0x02, 0x00, 0x00, 0x00, 0x0B, 0x14, 0x00, 0x00, 0x00, 0x00, 0xE0,
0x00, 0x0B, 0x14, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x14, 0x00, 0x00, 0x00, 0x00, 0xE0,
0x00, 0x00, 0x00, 0x0B, 0x14, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10,
0x0C, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x20, 0x00, 0x00, 0x00, 0x20, 0x02, 0x00, 0x00, 0x00, 0x0B, 0x14, 0x00,
0x00, 0x05, 0x20, 0x00, 0x00, 0x00, 0x20, 0x02, 0x00, 0x00, 0x00, 0x0B, 0x14, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00};
0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00};
// SACL structure // SACL structure
// NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
const uint8_t sacl_data[] = {0x02, 0x00, 0x1C, 0x00, 0x01, 0x00, 0x00, 0x00, 0x11, 0x00, const uint8_t sacl_data[] = {0x02, 0x00, 0x1C, 0x00, 0x01, 0x00, 0x00, 0x00, 0x11, 0x00, 0x14, 0x00, 0x01, 0x00,
0x14, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x10, 0x00, 0x00};
0x00, 0x00, 0x00, 0x10, 0x00, 0x10, 0x00, 0x00};
ULONG total_size = sizeof(SECURITY_DESCRIPTOR_RELATIVE); ULONG total_size = sizeof(SECURITY_DESCRIPTOR_RELATIVE);

View File

@@ -9,8 +9,7 @@ namespace syscalls
const emulator_object<SECURITY_QUALITY_OF_SERVICE> /*security_qos*/, const emulator_object<SECURITY_QUALITY_OF_SERVICE> /*security_qos*/,
const emulator_object<PORT_VIEW64> client_shared_memory, const emulator_object<PORT_VIEW64> client_shared_memory,
const emulator_object<REMOTE_PORT_VIEW64> /*server_shared_memory*/, const emulator_object<REMOTE_PORT_VIEW64> /*server_shared_memory*/,
const emulator_object<ULONG> /*maximum_message_length*/, const emulator_object<ULONG> /*maximum_message_length*/, const emulator_pointer connection_info,
const emulator_pointer connection_info,
const emulator_object<ULONG> connection_info_length) const emulator_object<ULONG> connection_info_length)
{ {
auto port_name = read_unicode_string(c.emu, server_port_name); auto port_name = read_unicode_string(c.emu, server_port_name);
@@ -27,8 +26,7 @@ namespace syscalls
} }
client_shared_memory.access([&](PORT_VIEW64& view) { client_shared_memory.access([&](PORT_VIEW64& view) {
p.view_base = p.view_base = c.win_emu.memory.allocate_memory(static_cast<size_t>(view.ViewSize), memory_permission::read_write);
c.win_emu.memory.allocate_memory(static_cast<size_t>(view.ViewSize), memory_permission::read_write);
view.ViewBase = p.view_base; view.ViewBase = p.view_base;
view.ViewRemoteBase = view.ViewBase; view.ViewRemoteBase = view.ViewBase;
}); });
@@ -42,15 +40,13 @@ namespace syscalls
NTSTATUS handle_NtSecureConnectPort(const syscall_context& c, emulator_object<handle> client_port_handle, NTSTATUS handle_NtSecureConnectPort(const syscall_context& c, emulator_object<handle> client_port_handle,
emulator_object<UNICODE_STRING<EmulatorTraits<Emu64>>> server_port_name, emulator_object<UNICODE_STRING<EmulatorTraits<Emu64>>> server_port_name,
emulator_object<SECURITY_QUALITY_OF_SERVICE> security_qos, emulator_object<SECURITY_QUALITY_OF_SERVICE> security_qos,
emulator_object<PORT_VIEW64> client_shared_memory, emulator_object<PORT_VIEW64> client_shared_memory, emulator_pointer /*server_sid*/,
emulator_pointer /*server_sid*/,
emulator_object<REMOTE_PORT_VIEW64> server_shared_memory, emulator_object<REMOTE_PORT_VIEW64> server_shared_memory,
emulator_object<ULONG> maximum_message_length, emulator_pointer connection_info, emulator_object<ULONG> maximum_message_length, emulator_pointer connection_info,
emulator_object<ULONG> connection_info_length) emulator_object<ULONG> connection_info_length)
{ {
return handle_NtConnectPort(c, client_port_handle, server_port_name, security_qos, client_shared_memory, return handle_NtConnectPort(c, client_port_handle, server_port_name, security_qos, client_shared_memory, server_shared_memory,
server_shared_memory, maximum_message_length, connection_info, maximum_message_length, connection_info, connection_info_length);
connection_info_length);
} }
NTSTATUS handle_NtAlpcSendWaitReceivePort(const syscall_context& c, const handle port_handle, const ULONG /*flags*/, NTSTATUS handle_NtAlpcSendWaitReceivePort(const syscall_context& c, const handle port_handle, const ULONG /*flags*/,

View File

@@ -6,9 +6,8 @@
namespace syscalls namespace syscalls
{ {
NTSTATUS handle_NtQueryInformationProcess(const syscall_context& c, const handle process_handle, NTSTATUS handle_NtQueryInformationProcess(const syscall_context& c, const handle process_handle, const uint32_t info_class,
const uint32_t info_class, const uint64_t process_information, const uint64_t process_information, const uint32_t process_information_length,
const uint32_t process_information_length,
const emulator_object<uint32_t> return_length) const emulator_object<uint32_t> return_length)
{ {
if (process_handle != CURRENT_PROCESS) if (process_handle != CURRENT_PROCESS)
@@ -24,48 +23,43 @@ namespace syscalls
return STATUS_NOT_SUPPORTED; return STATUS_NOT_SUPPORTED;
case ProcessTimes: case ProcessTimes:
return handle_query<KERNEL_USER_TIMES>(c.emu, process_information, process_information_length, return handle_query<KERNEL_USER_TIMES>(c.emu, process_information, process_information_length, return_length,
return_length, [](KERNEL_USER_TIMES& t) { [](KERNEL_USER_TIMES& t) {
t = {}; // t = {}; //
}); });
case ProcessCookie: case ProcessCookie:
return handle_query<uint32_t>(c.emu, process_information, process_information_length, return_length, return handle_query<uint32_t>(c.emu, process_information, process_information_length, return_length, [](uint32_t& cookie) {
[](uint32_t& cookie) { cookie = 0x01234567; //
cookie = 0x01234567; // });
});
case ProcessDebugObjectHandle: case ProcessDebugObjectHandle:
return handle_query<handle>(c.emu, process_information, process_information_length, return_length, return handle_query<handle>(c.emu, process_information, process_information_length, return_length, [](handle& h) {
[](handle& h) { h = NULL_HANDLE;
h = NULL_HANDLE; return STATUS_PORT_NOT_SET;
return STATUS_PORT_NOT_SET; });
});
case ProcessDebugFlags: case ProcessDebugFlags:
case ProcessWx86Information: case ProcessWx86Information:
case ProcessDefaultHardErrorMode: case ProcessDefaultHardErrorMode:
return handle_query<ULONG>(c.emu, process_information, process_information_length, return_length, return handle_query<ULONG>(c.emu, process_information, process_information_length, return_length, [&](ULONG& res) {
[&](ULONG& res) { res = (info_class == ProcessDebugFlags ? 1 : 0); //
res = (info_class == ProcessDebugFlags ? 1 : 0); // });
});
case ProcessDebugPort: case ProcessDebugPort:
case ProcessDeviceMap: case ProcessDeviceMap:
return handle_query<EmulatorTraits<Emu64>::PVOID>(c.emu, process_information, process_information_length, return handle_query<EmulatorTraits<Emu64>::PVOID>(c.emu, process_information, process_information_length, return_length,
return_length, [](EmulatorTraits<Emu64>::PVOID& ptr) { [](EmulatorTraits<Emu64>::PVOID& ptr) {
ptr = 0; // ptr = 0; //
}); });
case ProcessEnableAlignmentFaultFixup: case ProcessEnableAlignmentFaultFixup:
return handle_query<BOOLEAN>(c.emu, process_information, process_information_length, return_length, return handle_query<BOOLEAN>(c.emu, process_information, process_information_length, return_length, [](BOOLEAN& b) {
[](BOOLEAN& b) { b = FALSE; //
b = FALSE; // });
});
case ProcessBasicInformation: case ProcessBasicInformation:
return handle_query<PROCESS_BASIC_INFORMATION64>(c.emu, process_information, process_information_length, return handle_query<PROCESS_BASIC_INFORMATION64>(c.emu, process_information, process_information_length, return_length,
return_length,
[&](PROCESS_BASIC_INFORMATION64& basic_info) { [&](PROCESS_BASIC_INFORMATION64& basic_info) {
basic_info.PebBaseAddress = c.proc.peb.value(); basic_info.PebBaseAddress = c.proc.peb.value();
basic_info.UniqueProcessId = 1; basic_info.UniqueProcessId = 1;
@@ -80,8 +74,7 @@ namespace syscalls
const emulator_object<PEDosHeader_t> dos_header_obj{c.emu, mod.image_base}; const emulator_object<PEDosHeader_t> dos_header_obj{c.emu, mod.image_base};
const auto dos_header = dos_header_obj.read(); const auto dos_header = dos_header_obj.read();
const emulator_object<PENTHeaders_t<uint64_t>> nt_headers_obj{c.emu, const emulator_object<PENTHeaders_t<uint64_t>> nt_headers_obj{c.emu, mod.image_base + dos_header.e_lfanew};
mod.image_base + dos_header.e_lfanew};
const auto nt_headers = nt_headers_obj.read(); const auto nt_headers = nt_headers_obj.read();
const auto& file_header = nt_headers.FileHeader; const auto& file_header = nt_headers.FileHeader;
@@ -123,8 +116,7 @@ namespace syscalls
const emulator_object<UNICODE_STRING<EmulatorTraits<Emu64>>> info{c.emu, process_information}; const emulator_object<UNICODE_STRING<EmulatorTraits<Emu64>>> info{c.emu, process_information};
info.access([&](UNICODE_STRING<EmulatorTraits<Emu64>>& str) { info.access([&](UNICODE_STRING<EmulatorTraits<Emu64>>& str) {
const auto buffer_start = const auto buffer_start = static_cast<uint64_t>(process_information) + sizeof(UNICODE_STRING<EmulatorTraits<Emu64>>);
static_cast<uint64_t>(process_information) + sizeof(UNICODE_STRING<EmulatorTraits<Emu64>>);
const auto string = read_unicode_string(c.emu, params.ImagePathName); const auto string = read_unicode_string(c.emu, params.ImagePathName);
c.emu.write_memory(buffer_start, string.c_str(), (string.size() + 1) * 2); c.emu.write_memory(buffer_start, string.c_str(), (string.size() + 1) * 2);
str.Length = params.ImagePathName.Length; str.Length = params.ImagePathName.Length;
@@ -143,9 +135,8 @@ namespace syscalls
} }
} }
NTSTATUS handle_NtSetInformationProcess(const syscall_context& c, const handle process_handle, NTSTATUS handle_NtSetInformationProcess(const syscall_context& c, const handle process_handle, const uint32_t info_class,
const uint32_t info_class, const uint64_t process_information, const uint64_t process_information, const uint32_t process_information_length)
const uint32_t process_information_length)
{ {
if (process_handle != CURRENT_PROCESS) if (process_handle != CURRENT_PROCESS)
{ {
@@ -243,8 +234,8 @@ namespace syscalls
return STATUS_NOT_SUPPORTED; return STATUS_NOT_SUPPORTED;
} }
NTSTATUS handle_NtOpenProcessToken(const syscall_context&, const handle process_handle, NTSTATUS handle_NtOpenProcessToken(const syscall_context&, const handle process_handle, const ACCESS_MASK /*desired_access*/,
const ACCESS_MASK /*desired_access*/, const emulator_object<handle> token_handle) const emulator_object<handle> token_handle)
{ {
if (process_handle != CURRENT_PROCESS) if (process_handle != CURRENT_PROCESS)
{ {
@@ -256,9 +247,8 @@ namespace syscalls
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
NTSTATUS handle_NtOpenProcessTokenEx(const syscall_context& c, const handle process_handle, NTSTATUS handle_NtOpenProcessTokenEx(const syscall_context& c, const handle process_handle, const ACCESS_MASK desired_access,
const ACCESS_MASK desired_access, const ULONG /*handle_attributes*/, const ULONG /*handle_attributes*/, const emulator_object<handle> token_handle)
const emulator_object<handle> token_handle)
{ {
return handle_NtOpenProcessToken(c, process_handle, desired_access, token_handle); return handle_NtOpenProcessToken(c, process_handle, desired_access, token_handle);
} }

View File

@@ -6,8 +6,7 @@
namespace syscalls namespace syscalls
{ {
NTSTATUS handle_NtOpenKey(const syscall_context& c, const emulator_object<handle> key_handle, NTSTATUS handle_NtOpenKey(const syscall_context& c, const emulator_object<handle> key_handle, const ACCESS_MASK /*desired_access*/,
const ACCESS_MASK /*desired_access*/,
const emulator_object<OBJECT_ATTRIBUTES<EmulatorTraits<Emu64>>> object_attributes) const emulator_object<OBJECT_ATTRIBUTES<EmulatorTraits<Emu64>>> object_attributes)
{ {
const auto attributes = object_attributes.read(); const auto attributes = object_attributes.read();
@@ -39,17 +38,14 @@ namespace syscalls
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
NTSTATUS handle_NtOpenKeyEx(const syscall_context& c, const emulator_object<handle> key_handle, NTSTATUS handle_NtOpenKeyEx(const syscall_context& c, const emulator_object<handle> key_handle, const ACCESS_MASK desired_access,
const ACCESS_MASK desired_access, const emulator_object<OBJECT_ATTRIBUTES<EmulatorTraits<Emu64>>> object_attributes, ULONG /*open_options*/)
const emulator_object<OBJECT_ATTRIBUTES<EmulatorTraits<Emu64>>> object_attributes,
ULONG /*open_options*/)
{ {
return handle_NtOpenKey(c, key_handle, desired_access, object_attributes); return handle_NtOpenKey(c, key_handle, desired_access, object_attributes);
} }
NTSTATUS handle_NtQueryKey(const syscall_context& c, const handle key_handle, NTSTATUS handle_NtQueryKey(const syscall_context& c, const handle key_handle, const KEY_INFORMATION_CLASS key_information_class,
const KEY_INFORMATION_CLASS key_information_class, const uint64_t key_information, const uint64_t key_information, const ULONG length, const emulator_object<ULONG> result_length)
const ULONG length, const emulator_object<ULONG> result_length)
{ {
const auto* key = c.proc.registry_keys.get(key_handle); const auto* key = c.proc.registry_keys.get(key_handle);
if (!key) if (!key)
@@ -81,8 +77,7 @@ namespace syscalls
const emulator_object<KEY_NAME_INFORMATION> info_obj{c.emu, key_information}; const emulator_object<KEY_NAME_INFORMATION> info_obj{c.emu, key_information};
info_obj.write(info); info_obj.write(info);
c.emu.write_memory(key_information + offsetof(KEY_NAME_INFORMATION, Name), key_name.data(), c.emu.write_memory(key_information + offsetof(KEY_NAME_INFORMATION, Name), key_name.data(), info.NameLength);
info.NameLength);
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
@@ -118,9 +113,8 @@ namespace syscalls
NTSTATUS handle_NtQueryValueKey(const syscall_context& c, const handle key_handle, NTSTATUS handle_NtQueryValueKey(const syscall_context& c, const handle key_handle,
const emulator_object<UNICODE_STRING<EmulatorTraits<Emu64>>> value_name, const emulator_object<UNICODE_STRING<EmulatorTraits<Emu64>>> value_name,
const KEY_VALUE_INFORMATION_CLASS key_value_information_class, const KEY_VALUE_INFORMATION_CLASS key_value_information_class, const uint64_t key_value_information,
const uint64_t key_value_information, const ULONG length, const ULONG length, const emulator_object<ULONG> result_length)
const emulator_object<ULONG> result_length)
{ {
const auto* key = c.proc.registry_keys.get(key_handle); const auto* key = c.proc.registry_keys.get(key_handle);
if (!key) if (!key)
@@ -222,8 +216,7 @@ namespace syscalls
c.emu.write_memory(key_value_information + base_size, original_name.data(), info.NameLength); c.emu.write_memory(key_value_information + base_size, original_name.data(), info.NameLength);
c.emu.write_memory(key_value_information + base_size + info.NameLength, value->data.data(), c.emu.write_memory(key_value_information + base_size + info.NameLength, value->data.data(), value->data.size());
value->data.size());
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
@@ -233,11 +226,9 @@ namespace syscalls
return STATUS_NOT_SUPPORTED; return STATUS_NOT_SUPPORTED;
} }
NTSTATUS handle_NtCreateKey(const syscall_context& c, const emulator_object<handle> key_handle, NTSTATUS handle_NtCreateKey(const syscall_context& c, const emulator_object<handle> key_handle, const ACCESS_MASK desired_access,
const ACCESS_MASK desired_access,
const emulator_object<OBJECT_ATTRIBUTES<EmulatorTraits<Emu64>>> object_attributes, const emulator_object<OBJECT_ATTRIBUTES<EmulatorTraits<Emu64>>> object_attributes,
const ULONG /*title_index*/, const ULONG /*title_index*/, const emulator_object<UNICODE_STRING<EmulatorTraits<Emu64>>> /*class*/,
const emulator_object<UNICODE_STRING<EmulatorTraits<Emu64>>> /*class*/,
const ULONG /*create_options*/, const emulator_object<ULONG> /*disposition*/) const ULONG /*create_options*/, const emulator_object<ULONG> /*disposition*/)
{ {
const auto result = handle_NtOpenKey(c, key_handle, desired_access, object_attributes); const auto result = handle_NtOpenKey(c, key_handle, desired_access, object_attributes);
@@ -261,8 +252,8 @@ namespace syscalls
} }
NTSTATUS handle_NtEnumerateKey(const syscall_context& c, const handle key_handle, const ULONG index, NTSTATUS handle_NtEnumerateKey(const syscall_context& c, const handle key_handle, const ULONG index,
const KEY_INFORMATION_CLASS key_information_class, const uint64_t key_information, const KEY_INFORMATION_CLASS key_information_class, const uint64_t key_information, const ULONG length,
const ULONG length, const emulator_object<ULONG> result_length) const emulator_object<ULONG> result_length)
{ {
const auto* key = c.proc.registry_keys.get(key_handle); const auto* key = c.proc.registry_keys.get(key_handle);
if (!key) if (!key)
@@ -341,9 +332,8 @@ namespace syscalls
} }
NTSTATUS handle_NtEnumerateValueKey(const syscall_context& c, const handle key_handle, const ULONG index, NTSTATUS handle_NtEnumerateValueKey(const syscall_context& c, const handle key_handle, const ULONG index,
const KEY_VALUE_INFORMATION_CLASS key_value_information_class, const KEY_VALUE_INFORMATION_CLASS key_value_information_class, const uint64_t key_value_information,
const uint64_t key_value_information, const ULONG length, const ULONG length, const emulator_object<ULONG> result_length)
const emulator_object<ULONG> result_length)
{ {
const auto* key = c.proc.registry_keys.get(key_handle); const auto* key = c.proc.registry_keys.get(key_handle);
if (!key) if (!key)

View File

@@ -9,9 +9,8 @@ namespace syscalls
NTSTATUS handle_NtCreateSection(const syscall_context& c, const emulator_object<handle> section_handle, NTSTATUS handle_NtCreateSection(const syscall_context& c, const emulator_object<handle> section_handle,
const ACCESS_MASK /*desired_access*/, const ACCESS_MASK /*desired_access*/,
const emulator_object<OBJECT_ATTRIBUTES<EmulatorTraits<Emu64>>> object_attributes, const emulator_object<OBJECT_ATTRIBUTES<EmulatorTraits<Emu64>>> object_attributes,
const emulator_object<ULARGE_INTEGER> maximum_size, const emulator_object<ULARGE_INTEGER> maximum_size, const ULONG section_page_protection,
const ULONG section_page_protection, const ULONG allocation_attributes, const ULONG allocation_attributes, const handle file_handle)
const handle file_handle)
{ {
section s{}; section s{};
s.section_page_protection = section_page_protection; s.section_page_protection = section_page_protection;
@@ -96,8 +95,7 @@ namespace syscalls
return STATUS_NOT_SUPPORTED; return STATUS_NOT_SUPPORTED;
} }
if (attributes.RootDirectory != KNOWN_DLLS_DIRECTORY && if (attributes.RootDirectory != KNOWN_DLLS_DIRECTORY && attributes.RootDirectory != BASE_NAMED_OBJECTS_DIRECTORY)
attributes.RootDirectory != BASE_NAMED_OBJECTS_DIRECTORY)
{ {
c.win_emu.log.error("Unsupported section\n"); c.win_emu.log.error("Unsupported section\n");
c.emu.stop(); c.emu.stop();
@@ -118,14 +116,14 @@ namespace syscalls
return STATUS_OBJECT_NAME_NOT_FOUND; return STATUS_OBJECT_NAME_NOT_FOUND;
} }
NTSTATUS handle_NtMapViewOfSection( NTSTATUS handle_NtMapViewOfSection(const syscall_context& c, const handle section_handle, const handle process_handle,
const syscall_context& c, const handle section_handle, const handle process_handle, const emulator_object<uint64_t> base_address,
const emulator_object<uint64_t> base_address, const EMULATOR_CAST(EmulatorTraits<Emu64>::ULONG_PTR, ULONG_PTR) /*zero_bits*/,
const EMULATOR_CAST(EmulatorTraits<Emu64>::ULONG_PTR, ULONG_PTR) /*zero_bits*/, const EMULATOR_CAST(EmulatorTraits<Emu64>::SIZE_T, SIZE_T) /*commit_size*/,
const EMULATOR_CAST(EmulatorTraits<Emu64>::SIZE_T, SIZE_T) /*commit_size*/, const emulator_object<LARGE_INTEGER> /*section_offset*/,
const emulator_object<LARGE_INTEGER> /*section_offset*/, const emulator_object<EMULATOR_CAST(EmulatorTraits<Emu64>::SIZE_T, SIZE_T)> view_size,
const emulator_object<EMULATOR_CAST(EmulatorTraits<Emu64>::SIZE_T, SIZE_T)> view_size, const SECTION_INHERIT /*inherit_disposition*/, const ULONG /*allocation_type*/,
const SECTION_INHERIT /*inherit_disposition*/, const ULONG /*allocation_type*/, const ULONG /*win32_protect*/) const ULONG /*win32_protect*/)
{ {
if (process_handle != CURRENT_PROCESS) if (process_handle != CURRENT_PROCESS)
{ {
@@ -155,15 +153,13 @@ namespace syscalls
ucs.MaximumLength = ucs.Length; ucs.MaximumLength = ucs.Length;
}); });
const emulator_object<UNICODE_STRING<EmulatorTraits<Emu64>>> sysdir_obj{c.emu, windir_obj.value() + const emulator_object<UNICODE_STRING<EmulatorTraits<Emu64>>> sysdir_obj{c.emu, windir_obj.value() + windir_obj.size()};
windir_obj.size()};
sysdir_obj.access([&](UNICODE_STRING<EmulatorTraits<Emu64>>& ucs) { sysdir_obj.access([&](UNICODE_STRING<EmulatorTraits<Emu64>>& ucs) {
c.proc.base_allocator.make_unicode_string(ucs, u"C:\\WINDOWS\\System32"); c.proc.base_allocator.make_unicode_string(ucs, u"C:\\WINDOWS\\System32");
ucs.Buffer = ucs.Buffer - obj_address; ucs.Buffer = ucs.Buffer - obj_address;
}); });
const emulator_object<UNICODE_STRING<EmulatorTraits<Emu64>>> base_dir_obj{c.emu, sysdir_obj.value() + const emulator_object<UNICODE_STRING<EmulatorTraits<Emu64>>> base_dir_obj{c.emu, sysdir_obj.value() + sysdir_obj.size()};
sysdir_obj.size()};
base_dir_obj.access([&](UNICODE_STRING<EmulatorTraits<Emu64>>& ucs) { base_dir_obj.access([&](UNICODE_STRING<EmulatorTraits<Emu64>>& ucs) {
c.proc.base_allocator.make_unicode_string(ucs, u"\\Sessions\\1\\BaseNamedObjects"); c.proc.base_allocator.make_unicode_string(ucs, u"\\Sessions\\1\\BaseNamedObjects");
ucs.Buffer = ucs.Buffer - obj_address; ucs.Buffer = ucs.Buffer - obj_address;
@@ -257,8 +253,7 @@ namespace syscalls
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
NTSTATUS handle_NtUnmapViewOfSection(const syscall_context& c, const handle process_handle, NTSTATUS handle_NtUnmapViewOfSection(const syscall_context& c, const handle process_handle, const uint64_t base_address)
const uint64_t base_address)
{ {
if (process_handle != CURRENT_PROCESS) if (process_handle != CURRENT_PROCESS)
{ {
@@ -305,8 +300,8 @@ namespace syscalls
return STATUS_NOT_SUPPORTED; return STATUS_NOT_SUPPORTED;
} }
NTSTATUS handle_NtUnmapViewOfSectionEx(const syscall_context& c, const handle process_handle, NTSTATUS handle_NtUnmapViewOfSectionEx(const syscall_context& c, const handle process_handle, const uint64_t base_address,
const uint64_t base_address, const ULONG /*flags*/) const ULONG /*flags*/)
{ {
return handle_NtUnmapViewOfSection(c, process_handle, base_address); return handle_NtUnmapViewOfSection(c, process_handle, base_address);
} }

View File

@@ -19,8 +19,7 @@ namespace syscalls
return STATUS_INVALID_PARAMETER; return STATUS_INVALID_PARAMETER;
} }
const auto name = read_unicode_string( const auto name = read_unicode_string(c.emu, emulator_object<UNICODE_STRING<EmulatorTraits<Emu64>>>{c.emu, attributes.ObjectName});
c.emu, emulator_object<UNICODE_STRING<EmulatorTraits<Emu64>>>{c.emu, attributes.ObjectName});
if (name.empty()) if (name.empty())
{ {
return STATUS_INVALID_PARAMETER; return STATUS_INVALID_PARAMETER;
@@ -38,8 +37,8 @@ namespace syscalls
return STATUS_OBJECT_NAME_NOT_FOUND; return STATUS_OBJECT_NAME_NOT_FOUND;
} }
NTSTATUS handle_NtReleaseSemaphore(const syscall_context& c, const handle semaphore_handle, NTSTATUS handle_NtReleaseSemaphore(const syscall_context& c, const handle semaphore_handle, const ULONG release_count,
const ULONG release_count, const emulator_object<LONG> previous_count) const emulator_object<LONG> previous_count)
{ {
if (semaphore_handle.value.type != handle_types::semaphore) if (semaphore_handle.value.type != handle_types::semaphore)
{ {

View File

@@ -7,8 +7,7 @@ namespace syscalls
namespace namespace
{ {
NTSTATUS handle_logical_processor_and_group_information(const syscall_context& c, const uint64_t input_buffer, NTSTATUS handle_logical_processor_and_group_information(const syscall_context& c, const uint64_t input_buffer,
const uint32_t input_buffer_length, const uint32_t input_buffer_length, const uint64_t system_information,
const uint64_t system_information,
const uint32_t system_information_length, const uint32_t system_information_length,
const emulator_object<uint32_t> return_length) const emulator_object<uint32_t> return_length)
{ {
@@ -87,11 +86,9 @@ namespace syscalls
} }
} }
NTSTATUS handle_NtQuerySystemInformationEx(const syscall_context& c, const uint32_t info_class, NTSTATUS handle_NtQuerySystemInformationEx(const syscall_context& c, const uint32_t info_class, const uint64_t input_buffer,
const uint64_t input_buffer, const uint32_t input_buffer_length, const uint32_t input_buffer_length, const uint64_t system_information,
const uint64_t system_information, const uint32_t system_information_length, const emulator_object<uint32_t> return_length)
const uint32_t system_information_length,
const emulator_object<uint32_t> return_length)
{ {
switch (info_class) switch (info_class)
{ {
@@ -113,8 +110,7 @@ namespace syscalls
return STATUS_NOT_SUPPORTED; return STATUS_NOT_SUPPORTED;
case SystemTimeOfDayInformation: case SystemTimeOfDayInformation:
return handle_query<SYSTEM_TIMEOFDAY_INFORMATION64>(c.emu, system_information, system_information_length, return handle_query<SYSTEM_TIMEOFDAY_INFORMATION64>(c.emu, system_information, system_information_length, return_length,
return_length,
[&](SYSTEM_TIMEOFDAY_INFORMATION64& info) { [&](SYSTEM_TIMEOFDAY_INFORMATION64& info) {
memset(&info, 0, sizeof(info)); memset(&info, 0, sizeof(info));
info.BootTime.QuadPart = 0; info.BootTime.QuadPart = 0;
@@ -125,8 +121,7 @@ namespace syscalls
case SystemTimeZoneInformation: case SystemTimeZoneInformation:
case SystemCurrentTimeZoneInformation: case SystemCurrentTimeZoneInformation:
return handle_query<SYSTEM_TIMEZONE_INFORMATION>( return handle_query<SYSTEM_TIMEZONE_INFORMATION>(
c.emu, system_information, system_information_length, return_length, c.emu, system_information, system_information_length, return_length, [&](SYSTEM_TIMEZONE_INFORMATION& tzi) {
[&](SYSTEM_TIMEZONE_INFORMATION& tzi) {
memset(&tzi, 0, sizeof(tzi)); memset(&tzi, 0, sizeof(tzi));
tzi.Bias = -60; tzi.Bias = -60;
@@ -160,8 +155,7 @@ namespace syscalls
case SystemDynamicTimeZoneInformation: case SystemDynamicTimeZoneInformation:
return handle_query<SYSTEM_DYNAMIC_TIMEZONE_INFORMATION>( return handle_query<SYSTEM_DYNAMIC_TIMEZONE_INFORMATION>(
c.emu, system_information, system_information_length, return_length, c.emu, system_information, system_information_length, return_length, [&](SYSTEM_DYNAMIC_TIMEZONE_INFORMATION& dtzi) {
[&](SYSTEM_DYNAMIC_TIMEZONE_INFORMATION& dtzi) {
memset(&dtzi, 0, sizeof(dtzi)); memset(&dtzi, 0, sizeof(dtzi));
dtzi.Bias = -60; dtzi.Bias = -60;
@@ -199,24 +193,22 @@ namespace syscalls
}); });
case SystemRangeStartInformation: case SystemRangeStartInformation:
return handle_query<SYSTEM_RANGE_START_INFORMATION64>(c.emu, system_information, system_information_length, return handle_query<SYSTEM_RANGE_START_INFORMATION64>(c.emu, system_information, system_information_length, return_length,
return_length,
[&](SYSTEM_RANGE_START_INFORMATION64& info) { [&](SYSTEM_RANGE_START_INFORMATION64& info) {
info.SystemRangeStart = 0xFFFF800000000000; // info.SystemRangeStart = 0xFFFF800000000000; //
}); });
case SystemProcessorInformation: case SystemProcessorInformation:
return handle_query<SYSTEM_PROCESSOR_INFORMATION64>( return handle_query<SYSTEM_PROCESSOR_INFORMATION64>(c.emu, system_information, system_information_length, return_length,
c.emu, system_information, system_information_length, return_length, [&](SYSTEM_PROCESSOR_INFORMATION64& info) {
[&](SYSTEM_PROCESSOR_INFORMATION64& info) { memset(&info, 0, sizeof(info));
memset(&info, 0, sizeof(info)); info.MaximumProcessors = 2;
info.MaximumProcessors = 2; info.ProcessorArchitecture = PROCESSOR_ARCHITECTURE_AMD64;
info.ProcessorArchitecture = PROCESSOR_ARCHITECTURE_AMD64; });
});
case SystemNumaProcessorMap: case SystemNumaProcessorMap:
return handle_query<SYSTEM_NUMA_INFORMATION64>(c.emu, system_information, system_information_length, return handle_query<SYSTEM_NUMA_INFORMATION64>(c.emu, system_information, system_information_length, return_length,
return_length, [&](SYSTEM_NUMA_INFORMATION64& info) { [&](SYSTEM_NUMA_INFORMATION64& info) {
memset(&info, 0, sizeof(info)); memset(&info, 0, sizeof(info));
info.ActiveProcessorsGroupAffinity->Mask = 0xFFF; info.ActiveProcessorsGroupAffinity->Mask = 0xFFF;
info.AvailableMemory[0] = 0xFFF; info.AvailableMemory[0] = 0xFFF;
@@ -224,23 +216,22 @@ namespace syscalls
}); });
case SystemErrorPortTimeouts: case SystemErrorPortTimeouts:
return handle_query<SYSTEM_ERROR_PORT_TIMEOUTS>(c.emu, system_information, system_information_length, return handle_query<SYSTEM_ERROR_PORT_TIMEOUTS>(c.emu, system_information, system_information_length, return_length,
return_length, [&](SYSTEM_ERROR_PORT_TIMEOUTS& info) { [&](SYSTEM_ERROR_PORT_TIMEOUTS& info) {
info.StartTimeout = 0; info.StartTimeout = 0;
info.CommTimeout = 0; info.CommTimeout = 0;
}); });
case SystemKernelDebuggerInformation: case SystemKernelDebuggerInformation:
return handle_query<SYSTEM_KERNEL_DEBUGGER_INFORMATION>(c.emu, system_information, return handle_query<SYSTEM_KERNEL_DEBUGGER_INFORMATION>(c.emu, system_information, system_information_length, return_length,
system_information_length, return_length,
[&](SYSTEM_KERNEL_DEBUGGER_INFORMATION& info) { [&](SYSTEM_KERNEL_DEBUGGER_INFORMATION& info) {
info.KernelDebuggerEnabled = FALSE; info.KernelDebuggerEnabled = FALSE;
info.KernelDebuggerNotPresent = TRUE; info.KernelDebuggerNotPresent = TRUE;
}); });
case SystemLogicalProcessorAndGroupInformation: case SystemLogicalProcessorAndGroupInformation:
return handle_logical_processor_and_group_information( return handle_logical_processor_and_group_information(c, input_buffer, input_buffer_length, system_information,
c, input_buffer, input_buffer_length, system_information, system_information_length, return_length); system_information_length, return_length);
case SystemLogicalProcessorInformation: { case SystemLogicalProcessorInformation: {
if (!input_buffer || input_buffer_length != sizeof(USHORT)) if (!input_buffer || input_buffer_length != sizeof(USHORT))
@@ -252,35 +243,33 @@ namespace syscalls
const auto processor_group = c.emu.read_memory<USHORT>(input_buffer); const auto processor_group = c.emu.read_memory<USHORT>(input_buffer);
return handle_query<info_type>( return handle_query<info_type>(c.emu, system_information, system_information_length, return_length, [&](info_type& info) {
c.emu, system_information, system_information_length, return_length, [&](info_type& info) { info.Relationship = RelationProcessorCore;
info.Relationship = RelationProcessorCore;
if (processor_group == 0) if (processor_group == 0)
{ {
using mask_type = decltype(info.ProcessorMask); using mask_type = decltype(info.ProcessorMask);
const auto active_processor_count = c.proc.kusd.get().ActiveProcessorCount; const auto active_processor_count = c.proc.kusd.get().ActiveProcessorCount;
info.ProcessorMask = (static_cast<mask_type>(1) << active_processor_count) - 1; info.ProcessorMask = (static_cast<mask_type>(1) << active_processor_count) - 1;
} }
}); });
} }
case SystemBasicInformation: case SystemBasicInformation:
case SystemEmulationBasicInformation: case SystemEmulationBasicInformation:
return handle_query<SYSTEM_BASIC_INFORMATION64>( return handle_query<SYSTEM_BASIC_INFORMATION64>(c.emu, system_information, system_information_length, return_length,
c.emu, system_information, system_information_length, return_length, [&](SYSTEM_BASIC_INFORMATION64& basic_info) {
[&](SYSTEM_BASIC_INFORMATION64& basic_info) { basic_info.Reserved = 0;
basic_info.Reserved = 0; basic_info.TimerResolution = 0x0002625a;
basic_info.TimerResolution = 0x0002625a; basic_info.PageSize = 0x1000;
basic_info.PageSize = 0x1000; basic_info.LowestPhysicalPageNumber = 0x00000001;
basic_info.LowestPhysicalPageNumber = 0x00000001; basic_info.HighestPhysicalPageNumber = 0x00c9c7ff;
basic_info.HighestPhysicalPageNumber = 0x00c9c7ff; basic_info.AllocationGranularity = ALLOCATION_GRANULARITY;
basic_info.AllocationGranularity = ALLOCATION_GRANULARITY; basic_info.MinimumUserModeAddress = MIN_ALLOCATION_ADDRESS;
basic_info.MinimumUserModeAddress = MIN_ALLOCATION_ADDRESS; basic_info.MaximumUserModeAddress = MAX_ALLOCATION_ADDRESS;
basic_info.MaximumUserModeAddress = MAX_ALLOCATION_ADDRESS; basic_info.ActiveProcessorsAffinityMask = 0x0000000000000fff;
basic_info.ActiveProcessorsAffinityMask = 0x0000000000000fff; basic_info.NumberOfProcessors = 1;
basic_info.NumberOfProcessors = 1; });
});
default: default:
c.win_emu.log.error("Unsupported system info class: %X\n", info_class); c.win_emu.log.error("Unsupported system info class: %X\n", info_class);
@@ -289,13 +278,10 @@ namespace syscalls
} }
} }
NTSTATUS handle_NtQuerySystemInformation(const syscall_context& c, const uint32_t info_class, NTSTATUS handle_NtQuerySystemInformation(const syscall_context& c, const uint32_t info_class, const uint64_t system_information,
const uint64_t system_information, const uint32_t system_information_length, const emulator_object<uint32_t> return_length)
const uint32_t system_information_length,
const emulator_object<uint32_t> return_length)
{ {
return handle_NtQuerySystemInformationEx(c, info_class, 0, 0, system_information, system_information_length, return handle_NtQuerySystemInformationEx(c, info_class, 0, 0, system_information, system_information_length, return_length);
return_length);
} }
NTSTATUS handle_NtSetSystemInformation() NTSTATUS handle_NtSetSystemInformation()

View File

@@ -7,9 +7,8 @@
namespace syscalls namespace syscalls
{ {
NTSTATUS handle_NtSetInformationThread(const syscall_context& c, const handle thread_handle, NTSTATUS handle_NtSetInformationThread(const syscall_context& c, const handle thread_handle, const THREADINFOCLASS info_class,
const THREADINFOCLASS info_class, const uint64_t thread_information, const uint64_t thread_information, const uint32_t thread_information_length)
const uint32_t thread_information_length)
{ {
auto* thread = thread_handle == CURRENT_THREAD ? c.proc.active_thread : c.proc.threads.get(thread_handle); auto* thread = thread_handle == CURRENT_THREAD ? c.proc.active_thread : c.proc.threads.get(thread_handle);
@@ -18,8 +17,7 @@ namespace syscalls
return STATUS_INVALID_HANDLE; return STATUS_INVALID_HANDLE;
} }
if (info_class == ThreadSchedulerSharedDataSlot || info_class == ThreadBasePriority || if (info_class == ThreadSchedulerSharedDataSlot || info_class == ThreadBasePriority || info_class == ThreadAffinityMask)
info_class == ThreadAffinityMask)
{ {
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
@@ -91,9 +89,8 @@ namespace syscalls
return STATUS_NOT_SUPPORTED; return STATUS_NOT_SUPPORTED;
} }
NTSTATUS handle_NtQueryInformationThread(const syscall_context& c, const handle thread_handle, NTSTATUS handle_NtQueryInformationThread(const syscall_context& c, const handle thread_handle, const uint32_t info_class,
const uint32_t info_class, const uint64_t thread_information, const uint64_t thread_information, const uint32_t thread_information_length,
const uint32_t thread_information_length,
const emulator_object<uint32_t> return_length) const emulator_object<uint32_t> return_length)
{ {
const auto* thread = thread_handle == CURRENT_THREAD ? c.proc.active_thread : c.proc.threads.get(thread_handle); const auto* thread = thread_handle == CURRENT_THREAD ? c.proc.active_thread : c.proc.threads.get(thread_handle);
@@ -246,9 +243,8 @@ namespace syscalls
return STATUS_NOT_SUPPORTED; return STATUS_NOT_SUPPORTED;
} }
NTSTATUS handle_NtOpenThreadToken(const syscall_context&, const handle thread_handle, NTSTATUS handle_NtOpenThreadToken(const syscall_context&, const handle thread_handle, const ACCESS_MASK /*desired_access*/,
const ACCESS_MASK /*desired_access*/, const BOOLEAN /*open_as_self*/, const BOOLEAN /*open_as_self*/, const emulator_object<handle> token_handle)
const emulator_object<handle> token_handle)
{ {
if (thread_handle != CURRENT_THREAD) if (thread_handle != CURRENT_THREAD)
{ {
@@ -260,9 +256,9 @@ namespace syscalls
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
NTSTATUS handle_NtOpenThreadTokenEx(const syscall_context& c, const handle thread_handle, NTSTATUS handle_NtOpenThreadTokenEx(const syscall_context& c, const handle thread_handle, const ACCESS_MASK desired_access,
const ACCESS_MASK desired_access, const BOOLEAN open_as_self, const BOOLEAN open_as_self, const ULONG /*handle_attributes*/,
const ULONG /*handle_attributes*/, const emulator_object<handle> token_handle) const emulator_object<handle> token_handle)
{ {
return handle_NtOpenThreadToken(c, thread_handle, desired_access, open_as_self, token_handle); return handle_NtOpenThreadToken(c, thread_handle, desired_access, open_as_self, token_handle);
} }
@@ -304,8 +300,7 @@ namespace syscalls
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
NTSTATUS handle_NtDelayExecution(const syscall_context& c, const BOOLEAN alertable, NTSTATUS handle_NtDelayExecution(const syscall_context& c, const BOOLEAN alertable, const emulator_object<LARGE_INTEGER> delay_interval)
const emulator_object<LARGE_INTEGER> delay_interval)
{ {
auto& t = c.win_emu.current_thread(); auto& t = c.win_emu.current_thread();
t.await_time = utils::convert_delay_interval_to_time_point(c.win_emu.clock(), delay_interval.read()); t.await_time = utils::convert_delay_interval_to_time_point(c.win_emu.clock(), delay_interval.read());
@@ -342,8 +337,7 @@ namespace syscalls
return handle_NtAlertThreadByThreadId(c, thread_id); return handle_NtAlertThreadByThreadId(c, thread_id);
} }
NTSTATUS handle_NtWaitForAlertByThreadId(const syscall_context& c, const uint64_t, NTSTATUS handle_NtWaitForAlertByThreadId(const syscall_context& c, const uint64_t, const emulator_object<LARGE_INTEGER> timeout)
const emulator_object<LARGE_INTEGER> timeout)
{ {
auto& t = c.win_emu.current_thread(); auto& t = c.win_emu.current_thread();
t.waiting_for_alert = true; t.waiting_for_alert = true;
@@ -413,15 +407,14 @@ namespace syscalls
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
NTSTATUS handle_NtContinue(const syscall_context& c, const emulator_object<CONTEXT64> thread_context, NTSTATUS handle_NtContinue(const syscall_context& c, const emulator_object<CONTEXT64> thread_context, const BOOLEAN raise_alert)
const BOOLEAN raise_alert)
{ {
return handle_NtContinueEx(c, thread_context, raise_alert ? 1 : 0); return handle_NtContinueEx(c, thread_context, raise_alert ? 1 : 0);
} }
NTSTATUS handle_NtGetNextThread(const syscall_context& c, const handle process_handle, const handle thread_handle, NTSTATUS handle_NtGetNextThread(const syscall_context& c, const handle process_handle, const handle thread_handle,
const ACCESS_MASK /*desired_access*/, const ULONG /*handle_attributes*/, const ACCESS_MASK /*desired_access*/, const ULONG /*handle_attributes*/, const ULONG flags,
const ULONG flags, const emulator_object<handle> new_thread_handle) const emulator_object<handle> new_thread_handle)
{ {
if (process_handle != CURRENT_PROCESS || thread_handle.value.type != handle_types::thread) if (process_handle != CURRENT_PROCESS || thread_handle.value.type != handle_types::thread)
{ {
@@ -535,8 +528,7 @@ namespace syscalls
return STATUS_NOT_SUPPORTED; return STATUS_NOT_SUPPORTED;
} }
const auto h = c.proc.create_thread(c.win_emu.memory, start_routine, argument, stack_size, const auto h = c.proc.create_thread(c.win_emu.memory, start_routine, argument, stack_size, create_flags & CREATE_SUSPENDED);
create_flags & CREATE_SUSPENDED);
thread_handle.write(h); thread_handle.write(h);
if (!attribute_list) if (!attribute_list)
@@ -581,8 +573,7 @@ namespace syscalls
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
NTSTATUS handle_NtGetCurrentProcessorNumberEx(const syscall_context&, NTSTATUS handle_NtGetCurrentProcessorNumberEx(const syscall_context&, const emulator_object<PROCESSOR_NUMBER> processor_number)
const emulator_object<PROCESSOR_NUMBER> processor_number)
{ {
constexpr PROCESSOR_NUMBER number{}; constexpr PROCESSOR_NUMBER number{};
processor_number.write(number); processor_number.write(number);
@@ -594,9 +585,8 @@ namespace syscalls
return 0; return 0;
} }
NTSTATUS handle_NtQueueApcThreadEx2(const syscall_context& c, const handle thread_handle, NTSTATUS handle_NtQueueApcThreadEx2(const syscall_context& c, const handle thread_handle, const handle /*reserve_handle*/,
const handle /*reserve_handle*/, const uint32_t apc_flags, const uint32_t apc_flags, const uint64_t apc_routine, const uint64_t apc_argument1,
const uint64_t apc_routine, const uint64_t apc_argument1,
const uint64_t apc_argument2, const uint64_t apc_argument3) const uint64_t apc_argument2, const uint64_t apc_argument3)
{ {
auto* thread = thread_handle == CURRENT_THREAD ? c.proc.active_thread : c.proc.threads.get(thread_handle); auto* thread = thread_handle == CURRENT_THREAD ? c.proc.active_thread : c.proc.threads.get(thread_handle);
@@ -624,9 +614,8 @@ namespace syscalls
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
NTSTATUS handle_NtQueueApcThreadEx(const syscall_context& c, const handle thread_handle, NTSTATUS handle_NtQueueApcThreadEx(const syscall_context& c, const handle thread_handle, const handle reserve_handle,
const handle reserve_handle, const uint64_t apc_routine, const uint64_t apc_routine, const uint64_t apc_argument1, const uint64_t apc_argument2,
const uint64_t apc_argument1, const uint64_t apc_argument2,
const uint64_t apc_argument3) const uint64_t apc_argument3)
{ {
uint32_t flags{0}; uint32_t flags{0};
@@ -638,15 +627,13 @@ namespace syscalls
static_assert(QUEUE_USER_APC_FLAGS_SPECIAL_USER_APC == 1); static_assert(QUEUE_USER_APC_FLAGS_SPECIAL_USER_APC == 1);
} }
return handle_NtQueueApcThreadEx2(c, thread_handle, real_reserve_handle, flags, apc_routine, apc_argument1, return handle_NtQueueApcThreadEx2(c, thread_handle, real_reserve_handle, flags, apc_routine, apc_argument1, apc_argument2,
apc_argument2, apc_argument3); apc_argument3);
} }
NTSTATUS handle_NtQueueApcThread(const syscall_context& c, const handle thread_handle, const uint64_t apc_routine, NTSTATUS handle_NtQueueApcThread(const syscall_context& c, const handle thread_handle, const uint64_t apc_routine,
const uint64_t apc_argument1, const uint64_t apc_argument2, const uint64_t apc_argument1, const uint64_t apc_argument2, const uint64_t apc_argument3)
const uint64_t apc_argument3)
{ {
return handle_NtQueueApcThreadEx(c, thread_handle, make_handle(0), apc_routine, apc_argument1, apc_argument2, return handle_NtQueueApcThreadEx(c, thread_handle, make_handle(0), apc_routine, apc_argument1, apc_argument2, apc_argument3);
apc_argument3);
} }
} }

View File

@@ -6,8 +6,7 @@
namespace syscalls namespace syscalls
{ {
NTSTATUS handle_NtQueryTimerResolution(const syscall_context&, const emulator_object<ULONG> maximum_time, NTSTATUS handle_NtQueryTimerResolution(const syscall_context&, const emulator_object<ULONG> maximum_time,
const emulator_object<ULONG> minimum_time, const emulator_object<ULONG> minimum_time, const emulator_object<ULONG> current_time)
const emulator_object<ULONG> current_time)
{ {
maximum_time.write_if_valid(0x0002625a); maximum_time.write_if_valid(0x0002625a);
minimum_time.write_if_valid(0x00001388); minimum_time.write_if_valid(0x00001388);
@@ -15,8 +14,8 @@ namespace syscalls
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
NTSTATUS handle_NtSetTimerResolution(const syscall_context&, const ULONG /*desired_resolution*/, NTSTATUS handle_NtSetTimerResolution(const syscall_context&, const ULONG /*desired_resolution*/, const BOOLEAN set_resolution,
const BOOLEAN set_resolution, const emulator_object<ULONG> current_resolution) const emulator_object<ULONG> current_resolution)
{ {
if (current_resolution) if (current_resolution)
{ {
@@ -31,10 +30,9 @@ namespace syscalls
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
NTSTATUS handle_NtCreateTimer2(const syscall_context& c, const emulator_object<handle> timer_handle, NTSTATUS handle_NtCreateTimer2(const syscall_context& c, const emulator_object<handle> timer_handle, uint64_t /*reserved*/,
uint64_t /*reserved*/, const emulator_object<OBJECT_ATTRIBUTES<EmulatorTraits<Emu64>>> object_attributes, ULONG /*attributes*/,
const emulator_object<OBJECT_ATTRIBUTES<EmulatorTraits<Emu64>>> object_attributes, ACCESS_MASK /*desired_access*/)
ULONG /*attributes*/, ACCESS_MASK /*desired_access*/)
{ {
std::u16string name{}; std::u16string name{};
if (object_attributes) if (object_attributes)
@@ -69,10 +67,8 @@ namespace syscalls
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
NTSTATUS handle_NtCreateTimer(const syscall_context& c, const emulator_object<handle> timer_handle, NTSTATUS handle_NtCreateTimer(const syscall_context& c, const emulator_object<handle> timer_handle, ACCESS_MASK desired_access,
ACCESS_MASK desired_access, const emulator_object<OBJECT_ATTRIBUTES<EmulatorTraits<Emu64>>> object_attributes, ULONG timer_type)
const emulator_object<OBJECT_ATTRIBUTES<EmulatorTraits<Emu64>>> object_attributes,
ULONG timer_type)
{ {
return handle_NtCreateTimer2(c, timer_handle, 0, object_attributes, timer_type, desired_access); return handle_NtCreateTimer2(c, timer_handle, 0, object_attributes, timer_type, desired_access);
} }
@@ -87,9 +83,8 @@ namespace syscalls
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
NTSTATUS handle_NtSetTimerEx(const syscall_context& /*c*/, handle /*timer_handle*/, NTSTATUS handle_NtSetTimerEx(const syscall_context& /*c*/, handle /*timer_handle*/, uint32_t /*timer_set_info_class*/,
uint32_t /*timer_set_info_class*/, uint64_t /*timer_set_information*/, uint64_t /*timer_set_information*/, ULONG /*timer_set_information_length*/)
ULONG /*timer_set_information_length*/)
{ {
return STATUS_NOT_SUPPORTED; return STATUS_NOT_SUPPORTED;
} }

View File

@@ -11,8 +11,7 @@ namespace syscalls
: TokenPrimary; : TokenPrimary;
} }
NTSTATUS handle_NtDuplicateToken(const syscall_context&, const handle existing_token_handle, NTSTATUS handle_NtDuplicateToken(const syscall_context&, const handle existing_token_handle, ACCESS_MASK /*desired_access*/,
ACCESS_MASK /*desired_access*/,
const emulator_object<OBJECT_ATTRIBUTES<EmulatorTraits<Emu64>>> const emulator_object<OBJECT_ATTRIBUTES<EmulatorTraits<Emu64>>>
/*object_attributes*/, /*object_attributes*/,
const BOOLEAN /*effective_only*/, const TOKEN_TYPE type, const BOOLEAN /*effective_only*/, const TOKEN_TYPE type,
@@ -35,9 +34,8 @@ namespace syscalls
} }
NTSTATUS handle_NtQueryInformationToken(const syscall_context& c, const handle token_handle, NTSTATUS handle_NtQueryInformationToken(const syscall_context& c, const handle token_handle,
const TOKEN_INFORMATION_CLASS token_information_class, const TOKEN_INFORMATION_CLASS token_information_class, const uint64_t token_information,
const uint64_t token_information, const ULONG token_information_length, const ULONG token_information_length, const emulator_object<ULONG> return_length)
const emulator_object<ULONG> return_length)
{ {
if (token_handle != CURRENT_PROCESS_TOKEN && token_handle != CURRENT_THREAD_TOKEN && if (token_handle != CURRENT_PROCESS_TOKEN && token_handle != CURRENT_THREAD_TOKEN &&
token_handle != CURRENT_THREAD_EFFECTIVE_TOKEN && token_handle != DUMMY_IMPERSONATION_TOKEN) token_handle != CURRENT_THREAD_EFFECTIVE_TOKEN && token_handle != DUMMY_IMPERSONATION_TOKEN)
@@ -270,8 +268,7 @@ namespace syscalls
TOKEN_STATISTICS stats{}; TOKEN_STATISTICS stats{};
stats.TokenType = get_token_type(token_handle); stats.TokenType = get_token_type(token_handle);
stats.ImpersonationLevel = stats.ImpersonationLevel = stats.TokenType == TokenImpersonation ? SecurityImpersonation : SecurityAnonymous;
stats.TokenType == TokenImpersonation ? SecurityImpersonation : SecurityAnonymous;
stats.GroupCount = 1; stats.GroupCount = 1;
stats.PrivilegeCount = 0; stats.PrivilegeCount = 0;
@@ -304,8 +301,7 @@ namespace syscalls
{ {
// NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
const uint8_t medium_integrity_sid[] = { const uint8_t medium_integrity_sid[] = {
0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x20, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
}; };
constexpr auto required_size = sizeof(medium_integrity_sid) + sizeof(TOKEN_MANDATORY_LABEL64); constexpr auto required_size = sizeof(medium_integrity_sid) + sizeof(TOKEN_MANDATORY_LABEL64);
@@ -321,8 +317,7 @@ namespace syscalls
label.Label.Sid = token_information + sizeof(TOKEN_MANDATORY_LABEL64); label.Label.Sid = token_information + sizeof(TOKEN_MANDATORY_LABEL64);
emulator_object<TOKEN_MANDATORY_LABEL64>{c.emu, token_information}.write(label); emulator_object<TOKEN_MANDATORY_LABEL64>{c.emu, token_information}.write(label);
c.emu.write_memory(token_information + sizeof(TOKEN_MANDATORY_LABEL64), medium_integrity_sid, c.emu.write_memory(token_information + sizeof(TOKEN_MANDATORY_LABEL64), medium_integrity_sid, sizeof(medium_integrity_sid));
sizeof(medium_integrity_sid));
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }

View File

@@ -254,8 +254,7 @@ namespace
} }
}; };
std::unique_ptr<utils::clock> get_clock(emulator_interfaces& interfaces, const uint64_t& instructions, std::unique_ptr<utils::clock> get_clock(emulator_interfaces& interfaces, const uint64_t& instructions, const bool use_relative_time)
const bool use_relative_time)
{ {
if (interfaces.clock) if (interfaces.clock)
{ {
@@ -285,16 +284,15 @@ namespace
} }
windows_emulator::windows_emulator(std::unique_ptr<x86_64_emulator> emu, application_settings app_settings, windows_emulator::windows_emulator(std::unique_ptr<x86_64_emulator> emu, application_settings app_settings,
const emulator_settings& settings, emulator_callbacks callbacks, const emulator_settings& settings, emulator_callbacks callbacks, emulator_interfaces interfaces)
emulator_interfaces interfaces)
: windows_emulator(std::move(emu), settings, std::move(callbacks), std::move(interfaces)) : windows_emulator(std::move(emu), settings, std::move(callbacks), std::move(interfaces))
{ {
fixup_application_settings(app_settings); fixup_application_settings(app_settings);
this->application_settings_ = std::move(app_settings); this->application_settings_ = std::move(app_settings);
} }
windows_emulator::windows_emulator(std::unique_ptr<x86_64_emulator> emu, const emulator_settings& settings, windows_emulator::windows_emulator(std::unique_ptr<x86_64_emulator> emu, const emulator_settings& settings, emulator_callbacks callbacks,
emulator_callbacks callbacks, emulator_interfaces interfaces) emulator_interfaces interfaces)
: emu_(std::move(emu)), : emu_(std::move(emu)),
clock_(get_clock(interfaces, this->executed_instructions_, settings.use_relative_time)), clock_(get_clock(interfaces, this->executed_instructions_, settings.use_relative_time)),
socket_factory_(get_socket_factory(interfaces)), socket_factory_(get_socket_factory(interfaces)),
@@ -347,8 +345,8 @@ void windows_emulator::setup_process(const application_settings& app_settings)
const auto& emu = this->emu(); const auto& emu = this->emu();
auto& context = this->process; auto& context = this->process;
this->mod_manager.map_main_modules(app_settings.application, R"(C:\Windows\System32\ntdll.dll)", this->mod_manager.map_main_modules(app_settings.application, R"(C:\Windows\System32\ntdll.dll)", R"(C:\Windows\System32\win32u.dll)",
R"(C:\Windows\System32\win32u.dll)", this->log); this->log);
const auto* executable = this->mod_manager.executable; const auto* executable = this->mod_manager.executable;
const auto* ntdll = this->mod_manager.ntdll; const auto* ntdll = this->mod_manager.ntdll;
@@ -363,8 +361,7 @@ void windows_emulator::setup_process(const application_settings& app_settings)
this->dispatcher.setup(ntdll->exports, ntdll_data, win32u->exports, win32u_data); this->dispatcher.setup(ntdll->exports, ntdll_data, win32u->exports, win32u_data);
const auto main_thread_id = const auto main_thread_id = context.create_thread(this->memory, this->mod_manager.executable->entry_point, 0, 0, false);
context.create_thread(this->memory, this->mod_manager.executable->entry_point, 0, 0, false);
switch_to_thread(*this, main_thread_id); switch_to_thread(*this, main_thread_id);
} }
@@ -504,24 +501,23 @@ void windows_emulator::setup_hooks()
} }
}); });
this->emu().hook_memory_violation([&](const uint64_t address, const size_t size, const memory_operation operation, this->emu().hook_memory_violation(
const memory_violation_type type) { [&](const uint64_t address, const size_t size, const memory_operation operation, const memory_violation_type type) {
auto region = this->memory.get_region_info(address); auto region = this->memory.get_region_info(address);
if (region.permissions.is_guarded()) if (region.permissions.is_guarded())
{ {
// Unset the GUARD_PAGE flag and dispatch a STATUS_GUARD_PAGE_VIOLATION // Unset the GUARD_PAGE flag and dispatch a STATUS_GUARD_PAGE_VIOLATION
this->memory.protect_memory(region.allocation_base, region.length, this->memory.protect_memory(region.allocation_base, region.length, region.permissions & ~memory_permission_ext::guard);
region.permissions & ~memory_permission_ext::guard); dispatch_guard_page_violation(this->emu(), this->process, address, operation);
dispatch_guard_page_violation(this->emu(), this->process, address, operation); }
} else
else {
{ this->callbacks.on_memory_violate(address, size, operation, type);
this->callbacks.on_memory_violate(address, size, operation, type); dispatch_access_violation(this->emu(), this->process, address, operation);
dispatch_access_violation(this->emu(), this->process, address, operation); }
}
return memory_violation_continuation::resume; return memory_violation_continuation::resume;
}); });
this->emu().hook_memory_execution([&](const uint64_t address) { this->emu().hook_memory_execution([&](const uint64_t address) {
this->on_instruction_execution(address); // this->on_instruction_execution(address); //

View File

@@ -98,11 +98,10 @@ class windows_emulator
process_context process; process_context process;
syscall_dispatcher dispatcher; syscall_dispatcher dispatcher;
windows_emulator(std::unique_ptr<x86_64_emulator> emu, const emulator_settings& settings = {}, windows_emulator(std::unique_ptr<x86_64_emulator> emu, const emulator_settings& settings = {}, emulator_callbacks callbacks = {},
emulator_callbacks callbacks = {}, emulator_interfaces interfaces = {});
windows_emulator(std::unique_ptr<x86_64_emulator> emu, application_settings app_settings,
const emulator_settings& settings = {}, emulator_callbacks callbacks = {},
emulator_interfaces interfaces = {}); emulator_interfaces interfaces = {});
windows_emulator(std::unique_ptr<x86_64_emulator> emu, application_settings app_settings, const emulator_settings& settings = {},
emulator_callbacks callbacks = {}, emulator_interfaces interfaces = {});
windows_emulator(windows_emulator&&) = delete; windows_emulator(windows_emulator&&) = delete;
windows_emulator(const windows_emulator&) = delete; windows_emulator(const windows_emulator&) = delete;

View File

@@ -74,8 +74,7 @@ class windows_path
} }
template <typename T> template <typename T>
requires(!std::is_same_v<std::remove_cvref_t<T>, windows_path> && requires(!std::is_same_v<std::remove_cvref_t<T>, windows_path> && !std::is_same_v<std::remove_cvref_t<T>, std::filesystem::path> &&
!std::is_same_v<std::remove_cvref_t<T>, std::filesystem::path> &&
!std::is_same_v<std::remove_cvref_t<T>, utils::buffer_deserializer>) !std::is_same_v<std::remove_cvref_t<T>, utils::buffer_deserializer>)
windows_path(T&& path_like) windows_path(T&& path_like)
: windows_path(std::filesystem::path(std::forward<T>(path_like))) : windows_path(std::filesystem::path(std::forward<T>(path_like)))

View File

@@ -278,8 +278,7 @@ class x64_gdb_stub_handler : public gdb_stub::debugging_handler
return {hook}; return {hook};
} }
std::vector<emulator_hook*> create_hook(const gdb_stub::breakpoint_type type, const uint64_t addr, std::vector<emulator_hook*> create_hook(const gdb_stub::breakpoint_type type, const uint64_t addr, const size_t size)
const size_t size)
{ {
using enum gdb_stub::breakpoint_type; using enum gdb_stub::breakpoint_type;

View File

@@ -9,8 +9,7 @@ struct register_entry
std::optional<size_t> expected_size; std::optional<size_t> expected_size;
std::optional<size_t> offset; std::optional<size_t> offset;
register_entry(const x86_register reg = x86_register::invalid, register_entry(const x86_register reg = x86_register::invalid, const std::optional<size_t> expected_size = std::nullopt,
const std::optional<size_t> expected_size = std::nullopt,
const std::optional<size_t> offset = std::nullopt) const std::optional<size_t> offset = std::nullopt)
: reg(reg), : reg(reg),
expected_size(expected_size), expected_size(expected_size),