Log foreign memory access

This commit is contained in:
momo5502
2025-08-14 16:50:13 +02:00
parent e10df224a7
commit 73000c8d22
3 changed files with 83 additions and 1 deletions

View File

@@ -155,6 +155,23 @@ export class SettingsMenu extends React.Component<SettingsMenuProps, Settings> {
/>
</div>
<div className="flex gap-6">
<Checkbox
id="settings-foreign"
checked={this.state.foreignAccess}
onCheckedChange={(checked: boolean) => {
this.setState({ foreignAccess: checked });
}}
/>
<SettingsLabel
htmlFor="settings-foreign"
text={"Log Foreign Access"}
tooltip={
"Log when the application reads/writes memory of other modules"
}
/>
</div>
<div className="flex gap-6">
<Checkbox
id="settings-persist"
@@ -165,7 +182,7 @@ export class SettingsMenu extends React.Component<SettingsMenuProps, Settings> {
/>
<SettingsLabel
htmlFor="settings-persist"
text={"Persist filesystem"}
text={"Persist Filesystem"}
tooltip={
"Persist files and folders that were created, modified or deleted during the emulation"
}

View File

@@ -7,6 +7,7 @@ export interface Settings {
bufferStdout: boolean;
persist: boolean;
execAccess: boolean;
foreignAccess: boolean;
wasm64: boolean;
ignoredFunctions: string[];
interestingModules: string[];
@@ -21,6 +22,7 @@ export function createDefaultSettings(): Settings {
bufferStdout: true,
persist: false,
execAccess: true,
foreignAccess: true, // maybe false?
wasm64: false,
ignoredFunctions: [],
interestingModules: [],
@@ -77,6 +79,10 @@ export function translateSettings(settings: Settings): string[] {
switches.push("-x");
}
if (settings.foreignAccess) {
switches.push("-f");
}
settings.ignoredFunctions.forEach((f) => {
switches.push("-i");
switches.push(f);

View File

@@ -24,6 +24,7 @@ namespace
{
mutable bool use_gdb{false};
bool log_executable_access{false};
bool log_foreign_module_access{false};
bool tenet_trace{false};
std::filesystem::path dump{};
std::filesystem::path minidump_path{};
@@ -402,6 +403,33 @@ namespace
return create_application_emulator(options, args);
}
const char* get_module_memory_region_name(const mapped_module& mod, const uint64_t address)
{
if (!mod.is_within(address))
{
return "outside???";
}
uint64_t first_section = mod.image_base + mod.size_of_image;
for (const auto& section : mod.sections)
{
first_section = std::min(first_section, section.region.start);
if (is_within_start_and_length(address, section.region.start, section.region.length))
{
return section.name.c_str();
}
}
if (address < first_section)
{
return "header";
}
return "?";
}
bool run(const analysis_options& options, const std::span<const std::string_view> args)
{
analysis_context context{
@@ -442,6 +470,33 @@ namespace
return instruction_hook_continuation::run_instruction;
});
if (options.log_foreign_module_access)
{
win_emu->emu().hook_memory_read(
0, std::numeric_limits<uint64_t>::max(), [&](const uint64_t address, const void*, size_t) {
const auto rip = win_emu->emu().read_instruction_pointer();
const auto accessor = get_module_if_interesting(win_emu->mod_manager, options.modules, rip);
if (!accessor.has_value())
{
return;
}
const auto* mod = win_emu->mod_manager.find_by_address(address);
if (!mod || mod == *accessor)
{
return;
}
const auto* region_name = get_module_memory_region_name(*mod, address);
win_emu->log.print(color::pink,
"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>");
});
}
if (options.log_executable_access)
{
for (const auto& section : exe.sections)
@@ -573,6 +628,10 @@ namespace
{
options.log_executable_access = true;
}
else if (arg == "-f" || arg == "--foreign")
{
options.log_foreign_module_access = true;
}
else if (arg == "-c" || arg == "--concise")
{
options.concise_logging = true;