mirror of
https://github.com/icicle-emu/icicle-python
synced 2026-06-21 13:53:41 +00:00
Compare commits
19 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e2d2f46a54 | |||
| e9c03d562f | |||
| 8acc071b8a | |||
| 503cf2ce72 | |||
| 36d4e46246 | |||
| 4e32ae3ff5 | |||
| f491a2259a | |||
| 37c0fc57a8 | |||
| 412bb928b6 | |||
| 08701ee1f2 | |||
| 435e9e4df7 | |||
| 210b64cbb7 | |||
| 0fc786f5f1 | |||
| 583932dd33 | |||
| ad481a2124 | |||
| aef686faa6 | |||
| 556eb71fe7 | |||
| de16238d15 | |||
| 7a095640b4 |
@@ -141,6 +141,7 @@ jobs:
|
||||
permissions:
|
||||
contents: write
|
||||
discussions: write
|
||||
id-token: write
|
||||
steps:
|
||||
- name: Download wheels
|
||||
uses: actions/download-artifact@v4
|
||||
@@ -151,12 +152,9 @@ jobs:
|
||||
|
||||
- name: Publish to PyPI
|
||||
uses: pypa/gh-action-pypi-publish@67339c736fd9354cd4f8cb0b744f2b82a74b5c70 # v1.12.13
|
||||
with:
|
||||
password: ${{ secrets.PYPI_API_TOKEN }}
|
||||
packages-dir: dist/
|
||||
|
||||
- name: Release
|
||||
uses: softprops/action-gh-release@7b4da11513bf3f43f9999e90eabced41ab8bb048 # v2.2.0
|
||||
uses: softprops/action-gh-release@e7a8f85e1c67a31e6ed99a94b41bd0b71bbee6b8 # v2.0.9
|
||||
with:
|
||||
generate_release_notes: true
|
||||
files: dist/*
|
||||
|
||||
Generated
+1
-1
@@ -424,7 +424,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "icicle-python"
|
||||
version = "0.0.5"
|
||||
version = "0.0.10"
|
||||
dependencies = [
|
||||
"icicle-cpu",
|
||||
"icicle-vm",
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@ exclude = ["icicle-emu"]
|
||||
|
||||
[package]
|
||||
name = "icicle-python"
|
||||
version = "0.0.5"
|
||||
version = "0.0.10"
|
||||
edition = "2021"
|
||||
|
||||
[lib]
|
||||
|
||||
+1
-1
Submodule icicle-emu updated: 7f17fc4cd0...a2bba228b7
@@ -1145,78 +1145,78 @@ macro ptr8(r,x) {
|
||||
|
||||
macro push22(x) {
|
||||
mysave:2 = x;
|
||||
SP = SP -2;
|
||||
tmp:$(SIZE) = segment(SS,SP);
|
||||
tmp:$(SIZE) = segment(SS,SP-2);
|
||||
*:2 tmp = mysave;
|
||||
SP = SP-2;
|
||||
}
|
||||
|
||||
macro push24(x) {
|
||||
mysave:4 = x;
|
||||
SP = SP-4;
|
||||
tmp:$(SIZE) = segment(SS,SP);
|
||||
tmp:$(SIZE) = segment(SS,SP-4);
|
||||
*:4 tmp = mysave;
|
||||
SP = SP-4;
|
||||
}
|
||||
|
||||
macro push28(x) {
|
||||
mysave:8 = x;
|
||||
SP = SP-8;
|
||||
tmp:$(SIZE) = segment(SS,SP);
|
||||
tmp:$(SIZE) = segment(SS,SP-8);
|
||||
*:8 tmp = mysave;
|
||||
SP = SP-8;
|
||||
}
|
||||
|
||||
macro push42(x) {
|
||||
mysave:2 = x;
|
||||
$(STACKPTR) = $(STACKPTR) - 2;
|
||||
*:2 $(STACKPTR) = mysave;
|
||||
*:2 ($(STACKPTR)-2) = mysave;
|
||||
$(STACKPTR) = $(STACKPTR)-2;
|
||||
}
|
||||
|
||||
macro push44(x) {
|
||||
mysave:4 = x;
|
||||
$(STACKPTR) = $(STACKPTR) - 4;
|
||||
*:4 $(STACKPTR) = mysave;
|
||||
*:4 ($(STACKPTR)-4) = mysave;
|
||||
$(STACKPTR) = $(STACKPTR)-4;
|
||||
}
|
||||
|
||||
macro pushseg44(x) {
|
||||
mysave:2 = x;
|
||||
$(STACKPTR) = $(STACKPTR) - 4;
|
||||
*:2 $(STACKPTR) = mysave;
|
||||
*:2 ($(STACKPTR)-4) = mysave;
|
||||
$(STACKPTR) = $(STACKPTR)-4;
|
||||
}
|
||||
|
||||
macro push48(x) {
|
||||
mysave:8 = x;
|
||||
$(STACKPTR) = $(STACKPTR) - 8;
|
||||
*:8 $(STACKPTR) = mysave;
|
||||
*:8 ($(STACKPTR)-8) = mysave;
|
||||
$(STACKPTR) = $(STACKPTR)-8;
|
||||
}
|
||||
|
||||
@ifdef IA64
|
||||
macro push82(x) {
|
||||
mysave:2 = x;
|
||||
$(STACKPTR) = $(STACKPTR) - 2;
|
||||
*:2 $(STACKPTR) = mysave;
|
||||
*:2 ($(STACKPTR)-2) = mysave;
|
||||
$(STACKPTR) = $(STACKPTR)-2;
|
||||
}
|
||||
|
||||
macro push84(x) {
|
||||
mysave:4 = x;
|
||||
$(STACKPTR) = $(STACKPTR) - 4;
|
||||
*:4 $(STACKPTR) = mysave;
|
||||
*:4 ($(STACKPTR)-4) = mysave;
|
||||
$(STACKPTR) = $(STACKPTR)-4;
|
||||
}
|
||||
|
||||
macro push88(x) {
|
||||
mysave:8 = x;
|
||||
$(STACKPTR) = $(STACKPTR) - 8;
|
||||
*:8 $(STACKPTR) = mysave;
|
||||
*:8 ($(STACKPTR)-8) = mysave;
|
||||
$(STACKPTR) = $(STACKPTR)-8;
|
||||
}
|
||||
|
||||
macro pushseg82(x) {
|
||||
mysave:2 = x;
|
||||
$(STACKPTR) = $(STACKPTR) - 2;
|
||||
*:2 $(STACKPTR) = mysave;
|
||||
*:2 ($(STACKPTR)-2) = mysave;
|
||||
$(STACKPTR) = $(STACKPTR)-2;
|
||||
}
|
||||
|
||||
macro pushseg88(x) {
|
||||
mysave:2 = x;
|
||||
$(STACKPTR) = $(STACKPTR) - 8;
|
||||
*:2 $(STACKPTR) = mysave;
|
||||
*:2 ($(STACKPTR)-8) = mysave;
|
||||
$(STACKPTR) = $(STACKPTR)-8;
|
||||
}
|
||||
@endif
|
||||
|
||||
|
||||
@@ -104,6 +104,12 @@ class Icicle:
|
||||
|
||||
sp: int
|
||||
|
||||
"""
|
||||
Physical memory capacity in pages (adjust when seeing OutOfMemory)
|
||||
The default limit is set so that the maximum corresponds to ~400 MB of host memory.
|
||||
"""
|
||||
mem_capacity: int
|
||||
|
||||
# TODO: API to get memory information?
|
||||
|
||||
def mem_map(self, address: int, size: int, protection: MemoryProtection): ...
|
||||
@@ -146,7 +152,7 @@ class MemoryException(Exception):
|
||||
self.code = code
|
||||
|
||||
def __str__(self):
|
||||
return f"{super().__str__()}: {self.code}"
|
||||
return f"{super().__str__()} ({self.code})"
|
||||
|
||||
def __ghidra_init():
|
||||
import os
|
||||
|
||||
+56
-11
@@ -1,19 +1,35 @@
|
||||
use std::borrow::Cow;
|
||||
use std::collections::HashMap;
|
||||
use icicle_cpu::mem::{Mapping, MemError, perm};
|
||||
use icicle_cpu::{ExceptionCode, VmExit};
|
||||
use icicle_cpu::{Cpu, ExceptionCode, ValueSource, VmExit};
|
||||
use pyo3::prelude::*;
|
||||
use icicle_vm;
|
||||
use icicle_vm::linux::LinuxCpu;
|
||||
use pyo3::exceptions::*;
|
||||
use target_lexicon;
|
||||
use indexmap::IndexMap;
|
||||
use target_lexicon::Architecture;
|
||||
use sleigh_runtime::NamedRegister;
|
||||
|
||||
// References:
|
||||
// - https://pyo3.rs/main/conversions/tables
|
||||
// - https://pyo3.rs/main/class
|
||||
|
||||
struct X86FlagsRegHandler {
|
||||
pub eflags: pcode::VarNode,
|
||||
}
|
||||
|
||||
impl icicle_cpu::RegHandler for X86FlagsRegHandler {
|
||||
fn read(&mut self, cpu: &mut Cpu) {
|
||||
let eflags = icicle_vm::x86::eflags(cpu);
|
||||
cpu.write_var::<u32>(self.eflags, eflags);
|
||||
}
|
||||
|
||||
fn write(&mut self, cpu: &mut Cpu) {
|
||||
let eflags = cpu.read_var::<u32>(self.eflags);
|
||||
icicle_vm::x86::set_eflags(cpu, eflags);
|
||||
}
|
||||
}
|
||||
|
||||
#[pyclass(eq, eq_int, module = "icicle")]
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub enum MemoryProtection {
|
||||
@@ -227,7 +243,7 @@ pub struct Icicle {
|
||||
}
|
||||
|
||||
fn reg_find<'a>(i: &'a Icicle, name: &str) -> PyResult<&'a NamedRegister> {
|
||||
let sleigh = i.vm.cpu.sleigh();
|
||||
let sleigh = &i.vm.cpu.arch.sleigh;
|
||||
match sleigh.get_reg(name) {
|
||||
None => {
|
||||
i.regs.get(name.to_lowercase().as_str())
|
||||
@@ -253,7 +269,7 @@ impl Icicle {
|
||||
|
||||
#[getter]
|
||||
pub fn get_icount(&mut self) -> u64 {
|
||||
return self.vm.cpu.icount;
|
||||
self.vm.cpu.icount
|
||||
}
|
||||
|
||||
#[setter]
|
||||
@@ -296,6 +312,24 @@ impl Icicle {
|
||||
self.vm.cpu.write_reg(self.vm.cpu.arch.reg_sp, address)
|
||||
}
|
||||
|
||||
#[getter]
|
||||
pub fn get_mem_capacity(&self) -> usize {
|
||||
self.vm.cpu.mem.capacity()
|
||||
}
|
||||
|
||||
#[setter]
|
||||
pub fn set_mem_capacity(&mut self, capacity: usize) -> PyResult<()> {
|
||||
if self.vm.cpu.mem.set_capacity(capacity) {
|
||||
return Ok(());
|
||||
}
|
||||
Err(
|
||||
raise_MemoryException(
|
||||
format!("Reducing memory capacity is not supported"),
|
||||
MemError::Unknown,
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
#[new]
|
||||
#[pyo3(signature = (
|
||||
architecture,
|
||||
@@ -335,7 +369,7 @@ impl Icicle {
|
||||
}
|
||||
}
|
||||
|
||||
// Setup the CPU state for the target triple
|
||||
// Set up the CPU state for the target triple
|
||||
let mut config = icicle_vm::cpu::Config::from_target_triple(
|
||||
format!("{architecture}-none").as_str()
|
||||
);
|
||||
@@ -354,19 +388,29 @@ impl Icicle {
|
||||
config.optimize_instructions = optimize_instructions;
|
||||
config.optimize_block = optimize_block;
|
||||
|
||||
let vm = icicle_vm::build(&config)
|
||||
let mut vm = icicle_vm::build(&config)
|
||||
.map_err(|e| {
|
||||
PyException::new_err(format!("VM build error: {e}"))
|
||||
})?;
|
||||
|
||||
// Populate the lowercase register map
|
||||
let mut regs = HashMap::new();
|
||||
let sleigh = vm.cpu.sleigh();
|
||||
let sleigh = &vm.cpu.arch.sleigh;
|
||||
for reg in &sleigh.named_registers {
|
||||
let name = sleigh.get_str(reg.name);
|
||||
regs.insert(name.to_lowercase(), reg.clone());
|
||||
}
|
||||
|
||||
// Special handling for x86 flags
|
||||
match config.triple.architecture {
|
||||
Architecture::X86_32(_) | Architecture::X86_64 | Architecture::X86_64h => {
|
||||
let eflags = sleigh.get_reg("eflags").unwrap().var;
|
||||
let reg_handler = X86FlagsRegHandler { eflags };
|
||||
vm.cpu.add_reg_handler(eflags.id, Box::new(reg_handler));
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
Ok(Icicle {
|
||||
architecture,
|
||||
vm,
|
||||
@@ -385,8 +429,9 @@ impl Icicle {
|
||||
}
|
||||
|
||||
pub fn mem_map(&mut self, address: u64, size: u64, protection: MemoryProtection) -> PyResult<()> {
|
||||
let init_perm = if self.vm.cpu.mem.track_uninitialized { perm::NONE } else { perm::INIT };
|
||||
let mapping = Mapping {
|
||||
perm: convert_protection(protection),
|
||||
perm: convert_protection(protection) | init_perm,
|
||||
value: 0,
|
||||
};
|
||||
if self.vm.cpu.mem.map_memory_len(address, size, mapping) {
|
||||
@@ -438,7 +483,7 @@ impl Icicle {
|
||||
e,
|
||||
)
|
||||
})?;
|
||||
return Ok(Cow::Owned(buffer));
|
||||
Ok(Cow::Owned(buffer))
|
||||
}
|
||||
|
||||
pub fn mem_write(&mut self, address: u64, data: Vec<u8>) -> PyResult<()> {
|
||||
@@ -454,12 +499,12 @@ impl Icicle {
|
||||
|
||||
pub fn reg_list(&self) -> PyResult<IndexMap<String, (u32, u8)>> {
|
||||
let mut result = IndexMap::new();
|
||||
let sleigh = self.vm.cpu.sleigh();
|
||||
let sleigh = &self.vm.cpu.arch.sleigh;
|
||||
for reg in &sleigh.named_registers {
|
||||
let name = sleigh.get_str(reg.name);
|
||||
result.insert(name.to_string(), (reg.offset, reg.var.size));
|
||||
}
|
||||
return Ok(result);
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
pub fn reg_offset(&self, name: &str) -> PyResult<u32> {
|
||||
|
||||
+156
-16
@@ -1,3 +1,5 @@
|
||||
#![allow(unused)]
|
||||
|
||||
use icicle::*;
|
||||
use pyo3::PyResult;
|
||||
use std::process::exit;
|
||||
@@ -22,6 +24,20 @@ fn new_vm(jit: bool) -> PyResult<Icicle> {
|
||||
)
|
||||
}
|
||||
|
||||
fn new_trace_vm(jit: bool) -> PyResult<Icicle> {
|
||||
Icicle::new(
|
||||
"x86_64".to_string(),
|
||||
jit,
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
)
|
||||
}
|
||||
|
||||
fn nx_start() -> PyResult<()> {
|
||||
let mut vm = new_vm(false)?;
|
||||
let page = 0x10000;
|
||||
@@ -102,7 +118,7 @@ fn block_optimization() -> PyResult<()> {
|
||||
vm.mem_map(heap, 0x1000, MemoryProtection::ReadWrite)?;
|
||||
vm.mem_write(heap + 4, b"\x37\x13\x00\x00".to_vec())?;
|
||||
vm.mem_map(addr & !0xFFF, 0x1000, MemoryProtection::ExecuteRead)?;
|
||||
vm.mem_write(addr, b"\x41\xc1\xea\x07\x41\x83\xe2\x1f\x74\x08\x44\x89\xd0\x48\x89\x54\xc6\x08\x49\x83\xc1\x04\x4c\x89\x0e\x4c\x89\xc9\x44\x8b\x11\x44\x89\xd0\xf7\xd0\x49\x89\xc9\xa8\x03\x0f\x84\x88\xf6\xff\xff\xeb\x4c".to_vec())?;
|
||||
vm.mem_write(addr, b"\x41\xc1\xea\x07\x41\x83\xe2\x1f\x74\x08\x44\x89\xd0\x48\x89\x54\xc6\x08\x49\x83\xc1\x04\x4c\x89\x0e\x4c\x89\xc9\x44\x8b\x11\x44\x89\xd0\xf7\xd0\x49\x89\xc9\xa8\x03\x0f\x84\x88\xf6\xff\xff\xeb\x4c\xcc".to_vec())?;
|
||||
|
||||
// Register setup
|
||||
vm.reg_write("r9", heap)?;
|
||||
@@ -142,7 +158,7 @@ fn rewind() -> PyResult<()> {
|
||||
vm.mem_map(0x100, 0x20, MemoryProtection::ExecuteRead)?;
|
||||
vm.mem_map(0x200, 0x20, MemoryProtection::ReadOnly)?;
|
||||
|
||||
vm.mem_write(0x100, b"\x55".to_vec())?; // push rbp
|
||||
vm.mem_write(0x100, b"\x55\xCC".to_vec())?; // push rbp
|
||||
vm.reg_write("rbp", 0xF00)?;
|
||||
vm.reg_write("rsp", 0x210)?;
|
||||
vm.reg_write("rip", 0x100)?;
|
||||
@@ -155,22 +171,86 @@ fn rewind() -> PyResult<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn execute_only() -> PyResult<()> {
|
||||
let mut vm = new_vm(true)?;
|
||||
fn execute_uninitialized() -> PyResult<()> {
|
||||
let mut vm = Icicle::new(
|
||||
"x86_64".to_string(),
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
true, // NOTE: setting this to true is not properly supported
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
)?;
|
||||
|
||||
// \x48\x8d\x05\x01\x00\x00\x00\x90\x8a\x18\x90
|
||||
|
||||
vm.mem_map(0x100, 0x20, MemoryProtection::ExecuteOnly)?;
|
||||
vm.mem_write(0x100, b"\x90".to_vec())?; // nop
|
||||
vm.mem_write(0x100, b"\x90\xFF\xC0".to_vec())?; // inc eax
|
||||
vm.reg_write("rip", 0x100)?;
|
||||
{
|
||||
println!("[pre1] icount: {}", vm.get_icount());
|
||||
let status = vm.step(2);
|
||||
// NOTE: the real reason is that INIT is not set
|
||||
println!("run status : {:?}", status);
|
||||
println!("exception code : {:?}", vm.get_exception_code());
|
||||
println!("exception value : {:#x}", vm.get_exception_value());
|
||||
println!("rax : {:#x}", vm.reg_read("rax")?);
|
||||
}
|
||||
|
||||
{
|
||||
println!("[pre2] icount: {}", vm.get_icount());
|
||||
let status = vm.step(1);
|
||||
// NOTE: the real reason is that INIT is not set
|
||||
println!("run status : {:?}", status);
|
||||
println!("exception code : {:?}", vm.get_exception_code());
|
||||
println!("exception value : {:#x}", vm.get_exception_value());
|
||||
println!("rax : {:#x}", vm.reg_read("rax")?);
|
||||
println!("[post] icount: {}", vm.get_icount());
|
||||
}
|
||||
|
||||
// TODO: status is now UnhandledException, should be InstructionLimit
|
||||
// on the next stpe it should be UnhandledException -> ExecViolation
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn execute_only() -> PyResult<()> {
|
||||
let mut vm = new_vm(false)?;
|
||||
|
||||
vm.mem_map(0x100, 0x20, MemoryProtection::ExecuteOnly)?;
|
||||
/*
|
||||
0x100: lea rax, [rip]
|
||||
0x107: nop
|
||||
0x108: mov bl, byte ptr [rax]
|
||||
0x10A: int3
|
||||
*/
|
||||
vm.mem_write(
|
||||
0x100,
|
||||
b"\x48\x8d\x05\x00\x00\x00\x00\x90\x8a\x18\xCC".to_vec(),
|
||||
)?; // nop
|
||||
vm.reg_write("rip", 0x100)?;
|
||||
vm.step(2);
|
||||
let status = vm.step(1);
|
||||
// NOTE: the real reason is that INIT is not set
|
||||
println!("run status : {:?}", status);
|
||||
println!("exception code : {:?}", vm.get_exception_code());
|
||||
println!("exception value : {:#x}", vm.get_exception_value());
|
||||
println!("bl: {:#x}", vm.reg_read("bl")?);
|
||||
println!("rip: {:#x}", vm.reg_read("rip")?);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn self_modifying() -> PyResult<()> {
|
||||
// TODO: add a self-modifying code check (where the previously-executed code is written to)
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn step_modify_rip() -> PyResult<()> {
|
||||
let mut vm = new_trace_vm(false)?;
|
||||
let mut vm = new_vm(false)?;
|
||||
vm.mem_map(0x100, 0x20, MemoryProtection::ExecuteRead)?;
|
||||
|
||||
// 0x100: 48 01 d8 add rax,rbx
|
||||
@@ -178,7 +258,10 @@ fn step_modify_rip() -> PyResult<()> {
|
||||
// 0x107: 48 89 d9 mov rcx,rbx
|
||||
// 0x10a: 90 nop
|
||||
// 0x10b: 90 nop
|
||||
vm.mem_write(0x100, b"\x48\x01\xD8\x48\x83\xE9\x05\x48\x89\xD9\x90\x90".to_vec())?;
|
||||
vm.mem_write(
|
||||
0x100,
|
||||
b"\x48\x01\xD8\x48\x83\xE9\x05\x48\x89\xD9\x90\x90\xCC".to_vec(),
|
||||
)?;
|
||||
|
||||
vm.reg_write("rax", 0xF00)?;
|
||||
vm.reg_write("rbx", 0x210)?;
|
||||
@@ -194,7 +277,7 @@ fn step_modify_rip() -> PyResult<()> {
|
||||
);
|
||||
vm.reg_write("rip", 0x100)?;
|
||||
//vm.write_pc(0x100);
|
||||
//println!("pc: {:#x}", vm.read_pc());
|
||||
//println!("pc: {:#x}", vm.read_pc());
|
||||
println!("rip rewritten {:#x}", vm.reg_read("rip")?);
|
||||
status = vm.step(1);
|
||||
println!(
|
||||
@@ -206,6 +289,61 @@ fn step_modify_rip() -> PyResult<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn eflags_reconstruction() -> PyResult<()> {
|
||||
let mut vm = new_vm(false)?;
|
||||
vm.mem_map(0x100, 0x20, MemoryProtection::ExecuteRead)?;
|
||||
|
||||
vm.mem_write(0x100, b"\x48\x01\xD8\xCC".to_vec())?;
|
||||
vm.reg_write("rax", 0x7FFFFFFFFFFFFFFF)?;
|
||||
vm.reg_write("rbx", 0x1)?;
|
||||
|
||||
let of_mask = (1 << 11) as u64;
|
||||
|
||||
{
|
||||
let eflags = vm.reg_read("eflags")?;
|
||||
let of = vm.reg_read("OF")?;
|
||||
let of_set = (eflags & of_mask) == of_mask;
|
||||
println!("[pre] eflags: {:#x}, OF: {:#x} == {}", eflags, of, of_set);
|
||||
}
|
||||
|
||||
vm.set_pc(0x100);
|
||||
let status = vm.step(1);
|
||||
println!("run status: {:?}", status);
|
||||
|
||||
{
|
||||
let eflags = vm.reg_read("eflags")?;
|
||||
let rflags = vm.reg_read("rflags")?;
|
||||
let of = vm.reg_read("OF")?;
|
||||
let of_set = (eflags & of_mask) == of_mask;
|
||||
println!(
|
||||
"[post] eflags: {:#x} == {:#x}, OF: {:#x} == {}",
|
||||
eflags, rflags, of, of_set
|
||||
);
|
||||
}
|
||||
|
||||
{
|
||||
vm.reg_write("OF", 0)?;
|
||||
let eflags = vm.reg_read("eflags")?;
|
||||
let of = vm.reg_read("OF")?;
|
||||
let of_set = (eflags >> 11) & 1;
|
||||
println!("[OF=0] eflags: {:#x}, OF: {:#x} == {}", eflags, of, of_set);
|
||||
}
|
||||
|
||||
{
|
||||
let mut eflags = vm.reg_read("eflags")?;
|
||||
eflags |= of_mask;
|
||||
vm.reg_write("rflags", eflags)?;
|
||||
let of = vm.reg_read("OF")?;
|
||||
let of_set = (eflags >> 11) & 1;
|
||||
println!(
|
||||
"[rflags|={:#x}] eflags: {:#x}, OF: {:#x} == {}",
|
||||
of_mask, eflags, of, of_set
|
||||
);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn main() {
|
||||
// Make sure the GHIDRA_SRC environment variable is valid
|
||||
match std::env::var("GHIDRA_SRC") {
|
||||
@@ -228,14 +366,16 @@ fn main() {
|
||||
}
|
||||
|
||||
let tests: Vec<(&str, fn() -> PyResult<()>)> = vec![
|
||||
("NX (block start)", nx_start),
|
||||
("NX (block middle)", nx_middle),
|
||||
("Invalid instruction (block start)", inv_start),
|
||||
("Invalid instruction (block middle)", inv_middle),
|
||||
("Block optimization bug", block_optimization),
|
||||
("Rewind", rewind),
|
||||
("Execute only", execute_only),
|
||||
("Step modify rip", step_modify_rip),
|
||||
//("NX (block start)", nx_start),
|
||||
//("NX (block middle)", nx_middle),
|
||||
//("Invalid instruction (block start)", inv_start),
|
||||
//("Invalid instruction (block middle)", inv_middle),
|
||||
//("Block optimization bug", block_optimization),
|
||||
//("Rewind", rewind),
|
||||
//("Execute only", execute_only),
|
||||
("Execute uninitialized", execute_uninitialized),
|
||||
//("Step modify rip", step_modify_rip),
|
||||
//("EFlags reconstruction", eflags_reconstruction),
|
||||
];
|
||||
|
||||
let mut success = 0;
|
||||
|
||||
Reference in New Issue
Block a user