mirror of
https://github.com/momo5502/emulator.git
synced 2026-01-28 15:31:02 +00:00
Icicle progress
This commit is contained in:
committed by
momo5502
parent
985dd49059
commit
63f54df78c
65
src/icicle/src/icicle.rs
Normal file
65
src/icicle/src/icicle.rs
Normal file
@@ -0,0 +1,65 @@
|
||||
fn create_x64_vm() -> icicle_vm::Vm {
|
||||
let cpu_config = icicle_vm::cpu::Config::from_target_triple("x86_64-none");
|
||||
let vm = icicle_vm::build(&cpu_config).unwrap();
|
||||
return vm;
|
||||
}
|
||||
|
||||
fn map_permissions(foreign_permissions: u8) -> u8 {
|
||||
const FOREIGN_READ: u8 = 1 << 0;
|
||||
const FOREIGN_WRITE: u8 = 1 << 1;
|
||||
const FOREIGN_EXEC: u8 = 1 << 2;
|
||||
|
||||
let mut permissions: u8 = 0;
|
||||
|
||||
if (foreign_permissions & FOREIGN_READ) != 0 {
|
||||
permissions |= icicle_vm::cpu::mem::perm::READ;
|
||||
}
|
||||
|
||||
if (foreign_permissions & FOREIGN_WRITE) != 0 {
|
||||
permissions |= icicle_vm::cpu::mem::perm::WRITE;
|
||||
}
|
||||
|
||||
if (foreign_permissions & FOREIGN_EXEC) != 0 {
|
||||
permissions |= icicle_vm::cpu::mem::perm::EXEC;
|
||||
}
|
||||
|
||||
return permissions;
|
||||
}
|
||||
|
||||
pub struct IcicleEmulator {
|
||||
vm: icicle_vm::Vm,
|
||||
}
|
||||
|
||||
impl IcicleEmulator {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
vm: create_x64_vm(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn map_memory(&mut self, address: u64, length: u64, permissions: u8) -> bool {
|
||||
const MAPPING_PERMISSIONS: u8 = icicle_vm::cpu::mem::perm::MAP
|
||||
| icicle_vm::cpu::mem::perm::INIT
|
||||
| icicle_vm::cpu::mem::perm::IN_CODE_CACHE;
|
||||
|
||||
let native_permissions = map_permissions(permissions);
|
||||
|
||||
let mapping = icicle_vm::cpu::mem::Mapping {
|
||||
perm: native_permissions | MAPPING_PERMISSIONS,
|
||||
value: 0x0,
|
||||
};
|
||||
|
||||
let layout = icicle_vm::cpu::mem::AllocLayout {
|
||||
addr: Some(address),
|
||||
size: length,
|
||||
align: 0x1000,
|
||||
};
|
||||
|
||||
let res = self.vm.cpu.mem.alloc_memory(layout, mapping);
|
||||
return res.is_ok();
|
||||
}
|
||||
|
||||
pub fn unmap_memory(&mut self, address: u64, length: u64) -> bool {
|
||||
return self.vm.cpu.mem.unmap_memory_len(address, length);
|
||||
}
|
||||
}
|
||||
@@ -1,58 +1,54 @@
|
||||
mod icicle;
|
||||
|
||||
use icicle::IcicleEmulator;
|
||||
use std::os::raw::c_void;
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub fn test_rust() {
|
||||
// Setup the CPU state for the target triple
|
||||
let cpu_config = icicle_vm::cpu::Config::from_target_triple("x86_64-none");
|
||||
let mut vm = icicle_vm::build(&cpu_config).unwrap();
|
||||
|
||||
// Setup an environment to run inside of.
|
||||
//let mut env = icicle_vm::env::build_auto(&mut vm).unwrap();
|
||||
// Load a binary into the environment.
|
||||
//env.load(&mut vm.cpu, b"./test.elf").unwrap();
|
||||
//vm.env = env;
|
||||
|
||||
let mapping = icicle_vm::cpu::mem::Mapping { perm: icicle_vm::cpu::mem::perm::ALL, value: 0x0 };
|
||||
|
||||
let alloc1 =
|
||||
vm.cpu.mem.alloc_memory(icicle_vm::cpu::mem::AllocLayout { addr: Some(0x10000), size: 0x100, align: 0x100 }, mapping).unwrap();
|
||||
|
||||
// Add instrumentation
|
||||
let counter = vm.cpu.trace.register_store(vec![0_u64]);
|
||||
vm.add_injector(BlockCounter { counter });
|
||||
|
||||
// Run until the VM exits.
|
||||
let exit = vm.run();
|
||||
println!("{exit:?}\n{}", icicle_vm::debug::current_disasm(&mut vm));
|
||||
|
||||
|
||||
// Read instrumentation data.
|
||||
let blocks_hit = vm.cpu.trace[counter].as_any().downcast_ref::<Vec<u64>>().unwrap()[0];
|
||||
let blocks_executed = blocks_hit.saturating_sub(1);
|
||||
println!("{blocks_executed} blocks were executed");
|
||||
pub fn icicle_create_emulator() -> *mut c_void {
|
||||
let emulator = Box::new(IcicleEmulator::new());
|
||||
return Box::into_raw(emulator) as *mut c_void;
|
||||
}
|
||||
|
||||
struct BlockCounter {
|
||||
counter: icicle_vm::cpu::StoreRef,
|
||||
#[unsafe(no_mangle)]
|
||||
pub fn icicle_map_memory(
|
||||
ptr: *mut c_void,
|
||||
address: u64,
|
||||
length: u64,
|
||||
permissions: u8,
|
||||
) -> i32 {
|
||||
unsafe {
|
||||
let emulator = &mut *(ptr as *mut IcicleEmulator);
|
||||
let res = emulator.map_memory(address, length, permissions);
|
||||
|
||||
if res {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
impl icicle_vm::CodeInjector for BlockCounter {
|
||||
fn inject(
|
||||
&mut self,
|
||||
_cpu: &mut icicle_vm::cpu::Cpu,
|
||||
group: &icicle_vm::cpu::BlockGroup,
|
||||
code: &mut icicle_vm::BlockTable,
|
||||
) {
|
||||
let store_id = self.counter.get_store_id();
|
||||
for block in &mut code.blocks[group.range()] {
|
||||
// counter += 1
|
||||
let counter = block.pcode.alloc_tmp(8);
|
||||
let instrumentation = [
|
||||
(counter, pcode::Op::Load(store_id), 0_u64).into(),
|
||||
(counter, pcode::Op::IntAdd, (counter, 1_u64)).into(),
|
||||
(pcode::Op::Store(store_id), (0_u64, counter)).into(),
|
||||
];
|
||||
#[unsafe(no_mangle)]
|
||||
pub fn icicle_unmap_memory(ptr: *mut c_void, address: u64, length: u64) -> i32 {
|
||||
unsafe {
|
||||
let emulator = &mut *(ptr as *mut IcicleEmulator);
|
||||
let res = emulator.unmap_memory(address, length);
|
||||
|
||||
// Inject the instrumentation at the start of the block.
|
||||
block.pcode.instructions.splice(..0, instrumentation);
|
||||
}
|
||||
}
|
||||
}
|
||||
if res {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub fn icicle_destroy_emulator(ptr: *mut c_void) {
|
||||
if ptr.is_null() {
|
||||
return;
|
||||
}
|
||||
|
||||
unsafe {
|
||||
let _ = Box::from_raw(ptr as *mut IcicleEmulator);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user