Support reading and writing memory

This commit is contained in:
momo5502
2025-03-27 20:57:04 +01:00
parent 65d0da70a0
commit da6ba1a329
4 changed files with 87 additions and 33 deletions

View File

@@ -6,13 +6,27 @@ using icicle_emulator = struct icicle_emulator_;
extern "C"
{
icicle_emulator* icicle_create_emulator();
int32_t icicle_protect_memory(icicle_emulator*, uint64_t address, uint64_t length, uint8_t permissions);
int32_t icicle_map_memory(icicle_emulator*, uint64_t address, uint64_t length, uint8_t permissions);
int32_t icicle_unmap_memory(icicle_emulator*, uint64_t address, uint64_t length);
int32_t icicle_read_memory(icicle_emulator*, uint64_t address, void* data, size_t length);
int32_t icicle_write_memory(icicle_emulator*, uint64_t address, const void* data, size_t length);
void icicle_destroy_emulator(icicle_emulator*);
}
namespace icicle
{
namespace
{
void ice(const bool result, const std::string_view error)
{
if (!result)
{
throw std::runtime_error(std::string(error));
}
}
}
class icicle_x64_emulator : public x64_emulator
{
public:
@@ -66,42 +80,36 @@ namespace icicle
void map_memory(const uint64_t address, const size_t size, memory_permission permissions) override
{
const auto res = icicle_map_memory(this->emu_, address, size, static_cast<uint8_t>(permissions));
if (!res)
{
throw std::runtime_error("Failed to map memory");
}
ice(res, "Failed to map memory");
}
void unmap_memory(const uint64_t address, const size_t size) override
{
const auto res = icicle_unmap_memory(this->emu_, address, size);
if (!res)
{
throw std::runtime_error("Failed to map memory");
}
ice(res, "Failed to unmap memory");
}
bool try_read_memory(const uint64_t address, void* data, const size_t size) const override
{
throw std::runtime_error("Not implemented");
return icicle_read_memory(this->emu_, address, data, size);
}
void read_memory(const uint64_t address, void* data, const size_t size) const override
{
if (!this->try_read_memory(address, data, size))
{
throw std::runtime_error("Failed to read memory");
}
const auto res = this->try_read_memory(address, data, size);
ice(res, "Failed to read memory");
}
void write_memory(const uint64_t address, const void* data, const size_t size) override
{
throw std::runtime_error("Not implemented");
const auto res = icicle_write_memory(this->emu_, address, data, size);
ice(res, "Failed to write memory");
}
void apply_memory_protection(const uint64_t address, const size_t size, memory_permission permissions) override
{
throw std::runtime_error("Not implemented");
const auto res = icicle_protect_memory(this->emu_, address, size, static_cast<uint8_t>(permissions));
ice(res, "Failed to apply permissions");
}
emulator_hook* hook_instruction(int instruction_type, instruction_hook_callback callback) override

2
src/icicle/.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
/target
/Ghidra

View File

@@ -37,6 +37,10 @@ impl IcicleEmulator {
}
}
fn get_mem(&mut self) -> &mut icicle_vm::cpu::Mmu {
return &mut self.vm.cpu.mem;
}
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
@@ -55,11 +59,27 @@ impl IcicleEmulator {
align: 0x1000,
};
let res = self.vm.cpu.mem.alloc_memory(layout, mapping);
let res = self.get_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);
return self.get_mem().unmap_memory_len(address, length);
}
pub fn protect_memory(&mut self, address: u64, length: u64, permissions: u8) -> bool {
let native_permissions = map_permissions(permissions);
let res = self.get_mem().update_perm(address, length, native_permissions);
return res.is_ok();
}
pub fn write_memory(&mut self, address: u64, data: &[u8]) -> bool {
let res = self.get_mem().write_bytes(address, data, icicle_vm::cpu::mem::perm::WRITE);
return res.is_ok();
}
pub fn read_memory(&mut self, address: u64, data: &mut [u8]) -> bool {
let res = self.get_mem().read_bytes(address, data, icicle_vm::cpu::mem::perm::READ);
return res.is_ok();
}
}

View File

@@ -3,6 +3,14 @@ mod icicle;
use icicle::IcicleEmulator;
use std::os::raw::c_void;
fn to_cbool(value: bool) -> i32 {
if value {
return 1;
}
return 0;
}
#[unsafe(no_mangle)]
pub fn icicle_create_emulator() -> *mut c_void {
let emulator = Box::new(IcicleEmulator::new());
@@ -10,21 +18,11 @@ pub fn icicle_create_emulator() -> *mut c_void {
}
#[unsafe(no_mangle)]
pub fn icicle_map_memory(
ptr: *mut c_void,
address: u64,
length: u64,
permissions: u8,
) -> i32 {
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;
return to_cbool(res);
}
}
@@ -33,12 +31,38 @@ 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);
return to_cbool(res);
}
}
if res {
return 1;
}
#[unsafe(no_mangle)]
pub fn icicle_protect_memory(ptr: *mut c_void, address: u64, length: u64, permissions: u8) -> i32 {
unsafe {
let emulator = &mut *(ptr as *mut IcicleEmulator);
let res = emulator.protect_memory(address, length, permissions);
return to_cbool(res);
}
}
return 0;
#[unsafe(no_mangle)]
pub fn icicle_write_memory(ptr: *mut c_void, address: u64, data: *const c_void, size: usize) -> i32 {
unsafe {
let emulator = &mut *(ptr as *mut IcicleEmulator);
let u8_ptr = data as *const u8;
let u8_slice = std::slice::from_raw_parts(u8_ptr, size);
let res = emulator.write_memory(address, u8_slice);
return to_cbool(res);
}
}
#[unsafe(no_mangle)]
pub fn icicle_read_memory(ptr: *mut c_void, address: u64, data: *mut c_void, size: usize) -> i32 {
unsafe {
let emulator = &mut *(ptr as *mut IcicleEmulator);
let u8_ptr = data as *mut u8;
let u8_slice = std::slice::from_raw_parts_mut(u8_ptr, size);
let res = emulator.read_memory(address, u8_slice);
return to_cbool(res);
}
}