diff --git a/deps/unicorn b/deps/unicorn index 1cdd062a..f33976a4 160000 --- a/deps/unicorn +++ b/deps/unicorn @@ -1 +1 @@ -Subproject commit 1cdd062a453c22c7bbd8dc9000efc29d4f3e4a38 +Subproject commit f33976a41bb06dde7c48b5e6de96157f8334b3d7 diff --git a/src/analyzer/main.cpp b/src/analyzer/main.cpp index f5f121e9..a4abead2 100644 --- a/src/analyzer/main.cpp +++ b/src/analyzer/main.cpp @@ -444,6 +444,19 @@ namespace const auto concise_logging = !options.verbose_logging; + win_emu->emu().hook_instruction(x86_hookable_instructions::sgdt, [&](const uint64_t) { + const auto rip = win_emu->emu().read_instruction_pointer(); + const auto mod = get_module_if_interesting(win_emu->mod_manager, options.modules, rip); + + if (mod.has_value()) + { + win_emu->log.print(color::blue, "Executing SGDT instruction at 0x%" PRIx64 " (%s)\n", rip, + (*mod) ? (*mod)->name.c_str() : ""); + } + + return instruction_hook_continuation::run_instruction; + }); + win_emu->emu().hook_instruction(x86_hookable_instructions::cpuid, [&] { const auto rip = win_emu->emu().read_instruction_pointer(); const auto mod = get_module_if_interesting(win_emu->mod_manager, options.modules, rip); diff --git a/src/backends/icicle-emulator/icicle_x86_64_emulator.cpp b/src/backends/icicle-emulator/icicle_x86_64_emulator.cpp index acd7bb7a..42286bb9 100644 --- a/src/backends/icicle-emulator/icicle_x86_64_emulator.cpp +++ b/src/backends/icicle-emulator/icicle_x86_64_emulator.cpp @@ -266,7 +266,7 @@ namespace icicle const auto invoker = +[](void* cb) { const auto& func = *static_cast(cb); - (void)func(); // + (void)func(0); // }; const auto id = icicle_add_syscall_hook(this->emu_, invoker, ptr); diff --git a/src/backends/unicorn-emulator/unicorn_x86_64_emulator.cpp b/src/backends/unicorn-emulator/unicorn_x86_64_emulator.cpp index 672eed0b..87db9a92 100644 --- a/src/backends/unicorn-emulator/unicorn_x86_64_emulator.cpp +++ b/src/backends/unicorn-emulator/unicorn_x86_64_emulator.cpp @@ -32,6 +32,8 @@ namespace unicorn return UC_X86_INS_RDTSC; case x86_hookable_instructions::rdtscp: return UC_X86_INS_RDTSCP; + case x86_hookable_instructions::sgdt: + return UC_X86_INS_SGDT; default: throw std::runtime_error("Bad instruction for mapping"); } @@ -376,8 +378,9 @@ namespace unicorn if (inst_type == x86_hookable_instructions::invalid) { - function_wrapper wrapper( - [c = std::move(callback)](uc_engine*) { return (c() == instruction_hook_continuation::skip_instruction) ? 1 : 0; }); + function_wrapper wrapper([c = std::move(callback)](uc_engine*) { + return (c(0) == instruction_hook_continuation::skip_instruction) ? 1 : 0; + }); uce(uc_hook_add(*this, hook.make_reference(), UC_HOOK_INSN_INVALID, wrapper.get_function(), wrapper.get_user_data(), 0, std::numeric_limits::max())); @@ -385,7 +388,19 @@ namespace unicorn } else if (inst_type == x86_hookable_instructions::syscall) { - function_wrapper wrapper([c = std::move(callback)](uc_engine*) { c(); }); + function_wrapper wrapper([c = std::move(callback)](uc_engine*) { (void)c(0); }); + + const auto uc_instruction = map_hookable_instruction(inst_type); + uce(uc_hook_add(*this, hook.make_reference(), UC_HOOK_INSN, wrapper.get_function(), wrapper.get_user_data(), 0, + std::numeric_limits::max(), uc_instruction)); + + container->add(std::move(wrapper), std::move(hook)); + } + else if (inst_type == x86_hookable_instructions::sgdt) + { + function_wrapper wrapper([c = std::move(callback)](uc_engine*, const uint64_t data) { + return (c(data) == instruction_hook_continuation::skip_instruction) ? 1 : 0; + }); const auto uc_instruction = map_hookable_instruction(inst_type); uce(uc_hook_add(*this, hook.make_reference(), UC_HOOK_INSN, wrapper.get_function(), wrapper.get_user_data(), 0, @@ -395,8 +410,9 @@ namespace unicorn } else { - function_wrapper wrapper( - [c = std::move(callback)](uc_engine*) { return (c() == instruction_hook_continuation::skip_instruction) ? 1 : 0; }); + function_wrapper wrapper([c = std::move(callback)](uc_engine*) { + return (c(0) == instruction_hook_continuation::skip_instruction) ? 1 : 0; + }); const auto uc_instruction = map_hookable_instruction(inst_type); uce(uc_hook_add(*this, hook.make_reference(), UC_HOOK_INSN, wrapper.get_function(), wrapper.get_user_data(), 0, diff --git a/src/emulator/arch_emulator.hpp b/src/emulator/arch_emulator.hpp index f20283a1..99260c7d 100644 --- a/src/emulator/arch_emulator.hpp +++ b/src/emulator/arch_emulator.hpp @@ -50,6 +50,7 @@ enum class x86_hookable_instructions cpuid, rdtsc, rdtscp, + sgdt, }; // --[x86_64]------------------------------------------------------------------------- diff --git a/src/emulator/hook_interface.hpp b/src/emulator/hook_interface.hpp index a6f84568..7c3c6f1b 100644 --- a/src/emulator/hook_interface.hpp +++ b/src/emulator/hook_interface.hpp @@ -38,7 +38,8 @@ struct basic_block using edge_generation_hook_callback = std::function; using basic_block_hook_callback = std::function; -using instruction_hook_callback = std::function; +using simple_instruction_hook_callback = std::function; +using instruction_hook_callback = std::function; using interrupt_hook_callback = std::function; using memory_access_hook_callback = std::function; diff --git a/src/emulator/typed_emulator.hpp b/src/emulator/typed_emulator.hpp index a17b595f..a43b5924 100644 --- a/src/emulator/typed_emulator.hpp +++ b/src/emulator/typed_emulator.hpp @@ -81,6 +81,13 @@ class typed_emulator : public emulator return this->hook_instruction(static_cast(instruction_type), std::move(callback)); } + emulator_hook* hook_instruction(hookable_instructions instruction_type, simple_instruction_hook_callback callback) + { + return this->hook_instruction(instruction_type, [c = std::move(callback)](const uint64_t) { + return c(); // + }); + } + private: emulator_hook* hook_instruction(int instruction_type, instruction_hook_callback callback) override = 0;