From af6492be6d58ef25d458ba61cab7d45a2efc720b Mon Sep 17 00:00:00 2001 From: momo5502 Date: Sat, 29 Mar 2025 08:04:56 +0100 Subject: [PATCH] Unify setting segment base --- src/emulator/x64_emulator.hpp | 7 ++-- src/icicle-emulator/icicle_x64_emulator.cpp | 20 +++++++++++ src/icicle/src/icicle.rs | 22 +++++++++---- src/icicle/src/lib.rs | 33 ++++++++++++++++--- src/unicorn-emulator/unicorn_x64_emulator.cpp | 33 +++++++++++++++++++ src/windows-emulator/emulator_thread.cpp | 15 +-------- src/windows-emulator/process_context.hpp | 2 -- 7 files changed, 102 insertions(+), 30 deletions(-) diff --git a/src/emulator/x64_emulator.hpp b/src/emulator/x64_emulator.hpp index b77882b9..cdb0caaf 100644 --- a/src/emulator/x64_emulator.hpp +++ b/src/emulator/x64_emulator.hpp @@ -11,5 +11,8 @@ enum class x64_hookable_instructions rdtscp, }; -using x64_emulator = - typed_emulator; +struct x64_emulator + : typed_emulator +{ + virtual void set_segment_base(x64_register base, pointer_type value) = 0; +}; diff --git a/src/icicle-emulator/icicle_x64_emulator.cpp b/src/icicle-emulator/icicle_x64_emulator.cpp index 845327ae..062f0965 100644 --- a/src/icicle-emulator/icicle_x64_emulator.cpp +++ b/src/icicle-emulator/icicle_x64_emulator.cpp @@ -13,6 +13,7 @@ extern "C" int32_t icicle_write_memory(icicle_emulator*, uint64_t address, const void* data, size_t length); size_t icicle_read_register(icicle_emulator*, int reg, void* data, size_t length); size_t icicle_write_register(icicle_emulator*, int reg, const void* data, size_t length); + void icicle_start(icicle_emulator*); void icicle_destroy_emulator(icicle_emulator*); } @@ -57,12 +58,31 @@ namespace icicle { timeout = {}; } + + icicle_start(this->emu_); } void stop() override { } + void set_segment_base(const x64_register base, const pointer_type value) override + { + switch (base) + { + case x64_register::fs: + case x64_register::fs_base: + this->reg(x64_register::fs_base, value); + break; + case x64_register::gs: + case x64_register::gs_base: + this->reg(x64_register::gs_base, value); + break; + default: + break; + } + } + size_t write_raw_register(const int reg, const void* value, const size_t size) override { return icicle_write_register(this->emu_, reg, value, size); diff --git a/src/icicle/src/icicle.rs b/src/icicle/src/icicle.rs index 3cfbceba..60e77e82 100644 --- a/src/icicle/src/icicle.rs +++ b/src/icicle/src/icicle.rs @@ -46,6 +46,14 @@ impl IcicleEmulator { return &mut self.vm.cpu.mem; } + pub fn start(&mut self) { + self.vm.run(); + } + + pub fn stop(&mut self) { + //self.vm.stop(); + } + pub fn map_memory(&mut self, address: u64, length: u64, permissions: u8) -> bool { const MAPPING_PERMISSIONS: u8 = icicle_vm::cpu::mem::perm::MAP | icicle_vm::cpu::mem::perm::INIT @@ -608,8 +616,8 @@ struct X64RegisterNodes { fptag: pcode::VarNode, //msr: pcode::VarNode, mxcsr: pcode::VarNode, - //fs_base: pcode::VarNode, - //gs_base: pcode::VarNode, + fs_base: pcode::VarNode, + gs_base: pcode::VarNode, flags: pcode::VarNode, rflags: pcode::VarNode, fip: pcode::VarNode, @@ -849,9 +857,9 @@ impl X64RegisterNodes { fop: r("FPULastInstructionOpcode"), /*fds: r("FDS"), msr: r("MSR"), - fcs: r("FCS"), - fs_base: r("FSBASE"), - gs_base: r("GSBASE"),*/ + fcs: r("FCS"),*/ + fs_base: r("FS_OFFSET"), + gs_base: r("GS_OFFSET"), } } @@ -1077,8 +1085,8 @@ impl X64RegisterNodes { X64Register::Fptag => self.fptag, //X64Register::Msr => self.msr, X64Register::Mxcsr => self.mxcsr, - //X64Register::FsBase => self.fs_base, - //X64Register::GsBase => self.gs_base, + X64Register::FsBase => self.fs_base, + X64Register::GsBase => self.gs_base, X64Register::Flags => self.flags, X64Register::Rflags => self.rflags, X64Register::Fip => self.fip, diff --git a/src/icicle/src/lib.rs b/src/icicle/src/lib.rs index 688b209c..b11b022f 100644 --- a/src/icicle/src/lib.rs +++ b/src/icicle/src/lib.rs @@ -17,6 +17,14 @@ pub fn icicle_create_emulator() -> *mut c_void { return Box::into_raw(emulator) as *mut c_void; } +#[unsafe(no_mangle)] +pub fn icicle_start(ptr: *mut c_void) { + unsafe { + let emulator = &mut *(ptr as *mut IcicleEmulator); + emulator.start(); + } +} + #[unsafe(no_mangle)] pub fn icicle_map_memory(ptr: *mut c_void, address: u64, length: u64, permissions: u8) -> i32 { unsafe { @@ -45,7 +53,12 @@ pub fn icicle_protect_memory(ptr: *mut c_void, address: u64, length: u64, permis } #[unsafe(no_mangle)] -pub fn icicle_write_memory(ptr: *mut c_void, address: u64, data: *const c_void, size: usize) -> i32 { +pub fn icicle_write_memory( + ptr: *mut c_void, + address: u64, + data: *const c_void, + size: usize, +) -> i32 { unsafe { let emulator = &mut *(ptr as *mut IcicleEmulator); let u8_slice = std::slice::from_raw_parts(data as *const u8, size); @@ -65,20 +78,30 @@ pub fn icicle_read_memory(ptr: *mut c_void, address: u64, data: *mut c_void, siz } #[unsafe(no_mangle)] -pub fn icicle_read_register(ptr: *mut c_void, reg: X64Register, data: *mut c_void, size: usize) -> usize { +pub fn icicle_read_register( + ptr: *mut c_void, + reg: X64Register, + data: *mut c_void, + size: usize, +) -> usize { unsafe { let emulator = &mut *(ptr as *mut IcicleEmulator); let u8_slice = std::slice::from_raw_parts_mut(data as *mut u8, size); - return emulator.read_register(reg, u8_slice); + return emulator.read_register(reg, u8_slice); } } #[unsafe(no_mangle)] -pub fn icicle_write_register(ptr: *mut c_void, reg: X64Register, data: *const c_void, size: usize) -> usize { +pub fn icicle_write_register( + ptr: *mut c_void, + reg: X64Register, + data: *const c_void, + size: usize, +) -> usize { unsafe { let emulator = &mut *(ptr as *mut IcicleEmulator); let u8_slice = std::slice::from_raw_parts(data as *const u8, size); - return emulator.write_register(reg, u8_slice); + return emulator.write_register(reg, u8_slice); } } diff --git a/src/unicorn-emulator/unicorn_x64_emulator.cpp b/src/unicorn-emulator/unicorn_x64_emulator.cpp index b6ec8dfa..d301c10f 100644 --- a/src/unicorn-emulator/unicorn_x64_emulator.cpp +++ b/src/unicorn-emulator/unicorn_x64_emulator.cpp @@ -302,6 +302,39 @@ namespace unicorn uce(uc_emu_stop(*this)); } + void set_segment_base(const x64_register base, const pointer_type value) override + { + constexpr auto IA32_FS_BASE_MSR = 0xC0000100; + constexpr auto IA32_GS_BASE_MSR = 0xC0000101; + + struct msr_value + { + uint32_t id; + uint64_t value; + }; + + msr_value msr_val{ + .id = 0, + .value = value, + }; + + switch (base) + { + case x64_register::fs: + case x64_register::fs_base: + msr_val.id = IA32_FS_BASE_MSR; + break; + case x64_register::gs: + case x64_register::gs_base: + msr_val.id = IA32_GS_BASE_MSR; + break; + default: + return; + } + + this->write_register(x64_register::msr, &msr_val, sizeof(msr_val)); + } + size_t write_raw_register(const int reg, const void* value, const size_t size) override { auto result_size = size; diff --git a/src/windows-emulator/emulator_thread.cpp b/src/windows-emulator/emulator_thread.cpp index 1e9f6f58..144bcbcd 100644 --- a/src/windows-emulator/emulator_thread.cpp +++ b/src/windows-emulator/emulator_thread.cpp @@ -28,19 +28,6 @@ namespace emu.reg(x64_register::rsp, stack_end); } - void setup_gs_segment(x64_emulator& emu, const emulator_allocator& allocator) - { - struct msr_value - { - uint32_t id; - uint64_t value; - }; - - const msr_value value{IA32_GS_BASE_MSR, allocator.get_base()}; - - emu.write_register(x64_register::msr, &value, sizeof(value)); - } - bool is_object_signaled(process_context& c, const handle h, const uint32_t current_thread_id) { const auto type = h.value.type; @@ -228,7 +215,7 @@ void emulator_thread::setup_registers(x64_emulator& emu, const process_context& } setup_stack(emu, this->stack_base, this->stack_size); - setup_gs_segment(emu, *this->gs_segment); + emu.set_segment_base(x64_register::gs, this->gs_segment->get_base()); CONTEXT64 ctx{}; ctx.ContextFlags = CONTEXT64_ALL; diff --git a/src/windows-emulator/process_context.hpp b/src/windows-emulator/process_context.hpp index 73f844b2..7fa62bbb 100644 --- a/src/windows-emulator/process_context.hpp +++ b/src/windows-emulator/process_context.hpp @@ -19,8 +19,6 @@ #define PEB_SEGMENT_SIZE (20 << 20) // 20 MB #define GS_SEGMENT_SIZE (1 << 20) // 1 MB -#define IA32_GS_BASE_MSR 0xC0000101 - #define STACK_SIZE 0x40000ULL #define GDT_ADDR 0x30000