mirror of
https://github.com/frida/frida-rust.git
synced 2026-11-09 10:09:36 -10:00
feat(session): wrap compile_script + create_script_from_bytes
frida-core has shipped a bytecode path for years: frida_session_compile_script_sync(session, source, opts) -> GBytes frida_session_create_script_from_bytes_sync(session, bytes, opts) -> FridaScript The Python and Node bindings expose both. frida-rust 0.17.2 only wraps the source-string path through `create_script`, leaving callers to either drop into frida-sys themselves or recompile on every load. This adds two thin methods on `Session`: fn compile_script(&self, source, &mut opts) -> Result<Vec<u8>> fn create_script_from_bytes<'b>(&self, bytes, &mut opts) -> Result<Script<'b>> `compile_script` copies the returned GBytes into an owned `Vec<u8>` and `g_bytes_unref`s the original. `create_script_from_bytes` wraps `g_bytes_new` / `g_bytes_unref` around the C call. Bytecode is runtime-specific — callers must compile and load with matching `ScriptOption::set_runtime`. Documented inline. Use cases this unblocks: - Startup speedup: skip the JS parse pass at every attach. - Soft script protection: ship .bin artifacts instead of readable JS. - Self-attach `compile_script` workflows so build pipelines can emit bytecode without spinning up an extra process.
This commit is contained in:
1 parent
9f72b70431
commit
6a92b72526
1 file changed
+65
-1
+65
-1
@@ -4,7 +4,7 @@
|
||||
* Licence: wxWindows Library Licence, Version 3.1
|
||||
*/
|
||||
|
||||
use frida_sys::_FridaSession;
|
||||
use frida_sys::{_FridaSession, g_bytes_get_data, g_bytes_new, g_bytes_unref, gsize};
|
||||
use std::ffi::CString;
|
||||
use std::marker::PhantomData;
|
||||
use std::ptr::null_mut;
|
||||
@@ -62,6 +62,70 @@ impl<'a> Session<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates a [`Script`] from a pre-compiled bytecode blob produced by
|
||||
/// `frida_session_compile_script_sync` (or e.g. `session.compileScript`
|
||||
/// in the Node binding).
|
||||
///
|
||||
/// Note: bytecode is runtime-specific. A blob produced with the QJS
|
||||
/// runtime won't load under V8 and vice-versa — make sure the bytecode
|
||||
/// was compiled with the same `ScriptRuntime` you pass here.
|
||||
pub fn create_script_from_bytes<'b>(
|
||||
&'a self,
|
||||
bytes: &[u8],
|
||||
option: &mut ScriptOption,
|
||||
) -> Result<Script<'b>>
|
||||
where
|
||||
'a: 'b,
|
||||
{
|
||||
let mut error: *mut frida_sys::GError = std::ptr::null_mut();
|
||||
let script = unsafe {
|
||||
let g = g_bytes_new(bytes.as_ptr() as _, bytes.len() as _);
|
||||
let s = frida_sys::frida_session_create_script_from_bytes_sync(
|
||||
self.session_ptr,
|
||||
g,
|
||||
option.as_mut_ptr(),
|
||||
null_mut(),
|
||||
&mut error,
|
||||
);
|
||||
g_bytes_unref(g);
|
||||
s
|
||||
};
|
||||
if error.is_null() {
|
||||
Ok(Script::from_raw(script))
|
||||
} else {
|
||||
Err(Error::ScriptCreationError)
|
||||
}
|
||||
}
|
||||
|
||||
/// Compile JS source to V8/QJS bytecode. Runtime is taken from `option`
|
||||
/// (default = QJS as of frida 16.x). The returned bytes can later be
|
||||
/// loaded with [`create_script_from_bytes`](Self::create_script_from_bytes).
|
||||
pub fn compile_script(&self, source: &str, option: &mut ScriptOption) -> Result<Vec<u8>> {
|
||||
let source_c = CString::new(source).map_err(|_| Error::CStringFailed)?;
|
||||
let mut error: *mut frida_sys::GError = std::ptr::null_mut();
|
||||
unsafe {
|
||||
let g = frida_sys::frida_session_compile_script_sync(
|
||||
self.session_ptr,
|
||||
source_c.as_ptr(),
|
||||
option.as_mut_ptr(),
|
||||
null_mut(),
|
||||
&mut error,
|
||||
);
|
||||
if !error.is_null() {
|
||||
return Err(Error::ScriptCreationError);
|
||||
}
|
||||
let mut len: gsize = 0;
|
||||
let raw = g_bytes_get_data(g, &mut len) as *const u8;
|
||||
let out = if raw.is_null() || len == 0 {
|
||||
Vec::new()
|
||||
} else {
|
||||
std::slice::from_raw_parts(raw, len as usize).to_vec()
|
||||
};
|
||||
g_bytes_unref(g);
|
||||
Ok(out)
|
||||
}
|
||||
}
|
||||
|
||||
/// Detaches the current session.
|
||||
pub fn detach(&self) -> Result<()> {
|
||||
let mut error: *mut frida_sys::GError = std::ptr::null_mut();
|
||||
|
||||
Reference in new issue
Block a user