From ed228147a043978c0f35570ca39dada89374a7fb Mon Sep 17 00:00:00 2001 From: Andrea Fioraldi Date: Mon, 27 Sep 2021 14:48:44 +0200 Subject: [PATCH] Python QEMU example fuzzer --- fuzzers/python_qemu/fuzz.c | 16 ++++++++++++ fuzzers/python_qemu/fuzzer.py | 48 +++++++++++++++++++++++++++++++++++ libafl_qemu/src/lib.rs | 3 +-- 3 files changed, 65 insertions(+), 2 deletions(-) create mode 100644 fuzzers/python_qemu/fuzz.c create mode 100644 fuzzers/python_qemu/fuzzer.py diff --git a/fuzzers/python_qemu/fuzz.c b/fuzzers/python_qemu/fuzz.c new file mode 100644 index 0000000000..70afd693f1 --- /dev/null +++ b/fuzzers/python_qemu/fuzz.c @@ -0,0 +1,16 @@ +#include +#include +#include + +int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { + // printf("Got %ld bytes.\n", Size); + if (Size >= 4 && *(uint32_t*)Data == 0xaabbccdd) + abort(); +} + +int main() { + + char buf [10] = {0}; + LLVMFuzzerTestOneInput(buf, 10); + +} diff --git a/fuzzers/python_qemu/fuzzer.py b/fuzzers/python_qemu/fuzzer.py new file mode 100644 index 0000000000..1044f4a522 --- /dev/null +++ b/fuzzers/python_qemu/fuzzer.py @@ -0,0 +1,48 @@ +# from the maturin venv, after running 'maturin develop' in the pylibafl directory + +from pylibafl import sugar, qemu +import lief + +RSI = 4 +RDI = 5 +RSP = 7 +RIP = 8 + +BINARY_PATH = './a.out' + +qemu.init(['qemu-x86_64', BINARY_PATH], []) + +elf = lief.parse(BINARY_PATH) +test_one_input = elf.get_function_address("LLVMFuzzerTestOneInput") +if elf.is_pie: + test_one_input += qemu.load_addr() +print('LLVMFuzzerTestOneInput @ 0x%x' % test_one_input) + +qemu.set_breakpoint(test_one_input) +qemu.run() + +buf = qemu.read_reg(RDI) +size = qemu.read_reg(RSI) +sp = qemu.read_reg(RSP) +print('buf = 0x%x' % buf) +print('size = 0x%x' % size) +print('SP = 0x%x' % sp) + +retaddr = int.from_bytes(qemu.read_mem(sp, 8), 'little') +print('RET = 0x%x' % retaddr) + +qemu.remove_breakpoint(test_one_input) +qemu.set_breakpoint(retaddr) + +def harness(b): + if len(b) > size: + b = b[:size] + qemu.write_mem(buf, b) + qemu.write_reg(RSI, size) + qemu.write_reg(RDI, buf) + qemu.write_reg(RSP, sp) + qemu.write_reg(RIP, test_one_input) + qemu.run() + +fuzz = sugar.QemuBytesCoverageSugar(['./in'], './out', 3456, [0,1,2,3]) +fuzz.run(harness) diff --git a/libafl_qemu/src/lib.rs b/libafl_qemu/src/lib.rs index 29012a83f2..9fbeb8e554 100644 --- a/libafl_qemu/src/lib.rs +++ b/libafl_qemu/src/lib.rs @@ -55,8 +55,7 @@ pub fn python_module(_py: Python, m: &PyModule) -> PyResult<()> { } #[pyfn(m)] fn read_mem(addr: u64, size: usize) -> Vec { - let mut buf = vec![]; - unsafe { buf.set_len(size) }; + let mut buf = vec![0; size]; emu::read_mem(addr, &mut buf); buf }