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

frida-gum: force frida-gum init to use Module (#98) #172

Merged
merged 3 commits into from
Oct 29, 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
13 changes: 6 additions & 7 deletions examples/gum/debug_symbol/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
use frida_gum::DebugSymbol;
use frida_gum::{Gum, Module};
use lazy_static::lazy_static;

lazy_static! {
static ref GUM: Gum = unsafe { Gum::obtain() };
}
use std::iter::Once;
use std::sync::OnceLock;

fn main() {
lazy_static::initialize(&GUM);
static CELL: OnceLock<Gum> = OnceLock::new();
let gum = CELL.get_or_init(|| Gum::obtain());

let symbol = Module::find_export_by_name(None, "mmap").unwrap();
let module = Module::obtain(gum);
let symbol = module.find_export_by_name(None, "mmap").unwrap();
let symbol_details = DebugSymbol::from_address(symbol).unwrap();
println!(
"address={:#x?} module_name={:?} symbol_name={:?} file_name={:?} line_number={:?}",
Expand Down
1 change: 0 additions & 1 deletion examples/gum/hook_instruction/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,4 @@ crate-type = ["cdylib"]

[dependencies]
frida-gum = { path = "../../../frida-gum", features = ["invocation-listener"] }
lazy_static = "1.4"
ctor = "0.2"
13 changes: 6 additions & 7 deletions examples/gum/hook_instruction/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,7 @@ use frida_gum::{
interceptor::{Interceptor, InvocationContext, ProbeListener},
Gum, Module,
};
use lazy_static::lazy_static;

lazy_static! {
static ref GUM: Gum = unsafe { Gum::obtain() };
}
use std::sync::OnceLock;
#[derive(Default, Debug)]
struct OpenProbeListener;

Expand All @@ -19,8 +15,11 @@ impl ProbeListener for OpenProbeListener {

#[ctor]
fn init() {
let mut interceptor = Interceptor::obtain(&GUM);
let open = Module::find_export_by_name(None, "open").unwrap();
static CELL: OnceLock<Gum> = OnceLock::new();
let gum = CELL.get_or_init(|| Gum::obtain());
let mut interceptor = Interceptor::obtain(gum);
let module = Module::obtain(gum);
let open = module.find_export_by_name(None, "open").unwrap();
let mut listener = OpenProbeListener;
interceptor.attach_instruction(open, &mut listener).unwrap();
}
9 changes: 6 additions & 3 deletions examples/gum/hook_open/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ use lazy_static::lazy_static;
use libc::{c_char, c_int, c_void};
use std::cell::UnsafeCell;
use std::sync::Mutex;
use std::sync::OnceLock;

lazy_static! {
static ref GUM: Gum = unsafe { Gum::obtain() };
static ref ORIGINAL_OPEN: Mutex<UnsafeCell<Option<OpenFunc>>> =
Mutex::new(UnsafeCell::new(None));
}
Expand All @@ -29,8 +29,11 @@ unsafe extern "C" fn open_detour(name: *const c_char, flags: c_int) -> c_int {

#[ctor]
fn init() {
let mut interceptor = Interceptor::obtain(&GUM);
let open = Module::find_export_by_name(None, "open").unwrap();
static CELL: OnceLock<Gum> = OnceLock::new();
let gum = CELL.get_or_init(|| Gum::obtain());
let module = Module::obtain(gum);
let mut interceptor = Interceptor::obtain(gum);
let open = module.find_export_by_name(None, "open").unwrap();
unsafe {
*ORIGINAL_OPEN.lock().unwrap().get_mut() = Some(std::mem::transmute::<
*mut libc::c_void,
Expand Down
1 change: 0 additions & 1 deletion examples/gum/open/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,3 @@ crate-type = ["cdylib"]

[dependencies]
frida-gum = { path = "../../../frida-gum", features = ["invocation-listener"] }
lazy_static = "1.4"
16 changes: 8 additions & 8 deletions examples/gum/open/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,8 @@ use gum::{
interceptor::{Interceptor, InvocationContext, InvocationListener},
Gum, Module,
};
use lazy_static::lazy_static;
use std::os::raw::{c_int, c_void};

lazy_static! {
static ref GUM: Gum = unsafe { Gum::obtain() };
}
use std::sync::OnceLock;

struct OpenListener;

Expand All @@ -28,17 +24,21 @@ impl InvocationListener for OpenListener {
extern "C" fn example_agent_main(_user_data: *const c_void, resident: *mut c_int) {
unsafe { *resident = 1 };

let mut interceptor = Interceptor::obtain(&GUM);
static CELL: OnceLock<Gum> = OnceLock::new();
let gum = CELL.get_or_init(|| Gum::obtain());

let mut interceptor = Interceptor::obtain(gum);
let mut listener = OpenListener {};

let modules = Module::enumerate_modules();
let module = Module::obtain(gum);
let modules = module.enumerate_modules();
for module in modules {
println!(
"{}@{:#x}/{:#x}",
module.name, module.base_address, module.size
);
}

let open = Module::find_export_by_name(None, "open").unwrap();
let open = module.find_export_by_name(None, "open").unwrap();
interceptor.attach(open, &mut listener).unwrap();
}
30 changes: 23 additions & 7 deletions frida-gum/src/module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
)]

use {
crate::{NativePointer, PageProtection, RangeDetails},
crate::{Gum, NativePointer, PageProtection, RangeDetails},
core::ffi::c_void,
cstr_core::CString,
frida_gum_sys as gum_sys,
Expand Down Expand Up @@ -56,12 +56,23 @@ pub struct ModuleDetailsOwned {
pub size: usize,
}

pub struct Module;
pub struct Module {
// This is to verify that Gum is initialized before using any Module methods which requires
// intialization.
// Note that Gum is expected to be initialized via OnceCell which provides &Gum for every
// instance.
_gum: &'static Gum,
}

impl Module {
pub fn obtain(gum: &'static Gum) -> Module {
Module { _gum: gum }
}

/// The absolute address of the export. In the event that no such export
/// could be found, returns NULL.
pub fn find_export_by_name(
&self,
module_name: Option<&str>,
symbol_name: &str,
) -> Option<NativePointer> {
Expand Down Expand Up @@ -92,7 +103,11 @@ impl Module {

/// The absolute address of the symbol. In the event that no such symbol
/// could be found, returns NULL.
pub fn find_symbol_by_name(module_name: &str, symbol_name: &str) -> Option<NativePointer> {
pub fn find_symbol_by_name(
&self,
module_name: &str,
symbol_name: &str,
) -> Option<NativePointer> {
let symbol_name = CString::new(symbol_name).unwrap();

let module_name = CString::new(module_name).unwrap();
Expand All @@ -112,7 +127,7 @@ impl Module {

/// Returns the base address of the specified module. In the event that no
/// such module could be found, returns NULL.
pub fn find_base_address(module_name: &str) -> NativePointer {
pub fn find_base_address(&self, module_name: &str) -> NativePointer {
let module_name = CString::new(module_name).unwrap();

unsafe {
Expand All @@ -124,6 +139,7 @@ impl Module {

/// Enumerates memory ranges satisfying protection given.
pub fn enumerate_ranges(
&self,
module_name: &str,
prot: PageProtection,
callout: impl FnMut(RangeDetails) -> bool,
Expand All @@ -147,7 +163,7 @@ impl Module {
}

/// Enumerates modules.
pub fn enumerate_modules() -> Vec<ModuleDetailsOwned> {
pub fn enumerate_modules(&self) -> Vec<ModuleDetailsOwned> {
let result: Vec<ModuleDetailsOwned> = vec![];

unsafe extern "C" fn callback(
Expand Down Expand Up @@ -187,7 +203,7 @@ impl Module {
}

/// Enumerates exports in module.
pub fn enumerate_exports(module_name: &str) -> Vec<ExportDetails> {
pub fn enumerate_exports(&self, module_name: &str) -> Vec<ExportDetails> {
let result: Vec<ExportDetails> = vec![];

unsafe extern "C" fn callback(
Expand Down Expand Up @@ -219,7 +235,7 @@ impl Module {
}

/// Enumerates symbols in module.
pub fn enumerate_symbols(module_name: &str) -> Vec<SymbolDetails> {
pub fn enumerate_symbols(&self, module_name: &str) -> Vec<SymbolDetails> {
let result: Vec<SymbolDetails> = vec![];
unsafe extern "C" fn callback(
details: *const GumSymbolDetails,
Expand Down
Loading