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

list_exports func added and initial RPC code. #147

Merged
merged 8 commits into from
Sep 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ members = [
"examples/core/hello",
"examples/core/usb_device",
"examples/core/console_log",
"examples/core/list_exports",
"examples/core/get_processes",
]
# We miss our linux_no_std example from the default members since `cargo check`
Expand Down
8 changes: 4 additions & 4 deletions examples/core/console_log/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,11 @@ fn main() {
let mut script_option = ScriptOption::new()
.set_name("example")
.set_runtime(ScriptRuntime::QJS);
let script = session
let mut script = session
.create_script("console.log('Log test');", &mut script_option)
.unwrap();

script.handle_message(&mut Handler).unwrap();
script.handle_message(Handler).unwrap();

script.load().unwrap();
println!("[*] Script loaded");
Expand All @@ -48,7 +48,7 @@ fn main() {
struct Handler;

impl ScriptHandler for Handler {
fn on_message(&mut self, message: &str) {
println!("{message}");
fn on_message(&mut self, message: &frida::Message) {
println!("{:?}", message);
}
}
10 changes: 10 additions & 0 deletions examples/core/list_exports/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[package]
name = "list_exports"
version = "0.1.0"
edition = "2021"
authors = ["Ricardo J Marques Montilla / Xoffio"]

[dependencies]
frida = { path = "../../../frida" }
frida-sys = { path = "../../../frida-sys" }
lazy_static = "1.5.0"
18 changes: 18 additions & 0 deletions examples/core/list_exports/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
Example to showing how to use `script.list_exports()`.
Once ran you should expect an output similar to the next one:

```
[*] Frida version: 16.4.8
[*] Device name: Local System
- Log(MessageLog { level: Info, payload: "Logging message from JS" })
- Log(MessageLog { level: Warning, payload: "Warning message from JS" })
- Log(MessageLog { level: Debug, payload: "Debug message from JS" })
- Log(MessageLog { level: Error, payload: "Error message from JS" })
[*] Script loaded.
["increment", "getvalue"]
["increment", "getvalue"]
["increment", "getvalue"]
[*] Script unloaded
[*] Session detached
Exiting...
```
82 changes: 82 additions & 0 deletions examples/core/list_exports/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
use frida::{Frida, Message};
use lazy_static::lazy_static;
use std::{thread, time::Duration};

lazy_static! {
static ref FRIDA: Frida = unsafe { Frida::obtain() };
}

fn main() {
let device_manager = frida::DeviceManager::obtain(&FRIDA);
let local_device = device_manager.get_local_device();

if let Ok(device) = local_device {
println!("[*] Frida version: {}", frida::Frida::version());
println!("[*] Device name: {}", device.get_name());

// Attach to the program
let session = device.attach(0).unwrap();

if session.is_detached() {
println!("Session is detached");
return;
}

let script_source = r#"
var globalVar = 0;
console.log("Logging message from JS");
console.warn("Warning message from JS");
console.debug("Debug message from JS");
console.error("Error message from JS");

rpc.exports = {
increment: function() {
globalVar += 1;
return globalVar;
},
getvalue: function() {
return globalVar;
}
};
"#;
let mut script_option = frida::ScriptOption::default();
let mut script = match session.create_script(script_source, &mut script_option) {
Ok(s) => s,
Err(err) => {
println!("{}", err);
return;
}
};

let msg_handler = script.handle_message(Handler);
if let Err(err) = msg_handler {
panic!("{:?}", err);
}

script.load().unwrap();
println!("[*] Script loaded.");

println!("{:?}", script.list_exports().unwrap());

for _ in 0..2 {
thread::sleep(Duration::from_secs(1));
println!("{:?}", script.list_exports().unwrap());
}

script.unload().unwrap();
println!("[*] Script unloaded");

session.detach().unwrap();
println!("[*] Session detached");
}

println!("Exiting...");
}

struct Handler;

impl frida::ScriptHandler for Handler {
fn on_message(&mut self, message: &Message) {
println!("- {:?}", message);
}
}
5 changes: 1 addition & 4 deletions frida-gum/src/interceptor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,7 @@ impl<'a> Interceptor<'a> {
/// Obtain an Interceptor handle, ensuring that the runtime is properly initialized. This may
/// be called as many times as needed, and results in a no-op if the Interceptor is
/// already initialized.
pub fn obtain<'b>(_gum: &'b Gum) -> Interceptor
where
'b: 'a,
{
pub fn obtain<'b: 'a>(_gum: &'b Gum) -> Interceptor<'b> {
Copy link
Contributor

Choose a reason for hiding this comment

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

Why is the 'a lifetime here?

Copy link
Contributor

Choose a reason for hiding this comment

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

what about this?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

'b: 'a ensures that the lifetime of the input is at least as long as 'a. I had to put that because 117003b broke the no_std test

Copy link
Contributor

Choose a reason for hiding this comment

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

Oh I didn't realize 'a was on the Interceptor.

Interceptor {
interceptor: unsafe { gum_sys::gum_interceptor_obtain() },
phantom: PhantomData,
Expand Down
5 changes: 1 addition & 4 deletions frida-gum/src/stalker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,10 +104,7 @@ impl<'a> Stalker<'a> {
/// This call has the overhead of checking if the Stalker is
/// available on the current platform, as creating a Stalker on an
/// unsupported platform results in unwanted behaviour.
pub fn new<'b>(gum: &'b Gum) -> Stalker
where
'b: 'a,
{
pub fn new<'b: 'a>(gum: &'b Gum) -> Stalker<'b> {
Xoffio marked this conversation as resolved.
Show resolved Hide resolved
assert!(Self::is_supported(gum));

Stalker {
Expand Down
4 changes: 3 additions & 1 deletion frida/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,10 @@ description.workspace = true
auto-download = ["frida-sys/auto-download"]

[dependencies]
frida-sys = { path = "../frida-sys" , version = "0.13.7"}
frida-sys = { path = "../frida-sys", version = "0.13.7" }
thiserror = "1"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0.127"

[dev-dependencies]
lazy_static = "1"
Expand Down
2 changes: 1 addition & 1 deletion frida/src/device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ impl<'a> Device<'a> {
let mut key = std::ptr::null_mut();
let mut val = std::ptr::null_mut();
while (unsafe { frida_sys::g_hash_table_iter_next(&mut iter, &mut key, &mut val) }
!= frida_sys::FALSE as _)
!= frida_sys::FALSE as i32)
{
let key = unsafe { CStr::from_ptr(key as _) };
let val = unsafe { Variant::from_ptr(val as _) };
Expand Down
Loading
Loading