[libafl_qemu] map_fixed and mprotect target memory (#483)

This commit is contained in:
Evan Richter 2022-01-20 15:06:26 -06:00 committed by GitHub
parent 5e1c0b96ea
commit ab7d16347f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -6,6 +6,7 @@ use core::{
mem::{size_of, transmute, MaybeUninit},
ptr::{addr_of, addr_of_mut, copy_nonoverlapping, null},
};
use libc::c_int;
use num_enum::{IntoPrimitive, TryFromPrimitive};
use num_traits::Num;
use std::{slice::from_raw_parts, str::from_utf8_unchecked};
@ -190,6 +191,9 @@ extern "C" {
fn target_mmap(start: u64, len: u64, target_prot: i32, flags: i32, fd: i32, offset: u64)
-> u64;
/// int target_mprotect(abi_ulong start, abi_ulong len, int prot);
fn target_mprotect(start: u64, len: u64, target_prot: i32) -> i32;
/// int target_munmap(abi_ulong start, abi_ulong len)
fn target_munmap(start: u64, len: u64) -> i32;
@ -465,24 +469,44 @@ impl Emulator {
unsafe { libafl_set_brk(brk) };
}
pub fn map_private(&self, addr: u64, size: usize, perms: MmapPerms) -> Result<u64, String> {
let res = unsafe {
target_mmap(
addr,
size as u64,
perms.into(),
libc::MAP_PRIVATE | libc::MAP_ANONYMOUS,
-1,
0,
)
};
fn mmap(&self, addr: u64, size: usize, perms: MmapPerms, flags: c_int) -> Result<u64, ()> {
let res = unsafe { target_mmap(addr, size as u64, perms.into(), flags, -1, 0) };
if res == 0 {
Err(format!("Failed to map {}", addr))
Err(())
} else {
Ok(res)
}
}
pub fn map_private(&self, addr: u64, size: usize, perms: MmapPerms) -> Result<u64, String> {
self.mmap(
addr,
size,
perms.into(),
libc::MAP_PRIVATE | libc::MAP_ANONYMOUS,
)
.map_err(|_| format!("Failed to map {}", addr))
}
pub fn map_fixed(&self, addr: u64, size: usize, perms: MmapPerms) -> Result<u64, String> {
self.mmap(
addr,
size,
perms.into(),
libc::MAP_FIXED | libc::MAP_PRIVATE | libc::MAP_ANONYMOUS,
)
.map_err(|_| format!("Failed to map {}", addr))
}
pub fn mprotect(&self, addr: u64, size: usize, perms: MmapPerms) -> Result<(), String> {
let res = unsafe { target_mprotect(addr, size as u64, perms.into()) };
if res == 0 {
Ok(())
} else {
Err(format!("Failed to mprotect {}", addr))
}
}
pub fn unmap(&self, addr: u64, size: usize) -> Result<(), String> {
if unsafe { target_munmap(addr, size as u64) } == 0 {
Ok(())
@ -774,6 +798,26 @@ pub mod pybind {
}
}
fn map_fixed(&self, addr: u64, size: usize, perms: i32) -> PyResult<u64> {
if let Ok(p) = MmapPerms::try_from(perms) {
self.emu
.map_fixed(addr, size, p)
.map_err(PyValueError::new_err)
} else {
Err(PyValueError::new_err("Invalid perms"))
}
}
fn mprotect(&self, addr: u64, size: usize, perms: i32) -> PyResult<()> {
if let Ok(p) = MmapPerms::try_from(perms) {
self.emu
.mprotect(addr, size, p)
.map_err(PyValueError::new_err)
} else {
Err(PyValueError::new_err("Invalid perms"))
}
}
fn unmap(&self, addr: u64, size: usize) -> PyResult<()> {
self.emu.unmap(addr, size).map_err(PyValueError::new_err)
}