Skip to content

AFL stucks when use unicorn+qiling to fuzz Android native library with a real world gdb context #748

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
D0nYu opened this issue Mar 24, 2021 · 11 comments

Comments

@D0nYu
Copy link

D0nYu commented Mar 24, 2021

Hello,
I tried to use AFLplusplus+unicorn to fuzz an Android native jpg codec library and use qiling to emulate the Android system runtime. The initial state is dumped from a physical device from a gdb connection (https://github.com/AFLplusplus/AFLplusplus/tree/stable/unicorn_mode/helper_scripts).
After adding some necessary hooks, the harness works. When I use AFL to fuzz it (https://github.com/qilingframework/qiling/tree/master/examples/fuzzing) , it also works well in the very first minutes.
But soon the AFL stucks and the exec speed becomes extremely slow.
image

I wonder how could I solve this.
It seems that AFL hangs because the qiling/unicorn struggle to request memory. Maybe map all the memory context is too cumbersome, or I misuse some APIs of qiling or unicorn?
I have uploaded the code and environment at https://github.com/D0nYu/JpegFuzzer . Run fuzzit.sh can start the fuzzing. If you use the seed in my input directory, the AFL would stuck after 1582 execs.

@aquynh
Copy link
Member

aquynh commented Mar 24, 2021

Where is the src code of the loader?

@D0nYu
Copy link
Author

D0nYu commented Mar 24, 2021

The Jpegloader is just a dummy binary to satisfy the qiling initialization. Once it is initialized, I overwrite all the memory regions and registers with the dumped context. And the code I try to emulate is a snippet of a dynamic library, so I think the loader does not matter.

@xwings
Copy link
Member

xwings commented Mar 25, 2021

not too sure which part of this is having issue.
according to @wtdcode very likely is unicorn.

What you can do is to add a timeout in AFL++ and see does it help.

maybe @domenukk can give us some hint :) calling @domenukk

@wtdcode
Copy link
Member

wtdcode commented Mar 25, 2021

Could you post qiling log?

@D0nYu
Copy link
Author

D0nYu commented Mar 25, 2021

The log file has been attached.
qlog.txt

The "Allocating" entries by the malloc hook and the "android_log_print" entries are recorded by the hooks of android logging functions.

BTW, the log_file option cannot work well with console=True, when it tries to record the colored log.

@wtdcode
Copy link
Member

wtdcode commented Mar 25, 2021

The log file has been attached.
qlog.txt

The "Allocating" entries by the malloc hook and the "android_log_print" entries are recorded by the hooks of android logging functions.

BTW, the log_file option cannot work well with console=True, when it tries to record the colored log.

you could try log_plain=True

@wtdcode
Copy link
Member

wtdcode commented Mar 25, 2021

Seems that the big allocation may slow down the whole fuzzer. But the problem is that it should not make AFL hang. I will try to reproduce it later.

@domenukk
Copy link
Contributor

The AFL run is set to a timeout of -t 50000, so afl will hardly ever kill slow testcases. Hitting a single infinite loop will lead to very slow fuzzing (below 1 exec per sec).

https://github.com/D0nYu/JpegFuzzer/blob/10d672c16f23b56cd4c7eb52fd2570c4dbade318/fuzzit.sh#L1

Changing this timeout to a normal time, like -t 1000 may just solve your issue here.
On top, for a full snapshot, the fuzzer may just have found another way out of the harness and spend all of its time (up to 50 seconds) in other parts of the snapshot.

@D0nYu
Copy link
Author

D0nYu commented Mar 26, 2021

The AFL run is set to a timeout of -t 50000, so afl will hardly ever kill slow testcases. Hitting a single infinite loop will lead to very slow fuzzing (below 1 exec per sec).

https://github.com/D0nYu/JpegFuzzer/blob/10d672c16f23b56cd4c7eb52fd2570c4dbade318/fuzzit.sh#L1

Changing this timeout to a normal time, like -t 1000 may just solve your issue here.
On top, for a full snapshot, the fuzzer may just have found another way out of the harness and spend all of its time (up to 50 seconds) in other parts of the snapshot.

In fact, the fuzzer takes over 30s to boot up but performs well in the first few minutes (30-40 execs per sec) until it finds a new path. I also tried to use AFL qemu mode to fuzz the same target and everything went well. So I wonder why qiling takes so much time. Is it because a large amount of memory allocation slows down the fuzzer?

@wtdcode
Copy link
Member

wtdcode commented Mar 26, 2021

image

Did a perf and seems that it's memory operation which slows down the whole fuzzer.

Link to unicorn-engine/unicorn#1217 for now.

@xwings
Copy link
Member

xwings commented Oct 6, 2022

Will you be able to try the latest version of Qiling and see if you still face same issue. There is lots of rework since 2021. Feel free to open a new issue if you have any similar problem.

@xwings xwings closed this as completed Oct 6, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants