mirror of
https://github.com/icicle-emu/icicle-python
synced 2026-06-21 13:53:41 +00:00
Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e2d2f46a54 | |||
| e9c03d562f | |||
| 8acc071b8a | |||
| 503cf2ce72 | |||
| 36d4e46246 | |||
| 4e32ae3ff5 |
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
@@ -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
|
||||
|
||||
+18
@@ -312,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,
|
||||
|
||||
+39
-19
@@ -174,27 +174,41 @@ fn rewind() -> PyResult<()> {
|
||||
fn execute_uninitialized() -> PyResult<()> {
|
||||
let mut vm = Icicle::new(
|
||||
"x86_64".to_string(),
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
true, // NOTE: setting this to true is not properly supported
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
)?;
|
||||
|
||||
// \x48\x8d\x05\x01\x00\x00\x00\x90\x8a\x18\x90
|
||||
|
||||
vm.mem_map(0x100, 0x20, MemoryProtection::ExecuteOnly)?;
|
||||
vm.mem_write(0x100, b"\xFF\xC0".to_vec())?; // inc eax
|
||||
vm.mem_write(0x100, b"\x90\xFF\xC0".to_vec())?; // inc eax
|
||||
vm.reg_write("rip", 0x100)?;
|
||||
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!("[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
|
||||
@@ -229,8 +243,14 @@ fn execute_only() -> PyResult<()> {
|
||||
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
|
||||
@@ -346,16 +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),
|
||||
//("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),
|
||||
//("Step modify rip", step_modify_rip),
|
||||
//("EFlags reconstruction", eflags_reconstruction),
|
||||
];
|
||||
|
||||
let mut success = 0;
|
||||
|
||||
Reference in New Issue
Block a user