Fix reading/writing eflags

This commit is contained in:
momo5502
2025-04-06 09:44:46 +02:00
parent 320af6bb46
commit 3450a6a517
2 changed files with 95 additions and 74 deletions

View File

@@ -519,7 +519,7 @@ impl IcicleEmulator {
};
}
pub fn read_register(&mut self, reg: registers::X64Register, buffer: &mut [u8]) -> usize {
fn read_generic_register(&mut self, reg: registers::X64Register, buffer: &mut [u8]) -> usize {
let reg_node = self.reg.get_node(reg);
let res = self.vm.cpu.read_dynamic(pcode::Value::Var(reg_node));
@@ -531,7 +531,58 @@ impl IcicleEmulator {
return reg_node.size.into();
}
fn read_flags<T>(&mut self, data: &mut [u8]) -> usize
{
const REAL_SIZE: usize = std::mem::size_of::<u64>();
let limit: usize = std::mem::size_of::<T>();
let size = std::cmp::min(REAL_SIZE, limit);
let flags: u64 = self.reg.get_flags(&mut self.vm.cpu);
let copy_size = std::cmp::min(data.len(), size);
data[..copy_size].copy_from_slice(&flags.to_ne_bytes()[..copy_size]);
return limit;
}
pub fn read_register(&mut self, reg: registers::X64Register, data: &mut [u8]) -> usize {
match reg {
registers::X64Register::Rflags => self.read_flags::<u64>(data),
registers::X64Register::Eflags => self.read_flags::<u32>(data),
registers::X64Register::Flags => self.read_flags::<u16>(data),
_ => self.read_generic_register(reg, data),
}
}
fn write_flags<T>(&mut self, data: &[u8]) -> usize
{
const REAL_SIZE: usize = std::mem::size_of::<u64>();
let limit: usize = std::mem::size_of::<T>();
let size = std::cmp::min(REAL_SIZE, limit);
let copy_size = std::cmp::min(data.len(), size);
let mut buffer = [0u8; REAL_SIZE];
self.read_flags::<u64>(&mut buffer);
buffer[..copy_size].copy_from_slice(&data[..copy_size]);
let flags = u64::from_ne_bytes(buffer);
self.reg.set_flags(&mut self.vm.cpu, flags);
return limit;
}
pub fn write_register(&mut self, reg: registers::X64Register, data: &[u8]) -> usize {
match reg {
registers::X64Register::Rflags => self.write_flags::<u64>(data),
registers::X64Register::Eflags => self.write_flags::<u32>(data),
registers::X64Register::Flags => self.write_flags::<u16>(data),
_ => self.write_generic_register(reg, data),
}
}
fn write_generic_register(&mut self, reg: registers::X64Register, data: &[u8]) -> usize {
let reg_node = self.reg.get_node(reg);
let mut buffer = [0u8; 32];
@@ -541,71 +592,25 @@ impl IcicleEmulator {
//let value = icicle_cpu::regs::DynamicValue::new(buffer, reg_node.size.into());
//self.vm.cpu.write_trunc(reg_node, value);
let cpu = &mut self.vm.cpu;
match reg_node.size {
1 => self
.vm
.cpu
.write_var::<[u8; 1]>(reg_node, buffer[..1].try_into().expect("")),
2 => self
.vm
.cpu
.write_var::<[u8; 2]>(reg_node, buffer[..2].try_into().expect("")),
3 => self
.vm
.cpu
.write_var::<[u8; 3]>(reg_node, buffer[..3].try_into().expect("")),
4 => self
.vm
.cpu
.write_var::<[u8; 4]>(reg_node, buffer[..4].try_into().expect("")),
5 => self
.vm
.cpu
.write_var::<[u8; 5]>(reg_node, buffer[..5].try_into().expect("")),
6 => self
.vm
.cpu
.write_var::<[u8; 6]>(reg_node, buffer[..6].try_into().expect("")),
7 => self
.vm
.cpu
.write_var::<[u8; 7]>(reg_node, buffer[..7].try_into().expect("")),
8 => self
.vm
.cpu
.write_var::<[u8; 8]>(reg_node, buffer[..8].try_into().expect("")),
9 => self
.vm
.cpu
.write_var::<[u8; 9]>(reg_node, buffer[..9].try_into().expect("")),
10 => self
.vm
.cpu
.write_var::<[u8; 10]>(reg_node, buffer[..10].try_into().expect("")),
11 => self
.vm
.cpu
.write_var::<[u8; 11]>(reg_node, buffer[..11].try_into().expect("")),
12 => self
.vm
.cpu
.write_var::<[u8; 12]>(reg_node, buffer[..12].try_into().expect("")),
13 => self
.vm
.cpu
.write_var::<[u8; 13]>(reg_node, buffer[..13].try_into().expect("")),
14 => self
.vm
.cpu
.write_var::<[u8; 14]>(reg_node, buffer[..14].try_into().expect("")),
15 => self
.vm
.cpu
.write_var::<[u8; 15]>(reg_node, buffer[..15].try_into().expect("")),
16 => self
.vm
.cpu
.write_var::<[u8; 16]>(reg_node, buffer[..16].try_into().expect("")),
1 => cpu.write_var::<[u8; 1]>(reg_node, buffer[..1].try_into().unwrap()),
2 => cpu.write_var::<[u8; 2]>(reg_node, buffer[..2].try_into().unwrap()),
3 => cpu.write_var::<[u8; 3]>(reg_node, buffer[..3].try_into().unwrap()),
4 => cpu.write_var::<[u8; 4]>(reg_node, buffer[..4].try_into().unwrap()),
5 => cpu.write_var::<[u8; 5]>(reg_node, buffer[..5].try_into().unwrap()),
6 => cpu.write_var::<[u8; 6]>(reg_node, buffer[..6].try_into().unwrap()),
7 => cpu.write_var::<[u8; 7]>(reg_node, buffer[..7].try_into().unwrap()),
8 => cpu.write_var::<[u8; 8]>(reg_node, buffer[..8].try_into().unwrap()),
9 => cpu.write_var::<[u8; 9]>(reg_node, buffer[..9].try_into().unwrap()),
10 => cpu.write_var::<[u8; 10]>(reg_node, buffer[..10].try_into().unwrap()),
11 => cpu.write_var::<[u8; 11]>(reg_node, buffer[..11].try_into().unwrap()),
12 => cpu.write_var::<[u8; 12]>(reg_node, buffer[..12].try_into().unwrap()),
13 => cpu.write_var::<[u8; 13]>(reg_node, buffer[..13].try_into().unwrap()),
14 => cpu.write_var::<[u8; 14]>(reg_node, buffer[..14].try_into().unwrap()),
15 => cpu.write_var::<[u8; 15]>(reg_node, buffer[..15].try_into().unwrap()),
16 => cpu.write_var::<[u8; 16]>(reg_node, buffer[..16].try_into().unwrap()),
_ => panic!("invalid dynamic value size"),
}

View File

@@ -262,7 +262,6 @@ pub(crate) struct X64RegisterNodes {
r14: pcode::VarNode,
r15: pcode::VarNode,
rip: pcode::VarNode,
eflags: pcode::VarNode,
cs: pcode::VarNode,
ds: pcode::VarNode,
es: pcode::VarNode,
@@ -467,18 +466,22 @@ pub(crate) struct X64RegisterNodes {
mxcsr: pcode::VarNode,
fs_base: pcode::VarNode,
gs_base: pcode::VarNode,
flags: pcode::VarNode,
rflags: pcode::VarNode,
fip: pcode::VarNode,
fcs: pcode::VarNode,
fdp: pcode::VarNode,
fds: pcode::VarNode,
fop: pcode::VarNode,
flags: Vec<pcode::VarNode>,
}
impl X64RegisterNodes {
pub fn new(arch: &icicle_cpu::Arch) -> Self {
let r = |name: &str| arch.sleigh.get_reg(name).unwrap().var;
let nodes = [
"CF", "F1", "PF", "F3", "AF", "F5", "ZF", "SF", "TF", "IF", "DF", "OF", "IOPL", "NT",
"F15", "RF", "VM", "AC", "VIF", "VIP", "ID",
];
Self {
rax: r("RAX"),
rbx: r("RBX"),
@@ -497,7 +500,6 @@ impl X64RegisterNodes {
r14: r("R14"),
r15: r("R15"),
rip: r("RIP"),
eflags: r("eflags"),
cs: r("CS"),
ds: r("DS"),
es: r("ES"),
@@ -699,8 +701,6 @@ impl X64RegisterNodes {
fpcw: r("FPUControlWord"),
fptag: r("FPUTagWord"),
mxcsr: r("MXCSR"),
flags: r("flags"),
rflags: r("rflags"),
fip: r("FPUInstructionPointer"),
fdp: r("FPUDataPointer"),
fop: r("FPULastInstructionOpcode"),
@@ -709,6 +709,25 @@ impl X64RegisterNodes {
//msr: r("MSR"),
fs_base: r("FS_OFFSET"),
gs_base: r("GS_OFFSET"),
flags: nodes.map(|name: &str| r(name)).to_vec(),
}
}
pub fn get_flags(&self, cpu: &mut icicle_cpu::Cpu) -> u64 {
let mut res: u64 = 0;
for (index, element) in self.flags.iter().enumerate() {
let flag = cpu.read_reg(*element);
res |= (flag & 1) << index;
}
res
}
pub fn set_flags(&self, cpu: &mut icicle_cpu::Cpu, value: u64) {
for (index, element) in self.flags.iter().enumerate() {
let flag = (value >> index) & 1;
cpu.write_reg(*element, flag);
}
}
@@ -731,7 +750,6 @@ impl X64RegisterNodes {
X64Register::R14 => self.r14,
X64Register::R15 => self.r15,
X64Register::Rip => self.rip,
X64Register::Eflags => self.eflags,
X64Register::Cs => self.cs,
X64Register::Ds => self.ds,
X64Register::Es => self.es,
@@ -936,8 +954,6 @@ impl X64RegisterNodes {
X64Register::Mxcsr => self.mxcsr,
X64Register::FsBase => self.fs_base,
X64Register::GsBase => self.gs_base,
X64Register::Flags => self.flags,
X64Register::Rflags => self.rflags,
X64Register::Fip => self.fip,
X64Register::Fcs => self.fcs,
X64Register::Fdp => self.fdp,