diff --git a/frida-gum/src/module.rs b/frida-gum/src/module.rs index 21f368b..776a856 100644 --- a/frida-gum/src/module.rs +++ b/frida-gum/src/module.rs @@ -18,7 +18,9 @@ use { core::ffi::c_void, cstr_core::CString, frida_gum_sys as gum_sys, - frida_gum_sys::{gboolean, gpointer, GumExportDetails, GumModuleDetails, GumSymbolDetails}, + frida_gum_sys::{ + gboolean, gpointer, GumExportDetails, GumModuleDetails, GumSectionDetails, GumSymbolDetails, + }, }; #[cfg(not(feature = "std"))] @@ -41,6 +43,14 @@ pub struct SymbolDetails { pub size: usize, } +/// Module symbol details returned by [`Module::enumerate_sections`]. +pub struct SectionDetails { + pub id: String, + pub name: String, + pub address: usize, + pub size: usize, +} + /// Module export details returned by [`Module::enumerate_exports`]. pub struct ExportDetails { pub typ: u32, @@ -270,4 +280,46 @@ impl<'a> Module<'a> { } result } + + /// Enumerates sections of module. + pub fn enumerate_sections(&self, module_name: &str) -> Vec { + let result: Vec = vec![]; + + unsafe extern "C" fn callback( + details: *const GumSectionDetails, + user_data: gpointer, + ) -> gboolean { + let res = &mut *(user_data as *mut Vec); + + let id: String = NativePointer((*details).id as *mut _) + .try_into() + .unwrap_or_default(); + let name: String = NativePointer((*details).name as *mut _) + .try_into() + .unwrap_or_default(); + let address = (*details).address as usize; + let size = (*details).size as usize; + + let info = SectionDetails { + id, + name, + address, + size, + }; + res.push(info); + + 1 + } + + let module_name = CString::new(module_name).unwrap(); + + unsafe { + frida_gum_sys::gum_module_enumerate_sections( + module_name.as_ptr().cast(), + Some(callback), + &result as *const _ as *mut c_void, + ); + } + result + } }