Make inputs in libafl_qemu generic (#1991)

* fix non-generic input in libafl_qemu

* Update setup_libxml2.sh of nyx_libxml2_standalone fuzzer (#1990)

On testing this on my machine not all neccessary files for fuzzing with nyx where provided by the setup. Compared to the nyx_libxml2_parallel fuzzer this packer generation line was missing.
After adding this the fuzzer was able to start.

---------

Co-authored-by: Dominik Maier <domenukk@gmail.com>
Co-authored-by: Tobias Mayer <arbeitskraftmayer@gmail.com>
This commit is contained in:
Romain Malmain 2024-04-02 12:30:12 +02:00 committed by GitHub
parent aaafe1fc6c
commit cca4e3daa9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 38 additions and 22 deletions

View File

@ -5,9 +5,10 @@ use std::fmt::{Debug, Display, Formatter};
use enum_map::Enum; use enum_map::Enum;
use libafl::{ use libafl::{
executors::ExitKind, executors::ExitKind,
inputs::{BytesInput, HasBytesVec}, inputs::HasTargetBytes,
state::{HasExecutions, State}, state::{HasExecutions, State},
}; };
use libafl_bolts::AsSlice;
use libafl_qemu_sys::{GuestPhysAddr, GuestVirtAddr}; use libafl_qemu_sys::{GuestPhysAddr, GuestVirtAddr};
use num_enum::TryFromPrimitive; use num_enum::TryFromPrimitive;
@ -77,7 +78,7 @@ where
&self, &self,
emu: &Emulator<QT, S, E>, emu: &Emulator<QT, S, E>,
qemu_executor_state: &mut QemuExecutorState<QT, S>, qemu_executor_state: &mut QemuExecutorState<QT, S>,
input: &BytesInput, input: &S::Input,
ret_reg: Option<Regs>, ret_reg: Option<Regs>,
) -> Result<InnerHandlerResult, HandlerError>; ) -> Result<InnerHandlerResult, HandlerError>;
} }
@ -106,6 +107,7 @@ where
SM: IsSnapshotManager, SM: IsSnapshotManager,
QT: QemuHelperTuple<S> + StdInstrumentationFilter<S> + Debug, QT: QemuHelperTuple<S> + StdInstrumentationFilter<S> + Debug,
S: State + HasExecutions, S: State + HasExecutions,
S::Input: HasTargetBytes,
{ {
fn usable_at_runtime(&self) -> bool { fn usable_at_runtime(&self) -> bool {
match self { match self {
@ -145,7 +147,7 @@ where
&self, &self,
emu: &Emulator<QT, S, StdEmuExitHandler<SM>>, emu: &Emulator<QT, S, StdEmuExitHandler<SM>>,
qemu_executor_state: &mut QemuExecutorState<QT, S>, qemu_executor_state: &mut QemuExecutorState<QT, S>,
input: &BytesInput, input: &S::Input,
ret_reg: Option<Regs>, ret_reg: Option<Regs>,
) -> Result<InnerHandlerResult, HandlerError> { ) -> Result<InnerHandlerResult, HandlerError> {
match self { match self {
@ -233,6 +235,7 @@ where
SM: IsSnapshotManager, SM: IsSnapshotManager,
QT: QemuHelperTuple<S> + StdInstrumentationFilter<S> + Debug, QT: QemuHelperTuple<S> + StdInstrumentationFilter<S> + Debug,
S: State + HasExecutions, S: State + HasExecutions,
S::Input: HasTargetBytes,
{ {
fn usable_at_runtime(&self) -> bool { fn usable_at_runtime(&self) -> bool {
false false
@ -246,7 +249,7 @@ where
QT, QT,
S, S,
>, >,
_input: &BytesInput, _input: &S::Input,
_ret_reg: Option<Regs>, _ret_reg: Option<Regs>,
) -> Result<InnerHandlerResult, HandlerError> { ) -> Result<InnerHandlerResult, HandlerError> {
let qemu = emu.qemu(); let qemu = emu.qemu();
@ -286,6 +289,7 @@ where
SM: IsSnapshotManager, SM: IsSnapshotManager,
QT: QemuHelperTuple<S> + StdInstrumentationFilter<S> + Debug, QT: QemuHelperTuple<S> + StdInstrumentationFilter<S> + Debug,
S: State + HasExecutions, S: State + HasExecutions,
S::Input: HasTargetBytes,
{ {
fn usable_at_runtime(&self) -> bool { fn usable_at_runtime(&self) -> bool {
false false
@ -295,7 +299,7 @@ where
&self, &self,
emu: &Emulator<QT, S, StdEmuExitHandler<SM>>, emu: &Emulator<QT, S, StdEmuExitHandler<SM>>,
_qemu_executor_state: &mut QemuExecutorState<QT, S>, _qemu_executor_state: &mut QemuExecutorState<QT, S>,
_input: &BytesInput, _input: &S::Input,
_ret_reg: Option<Regs>, _ret_reg: Option<Regs>,
) -> Result<InnerHandlerResult, HandlerError> { ) -> Result<InnerHandlerResult, HandlerError> {
let qemu = emu.qemu(); let qemu = emu.qemu();
@ -323,6 +327,7 @@ where
SM: IsSnapshotManager, SM: IsSnapshotManager,
QT: QemuHelperTuple<S> + StdInstrumentationFilter<S> + Debug, QT: QemuHelperTuple<S> + StdInstrumentationFilter<S> + Debug,
S: State + HasExecutions, S: State + HasExecutions,
S::Input: HasTargetBytes,
{ {
fn usable_at_runtime(&self) -> bool { fn usable_at_runtime(&self) -> bool {
true true
@ -332,12 +337,12 @@ where
&self, &self,
emu: &Emulator<QT, S, StdEmuExitHandler<SM>>, emu: &Emulator<QT, S, StdEmuExitHandler<SM>>,
_qemu_executor_state: &mut QemuExecutorState<QT, S>, _qemu_executor_state: &mut QemuExecutorState<QT, S>,
input: &BytesInput, input: &S::Input,
ret_reg: Option<Regs>, ret_reg: Option<Regs>,
) -> Result<InnerHandlerResult, HandlerError> { ) -> Result<InnerHandlerResult, HandlerError> {
let qemu = emu.qemu(); let qemu = emu.qemu();
let ret_value = self.location.write(qemu, input.bytes()); let ret_value = self.location.write(qemu, input.target_bytes().as_slice());
if let Some(reg) = ret_reg { if let Some(reg) = ret_reg {
qemu.write_reg(reg, ret_value).unwrap(); qemu.write_reg(reg, ret_value).unwrap();
@ -357,6 +362,7 @@ where
SM: IsSnapshotManager, SM: IsSnapshotManager,
QT: QemuHelperTuple<S> + StdInstrumentationFilter<S> + Debug, QT: QemuHelperTuple<S> + StdInstrumentationFilter<S> + Debug,
S: State + HasExecutions, S: State + HasExecutions,
S::Input: HasTargetBytes,
{ {
fn usable_at_runtime(&self) -> bool { fn usable_at_runtime(&self) -> bool {
false false
@ -366,7 +372,7 @@ where
&self, &self,
emu: &Emulator<QT, S, StdEmuExitHandler<SM>>, emu: &Emulator<QT, S, StdEmuExitHandler<SM>>,
_qemu_executor_state: &mut QemuExecutorState<QT, S>, _qemu_executor_state: &mut QemuExecutorState<QT, S>,
input: &BytesInput, input: &S::Input,
ret_reg: Option<Regs>, ret_reg: Option<Regs>,
) -> Result<InnerHandlerResult, HandlerError> { ) -> Result<InnerHandlerResult, HandlerError> {
let emu_exit_handler = emu.exit_handler().borrow_mut(); let emu_exit_handler = emu.exit_handler().borrow_mut();
@ -381,7 +387,9 @@ where
.set_input_location(self.input_location.clone(), ret_reg) .set_input_location(self.input_location.clone(), ret_reg)
.unwrap(); .unwrap();
let ret_value = self.input_location.write(qemu, input.bytes()); let ret_value = self
.input_location
.write(qemu, input.target_bytes().as_slice());
if let Some(reg) = ret_reg { if let Some(reg) = ret_reg {
qemu.write_reg(reg, ret_value).unwrap(); qemu.write_reg(reg, ret_value).unwrap();
@ -399,6 +407,7 @@ where
SM: IsSnapshotManager, SM: IsSnapshotManager,
QT: QemuHelperTuple<S> + StdInstrumentationFilter<S> + Debug, QT: QemuHelperTuple<S> + StdInstrumentationFilter<S> + Debug,
S: State + HasExecutions, S: State + HasExecutions,
S::Input: HasTargetBytes,
{ {
fn usable_at_runtime(&self) -> bool { fn usable_at_runtime(&self) -> bool {
false false
@ -408,7 +417,7 @@ where
&self, &self,
emu: &Emulator<QT, S, StdEmuExitHandler<SM>>, emu: &Emulator<QT, S, StdEmuExitHandler<SM>>,
_qemu_executor_state: &mut QemuExecutorState<QT, S>, _qemu_executor_state: &mut QemuExecutorState<QT, S>,
_input: &BytesInput, _input: &S::Input,
_ret_reg: Option<Regs>, _ret_reg: Option<Regs>,
) -> Result<InnerHandlerResult, HandlerError> { ) -> Result<InnerHandlerResult, HandlerError> {
let emu_exit_handler = emu.exit_handler().borrow_mut(); let emu_exit_handler = emu.exit_handler().borrow_mut();
@ -433,6 +442,7 @@ where
SM: IsSnapshotManager, SM: IsSnapshotManager,
QT: QemuHelperTuple<S> + StdInstrumentationFilter<S> + Debug, QT: QemuHelperTuple<S> + StdInstrumentationFilter<S> + Debug,
S: State + HasExecutions, S: State + HasExecutions,
S::Input: HasTargetBytes,
{ {
fn usable_at_runtime(&self) -> bool { fn usable_at_runtime(&self) -> bool {
true true
@ -442,7 +452,7 @@ where
&self, &self,
_emu: &Emulator<QT, S, StdEmuExitHandler<SM>>, _emu: &Emulator<QT, S, StdEmuExitHandler<SM>>,
_qemu_executor_state: &mut QemuExecutorState<QT, S>, _qemu_executor_state: &mut QemuExecutorState<QT, S>,
_input: &BytesInput, _input: &S::Input,
_ret_reg: Option<Regs>, _ret_reg: Option<Regs>,
) -> Result<InnerHandlerResult, HandlerError> { ) -> Result<InnerHandlerResult, HandlerError> {
let guest_version = self.0; let guest_version = self.0;
@ -471,6 +481,7 @@ where
SM: IsSnapshotManager, SM: IsSnapshotManager,
QT: QemuHelperTuple<S> + StdInstrumentationFilter<S> + Debug, QT: QemuHelperTuple<S> + StdInstrumentationFilter<S> + Debug,
S: State + HasExecutions, S: State + HasExecutions,
S::Input: HasTargetBytes,
{ {
fn usable_at_runtime(&self) -> bool { fn usable_at_runtime(&self) -> bool {
true true
@ -480,7 +491,7 @@ where
&self, &self,
_emu: &Emulator<QT, S, StdEmuExitHandler<SM>>, _emu: &Emulator<QT, S, StdEmuExitHandler<SM>>,
qemu_executor_state: &mut QemuExecutorState<QT, S>, qemu_executor_state: &mut QemuExecutorState<QT, S>,
_input: &BytesInput, _input: &S::Input,
_ret_reg: Option<Regs>, _ret_reg: Option<Regs>,
) -> Result<InnerHandlerResult, HandlerError> { ) -> Result<InnerHandlerResult, HandlerError> {
let qemu_helpers = qemu_executor_state.hooks_mut().helpers_mut(); let qemu_helpers = qemu_executor_state.hooks_mut().helpers_mut();
@ -501,6 +512,7 @@ where
SM: IsSnapshotManager, SM: IsSnapshotManager,
QT: QemuHelperTuple<S> + StdInstrumentationFilter<S> + Debug, QT: QemuHelperTuple<S> + StdInstrumentationFilter<S> + Debug,
S: State + HasExecutions, S: State + HasExecutions,
S::Input: HasTargetBytes,
{ {
fn usable_at_runtime(&self) -> bool { fn usable_at_runtime(&self) -> bool {
true true
@ -511,7 +523,7 @@ where
&self, &self,
_emu: &Emulator<QT, S, StdEmuExitHandler<SM>>, _emu: &Emulator<QT, S, StdEmuExitHandler<SM>>,
qemu_executor_state: &mut QemuExecutorState<QT, S>, qemu_executor_state: &mut QemuExecutorState<QT, S>,
_input: &BytesInput, _input: &S::Input,
_ret_reg: Option<Regs>, _ret_reg: Option<Regs>,
) -> Result<InnerHandlerResult, HandlerError> { ) -> Result<InnerHandlerResult, HandlerError> {
let qemu_helpers = qemu_executor_state.hooks_mut().helpers_mut(); let qemu_helpers = qemu_executor_state.hooks_mut().helpers_mut();

View File

@ -14,7 +14,7 @@ use std::{
ptr, ptr,
}; };
use libafl::{executors::ExitKind, inputs::BytesInput}; use libafl::executors::ExitKind;
#[cfg(emulation_mode = "systemmode")] #[cfg(emulation_mode = "systemmode")]
use libafl_qemu_sys::qemu_init; use libafl_qemu_sys::qemu_init;
#[cfg(emulation_mode = "usermode")] #[cfg(emulation_mode = "usermode")]
@ -128,14 +128,14 @@ where
fn try_put_input( fn try_put_input(
emu: &Emulator<QT, S, Self>, emu: &Emulator<QT, S, Self>,
qemu_executor_state: &mut QemuExecutorState<QT, S>, qemu_executor_state: &mut QemuExecutorState<QT, S>,
input: &BytesInput, input: &S::Input,
); );
fn handle( fn handle(
emu: &Emulator<QT, S, Self>, emu: &Emulator<QT, S, Self>,
exit_reason: Result<EmuExitReason, EmuExitReasonError>, exit_reason: Result<EmuExitReason, EmuExitReasonError>,
qemu_executor_state: &mut QemuExecutorState<QT, S>, qemu_executor_state: &mut QemuExecutorState<QT, S>,
input: &BytesInput, input: &S::Input,
) -> Result<InnerHandlerResult, HandlerError>; ) -> Result<InnerHandlerResult, HandlerError>;
} }
@ -157,13 +157,13 @@ where
QT: QemuHelperTuple<S>, QT: QemuHelperTuple<S>,
S: State + HasExecutions, S: State + HasExecutions,
{ {
fn try_put_input(_: &Emulator<QT, S, Self>, _: &mut QemuExecutorState<QT, S>, _: &BytesInput) {} fn try_put_input(_: &Emulator<QT, S, Self>, _: &mut QemuExecutorState<QT, S>, _: &S::Input) {}
fn handle( fn handle(
_: &Emulator<QT, S, Self>, _: &Emulator<QT, S, Self>,
exit_reason: Result<EmuExitReason, EmuExitReasonError>, exit_reason: Result<EmuExitReason, EmuExitReasonError>,
_: &mut QemuExecutorState<QT, S>, _: &mut QemuExecutorState<QT, S>,
_: &BytesInput, _: &S::Input,
) -> Result<InnerHandlerResult, HandlerError> { ) -> Result<InnerHandlerResult, HandlerError> {
match exit_reason { match exit_reason {
Ok(reason) => Ok(InnerHandlerResult::ReturnToHarness(reason)), Ok(reason) => Ok(InnerHandlerResult::ReturnToHarness(reason)),
@ -226,11 +226,12 @@ where
SM: IsSnapshotManager, SM: IsSnapshotManager,
QT: QemuHelperTuple<S> + StdInstrumentationFilter<S> + Debug, QT: QemuHelperTuple<S> + StdInstrumentationFilter<S> + Debug,
S: State + HasExecutions, S: State + HasExecutions,
S::Input: HasTargetBytes,
{ {
fn try_put_input( fn try_put_input(
emu: &Emulator<QT, S, Self>, emu: &Emulator<QT, S, Self>,
qemu_executor_state: &mut QemuExecutorState<QT, S>, qemu_executor_state: &mut QemuExecutorState<QT, S>,
input: &BytesInput, input: &S::Input,
) { ) {
let exit_handler = emu.state().exit_handler.borrow(); let exit_handler = emu.state().exit_handler.borrow();
@ -246,7 +247,7 @@ where
emu: &Emulator<QT, S, Self>, emu: &Emulator<QT, S, Self>,
exit_reason: Result<EmuExitReason, EmuExitReasonError>, exit_reason: Result<EmuExitReason, EmuExitReasonError>,
qemu_executor_state: &mut QemuExecutorState<QT, S>, qemu_executor_state: &mut QemuExecutorState<QT, S>,
input: &BytesInput, input: &S::Input,
) -> Result<InnerHandlerResult, HandlerError> { ) -> Result<InnerHandlerResult, HandlerError> {
let exit_handler = emu.exit_handler().borrow_mut(); let exit_handler = emu.exit_handler().borrow_mut();
let qemu = emu.qemu(); let qemu = emu.qemu();
@ -632,7 +633,10 @@ create_hook_id!(NewThread, libafl_qemu_remove_new_thread_hook, false);
use std::{pin::Pin, ptr::NonNull}; use std::{pin::Pin, ptr::NonNull};
use libafl::state::{HasExecutions, State}; use libafl::{
inputs::HasTargetBytes,
state::{HasExecutions, State},
};
use libafl_bolts::os::unix_signals::Signal; use libafl_bolts::os::unix_signals::Signal;
use crate::{ use crate::{
@ -1528,7 +1532,7 @@ where
/// Of course, the emulated target is not contained securely and can corrupt state or interact with the operating system. /// Of course, the emulated target is not contained securely and can corrupt state or interact with the operating system.
pub unsafe fn run( pub unsafe fn run(
&self, &self,
input: &BytesInput, input: &S::Input,
qemu_executor_state: &mut QemuExecutorState<QT, S>, qemu_executor_state: &mut QemuExecutorState<QT, S>,
) -> Result<HandlerResult, HandlerError> { ) -> Result<HandlerResult, HandlerError> {
loop { loop {