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

adding process #182

Merged
merged 6 commits into from
Dec 17, 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
3 changes: 3 additions & 0 deletions frida-gum/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,9 @@ pub use module::*;
mod module_map;
pub use module_map::*;

mod process;
pub use process::*;

mod error;
pub use error::Error;

Expand Down
51 changes: 33 additions & 18 deletions frida-gum/src/module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,37 @@ impl fmt::Display for ExportType {
}
}

impl ModuleDetailsOwned {
pub unsafe fn from_module_details(details: *const GumModuleDetails) -> Self {
let name: String = NativePointer((*details).name as *mut _)
.try_into()
.unwrap_or_default();
let path: String = NativePointer((*details).path as *mut _)
.try_into()
.unwrap_or_default();
let range = (*details).range;
let base_address = (*range).base_address as usize;
let size = (*range).size as usize;

ModuleDetailsOwned {
name,
path,
base_address,
size,
}
}
}

impl fmt::Display for ModuleDetailsOwned {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
fmt,
"{{\n\tbase: 0x{:x}\n\tname: {}\n\tpath: {}\n\tsize: {}\n}}",
self.base_address, self.name, self.path, self.size
)
}
}

/// Module symbol details returned by [`Module::enumerate_symbols`].
pub struct SymbolDetails {
pub name: String,
Expand Down Expand Up @@ -91,7 +122,7 @@ pub struct Module<'a> {
_gum: &'a Gum,
}

impl<'a> Module<'a> {
impl Module<'_> {
pub fn obtain(gum: &Gum) -> Module {
Module { _gum: gum }
}
Expand Down Expand Up @@ -198,23 +229,7 @@ impl<'a> Module<'a> {
user_data: gpointer,
) -> gboolean {
let res = &mut *(user_data as *mut Vec<ModuleDetailsOwned>);

let name: String = NativePointer((*details).name as *mut _)
.try_into()
.unwrap_or_default();
let path: String = NativePointer((*details).path as *mut _)
.try_into()
.unwrap_or_default();
let range = (*details).range;
let base_address = (*range).base_address as usize;
let size = (*range).size as usize;
let module_details = ModuleDetailsOwned {
name,
path,
base_address,
size,
};
res.push(module_details);
res.push(ModuleDetailsOwned::from_module_details(details));

1
}
Expand Down
139 changes: 139 additions & 0 deletions frida-gum/src/process.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
//! Process helpers.
//!

#![cfg_attr(
any(target_arch = "x86_64", target_arch = "x86"),
allow(clippy::unnecessary_cast)
)]

use crate::{FileMapping, NativePointer};

use {
crate::{module, Gum, PageProtection, RangeDetails},
core::ffi::c_void,
frida_gum_sys as gum_sys,
frida_gum_sys::{gboolean, gpointer},
};

#[cfg(not(feature = "std"))]
use alloc::vec::Vec;

#[derive(Clone, FromPrimitive, Debug)]
#[repr(u32)]
pub enum CodeSigningPolicy {
CodeSigningOptional = gum_sys::GumCodeSigningPolicy_GUM_CODE_SIGNING_OPTIONAL as u32,
CodeSigningRequired = gum_sys::GumCodeSigningPolicy_GUM_CODE_SIGNING_REQUIRED as u32,
}

#[derive(Clone, FromPrimitive, Debug)]
#[repr(u32)]
pub enum Os {
OsWindows = gum_sys::_GumOS_GUM_OS_WINDOWS as u32,
OsMacos = gum_sys::_GumOS_GUM_OS_MACOS as u32,
OsLinux = gum_sys::_GumOS_GUM_OS_LINUX as u32,
OsIos = gum_sys::_GumOS_GUM_OS_IOS as u32,
OsWatchos = gum_sys::_GumOS_GUM_OS_WATCHOS as u32,
OsTvos = gum_sys::_GumOS_GUM_OS_TVOS as u32,
OsAndroid = gum_sys::_GumOS_GUM_OS_ANDROID as u32,
OsFreebsd = gum_sys::_GumOS_GUM_OS_FREEBSD as u32,
OsQnx = gum_sys::_GumOS_GUM_OS_QNX as u32,
}

