Expose qemu's image_info for qemu usermode (#2889)

* image info for qemu usermode

* must use

---------

Co-authored-by: Toka <tokazerkje@outlook.com>
This commit is contained in:
Romain Malmain 2025-01-24 20:05:38 +01:00 committed by GitHub
parent 4083f0ba73
commit 1addbd04b9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -1,5 +1,5 @@
use std::{ use std::{
mem::MaybeUninit, ptr::copy_nonoverlapping, slice::from_raw_parts_mut, mem::MaybeUninit, ops::Range, ptr::copy_nonoverlapping, slice::from_raw_parts_mut,
str::from_utf8_unchecked_mut, str::from_utf8_unchecked_mut,
}; };
@ -21,6 +21,18 @@ pub struct GuestMaps {
pageflags_node: *mut IntervalTreeNode, pageflags_node: *mut IntervalTreeNode,
} }
/// Information about the image loaded by QEMU.
pub struct ImageInfo {
pub code: Range<GuestAddr>,
pub data: Range<GuestAddr>,
pub stack: Range<GuestAddr>,
pub vdso: GuestAddr,
pub entry: GuestAddr,
pub brk: GuestAddr,
pub alignment: GuestAddr,
pub exec_stack: bool,
}
// Consider a private new only for Emulator // Consider a private new only for Emulator
impl GuestMaps { impl GuestMaps {
#[must_use] #[must_use]
@ -129,6 +141,33 @@ impl Qemu {
GuestMaps::new() GuestMaps::new()
} }
#[must_use]
pub fn image_info(&self) -> ImageInfo {
// # Safety
// Safe because QEMU has been correctly initialized since it takes self as parameter.
let image_info = unsafe { *libafl_qemu_sys::libafl_get_image_info() };
let code_start = image_info.start_code;
let code_end = image_info.end_code;
let data_start = image_info.start_data;
let data_end = image_info.end_data;
let stack_start = image_info.stack_limit;
let stack_end = image_info.start_stack;
ImageInfo {
code: code_start..code_end,
data: data_start..data_end,
stack: stack_start..stack_end,
vdso: image_info.vdso,
entry: image_info.entry,
brk: image_info.brk,
alignment: image_info.alignment,
exec_stack: image_info.exec_stack,
}
}
#[must_use] #[must_use]
pub fn g2h<T>(&self, addr: GuestAddr) -> *mut T { pub fn g2h<T>(&self, addr: GuestAddr) -> *mut T {
unsafe { (addr as usize + guest_base) as *mut T } unsafe { (addr as usize + guest_base) as *mut T }