From ac16b4a7276e273cc8faf741f34068e37e3ee731 Mon Sep 17 00:00:00 2001 From: momo5502 Date: Sun, 5 Jan 2025 09:28:16 +0100 Subject: [PATCH] Handle concise logging via options --- src/analyzer/main.cpp | 151 +++++++++++++++++++------------ src/analyzer/object_watching.hpp | 17 ++-- 2 files changed, 103 insertions(+), 65 deletions(-) diff --git a/src/analyzer/main.cpp b/src/analyzer/main.cpp index d6d7e191..578540dd 100644 --- a/src/analyzer/main.cpp +++ b/src/analyzer/main.cpp @@ -3,23 +3,25 @@ #include #include -#define CONCISE_EMULATOR_OUTPUT - #include "object_watching.hpp" -bool use_gdb = false; - namespace { - void watch_system_objects(windows_emulator& win_emu) + struct analysis_options { - watch_object(win_emu, *win_emu.current_thread().teb); - watch_object(win_emu, win_emu.process().peb); - watch_object(win_emu, emulator_object{win_emu.emu(), kusd_mmio::address()}); - auto* params_hook = watch_object(win_emu, win_emu.process().process_params); + bool use_gdb{false}; + bool concise_logging{false}; + }; + + void watch_system_objects(windows_emulator& win_emu, const bool cache_logging) + { + watch_object(win_emu, *win_emu.current_thread().teb, cache_logging); + watch_object(win_emu, win_emu.process().peb, cache_logging); + watch_object(win_emu, emulator_object{win_emu.emu(), kusd_mmio::address()}, cache_logging); + auto* params_hook = watch_object(win_emu, win_emu.process().process_params, cache_logging); win_emu.emu().hook_memory_write(win_emu.process().peb.value() + offsetof(PEB, ProcessParameters), 0x8, - [&](const uint64_t address, size_t, const uint64_t value) + [&, cache_logging](const uint64_t address, size_t, const uint64_t value) { const auto target_address = win_emu.process().peb.value() + offsetof( PEB, ProcessParameters); @@ -31,16 +33,16 @@ namespace }; win_emu.emu().delete_hook(params_hook); - params_hook = watch_object(win_emu, obj); + params_hook = watch_object(win_emu, obj, cache_logging); } }); } - void run_emulation(windows_emulator& win_emu) + void run_emulation(windows_emulator& win_emu, const analysis_options& options) { try { - if (use_gdb) + if (options.use_gdb) { const auto* address = "127.0.0.1:28960"; win_emu.logger.print(color::pink, "Waiting for GDB connection on %s...\n", address); @@ -76,44 +78,44 @@ namespace } } - std::vector parse_arguments(char* argv[], const size_t argc) + std::vector parse_arguments(const std::span args) { - std::vector args{}; - args.reserve(argc - 1); + std::vector wide_args{}; + wide_args.reserve(args.size() - 1); - for (size_t i = 1; i < argc; ++i) + for (size_t i = 1; i < args.size(); ++i) { - std::string_view arg(argv[i]); - args.emplace_back(arg.begin(), arg.end()); + const auto& arg = args[i]; + wide_args.emplace_back(arg.begin(), arg.end()); } - return args; + return wide_args; } - void run(char* argv[], const size_t argc) + void run(const analysis_options& options, const std::span args) { - if (argc < 1) + if (args.empty()) { return; } emulator_settings settings{ - .application = argv[0], - .arguments = parse_arguments(argv, argc), -#ifdef CONCISE_EMULATOR_OUTPUT - .silent_until_main = true, -#endif + .application = args[0], + .arguments = parse_arguments(args), + .silent_until_main = options.concise_logging, }; windows_emulator win_emu{std::move(settings)}; (void)&watch_system_objects; - watch_system_objects(win_emu); + watch_system_objects(win_emu, options.concise_logging); win_emu.buffer_stdout = true; //win_emu.verbose_calls = true; const auto& exe = *win_emu.process().executable; + const auto concise_logging = options.concise_logging; + for (const auto& section : exe.sections) { if ((section.region.permissions & memory_permission::exec) != memory_permission::exec) @@ -121,7 +123,7 @@ namespace continue; } - auto read_handler = [&, section](const uint64_t address, size_t, uint64_t) + auto read_handler = [&, section, concise_logging](const uint64_t address, size_t, uint64_t) { const auto rip = win_emu.emu().read_instruction_pointer(); if (win_emu.process().module_manager.find_by_address(rip) != win_emu.process().executable) @@ -129,11 +131,12 @@ namespace return; } -#ifdef CONCISE_EMULATOR_OUTPUT - static uint64_t count{0}; - ++count; - if (count > 100 && count % 10000 != 0) return; -#endif + if (concise_logging) + { + static uint64_t count{0}; + ++count; + if (count > 100 && count % 10000 != 0) return; + } win_emu.logger.print( color::green, @@ -141,7 +144,7 @@ namespace section.name.c_str(), address, rip); }; - const auto write_handler = [&, section](const uint64_t address, size_t, uint64_t) + const auto write_handler = [&, section, concise_logging](const uint64_t address, size_t, uint64_t) { const auto rip = win_emu.emu().read_instruction_pointer(); if (win_emu.process().module_manager.find_by_address(rip) != win_emu.process().executable) @@ -149,11 +152,12 @@ namespace return; } -#ifdef CONCISE_EMULATOR_OUTPUT - static uint64_t count{0}; - ++count; - if (count > 100 && count % 10000 != 0) return; -#endif + if (concise_logging) + { + static uint64_t count{0}; + ++count; + if (count > 100 && count % 10000 != 0) return; + } win_emu.logger.print( color::blue, @@ -165,32 +169,67 @@ namespace win_emu.emu().hook_memory_write(section.region.start, section.region.length, std::move(write_handler)); } - run_emulation(win_emu); + run_emulation(win_emu, options); + } + + std::vector bundle_arguments(const int argc, char** argv) + { + std::vector args{}; + + for (int i = 1; i < argc; ++i) + { + args.push_back(argv[i]); + } + + return args; + } + + analysis_options parse_options(std::vector& args) + { + analysis_options options{}; + + while (!args.empty()) + { + auto arg_it = args.begin(); + const auto& arg = *arg_it; + + if (arg == "-d") + { + options.use_gdb = true; + } + else if (arg == "-c") + { + options.concise_logging = true; + } + else + { + break; + } + + args.erase(arg_it); + } + + return options; } } int main(const int argc, char** argv) { - if (argc <= 1) - { - puts("Application not specified!"); - return 1; - } - - //setvbuf(stdout, nullptr, _IOFBF, 0x10000); - if (argc > 2 && argv[1] == "-d"sv) - { - use_gdb = true; - } - try { + auto args = bundle_arguments(argc, argv); + const auto options = parse_options(args); + + if (args.empty()) + { + throw std::runtime_error("Application not specified!"); + } + do { - const auto offset = use_gdb ? 2 : 1; - run(argv + offset, static_cast(argc - offset)); + run(options, args); } - while (use_gdb); + while (options.use_gdb); return 0; } diff --git a/src/analyzer/object_watching.hpp b/src/analyzer/object_watching.hpp index 9e0db652..4ebb62b8 100644 --- a/src/analyzer/object_watching.hpp +++ b/src/analyzer/object_watching.hpp @@ -2,15 +2,13 @@ #include "reflect_type_info.hpp" -//#define CACHE_OBJECT_ADDRESSES - template -emulator_hook* watch_object(windows_emulator& emu, emulator_object object) +emulator_hook* watch_object(windows_emulator& emu, emulator_object object, const bool cache_logging = false) { const reflect_type_info info{}; return emu.emu().hook_memory_read(object.value(), object.size(), - [i = std::move(info), object, &emu]( + [i = std::move(info), object, &emu, cache_logging]( const uint64_t address, size_t, uint64_t) { const auto rip = emu.emu().read_instruction_pointer(); @@ -22,13 +20,14 @@ emulator_hook* watch_object(windows_emulator& emu, emulator_object object) return; } -#if defined(CACHE_OBJECT_ADDRESSES) || defined(CONCISE_EMULATOR_OUTPUT) - static std::unordered_set logged_addresses{}; - if (is_main_access && !logged_addresses.insert(address).second) + if (cache_logging) { - return; + static std::unordered_set logged_addresses{}; + if (is_main_access && !logged_addresses.insert(address).second) + { + return; + } } -#endif const auto offset = address - object.value(); emu.logger.print(is_main_access ? color::green : color::dark_gray,