pub struct Range<'a> {
/// Base address
pub base: NativePointer,
/// Size in bytes
pub size: usize,
/// Protection flag (e.g., Read, Write, Execute)
pub protection: PageProtection,
/// When available, file mapping details.
pub file: Option<FileMapping<'a>>,
}

pub struct Process<'a> {
// 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: &'a Gum,
/// Property containing the PID as a number
pub id: u32,
/// Properly specifying the current platform.
pub platform: Os,
/// Property which can be `optional` or `required`, where the latter means Frida will avoid modifying
/// existing code in memory and will not try to run unsigned code.
pub code_signing_policy: CodeSigningPolicy,
/// Contains a Module representing the main executable of the process.
pub main_module: module::ModuleDetailsOwned,
}

impl<'a> Process<'a> {
/// Initialize a new process
pub fn obtain(gum: &'a Gum) -> Process<'a> {
let id = unsafe { gum_sys::gum_process_get_id() };
let platform =
num::FromPrimitive::from_u32(unsafe { gum_sys::gum_process_get_native_os() }).unwrap();
let code_signing_policy = num::FromPrimitive::from_u32(unsafe {
gum_sys::gum_process_get_code_signing_policy() as u32
})
.unwrap();

let main_module = unsafe {
module::ModuleDetailsOwned::from_module_details(gum_sys::gum_process_get_main_module())
};

Process {
_gum: gum,
id,
platform,
code_signing_policy,
main_module,
}
}

/// Enumerates memory ranges satisfying `protection` given
pub fn enumerate_ranges(&self, protection: PageProtection) -> Vec<Range<'a>> {
struct CallbackData<'a> {
ranges: Vec<Range<'a>>,
protection: PageProtection,
}

unsafe extern "C" fn enumerate_ranges_callback(
details: *const gum_sys::GumRangeDetails,
user_data: gpointer,
) -> gboolean {
let res = &mut *(user_data as *mut CallbackData);
let r_details = RangeDetails::from_raw(details);

let prot = r_details.protection();
if res.protection == prot {
let m_range = r_details.memory_range();
let file_map = r_details.file_mapping();

res.ranges.push(Range {
base: m_range.base_address(),
size: m_range.size(),
protection: prot,
file: file_map,
});
}

1
}

let callback_data = CallbackData {
ranges: Vec::new(),
protection: protection.clone(),
};

unsafe {
gum_sys::gum_process_enumerate_ranges(
protection as u32,
Some(enumerate_ranges_callback),
&callback_data as *const _ as *mut c_void,
);
}

callback_data.ranges
}
}
4 changes: 2 additions & 2 deletions frida-gum/src/range_details.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ use {
use alloc::{boxed::Box, string::String};

/// The memory protection of an unassociated page.
#[derive(Clone, FromPrimitive, Debug)]
#[derive(Clone, FromPrimitive, Debug, PartialEq)]
#[repr(u32)]
pub enum PageProtection {
NoAccess = gum_sys::_GumPageProtection_GUM_PAGE_NO_ACCESS as u32,
Expand Down Expand Up @@ -64,7 +64,7 @@ pub struct FileMapping<'a> {
phantom: PhantomData<&'a gum_sys::GumFileMapping>,
}

impl<'a> FileMapping<'a> {
impl FileMapping<'_> {
pub(crate) fn from_raw(file: *const gum_sys::GumFileMapping) -> Option<Self> {
if file.is_null() {
None
Expand Down
2 changes: 1 addition & 1 deletion frida-gum/src/stalker/transformer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ impl<'a> Transformer<'a> {
}
}

impl<'a> Drop for Transformer<'a> {
impl Drop for Transformer<'_> {
fn drop(&mut self) {
unsafe { frida_gum_sys::g_object_unref(self.transformer as *mut c_void) }
}
Expand Down
2 changes: 1 addition & 1 deletion frida/src/device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@ impl<'a> Device<'a> {
}
}

impl<'a> Drop for Device<'a> {
impl Drop for Device<'_> {
fn drop(&mut self) {
unsafe { frida_sys::frida_unref(self.device_ptr as _) }
}
Expand Down
8 changes: 4 additions & 4 deletions frida/src/device_manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ impl<'a> DeviceManager<'a> {
return Err(Error::DeviceLookupFailed);
}

return Ok(Device::from_raw(device_ptr));
Ok(Device::from_raw(device_ptr))
}

/// Returns the remote device with the specified host.
Expand All @@ -104,7 +104,7 @@ impl<'a> DeviceManager<'a> {
return Err(Error::DeviceLookupFailed);
}

return Ok(Device::from_raw(device_ptr));
Ok(Device::from_raw(device_ptr))
}

/// Returns the local device.
Expand Down Expand Up @@ -141,11 +141,11 @@ impl<'a> DeviceManager<'a> {
return Err(Error::DeviceLookupFailed);
}

return Ok(Device::from_raw(device_ptr));
Ok(Device::from_raw(device_ptr))
}
}

