Support SGDT hooking

This commit is contained in:
momo5502
2025-08-18 15:33:32 +02:00
parent acf28467c5
commit 10cd7868ac
7 changed files with 46 additions and 8 deletions

2
deps/unicorn vendored

View File

@@ -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() : "<N/A>");
}
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);

View File

@@ -266,7 +266,7 @@ namespace icicle
const auto invoker = +[](void* cb) {
const auto& func = *static_cast<decltype(ptr)>(cb);
(void)func(); //
(void)func(0); //
};
const auto id = icicle_add_syscall_hook(this->emu_, invoker, ptr);

View File

@@ -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<int, uc_engine*> wrapper(
[c = std::move(callback)](uc_engine*) { return (c() == instruction_hook_continuation::skip_instruction) ? 1 : 0; });
function_wrapper<int, uc_engine*> 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<pointer_type>::max()));
@@ -385,7 +388,19 @@ namespace unicorn
}
else if (inst_type == x86_hookable_instructions::syscall)
{
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*) { (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<pointer_type>::max(), uc_instruction));
container->add(std::move(wrapper), std::move(hook));
}
else if (inst_type == x86_hookable_instructions::sgdt)
{
function_wrapper<int, uc_engine*, uint64_t> 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<int, uc_engine*> wrapper(
[c = std::move(callback)](uc_engine*) { return (c() == instruction_hook_continuation::skip_instruction) ? 1 : 0; });
function_wrapper<int, uc_engine*> 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,

View File

@@ -50,6 +50,7 @@ enum class x86_hookable_instructions
cpuid,
rdtsc,
rdtscp,
sgdt,
};
// --[x86_64]-------------------------------------------------------------------------

View File

@@ -38,7 +38,8 @@ struct basic_block
using edge_generation_hook_callback = 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 instruction_hook_callback = std::function<instruction_hook_continuation()>;
using simple_instruction_hook_callback = std::function<instruction_hook_continuation()>;
using instruction_hook_callback = std::function<instruction_hook_continuation(uint64_t data)>;
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)>;

View File

@@ -81,6 +81,13 @@ class typed_emulator : public emulator
return this->hook_instruction(static_cast<int>(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;