mirror of
https://github.com/momo5502/emulator.git
synced 2026-01-23 05:31:03 +00:00
Fix reading/writing eflags
This commit is contained in:
@@ -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"),
|
||||
}
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user