LibAFL
LibAFL copied to clipboard
Make libafl_frida run executables
We have to add too some code to run binaries not just shared objects. Should be easy, just hook libc start main, compile the fuzzer as a shared object and inject into the target with LD_PRELOAD.
Originally posted by @andreafioraldi in https://github.com/AFLplusplus/LibAFL/issues/307#issuecomment-931045608
Now, libafl_frida can fuzz only shared library (.so, .dll), but we want to extend it to executables.
ok I am currently seeing it but Can you please elaborate it in detail.
hey if you take a look at frida_libpng then you'll see what we want. now, our fuzzer fuzz a function in a shared lib (.so), but we want to make it possible to fuzz a executable.
Hello, I just wanted to make sure that I'm starting contributing to this issue correctly. So, initially I should fork the dev
branch, make the changes to the code related to this issue and then make a pull request to the dev
branch again. Is that right?
no unlike AFL++ there's no dev branch in libafl you can just send pr to main
Hi! Just updating that I've been going through the frida_libpng example and I believe I understood how it loads the library and the function from the library, given as CLI arguments, in the fuzzer file. Also, I gave a look at the Make.toml
file to follow how ithe execution of the exmaple takes place, how it compiles the harness:
clang++ -O3 -c -fPIC harness.cc -o harness.o
And then it links with libpng to create the shared object:
clang++ -O3 harness.o libpng-1.6.37/.libs/libpng16.a -shared -lz -o libpng-harness.so
So that it can finally execute the fuzzer, passing the shared object as a CLI argument:
./${FUZZER_NAME} -F LLVMFuzzerTestOneInput -H ./libpng-harness.so -l ./libpng-harness.so
Which will then be parsed and assigned to variables here:
let lib = libloading::Library::new(options.clone().harness.unwrap()).unwrap();
let target_func: libloading::Symbol<
unsafe extern "C" fn(data: *const u8, size: usize) -> i32,
> = lib.get(options.harness_function.as_bytes()).unwrap();
I'm quite confused where you said "[...] just hook libc start main, compile the fuzzer as a shared object and inject into the target with LD_PRELOAD", so the idea would be to trick the target program into beginning execution on the fuzzers's main (by using LD_PRELOAD and the hook), so that the fuzzer would execute instead of the target?
yes that's what it means
in frida_libpng you compiled .so, shared library and your fuzzer run that harness as the shared lib
but we want to do the opposite. your fuzzer is the shared lib this time and the harness is an executable. it has libc_start_main, so hook it and iteratively execute main() as the harness function (so this main() is the target_func now)
@tokatoka @matheusbaptistella
Sorry for bothering you guys, I've been trying to solve this issue to recently too. (Please refer to #1117 draft PR as reference)
I think this what tokatoka mean by hooking libc_start_main. (maybe)
https://github.com/AFLplusplus/LibAFL/pull/1117/files#diff-f330f0c5f045e9fef72d9e93fa2fb9d209f0d713caa63dbd2a1734cc3be5c8a6R5-R9
Instead of executing library by using default GNU libc_start_main, we use PRELOAD to overwrite existing libc_start_main with libc_start_main defined by so library.
Oh nice you probably have developed more than me in this issue! So, I guess I should work on something else (?) or if you want any help I could do that too!
This issue has been fixed in this https://github.com/AFLplusplus/LibAFL/pull/1117 pr