talos-vulndev / afl-dyninst Goto Github PK
View Code? Open in Web Editor NEWAmerican Fuzzy Lop + Dyninst == AFL Fuzzing blackbox binaries
License: Apache License 2.0
American Fuzzy Lop + Dyninst == AFL Fuzzing blackbox binaries
License: Apache License 2.0
American Fuzzy Lop + Dyninst == AFL Fuzzing blackbox binaries The tool has two parts. The instrumentation tool and the instrumentation library. Instrumentation library has an initialization callback and basic block callback functions which are designed to emulate what AFL is doing with afl-gcc/afl-g++/afl-as. Instrumentation tool (afl-dyninst) instruments the supplied binary by inserting callbacks for each basic block and an initialization callback either at _init or at specified entry point. Commandline options ------------------- Usage: ./afl-dyninst-dfvD -i <binary> -o <binary> -l <library> -e <address> -E <address> -s <number> -S <funcname> -m <size> -i: input binary -o: output binary -d: do not instrument the binary, only supplied libraries -l: linked library to instrument (repeat for more than one) -r: runtime library to instrument (path to, repeat for more than one) -e: entry point address to patch (required for stripped binaries) -E: exit point - force exit(0) at this address (repeat for more than one) -s: number of initial basic blocks to skip in binary -m: minimum size of a basic bock to instrument (default: 1) -f: try to fix a dyninst bug that leads to crashes -S: do not instrument this function (repeat for more than one) -D: instrument fork server and forced exit functions but no basic blocks -v: verbose output Switch -l is used to supply the names of the libraries that should be instrumented along the binary. Instrumented libraries will be copied to the current working directory. This option can be repeated as many times as needed. Depending on the environment, the LD_LIBRARY_PATH should be set to point to instrumented libraries while fuzzing. Switch -e is used to manualy specify the entry point where initialization callback is to be inserted. For unstipped binaries, afl-dyninst defaults to using _init of the binary as an entry point. In case of stripped binaries this option is required and is best set to the address of main which can easily be determined by disassembling the binary and looking for an argument to __libc_start_main. Switch -E is used to specify addresses that should force a clean exit when reached. This can speed up the fuzzing tremendously. Switch -s instructs afl-dyninst to skip the first <number> of basic blocks. Currently, it is used to work around a bug in Dyninst but doubles as an optimization option, as skipping the basic blocks of the initialization rutines makes things run faster. If the instrumented binary is crashing by itself, try skiping a number of blocks. Switch -r allows you to specify a path to the library that is loaded via dlopen() at runtime. Instrumented runtime libraries will be written to the same location with a ".ins" suffix as not to overwrite the original ones. Make sure to backup the originals and then rename the instrumented ones to original name. Switch -m allows you to only instrument basic blocks of a minimum size - the default minimum size is 1 Switch -f fixes a dyninst bug that lead to bugs in the instrumented program: our basic block instrumentation function loaded into the instrumentd binaries uses the edi/rdi. However dyninst does not always saves and restores it when instrumenting that function leading to crashes and changed program behaviour when the register is used for function parameters. Switch -S allows you to not instrument specific functions. This options is mainly to hunt down bugs in dyninst. Switch -D installs the afl fork server and forced exit functions but no basic block instrumentation. That would serve no purpose - unless there is another interesting tool coming up ... :) Compiling: ---------- 1. Edit the Makefile and set DYNINST_ROOT and AFL_ROOT to appropriate paths. 2. make 3. make install Example of running the tool --------------------------- Dyninst requires DYNINSTAPI_RT_LIB environment variable to point to the location of libdyninstAPI_RT.so. $ export DYNINSTAPI_RT_LIB=/usr/local/lib/libdyninstAPI_RT.so $ ./afl-dyninst -i ./rar -o ./rar_ins -e 0x4034c0 -s 100 Skipping library: libAflDyninst.so Instrumenting module: DEFAULT_MODULE Inserting init callback. Saving the instrumented binary to ./rar_ins... All done! Happy fuzzing! Here we are instrumenting the rar binary with entrypoint at 0x4034c0 (manualy found address of main), skipping the first 100 basic blocks and outputing to rar_ins. Running AFL on instrumented binary ---------------------------------- NOTE: The instrumentation library "libDyninst.so" must be available in the current working directory or LD_LIBRARY_PATH as that is where the instrumented binary will be looking for it. Since AFL checks if the binary has been instrumented by afl-gcc,AFL_SKIP_BIN_CHECK environment variable needs to be set. No modifications to AFL it self is needed. $ export AFL_SKIP_BIN_CHECK=1 Then, AFL can be run as usual: $ afl-fuzz -i testcases/archives/common/gzip/ -o test_gzip -- ./gzip_ins -d -c Note that there are the helper scripts afl-fuzz-dyninst.sh and afl-dyninst.sh for you which set the required environment variables for you.
After instrument, the binary exists lots of bad instruction, Is this normal?
401dfd: 27 (bad)
401dfe: 00 be cd 0c 45 00 add %bh,0x450ccd(%rsi)
401e04: e8 37 fb ff ff callq 401940 freopen@plt
401e09: e9 1f f5 39 00 jmpq 7a132d <main_dyninst+0xeef>
401e0e: c9 leaveq
401e0f: 10 00 adc %al,(%rax)
401e11: 00 e9 add %ch,%cl
401e13: 27 (bad)
401e14: f6 39 idivb (%rcx)
401e16: 00 27 add %ah,(%rdi)
401e18: 00 e8 add %ch,%al
401e1a: 42 fc rex.X cld
401e1c: ff (bad)
401e1d: ff (bad)
401e1e: e9 2f f7 39 00 jmpq 7a1552 <main_dyninst+0x1114>
401e23: 27 (bad)
recently. i got the following error ,when i typed 'make ' command
`
afl-dyninst.cpp:19:28: fatal error: dyninstversion.h: 没有那个文件或目录
`
is it support osx?
Hi, when I tried to fuzz the instrumented binary, it failed. I don't know why .
dyninst123@ubuntu:~/Desktop$ afl-fuzz -i in -o out ./base64_ins
afl-fuzz 2.39b by <[email protected]>
[+] You have 1 CPU core and 3 runnable tasks (utilization: 300%).
[*] Checking core_pattern...
[*] Setting up output directories...
[+] Output directory exists but deemed OK to reuse.
[*] Deleting old session data...
[+] Output dir cleanup successful.
[*] Scanning 'in'...
[+] No auto-generated dictionary tokens to reuse.
[*] Creating hard links for all input files...
[*] Validating target binary...
[*] Attempting dry run with 'id:000000,orig:1'...
[*] Spinning up the fork server...
[-] Hmm, looks like the target binary terminated before we could complete a
handshake with the injected code. There are two probable explanations:
- The current memory limit (25.0 MB) is too restrictive, causing an OOM
fault in the dynamic linker. This can be fixed with the -m option. A
simple way to confirm the diagnosis may be:
( ulimit -Sv $[24 << 10]; /path/to/fuzzed_app )
Tip: you can use http://jwilk.net/software/recidivm to quickly
estimate the required amount of virtual memory for the binary.
- Less likely, there is a horrible bug in the fuzzer. If other options
fail, poke <[email protected]> for troubleshooting tips.
[-] PROGRAM ABORT : Fork server handshake failed
Location : init_forkserver(), afl-fuzz.c:2247
Doesn't build anymore after one of the last changes. Basically afl-dyninst.cpp now includes dyninstversion.h (line 19), which is not in the src tree.
Hi, does it support arm?
My environment is x86_64, and I want to test a aarch64 binary.
Just like I said under #13 , it is not work if my target is based on arm. I need to compile dyninst to aarch64 architecture to solve it, but it is painful and I failed.
Thus, I use an arm docker container for this purpose. It works but the fuzz speed is slow. I think the reason is that the container is running above qemu.
As a result, I move the binary, created by afl-dyninst, to my x86 machine, and it is able to fuzz but also very slow.
aarch64-linux-gnu-gcc test.c -o testQemu
afl-fuzz -i in -o out -Q ./testQemu
exec speed: 1580/sec
Under docker container:
gcc test.c -o testQemu
afl-dyninst -i testQemu -o armDy
Move to x86 ,and run:
afl-fuzz -i in -o out ./armDy
exec speed: 160/sec
Why do I get this result? Which part might be the problem?
I saw that AFL's frida-mode does not support multi-threading now, so I would like to ask if afl-dyninst also does not support multi-threading
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.