From b2296930d3b6816ef7f5f7d631cbf749d4d05c81 Mon Sep 17 00:00:00 2001 From: robert-yates Date: Sat, 19 Apr 2025 22:45:07 +0200 Subject: [PATCH] prepare 32bit support with name and class inheritance modifications --- .../icicle-bridge/src/icicle.rs | 24 +- .../icicle-emulator/icicle-bridge/src/lib.rs | 6 +- .../icicle-bridge/src/registers.rs | 460 +++++++++--------- ...mulator.cpp => icicle_x86_64_emulator.cpp} | 30 +- ...mulator.hpp => icicle_x86_64_emulator.hpp} | 4 +- ...ulator.cpp => unicorn_x86_64_emulator.cpp} | 44 +- ...ulator.hpp => unicorn_x86_64_emulator.hpp} | 4 +- src/emulator/arch_emulator.hpp | 66 +++ src/emulator/typed_emulator.hpp | 13 +- src/emulator/x64_emulator.hpp | 19 - .../{x64_register.hpp => x86_register.hpp} | 3 +- src/fuzzer/main.cpp | 4 +- src/windows-emulator/apiset/apiset.cpp | 10 +- src/windows-emulator/apiset/apiset.hpp | 4 +- src/windows-emulator/cpu_context.cpp | 148 +++--- src/windows-emulator/cpu_context.hpp | 6 +- src/windows-emulator/emulator_thread.cpp | 29 +- src/windows-emulator/emulator_thread.hpp | 10 +- src/windows-emulator/emulator_utils.hpp | 4 +- src/windows-emulator/exception_dispatch.cpp | 20 +- src/windows-emulator/exception_dispatch.hpp | 16 +- src/windows-emulator/io_device.hpp | 4 +- src/windows-emulator/kusd_mmio.hpp | 2 +- src/windows-emulator/process_context.cpp | 8 +- src/windows-emulator/process_context.hpp | 6 +- src/windows-emulator/syscall_dispatcher.cpp | 10 +- src/windows-emulator/syscall_utils.hpp | 30 +- src/windows-emulator/windows_emulator.cpp | 36 +- src/windows-emulator/windows_emulator.hpp | 16 +- src/windows-gdb-stub/x64_gdb_stub_handler.hpp | 6 +- src/windows-gdb-stub/x64_register_mapping.hpp | 156 +++--- 31 files changed, 623 insertions(+), 575 deletions(-) rename src/backends/icicle-emulator/{icicle_x64_emulator.cpp => icicle_x86_64_emulator.cpp} (95%) rename src/backends/icicle-emulator/{icicle_x64_emulator.hpp => icicle_x86_64_emulator.hpp} (76%) rename src/backends/unicorn-emulator/{unicorn_x64_emulator.cpp => unicorn_x86_64_emulator.cpp} (95%) rename src/backends/unicorn-emulator/{unicorn_x64_emulator.hpp => unicorn_x86_64_emulator.hpp} (76%) create mode 100644 src/emulator/arch_emulator.hpp delete mode 100644 src/emulator/x64_emulator.hpp rename src/emulator/{x64_register.hpp => x86_register.hpp} (97%) diff --git a/src/backends/icicle-emulator/icicle-bridge/src/icicle.rs b/src/backends/icicle-emulator/icicle-bridge/src/icicle.rs index d9b07b9f..19963833 100644 --- a/src/backends/icicle-emulator/icicle-bridge/src/icicle.rs +++ b/src/backends/icicle-emulator/icicle-bridge/src/icicle.rs @@ -204,7 +204,7 @@ impl ExecutionHooks { pub struct IcicleEmulator { executing_thread: std::thread::ThreadId, vm: icicle_vm::Vm, - reg: registers::X64RegisterNodes, + reg: registers::X86RegisterNodes, syscall_hooks: HookContainer, interrupt_hooks: HookContainer, violation_hooks: HookContainer bool>, @@ -275,7 +275,7 @@ impl IcicleEmulator { Self { stop: stop_value, executing_thread: std::thread::current().id(), - reg: registers::X64RegisterNodes::new(&virtual_machine.cpu.arch), + reg: registers::X86RegisterNodes::new(&virtual_machine.cpu.arch), vm: virtual_machine, syscall_hooks: HookContainer::new(), interrupt_hooks: HookContainer::new(), @@ -555,7 +555,7 @@ impl IcicleEmulator { }; } - fn read_generic_register(&mut self, reg: registers::X64Register, buffer: &mut [u8]) -> usize { + fn read_generic_register(&mut self, reg: registers::X86Register, buffer: &mut [u8]) -> usize { let reg_node = self.reg.get_node(reg); let res = self.vm.cpu.read_dynamic(pcode::Value::Var(reg_node)); @@ -580,11 +580,11 @@ impl IcicleEmulator { return limit; } - pub fn read_register(&mut self, reg: registers::X64Register, data: &mut [u8]) -> usize { + pub fn read_register(&mut self, reg: registers::X86Register, data: &mut [u8]) -> usize { match reg { - registers::X64Register::Rflags => self.read_flags::(data), - registers::X64Register::Eflags => self.read_flags::(data), - registers::X64Register::Flags => self.read_flags::(data), + registers::X86Register::Rflags => self.read_flags::(data), + registers::X86Register::Eflags => self.read_flags::(data), + registers::X86Register::Flags => self.read_flags::(data), _ => self.read_generic_register(reg, data), } } @@ -606,16 +606,16 @@ impl IcicleEmulator { return limit; } - pub fn write_register(&mut self, reg: registers::X64Register, data: &[u8]) -> usize { + pub fn write_register(&mut self, reg: registers::X86Register, data: &[u8]) -> usize { match reg { - registers::X64Register::Rflags => self.write_flags::(data), - registers::X64Register::Eflags => self.write_flags::(data), - registers::X64Register::Flags => self.write_flags::(data), + registers::X86Register::Rflags => self.write_flags::(data), + registers::X86Register::Eflags => self.write_flags::(data), + registers::X86Register::Flags => self.write_flags::(data), _ => self.write_generic_register(reg, data), } } - fn write_generic_register(&mut self, reg: registers::X64Register, data: &[u8]) -> usize { + fn write_generic_register(&mut self, reg: registers::X86Register, data: &[u8]) -> usize { let reg_node = self.reg.get_node(reg); let mut buffer = [0u8; 32]; diff --git a/src/backends/icicle-emulator/icicle-bridge/src/lib.rs b/src/backends/icicle-emulator/icicle-bridge/src/lib.rs index 19706c0f..fe5ac7a5 100644 --- a/src/backends/icicle-emulator/icicle-bridge/src/lib.rs +++ b/src/backends/icicle-emulator/icicle-bridge/src/lib.rs @@ -2,7 +2,7 @@ mod icicle; mod registers; use icicle::IcicleEmulator; -use registers::X64Register; +use registers::X86Register; use std::os::raw::c_void; fn to_cbool(value: bool) -> i32 { @@ -252,7 +252,7 @@ pub fn icicle_remove_hook(ptr: *mut c_void, id: u32) { #[unsafe(no_mangle)] pub fn icicle_read_register( ptr: *mut c_void, - reg: X64Register, + reg: X86Register, data: *mut c_void, size: usize, ) -> usize { @@ -274,7 +274,7 @@ pub fn icicle_read_register( #[unsafe(no_mangle)] pub fn icicle_write_register( ptr: *mut c_void, - reg: X64Register, + reg: X86Register, data: *const c_void, size: usize, ) -> usize { diff --git a/src/backends/icicle-emulator/icicle-bridge/src/registers.rs b/src/backends/icicle-emulator/icicle-bridge/src/registers.rs index c32243ec..390d6cc5 100644 --- a/src/backends/icicle-emulator/icicle-bridge/src/registers.rs +++ b/src/backends/icicle-emulator/icicle-bridge/src/registers.rs @@ -1,6 +1,6 @@ #[repr(i32)] #[derive(PartialEq)] -pub enum X64Register { +pub enum X86Register { Invalid = 0, Ah, Al, @@ -244,7 +244,7 @@ pub enum X64Register { } #[derive(Clone)] -pub(crate) struct X64RegisterNodes { +pub(crate) struct X86RegisterNodes { rax: pcode::VarNode, rbx: pcode::VarNode, rcx: pcode::VarNode, @@ -474,7 +474,7 @@ pub(crate) struct X64RegisterNodes { flags: Vec, } -impl X64RegisterNodes { +impl X86RegisterNodes { pub fn new(arch: &icicle_cpu::Arch) -> Self { let r = |name: &str| arch.sleigh.get_reg(name).unwrap().var; let nodes = [ @@ -731,234 +731,234 @@ impl X64RegisterNodes { } } - pub fn get_node(&self, reg: X64Register) -> pcode::VarNode { + pub fn get_node(&self, reg: X86Register) -> pcode::VarNode { match reg { - X64Register::Rax => self.rax, - X64Register::Rbx => self.rbx, - X64Register::Rcx => self.rcx, - X64Register::Rdx => self.rdx, - X64Register::Rsi => self.rsi, - X64Register::Rdi => self.rdi, - X64Register::Rbp => self.rbp, - X64Register::Rsp => self.rsp, - X64Register::R8 => self.r8, - X64Register::R9 => self.r9, - X64Register::R10 => self.r10, - X64Register::R11 => self.r11, - X64Register::R12 => self.r12, - X64Register::R13 => self.r13, - X64Register::R14 => self.r14, - X64Register::R15 => self.r15, - X64Register::Rip => self.rip, - X64Register::Cs => self.cs, - X64Register::Ds => self.ds, - X64Register::Es => self.es, - X64Register::Fs => self.fs, - X64Register::Gs => self.gs, - X64Register::Ss => self.ss, - X64Register::Ah => self.ah, - X64Register::Al => self.al, - X64Register::Ax => self.ax, - X64Register::Bh => self.bh, - X64Register::Bl => self.bl, - X64Register::Bpl => self.bpl, - X64Register::Ch => self.ch, - X64Register::Cl => self.cl, - X64Register::Cx => self.cx, - X64Register::Dh => self.dh, - X64Register::Dil => self.dil, - X64Register::Dl => self.dl, - X64Register::Dx => self.dx, - X64Register::Eax => self.eax, - X64Register::Ebp => self.ebp, - X64Register::Ebx => self.ebx, - X64Register::Ecx => self.ecx, - X64Register::Edi => self.edi, - X64Register::Edx => self.edx, - X64Register::Esi => self.esi, - X64Register::Esp => self.esp, - X64Register::Fpsw => self.fpsw, - X64Register::Gdtr => self.gdtr, - X64Register::Idtr => self.idtr, - X64Register::Ldtr => self.ldtr, - X64Register::Tr => self.tr, - X64Register::Cr0 => self.cr0, - X64Register::Cr1 => self.cr1, - X64Register::Cr2 => self.cr2, - X64Register::Cr3 => self.cr3, - X64Register::Cr4 => self.cr4, - X64Register::Cr8 => self.cr8, - X64Register::Dr0 => self.dr0, - X64Register::Dr1 => self.dr1, - X64Register::Dr2 => self.dr2, - X64Register::Dr3 => self.dr3, - X64Register::Dr4 => self.dr4, - X64Register::Dr5 => self.dr5, - X64Register::Dr6 => self.dr6, - X64Register::Dr7 => self.dr7, - X64Register::Fp0 => self.fp0, - X64Register::Fp1 => self.fp1, - X64Register::Fp2 => self.fp2, - X64Register::Fp3 => self.fp3, - X64Register::Fp4 => self.fp4, - X64Register::Fp5 => self.fp5, - X64Register::Fp6 => self.fp6, - X64Register::Fp7 => self.fp7, - /*X64Register::K0 => self.k0, - X64Register::K1 => self.k1, - X64Register::K2 => self.k2, - X64Register::K3 => self.k3, - X64Register::K4 => self.k4, - X64Register::K5 => self.k5, - X64Register::K6 => self.k6, - X64Register::K7 => self.k7,*/ - X64Register::Mm0 => self.mm0, - X64Register::Mm1 => self.mm1, - X64Register::Mm2 => self.mm2, - X64Register::Mm3 => self.mm3, - X64Register::Mm4 => self.mm4, - X64Register::Mm5 => self.mm5, - X64Register::Mm6 => self.mm6, - X64Register::Mm7 => self.mm7, - X64Register::St0 => self.st0, - X64Register::St1 => self.st1, - X64Register::St2 => self.st2, - X64Register::St3 => self.st3, - X64Register::St4 => self.st4, - X64Register::St5 => self.st5, - X64Register::St6 => self.st6, - X64Register::St7 => self.st7, - X64Register::Xmm0 => self.xmm0, - X64Register::Xmm1 => self.xmm1, - X64Register::Xmm2 => self.xmm2, - X64Register::Xmm3 => self.xmm3, - X64Register::Xmm4 => self.xmm4, - X64Register::Xmm5 => self.xmm5, - X64Register::Xmm6 => self.xmm6, - X64Register::Xmm7 => self.xmm7, - X64Register::Xmm8 => self.xmm8, - X64Register::Xmm9 => self.xmm9, - X64Register::Xmm10 => self.xmm10, - X64Register::Xmm11 => self.xmm11, - X64Register::Xmm12 => self.xmm12, - X64Register::Xmm13 => self.xmm13, - X64Register::Xmm14 => self.xmm14, - X64Register::Xmm15 => self.xmm15, - /*X64Register::Xmm16 => self.xmm16, - X64Register::Xmm17 => self.xmm17, - X64Register::Xmm18 => self.xmm18, - X64Register::Xmm19 => self.xmm19, - X64Register::Xmm20 => self.xmm20, - X64Register::Xmm21 => self.xmm21, - X64Register::Xmm22 => self.xmm22, - X64Register::Xmm23 => self.xmm23, - X64Register::Xmm24 => self.xmm24, - X64Register::Xmm25 => self.xmm25, - X64Register::Xmm26 => self.xmm26, - X64Register::Xmm27 => self.xmm27, - X64Register::Xmm28 => self.xmm28, - X64Register::Xmm29 => self.xmm29, - X64Register::Xmm30 => self.xmm30, - X64Register::Xmm31 => self.xmm31,*/ - X64Register::Ymm0 => self.ymm0, - X64Register::Ymm1 => self.ymm1, - X64Register::Ymm2 => self.ymm2, - X64Register::Ymm3 => self.ymm3, - X64Register::Ymm4 => self.ymm4, - X64Register::Ymm5 => self.ymm5, - X64Register::Ymm6 => self.ymm6, - X64Register::Ymm7 => self.ymm7, - X64Register::Ymm8 => self.ymm8, - X64Register::Ymm9 => self.ymm9, - X64Register::Ymm10 => self.ymm10, - X64Register::Ymm11 => self.ymm11, - X64Register::Ymm12 => self.ymm12, - X64Register::Ymm13 => self.ymm13, - X64Register::Ymm14 => self.ymm14, - X64Register::Ymm15 => self.ymm15, - /*X64Register::Ymm16 => self.ymm16, - X64Register::Ymm17 => self.ymm17, - X64Register::Ymm18 => self.ymm18, - X64Register::Ymm19 => self.ymm19, - X64Register::Ymm20 => self.ymm20, - X64Register::Ymm21 => self.ymm21, - X64Register::Ymm22 => self.ymm22, - X64Register::Ymm23 => self.ymm23, - X64Register::Ymm24 => self.ymm24, - X64Register::Ymm25 => self.ymm25, - X64Register::Ymm26 => self.ymm26, - X64Register::Ymm27 => self.ymm27, - X64Register::Ymm28 => self.ymm28, - X64Register::Ymm29 => self.ymm29, - X64Register::Ymm30 => self.ymm30, - X64Register::Ymm31 => self.ymm31,*/ - /*X64Register::Zmm0 => self.zmm0, - X64Register::Zmm1 => self.zmm1, - X64Register::Zmm2 => self.zmm2, - X64Register::Zmm3 => self.zmm3, - X64Register::Zmm4 => self.zmm4, - X64Register::Zmm5 => self.zmm5, - X64Register::Zmm6 => self.zmm6, - X64Register::Zmm7 => self.zmm7, - X64Register::Zmm8 => self.zmm8, - X64Register::Zmm9 => self.zmm9, - X64Register::Zmm10 => self.zmm10, - X64Register::Zmm11 => self.zmm11, - X64Register::Zmm12 => self.zmm12, - X64Register::Zmm13 => self.zmm13, - X64Register::Zmm14 => self.zmm14, - X64Register::Zmm15 => self.zmm15, - X64Register::Zmm16 => self.zmm16, - X64Register::Zmm17 => self.zmm17, - X64Register::Zmm18 => self.zmm18, - X64Register::Zmm19 => self.zmm19, - X64Register::Zmm20 => self.zmm20, - X64Register::Zmm21 => self.zmm21, - X64Register::Zmm22 => self.zmm22, - X64Register::Zmm23 => self.zmm23, - X64Register::Zmm24 => self.zmm24, - X64Register::Zmm25 => self.zmm25, - X64Register::Zmm26 => self.zmm26, - X64Register::Zmm27 => self.zmm27, - X64Register::Zmm28 => self.zmm28, - X64Register::Zmm29 => self.zmm29, - X64Register::Zmm30 => self.zmm30, - X64Register::Zmm31 => self.zmm31,*/ - X64Register::R8b => self.r8b, - X64Register::R9b => self.r9b, - X64Register::R10b => self.r10b, - X64Register::R11b => self.r11b, - X64Register::R12b => self.r12b, - X64Register::R13b => self.r13b, - X64Register::R14b => self.r14b, - X64Register::R15b => self.r15b, - X64Register::R8d => self.r8d, - X64Register::R9d => self.r9d, - X64Register::R10d => self.r10d, - X64Register::R11d => self.r11d, - X64Register::R12d => self.r12d, - X64Register::R13d => self.r13d, - X64Register::R14d => self.r14d, - X64Register::R15d => self.r15d, - X64Register::R8w => self.r8w, - X64Register::R9w => self.r9w, - X64Register::R10w => self.r10w, - X64Register::R11w => self.r11w, - X64Register::R12w => self.r12w, - X64Register::R13w => self.r13w, - X64Register::R14w => self.r14w, - X64Register::R15w => self.r15w, - X64Register::Fpcw => self.fpcw, - X64Register::Fptag => self.fptag, - //X64Register::Msr => self.msr, - X64Register::Mxcsr => self.mxcsr, - X64Register::FsBase => self.fs_base, - X64Register::GsBase => self.gs_base, - X64Register::Fip => self.fip, - X64Register::Fcs => self.fcs, - X64Register::Fdp => self.fdp, - X64Register::Fds => self.fds, - X64Register::Fop => self.fop, + X86Register::Rax => self.rax, + X86Register::Rbx => self.rbx, + X86Register::Rcx => self.rcx, + X86Register::Rdx => self.rdx, + X86Register::Rsi => self.rsi, + X86Register::Rdi => self.rdi, + X86Register::Rbp => self.rbp, + X86Register::Rsp => self.rsp, + X86Register::R8 => self.r8, + X86Register::R9 => self.r9, + X86Register::R10 => self.r10, + X86Register::R11 => self.r11, + X86Register::R12 => self.r12, + X86Register::R13 => self.r13, + X86Register::R14 => self.r14, + X86Register::R15 => self.r15, + X86Register::Rip => self.rip, + X86Register::Cs => self.cs, + X86Register::Ds => self.ds, + X86Register::Es => self.es, + X86Register::Fs => self.fs, + X86Register::Gs => self.gs, + X86Register::Ss => self.ss, + X86Register::Ah => self.ah, + X86Register::Al => self.al, + X86Register::Ax => self.ax, + X86Register::Bh => self.bh, + X86Register::Bl => self.bl, + X86Register::Bpl => self.bpl, + X86Register::Ch => self.ch, + X86Register::Cl => self.cl, + X86Register::Cx => self.cx, + X86Register::Dh => self.dh, + X86Register::Dil => self.dil, + X86Register::Dl => self.dl, + X86Register::Dx => self.dx, + X86Register::Eax => self.eax, + X86Register::Ebp => self.ebp, + X86Register::Ebx => self.ebx, + X86Register::Ecx => self.ecx, + X86Register::Edi => self.edi, + X86Register::Edx => self.edx, + X86Register::Esi => self.esi, + X86Register::Esp => self.esp, + X86Register::Fpsw => self.fpsw, + X86Register::Gdtr => self.gdtr, + X86Register::Idtr => self.idtr, + X86Register::Ldtr => self.ldtr, + X86Register::Tr => self.tr, + X86Register::Cr0 => self.cr0, + X86Register::Cr1 => self.cr1, + X86Register::Cr2 => self.cr2, + X86Register::Cr3 => self.cr3, + X86Register::Cr4 => self.cr4, + X86Register::Cr8 => self.cr8, + X86Register::Dr0 => self.dr0, + X86Register::Dr1 => self.dr1, + X86Register::Dr2 => self.dr2, + X86Register::Dr3 => self.dr3, + X86Register::Dr4 => self.dr4, + X86Register::Dr5 => self.dr5, + X86Register::Dr6 => self.dr6, + X86Register::Dr7 => self.dr7, + X86Register::Fp0 => self.fp0, + X86Register::Fp1 => self.fp1, + X86Register::Fp2 => self.fp2, + X86Register::Fp3 => self.fp3, + X86Register::Fp4 => self.fp4, + X86Register::Fp5 => self.fp5, + X86Register::Fp6 => self.fp6, + X86Register::Fp7 => self.fp7, + /*X86Register::K0 => self.k0, + X86Register::K1 => self.k1, + X86Register::K2 => self.k2, + X86Register::K3 => self.k3, + X86Register::K4 => self.k4, + X86Register::K5 => self.k5, + X86Register::K6 => self.k6, + X86Register::K7 => self.k7,*/ + X86Register::Mm0 => self.mm0, + X86Register::Mm1 => self.mm1, + X86Register::Mm2 => self.mm2, + X86Register::Mm3 => self.mm3, + X86Register::Mm4 => self.mm4, + X86Register::Mm5 => self.mm5, + X86Register::Mm6 => self.mm6, + X86Register::Mm7 => self.mm7, + X86Register::St0 => self.st0, + X86Register::St1 => self.st1, + X86Register::St2 => self.st2, + X86Register::St3 => self.st3, + X86Register::St4 => self.st4, + X86Register::St5 => self.st5, + X86Register::St6 => self.st6, + X86Register::St7 => self.st7, + X86Register::Xmm0 => self.xmm0, + X86Register::Xmm1 => self.xmm1, + X86Register::Xmm2 => self.xmm2, + X86Register::Xmm3 => self.xmm3, + X86Register::Xmm4 => self.xmm4, + X86Register::Xmm5 => self.xmm5, + X86Register::Xmm6 => self.xmm6, + X86Register::Xmm7 => self.xmm7, + X86Register::Xmm8 => self.xmm8, + X86Register::Xmm9 => self.xmm9, + X86Register::Xmm10 => self.xmm10, + X86Register::Xmm11 => self.xmm11, + X86Register::Xmm12 => self.xmm12, + X86Register::Xmm13 => self.xmm13, + X86Register::Xmm14 => self.xmm14, + X86Register::Xmm15 => self.xmm15, + /*X86Register::Xmm16 => self.xmm16, + X86Register::Xmm17 => self.xmm17, + X86Register::Xmm18 => self.xmm18, + X86Register::Xmm19 => self.xmm19, + X86Register::Xmm20 => self.xmm20, + X86Register::Xmm21 => self.xmm21, + X86Register::Xmm22 => self.xmm22, + X86Register::Xmm23 => self.xmm23, + X86Register::Xmm24 => self.xmm24, + X86Register::Xmm25 => self.xmm25, + X86Register::Xmm26 => self.xmm26, + X86Register::Xmm27 => self.xmm27, + X86Register::Xmm28 => self.xmm28, + X86Register::Xmm29 => self.xmm29, + X86Register::Xmm30 => self.xmm30, + X86Register::Xmm31 => self.xmm31,*/ + X86Register::Ymm0 => self.ymm0, + X86Register::Ymm1 => self.ymm1, + X86Register::Ymm2 => self.ymm2, + X86Register::Ymm3 => self.ymm3, + X86Register::Ymm4 => self.ymm4, + X86Register::Ymm5 => self.ymm5, + X86Register::Ymm6 => self.ymm6, + X86Register::Ymm7 => self.ymm7, + X86Register::Ymm8 => self.ymm8, + X86Register::Ymm9 => self.ymm9, + X86Register::Ymm10 => self.ymm10, + X86Register::Ymm11 => self.ymm11, + X86Register::Ymm12 => self.ymm12, + X86Register::Ymm13 => self.ymm13, + X86Register::Ymm14 => self.ymm14, + X86Register::Ymm15 => self.ymm15, + /*X86Register::Ymm16 => self.ymm16, + X86Register::Ymm17 => self.ymm17, + X86Register::Ymm18 => self.ymm18, + X86Register::Ymm19 => self.ymm19, + X86Register::Ymm20 => self.ymm20, + X86Register::Ymm21 => self.ymm21, + X86Register::Ymm22 => self.ymm22, + X86Register::Ymm23 => self.ymm23, + X86Register::Ymm24 => self.ymm24, + X86Register::Ymm25 => self.ymm25, + X86Register::Ymm26 => self.ymm26, + X86Register::Ymm27 => self.ymm27, + X86Register::Ymm28 => self.ymm28, + X86Register::Ymm29 => self.ymm29, + X86Register::Ymm30 => self.ymm30, + X86Register::Ymm31 => self.ymm31,*/ + /*X86Register::Zmm0 => self.zmm0, + X86Register::Zmm1 => self.zmm1, + X86Register::Zmm2 => self.zmm2, + X86Register::Zmm3 => self.zmm3, + X86Register::Zmm4 => self.zmm4, + X86Register::Zmm5 => self.zmm5, + X86Register::Zmm6 => self.zmm6, + X86Register::Zmm7 => self.zmm7, + X86Register::Zmm8 => self.zmm8, + X86Register::Zmm9 => self.zmm9, + X86Register::Zmm10 => self.zmm10, + X86Register::Zmm11 => self.zmm11, + X86Register::Zmm12 => self.zmm12, + X86Register::Zmm13 => self.zmm13, + X86Register::Zmm14 => self.zmm14, + X86Register::Zmm15 => self.zmm15, + X86Register::Zmm16 => self.zmm16, + X86Register::Zmm17 => self.zmm17, + X86Register::Zmm18 => self.zmm18, + X86Register::Zmm19 => self.zmm19, + X86Register::Zmm20 => self.zmm20, + X86Register::Zmm21 => self.zmm21, + X86Register::Zmm22 => self.zmm22, + X86Register::Zmm23 => self.zmm23, + X86Register::Zmm24 => self.zmm24, + X86Register::Zmm25 => self.zmm25, + X86Register::Zmm26 => self.zmm26, + X86Register::Zmm27 => self.zmm27, + X86Register::Zmm28 => self.zmm28, + X86Register::Zmm29 => self.zmm29, + X86Register::Zmm30 => self.zmm30, + X86Register::Zmm31 => self.zmm31,*/ + X86Register::R8b => self.r8b, + X86Register::R9b => self.r9b, + X86Register::R10b => self.r10b, + X86Register::R11b => self.r11b, + X86Register::R12b => self.r12b, + X86Register::R13b => self.r13b, + X86Register::R14b => self.r14b, + X86Register::R15b => self.r15b, + X86Register::R8d => self.r8d, + X86Register::R9d => self.r9d, + X86Register::R10d => self.r10d, + X86Register::R11d => self.r11d, + X86Register::R12d => self.r12d, + X86Register::R13d => self.r13d, + X86Register::R14d => self.r14d, + X86Register::R15d => self.r15d, + X86Register::R8w => self.r8w, + X86Register::R9w => self.r9w, + X86Register::R10w => self.r10w, + X86Register::R11w => self.r11w, + X86Register::R12w => self.r12w, + X86Register::R13w => self.r13w, + X86Register::R14w => self.r14w, + X86Register::R15w => self.r15w, + X86Register::Fpcw => self.fpcw, + X86Register::Fptag => self.fptag, + //X86Register::Msr => self.msr, + X86Register::Mxcsr => self.mxcsr, + X86Register::FsBase => self.fs_base, + X86Register::GsBase => self.gs_base, + X86Register::Fip => self.fip, + X86Register::Fcs => self.fcs, + X86Register::Fdp => self.fdp, + X86Register::Fds => self.fds, + X86Register::Fop => self.fop, _ => panic!("Unsupported register"), } } diff --git a/src/backends/icicle-emulator/icicle_x64_emulator.cpp b/src/backends/icicle-emulator/icicle_x86_64_emulator.cpp similarity index 95% rename from src/backends/icicle-emulator/icicle_x64_emulator.cpp rename to src/backends/icicle-emulator/icicle_x86_64_emulator.cpp index 46276f22..001ccdd5 100644 --- a/src/backends/icicle-emulator/icicle_x64_emulator.cpp +++ b/src/backends/icicle-emulator/icicle_x86_64_emulator.cpp @@ -1,5 +1,5 @@ #define ICICLE_EMULATOR_IMPL -#include "icicle_x64_emulator.hpp" +#include "icicle_x86_64_emulator.hpp" #include @@ -85,10 +85,10 @@ namespace icicle } } - class icicle_x64_emulator : public x64_emulator + class icicle_x86_64_emulator : public x86_64_emulator { public: - icicle_x64_emulator() + icicle_x86_64_emulator() : emu_(icicle_create_emulator()) { if (!this->emu_) @@ -97,7 +97,7 @@ namespace icicle } } - ~icicle_x64_emulator() override + ~icicle_x86_64_emulator() override { if (this->emu_) { @@ -128,20 +128,20 @@ namespace icicle const gdtr entry{.limit = limit, .address = address}; static_assert(sizeof(gdtr) - offsetof(gdtr, limit) == 12); - this->write_register(x64_register::gdtr, &entry.limit, 12); + this->write_register(x86_register::gdtr, &entry.limit, 12); } - void set_segment_base(const x64_register base, const pointer_type value) override + void set_segment_base(const x86_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); + case x86_register::fs: + case x86_register::fs_base: + this->reg(x86_register::fs_base, value); break; - case x64_register::gs: - case x64_register::gs_base: - this->reg(x64_register::gs_base, value); + case x86_register::gs: + case x86_register::gs_base: + this->reg(x86_register::gs_base, value); break; default: break; @@ -226,7 +226,7 @@ namespace icicle emulator_hook* hook_instruction(int instruction_type, instruction_hook_callback callback) override { - if (static_cast(instruction_type) != x64_hookable_instructions::syscall) + if (static_cast(instruction_type) != x86_hookable_instructions::syscall) { // TODO return nullptr; @@ -427,8 +427,8 @@ namespace icicle icicle_emulator* emu_{}; }; - std::unique_ptr create_x64_emulator() + std::unique_ptr create_x86_64_emulator() { - return std::make_unique(); + return std::make_unique(); } } diff --git a/src/backends/icicle-emulator/icicle_x64_emulator.hpp b/src/backends/icicle-emulator/icicle_x86_64_emulator.hpp similarity index 76% rename from src/backends/icicle-emulator/icicle_x64_emulator.hpp rename to src/backends/icicle-emulator/icicle_x86_64_emulator.hpp index 57b408db..bc2ab6fb 100644 --- a/src/backends/icicle-emulator/icicle_x64_emulator.hpp +++ b/src/backends/icicle-emulator/icicle_x86_64_emulator.hpp @@ -1,7 +1,7 @@ #pragma once #include -#include +#include #include "platform/platform.hpp" #ifdef ICICLE_EMULATOR_IMPL @@ -15,5 +15,5 @@ namespace icicle #if !MOMO_BUILD_AS_LIBRARY ICICLE_EMULATOR_DLL_STORAGE #endif - std::unique_ptr create_x64_emulator(); + std::unique_ptr create_x86_64_emulator(); } diff --git a/src/backends/unicorn-emulator/unicorn_x64_emulator.cpp b/src/backends/unicorn-emulator/unicorn_x86_64_emulator.cpp similarity index 95% rename from src/backends/unicorn-emulator/unicorn_x64_emulator.cpp rename to src/backends/unicorn-emulator/unicorn_x86_64_emulator.cpp index d542ed8f..659e6d49 100644 --- a/src/backends/unicorn-emulator/unicorn_x64_emulator.cpp +++ b/src/backends/unicorn-emulator/unicorn_x86_64_emulator.cpp @@ -1,5 +1,5 @@ #define UNICORN_EMULATOR_IMPL -#include "unicorn_x64_emulator.hpp" +#include "unicorn_x86_64_emulator.hpp" #include @@ -18,19 +18,19 @@ namespace unicorn static_assert(static_cast(memory_permission::exec) == UC_PROT_EXEC); static_assert(static_cast(memory_permission::all) == UC_PROT_ALL); - static_assert(static_cast(x64_register::end) == UC_X86_REG_ENDING); + static_assert(static_cast(x86_register::end) == UC_X86_REG_ENDING); - uc_x86_insn map_hookable_instruction(const x64_hookable_instructions instruction) + uc_x86_insn map_hookable_instruction(const x86_hookable_instructions instruction) { switch (instruction) { - case x64_hookable_instructions::syscall: + case x86_hookable_instructions::syscall: return UC_X86_INS_SYSCALL; - case x64_hookable_instructions::cpuid: + case x86_hookable_instructions::cpuid: return UC_X86_INS_CPUID; - case x64_hookable_instructions::rdtsc: + case x86_hookable_instructions::rdtsc: return UC_X86_INS_RDTSC; - case x64_hookable_instructions::rdtscp: + case x86_hookable_instructions::rdtscp: return UC_X86_INS_RDTSCP; default: throw std::runtime_error("Bad instruction for mapping"); @@ -195,10 +195,10 @@ namespace unicorn } } - class unicorn_x64_emulator : public x64_emulator + class unicorn_x86_64_emulator : public x86_64_emulator { public: - unicorn_x64_emulator() + unicorn_x86_64_emulator() { uce(uc_open(UC_ARCH_X86, UC_MODE_64, &this->uc_)); uce(uc_ctl_set_cpu_model(this->uc_, UC_CPU_X86_EPYC_ROME)); @@ -215,7 +215,7 @@ namespace unicorn #endif } - ~unicorn_x64_emulator() override + ~unicorn_x86_64_emulator() override { this->hooks_.clear(); uc_close(this->uc_); @@ -254,10 +254,10 @@ namespace unicorn void load_gdt(const pointer_type address, const uint32_t limit) override { const std::array gdtr = {0, address, limit, 0}; - this->write_register(x64_register::gdtr, gdtr.data(), gdtr.size() * sizeof(uint64_t)); + this->write_register(x86_register::gdtr, gdtr.data(), gdtr.size() * sizeof(uint64_t)); } - void set_segment_base(const x64_register base, const pointer_type value) override + void set_segment_base(const x86_register base, const pointer_type value) override { constexpr auto IA32_FS_BASE_MSR = 0xC0000100; constexpr auto IA32_GS_BASE_MSR = 0xC0000101; @@ -275,19 +275,19 @@ namespace unicorn switch (base) { - case x64_register::fs: - case x64_register::fs_base: + case x86_register::fs: + case x86_register::fs_base: msr_val.id = IA32_FS_BASE_MSR; break; - case x64_register::gs: - case x64_register::gs_base: + case x86_register::gs: + case x86_register::gs_base: msr_val.id = IA32_GS_BASE_MSR; break; default: return; } - this->write_register(x64_register::msr, &msr_val, sizeof(msr_val)); + this->write_register(x86_register::msr, &msr_val, sizeof(msr_val)); } size_t write_raw_register(const int reg, const void* value, const size_t size) override @@ -388,9 +388,9 @@ namespace unicorn unicorn_hook hook{*this}; auto container = std::make_unique(); - const auto inst_type = static_cast(instruction_type); + const auto inst_type = static_cast(instruction_type); - if (inst_type == x64_hookable_instructions::invalid) + 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; @@ -400,7 +400,7 @@ namespace unicorn wrapper.get_user_data(), 0, std::numeric_limits::max())); container->add(std::move(wrapper), std::move(hook)); } - else if (inst_type == x64_hookable_instructions::syscall) + else if (inst_type == x86_hookable_instructions::syscall) { function_wrapper wrapper([c = std::move(callback)](uc_engine*) { c(); }); @@ -708,8 +708,8 @@ namespace unicorn }; } - std::unique_ptr create_x64_emulator() + std::unique_ptr create_x86_64_emulator() { - return std::make_unique(); + return std::make_unique(); } } diff --git a/src/backends/unicorn-emulator/unicorn_x64_emulator.hpp b/src/backends/unicorn-emulator/unicorn_x86_64_emulator.hpp similarity index 76% rename from src/backends/unicorn-emulator/unicorn_x64_emulator.hpp rename to src/backends/unicorn-emulator/unicorn_x86_64_emulator.hpp index 6d5bd48e..a64b399f 100644 --- a/src/backends/unicorn-emulator/unicorn_x64_emulator.hpp +++ b/src/backends/unicorn-emulator/unicorn_x86_64_emulator.hpp @@ -1,7 +1,7 @@ #pragma once #include -#include +#include #include "platform/platform.hpp" #ifdef UNICORN_EMULATOR_IMPL @@ -15,5 +15,5 @@ namespace unicorn #if !MOMO_BUILD_AS_LIBRARY UNICORN_EMULATOR_DLL_STORAGE #endif - std::unique_ptr create_x64_emulator(); + std::unique_ptr create_x86_64_emulator(); } diff --git a/src/emulator/arch_emulator.hpp b/src/emulator/arch_emulator.hpp new file mode 100644 index 00000000..ef218374 --- /dev/null +++ b/src/emulator/arch_emulator.hpp @@ -0,0 +1,66 @@ +/* +Design notes: + +1. emulator: the root interface (provides CPU, memory, and hook interfaces). +2. typed_emulator: a template that adapts to architecture/bitness via the Traits struct. +3. arch_emulator: a thin layer for architecture-specific logic, things that are shared by all x86 (32/64), or + all ARM (32/64), etc. +X. x86_emulator: x86_emulator are specialisations for + x86 and ARM, parameterised by their respective traits (e.g., x86_64_traits) and stuff :) + +1. emulator (cpu_interface, memory_interface, hook_interface) +2. └── typed_emulator +3. └── arch_emulator + ├── x86_emulator + ├── x86_emulator + ├── arm_emulator + └── arm_emulator +*/ + +#pragma once +#include "typed_emulator.hpp" +#include "x86_register.hpp" + +// --[Core]-------------------------------------------------------------------------- + +template +struct arch_emulator : typed_emulator +{ +}; + +template +struct x86_emulator : arch_emulator +{ + using register_type = typename Traits::register_type; + using pointer_type = typename Traits::pointer_type; + + virtual void set_segment_base(register_type base, pointer_type value) = 0; + virtual void load_gdt(pointer_type address, uint32_t limit) = 0; +}; + +template +struct arm_emulator : arch_emulator +{ +}; + +enum class x86_hookable_instructions +{ + invalid, + syscall, + cpuid, + rdtsc, + rdtscp, +}; + +// --[x86_64]------------------------------------------------------------------------- + +struct x86_64_traits +{ + using pointer_type = uint64_t; + using register_type = x86_register; + static constexpr register_type instruction_pointer = x86_register::rip; + static constexpr register_type stack_pointer = x86_register::rsp; + using hookable_instructions = x86_hookable_instructions; +}; + +using x86_64_emulator = x86_emulator; diff --git a/src/emulator/typed_emulator.hpp b/src/emulator/typed_emulator.hpp index 1a67b038..a17b595f 100644 --- a/src/emulator/typed_emulator.hpp +++ b/src/emulator/typed_emulator.hpp @@ -2,18 +2,17 @@ #include "emulator.hpp" -template +template class typed_emulator : public emulator { public: - using registers = Register; - using pointer_type = PointerType; - using hookable_instructions = HookableInstructions; + using registers = typename Traits::register_type; + using pointer_type = typename Traits::pointer_type; + using hookable_instructions = typename Traits::hookable_instructions; static constexpr size_t pointer_size = sizeof(pointer_type); - static constexpr registers stack_pointer = StackPointer; - static constexpr registers instruction_pointer = InstructionPointer; + static constexpr registers stack_pointer = Traits::stack_pointer; + static constexpr registers instruction_pointer = Traits::instruction_pointer; size_t write_register(registers reg, const void* value, const size_t size) { diff --git a/src/emulator/x64_emulator.hpp b/src/emulator/x64_emulator.hpp deleted file mode 100644 index 5eeb1a3c..00000000 --- a/src/emulator/x64_emulator.hpp +++ /dev/null @@ -1,19 +0,0 @@ -#pragma once -#include "typed_emulator.hpp" -#include "x64_register.hpp" - -enum class x64_hookable_instructions -{ - invalid, - syscall, - cpuid, - rdtsc, - rdtscp, -}; - -struct x64_emulator - : typed_emulator -{ - virtual void set_segment_base(x64_register base, pointer_type value) = 0; - virtual void load_gdt(pointer_type address, uint32_t limit) = 0; -}; diff --git a/src/emulator/x64_register.hpp b/src/emulator/x86_register.hpp similarity index 97% rename from src/emulator/x64_register.hpp rename to src/emulator/x86_register.hpp index 9682a966..4e4135e0 100644 --- a/src/emulator/x64_register.hpp +++ b/src/emulator/x86_register.hpp @@ -1,6 +1,7 @@ #pragma once -enum class x64_register +// x86_64 and x86_32 register definitions +enum class x86_register { invalid = 0, ah, diff --git a/src/fuzzer/main.cpp b/src/fuzzer/main.cpp index 0184a3af..9623f7e9 100644 --- a/src/fuzzer/main.cpp +++ b/src/fuzzer/main.cpp @@ -89,8 +89,8 @@ namespace memory_permission::read_write); emu.emu().write_memory(memory, data.data(), data.size()); - emu.emu().reg(x64_register::rcx, memory); - emu.emu().reg(x64_register::rdx, data.size()); + emu.emu().reg(x86_register::rcx, memory); + emu.emu().reg(x86_register::rdx, data.size()); try { diff --git a/src/windows-emulator/apiset/apiset.cpp b/src/windows-emulator/apiset/apiset.cpp index 53492205..c136f796 100644 --- a/src/windows-emulator/apiset/apiset.cpp +++ b/src/windows-emulator/apiset/apiset.cpp @@ -5,7 +5,7 @@ #include "../emulator_utils.hpp" -#include +#include #include #include @@ -14,7 +14,7 @@ namespace apiset { namespace { - uint64_t copy_string(x64_emulator& emu, emulator_allocator& allocator, const void* base_ptr, + uint64_t copy_string(x86_64_emulator& emu, emulator_allocator& allocator, const void* base_ptr, const uint64_t offset, const size_t length) { if (!length) @@ -29,7 +29,7 @@ namespace apiset return str_obj; } - ULONG copy_string_as_relative(x64_emulator& emu, emulator_allocator& allocator, const uint64_t result_base, + ULONG copy_string_as_relative(x86_64_emulator& emu, emulator_allocator& allocator, const uint64_t result_base, const void* base_ptr, const uint64_t offset, const size_t length) { const auto address = copy_string(emu, allocator, base_ptr, offset, length); @@ -115,13 +115,13 @@ namespace apiset return obtain(apiset_loc, root); } - emulator_object clone(x64_emulator& emu, emulator_allocator& allocator, + emulator_object clone(x86_64_emulator& emu, emulator_allocator& allocator, const container& container) { return clone(emu, allocator, container.get()); } - emulator_object clone(x64_emulator& emu, emulator_allocator& allocator, + emulator_object clone(x86_64_emulator& emu, emulator_allocator& allocator, const API_SET_NAMESPACE& orig_api_set_map) { const auto api_set_map_obj = allocator.reserve(); diff --git a/src/windows-emulator/apiset/apiset.hpp b/src/windows-emulator/apiset/apiset.hpp index 55deda12..cde53b19 100644 --- a/src/windows-emulator/apiset/apiset.hpp +++ b/src/windows-emulator/apiset/apiset.hpp @@ -29,9 +29,9 @@ namespace apiset container obtain(location location, const std::filesystem::path& root); container obtain(const std::filesystem::path& root); - emulator_object clone(x64_emulator& emu, emulator_allocator& allocator, + emulator_object clone(x86_64_emulator& emu, emulator_allocator& allocator, const API_SET_NAMESPACE& orig_api_set_map); - emulator_object clone(x64_emulator& emu, emulator_allocator& allocator, + emulator_object clone(x86_64_emulator& emu, emulator_allocator& allocator, const container& container); } diff --git a/src/windows-emulator/cpu_context.cpp b/src/windows-emulator/cpu_context.cpp index 3fd234ba..0d397393 100644 --- a/src/windows-emulator/cpu_context.cpp +++ b/src/windows-emulator/cpu_context.cpp @@ -3,147 +3,147 @@ namespace cpu_context { - void restore(x64_emulator& emu, const CONTEXT64& context) + void restore(x86_64_emulator& emu, const CONTEXT64& context) { if ((context.ContextFlags & CONTEXT_DEBUG_REGISTERS_64) == CONTEXT_DEBUG_REGISTERS_64) { - emu.reg(x64_register::dr0, context.Dr0); - emu.reg(x64_register::dr1, context.Dr1); - emu.reg(x64_register::dr2, context.Dr2); - emu.reg(x64_register::dr3, context.Dr3); - emu.reg(x64_register::dr6, context.Dr6); - emu.reg(x64_register::dr7, context.Dr7); + emu.reg(x86_register::dr0, context.Dr0); + emu.reg(x86_register::dr1, context.Dr1); + emu.reg(x86_register::dr2, context.Dr2); + emu.reg(x86_register::dr3, context.Dr3); + emu.reg(x86_register::dr6, context.Dr6); + emu.reg(x86_register::dr7, context.Dr7); } if ((context.ContextFlags & CONTEXT_CONTROL_64) == CONTEXT_CONTROL_64) { - emu.reg(x64_register::ss, context.SegSs); - emu.reg(x64_register::cs, context.SegCs); + emu.reg(x86_register::ss, context.SegSs); + emu.reg(x86_register::cs, context.SegCs); - emu.reg(x64_register::rip, context.Rip); - emu.reg(x64_register::rsp, context.Rsp); + emu.reg(x86_register::rip, context.Rip); + emu.reg(x86_register::rsp, context.Rsp); - emu.reg(x64_register::eflags, context.EFlags); + emu.reg(x86_register::eflags, context.EFlags); } if ((context.ContextFlags & CONTEXT_INTEGER_64) == CONTEXT_INTEGER_64) { - emu.reg(x64_register::rax, context.Rax); - emu.reg(x64_register::rbx, context.Rbx); - emu.reg(x64_register::rcx, context.Rcx); - emu.reg(x64_register::rdx, context.Rdx); - emu.reg(x64_register::rbp, context.Rbp); - emu.reg(x64_register::rsi, context.Rsi); - emu.reg(x64_register::rdi, context.Rdi); - emu.reg(x64_register::r8, context.R8); - emu.reg(x64_register::r9, context.R9); - emu.reg(x64_register::r10, context.R10); - emu.reg(x64_register::r11, context.R11); - emu.reg(x64_register::r12, context.R12); - emu.reg(x64_register::r13, context.R13); - emu.reg(x64_register::r14, context.R14); - emu.reg(x64_register::r15, context.R15); + emu.reg(x86_register::rax, context.Rax); + emu.reg(x86_register::rbx, context.Rbx); + emu.reg(x86_register::rcx, context.Rcx); + emu.reg(x86_register::rdx, context.Rdx); + emu.reg(x86_register::rbp, context.Rbp); + emu.reg(x86_register::rsi, context.Rsi); + emu.reg(x86_register::rdi, context.Rdi); + emu.reg(x86_register::r8, context.R8); + emu.reg(x86_register::r9, context.R9); + emu.reg(x86_register::r10, context.R10); + emu.reg(x86_register::r11, context.R11); + emu.reg(x86_register::r12, context.R12); + emu.reg(x86_register::r13, context.R13); + emu.reg(x86_register::r14, context.R14); + emu.reg(x86_register::r15, context.R15); } /*if ((context.ContextFlags & CONTEXT_SEGMENTS) == CONTEXT_SEGMENTS) { - emu.reg(x64_register::ds, context.SegDs); - emu.reg(x64_register::es, context.SegEs); - emu.reg(x64_register::fs, context.SegFs); - emu.reg(x64_register::gs, context.SegGs); + emu.reg(x86_register::ds, context.SegDs); + emu.reg(x86_register::es, context.SegEs); + emu.reg(x86_register::fs, context.SegFs); + emu.reg(x86_register::gs, context.SegGs); }*/ if ((context.ContextFlags & CONTEXT_FLOATING_POINT_64) == CONTEXT_FLOATING_POINT_64) { - emu.reg(x64_register::fpcw, context.FltSave.ControlWord); - emu.reg(x64_register::fpsw, context.FltSave.StatusWord); - emu.reg(x64_register::fptag, context.FltSave.TagWord); + emu.reg(x86_register::fpcw, context.FltSave.ControlWord); + emu.reg(x86_register::fpsw, context.FltSave.StatusWord); + emu.reg(x86_register::fptag, context.FltSave.TagWord); for (int i = 0; i < 8; i++) { - const auto reg = static_cast(static_cast(x64_register::st0) + i); + const auto reg = static_cast(static_cast(x86_register::st0) + i); emu.reg(reg, context.FltSave.FloatRegisters[i]); } } if ((context.ContextFlags & CONTEXT_XSTATE_64) == CONTEXT_XSTATE_64) { - emu.reg(x64_register::mxcsr, context.MxCsr); + emu.reg(x86_register::mxcsr, context.MxCsr); for (int i = 0; i < 16; i++) { - const auto reg = static_cast(static_cast(x64_register::xmm0) + i); + const auto reg = static_cast(static_cast(x86_register::xmm0) + i); emu.reg(reg, (&context.Xmm0)[i]); } } } - void save(x64_emulator& emu, CONTEXT64& context) + void save(x86_64_emulator& emu, CONTEXT64& context) { if ((context.ContextFlags & CONTEXT_DEBUG_REGISTERS_64) == CONTEXT_DEBUG_REGISTERS_64) { - context.Dr0 = emu.reg(x64_register::dr0); - context.Dr1 = emu.reg(x64_register::dr1); - context.Dr2 = emu.reg(x64_register::dr2); - context.Dr3 = emu.reg(x64_register::dr3); - context.Dr6 = emu.reg(x64_register::dr6); - context.Dr7 = emu.reg(x64_register::dr7); + context.Dr0 = emu.reg(x86_register::dr0); + context.Dr1 = emu.reg(x86_register::dr1); + context.Dr2 = emu.reg(x86_register::dr2); + context.Dr3 = emu.reg(x86_register::dr3); + context.Dr6 = emu.reg(x86_register::dr6); + context.Dr7 = emu.reg(x86_register::dr7); } if ((context.ContextFlags & CONTEXT_CONTROL_64) == CONTEXT_CONTROL_64) { - context.SegSs = emu.reg(x64_register::ss); - context.SegCs = emu.reg(x64_register::cs); - context.Rip = emu.reg(x64_register::rip); - context.Rsp = emu.reg(x64_register::rsp); - context.EFlags = emu.reg(x64_register::eflags); + context.SegSs = emu.reg(x86_register::ss); + context.SegCs = emu.reg(x86_register::cs); + context.Rip = emu.reg(x86_register::rip); + context.Rsp = emu.reg(x86_register::rsp); + context.EFlags = emu.reg(x86_register::eflags); } if ((context.ContextFlags & CONTEXT_INTEGER_64) == CONTEXT_INTEGER_64) { - context.Rax = emu.reg(x64_register::rax); - context.Rbx = emu.reg(x64_register::rbx); - context.Rcx = emu.reg(x64_register::rcx); - context.Rdx = emu.reg(x64_register::rdx); - context.Rbp = emu.reg(x64_register::rbp); - context.Rsi = emu.reg(x64_register::rsi); - context.Rdi = emu.reg(x64_register::rdi); - context.R8 = emu.reg(x64_register::r8); - context.R9 = emu.reg(x64_register::r9); - context.R10 = emu.reg(x64_register::r10); - context.R11 = emu.reg(x64_register::r11); - context.R12 = emu.reg(x64_register::r12); - context.R13 = emu.reg(x64_register::r13); - context.R14 = emu.reg(x64_register::r14); - context.R15 = emu.reg(x64_register::r15); + context.Rax = emu.reg(x86_register::rax); + context.Rbx = emu.reg(x86_register::rbx); + context.Rcx = emu.reg(x86_register::rcx); + context.Rdx = emu.reg(x86_register::rdx); + context.Rbp = emu.reg(x86_register::rbp); + context.Rsi = emu.reg(x86_register::rsi); + context.Rdi = emu.reg(x86_register::rdi); + context.R8 = emu.reg(x86_register::r8); + context.R9 = emu.reg(x86_register::r9); + context.R10 = emu.reg(x86_register::r10); + context.R11 = emu.reg(x86_register::r11); + context.R12 = emu.reg(x86_register::r12); + context.R13 = emu.reg(x86_register::r13); + context.R14 = emu.reg(x86_register::r14); + context.R15 = emu.reg(x86_register::r15); } if ((context.ContextFlags & CONTEXT_SEGMENTS_64) == CONTEXT_SEGMENTS_64) { - context.SegDs = emu.reg(x64_register::ds); - context.SegEs = emu.reg(x64_register::es); - context.SegFs = emu.reg(x64_register::fs); - context.SegGs = emu.reg(x64_register::gs); + context.SegDs = emu.reg(x86_register::ds); + context.SegEs = emu.reg(x86_register::es); + context.SegFs = emu.reg(x86_register::fs); + context.SegGs = emu.reg(x86_register::gs); } if ((context.ContextFlags & CONTEXT_FLOATING_POINT_64) == CONTEXT_FLOATING_POINT_64) { - context.FltSave.ControlWord = emu.reg(x64_register::fpcw); - context.FltSave.StatusWord = emu.reg(x64_register::fpsw); - context.FltSave.TagWord = static_cast(emu.reg(x64_register::fptag)); + context.FltSave.ControlWord = emu.reg(x86_register::fpcw); + context.FltSave.StatusWord = emu.reg(x86_register::fpsw); + context.FltSave.TagWord = static_cast(emu.reg(x86_register::fptag)); for (int i = 0; i < 8; i++) { - const auto reg = static_cast(static_cast(x64_register::st0) + i); + const auto reg = static_cast(static_cast(x86_register::st0) + i); context.FltSave.FloatRegisters[i] = emu.reg(reg); } } if ((context.ContextFlags & CONTEXT_INTEGER_64) == CONTEXT_INTEGER_64) { - context.MxCsr = emu.reg(x64_register::mxcsr); + context.MxCsr = emu.reg(x86_register::mxcsr); for (int i = 0; i < 16; i++) { - const auto reg = static_cast(static_cast(x64_register::xmm0) + i); + const auto reg = static_cast(static_cast(x86_register::xmm0) + i); (&context.Xmm0)[i] = emu.reg(reg); } } diff --git a/src/windows-emulator/cpu_context.hpp b/src/windows-emulator/cpu_context.hpp index c702e002..528ff8ef 100644 --- a/src/windows-emulator/cpu_context.hpp +++ b/src/windows-emulator/cpu_context.hpp @@ -1,8 +1,8 @@ #pragma once -#include "x64_emulator.hpp" +#include "arch_emulator.hpp" namespace cpu_context { - void save(x64_emulator& emu, CONTEXT64& context); - void restore(x64_emulator& emu, const CONTEXT64& context); + void save(x86_64_emulator& emu, CONTEXT64& context); + void restore(x86_64_emulator& emu, const CONTEXT64& context); } diff --git a/src/windows-emulator/emulator_thread.cpp b/src/windows-emulator/emulator_thread.cpp index c3f86a34..e3628706 100644 --- a/src/windows-emulator/emulator_thread.cpp +++ b/src/windows-emulator/emulator_thread.cpp @@ -7,25 +7,26 @@ namespace { template - emulator_object allocate_object_on_stack(x64_emulator& emu) + emulator_object allocate_object_on_stack(x86_64_emulator& emu) { - const auto old_sp = emu.reg(x64_register::rsp); - const auto new_sp = align_down(old_sp - sizeof(T), std::max(alignof(T), alignof(x64_emulator::pointer_type))); - emu.reg(x64_register::rsp, new_sp); + const auto old_sp = emu.reg(x86_register::rsp); + const auto new_sp = + align_down(old_sp - sizeof(T), std::max(alignof(T), alignof(x86_64_emulator::pointer_type))); + emu.reg(x86_register::rsp, new_sp); return {emu, new_sp}; } - void unalign_stack(x64_emulator& emu) + void unalign_stack(x86_64_emulator& emu) { - auto sp = emu.reg(x64_register::rsp); + auto sp = emu.reg(x86_register::rsp); sp = align_down(sp - 0x10, 0x10) + 8; - emu.reg(x64_register::rsp, sp); + emu.reg(x86_register::rsp, sp); } - void setup_stack(x64_emulator& emu, const uint64_t stack_base, const size_t stack_size) + void setup_stack(x86_64_emulator& emu, const uint64_t stack_base, const size_t stack_size) { const uint64_t stack_end = stack_base + stack_size; - emu.reg(x64_register::rsp, stack_end); + emu.reg(x86_register::rsp, stack_end); } bool is_object_signaled(process_context& c, const handle h, const uint32_t current_thread_id) @@ -207,7 +208,7 @@ bool emulator_thread::is_thread_ready(process_context& process, utils::clock& cl return true; } -void emulator_thread::setup_registers(x64_emulator& emu, const process_context& context) const +void emulator_thread::setup_registers(x86_64_emulator& emu, const process_context& context) const { if (!this->gs_segment) { @@ -215,7 +216,7 @@ void emulator_thread::setup_registers(x64_emulator& emu, const process_context& } setup_stack(emu, this->stack_base, static_cast(this->stack_size)); - emu.set_segment_base(x64_register::gs, this->gs_segment->get_base()); + emu.set_segment_base(x86_register::gs, this->gs_segment->get_base()); CONTEXT64 ctx{}; ctx.ContextFlags = CONTEXT64_ALL; @@ -232,7 +233,7 @@ void emulator_thread::setup_registers(x64_emulator& emu, const process_context& unalign_stack(emu); - emu.reg(x64_register::rcx, ctx_obj.value()); - emu.reg(x64_register::rdx, context.ntdll_image_base); - emu.reg(x64_register::rip, context.ldr_initialize_thunk); + emu.reg(x86_register::rcx, ctx_obj.value()); + emu.reg(x86_register::rdx, context.ntdll_image_base); + emu.reg(x86_register::rip, context.ldr_initialize_thunk); } diff --git a/src/windows-emulator/emulator_thread.hpp b/src/windows-emulator/emulator_thread.hpp index 07e3ed12..e9907d08 100644 --- a/src/windows-emulator/emulator_thread.hpp +++ b/src/windows-emulator/emulator_thread.hpp @@ -105,17 +105,17 @@ class emulator_thread : public ref_counted_object bool is_thread_ready(process_context& process, utils::clock& clock); - void save(x64_emulator& emu) + void save(x86_64_emulator& emu) { this->last_registers = emu.save_registers(); } - void restore(x64_emulator& emu) const + void restore(x86_64_emulator& emu) const { emu.restore_registers(this->last_registers); } - void setup_if_necessary(x64_emulator& emu, const process_context& context) + void setup_if_necessary(x86_64_emulator& emu, const process_context& context) { if (!this->executed_instructions) { @@ -127,7 +127,7 @@ class emulator_thread : public ref_counted_object const auto status = *this->pending_status; this->pending_status = {}; - emu.reg(x64_register::rax, static_cast(status)); + emu.reg(x86_register::rax, static_cast(status)); } } @@ -211,7 +211,7 @@ class emulator_thread : public ref_counted_object } private: - void setup_registers(x64_emulator& emu, const process_context& context) const; + void setup_registers(x86_64_emulator& emu, const process_context& context) const; void release() { diff --git a/src/windows-emulator/emulator_utils.hpp b/src/windows-emulator/emulator_utils.hpp index ba0932be..e339d50e 100644 --- a/src/windows-emulator/emulator_utils.hpp +++ b/src/windows-emulator/emulator_utils.hpp @@ -1,6 +1,6 @@ #pragma once -#include +#include #include "memory_manager.hpp" #include "memory_utils.hpp" @@ -51,7 +51,7 @@ class module_manager; struct process_context; using clock_wrapper = object_wrapper; -using x64_emulator_wrapper = object_wrapper; +using x64_emulator_wrapper = object_wrapper; using memory_manager_wrapper = object_wrapper; using module_manager_wrapper = object_wrapper; using process_context_wrapper = object_wrapper; diff --git a/src/windows-emulator/exception_dispatch.cpp b/src/windows-emulator/exception_dispatch.cpp index b3bd0b3f..e4626cf2 100644 --- a/src/windows-emulator/exception_dispatch.cpp +++ b/src/windows-emulator/exception_dispatch.cpp @@ -89,7 +89,7 @@ namespace uint64_t ss; }; - void dispatch_exception_pointers(x64_emulator& emu, const uint64_t dispatcher, + void dispatch_exception_pointers(x86_64_emulator& emu, const uint64_t dispatcher, const EMU_EXCEPTION_POINTERS> pointers) { constexpr auto mach_frame_size = 0x40; @@ -102,7 +102,7 @@ namespace const auto allocation_size = combined_size + mach_frame_size; - const auto initial_sp = emu.reg(x64_register::rsp); + const auto initial_sp = emu.reg(x86_register::rsp); const auto new_sp = align_down(initial_sp - allocation_size, 0x100); const auto total_size = initial_sp - new_sp; @@ -113,8 +113,8 @@ namespace emu.write_memory(new_sp, zero_memory.data(), zero_memory.size()); - emu.reg(x64_register::rsp, new_sp); - emu.reg(x64_register::rip, dispatcher); + emu.reg(x86_register::rsp, new_sp); + emu.reg(x86_register::rip, dispatcher); const emulator_object context_record_obj{emu, new_sp}; context_record_obj.write(*reinterpret_cast(pointers.ContextRecord)); @@ -140,7 +140,7 @@ namespace } } -void dispatch_exception(x64_emulator& emu, const process_context& proc, const DWORD status, +void dispatch_exception(x86_64_emulator& emu, const process_context& proc, const DWORD status, const std::vector::ULONG_PTR>& parameters) { CONTEXT64 ctx{}; @@ -172,7 +172,7 @@ void dispatch_exception(x64_emulator& emu, const process_context& proc, const DW dispatch_exception_pointers(emu, proc.ki_user_exception_dispatcher, pointers); } -void dispatch_access_violation(x64_emulator& emu, const process_context& proc, const uint64_t address, +void dispatch_access_violation(x86_64_emulator& emu, const process_context& proc, const uint64_t address, const memory_operation operation) { dispatch_exception(emu, proc, STATUS_ACCESS_VIOLATION, @@ -182,22 +182,22 @@ void dispatch_access_violation(x64_emulator& emu, const process_context& proc, c }); } -void dispatch_illegal_instruction_violation(x64_emulator& emu, const process_context& proc) +void dispatch_illegal_instruction_violation(x86_64_emulator& emu, const process_context& proc) { dispatch_exception(emu, proc, STATUS_ILLEGAL_INSTRUCTION, {}); } -void dispatch_integer_division_by_zero(x64_emulator& emu, const process_context& proc) +void dispatch_integer_division_by_zero(x86_64_emulator& emu, const process_context& proc) { dispatch_exception(emu, proc, STATUS_INTEGER_DIVIDE_BY_ZERO, {}); } -void dispatch_single_step(x64_emulator& emu, const process_context& proc) +void dispatch_single_step(x86_64_emulator& emu, const process_context& proc) { dispatch_exception(emu, proc, STATUS_SINGLE_STEP, {}); } -void dispatch_breakpoint(x64_emulator& emu, const process_context& proc) +void dispatch_breakpoint(x86_64_emulator& emu, const process_context& proc) { dispatch_exception(emu, proc, STATUS_BREAKPOINT, {}); } diff --git a/src/windows-emulator/exception_dispatch.hpp b/src/windows-emulator/exception_dispatch.hpp index c324399e..4a717c3d 100644 --- a/src/windows-emulator/exception_dispatch.hpp +++ b/src/windows-emulator/exception_dispatch.hpp @@ -1,25 +1,25 @@ #pragma once -#include +#include #include #include struct process_context; -void dispatch_exception(x64_emulator& emu, const process_context& proc, DWORD status, +void dispatch_exception(x86_64_emulator& emu, const process_context& proc, DWORD status, const std::vector::ULONG_PTR>& parameters); template requires(std::is_integral_v && !std::is_same_v) -void dispatch_exception(x64_emulator& emu, const process_context& proc, const T status, +void dispatch_exception(x86_64_emulator& emu, const process_context& proc, const T status, const std::vector::ULONG_PTR>& parameters) { dispatch_exception(emu, proc, static_cast(status), parameters); } -void dispatch_access_violation(x64_emulator& emu, const process_context& proc, uint64_t address, +void dispatch_access_violation(x86_64_emulator& emu, const process_context& proc, uint64_t address, memory_operation operation); -void dispatch_illegal_instruction_violation(x64_emulator& emu, const process_context& proc); -void dispatch_integer_division_by_zero(x64_emulator& emu, const process_context& proc); -void dispatch_single_step(x64_emulator& emu, const process_context& proc); -void dispatch_breakpoint(x64_emulator& emu, const process_context& proc); +void dispatch_illegal_instruction_violation(x86_64_emulator& emu, const process_context& proc); +void dispatch_integer_division_by_zero(x86_64_emulator& emu, const process_context& proc); +void dispatch_single_step(x86_64_emulator& emu, const process_context& proc); +void dispatch_breakpoint(x86_64_emulator& emu, const process_context& proc); diff --git a/src/windows-emulator/io_device.hpp b/src/windows-emulator/io_device.hpp index d5a8353a..1ff9faf1 100644 --- a/src/windows-emulator/io_device.hpp +++ b/src/windows-emulator/io_device.hpp @@ -1,7 +1,7 @@ #pragma once #include -#include +#include #include #include "emulator_utils.hpp" @@ -22,7 +22,7 @@ struct io_device_context emulator_pointer output_buffer{}; ULONG output_buffer_length{}; - io_device_context(x64_emulator& emu) + io_device_context(x86_64_emulator& emu) : io_status_block(emu) { } diff --git a/src/windows-emulator/kusd_mmio.hpp b/src/windows-emulator/kusd_mmio.hpp index bba54287..449b534b 100644 --- a/src/windows-emulator/kusd_mmio.hpp +++ b/src/windows-emulator/kusd_mmio.hpp @@ -3,7 +3,7 @@ #include "std_include.hpp" #include -#include "x64_emulator.hpp" +#include "arch_emulator.hpp" #include diff --git a/src/windows-emulator/process_context.cpp b/src/windows-emulator/process_context.cpp index 1ff0eb66..bb0dd610 100644 --- a/src/windows-emulator/process_context.cpp +++ b/src/windows-emulator/process_context.cpp @@ -14,20 +14,20 @@ namespace return emulator_allocator{memory, base, size}; } - void setup_gdt(x64_emulator& emu, memory_manager& memory) + void setup_gdt(x86_64_emulator& emu, memory_manager& memory) { memory.allocate_memory(GDT_ADDR, GDT_LIMIT, memory_permission::read); emu.load_gdt(GDT_ADDR, GDT_LIMIT); emu.write_memory(GDT_ADDR + 6 * (sizeof(uint64_t)), 0xEFFE000000FFFF); - emu.reg(x64_register::cs, 0x33); + emu.reg(x86_register::cs, 0x33); emu.write_memory(GDT_ADDR + 5 * (sizeof(uint64_t)), 0xEFF6000000FFFF); - emu.reg(x64_register::ss, 0x2B); + emu.reg(x86_register::ss, 0x2B); } } -void process_context::setup(x64_emulator& emu, memory_manager& memory, const application_settings& app_settings, +void process_context::setup(x86_64_emulator& emu, memory_manager& memory, const application_settings& app_settings, const mapped_module& executable, const mapped_module& ntdll, const apiset::container& apiset_container) { diff --git a/src/windows-emulator/process_context.hpp b/src/windows-emulator/process_context.hpp index 02d4cf17..293b7d03 100644 --- a/src/windows-emulator/process_context.hpp +++ b/src/windows-emulator/process_context.hpp @@ -7,7 +7,7 @@ #include "module/module_manager.hpp" #include -#include +#include #include "io_device.hpp" #include "kusd_mmio.hpp" @@ -50,7 +50,7 @@ struct process_context atom_entry() = default; }; - process_context(x64_emulator& emu, memory_manager& memory, utils::clock& clock, callbacks& cb) + process_context(x86_64_emulator& emu, memory_manager& memory, utils::clock& clock, callbacks& cb) : callbacks_(&cb), base_allocator(emu), peb(emu), @@ -59,7 +59,7 @@ struct process_context { } - void setup(x64_emulator& emu, memory_manager& memory, const application_settings& app_settings, + void setup(x86_64_emulator& emu, memory_manager& memory, const application_settings& app_settings, const mapped_module& executable, const mapped_module& ntdll, const apiset::container& apiset_container); handle create_thread(memory_manager& memory, uint64_t start_address, uint64_t argument, uint64_t stack_size, diff --git a/src/windows-emulator/syscall_dispatcher.cpp b/src/windows-emulator/syscall_dispatcher.cpp index e652c69a..164da74b 100644 --- a/src/windows-emulator/syscall_dispatcher.cpp +++ b/src/windows-emulator/syscall_dispatcher.cpp @@ -65,7 +65,7 @@ void syscall_dispatcher::dispatch(windows_emulator& win_emu) auto& context = win_emu.process; const auto address = emu.read_instruction_pointer(); - const auto syscall_id = emu.reg(x64_register::eax); + const auto syscall_id = emu.reg(x86_register::eax); const syscall_context c{ .win_emu = win_emu, @@ -82,7 +82,7 @@ void syscall_dispatcher::dispatch(windows_emulator& win_emu) if (entry == this->handlers_.end()) { win_emu.log.error("Unknown syscall: 0x%X\n", syscall_id); - c.emu.reg(x64_register::rax, STATUS_NOT_SUPPORTED); + c.emu.reg(x86_register::rax, STATUS_NOT_SUPPORTED); c.emu.stop(); return; } @@ -97,7 +97,7 @@ void syscall_dispatcher::dispatch(windows_emulator& win_emu) if (!entry->second.handler) { win_emu.log.error("Unimplemented syscall: %s - 0x%X\n", entry->second.name.c_str(), syscall_id); - c.emu.reg(x64_register::rax, STATUS_NOT_SUPPORTED); + c.emu.reg(x86_register::rax, STATUS_NOT_SUPPORTED); c.emu.stop(); return; } @@ -139,13 +139,13 @@ void syscall_dispatcher::dispatch(windows_emulator& win_emu) catch (std::exception& e) { win_emu.log.error("Syscall threw an exception: %X (0x%" PRIx64 ") - %s\n", syscall_id, address, e.what()); - emu.reg(x64_register::rax, STATUS_UNSUCCESSFUL); + emu.reg(x86_register::rax, STATUS_UNSUCCESSFUL); emu.stop(); } catch (...) { win_emu.log.error("Syscall threw an unknown exception: %X (0x%" PRIx64 ")\n", syscall_id, address); - emu.reg(x64_register::rax, STATUS_UNSUCCESSFUL); + emu.reg(x86_register::rax, STATUS_UNSUCCESSFUL); emu.stop(); } } diff --git a/src/windows-emulator/syscall_utils.hpp b/src/windows-emulator/syscall_utils.hpp index 697e13e8..392daa89 100644 --- a/src/windows-emulator/syscall_utils.hpp +++ b/src/windows-emulator/syscall_utils.hpp @@ -7,24 +7,24 @@ struct syscall_context { windows_emulator& win_emu; - x64_emulator& emu; + x86_64_emulator& emu; process_context& proc; mutable bool write_status{true}; mutable bool retrigger_syscall{false}; }; -inline uint64_t get_syscall_argument(x64_emulator& emu, const size_t index) +inline uint64_t get_syscall_argument(x86_64_emulator& emu, const size_t index) { switch (index) { case 0: - return emu.reg(x64_register::r10); + return emu.reg(x86_register::r10); case 1: - return emu.reg(x64_register::rdx); + return emu.reg(x86_register::rdx); case 2: - return emu.reg(x64_register::r8); + return emu.reg(x86_register::r8); case 3: - return emu.reg(x64_register::r9); + return emu.reg(x86_register::r9); default: return emu.read_stack(index + 1); } @@ -110,7 +110,7 @@ inline void map_syscalls(std::map& handlers, st template requires(std::is_integral_v || std::is_enum_v) -T resolve_argument(x64_emulator& emu, const size_t index) +T resolve_argument(x86_64_emulator& emu, const size_t index) { const auto arg = get_syscall_argument(emu, index); return static_cast(arg); @@ -118,7 +118,7 @@ T resolve_argument(x64_emulator& emu, const size_t index) template requires(std::is_same_v, handle>) -handle resolve_argument(x64_emulator& emu, const size_t index) +handle resolve_argument(x86_64_emulator& emu, const size_t index) { handle h{}; h.bits = resolve_argument(emu, index); @@ -127,14 +127,14 @@ handle resolve_argument(x64_emulator& emu, const size_t index) template requires(std::is_same_v>) -T resolve_argument(x64_emulator& emu, const size_t index) +T resolve_argument(x86_64_emulator& emu, const size_t index) { const auto arg = get_syscall_argument(emu, index); return T(emu, arg); } template -T resolve_indexed_argument(x64_emulator& emu, size_t& index) +T resolve_indexed_argument(x86_64_emulator& emu, size_t& index) { return resolve_argument(emu, index++); } @@ -143,13 +143,13 @@ inline void write_syscall_status(const syscall_context& c, const NTSTATUS status { if (c.write_status && !c.retrigger_syscall) { - c.emu.reg(x64_register::rax, static_cast(status)); + c.emu.reg(x86_register::rax, static_cast(status)); } const auto new_ip = c.emu.read_instruction_pointer(); if (initial_ip != new_ip || c.retrigger_syscall) { - c.emu.reg(x64_register::rip, new_ip - 2); + c.emu.reg(x86_register::rip, new_ip - 2); } } @@ -197,7 +197,7 @@ void write_attribute(emulator& emu, const PS_ATTRIBUTE& attribute, const } template -NTSTATUS handle_query_internal(x64_emulator& emu, const uint64_t buffer, const uint32_t length, +NTSTATUS handle_query_internal(x86_64_emulator& emu, const uint64_t buffer, const uint32_t length, const ReturnLengthSetter& return_length_setter, const Action& action) { constexpr auto required_size = sizeof(ResponseType); @@ -217,7 +217,7 @@ NTSTATUS handle_query_internal(x64_emulator& emu, const uint64_t buffer, const u } template -NTSTATUS handle_query(x64_emulator& emu, const uint64_t buffer, const uint32_t length, +NTSTATUS handle_query(x86_64_emulator& emu, const uint64_t buffer, const uint32_t length, const emulator_object return_length, const Action& action) { const auto length_setter = [&](const uint32_t required_size) { @@ -231,7 +231,7 @@ NTSTATUS handle_query(x64_emulator& emu, const uint64_t buffer, const uint32_t l } template -NTSTATUS handle_query(x64_emulator& emu, const uint64_t buffer, const uint32_t length, +NTSTATUS handle_query(x86_64_emulator& emu, const uint64_t buffer, const uint32_t length, const emulator_object>> io_status_block, const Action& action) { diff --git a/src/windows-emulator/windows_emulator.cpp b/src/windows-emulator/windows_emulator.cpp index 99aef9cf..c5f90080 100644 --- a/src/windows-emulator/windows_emulator.cpp +++ b/src/windows-emulator/windows_emulator.cpp @@ -3,10 +3,10 @@ #include "cpu_context.hpp" -#include +#include #if MOMO_ENABLE_RUST_CODE -#include +#include #endif #include @@ -117,13 +117,13 @@ namespace ctx.ContextFlags = CONTEXT64_ALL; cpu_context::save(emu, ctx); - const auto initial_sp = emu.reg(x64_register::rsp); + const auto initial_sp = emu.reg(x86_register::rsp); const auto new_sp = align_down(initial_sp - sizeof(stack_layout), 0x100); emu.write_memory(new_sp, stack_layout); - emu.reg(x64_register::rsp, new_sp); - emu.reg(x64_register::rip, win_emu.process.ki_user_apc_dispatcher); + emu.reg(x86_register::rsp, new_sp); + emu.reg(x86_register::rip, win_emu.process.ki_user_apc_dispatcher); } bool switch_to_thread(windows_emulator& win_emu, emulator_thread& thread, const bool force = false) @@ -267,22 +267,22 @@ namespace } } -std::unique_ptr create_default_x64_emulator() +std::unique_ptr create_default_x86_64_emulator() { #if MOMO_ENABLE_RUST_CODE const auto* env = getenv("EMULATOR_ICICLE"); if (env && (env == "1"sv || env == "true"sv)) { - return icicle::create_x64_emulator(); + return icicle::create_x86_64_emulator(); } #endif - return unicorn::create_x64_emulator(); + return unicorn::create_x86_64_emulator(); } windows_emulator::windows_emulator(application_settings app_settings, const emulator_settings& settings, emulator_callbacks callbacks, emulator_interfaces interfaces, - std::unique_ptr emu) + std::unique_ptr emu) : windows_emulator(settings, std::move(callbacks), std::move(interfaces), std::move(emu)) { fixup_application_settings(app_settings); @@ -290,7 +290,7 @@ windows_emulator::windows_emulator(application_settings app_settings, const emul } windows_emulator::windows_emulator(const emulator_settings& settings, emulator_callbacks callbacks, - emulator_interfaces interfaces, std::unique_ptr emu) + emulator_interfaces interfaces, std::unique_ptr emu) : emu_(std::move(emu)), clock_(get_clock(interfaces, this->executed_instructions_, settings.use_relative_time)), socket_factory_(get_socket_factory(interfaces)), @@ -485,26 +485,26 @@ void windows_emulator::on_instruction_execution(const uint64_t address) log.print(color::gray, "Inst: %16" PRIx64 " - RAX: %16" PRIx64 " - RBX: %16" PRIx64 " - RCX: %16" PRIx64 " - RDX: %16" PRIx64 " - R8: %16" PRIx64 " - R9: %16" PRIx64 " - RDI: %16" PRIx64 " - RSI: %16" PRIx64 " - %s\n", - address, emu.reg(x64_register::rax), emu.reg(x64_register::rbx), emu.reg(x64_register::rcx), - emu.reg(x64_register::rdx), emu.reg(x64_register::r8), emu.reg(x64_register::r9), - emu.reg(x64_register::rdi), emu.reg(x64_register::rsi), binary ? binary->name.c_str() : ""); + address, emu.reg(x86_register::rax), emu.reg(x86_register::rbx), emu.reg(x86_register::rcx), + emu.reg(x86_register::rdx), emu.reg(x86_register::r8), emu.reg(x86_register::r9), + emu.reg(x86_register::rdi), emu.reg(x86_register::rsi), binary ? binary->name.c_str() : ""); } void windows_emulator::setup_hooks() { - this->emu().hook_instruction(x64_hookable_instructions::syscall, [&] { + this->emu().hook_instruction(x86_hookable_instructions::syscall, [&] { this->dispatcher.dispatch(*this); return instruction_hook_continuation::skip_instruction; }); - this->emu().hook_instruction(x64_hookable_instructions::rdtsc, [&] { + this->emu().hook_instruction(x86_hookable_instructions::rdtsc, [&] { const auto ticks = this->clock_->timestamp_counter(); - this->emu().reg(x64_register::rax, ticks & 0xFFFFFFFF); - this->emu().reg(x64_register::rdx, (ticks >> 32) & 0xFFFFFFFF); + this->emu().reg(x86_register::rax, ticks & 0xFFFFFFFF); + this->emu().reg(x86_register::rdx, (ticks >> 32) & 0xFFFFFFFF); return instruction_hook_continuation::skip_instruction; }); - this->emu().hook_instruction(x64_hookable_instructions::invalid, [&] { + this->emu().hook_instruction(x86_hookable_instructions::invalid, [&] { const auto ip = this->emu().read_instruction_pointer(); this->log.print(color::gray, "Invalid instruction at: 0x%" PRIx64 " (via 0x%" PRIx64 ")\n", ip, diff --git a/src/windows-emulator/windows_emulator.hpp b/src/windows-emulator/windows_emulator.hpp index 5a68f614..965d0037 100644 --- a/src/windows-emulator/windows_emulator.hpp +++ b/src/windows-emulator/windows_emulator.hpp @@ -1,7 +1,7 @@ #pragma once #include "std_include.hpp" -#include +#include #include @@ -13,11 +13,11 @@ #include "module/module_manager.hpp" #include "network/socket_factory.hpp" -std::unique_ptr create_default_x64_emulator(); +std::unique_ptr create_default_x86_64_emulator(); struct emulator_callbacks : module_manager::callbacks, process_context::callbacks { - utils::optional_function on_syscall{}; @@ -57,7 +57,7 @@ class windows_emulator { uint64_t executed_instructions_{0}; - std::unique_ptr emu_{}; + std::unique_ptr emu_{}; std::unique_ptr clock_{}; std::unique_ptr socket_factory_{}; @@ -74,10 +74,10 @@ class windows_emulator windows_emulator(const emulator_settings& settings = {}, emulator_callbacks callbacks = {}, emulator_interfaces interfaces = {}, - std::unique_ptr emu = create_default_x64_emulator()); + std::unique_ptr emu = create_default_x86_64_emulator()); windows_emulator(application_settings app_settings, const emulator_settings& settings = {}, emulator_callbacks callbacks = {}, emulator_interfaces interfaces = {}, - std::unique_ptr emu = create_default_x64_emulator()); + std::unique_ptr emu = create_default_x86_64_emulator()); windows_emulator(windows_emulator&&) = delete; windows_emulator(const windows_emulator&) = delete; @@ -86,12 +86,12 @@ class windows_emulator ~windows_emulator(); - x64_emulator& emu() + x86_64_emulator& emu() { return *this->emu_; } - const x64_emulator& emu() const + const x86_64_emulator& emu() const { return *this->emu_; } diff --git a/src/windows-gdb-stub/x64_gdb_stub_handler.hpp b/src/windows-gdb-stub/x64_gdb_stub_handler.hpp index 3fb33992..33a23d8e 100644 --- a/src/windows-gdb-stub/x64_gdb_stub_handler.hpp +++ b/src/windows-gdb-stub/x64_gdb_stub_handler.hpp @@ -1,7 +1,7 @@ #pragma once #include #include -#include +#include #include @@ -33,7 +33,7 @@ struct std::hash class x64_gdb_stub_handler : public gdb_stub::debugging_handler { public: - x64_gdb_stub_handler(x64_emulator& emu) + x64_gdb_stub_handler(x86_64_emulator& emu) : emu_(&emu) { } @@ -238,7 +238,7 @@ class x64_gdb_stub_handler : public gdb_stub::debugging_handler } private: - x64_emulator* emu_{}; + x86_64_emulator* emu_{}; using hook_map = std::unordered_map; utils::concurrency::container hooks_{}; diff --git a/src/windows-gdb-stub/x64_register_mapping.hpp b/src/windows-gdb-stub/x64_register_mapping.hpp index cedbc1ad..2f1ed9f0 100644 --- a/src/windows-gdb-stub/x64_register_mapping.hpp +++ b/src/windows-gdb-stub/x64_register_mapping.hpp @@ -1,15 +1,15 @@ #pragma once #include #include -#include +#include struct register_entry { - x64_register reg; + x86_register reg; std::optional expected_size; std::optional offset; - register_entry(const x64_register reg = x64_register::invalid, + register_entry(const x86_register reg = x86_register::invalid, const std::optional expected_size = std::nullopt, const std::optional offset = std::nullopt) : reg(reg), @@ -20,83 +20,83 @@ struct register_entry }; inline std::vector gdb_registers{ - x64_register::rax, - x64_register::rbx, - x64_register::rcx, - x64_register::rdx, - x64_register::rsi, - x64_register::rdi, - x64_register::rbp, - x64_register::rsp, - x64_register::r8, - x64_register::r9, - x64_register::r10, - x64_register::r11, - x64_register::r12, - x64_register::r13, - x64_register::r14, - x64_register::r15, - x64_register::rip, - x64_register::eflags, + x86_register::rax, + x86_register::rbx, + x86_register::rcx, + x86_register::rdx, + x86_register::rsi, + x86_register::rdi, + x86_register::rbp, + x86_register::rsp, + x86_register::r8, + x86_register::r9, + x86_register::r10, + x86_register::r11, + x86_register::r12, + x86_register::r13, + x86_register::r14, + x86_register::r15, + x86_register::rip, + x86_register::eflags, - {x64_register::cs, 4}, - {x64_register::ss, 4}, - {x64_register::ds, 4}, - {x64_register::es, 4}, - {x64_register::fs, 4}, - {x64_register::gs, 4}, + {x86_register::cs, 4}, + {x86_register::ss, 4}, + {x86_register::ds, 4}, + {x86_register::es, 4}, + {x86_register::fs, 4}, + {x86_register::gs, 4}, - x64_register::st0, - x64_register::st1, - x64_register::st2, - x64_register::st3, - x64_register::st4, - x64_register::st5, - x64_register::st6, - x64_register::st7, + x86_register::st0, + x86_register::st1, + x86_register::st2, + x86_register::st3, + x86_register::st4, + x86_register::st5, + x86_register::st6, + x86_register::st7, - {x64_register::fpcw, 4}, // fctrl - {x64_register::fpsw, 4}, // fstat - {x64_register::fptag, 4}, // ftag - {x64_register::fcs, 4}, // fiseg - {x64_register::fip, 4}, // fioff - {x64_register::fds, 4}, // foseg - {x64_register::fdp, 4}, // fooff - {x64_register::fop, 4}, // fop + {x86_register::fpcw, 4}, // fctrl + {x86_register::fpsw, 4}, // fstat + {x86_register::fptag, 4}, // ftag + {x86_register::fcs, 4}, // fiseg + {x86_register::fip, 4}, // fioff + {x86_register::fds, 4}, // foseg + {x86_register::fdp, 4}, // fooff + {x86_register::fop, 4}, // fop - x64_register::xmm0, - x64_register::xmm1, - x64_register::xmm2, - x64_register::xmm3, - x64_register::xmm4, - x64_register::xmm5, - x64_register::xmm6, - x64_register::xmm7, - x64_register::xmm8, - x64_register::xmm9, - x64_register::xmm10, - x64_register::xmm11, - x64_register::xmm12, - x64_register::xmm13, - x64_register::xmm14, - x64_register::xmm15, - x64_register::mxcsr, - x64_register::fs_base, - x64_register::gs_base, - {x64_register::ymm0, 16, 16}, - {x64_register::ymm1, 16, 16}, - {x64_register::ymm2, 16, 16}, - {x64_register::ymm3, 16, 16}, - {x64_register::ymm4, 16, 16}, - {x64_register::ymm5, 16, 16}, - {x64_register::ymm6, 16, 16}, - {x64_register::ymm7, 16, 16}, - {x64_register::ymm8, 16, 16}, - {x64_register::ymm9, 16, 16}, - {x64_register::ymm10, 16, 16}, - {x64_register::ymm11, 16, 16}, - {x64_register::ymm12, 16, 16}, - {x64_register::ymm13, 16, 16}, - {x64_register::ymm14, 16, 16}, - {x64_register::ymm15, 16, 16}, + x86_register::xmm0, + x86_register::xmm1, + x86_register::xmm2, + x86_register::xmm3, + x86_register::xmm4, + x86_register::xmm5, + x86_register::xmm6, + x86_register::xmm7, + x86_register::xmm8, + x86_register::xmm9, + x86_register::xmm10, + x86_register::xmm11, + x86_register::xmm12, + x86_register::xmm13, + x86_register::xmm14, + x86_register::xmm15, + x86_register::mxcsr, + x86_register::fs_base, + x86_register::gs_base, + {x86_register::ymm0, 16, 16}, + {x86_register::ymm1, 16, 16}, + {x86_register::ymm2, 16, 16}, + {x86_register::ymm3, 16, 16}, + {x86_register::ymm4, 16, 16}, + {x86_register::ymm5, 16, 16}, + {x86_register::ymm6, 16, 16}, + {x86_register::ymm7, 16, 16}, + {x86_register::ymm8, 16, 16}, + {x86_register::ymm9, 16, 16}, + {x86_register::ymm10, 16, 16}, + {x86_register::ymm11, 16, 16}, + {x86_register::ymm12, 16, 16}, + {x86_register::ymm13, 16, 16}, + {x86_register::ymm14, 16, 16}, + {x86_register::ymm15, 16, 16}, };