diff options
author | Nguyễn Gia Phong <cnx@loang.net> | 2024-11-05 16:19:38 +0900 |
---|---|---|
committer | Nguyễn Gia Phong <cnx@loang.net> | 2024-11-05 16:27:39 +0900 |
commit | e250d83f299b99904602d4b6843ca70a5d0992a1 (patch) | |
tree | 05f72410dcaf632e01059480bc88d7e8d5d7ade9 /README.md | |
parent | 1fe6579eb183c8762c6ce41fc2ace742c8f5a5c9 (diff) | |
download | afl-dyninst-e250d83f299b99904602d4b6843ca70a5d0992a1.tar.gz |
Reflect new CLI in README
Diffstat (limited to 'README.md')
-rw-r--r-- | README.md | 124 |
1 files changed, 63 insertions, 61 deletions
diff --git a/README.md b/README.md index 2119d58..60f69b3 100644 --- a/README.md +++ b/README.md @@ -24,25 +24,31 @@ to be injected into wrapper scripts: make DYNINST_LIB=$dyninst_prefix/lib PREFIX=$afl_dyninst_prefix install -## Commandline options -``` -Usage: afl-dyninst -vxD -i binary -o binary -e address -E address -s number -S funcname -I funcname -m size - -i: input binary program - -o: output binary program - -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: 10) - -I: only instrument this function and nothing else (repeat for more than one) - -S: do not instrument this function (repeat for more than one) - -D: instrument only a simple fork server and also forced exit functions - -x: experimental performance mode (~25-50% speed improvement) - -v: verbose output +## Usage + +```shell +$ afl-dyninst --help +Usage: afl-dyninst [OPTIONS]... INFILE OUTFILE + +Instrument binary to be fuzzed by AFL. + +Options: + -h, --help show this help message and exit + --version show program's version number and exit + -e ADDR, --entry=ADDR entry point address to patch (required for stripped binaries) + -E ADDR, --exit=ADDR force exit(0) at this address (multiple use) + -D instrument only a simple fork server and also forced exit functions + -r PATH, --library=PATH runtime library to instrument (multiple use) + -I NAME, --include=NAME instrument only this function and nothing else (multiple use) + -S NAME, --exclude=NAME do not instrument this function (multiple use) + -m N, --min-size=N minimum size of a basic bock to instrument (default to 10) + -s N, --skip=N number of initial basic blocks to skip in binary + -v, --verbose enable verbose output (up to 3 levels) + -x experimental performance mode (multiple use, ~25-50% speed improvement) ``` -Switch -e is used to manualy specify the entry point where initialization -callback is to be inserted. For unstipped binaries, afl-dyninst defaults +Switch -e is used to manually specify the entry point where initialization +callback is to be inserted. For unstripped 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 @@ -59,12 +65,12 @@ itself, try skiping a number of blocks. Switch -r allows you to specify a path to a 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 +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 +default minimum size is 10. Switch -S allows you to not instrument specific functions. This options is mainly to hunt down bugs in dyninst. @@ -84,64 +90,60 @@ Switch -x enables an experimental performance mode (+25-50% speed). Just try it and if the target crashes too often, instrument again without this. Should not crash though. -## Example of instrumenting a target binary +After instrumenting the target binary always check if it works. +Dyninst makes big changes to the code, and hence more often than not +things are not working anymore. -``` -$ ./afl-dyninst -i ./unrar -o ./rar_ins -e 0x4034c0 -x -Skipping library: libafldyninst.so -Instrumenting module: DEFAULT_MODULE -Inserting init callback. -Saving the instrumented binary to ./unrar_ins... -All done! Happy fuzzing! -``` +The instrumentation libraries `libafldyninst.so` and `libdyninstAPI_RT.so` +must be available in `LD_LIBRARY_PATH` as the instrumented binary +will be looking for them. The helper script afl-dyninst-env sets up +the environment accordingly. + +## Examples + +### Instrumentation + + afl-dyninst -e 0x4034c0 -x unrar unrar-ins -Here we are instrumenting the rar binary with entrypoint at 0x4034c0 -(manually found address of main), skipping the first 10 basic blocks -and outputing to `unrar_ins`. +Here we are instrumenting the `unrar` binary with entry point at 0x4034c0 +(manually found address of `main`), skipping the first 10 basic blocks +and outputting to `unrar-ins`. This instrumented binary can be tested via -## Running AFL on the instrumented binary + afl-dyninst-env ./unrar-ins ... -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. +### Fuzzing instrumented binary -Since AFL checks if the binary has been instrumented by afl-gcc, the -AFL_SKIP_BIN_CHECK environment variable needs to be set. +Since AFL checks if the binary has been instrumented by afl-gcc, +the `AFL_SKIP_BIN_CHECK` environment variable needs to be set. No modifications to AFL itself 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 -``` -You can also use the afl-dyninst-env helper script -which sets the required environment variables for you. + export AFL_SKIP_BIN_CHECK=1 - afl-dyninst-env afl-fuzz -i testcases/archives/common/gzip/ -o test_gzip -- ./gzip_ins -d -c +You can use the afl-dyninst-env helper script +to sets the required environment variables: + + afl-dyninst-env afl-fuzz -i testcases/archives/common/gzip/ -o test_gzip\ + -- ./gzip_ins -d -c ## Problems -After instrumenting the target binary always check if it works. -Dyninst is making big changes to the code, and hence more often than not -things are not working anymore. +### Instrumented binary not working -Problem 1: The binary does not work (crashes or hangs) +If the instrumented binary crashes or hangs, try to increase +the `--min-size` parameter. 8 is the minimum recommended, +on some targets e.g. 16 is required. -Solution: increase the -m parameter. -m 8 is the minimum recommended, on some - targets -m 16 is required etc. - You can also try to remove the -x performance enhancer +You can also try to remove the performance enhancer flag `-x`. +### AFL reporting executions as crash -Problem 2: Basically every fuzzing test case is reported as crash although it - does not when running it from the command line +If the target is using throw/catch, Dyninst fails to handle +the caught exception, hence `abort` is triggered. +AFL will report most fuzzing test case is reported as a crash +although it does not when running it from the command line. -Solution: This happens if the target is using throw/catch, and dyninst's - modification result in that the caught exception is not resetted and - hence abort() is triggered. - No solution to this issue is known yet. - Binary editing the target binary - to perform `_exit(0)` would help though. +No solution to this issue is known yet. +Binary editing the target binary to perform `_exit(0)` would help though. ## Copying |