mirror of
https://github.com/momo5502/emulator.git
synced 2026-01-18 19:23:56 +00:00
Unify setting segment base
This commit is contained in:
@@ -11,5 +11,8 @@ enum class x64_hookable_instructions
|
||||
rdtscp,
|
||||
};
|
||||
|
||||
using x64_emulator =
|
||||
typed_emulator<uint64_t, x64_register, x64_register::rip, x64_register::rsp, x64_hookable_instructions>;
|
||||
struct x64_emulator
|
||||
: typed_emulator<uint64_t, x64_register, x64_register::rip, x64_register::rsp, x64_hookable_instructions>
|
||||
{
|
||||
virtual void set_segment_base(x64_register base, pointer_type value) = 0;
|
||||
};
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user