diff --git a/src/analyzer/analysis.cpp b/src/analyzer/analysis.cpp index 29067a22..4d518a6e 100644 --- a/src/analyzer/analysis.cpp +++ b/src/analyzer/analysis.cpp @@ -31,7 +31,7 @@ namespace }; } - std::string get_instruction_string(const emulator& emu, const uint64_t address) + std::string get_instruction_string(const disassembler& d, const emulator& emu, const uint64_t address) { std::array instruction_bytes{}; const auto result = emu.try_read_memory(address, instruction_bytes.data(), instruction_bytes.size()); @@ -40,8 +40,7 @@ namespace return {}; } - disassembler disasm{}; - const auto instructions = disasm.disassemble(instruction_bytes, 1); + const auto instructions = d.disassemble(instruction_bytes, 1); if (instructions.empty()) { return {}; @@ -59,7 +58,7 @@ namespace // TODO: Pass enum? if (details == "Illegal instruction") { - const auto inst = get_instruction_string(c.win_emu->emu(), rip); + const auto inst = get_instruction_string(c.d, c.win_emu->emu(), rip); if (!inst.empty()) { addition = " (" + inst + ")"; @@ -258,7 +257,7 @@ namespace } } - bool is_return(const emulator& emu, const uint64_t address) + bool is_return(const disassembler& d, const emulator& emu, const uint64_t address) { std::array instruction_bytes{}; const auto result = emu.try_read_memory(address, instruction_bytes.data(), instruction_bytes.size()); @@ -267,14 +266,13 @@ namespace return false; } - disassembler disasm{}; - const auto instructions = disasm.disassemble(instruction_bytes, 1); + const auto instructions = d.disassemble(instruction_bytes, 1); if (instructions.empty()) { return false; } - return cs_insn_group(disasm.get_handle(), instructions.data(), CS_GRP_RET); + return cs_insn_group(d.get_handle(), instructions.data(), CS_GRP_RET); } void record_instruction(analysis_context& c, const uint64_t address) @@ -293,7 +291,7 @@ namespace return; } - ++c.instructions[instructions[0].mnemonic]; + ++c.instructions[instructions[0].id]; } void handle_instruction(analysis_context& c, const uint64_t address) @@ -384,7 +382,7 @@ namespace win_emu.log.print(is_interesting_call ? color::yellow : color::gray, "Executing entry point: %s (0x%" PRIx64 ")\n", binary->name.c_str(), address); } - else if (is_previous_main_exe && binary != previous_binary && !is_return(c.win_emu->emu(), previous_ip)) + else if (is_previous_main_exe && binary != previous_binary && !is_return(c.d, c.win_emu->emu(), previous_ip)) { auto nearest_entry = binary->address_names.upper_bound(address); if (nearest_entry == binary->address_names.begin()) diff --git a/src/analyzer/analysis.hpp b/src/analyzer/analysis.hpp index b24e5355..e03eeab2 100644 --- a/src/analyzer/analysis.hpp +++ b/src/analyzer/analysis.hpp @@ -2,6 +2,7 @@ #include #include +#include "disassembler.hpp" struct mapped_module; class module_manager; @@ -40,7 +41,8 @@ struct analysis_context std::string output{}; bool has_reached_main{false}; - std::map instructions{}; + disassembler d{}; + std::unordered_map instructions{}; std::vector accessed_imports{}; }; diff --git a/src/analyzer/main.cpp b/src/analyzer/main.cpp index a251c419..fa79f325 100644 --- a/src/analyzer/main.cpp +++ b/src/analyzer/main.cpp @@ -223,20 +223,21 @@ namespace void print_instruction_summary(const analysis_context& c) { - std::map> instruction_counts{}; + std::map> instruction_counts{}; - for (const auto& [mnemonic, count] : c.instructions) + for (const auto& [instruction, count] : c.instructions) { - instruction_counts[count].push_back(mnemonic); + instruction_counts[count].push_back(instruction); } c.win_emu->log.print(color::white, "Instruction summary:\n"); - for (const auto& [count, mnemonics] : instruction_counts) + for (const auto& [count, instructions] : instruction_counts) { - for (const auto& mnemonic : mnemonics) + for (const auto& instruction : instructions) { - c.win_emu->log.print(color::white, "%s: %" PRIx64 "\n", mnemonic.c_str(), count); + const auto* mnemonic = cs_insn_name(c.d.get_handle(), instruction); + c.win_emu->log.print(color::white, "%s: %" PRIx64 "\n", mnemonic, count); } } }