Skip to main content

frida_rs/
process.rs

1//!Frida functions for process-level functionality.
2//!
3//!The functions in this module correspond to the JavaScript functions
4//!grouped under
5//![https://frida.re/docs/javascript-api/#process](https://frida.re/docs/javascript-api/#process).
6
7use crate::module;
8use crate::nativepointer;
9use crate::plumbing;
10use crate::range::RangeDetails;
11use crate::thread;
12
13///Get the PID of the instrumented process.
14///
15///This is equivalent to calling `Process.id` in the JavaScript API.
16pub fn get_pid() -> u32 {
17    *plumbing::process::id
18}
19
20///Get the architecture of the instrumented process.
21///
22///This is equivalent to calling `Process.arch` in the JavaScript API.
23pub fn get_arch() -> &'static str {
24    &*plumbing::process::arch
25}
26
27///Get the platform of the instrumented process.
28///
29///This is equivalent to calling `Process.platform` in the JavaScript API.
30pub fn get_platform() -> &'static str {
31    &*plumbing::process::platform
32}
33
34///Get the page size of the instrumented process.
35///
36///This is equivalent to calling `Process.pageSize` in the JavaScript API.
37pub fn get_page_size() -> usize {
38    *plumbing::process::page_size
39}
40
41///Get the pointer size of the instrumented process.
42///
43///This is equivalent to calling `Process.pointerSize` in the JavaScript API.
44pub fn get_pointer_size() -> usize {
45    *plumbing::process::pointer_size
46}
47
48///Get the code signing policy of the instrumented process.
49///
50///This is equivalent to calling `Process.codeSigningPolicy` in the JavaScript
51///API.
52pub fn get_code_signing_policy() -> &'static str {
53    &*plumbing::process::code_signing_policy
54}
55
56///Check if a debugger is attached to the instrumented process.
57///
58///This is equivalent to calling `Process.isDebuggerAttached()` in the
59///JavaScript API.
60pub fn is_debugger_attached() -> bool {
61    plumbing::process::is_debugger_attached()
62}
63
64///Get the TID of the current thread.
65///
66///This is equivalent to calling `Process.getCurrentThreadId()` in the
67///JavaScript API.
68pub fn get_tid() -> u32 {
69    plumbing::process::get_current_thread_id()
70}
71
72///Get all threads in the instrumented process.
73///
74///This is the equivalent to calling `Process.enumerateThreads()` in the
75///JavaScript API.
76pub fn enumerate_threads() -> Vec<thread::ThreadDetails> {
77    let threads = plumbing::process::enumerate_threads();
78    let mut thread_details = Vec::new();
79
80    for thread in threads.iter() {
81        let td = thread::ThreadDetails::from(plumbing::thread::ThreadDetails::from(thread));
82        thread_details.push(td);
83    }
84
85    thread_details
86}
87
88///Get all loaded modules in the instrumented process.
89///
90///This is the equivalent to calling `Process.enumerateModules()` in the
91///JavaScript API.
92pub fn enumerate_modules() -> Vec<module::Module> {
93    let modules = plumbing::process::enumerate_modules();
94    let mut m = Vec::new();
95
96    for module in modules.iter() {
97        let md = module::Module::from(plumbing::module::Module::from(module));
98        m.push(md);
99    }
100
101    m
102}
103
104///Get a module by name.
105///
106///This is the equivalent to calling `Process.findModuleByName()` /
107///`Process.getModuleByName()` in the JavaScript API.
108pub fn get_module_by_name(name: &str) -> Option<module::Module> {
109    let ret = plumbing::process::get_module_by_name(name);
110
111    if ret.is_null() {
112        return None;
113    }
114
115    Some(module::Module::from(ret))
116}
117
118///Get a module by address.
119///
120///This is the equivalent to calling `Process.findModuleByAddress()` /
121///`Process.getModuleByAddress()` in the JavaScript API.
122pub fn get_module_by_address(address: &nativepointer::NativePointer) -> Option<module::Module> {
123    let ret = plumbing::process::get_module_by_address(&address);
124
125    if ret.is_null() {
126        return None;
127    }
128
129    Some(module::Module::from(ret))
130}
131
132///Get memory range containing `address`.
133///
134///This is the equivalent to calling `Process.findRangeByAddress()` /
135///`Process.getRangeByAddress()` in the JavaScript API.
136pub fn get_range_by_address(address: &nativepointer::NativePointer) -> Option<RangeDetails> {
137    let ret = plumbing::process::get_range_by_address(&address);
138
139    if ret.is_null() {
140        return None;
141    }
142
143    Some(RangeDetails::from(plumbing::range::RangeDetails::from(ret)))
144}
145
146///Get all memory ranges satisfying `protection`.
147///
148///`protection` is a string with the form "rwx" where "rw-" means "must be
149///at least readable and writable."
150///
151///This is the equivalent to calling `Process.enumerateRanges()` in the
152///JavaScript API.
153pub fn enumerate_ranges(protection: &str) -> Vec<RangeDetails> {
154    let mut range_details = Vec::new();
155
156    let ranges = plumbing::process::enumerate_ranges(protection);
157
158    for range in ranges.iter() {
159        let i = RangeDetails::from(plumbing::range::RangeDetails::from(range));
160        range_details.push(i);
161    }
162
163    range_details
164}
165
166///Get all individual memory allocations known to the system heap.
167///
168///This is the equivalent to calling `Process.enumerateMallocRanges()` in the
169///JavaScript API.
170pub fn enumerate_malloc_ranges() -> Vec<RangeDetails> {
171    let mut range_details = Vec::new();
172
173    let ranges = plumbing::process::enumerate_malloc_ranges();
174
175    for range in ranges.iter() {
176        let i = RangeDetails::from(plumbing::range::RangeDetails::from(range));
177        range_details.push(i);
178    }
179
180    range_details
181}