diff --git a/Cargo.lock b/Cargo.lock index 2013139..aac3692 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -226,6 +226,7 @@ dependencies = [ "frida", "goblin", "lazy_static", + "winapi", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index d24e5da..6e0bfa4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,15 +12,12 @@ path = "src/main.rs" [dependencies] # frida = { version = "0.4.0", features = ["auto-download"] } -# frida-sys = { version = "0.4.0", features = ["auto-download", "frida-build"] } frida = { git = "https://github.com/dzervas/frida-rust", features = ["auto-download"] } -# frida-sys = { git = "https://github.com/frida/frida-rust", features = ["auto-download"] } lazy_static = "1.4.0" ctor = "0.2.0" -# [target.'cfg(unix)'.build-dependencies] +[target.'cfg(windows)'.dependencies] +winapi = { version = "0.3.9", features = ["winnt"] } -# [target.'cfg(windows)'.build-dependencies] -# pelite = "0.10.0" [build-dependencies] goblin = "0.6.1" diff --git a/build.rs b/build.rs index cfc8e46..79680b2 100644 --- a/build.rs +++ b/build.rs @@ -2,20 +2,10 @@ use std::env; fn main() { println!("cargo:rerun-if-env-changed=FRIDA_CODE"); - println!("cargo:rerun-if-env-changed=FRIDA_CODE_FILE"); println!("cargo:rerun-if-env-changed=DLL_PROXY"); - if let Ok(code_file) = env::var("FRIDA_CODE_FILE") { - env::set_var("FRIDA_CODE", &std::fs::read_to_string(&code_file).unwrap()); - println!("cargo:warning=Using code from file: {}", &code_file); - } else if env::var("FRIDA_CODE").is_ok() { - println!("cargo:warning=Using code from environment variable: FRIDA_CODE"); - } else { - println!("Please set FRIDA_CODE or FRIDA_CODE_FILE environment variable"); - std::process::exit(1); - } - if let Ok(lib_path) = env::var("DLL_PROXY") { + println!("cargo:rerun-if-changed={}", &lib_path); use goblin::Object::{self, PE}; let path = std::path::Path::new(&lib_path); @@ -38,9 +28,9 @@ fn main() { }; for e in exports.iter() { - println!("cargo:warning=Exported function: {}", e); - // println!("cargo:rustc-link-lib=dylib={}-orig", lib_name); + // println!("cargo:warning=Exported function: {} => {}-orig.{}", e, lib_name, e); println!("cargo:rustc-link-arg=/export:{}={}-orig.{}", e, lib_name, e); + // println!("cargo:rustc-link-lib=dylib={}-orig", lib_name); } println!("cargo:warning=Expected library name: {}-orig.dll", lib_name); } diff --git a/src/injector.rs b/src/injector.rs index ff12171..bc4eb5b 100644 --- a/src/injector.rs +++ b/src/injector.rs @@ -5,51 +5,55 @@ lazy_static! { static ref FRIDA: Frida = unsafe { Frida::obtain() }; } -const FRIDA_CODE: &str = env!("FRIDA_CODE", "Please set FRIDA_CODE environment variable"); - #[no_mangle] -pub fn inject(pid: u32) { - let device_manager = DeviceManager::obtain(&FRIDA); +pub fn attach(pid: u32) { + let frida_code = env!("FRIDA_CODE").to_string(); + println!("[*] Injecting into PID: {}", pid); - if let Some(device) = device_manager.enumerate_all_devices().first() { - println!("[*] First device: {}", device.get_name()); + std::thread::spawn(move || { + let device_manager = DeviceManager::obtain(&FRIDA); + println!("[*] Device Manager obtained"); - let session = device.attach(pid).unwrap(); + if let Some(device) = device_manager.enumerate_all_devices().first() { + println!("[*] First device: {}", device.get_name()); - if !session.is_detached() { - println!("[*] Attached"); + let session = device.attach(pid).unwrap(); - let mut script_option = ScriptOption::new() - // .set_name("frida-deepfreeze-rs") - .set_runtime(ScriptRuntime::QJS); - let script = session - .create_script(FRIDA_CODE, &mut script_option) - .unwrap(); + if !session.is_detached() { + println!("[*] Attached"); - script.handle_message(&mut Handler).unwrap(); + let mut script_option = ScriptOption::new() + .set_name("frida-deepfreeze-rs") + .set_runtime(ScriptRuntime::QJS); + println!("[*] Script {}", frida_code); + let script = session + .create_script(&frida_code, &mut script_option) + .unwrap(); - script.load().unwrap(); - println!("[*] Script loaded"); + script.handle_message(&mut Handler).unwrap(); - script.unload().unwrap(); - println!("[*] Script unloaded"); - - session.detach().unwrap(); - println!("[*] Session detached"); - } - }; + script.load().unwrap(); + println!("[*] Script loaded"); + } + } else { + println!("[!] No device found!"); + }; + }); } #[no_mangle] -pub fn inject_self() { - println!("[*] Attaching to self (pid 0)"); - inject(0); +pub fn attach_self() { + println!("[*] Attaching to self"); + // #[cfg(windows)] + // attach(std::process::id()); + // #[cfg(unix)] + attach(0); } struct Handler; impl ScriptHandler for Handler { fn on_message(&mut self, message: &str) { - println!("[<] {message}"); + eprintln!("[<] {message}"); } } diff --git a/src/lib.rs b/src/lib.rs index d21dc4c..49e07d1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,11 +1,38 @@ pub mod injector; -pub use injector::{inject, inject_self}; +pub use injector::{attach, attach_self}; +#[cfg(unix)] use ctor::ctor; +#[cfg(unix)] #[ctor] fn _start() { - println!("[+] frida-deepfreeze-rs SO injected"); - inject_self(); + println!("[+] frida-deepfreeze-rs library injected"); + attach_self(); +} + +// For some reason ctor doesn't work on Windows - it hangs the process +// during DeviceManager::obtain. DllMain works fine though. +#[cfg(windows)] +use std::ffi::c_void; + +#[cfg(windows)] +use winapi::um::winnt::DLL_PROCESS_ATTACH; + +#[cfg(windows)] +#[no_mangle] +#[allow(non_snake_case, unused_variables)] +extern "system" fn DllMain(dll_module: *mut c_void, call_reason: u32, _: *mut ()) -> bool { + match call_reason { + DLL_PROCESS_ATTACH => { + println!("[+] frida-deepfreeze-rs DLL injected"); + attach_self(); + + } + // Maybe we should detach? Is it useful? + _ => () + } + + true } diff --git a/src/main.rs b/src/main.rs index b1c72b8..cc7c6c8 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,5 @@ pub mod injector; -pub use injector::inject; +pub use injector::attach; fn main() { let args: Vec = std::env::args().collect(); @@ -10,5 +10,5 @@ fn main() { } let pid: u32 = args[1].parse().unwrap(); - inject(pid); + attach(pid); }