This adds a new persistent hook library `mipsel_read_into_a0.c`. With it, you can test the persistent hook on the *mipsel* architecture. I'm also updating the README in `utils/qemu_persistent_hook` and Makefile and explain how to test the persistent hook on *mipsel*. This all works thanks to qemuafl already having the correct CPU struct for *mipsel* in `qemuafl/api.h`. This patch also updates the root `.gitignore` file to ignore the two test binaries `test` and `mipsel_test`.
QEMU persistent hook example
Compile the test binary and the library:
make
Fuzz with:
export AFL_QEMU_PERSISTENT_ADDR=0x$(nm test | grep "T target_func" | awk '{print $1}')
export AFL_QEMU_PERSISTENT_HOOK=./read_into_rdi.so
mkdir in
echo 0000 > in/in
../../afl-fuzz -Q -i in -o out -- ./test
Example for mipsel architecture
Compile QEMU with mipsel
support by running the following:
# From root directory
cd qemu_mode && CPU_TARGET=mipsel ./build_qemu_support.sh
To compile binaries for mipsel
, you need a GCC cross-compiler for
the target architecture.
How to build a GCC cross-compiler is out of scope for this document, but you
may find this
OSDev Wiki Tutorial helpful.
If you are using Nix, you may find
this tutorial useful.
The next step assumes that you have a GCC cross-compiler for mipsel
available
under mipsel-gnu-linux-cc
. Verify that qemu_mode
works properly by running
test/test-qemu-mode.sh
:
# From root directory
cd test
CPU_TARGET_CC=mipsel-linux-gnu-cc CPU_TARGET=mipsel ./test-qemu-mode.sh
The output should look something like this:
[*] Using environment variable CPU_TARGET=mipsel for SYS
[*] starting AFL++ test framework ...
[*] Testing: qemu_mode
[*] Using mipsel-linux-gnu-cc as compiler for target
[*] running afl-fuzz for qemu_mode, this will take approx 10 seconds
[+] afl-fuzz is working correctly with qemu_mode
[*] running afl-fuzz for qemu_mode AFL_ENTRYPOINT, this will take approx 6 seconds
[+] afl-fuzz is working correctly with qemu_mode AFL_ENTRYPOINT
[-] not an intel or arm platform, cannot test qemu_mode compcov
[-] not an intel or arm platform, cannot test qemu_mode cmplog
[*] running afl-fuzz for persistent qemu_mode, this will take approx 10 seconds
[+] afl-fuzz is working correctly with persistent qemu_mode
[+] persistent qemu_mode was noticeable faster than standard qemu_mode
[*] running afl-fuzz for persistent qemu_mode with AFL_QEMU_PERSISTENT_EXITS, this will take approx 10 seconds
[+] afl-fuzz is working correctly with persistent qemu_mode and AFL_QEMU_PERSISTENT_EXITS
[+] persistent qemu_mode with AFL_QEMU_PERSISTENT_EXITS was noticeable faster than standard qemu_mode
[-] we cannot test qemu_mode unsigaction library (32 bit) because it is not present
[+] qemu_mode unsigaction library (64 bit) ignores signals
[*] 1 test cases completed.
[-] not all test cases were executed
[+] all tests were successful :-)
Then, compile the test binary and library for mipsel
using the following
make
command:
CPU_TARGET_CC=mipsel-linux-gnu-cc make all_mipsel
Make sure that the test binary and library have the correct format. When you
run file
on the two output files, you should see something like the
following:
$ file mipsel_read_into_a0.so mipsel_test
mipsel_read_into_a0.so: ELF 32-bit LSB shared object, MIPS, MIPS32 rel2 version 1 (SYSV), dynamically linked, not stripped
mipsel_test: ELF 32-bit LSB executable, MIPS, MIPS32 rel2 version 1 (SYSV), dynamically linked, interpreter /nix/store/837z8p51k37n0s1l3hlawx6inc60cq9d-uclibc-ng-mipsel-linux-gnu-1.0.50/lib/ld64-uClibc.so.1, not stripped
Then, like in the previous section, prepare the fuzzing environment:
export AFL_QEMU_PERSISTENT_ADDR=0x$(nm mipsel_test | grep "T target_func" | awk '{print $1}')
export AFL_QEMU_PERSISTENT_HOOK=./mipsel_read_into_a0.so
mkdir in
echo 0000 > in/in
# Set the following environment variables to avoid having to adjust
# kernel settings:
export AFL_SKIP_CPUFREQ=1
export AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES=1
Run the fuzzer using the following command:
../../afl-fuzz -V10 -Q -i in -o out -- ./mipsel_test
If you run the fuzzer with export AFL_DEBUG=1
, you should see the following
repeating output:
...
Placing input into 0x410950
buffer:0x410950, size:1
Placing input into 0x410950
buffer:0x410950, size:1
Placing input into 0x410950
buffer:0x410950, size:185
Placing input into 0x410950
buffer:0x410950, size:5
Placing input into 0x410950
buffer:0x410950, size:113
Placing input into 0x410950
buffer:0x410950, size:28
Placing input into 0x410950
buffer:0x410950, size:78
Placing input into 0x410950
buffer:0x410950, size:2
...