Skip to content
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

LibAFL_Frida: add scripting support #2506

Merged
merged 1 commit into from
Oct 25, 2024

Conversation

WorksButNotTested
Copy link
Collaborator

No description provided.

s1341
s1341 previously requested changes Sep 5, 2024
xz2::read::XzDecoder,
};

fn extract() -> Result<()> {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this not be done in frida-rust?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah. Mostly likely. Seems there is only support for the gum devkit right now, we would need to replace it (probably a crate config option) with gumjs. Since one is a superset of the other.

entry.unpack(full_name.as_path())?;
found_header = true;
}
"libfrida-gumjs.a" => {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't take into account windows.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nope. Nor all of the other architectures.

@@ -429,6 +439,7 @@ where
.map(PathBuf::from)
.collect::<Vec<_>>();
FridaInstrumentationHelper::builder()
.load_script("/tmp/script.js")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This really needs to be an option.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Of course, it needs to come from the command line or similar.

/// Create a new Script
pub fn load<P: AsRef<Path>>(path: P) -> Result<()> {
unsafe {
gum_init_embedded();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should use frida-gum::Gum::obtain()

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In general, all of these calls should be abstracted away by frida-rust objects.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed. I didn't want to mix the two.


/// Callback function which can be called from the script
#[no_mangle]
pub extern "C" fn test_function(message: *const gchar) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe move this into the fuzzer example (or even create a new fuzzer which uses this functionality).

Copy link
Collaborator Author

@WorksButNotTested WorksButNotTested Sep 5, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The idea of this was to demonstrate that the library can export a function which in turn is accessible to the user through scripting. In AFL++ frida scripting support JS can be used to configure the fuzzer too. e.g. by setting the ranges to be included/excluded in coverage, enabling ASAN etc. See here.

@@ -0,0 +1,13 @@
"use strict";
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe move this into the fuzzer example (or even create a new fuzzer which uses this functionality).

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This relates to the above. The idea is to add a namespace and API to the JS layer which the user can call to interact with libafl_frida itself. e.g. the functions exported would not be target specific.

@WorksButNotTested
Copy link
Collaborator Author

The addition of the -rdynamic flag to the fuzzer is a bit ugly too. But without it rust seems to drop any exported functions from crates linked as dependencies. Perhaps adding the dependency as a dynamic lib may help, but that isn't pretty either.

@@ -44,7 +44,13 @@ track_hit_feedbacks = ["libafl/track_hit_feedbacks"]
auto-download = ["frida-gum-sys/auto-download", "frida-gum/auto-download"]

[build-dependencies]
anyhow = "1.0"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should stick to our libafl_bolts::Error struct in LibAFL (and potentially implement more .into() cases)

@domenukk
Copy link
Member

domenukk commented Sep 5, 2024

Cool stuff!

@domenukk
Copy link
Member

The changes in frida-rust have landed right?

@WorksButNotTested
Copy link
Collaborator Author

WorksButNotTested commented Oct 16, 2024

The changes in frida-rust have landed right?

Yup. Just need to get some free time and I'll integrate them. Happy if someone else wants to do it, if people are waiting on it. The heavy lifting is done.

@domenukk
Copy link
Member

No rush :)

@WorksButNotTested
Copy link
Collaborator Author

Running the command...

LIBAFL_DEBUG_OUTPUT=1 
./target/release/frida_fuzzer 
  -F LLVMFuzzerTestOneInput
  -H ./libpng-harness.so 
  -l ./libpng-harness.so 
  --backend quick-js 
  --script /tmp/script.js

Loading the script...

LibAfl.testFunction("TEST FUNCTION");
const bytes = new Uint8Array([0x11, 0x22, 0x33, 0x44, 0x55]);
send("SENDING", bytes);
console.log("LOGGING");

Results in the output...

LibAfl.testFunction("TEST FUNCTION");
const bytes = new Uint8Array([0x11, 0x22, 0x33, 0x44, 0x55]);
send("SENDING", bytes);
console.log("LOGGING");

@domenukk
Copy link
Member

If nobody really has the time to test this atm (I don't) - should we just merge this and fix things later if they come up? cc @s1341

@WorksButNotTested
Copy link
Collaborator Author

Sounds good to me if you're happy.

@domenukk domenukk changed the title WIP - Initial scripting support LibAFL_Frida: add scripting support Oct 23, 2024
@domenukk domenukk enabled auto-merge (squash) October 24, 2024 12:09
@domenukk domenukk merged commit 03af6aa into AFLplusplus:main Oct 25, 2024
89 of 98 checks passed
@WorksButNotTested
Copy link
Collaborator Author

Thanks for the merge.

@domenukk
Copy link
Member

Thanks for the scripting support ;)

riesentoaster pushed a commit to riesentoaster/LibAFL that referenced this pull request Dec 11, 2024
Co-authored-by: Your Name <you@example.com>
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

Successfully merging this pull request may close these issues.

3 participants