impl<'a> Drop for DeviceManager<'a> {
impl Drop for DeviceManager<'_> {
fn drop(&mut self) {
unsafe {
frida_sys::frida_device_manager_close_sync(
Expand Down
6 changes: 3 additions & 3 deletions frida/src/injector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ impl<'a> Injector<'a> {
}
}

impl<'a> Default for Injector<'a> {
impl Default for Injector<'_> {
fn default() -> Self {
Self::new()
}
Expand Down Expand Up @@ -130,7 +130,7 @@ pub trait Inject {
E: AsRef<str>;
}

impl<'a> Inject for Injector<'a> {
impl Inject for Injector<'_> {
fn inject_library_file_sync<D, E, P>(
&mut self,
pid: u32,
Expand Down Expand Up @@ -228,7 +228,7 @@ impl<'a> Inject for Injector<'a> {
}
}

impl<'a> Inject for Device<'a> {
impl Inject for Device<'_> {
fn inject_library_file_sync<D, E, P>(
&mut self,
pid: u32,
Expand Down
8 changes: 4 additions & 4 deletions frida/src/process.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ impl<'a> Process<'a> {
}
}

impl<'a> Drop for Process<'a> {
impl Drop for Process<'_> {
fn drop(&mut self) {
unsafe { frida_sys::frida_unref(self.process_ptr as _) }
}
Expand All @@ -59,7 +59,7 @@ pub struct SpawnOptions<'a> {
phantom: PhantomData<&'a FridaSpawnOptions>,
}

impl<'a> SpawnOptions<'a> {
impl SpawnOptions<'_> {
pub(crate) fn from_raw(options_ptr: *mut FridaSpawnOptions) -> Self {
Self {
options_ptr,
Expand Down Expand Up @@ -159,13 +159,13 @@ impl<'a> SpawnOptions<'a> {
}
}

impl<'a> Default for SpawnOptions<'a> {
impl Default for SpawnOptions<'_> {
fn default() -> Self {
Self::new()
}
}

impl<'a> Drop for SpawnOptions<'a> {
impl Drop for SpawnOptions<'_> {
fn drop(&mut self) {
unsafe { frida_sys::frida_unref(self.options_ptr as _) }
}
Expand Down
6 changes: 3 additions & 3 deletions frida/src/script.rs
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ pub struct Exports<'a> {
phantom: PhantomData<&'a _FridaScript>,
}

impl<'a> Exports<'a> {
impl Exports<'_> {
fn inc_id(&mut self) -> usize {
let mut counter_borrow = self.rpc_id_counter.borrow_mut();
*counter_borrow += 1;
Expand Down Expand Up @@ -306,7 +306,7 @@ impl<'a> Script<'a> {
}
}

impl<'a> Exports<'a> {
impl Exports<'_> {
/// Run exported functions from a Frida script.
pub fn call(&mut self, function_name: &str, args: Option<Value>) -> Result<Option<Value>> {
let json_req: String = {
Expand Down Expand Up @@ -356,7 +356,7 @@ impl<'a> Exports<'a> {
}
}

impl<'a> Drop for Script<'a> {
impl Drop for Script<'_> {
fn drop(&mut self) {
unsafe { frida_sys::frida_unref(self.script_ptr as _) }
}
Expand Down
2 changes: 1 addition & 1 deletion frida/src/session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ impl<'a> Session<'a> {
}
}

impl<'a> Drop for Session<'a> {
impl Drop for Session<'_> {
fn drop(&mut self) {
unsafe { frida_sys::frida_unref(self.session_ptr as _) }
}
Expand Down
Loading