Closed thenickdude closed 6 years ago
Hey! Just so this doesn't look ignored: we're super psyched for this change (thank you), but haven't had a chance to make sure that everything still works. Once we get a chance, this will be merged in post-haste.
I performed some tests to make sure it works fine. In the following you can see the results of the experiments:
In order to perform experiments I have cross-compiled test_instr.c which is the basic test-case of the afl-fuzz itself for the following archs:
aarch64 alpha arm armeb cris i386 m68k microblaze microblazeel
mips mips64 mips64el mipsel mipsn32 mipsn32el or32 ppc ppc64
ppc64abi32 ppc64le s390x sh4 sh4eb sparc sparc32plus sparc64 unicore32
x86_64
Also, I made sure that qemu has been successfully patched for each of the aforementioned archs by running each of the test cases in qemu user-mode emulation. One simple output is the following:
(angr) angr@2d6b6bc66e9f:~/.virtualenvs/angr/bin/afl-cgc$ file testcases/test-instr_powerpc
testcases/test-instr_powerpc: ELF 32-bit MSB executable, PowerPC or cisco 4500, version 1 (SYSV), statically linked, for GNU/Linux 3.2.0, BuildID[sha1]=e64879a027fff02788af1daefd13de9731a30493, not stripped
(angr) angr@2d6b6bc66e9f:~/.virtualenvs/angr/bin/afl-cgc$ echo 0 | qemu-ppc testcases/test-instr_powerpc
Looks like a zero to me!
Now when I try to fuzz it inside afl-fuzz, I ended up with this error...
(angr) angr@2d6b6bc66e9f:~/.virtualenvs/angr/bin/afl-cgc$ AFL_SKIP_BIN_CHECK=1 AFL_NO_FORKSRV=1 ./afl-fuzz -Q -m none -i inputs/ -o outputs testcases/test-instr_powerpc @@
error:
[-] PROGRAM ABORT : No instrumentation detected
Location : perform_dry_run(), afl-fuzz.c:2655
For getting more information around the issue, this is the afl-showmap output:
(angr) angr@2d6b6bc66e9f:~/.virtualenvs/angr/bin/afl-cgc$ echo 0 |AFL_NO_FORKSRV=1 AFL_SKIP_BIN_CHECK=1 ./afl-showmap -Q -m none -o /dev/null testcases/test-instr_powerpc
error:
-- Program output begins --
testcases/test-instr_powerpc: Invalid ELF image for this architecture
-- Program output ends --
The only test cases that has been passed so far was the mips arch binary:
(angr) angr@2d6b6bc66e9f:~/.virtualenvs/angr/bin/afl-cgc$ echo 0 |AFL_NO_FORKSRV=1 AFL_SKIP_BIN_CHECK=1 ./afl-showmap -Q -m none -o /dev/null testcases/test-instr_mips
output:
-- Program output begins --
Looks like a zero to me!
-- Program output ends --
[+] Captured 667 tuples in '/dev/null'.
After a bit of wasting time with error, I found that if we set AFL_PATH to point to an appropriate version of afl-qemu-trace that nasty error would be fixed. Furthermore, the corresponding code in any afl-XXX.c that handles the qemu argv is located in the following lines:
In the following you can use this bash script to solve it temporary. Before, running any analysis send your binary to this script and then use any afl-XXX, it'll automatically detect binary and set proper afl-qemu-tracer.
#!/bin/sh
if [ ! $# -eq 1 ]; then
echo "usage: $0 <binary>" >&2
exit 1
fi
echo
echo "====================================================="
echo "Setting AFL_PATH to the corresponding afl-qemu-tracer"
echo "====================================================="
echo
binary="$(pwd)/$1"
AFL_PATH="$(pwd)/tracers/"
setpath="export AFL_PATH=$AFL_PATH"
if [ ! -f $binary ]; then
echo "[-] Error: $(basename $binary) not found."
exit 1
fi
command=$(readelf -h $binary | grep -i machine | sed "s/^.*://" | tr -d "[:space:]")
arch=$(readelf -h $binary | grep -i "class\|machine" | sed "s/^.*://" | tr -d "[ /t]" | tr "\n" ":" | cut -d":" -f 1)
case $command in
"PowerPC"*)
if [ "$arch" = "ELF32" ]; then
AFL_PATH="${AFL_PATH}ppc"
else
AFL_PATH="${AFL_PATH}ppc64"
fi
$($setpath) || exit 1
echo "[+] AFL_PATH=$AFL_PATH"
;;
"AArch64")
AFL_PATH="${AFL_PATH}aarch64"
$($setpath) || exit 1
echo "[+] AFL_PATH=$AFL_PATH"
;;
"ARM")
AFL_PATH="${AFL_PATH}arm"
$($setpath) || exit 1
echo "[+] AFL_PATH=$AFL_PATH"
;;
*"390"*)
AFL_PATH="${AFL_PATH}s390x"
$($setpath) || exit 1
echo "[+] AFL_PATH=$AFL_PATH"
;;
*"SuperHSH"*)
AFL_PATH="${AFL_PATH}sh4"
$($setpath) || exit 1
echo "[+] AFL_PATH=$AFL_PATH"
;;
*"Sparc"*)
if [ "$arch" = "ELF32" ]; then
AFL_PATH="${AFL_PATH}sparc"
else
AFL_PATH="${AFL_PATH}sparc64"
fi
$($setpath) || exit 1
echo "[+] AFL_PATH=$AFL_PATH"
;;
*"X86-64"*)
AFL_PATH="${AFL_PATH}x86_64"
$($setpath) || exit 1
echo "[+] AFL_PATH=$AFL_PATH"
;;
*"MIPS"*)
if [ "$arch" = "ELF32" ]; then
AFL_PATH="${AFL_PATH}mips"
else
AFL_PATH="${AFL_PATH}mips64"
fi
$($setpath) || exit 1
echo "[+] AFL_PATH=$AFL_PATH"
;;
"Alpha")
AFL_PATH="${AFL_PATH}alpha"
$($setpath) || exit 1
echo "[+] AFL_PATH=$AFL_PATH"
;;
*)
echo "[-] Unfortunately it's not supported for $command"
esac
echo
Most of the test cases has been passed right now, but one of them failed:
Test:
for i in testcases/arch/*; do if [ ! -f $i ]; then continue; fi; . ./setpath.sh $i || exit 1 ; echo 0 | AFL_PATH=$AFL_PATH AFL_NO_FORKSRV=1 AFL_SKIP_BIN_CHECK=1 ./afl-showmap -Q -m none -o /dev/null $i ; done
Results:
=====================================================
Setting AFL_PATH to the corresponding afl-qemu-tracer
=====================================================
[+] AFL_PATH=/home/angr/angr-dev/afl-other-arch/tracers/ppc64
-- Program output begins --
Looks like a zero to me!
-- Program output ends --
[-] PROGRAM ABORT : No instrumentation detected
Location : main(), afl-showmap.c:767
Sorry about the delay, @thenickdude. We finally merged it :-)
Thank you!!
Rebased on AFL 2.51b (fixes AFL crashes I was having where fork failed)