Add PC to QEMU's read / write callbacks + logger module (#2896)
* Logger module (only read/write for now) * add pc to rw callbacks * regen bindings
This commit is contained in:
parent
133a0ffe7a
commit
b320a8dbab
@ -241,15 +241,16 @@ mac_alias = "unsupported"
|
|||||||
windows_alias = "unsupported"
|
windows_alias = "unsupported"
|
||||||
|
|
||||||
[tasks.run_unix]
|
[tasks.run_unix]
|
||||||
command = "${TARGET_DIR}/${PROFILE_DIR}/qemu_coverage-${CARGO_MAKE_PROFILE}"
|
script_runner = "@shell"
|
||||||
args = [
|
script = '''
|
||||||
"--coverage-path",
|
${TARGET_DIR}/${PROFILE_DIR}/qemu_coverage-${CARGO_MAKE_PROFILE} \
|
||||||
"${TARGET_DIR}/cov.drcov",
|
--coverage-path \
|
||||||
"--input-dir",
|
${TARGET_DIR}/cov.drcov \
|
||||||
"./corpus",
|
--input-dir \
|
||||||
"--",
|
./corpus \
|
||||||
"${TARGET_DIR}/libpng-harness-${CARGO_MAKE_PROFILE}",
|
-- \
|
||||||
]
|
${TARGET_DIR}/libpng-harness-${CARGO_MAKE_PROFILE}
|
||||||
|
'''
|
||||||
dependencies = ["harness", "fuzzer"]
|
dependencies = ["harness", "fuzzer"]
|
||||||
|
|
||||||
[tasks.test]
|
[tasks.test]
|
||||||
@ -297,11 +298,9 @@ cargo run --manifest-path ../../../utils/drcov_utils/Cargo.toml --bin drcov_merg
|
|||||||
-i ${TARGET_DIR}/cov-000.drcov ${TARGET_DIR}/cov-001.drcov ${TARGET_DIR}/cov-002.drcov ${TARGET_DIR}/cov-003.drcov \
|
-i ${TARGET_DIR}/cov-000.drcov ${TARGET_DIR}/cov-001.drcov ${TARGET_DIR}/cov-002.drcov ${TARGET_DIR}/cov-003.drcov \
|
||||||
--output ${TARGET_DIR}/cov-merged.drcov || exit 1
|
--output ${TARGET_DIR}/cov-merged.drcov || exit 1
|
||||||
|
|
||||||
TMP=$(cargo run --manifest-path ../../../utils/drcov_utils/Cargo.toml --bin drcov_dump_addrs -- \
|
NB_BLOCKS=$(cargo run --manifest-path ../../../utils/drcov_utils/Cargo.toml --bin drcov_dump_addrs -- \
|
||||||
-i ${TARGET_DIR}/cov-merged.drcov -a | wc -l || exit 1)
|
-i ${TARGET_DIR}/cov-merged.drcov -a | wc -l || exit 1)
|
||||||
|
|
||||||
NB_BLOCKS=$((TMP - 1))
|
|
||||||
|
|
||||||
echo "Nb blocks found: $NB_BLOCKS"
|
echo "Nb blocks found: $NB_BLOCKS"
|
||||||
|
|
||||||
if [ $NB_BLOCKS -ge 1700 ]; then
|
if [ $NB_BLOCKS -ge 1700 ]; then
|
||||||
|
@ -136,7 +136,7 @@ pub fn fuzz() {
|
|||||||
|
|
||||||
let emulator_modules = tuple_list!(
|
let emulator_modules = tuple_list!(
|
||||||
DrCovModule::builder().filename(cov_path.clone()).build(),
|
DrCovModule::builder().filename(cov_path.clone()).build(),
|
||||||
SnapshotModule::new()
|
SnapshotModule::new(),
|
||||||
);
|
);
|
||||||
|
|
||||||
let emulator = Emulator::empty()
|
let emulator = Emulator::empty()
|
||||||
|
@ -11,7 +11,7 @@ use crate::cargo_add_rpath;
|
|||||||
|
|
||||||
pub const QEMU_URL: &str = "https://github.com/AFLplusplus/qemu-libafl-bridge";
|
pub const QEMU_URL: &str = "https://github.com/AFLplusplus/qemu-libafl-bridge";
|
||||||
pub const QEMU_DIRNAME: &str = "qemu-libafl-bridge";
|
pub const QEMU_DIRNAME: &str = "qemu-libafl-bridge";
|
||||||
pub const QEMU_REVISION: &str = "2b5e4bfcff875571b2813a9494de8b2e4c56120e";
|
pub const QEMU_REVISION: &str = "7e0dc68430c509ad50c6b0c9887f7e642a4bba2d";
|
||||||
|
|
||||||
pub struct BuildResult {
|
pub struct BuildResult {
|
||||||
pub qemu_path: PathBuf,
|
pub qemu_path: PathBuf,
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* 1.85.0-nightly */
|
/* 1.86.0-nightly */
|
||||||
/* qemu git hash: 81e52dc60f83c3ae191c1a07b39bb255e633c234 */
|
/* qemu git hash: 3f7b2d86635aaf03818aaec1d285dba88255f831 */
|
||||||
/* automatically generated by rust-bindgen 0.71.1 */
|
/* automatically generated by rust-bindgen 0.71.1 */
|
||||||
|
|
||||||
use libc::siginfo_t;
|
use libc::siginfo_t;
|
||||||
@ -8025,6 +8025,8 @@ unsafe extern "C" {
|
|||||||
unsafe extern "C" {
|
unsafe extern "C" {
|
||||||
pub fn libafl_qemu_hook_edge_run();
|
pub fn libafl_qemu_hook_edge_run();
|
||||||
}
|
}
|
||||||
|
pub type libafl_instruction_cb =
|
||||||
|
::std::option::Option<unsafe extern "C" fn(data: u64, pc: target_ulong)>;
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Debug, Copy, Clone)]
|
#[derive(Debug, Copy, Clone)]
|
||||||
pub struct libafl_instruction_hook {
|
pub struct libafl_instruction_hook {
|
||||||
@ -8063,7 +8065,7 @@ impl Default for libafl_instruction_hook {
|
|||||||
unsafe extern "C" {
|
unsafe extern "C" {
|
||||||
pub fn libafl_qemu_add_instruction_hooks(
|
pub fn libafl_qemu_add_instruction_hooks(
|
||||||
pc: target_ulong,
|
pc: target_ulong,
|
||||||
callback: ::std::option::Option<unsafe extern "C" fn(data: u64, pc: target_ulong)>,
|
callback: libafl_instruction_cb,
|
||||||
data: u64,
|
data: u64,
|
||||||
invalidate: ::std::os::raw::c_int,
|
invalidate: ::std::os::raw::c_int,
|
||||||
) -> usize;
|
) -> usize;
|
||||||
@ -8086,12 +8088,19 @@ unsafe extern "C" {
|
|||||||
unsafe extern "C" {
|
unsafe extern "C" {
|
||||||
pub fn libafl_qemu_hook_instruction_run(pc_next: vaddr);
|
pub fn libafl_qemu_hook_instruction_run(pc_next: vaddr);
|
||||||
}
|
}
|
||||||
|
pub type libafl_rw_gen_cb = ::std::option::Option<
|
||||||
|
unsafe extern "C" fn(data: u64, pc: target_ulong, addr: *mut TCGTemp, oi: MemOpIdx) -> u64,
|
||||||
|
>;
|
||||||
|
pub type libafl_rw_exec_cb = ::std::option::Option<
|
||||||
|
unsafe extern "C" fn(data: u64, id: u64, pc: target_ulong, addr: target_ulong),
|
||||||
|
>;
|
||||||
|
pub type libafl_rw_execN_cb = ::std::option::Option<
|
||||||
|
unsafe extern "C" fn(data: u64, id: u64, pc: target_ulong, addr: target_ulong, size: usize),
|
||||||
|
>;
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Debug, Copy, Clone)]
|
#[derive(Debug, Copy, Clone)]
|
||||||
pub struct libafl_rw_hook {
|
pub struct libafl_rw_hook {
|
||||||
pub gen: ::std::option::Option<
|
pub gen: libafl_rw_gen_cb,
|
||||||
unsafe extern "C" fn(data: u64, pc: target_ulong, addr: *mut TCGTemp, oi: MemOpIdx) -> u64,
|
|
||||||
>,
|
|
||||||
pub data: u64,
|
pub data: u64,
|
||||||
pub num: usize,
|
pub num: usize,
|
||||||
pub helper_info1: TCGHelperInfo,
|
pub helper_info1: TCGHelperInfo,
|
||||||
@ -8132,48 +8141,30 @@ impl Default for libafl_rw_hook {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
unsafe extern "C" {
|
unsafe extern "C" {
|
||||||
pub fn libafl_gen_read(addr: *mut TCGTemp, oi: MemOpIdx);
|
pub fn libafl_gen_read(pc: *mut TCGTemp, addr: *mut TCGTemp, oi: MemOpIdx);
|
||||||
}
|
}
|
||||||
unsafe extern "C" {
|
unsafe extern "C" {
|
||||||
pub fn libafl_gen_write(addr: *mut TCGTemp, oi: MemOpIdx);
|
pub fn libafl_gen_write(pc: *mut TCGTemp, addr: *mut TCGTemp, oi: MemOpIdx);
|
||||||
}
|
}
|
||||||
unsafe extern "C" {
|
unsafe extern "C" {
|
||||||
pub fn libafl_add_read_hook(
|
pub fn libafl_add_read_hook(
|
||||||
gen: ::std::option::Option<
|
gen: libafl_rw_gen_cb,
|
||||||
unsafe extern "C" fn(
|
exec1: libafl_rw_exec_cb,
|
||||||
data: u64,
|
exec2: libafl_rw_exec_cb,
|
||||||
pc: target_ulong,
|
exec4: libafl_rw_exec_cb,
|
||||||
addr: *mut TCGTemp,
|
exec8: libafl_rw_exec_cb,
|
||||||
oi: MemOpIdx,
|
execN: libafl_rw_execN_cb,
|
||||||
) -> u64,
|
|
||||||
>,
|
|
||||||
exec1: ::std::option::Option<unsafe extern "C" fn(data: u64, id: u64, addr: target_ulong)>,
|
|
||||||
exec2: ::std::option::Option<unsafe extern "C" fn(data: u64, id: u64, addr: target_ulong)>,
|
|
||||||
exec4: ::std::option::Option<unsafe extern "C" fn(data: u64, id: u64, addr: target_ulong)>,
|
|
||||||
exec8: ::std::option::Option<unsafe extern "C" fn(data: u64, id: u64, addr: target_ulong)>,
|
|
||||||
execN: ::std::option::Option<
|
|
||||||
unsafe extern "C" fn(data: u64, id: u64, addr: target_ulong, size: usize),
|
|
||||||
>,
|
|
||||||
data: u64,
|
data: u64,
|
||||||
) -> usize;
|
) -> usize;
|
||||||
}
|
}
|
||||||
unsafe extern "C" {
|
unsafe extern "C" {
|
||||||
pub fn libafl_add_write_hook(
|
pub fn libafl_add_write_hook(
|
||||||
gen: ::std::option::Option<
|
gen: libafl_rw_gen_cb,
|
||||||
unsafe extern "C" fn(
|
exec1: libafl_rw_exec_cb,
|
||||||
data: u64,
|
exec2: libafl_rw_exec_cb,
|
||||||
pc: target_ulong,
|
exec4: libafl_rw_exec_cb,
|
||||||
addr: *mut TCGTemp,
|
exec8: libafl_rw_exec_cb,
|
||||||
oi: MemOpIdx,
|
execN: libafl_rw_execN_cb,
|
||||||
) -> u64,
|
|
||||||
>,
|
|
||||||
exec1: ::std::option::Option<unsafe extern "C" fn(data: u64, id: u64, addr: target_ulong)>,
|
|
||||||
exec2: ::std::option::Option<unsafe extern "C" fn(data: u64, id: u64, addr: target_ulong)>,
|
|
||||||
exec4: ::std::option::Option<unsafe extern "C" fn(data: u64, id: u64, addr: target_ulong)>,
|
|
||||||
exec8: ::std::option::Option<unsafe extern "C" fn(data: u64, id: u64, addr: target_ulong)>,
|
|
||||||
execN: ::std::option::Option<
|
|
||||||
unsafe extern "C" fn(data: u64, id: u64, addr: target_ulong, size: usize),
|
|
||||||
>,
|
|
||||||
data: u64,
|
data: u64,
|
||||||
) -> usize;
|
) -> usize;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* 1.85.0-nightly */
|
/* 1.86.0-nightly */
|
||||||
/* qemu git hash: 81e52dc60f83c3ae191c1a07b39bb255e633c234 */
|
/* qemu git hash: 3f7b2d86635aaf03818aaec1d285dba88255f831 */
|
||||||
/* automatically generated by rust-bindgen 0.71.1 */
|
/* automatically generated by rust-bindgen 0.71.1 */
|
||||||
|
|
||||||
pub const LIBAFL_SYNC_EXIT_OPCODE: u32 = 1727150607;
|
pub const LIBAFL_SYNC_EXIT_OPCODE: u32 = 1727150607;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* 1.85.0-nightly */
|
/* 1.86.0-nightly */
|
||||||
/* qemu git hash: 81e52dc60f83c3ae191c1a07b39bb255e633c234 */
|
/* qemu git hash: 3f7b2d86635aaf03818aaec1d285dba88255f831 */
|
||||||
/* automatically generated by rust-bindgen 0.71.1 */
|
/* automatically generated by rust-bindgen 0.71.1 */
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
@ -1078,33 +1078,35 @@ pub type intmax_t = __intmax_t;
|
|||||||
pub type uintmax_t = __uintmax_t;
|
pub type uintmax_t = __uintmax_t;
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
pub struct kAFL_payload {
|
pub struct _bindgen_ty_1 {
|
||||||
pub size: i32,
|
pub size: i32,
|
||||||
pub data: __IncompleteArrayField<u8>,
|
pub data: __IncompleteArrayField<u8>,
|
||||||
}
|
}
|
||||||
#[allow(clippy::unnecessary_operation, clippy::identity_op)]
|
#[allow(clippy::unnecessary_operation, clippy::identity_op)]
|
||||||
const _: () = {
|
const _: () = {
|
||||||
["Size of kAFL_payload"][::std::mem::size_of::<kAFL_payload>() - 4usize];
|
["Size of _bindgen_ty_1"][::std::mem::size_of::<_bindgen_ty_1>() - 4usize];
|
||||||
["Alignment of kAFL_payload"][::std::mem::align_of::<kAFL_payload>() - 4usize];
|
["Alignment of _bindgen_ty_1"][::std::mem::align_of::<_bindgen_ty_1>() - 4usize];
|
||||||
["Offset of field: kAFL_payload::size"][::std::mem::offset_of!(kAFL_payload, size) - 0usize];
|
["Offset of field: _bindgen_ty_1::size"][::std::mem::offset_of!(_bindgen_ty_1, size) - 0usize];
|
||||||
["Offset of field: kAFL_payload::data"][::std::mem::offset_of!(kAFL_payload, data) - 4usize];
|
["Offset of field: _bindgen_ty_1::data"][::std::mem::offset_of!(_bindgen_ty_1, data) - 4usize];
|
||||||
};
|
};
|
||||||
|
pub type kAFL_payload = _bindgen_ty_1;
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Debug, Default, Copy, Clone)]
|
#[derive(Debug, Default, Copy, Clone)]
|
||||||
pub struct kAFL_ranges {
|
pub struct _bindgen_ty_2 {
|
||||||
pub ip: [u64; 4usize],
|
pub ip: [u64; 4usize],
|
||||||
pub size: [u64; 4usize],
|
pub size: [u64; 4usize],
|
||||||
pub enabled: [u8; 4usize],
|
pub enabled: [u8; 4usize],
|
||||||
}
|
}
|
||||||
#[allow(clippy::unnecessary_operation, clippy::identity_op)]
|
#[allow(clippy::unnecessary_operation, clippy::identity_op)]
|
||||||
const _: () = {
|
const _: () = {
|
||||||
["Size of kAFL_ranges"][::std::mem::size_of::<kAFL_ranges>() - 72usize];
|
["Size of _bindgen_ty_2"][::std::mem::size_of::<_bindgen_ty_2>() - 72usize];
|
||||||
["Alignment of kAFL_ranges"][::std::mem::align_of::<kAFL_ranges>() - 8usize];
|
["Alignment of _bindgen_ty_2"][::std::mem::align_of::<_bindgen_ty_2>() - 8usize];
|
||||||
["Offset of field: kAFL_ranges::ip"][::std::mem::offset_of!(kAFL_ranges, ip) - 0usize];
|
["Offset of field: _bindgen_ty_2::ip"][::std::mem::offset_of!(_bindgen_ty_2, ip) - 0usize];
|
||||||
["Offset of field: kAFL_ranges::size"][::std::mem::offset_of!(kAFL_ranges, size) - 32usize];
|
["Offset of field: _bindgen_ty_2::size"][::std::mem::offset_of!(_bindgen_ty_2, size) - 32usize];
|
||||||
["Offset of field: kAFL_ranges::enabled"]
|
["Offset of field: _bindgen_ty_2::enabled"]
|
||||||
[::std::mem::offset_of!(kAFL_ranges, enabled) - 64usize];
|
[::std::mem::offset_of!(_bindgen_ty_2, enabled) - 64usize];
|
||||||
};
|
};
|
||||||
|
pub type kAFL_ranges = _bindgen_ty_2;
|
||||||
#[repr(C, packed)]
|
#[repr(C, packed)]
|
||||||
#[derive(Debug, Default, Copy, Clone)]
|
#[derive(Debug, Default, Copy, Clone)]
|
||||||
pub struct host_config_t {
|
pub struct host_config_t {
|
||||||
@ -1134,7 +1136,7 @@ const _: () = {
|
|||||||
};
|
};
|
||||||
#[repr(C, packed)]
|
#[repr(C, packed)]
|
||||||
#[derive(Debug, Default, Copy, Clone)]
|
#[derive(Debug, Default, Copy, Clone)]
|
||||||
pub struct agent_config_t {
|
pub struct _bindgen_ty_3 {
|
||||||
pub agent_magic: u32,
|
pub agent_magic: u32,
|
||||||
pub agent_version: u32,
|
pub agent_version: u32,
|
||||||
pub agent_timeout_detection: u8,
|
pub agent_timeout_detection: u8,
|
||||||
@ -1149,31 +1151,32 @@ pub struct agent_config_t {
|
|||||||
}
|
}
|
||||||
#[allow(clippy::unnecessary_operation, clippy::identity_op)]
|
#[allow(clippy::unnecessary_operation, clippy::identity_op)]
|
||||||
const _: () = {
|
const _: () = {
|
||||||
["Size of agent_config_t"][::std::mem::size_of::<agent_config_t>() - 37usize];
|
["Size of _bindgen_ty_3"][::std::mem::size_of::<_bindgen_ty_3>() - 37usize];
|
||||||
["Alignment of agent_config_t"][::std::mem::align_of::<agent_config_t>() - 1usize];
|
["Alignment of _bindgen_ty_3"][::std::mem::align_of::<_bindgen_ty_3>() - 1usize];
|
||||||
["Offset of field: agent_config_t::agent_magic"]
|
["Offset of field: _bindgen_ty_3::agent_magic"]
|
||||||
[::std::mem::offset_of!(agent_config_t, agent_magic) - 0usize];
|
[::std::mem::offset_of!(_bindgen_ty_3, agent_magic) - 0usize];
|
||||||
["Offset of field: agent_config_t::agent_version"]
|
["Offset of field: _bindgen_ty_3::agent_version"]
|
||||||
[::std::mem::offset_of!(agent_config_t, agent_version) - 4usize];
|
[::std::mem::offset_of!(_bindgen_ty_3, agent_version) - 4usize];
|
||||||
["Offset of field: agent_config_t::agent_timeout_detection"]
|
["Offset of field: _bindgen_ty_3::agent_timeout_detection"]
|
||||||
[::std::mem::offset_of!(agent_config_t, agent_timeout_detection) - 8usize];
|
[::std::mem::offset_of!(_bindgen_ty_3, agent_timeout_detection) - 8usize];
|
||||||
["Offset of field: agent_config_t::agent_tracing"]
|
["Offset of field: _bindgen_ty_3::agent_tracing"]
|
||||||
[::std::mem::offset_of!(agent_config_t, agent_tracing) - 9usize];
|
[::std::mem::offset_of!(_bindgen_ty_3, agent_tracing) - 9usize];
|
||||||
["Offset of field: agent_config_t::agent_ijon_tracing"]
|
["Offset of field: _bindgen_ty_3::agent_ijon_tracing"]
|
||||||
[::std::mem::offset_of!(agent_config_t, agent_ijon_tracing) - 10usize];
|
[::std::mem::offset_of!(_bindgen_ty_3, agent_ijon_tracing) - 10usize];
|
||||||
["Offset of field: agent_config_t::agent_non_reload_mode"]
|
["Offset of field: _bindgen_ty_3::agent_non_reload_mode"]
|
||||||
[::std::mem::offset_of!(agent_config_t, agent_non_reload_mode) - 11usize];
|
[::std::mem::offset_of!(_bindgen_ty_3, agent_non_reload_mode) - 11usize];
|
||||||
["Offset of field: agent_config_t::trace_buffer_vaddr"]
|
["Offset of field: _bindgen_ty_3::trace_buffer_vaddr"]
|
||||||
[::std::mem::offset_of!(agent_config_t, trace_buffer_vaddr) - 12usize];
|
[::std::mem::offset_of!(_bindgen_ty_3, trace_buffer_vaddr) - 12usize];
|
||||||
["Offset of field: agent_config_t::ijon_trace_buffer_vaddr"]
|
["Offset of field: _bindgen_ty_3::ijon_trace_buffer_vaddr"]
|
||||||
[::std::mem::offset_of!(agent_config_t, ijon_trace_buffer_vaddr) - 20usize];
|
[::std::mem::offset_of!(_bindgen_ty_3, ijon_trace_buffer_vaddr) - 20usize];
|
||||||
["Offset of field: agent_config_t::coverage_bitmap_size"]
|
["Offset of field: _bindgen_ty_3::coverage_bitmap_size"]
|
||||||
[::std::mem::offset_of!(agent_config_t, coverage_bitmap_size) - 28usize];
|
[::std::mem::offset_of!(_bindgen_ty_3, coverage_bitmap_size) - 28usize];
|
||||||
["Offset of field: agent_config_t::input_buffer_size"]
|
["Offset of field: _bindgen_ty_3::input_buffer_size"]
|
||||||
[::std::mem::offset_of!(agent_config_t, input_buffer_size) - 32usize];
|
[::std::mem::offset_of!(_bindgen_ty_3, input_buffer_size) - 32usize];
|
||||||
["Offset of field: agent_config_t::dump_payloads"]
|
["Offset of field: _bindgen_ty_3::dump_payloads"]
|
||||||
[::std::mem::offset_of!(agent_config_t, dump_payloads) - 36usize];
|
[::std::mem::offset_of!(_bindgen_ty_3, dump_payloads) - 36usize];
|
||||||
};
|
};
|
||||||
|
pub type agent_config_t = _bindgen_ty_3;
|
||||||
#[repr(C, packed)]
|
#[repr(C, packed)]
|
||||||
#[derive(Debug, Default, Copy, Clone)]
|
#[derive(Debug, Default, Copy, Clone)]
|
||||||
pub struct kafl_dump_file_t {
|
pub struct kafl_dump_file_t {
|
||||||
|
@ -455,22 +455,42 @@ where
|
|||||||
let exec1 = get_raw_hook!(
|
let exec1 = get_raw_hook!(
|
||||||
execution_hook_1,
|
execution_hook_1,
|
||||||
read_0_exec_hook_wrapper::<ET, I, S>,
|
read_0_exec_hook_wrapper::<ET, I, S>,
|
||||||
unsafe extern "C" fn(&mut TcgHookState<5, ReadHookId>, id: u64, addr: GuestAddr)
|
unsafe extern "C" fn(
|
||||||
|
&mut TcgHookState<5, ReadHookId>,
|
||||||
|
id: u64,
|
||||||
|
pc: GuestAddr,
|
||||||
|
addr: GuestAddr,
|
||||||
|
)
|
||||||
);
|
);
|
||||||
let exec2 = get_raw_hook!(
|
let exec2 = get_raw_hook!(
|
||||||
execution_hook_2,
|
execution_hook_2,
|
||||||
read_1_exec_hook_wrapper::<ET, I, S>,
|
read_1_exec_hook_wrapper::<ET, I, S>,
|
||||||
unsafe extern "C" fn(&mut TcgHookState<5, ReadHookId>, id: u64, addr: GuestAddr)
|
unsafe extern "C" fn(
|
||||||
|
&mut TcgHookState<5, ReadHookId>,
|
||||||
|
id: u64,
|
||||||
|
pc: GuestAddr,
|
||||||
|
addr: GuestAddr,
|
||||||
|
)
|
||||||
);
|
);
|
||||||
let exec4 = get_raw_hook!(
|
let exec4 = get_raw_hook!(
|
||||||
execution_hook_4,
|
execution_hook_4,
|
||||||
read_2_exec_hook_wrapper::<ET, I, S>,
|
read_2_exec_hook_wrapper::<ET, I, S>,
|
||||||
unsafe extern "C" fn(&mut TcgHookState<5, ReadHookId>, id: u64, addr: GuestAddr)
|
unsafe extern "C" fn(
|
||||||
|
&mut TcgHookState<5, ReadHookId>,
|
||||||
|
id: u64,
|
||||||
|
pc: GuestAddr,
|
||||||
|
addr: GuestAddr,
|
||||||
|
)
|
||||||
);
|
);
|
||||||
let exec8 = get_raw_hook!(
|
let exec8 = get_raw_hook!(
|
||||||
execution_hook_8,
|
execution_hook_8,
|
||||||
read_3_exec_hook_wrapper::<ET, I, S>,
|
read_3_exec_hook_wrapper::<ET, I, S>,
|
||||||
unsafe extern "C" fn(&mut TcgHookState<5, ReadHookId>, id: u64, addr: GuestAddr)
|
unsafe extern "C" fn(
|
||||||
|
&mut TcgHookState<5, ReadHookId>,
|
||||||
|
id: u64,
|
||||||
|
pc: GuestAddr,
|
||||||
|
addr: GuestAddr,
|
||||||
|
)
|
||||||
);
|
);
|
||||||
let execn = get_raw_hook!(
|
let execn = get_raw_hook!(
|
||||||
execution_hook_n,
|
execution_hook_n,
|
||||||
@ -478,6 +498,7 @@ where
|
|||||||
unsafe extern "C" fn(
|
unsafe extern "C" fn(
|
||||||
&mut TcgHookState<5, ReadHookId>,
|
&mut TcgHookState<5, ReadHookId>,
|
||||||
id: u64,
|
id: u64,
|
||||||
|
pc: GuestAddr,
|
||||||
addr: GuestAddr,
|
addr: GuestAddr,
|
||||||
size: usize,
|
size: usize,
|
||||||
)
|
)
|
||||||
@ -547,22 +568,42 @@ where
|
|||||||
let exec1 = get_raw_hook!(
|
let exec1 = get_raw_hook!(
|
||||||
execution_hook_1,
|
execution_hook_1,
|
||||||
write_0_exec_hook_wrapper::<ET, I, S>,
|
write_0_exec_hook_wrapper::<ET, I, S>,
|
||||||
unsafe extern "C" fn(&mut TcgHookState<5, WriteHookId>, id: u64, addr: GuestAddr)
|
unsafe extern "C" fn(
|
||||||
|
&mut TcgHookState<5, WriteHookId>,
|
||||||
|
id: u64,
|
||||||
|
pc: GuestAddr,
|
||||||
|
addr: GuestAddr,
|
||||||
|
)
|
||||||
);
|
);
|
||||||
let exec2 = get_raw_hook!(
|
let exec2 = get_raw_hook!(
|
||||||
execution_hook_2,
|
execution_hook_2,
|
||||||
write_1_exec_hook_wrapper::<ET, I, S>,
|
write_1_exec_hook_wrapper::<ET, I, S>,
|
||||||
unsafe extern "C" fn(&mut TcgHookState<5, WriteHookId>, id: u64, addr: GuestAddr)
|
unsafe extern "C" fn(
|
||||||
|
&mut TcgHookState<5, WriteHookId>,
|
||||||
|
id: u64,
|
||||||
|
pc: GuestAddr,
|
||||||
|
addr: GuestAddr,
|
||||||
|
)
|
||||||
);
|
);
|
||||||
let exec4 = get_raw_hook!(
|
let exec4 = get_raw_hook!(
|
||||||
execution_hook_4,
|
execution_hook_4,
|
||||||
write_2_exec_hook_wrapper::<ET, I, S>,
|
write_2_exec_hook_wrapper::<ET, I, S>,
|
||||||
unsafe extern "C" fn(&mut TcgHookState<5, WriteHookId>, id: u64, addr: GuestAddr)
|
unsafe extern "C" fn(
|
||||||
|
&mut TcgHookState<5, WriteHookId>,
|
||||||
|
id: u64,
|
||||||
|
pc: GuestAddr,
|
||||||
|
addr: GuestAddr,
|
||||||
|
)
|
||||||
);
|
);
|
||||||
let exec8 = get_raw_hook!(
|
let exec8 = get_raw_hook!(
|
||||||
execution_hook_8,
|
execution_hook_8,
|
||||||
write_3_exec_hook_wrapper::<ET, I, S>,
|
write_3_exec_hook_wrapper::<ET, I, S>,
|
||||||
unsafe extern "C" fn(&mut TcgHookState<5, WriteHookId>, id: u64, addr: GuestAddr)
|
unsafe extern "C" fn(
|
||||||
|
&mut TcgHookState<5, WriteHookId>,
|
||||||
|
id: u64,
|
||||||
|
pc: GuestAddr,
|
||||||
|
addr: GuestAddr,
|
||||||
|
)
|
||||||
);
|
);
|
||||||
let execn = get_raw_hook!(
|
let execn = get_raw_hook!(
|
||||||
execution_hook_n,
|
execution_hook_n,
|
||||||
@ -570,6 +611,7 @@ where
|
|||||||
unsafe extern "C" fn(
|
unsafe extern "C" fn(
|
||||||
&mut TcgHookState<5, WriteHookId>,
|
&mut TcgHookState<5, WriteHookId>,
|
||||||
id: u64,
|
id: u64,
|
||||||
|
pc: GuestAddr,
|
||||||
addr: GuestAddr,
|
addr: GuestAddr,
|
||||||
size: usize,
|
size: usize,
|
||||||
)
|
)
|
||||||
|
345
libafl_qemu/src/modules/logger.rs
Normal file
345
libafl_qemu/src/modules/logger.rs
Normal file
@ -0,0 +1,345 @@
|
|||||||
|
//! Logger Module
|
||||||
|
//!
|
||||||
|
//! It's a simple module logging selected events to the logger with the `info` level.
|
||||||
|
//! It must be built through [`LoggerModuleBuilder`].
|
||||||
|
|
||||||
|
use std::fmt::Debug;
|
||||||
|
|
||||||
|
use libafl_qemu_sys::TCGTemp;
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
modules::{
|
||||||
|
utils::filters::{AddressFilter, NopAddressFilter, NopPageFilter},
|
||||||
|
EmulatorModule, EmulatorModuleTuple,
|
||||||
|
},
|
||||||
|
qemu::Qemu,
|
||||||
|
EmulatorModules, GuestAddr, Hook, MemAccessInfo,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// A builder for [`LoggerModule`].
|
||||||
|
///
|
||||||
|
/// By default, no event is logged.
|
||||||
|
#[expect(clippy::struct_excessive_bools)]
|
||||||
|
pub struct LoggerModuleBuilder<AF, PF> {
|
||||||
|
calls: bool,
|
||||||
|
cmps: bool,
|
||||||
|
reads: bool,
|
||||||
|
writes: bool,
|
||||||
|
threads: bool,
|
||||||
|
syscalls: bool,
|
||||||
|
custom_insns: bool,
|
||||||
|
edges: bool,
|
||||||
|
blocks: bool,
|
||||||
|
instruction: Option<Vec<GuestAddr>>,
|
||||||
|
|
||||||
|
addr_filter: AF,
|
||||||
|
page_filter: PF,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for LoggerModuleBuilder<NopAddressFilter, NopPageFilter> {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
calls: false,
|
||||||
|
cmps: false,
|
||||||
|
reads: false,
|
||||||
|
writes: false,
|
||||||
|
threads: false,
|
||||||
|
syscalls: false,
|
||||||
|
custom_insns: false,
|
||||||
|
edges: false,
|
||||||
|
blocks: false,
|
||||||
|
instruction: None,
|
||||||
|
addr_filter: NopAddressFilter,
|
||||||
|
page_filter: NopPageFilter,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<AF, PF> LoggerModuleBuilder<AF, PF> {
|
||||||
|
#[must_use]
|
||||||
|
pub fn calls(mut self, calls: bool) -> Self {
|
||||||
|
self.calls = calls;
|
||||||
|
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
#[must_use]
|
||||||
|
pub fn cmps(mut self, cmps: bool) -> Self {
|
||||||
|
self.cmps = cmps;
|
||||||
|
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
#[must_use]
|
||||||
|
pub fn reads(mut self, reads: bool) -> Self {
|
||||||
|
self.reads = reads;
|
||||||
|
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
#[must_use]
|
||||||
|
pub fn writes(mut self, writes: bool) -> Self {
|
||||||
|
self.writes = writes;
|
||||||
|
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
#[must_use]
|
||||||
|
pub fn threads(mut self, threads: bool) -> Self {
|
||||||
|
self.threads = threads;
|
||||||
|
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
#[must_use]
|
||||||
|
pub fn syscalls(mut self, syscalls: bool) -> Self {
|
||||||
|
self.syscalls = syscalls;
|
||||||
|
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
#[must_use]
|
||||||
|
pub fn custom_insns(mut self, custom_insns: bool) -> Self {
|
||||||
|
self.custom_insns = custom_insns;
|
||||||
|
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
#[must_use]
|
||||||
|
pub fn edges(mut self, edges: bool) -> Self {
|
||||||
|
self.edges = edges;
|
||||||
|
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
#[must_use]
|
||||||
|
pub fn blocks(mut self, blocks: bool) -> Self {
|
||||||
|
self.blocks = blocks;
|
||||||
|
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
#[must_use]
|
||||||
|
pub fn instruction(mut self, instruction: GuestAddr) -> Self {
|
||||||
|
let instructions = if let Some(insns) = &mut self.instruction {
|
||||||
|
insns
|
||||||
|
} else {
|
||||||
|
self.instruction = Some(Vec::new());
|
||||||
|
|
||||||
|
self.instruction.as_mut().unwrap()
|
||||||
|
};
|
||||||
|
|
||||||
|
instructions.push(instruction);
|
||||||
|
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
#[must_use]
|
||||||
|
pub fn addr_filter<AF2>(self, addr_filter: AF2) -> LoggerModuleBuilder<AF2, PF> {
|
||||||
|
LoggerModuleBuilder {
|
||||||
|
calls: self.calls,
|
||||||
|
cmps: self.cmps,
|
||||||
|
reads: self.reads,
|
||||||
|
writes: self.writes,
|
||||||
|
threads: self.threads,
|
||||||
|
syscalls: self.syscalls,
|
||||||
|
custom_insns: self.custom_insns,
|
||||||
|
edges: self.edges,
|
||||||
|
blocks: self.blocks,
|
||||||
|
instruction: self.instruction,
|
||||||
|
addr_filter,
|
||||||
|
page_filter: self.page_filter,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[must_use]
|
||||||
|
pub fn page_filter<PF2>(self, page_filter: PF2) -> LoggerModuleBuilder<AF, PF2> {
|
||||||
|
LoggerModuleBuilder {
|
||||||
|
calls: self.calls,
|
||||||
|
cmps: self.cmps,
|
||||||
|
reads: self.reads,
|
||||||
|
writes: self.writes,
|
||||||
|
threads: self.threads,
|
||||||
|
syscalls: self.syscalls,
|
||||||
|
custom_insns: self.custom_insns,
|
||||||
|
edges: self.edges,
|
||||||
|
blocks: self.blocks,
|
||||||
|
instruction: self.instruction,
|
||||||
|
addr_filter: self.addr_filter,
|
||||||
|
page_filter,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[must_use]
|
||||||
|
pub fn build(self) -> LoggerModule<AF, PF> {
|
||||||
|
LoggerModule {
|
||||||
|
calls: self.calls,
|
||||||
|
cmps: self.cmps,
|
||||||
|
reads: self.reads,
|
||||||
|
writes: self.writes,
|
||||||
|
threads: self.threads,
|
||||||
|
syscalls: self.syscalls,
|
||||||
|
custom_insns: self.custom_insns,
|
||||||
|
edges: self.edges,
|
||||||
|
blocks: self.blocks,
|
||||||
|
instruction: self.instruction,
|
||||||
|
addr_filter: self.addr_filter,
|
||||||
|
page_filter: self.page_filter,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Module used to log events in QEMU.
|
||||||
|
/// It basically logs whatever goes through QEMU's hooks.
|
||||||
|
/// It can be configured through [`LoggerModuleBuilder`].
|
||||||
|
#[derive(Debug)]
|
||||||
|
#[expect(dead_code)]
|
||||||
|
#[expect(clippy::struct_excessive_bools)]
|
||||||
|
pub struct LoggerModule<AF, PF> {
|
||||||
|
calls: bool,
|
||||||
|
cmps: bool,
|
||||||
|
reads: bool,
|
||||||
|
writes: bool,
|
||||||
|
threads: bool,
|
||||||
|
syscalls: bool,
|
||||||
|
custom_insns: bool,
|
||||||
|
edges: bool,
|
||||||
|
blocks: bool,
|
||||||
|
instruction: Option<Vec<GuestAddr>>,
|
||||||
|
|
||||||
|
addr_filter: AF,
|
||||||
|
page_filter: PF,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LoggerModule<NopAddressFilter, NopPageFilter> {
|
||||||
|
#[must_use]
|
||||||
|
pub fn builder() -> LoggerModuleBuilder<NopAddressFilter, NopPageFilter> {
|
||||||
|
LoggerModuleBuilder::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[expect(clippy::unnecessary_wraps)]
|
||||||
|
fn gen_logger_rw<ET, I, S, const IS_WRITE: bool>(
|
||||||
|
_qemu: Qemu,
|
||||||
|
_emulator_modules: &mut EmulatorModules<ET, I, S>,
|
||||||
|
_state: Option<&mut S>,
|
||||||
|
pc: GuestAddr,
|
||||||
|
_addr: *mut TCGTemp,
|
||||||
|
info: MemAccessInfo,
|
||||||
|
) -> Option<u64>
|
||||||
|
where
|
||||||
|
ET: EmulatorModuleTuple<I, S>,
|
||||||
|
I: Unpin,
|
||||||
|
S: Unpin,
|
||||||
|
{
|
||||||
|
let kind = if IS_WRITE { "write" } else { "read" };
|
||||||
|
|
||||||
|
let size = info.size();
|
||||||
|
log::info!("[PC {pc:#x}] gen {kind} of {size} bytes");
|
||||||
|
|
||||||
|
Some(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn exec_logger_rw<ET, I, S, const IS_WRITE: bool, const N: usize>(
|
||||||
|
qemu: Qemu,
|
||||||
|
emulator_modules: &mut EmulatorModules<ET, I, S>,
|
||||||
|
state: Option<&mut S>,
|
||||||
|
id: u64,
|
||||||
|
pc: GuestAddr,
|
||||||
|
addr: GuestAddr,
|
||||||
|
) where
|
||||||
|
ET: EmulatorModuleTuple<I, S>,
|
||||||
|
I: Unpin,
|
||||||
|
S: Unpin,
|
||||||
|
{
|
||||||
|
exec_logger_rw_n::<ET, I, S, IS_WRITE>(qemu, emulator_modules, state, id, pc, addr, N);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn exec_logger_rw_n<ET, I, S, const IS_WRITE: bool>(
|
||||||
|
_qemu: Qemu,
|
||||||
|
_emulator_modules: &mut EmulatorModules<ET, I, S>,
|
||||||
|
_state: Option<&mut S>,
|
||||||
|
_id: u64,
|
||||||
|
pc: GuestAddr,
|
||||||
|
addr: GuestAddr,
|
||||||
|
size: usize,
|
||||||
|
) where
|
||||||
|
ET: EmulatorModuleTuple<I, S>,
|
||||||
|
I: Unpin,
|
||||||
|
S: Unpin,
|
||||||
|
{
|
||||||
|
let kind = if IS_WRITE { "write" } else { "read" };
|
||||||
|
|
||||||
|
log::info!("[PC {pc:#x}] exec {kind} of {size} bytes @addr {addr:#x}");
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<AF, I, PF, S> EmulatorModule<I, S> for LoggerModule<AF, PF>
|
||||||
|
where
|
||||||
|
AF: AddressFilter,
|
||||||
|
PF: Debug + 'static,
|
||||||
|
I: Unpin,
|
||||||
|
S: Unpin,
|
||||||
|
{
|
||||||
|
fn first_exec<ET>(
|
||||||
|
&mut self,
|
||||||
|
_qemu: Qemu,
|
||||||
|
emulator_modules: &mut EmulatorModules<ET, I, S>,
|
||||||
|
_state: &mut S,
|
||||||
|
) where
|
||||||
|
ET: EmulatorModuleTuple<I, S>,
|
||||||
|
{
|
||||||
|
if self.reads {
|
||||||
|
emulator_modules.reads(
|
||||||
|
Hook::Function(gen_logger_rw::<ET, I, S, false>),
|
||||||
|
Hook::Function(exec_logger_rw::<ET, I, S, false, 1>),
|
||||||
|
Hook::Function(exec_logger_rw::<ET, I, S, false, 2>),
|
||||||
|
Hook::Function(exec_logger_rw::<ET, I, S, false, 4>),
|
||||||
|
Hook::Function(exec_logger_rw::<ET, I, S, false, 8>),
|
||||||
|
Hook::Function(exec_logger_rw_n::<ET, I, S, false>),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.writes {
|
||||||
|
emulator_modules.writes(
|
||||||
|
Hook::Function(gen_logger_rw::<ET, I, S, true>),
|
||||||
|
Hook::Function(exec_logger_rw::<ET, I, S, true, 1>),
|
||||||
|
Hook::Function(exec_logger_rw::<ET, I, S, true, 2>),
|
||||||
|
Hook::Function(exec_logger_rw::<ET, I, S, true, 4>),
|
||||||
|
Hook::Function(exec_logger_rw::<ET, I, S, true, 8>),
|
||||||
|
Hook::Function(exec_logger_rw_n::<ET, I, S, true>),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.calls {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.blocks {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.cmps {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.custom_insns {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.edges {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.syscalls {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.threads {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.instruction.is_some() {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -44,6 +44,9 @@ pub mod drcov;
|
|||||||
#[cfg(not(cpu_target = "hexagon"))]
|
#[cfg(not(cpu_target = "hexagon"))]
|
||||||
pub use drcov::{DrCovMetadata, DrCovModule, DrCovModuleBuilder};
|
pub use drcov::{DrCovMetadata, DrCovModule, DrCovModuleBuilder};
|
||||||
|
|
||||||
|
pub mod logger;
|
||||||
|
pub use logger::LoggerModule;
|
||||||
|
|
||||||
pub mod utils;
|
pub mod utils;
|
||||||
|
|
||||||
/// [`EmulatorModule`] is a trait designed to define modules that interact with the QEMU emulator
|
/// [`EmulatorModule`] is a trait designed to define modules that interact with the QEMU emulator
|
||||||
|
@ -1008,6 +1008,7 @@ pub fn trace_read_asan<ET, I, S, const N: usize>(
|
|||||||
emulator_modules: &mut EmulatorModules<ET, I, S>,
|
emulator_modules: &mut EmulatorModules<ET, I, S>,
|
||||||
_state: Option<&mut S>,
|
_state: Option<&mut S>,
|
||||||
id: u64,
|
id: u64,
|
||||||
|
_pc: GuestAddr,
|
||||||
addr: GuestAddr,
|
addr: GuestAddr,
|
||||||
) where
|
) where
|
||||||
ET: EmulatorModuleTuple<I, S>,
|
ET: EmulatorModuleTuple<I, S>,
|
||||||
@ -1023,6 +1024,7 @@ pub fn trace_read_n_asan<ET, I, S>(
|
|||||||
emulator_modules: &mut EmulatorModules<ET, I, S>,
|
emulator_modules: &mut EmulatorModules<ET, I, S>,
|
||||||
_state: Option<&mut S>,
|
_state: Option<&mut S>,
|
||||||
id: u64,
|
id: u64,
|
||||||
|
_pc: GuestAddr,
|
||||||
addr: GuestAddr,
|
addr: GuestAddr,
|
||||||
size: usize,
|
size: usize,
|
||||||
) where
|
) where
|
||||||
@ -1039,6 +1041,7 @@ pub fn trace_write_asan<ET, I, S, const N: usize>(
|
|||||||
emulator_modules: &mut EmulatorModules<ET, I, S>,
|
emulator_modules: &mut EmulatorModules<ET, I, S>,
|
||||||
_state: Option<&mut S>,
|
_state: Option<&mut S>,
|
||||||
id: u64,
|
id: u64,
|
||||||
|
_pc: GuestAddr,
|
||||||
addr: GuestAddr,
|
addr: GuestAddr,
|
||||||
) where
|
) where
|
||||||
ET: EmulatorModuleTuple<I, S>,
|
ET: EmulatorModuleTuple<I, S>,
|
||||||
@ -1054,6 +1057,7 @@ pub fn trace_write_n_asan<ET, I, S>(
|
|||||||
emulator_modules: &mut EmulatorModules<ET, I, S>,
|
emulator_modules: &mut EmulatorModules<ET, I, S>,
|
||||||
_state: Option<&mut S>,
|
_state: Option<&mut S>,
|
||||||
id: u64,
|
id: u64,
|
||||||
|
_pc: GuestAddr,
|
||||||
addr: GuestAddr,
|
addr: GuestAddr,
|
||||||
size: usize,
|
size: usize,
|
||||||
) where
|
) where
|
||||||
@ -1091,6 +1095,7 @@ pub fn trace_write_asan_snapshot<ET, I, S, const N: usize>(
|
|||||||
emulator_modules: &mut EmulatorModules<ET, I, S>,
|
emulator_modules: &mut EmulatorModules<ET, I, S>,
|
||||||
_state: Option<&mut S>,
|
_state: Option<&mut S>,
|
||||||
id: u64,
|
id: u64,
|
||||||
|
_pc: GuestAddr,
|
||||||
addr: GuestAddr,
|
addr: GuestAddr,
|
||||||
) where
|
) where
|
||||||
ET: EmulatorModuleTuple<I, S>,
|
ET: EmulatorModuleTuple<I, S>,
|
||||||
@ -1110,6 +1115,7 @@ pub fn trace_write_n_asan_snapshot<ET, I, S>(
|
|||||||
emulator_modules: &mut EmulatorModules<ET, I, S>,
|
emulator_modules: &mut EmulatorModules<ET, I, S>,
|
||||||
_state: Option<&mut S>,
|
_state: Option<&mut S>,
|
||||||
id: u64,
|
id: u64,
|
||||||
|
_pc: GuestAddr,
|
||||||
addr: GuestAddr,
|
addr: GuestAddr,
|
||||||
size: usize,
|
size: usize,
|
||||||
) where
|
) where
|
||||||
|
@ -160,6 +160,7 @@ fn guest_trace_error_asan<ET, I, S>(
|
|||||||
_emulator_modules: &mut EmulatorModules<ET, I, S>,
|
_emulator_modules: &mut EmulatorModules<ET, I, S>,
|
||||||
_state: Option<&mut S>,
|
_state: Option<&mut S>,
|
||||||
_id: u64,
|
_id: u64,
|
||||||
|
_pc: GuestAddr,
|
||||||
_addr: GuestAddr,
|
_addr: GuestAddr,
|
||||||
) where
|
) where
|
||||||
ET: EmulatorModuleTuple<I, S>,
|
ET: EmulatorModuleTuple<I, S>,
|
||||||
@ -175,6 +176,7 @@ fn guest_trace_error_n_asan<ET, I, S>(
|
|||||||
_emulator_modules: &mut EmulatorModules<ET, I, S>,
|
_emulator_modules: &mut EmulatorModules<ET, I, S>,
|
||||||
_state: Option<&mut S>,
|
_state: Option<&mut S>,
|
||||||
_id: u64,
|
_id: u64,
|
||||||
|
_pc: GuestAddr,
|
||||||
_addr: GuestAddr,
|
_addr: GuestAddr,
|
||||||
_n: usize,
|
_n: usize,
|
||||||
) where
|
) where
|
||||||
|
@ -753,6 +753,7 @@ pub fn trace_write_snapshot<ET, I, S, const SIZE: usize>(
|
|||||||
emulator_modules: &mut EmulatorModules<ET, I, S>,
|
emulator_modules: &mut EmulatorModules<ET, I, S>,
|
||||||
_state: Option<&mut S>,
|
_state: Option<&mut S>,
|
||||||
_id: u64,
|
_id: u64,
|
||||||
|
_pc: GuestAddr,
|
||||||
addr: GuestAddr,
|
addr: GuestAddr,
|
||||||
) where
|
) where
|
||||||
ET: EmulatorModuleTuple<I, S>,
|
ET: EmulatorModuleTuple<I, S>,
|
||||||
@ -768,6 +769,7 @@ pub fn trace_write_n_snapshot<ET, I, S>(
|
|||||||
emulator_modules: &mut EmulatorModules<ET, I, S>,
|
emulator_modules: &mut EmulatorModules<ET, I, S>,
|
||||||
_state: Option<&mut S>,
|
_state: Option<&mut S>,
|
||||||
_id: u64,
|
_id: u64,
|
||||||
|
_pc: GuestAddr,
|
||||||
addr: GuestAddr,
|
addr: GuestAddr,
|
||||||
size: usize,
|
size: usize,
|
||||||
) where
|
) where
|
||||||
|
@ -731,7 +731,14 @@ create_hook_types!(
|
|||||||
);
|
);
|
||||||
create_hook_types!(
|
create_hook_types!(
|
||||||
ReadExec,
|
ReadExec,
|
||||||
fn(Qemu, &mut EmulatorModules<ET, I, S>, Option<&mut S>, id: u64, addr: GuestAddr),
|
fn(
|
||||||
|
Qemu,
|
||||||
|
&mut EmulatorModules<ET, I, S>,
|
||||||
|
Option<&mut S>,
|
||||||
|
id: u64,
|
||||||
|
pc: GuestAddr,
|
||||||
|
addr: GuestAddr,
|
||||||
|
),
|
||||||
Box<
|
Box<
|
||||||
dyn for<'a> FnMut(
|
dyn for<'a> FnMut(
|
||||||
Qemu,
|
Qemu,
|
||||||
@ -739,13 +746,22 @@ create_hook_types!(
|
|||||||
Option<&'a mut S>,
|
Option<&'a mut S>,
|
||||||
u64,
|
u64,
|
||||||
GuestAddr,
|
GuestAddr,
|
||||||
|
GuestAddr,
|
||||||
),
|
),
|
||||||
>,
|
>,
|
||||||
unsafe extern "C" fn(libafl_qemu_opaque: *const (), id: u64, addr: GuestAddr)
|
unsafe extern "C" fn(libafl_qemu_opaque: *const (), id: u64, pc: GuestAddr, addr: GuestAddr)
|
||||||
);
|
);
|
||||||
create_hook_types!(
|
create_hook_types!(
|
||||||
ReadExecN,
|
ReadExecN,
|
||||||
fn(Qemu, &mut EmulatorModules<ET, I, S>, Option<&mut S>, id: u64, addr: GuestAddr, size: usize),
|
fn(
|
||||||
|
Qemu,
|
||||||
|
&mut EmulatorModules<ET, I, S>,
|
||||||
|
Option<&mut S>,
|
||||||
|
id: u64,
|
||||||
|
pc: GuestAddr,
|
||||||
|
addr: GuestAddr,
|
||||||
|
size: usize,
|
||||||
|
),
|
||||||
Box<
|
Box<
|
||||||
dyn for<'a> FnMut(
|
dyn for<'a> FnMut(
|
||||||
Qemu,
|
Qemu,
|
||||||
@ -753,20 +769,27 @@ create_hook_types!(
|
|||||||
Option<&'a mut S>,
|
Option<&'a mut S>,
|
||||||
u64,
|
u64,
|
||||||
GuestAddr,
|
GuestAddr,
|
||||||
|
GuestAddr,
|
||||||
usize,
|
usize,
|
||||||
),
|
),
|
||||||
>,
|
>,
|
||||||
unsafe extern "C" fn(libafl_qemu_opaque: *const (), id: u64, addr: GuestAddr, size: usize)
|
unsafe extern "C" fn(
|
||||||
|
libafl_qemu_opaque: *const (),
|
||||||
|
id: u64,
|
||||||
|
pc: GuestAddr,
|
||||||
|
addr: GuestAddr,
|
||||||
|
size: usize,
|
||||||
|
)
|
||||||
);
|
);
|
||||||
create_hook_id!(Read, libafl_qemu_remove_read_hook, true);
|
create_hook_id!(Read, libafl_qemu_remove_read_hook, true);
|
||||||
create_gen_wrapper!(read, (pc: GuestAddr, addr: *mut TCGTemp, info: MemAccessInfo), u64, 5, ReadHookId);
|
create_gen_wrapper!(read, (pc: GuestAddr, addr: *mut TCGTemp, info: MemAccessInfo), u64, 5, ReadHookId);
|
||||||
create_exec_wrapper!(read, (id: u64, addr: GuestAddr), 0, 5, ReadHookId);
|
create_exec_wrapper!(read, (id: u64, pc: GuestAddr, addr: GuestAddr), 0, 5, ReadHookId);
|
||||||
create_exec_wrapper!(read, (id: u64, addr: GuestAddr), 1, 5, ReadHookId);
|
create_exec_wrapper!(read, (id: u64, pc: GuestAddr, addr: GuestAddr), 1, 5, ReadHookId);
|
||||||
create_exec_wrapper!(read, (id: u64, addr: GuestAddr), 2, 5, ReadHookId);
|
create_exec_wrapper!(read, (id: u64, pc: GuestAddr, addr: GuestAddr), 2, 5, ReadHookId);
|
||||||
create_exec_wrapper!(read, (id: u64, addr: GuestAddr), 3, 5, ReadHookId);
|
create_exec_wrapper!(read, (id: u64, pc: GuestAddr, addr: GuestAddr), 3, 5, ReadHookId);
|
||||||
create_exec_wrapper!(
|
create_exec_wrapper!(
|
||||||
read,
|
read,
|
||||||
(id: u64, addr: GuestAddr, size: usize),
|
(id: u64, addr: GuestAddr, pc: GuestAddr, size: usize),
|
||||||
4,
|
4,
|
||||||
5,
|
5,
|
||||||
ReadHookId
|
ReadHookId
|
||||||
@ -802,7 +825,14 @@ create_hook_types!(
|
|||||||
);
|
);
|
||||||
create_hook_types!(
|
create_hook_types!(
|
||||||
WriteExec,
|
WriteExec,
|
||||||
fn(Qemu, &mut EmulatorModules<ET, I, S>, Option<&mut S>, id: u64, addr: GuestAddr),
|
fn(
|
||||||
|
Qemu,
|
||||||
|
&mut EmulatorModules<ET, I, S>,
|
||||||
|
Option<&mut S>,
|
||||||
|
id: u64,
|
||||||
|
pc: GuestAddr,
|
||||||
|
addr: GuestAddr,
|
||||||
|
),
|
||||||
Box<
|
Box<
|
||||||
dyn for<'a> FnMut(
|
dyn for<'a> FnMut(
|
||||||
Qemu,
|
Qemu,
|
||||||
@ -810,13 +840,22 @@ create_hook_types!(
|
|||||||
Option<&'a mut S>,
|
Option<&'a mut S>,
|
||||||
u64,
|
u64,
|
||||||
GuestAddr,
|
GuestAddr,
|
||||||
|
GuestAddr,
|
||||||
),
|
),
|
||||||
>,
|
>,
|
||||||
unsafe extern "C" fn(libafl_qemu_opaque: *const (), id: u64, addr: GuestAddr)
|
unsafe extern "C" fn(libafl_qemu_opaque: *const (), id: u64, pc: GuestAddr, addr: GuestAddr)
|
||||||
);
|
);
|
||||||
create_hook_types!(
|
create_hook_types!(
|
||||||
WriteExecN,
|
WriteExecN,
|
||||||
fn(Qemu, &mut EmulatorModules<ET, I, S>, Option<&mut S>, id: u64, addr: GuestAddr, size: usize),
|
fn(
|
||||||
|
Qemu,
|
||||||
|
&mut EmulatorModules<ET, I, S>,
|
||||||
|
Option<&mut S>,
|
||||||
|
id: u64,
|
||||||
|
pc: GuestAddr,
|
||||||
|
addr: GuestAddr,
|
||||||
|
size: usize,
|
||||||
|
),
|
||||||
Box<
|
Box<
|
||||||
dyn for<'a> FnMut(
|
dyn for<'a> FnMut(
|
||||||
Qemu,
|
Qemu,
|
||||||
@ -824,20 +863,27 @@ create_hook_types!(
|
|||||||
Option<&'a mut S>,
|
Option<&'a mut S>,
|
||||||
u64,
|
u64,
|
||||||
GuestAddr,
|
GuestAddr,
|
||||||
|
GuestAddr,
|
||||||
usize,
|
usize,
|
||||||
),
|
),
|
||||||
>,
|
>,
|
||||||
unsafe extern "C" fn(libafl_qemu_opaque: *const (), id: u64, addr: GuestAddr, size: usize)
|
unsafe extern "C" fn(
|
||||||
|
libafl_qemu_opaque: *const (),
|
||||||
|
id: u64,
|
||||||
|
pc: GuestAddr,
|
||||||
|
addr: GuestAddr,
|
||||||
|
size: usize,
|
||||||
|
)
|
||||||
);
|
);
|
||||||
create_hook_id!(Write, libafl_qemu_remove_write_hook, true);
|
create_hook_id!(Write, libafl_qemu_remove_write_hook, true);
|
||||||
create_gen_wrapper!(write, (pc: GuestAddr, addr: *mut TCGTemp, info: MemAccessInfo), u64, 5, WriteHookId);
|
create_gen_wrapper!(write, (pc: GuestAddr, addr: *mut TCGTemp, info: MemAccessInfo), u64, 5, WriteHookId);
|
||||||
create_exec_wrapper!(write, (id: u64, addr: GuestAddr), 0, 5, WriteHookId);
|
create_exec_wrapper!(write, (id: u64, pc: GuestAddr, addr: GuestAddr), 0, 5, WriteHookId);
|
||||||
create_exec_wrapper!(write, (id: u64, addr: GuestAddr), 1, 5, WriteHookId);
|
create_exec_wrapper!(write, (id: u64, pc: GuestAddr, addr: GuestAddr), 1, 5, WriteHookId);
|
||||||
create_exec_wrapper!(write, (id: u64, addr: GuestAddr), 2, 5, WriteHookId);
|
create_exec_wrapper!(write, (id: u64, pc: GuestAddr, addr: GuestAddr), 2, 5, WriteHookId);
|
||||||
create_exec_wrapper!(write, (id: u64, addr: GuestAddr), 3, 5, WriteHookId);
|
create_exec_wrapper!(write, (id: u64, pc: GuestAddr, addr: GuestAddr), 3, 5, WriteHookId);
|
||||||
create_exec_wrapper!(
|
create_exec_wrapper!(
|
||||||
write,
|
write,
|
||||||
(id: u64, addr: GuestAddr, size: usize),
|
(id: u64, pc: GuestAddr, addr: GuestAddr, size: usize),
|
||||||
4,
|
4,
|
||||||
5,
|
5,
|
||||||
WriteHookId
|
WriteHookId
|
||||||
@ -1004,11 +1050,11 @@ impl QemuHooks {
|
|||||||
&self,
|
&self,
|
||||||
data: T,
|
data: T,
|
||||||
gen: Option<unsafe extern "C" fn(T, GuestAddr, *mut TCGTemp, MemAccessInfo) -> u64>,
|
gen: Option<unsafe extern "C" fn(T, GuestAddr, *mut TCGTemp, MemAccessInfo) -> u64>,
|
||||||
exec1: Option<unsafe extern "C" fn(T, u64, GuestAddr)>,
|
exec1: Option<unsafe extern "C" fn(T, u64, GuestAddr, GuestAddr)>,
|
||||||
exec2: Option<unsafe extern "C" fn(T, u64, GuestAddr)>,
|
exec2: Option<unsafe extern "C" fn(T, u64, GuestAddr, GuestAddr)>,
|
||||||
exec4: Option<unsafe extern "C" fn(T, u64, GuestAddr)>,
|
exec4: Option<unsafe extern "C" fn(T, u64, GuestAddr, GuestAddr)>,
|
||||||
exec8: Option<unsafe extern "C" fn(T, u64, GuestAddr)>,
|
exec8: Option<unsafe extern "C" fn(T, u64, GuestAddr, GuestAddr)>,
|
||||||
exec_n: Option<unsafe extern "C" fn(T, u64, GuestAddr, usize)>,
|
exec_n: Option<unsafe extern "C" fn(T, u64, GuestAddr, GuestAddr, usize)>,
|
||||||
) -> ReadHookId {
|
) -> ReadHookId {
|
||||||
unsafe {
|
unsafe {
|
||||||
let data: u64 = data.into().0;
|
let data: u64 = data.into().0;
|
||||||
@ -1020,11 +1066,15 @@ impl QemuHooks {
|
|||||||
libafl_qemu_sys::MemOpIdx,
|
libafl_qemu_sys::MemOpIdx,
|
||||||
) -> u64,
|
) -> u64,
|
||||||
> = transmute(gen);
|
> = transmute(gen);
|
||||||
let exec1: Option<unsafe extern "C" fn(u64, u64, GuestAddr)> = transmute(exec1);
|
let exec1: Option<unsafe extern "C" fn(u64, u64, GuestAddr, GuestAddr)> =
|
||||||
let exec2: Option<unsafe extern "C" fn(u64, u64, GuestAddr)> = transmute(exec2);
|
transmute(exec1);
|
||||||
let exec4: Option<unsafe extern "C" fn(u64, u64, GuestAddr)> = transmute(exec4);
|
let exec2: Option<unsafe extern "C" fn(u64, u64, GuestAddr, GuestAddr)> =
|
||||||
let exec8: Option<unsafe extern "C" fn(u64, u64, GuestAddr)> = transmute(exec8);
|
transmute(exec2);
|
||||||
let exec_n: Option<unsafe extern "C" fn(u64, u64, GuestAddr, usize)> =
|
let exec4: Option<unsafe extern "C" fn(u64, u64, GuestAddr, GuestAddr)> =
|
||||||
|
transmute(exec4);
|
||||||
|
let exec8: Option<unsafe extern "C" fn(u64, u64, GuestAddr, GuestAddr)> =
|
||||||
|
transmute(exec8);
|
||||||
|
let exec_n: Option<unsafe extern "C" fn(u64, u64, GuestAddr, GuestAddr, usize)> =
|
||||||
transmute(exec_n);
|
transmute(exec_n);
|
||||||
let num = libafl_qemu_sys::libafl_add_read_hook(
|
let num = libafl_qemu_sys::libafl_add_read_hook(
|
||||||
gen, exec1, exec2, exec4, exec8, exec_n, data,
|
gen, exec1, exec2, exec4, exec8, exec_n, data,
|
||||||
@ -1038,11 +1088,11 @@ impl QemuHooks {
|
|||||||
&self,
|
&self,
|
||||||
data: T,
|
data: T,
|
||||||
gen: Option<unsafe extern "C" fn(T, GuestAddr, *mut TCGTemp, MemAccessInfo) -> u64>,
|
gen: Option<unsafe extern "C" fn(T, GuestAddr, *mut TCGTemp, MemAccessInfo) -> u64>,
|
||||||
exec1: Option<unsafe extern "C" fn(T, u64, GuestAddr)>,
|
exec1: Option<unsafe extern "C" fn(T, u64, GuestAddr, GuestAddr)>,
|
||||||
exec2: Option<unsafe extern "C" fn(T, u64, GuestAddr)>,
|
exec2: Option<unsafe extern "C" fn(T, u64, GuestAddr, GuestAddr)>,
|
||||||
exec4: Option<unsafe extern "C" fn(T, u64, GuestAddr)>,
|
exec4: Option<unsafe extern "C" fn(T, u64, GuestAddr, GuestAddr)>,
|
||||||
exec8: Option<unsafe extern "C" fn(T, u64, GuestAddr)>,
|
exec8: Option<unsafe extern "C" fn(T, u64, GuestAddr, GuestAddr)>,
|
||||||
exec_n: Option<unsafe extern "C" fn(T, u64, GuestAddr, usize)>,
|
exec_n: Option<unsafe extern "C" fn(T, u64, GuestAddr, GuestAddr, usize)>,
|
||||||
) -> WriteHookId {
|
) -> WriteHookId {
|
||||||
unsafe {
|
unsafe {
|
||||||
let data: u64 = data.into().0;
|
let data: u64 = data.into().0;
|
||||||
@ -1054,11 +1104,15 @@ impl QemuHooks {
|
|||||||
libafl_qemu_sys::MemOpIdx,
|
libafl_qemu_sys::MemOpIdx,
|
||||||
) -> u64,
|
) -> u64,
|
||||||
> = transmute(gen);
|
> = transmute(gen);
|
||||||
let exec1: Option<unsafe extern "C" fn(u64, u64, GuestAddr)> = transmute(exec1);
|
let exec1: Option<unsafe extern "C" fn(u64, u64, GuestAddr, GuestAddr)> =
|
||||||
let exec2: Option<unsafe extern "C" fn(u64, u64, GuestAddr)> = transmute(exec2);
|
transmute(exec1);
|
||||||
let exec4: Option<unsafe extern "C" fn(u64, u64, GuestAddr)> = transmute(exec4);
|
let exec2: Option<unsafe extern "C" fn(u64, u64, GuestAddr, GuestAddr)> =
|
||||||
let exec8: Option<unsafe extern "C" fn(u64, u64, GuestAddr)> = transmute(exec8);
|
transmute(exec2);
|
||||||
let exec_n: Option<unsafe extern "C" fn(u64, u64, GuestAddr, usize)> =
|
let exec4: Option<unsafe extern "C" fn(u64, u64, GuestAddr, GuestAddr)> =
|
||||||
|
transmute(exec4);
|
||||||
|
let exec8: Option<unsafe extern "C" fn(u64, u64, GuestAddr, GuestAddr)> =
|
||||||
|
transmute(exec8);
|
||||||
|
let exec_n: Option<unsafe extern "C" fn(u64, u64, GuestAddr, GuestAddr, usize)> =
|
||||||
transmute(exec_n);
|
transmute(exec_n);
|
||||||
let num = libafl_qemu_sys::libafl_add_write_hook(
|
let num = libafl_qemu_sys::libafl_add_write_hook(
|
||||||
gen, exec1, exec2, exec4, exec8, exec_n, data,
|
gen, exec1, exec2, exec4, exec8, exec_n, data,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user