parent
f1aee3c376
commit
b4e987a640
@ -65,7 +65,7 @@ impl TryFrom<u32> for QasanAction {
|
|||||||
type Error = num_enum::TryFromPrimitiveError<QasanAction>;
|
type Error = num_enum::TryFromPrimitiveError<QasanAction>;
|
||||||
|
|
||||||
fn try_from(value: u32) -> Result<Self, Self::Error> {
|
fn try_from(value: u32) -> Result<Self, Self::Error> {
|
||||||
QasanAction::try_from(value as u64)
|
QasanAction::try_from(u64::from(value))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,8 +42,8 @@ pub enum GuestAddrKind {
|
|||||||
impl fmt::Display for GuestAddrKind {
|
impl fmt::Display for GuestAddrKind {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
GuestAddrKind::Physical(phys_addr) => write!(f, "hwaddr 0x{:x}", phys_addr),
|
GuestAddrKind::Physical(phys_addr) => write!(f, "hwaddr 0x{phys_addr:x}"),
|
||||||
GuestAddrKind::Virtual(virt_addr) => write!(f, "vaddr 0x{:x}", virt_addr),
|
GuestAddrKind::Virtual(virt_addr) => write!(f, "vaddr 0x{virt_addr:x}"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -793,13 +793,13 @@ impl<T> From<&'static T> for HookData {
|
|||||||
|
|
||||||
impl<T> From<*mut T> for HookData {
|
impl<T> From<*mut T> for HookData {
|
||||||
fn from(value: *mut T) -> Self {
|
fn from(value: *mut T) -> Self {
|
||||||
unsafe { HookData(core::mem::transmute(value)) }
|
HookData(value as u64)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> From<*const T> for HookData {
|
impl<T> From<*const T> for HookData {
|
||||||
fn from(value: *const T) -> Self {
|
fn from(value: *const T) -> Self {
|
||||||
unsafe { HookData(core::mem::transmute(value)) }
|
HookData(value as u64)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -811,19 +811,19 @@ impl From<u64> for HookData {
|
|||||||
|
|
||||||
impl From<u32> for HookData {
|
impl From<u32> for HookData {
|
||||||
fn from(value: u32) -> Self {
|
fn from(value: u32) -> Self {
|
||||||
HookData(value as u64)
|
HookData(u64::from(value))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<u16> for HookData {
|
impl From<u16> for HookData {
|
||||||
fn from(value: u16) -> Self {
|
fn from(value: u16) -> Self {
|
||||||
HookData(value as u64)
|
HookData(u64::from(value))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<u8> for HookData {
|
impl From<u8> for HookData {
|
||||||
fn from(value: u8) -> Self {
|
fn from(value: u8) -> Self {
|
||||||
HookData(value as u64)
|
HookData(u64::from(value))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -845,9 +845,9 @@ impl fmt::Display for EmuExitReason {
|
|||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
EmuExitReason::End => write!(f, "End"),
|
EmuExitReason::End => write!(f, "End"),
|
||||||
EmuExitReason::Breakpoint(vaddr) => write!(f, "Breakpoint @vaddr 0x{:x}", vaddr),
|
EmuExitReason::Breakpoint(vaddr) => write!(f, "Breakpoint @vaddr 0x{vaddr:x}"),
|
||||||
EmuExitReason::SyncBackdoor(sync_backdoor) => {
|
EmuExitReason::SyncBackdoor(sync_backdoor) => {
|
||||||
write!(f, "Sync backdoor exit: {}", sync_backdoor)
|
write!(f, "Sync backdoor exit: {sync_backdoor}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -874,7 +874,7 @@ impl TryFrom<&Emulator> for EmuExitReason {
|
|||||||
Err(EmuExitReasonError::UnexpectedExit)
|
Err(EmuExitReasonError::UnexpectedExit)
|
||||||
} else {
|
} else {
|
||||||
let exit_reason: &mut libafl_qemu_sys::libafl_exit_reason =
|
let exit_reason: &mut libafl_qemu_sys::libafl_exit_reason =
|
||||||
unsafe { transmute(exit_reason) };
|
unsafe { transmute(&mut *exit_reason) };
|
||||||
Ok(match exit_reason.kind {
|
Ok(match exit_reason.kind {
|
||||||
libafl_qemu_sys::libafl_exit_reason_kind_BREAKPOINT => unsafe {
|
libafl_qemu_sys::libafl_exit_reason_kind_BREAKPOINT => unsafe {
|
||||||
EmuExitReason::Breakpoint(exit_reason.data.breakpoint.addr.into())
|
EmuExitReason::Breakpoint(exit_reason.data.breakpoint.addr.into())
|
||||||
|
@ -58,10 +58,7 @@ pub enum Hook<F, C, R: Clone> {
|
|||||||
|
|
||||||
impl<F, C, R: Clone> Hook<F, C, R> {
|
impl<F, C, R: Clone> Hook<F, C, R> {
|
||||||
pub fn is_empty(&self) -> bool {
|
pub fn is_empty(&self) -> bool {
|
||||||
match self {
|
matches!(self, Hook::Empty)
|
||||||
Hook::Empty => true,
|
|
||||||
_ => false,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -81,7 +78,7 @@ macro_rules! get_raw_hook {
|
|||||||
macro_rules! hook_to_repr {
|
macro_rules! hook_to_repr {
|
||||||
($h:expr) => {
|
($h:expr) => {
|
||||||
match $h {
|
match $h {
|
||||||
Hook::Function(f) => HookRepr::Function(transmute(f)),
|
Hook::Function(f) => HookRepr::Function(f as *const libc::c_void),
|
||||||
Hook::Closure(c) => HookRepr::Closure(transmute(c)),
|
Hook::Closure(c) => HookRepr::Closure(transmute(c)),
|
||||||
Hook::Raw(_) => HookRepr::Empty, // managed by emu
|
Hook::Raw(_) => HookRepr::Empty, // managed by emu
|
||||||
Hook::Empty => HookRepr::Empty,
|
Hook::Empty => HookRepr::Empty,
|
||||||
@ -332,7 +329,7 @@ where
|
|||||||
let func: &mut Box<dyn FnMut(&mut QemuHooks<QT, S>, i32)> = transmute(ptr);
|
let func: &mut Box<dyn FnMut(&mut QemuHooks<QT, S>, i32)> = transmute(ptr);
|
||||||
func(hooks, target_sig);
|
func(hooks, target_sig);
|
||||||
}
|
}
|
||||||
_ => (),
|
HookRepr::Empty => (),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -459,16 +456,14 @@ where
|
|||||||
>,
|
>,
|
||||||
invalidate_block: bool,
|
invalidate_block: bool,
|
||||||
) -> HookId {
|
) -> HookId {
|
||||||
unsafe {
|
match hook {
|
||||||
match hook {
|
Hook::Function(f) => self.instruction_function(addr, f, invalidate_block),
|
||||||
Hook::Function(f) => self.instruction_function(addr, f, invalidate_block),
|
Hook::Closure(c) => self.instruction_closure(addr, c, invalidate_block),
|
||||||
Hook::Closure(c) => self.instruction_closure(addr, c, invalidate_block),
|
Hook::Raw(r) => {
|
||||||
Hook::Raw(r) => {
|
let z: *const () = ptr::null::<()>();
|
||||||
let z: *const () = transmute(0u64);
|
self.emulator.set_hook(z, addr, r, invalidate_block)
|
||||||
self.emulator.set_hook(z, addr, r, invalidate_block)
|
|
||||||
}
|
|
||||||
Hook::Empty => HookId(0), // TODO error type
|
|
||||||
}
|
}
|
||||||
|
Hook::Empty => HookId(0), // TODO error type
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -883,16 +878,14 @@ where
|
|||||||
extern "C" fn(*const (), pc: GuestAddr),
|
extern "C" fn(*const (), pc: GuestAddr),
|
||||||
>,
|
>,
|
||||||
) -> HookId {
|
) -> HookId {
|
||||||
unsafe {
|
match hook {
|
||||||
match hook {
|
Hook::Function(f) => self.backdoor_function(f),
|
||||||
Hook::Function(f) => self.backdoor_function(f),
|
Hook::Closure(c) => self.backdoor_closure(c),
|
||||||
Hook::Closure(c) => self.backdoor_closure(c),
|
Hook::Raw(r) => {
|
||||||
Hook::Raw(r) => {
|
let z: *const () = ptr::null::<()>();
|
||||||
let z: *const () = transmute(0u64);
|
self.emulator.add_backdoor_hook(z, r)
|
||||||
self.emulator.add_backdoor_hook(z, r)
|
|
||||||
}
|
|
||||||
Hook::Empty => HookId(0), // TODO error type
|
|
||||||
}
|
}
|
||||||
|
Hook::Empty => HookId(0), // TODO error type
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -966,16 +959,14 @@ where
|
|||||||
) -> SyscallHookResult,
|
) -> SyscallHookResult,
|
||||||
>,
|
>,
|
||||||
) -> HookId {
|
) -> HookId {
|
||||||
unsafe {
|
match hook {
|
||||||
match hook {
|
Hook::Function(f) => self.syscalls_function(f),
|
||||||
Hook::Function(f) => self.syscalls_function(f),
|
Hook::Closure(c) => self.syscalls_closure(c),
|
||||||
Hook::Closure(c) => self.syscalls_closure(c),
|
Hook::Raw(r) => {
|
||||||
Hook::Raw(r) => {
|
let z: *const () = ptr::null::<()>();
|
||||||
let z: *const () = transmute(0u64);
|
self.emulator.add_pre_syscall_hook(z, r)
|
||||||
self.emulator.add_pre_syscall_hook(z, r)
|
|
||||||
}
|
|
||||||
Hook::Empty => HookId(0), // TODO error type
|
|
||||||
}
|
}
|
||||||
|
Hook::Empty => HookId(0), // TODO error type
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1085,16 +1076,14 @@ where
|
|||||||
) -> GuestAddr,
|
) -> GuestAddr,
|
||||||
>,
|
>,
|
||||||
) -> HookId {
|
) -> HookId {
|
||||||
unsafe {
|
match hook {
|
||||||
match hook {
|
Hook::Function(f) => self.after_syscalls_function(f),
|
||||||
Hook::Function(f) => self.after_syscalls_function(f),
|
Hook::Closure(c) => self.after_syscalls_closure(c),
|
||||||
Hook::Closure(c) => self.after_syscalls_closure(c),
|
Hook::Raw(r) => {
|
||||||
Hook::Raw(r) => {
|
let z: *const () = ptr::null::<()>();
|
||||||
let z: *const () = transmute(0u64);
|
self.emulator.add_post_syscall_hook(z, r)
|
||||||
self.emulator.add_post_syscall_hook(z, r)
|
|
||||||
}
|
|
||||||
Hook::Empty => HookId(0), // TODO error type
|
|
||||||
}
|
}
|
||||||
|
Hook::Empty => HookId(0), // TODO error type
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1165,16 +1154,14 @@ where
|
|||||||
extern "C" fn(*const (), tid: u32) -> bool,
|
extern "C" fn(*const (), tid: u32) -> bool,
|
||||||
>,
|
>,
|
||||||
) -> HookId {
|
) -> HookId {
|
||||||
unsafe {
|
match hook {
|
||||||
match hook {
|
Hook::Function(f) => self.thread_creation_function(f),
|
||||||
Hook::Function(f) => self.thread_creation_function(f),
|
Hook::Closure(c) => self.thread_creation_closure(c),
|
||||||
Hook::Closure(c) => self.thread_creation_closure(c),
|
Hook::Raw(r) => {
|
||||||
Hook::Raw(r) => {
|
let z: *const () = ptr::null::<()>();
|
||||||
let z: *const () = transmute(0u64);
|
self.emulator.add_new_thread_hook(z, r)
|
||||||
self.emulator.add_new_thread_hook(z, r)
|
|
||||||
}
|
|
||||||
Hook::Empty => HookId(0), // TODO error type
|
|
||||||
}
|
}
|
||||||
|
Hook::Empty => HookId(0), // TODO error type
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,19 +79,19 @@ impl CommandInput {
|
|||||||
#[cfg(emulation_mode = "usermode")]
|
#[cfg(emulation_mode = "usermode")]
|
||||||
{
|
{
|
||||||
// For now the default behaviour is to fall back to virtual addresses
|
// For now the default behaviour is to fall back to virtual addresses
|
||||||
emu.write_mem(hwaddr.try_into().unwrap(), input)
|
emu.write_mem(hwaddr.try_into().unwrap(), input);
|
||||||
}
|
}
|
||||||
#[cfg(emulation_mode = "systemmode")]
|
#[cfg(emulation_mode = "systemmode")]
|
||||||
{
|
{
|
||||||
emu.write_phys_mem(hwaddr, input)
|
emu.write_phys_mem(hwaddr, input);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
GuestAddrKind::Virtual(vaddr) => unsafe {
|
GuestAddrKind::Virtual(vaddr) => unsafe {
|
||||||
emu.write_mem(vaddr.try_into().unwrap(), input)
|
emu.write_mem(vaddr.try_into().unwrap(), input);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
backdoor.ret(&emu, input.len().try_into().unwrap()).unwrap()
|
backdoor.ret(emu, input.len().try_into().unwrap()).unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -115,11 +115,11 @@ impl Display for Command {
|
|||||||
match self {
|
match self {
|
||||||
Command::Save => write!(f, "Save VM"),
|
Command::Save => write!(f, "Save VM"),
|
||||||
Command::Load => write!(f, "Reload VM"),
|
Command::Load => write!(f, "Reload VM"),
|
||||||
Command::Input(command_input) => write!(f, "Set fuzzing input @{}", command_input),
|
Command::Input(command_input) => write!(f, "Set fuzzing input @{command_input}"),
|
||||||
Command::Start(command_input) => {
|
Command::Start(command_input) => {
|
||||||
write!(f, "Start fuzzing with input @{}", command_input)
|
write!(f, "Start fuzzing with input @{command_input}")
|
||||||
}
|
}
|
||||||
Command::Exit(exit_kind) => write!(f, "Exit of kind {:?}", exit_kind),
|
Command::Exit(exit_kind) => write!(f, "Exit of kind {exit_kind:?}"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -131,6 +131,7 @@ pub struct SyncBackdoor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl SyncBackdoor {
|
impl SyncBackdoor {
|
||||||
|
#[must_use]
|
||||||
pub fn command(&self) -> &Command {
|
pub fn command(&self) -> &Command {
|
||||||
&self.command
|
&self.command
|
||||||
}
|
}
|
||||||
@ -197,18 +198,15 @@ impl TryFrom<&Emulator> for SyncBackdoor {
|
|||||||
let native_exit_kind: Result<NativeExitKind, _> =
|
let native_exit_kind: Result<NativeExitKind, _> =
|
||||||
u64::from(native_exit_kind).try_into();
|
u64::from(native_exit_kind).try_into();
|
||||||
|
|
||||||
let exit_kind = native_exit_kind
|
let exit_kind = native_exit_kind.ok().and_then(|k| {
|
||||||
.ok()
|
EMU_EXIT_KIND_MAP.get_or_init(|| {
|
||||||
.map(|k| {
|
enum_map! {
|
||||||
EMU_EXIT_KIND_MAP.get_or_init(|| {
|
NativeExitKind::Unknown => None,
|
||||||
enum_map! {
|
NativeExitKind::Ok => Some(ExitKind::Ok),
|
||||||
NativeExitKind::Unknown => None,
|
NativeExitKind::Crash => Some(ExitKind::Crash)
|
||||||
NativeExitKind::Ok => Some(ExitKind::Ok),
|
}
|
||||||
NativeExitKind::Crash => Some(ExitKind::Crash)
|
})[k]
|
||||||
}
|
});
|
||||||
})[k]
|
|
||||||
})
|
|
||||||
.flatten();
|
|
||||||
|
|
||||||
SyncBackdoor {
|
SyncBackdoor {
|
||||||
command: Command::Exit(exit_kind),
|
command: Command::Exit(exit_kind),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user