Test injectable DLL for windows
Signed-off-by: Dimitris Zervas <dzervas@dzervas.gr>
This commit is contained in:
parent
dafcf5d0eb
commit
21f7f06f13
45
Cargo.lock
generated
45
Cargo.lock
generated
@ -72,7 +72,7 @@ dependencies = [
|
||||
"regex",
|
||||
"rustc-hash",
|
||||
"shlex",
|
||||
"syn 2.0.51",
|
||||
"syn",
|
||||
"which",
|
||||
]
|
||||
|
||||
@ -132,16 +132,6 @@ dependencies = [
|
||||
"libloading",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "csbindgen"
|
||||
version = "1.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cf70eb656f35e0e6956cbde31c66431c53d8a546823489719099c71525767a9c"
|
||||
dependencies = [
|
||||
"regex",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ctor"
|
||||
version = "0.2.7"
|
||||
@ -149,7 +139,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ad291aa74992b9b7a7e88c38acbbf6ad7e107f1d90ee8775b7bc1fc3394f485c"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"syn 2.0.51",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -226,12 +216,10 @@ dependencies = [
|
||||
name = "frida-deepfreeze-rs"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"csbindgen",
|
||||
"ctor",
|
||||
"frida",
|
||||
"goblin",
|
||||
"lazy_static",
|
||||
"mylib",
|
||||
"pretty_assertions",
|
||||
"serde",
|
||||
"serde_json",
|
||||
@ -573,10 +561,6 @@ dependencies = [
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mylib"
|
||||
version = "0.1.0"
|
||||
|
||||
[[package]]
|
||||
name = "nom"
|
||||
version = "7.1.3"
|
||||
@ -635,7 +619,7 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.51",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -679,7 +663,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a41cf62165e97c7f814d2221421dbb9afcbcdb0a88068e5ea206e19951c2cbb5"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"syn 2.0.51",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -883,7 +867,7 @@ checksum = "7f81c2fde025af7e69b1d1420531c8a8811ca898919db177141a85313b1cb932"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.51",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -903,7 +887,7 @@ checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.51",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -972,17 +956,6 @@ version = "2.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.109"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.51"
|
||||
@ -1028,7 +1001,7 @@ checksum = "a953cb265bef375dae3de6663da4d3804eee9682ea80d8e2542529b73c531c81"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.51",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1201,7 +1174,7 @@ dependencies = [
|
||||
"once_cell",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.51",
|
||||
"syn",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
@ -1235,7 +1208,7 @@ checksum = "642f325be6301eb8107a83d12a8ac6c1e1c54345a7ef1a9261962dfefda09e66"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.51",
|
||||
"syn",
|
||||
"wasm-bindgen-backend",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
@ -12,7 +12,6 @@ path = "src/main.rs"
|
||||
|
||||
[features]
|
||||
default = ["frida"]
|
||||
dotnet = ["dep:csbindgen"]
|
||||
frida = ["dep:frida", "dep:lazy_static", "dep:serde", "dep:serde_json"]
|
||||
|
||||
[dependencies]
|
||||
@ -30,8 +29,7 @@ ctor = "0.2.7"
|
||||
|
||||
[build-dependencies]
|
||||
goblin = "0.8.0"
|
||||
csbindgen = { version = "1.9.1", optional = true}
|
||||
|
||||
[dev-dependencies]
|
||||
pretty_assertions = "1.4.0"
|
||||
mylib = { path = "tests/mylib" }
|
||||
# mylib = { path = "tests/mylib" }
|
||||
|
16
build.rs
16
build.rs
@ -2,14 +2,13 @@ use std::env;
|
||||
use std::io::Write;
|
||||
use std::fs::File;
|
||||
use std::path::Path;
|
||||
#[cfg(feature = "dotnet")]
|
||||
use csbindgen;
|
||||
|
||||
fn main() {
|
||||
println!("cargo:rerun-if-env-changed=FRIDA_CODE");
|
||||
println!("cargo:rerun-if-env-changed=DLL_PROXY");
|
||||
|
||||
let Ok(lib_path) = env::var("DLL_PROXY") else {
|
||||
println!("cargo:warning=No DLL_PROXY set, the resulting library has to be manually injected or compiled into the target binary");
|
||||
return;
|
||||
};
|
||||
|
||||
@ -72,7 +71,7 @@ fn main() {
|
||||
writeln!(symbols, "extern {{").unwrap();
|
||||
for e in exports.iter() {
|
||||
println!("cargo:warning=Exported function: {}", e);
|
||||
// writeln!(symbols, "\t#[no_mangle]").unwrap();
|
||||
writeln!(symbols, "\t#[no_mangle]").unwrap();
|
||||
writeln!(symbols, "\tpub fn {}();", e).unwrap();
|
||||
}
|
||||
writeln!(symbols, "}}").unwrap();
|
||||
@ -80,15 +79,4 @@ fn main() {
|
||||
|
||||
println!("cargo:warning=Expected library name: {}-orig.dll", lib_name);
|
||||
println!("cargo:rustc-env=LIB_NAME={}-orig.dll", lib_name);
|
||||
|
||||
#[cfg(feature = "dotnet")]
|
||||
{
|
||||
let lib_path = concat!(env!("CARGO_MANIFEST_DIR"), "/src/lib.rs");
|
||||
let csharp_file = concat!(env!("CARGO_MANIFEST_DIR"), "/dotnet/NativeMethods.g.cs");
|
||||
csbindgen::Builder::default()
|
||||
.input_extern_file(lib_path)
|
||||
.csharp_dll_name("deepfreeze")
|
||||
.generate_csharp_file(csharp_file)
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
|
@ -88,29 +88,29 @@ impl ScriptHandler for Handler {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use pretty_assertions::assert_eq;
|
||||
// #[cfg(test)]
|
||||
// mod tests {
|
||||
// use super::*;
|
||||
// use pretty_assertions::assert_eq;
|
||||
|
||||
#[link(name = "mylib", kind = "dylib")]
|
||||
extern {
|
||||
fn mylib_foo() -> u8;
|
||||
}
|
||||
// #[link(name = "mylib", kind = "dylib")]
|
||||
// extern {
|
||||
// fn mylib_foo() -> u8;
|
||||
// }
|
||||
|
||||
#[test]
|
||||
fn test_attach_pid() {
|
||||
assert_eq!(10, unsafe { mylib_foo() });
|
||||
// #[test]
|
||||
// fn test_attach_pid() {
|
||||
// assert_eq!(10, unsafe { mylib_foo() });
|
||||
|
||||
let frida_script = r#"
|
||||
const foo = Module.getExportByName(null, "mylib_foo");
|
||||
Interceptor.replace(foo, new NativeCallback(function () {
|
||||
console.log("replaced foo() called");
|
||||
return 20;
|
||||
}, "uint8", []));
|
||||
"#;
|
||||
// let frida_script = r#"
|
||||
// const foo = Module.getExportByName(null, "mylib_foo");
|
||||
// Interceptor.replace(foo, new NativeCallback(function () {
|
||||
// console.log("replaced foo() called");
|
||||
// return 20;
|
||||
// }, "uint8", []));
|
||||
// "#;
|
||||
|
||||
attach_pid(frida_script, 0);
|
||||
assert_eq!(20, unsafe { mylib_foo() });
|
||||
}
|
||||
}
|
||||
// attach_pid(frida_script, 0);
|
||||
// assert_eq!(20, unsafe { mylib_foo() });
|
||||
// }
|
||||
// }
|
||||
|
@ -1,13 +1,7 @@
|
||||
|
||||
#[cfg(all(unix, not(feature = "frida")))]
|
||||
compile_error!("Only Frida injection is supported for Unix targets");
|
||||
|
||||
#[cfg(all(not(feature = "dotnet"), not(feature = "frida")))]
|
||||
#[cfg(all(not(feature = "frida")))]
|
||||
compile_error!("No injection method is selected - please enable either dotnet (windows-only) and/or frida feature");
|
||||
|
||||
// #[cfg(all(not(windows), feature = "dotnet"))]
|
||||
// compile_error!("Managed library injection is only supported for Windows target");
|
||||
|
||||
#[cfg(feature = "frida")]
|
||||
use crate::frida_handler::attach_pid as frida_attach_pid;
|
||||
|
||||
|
90
src/lib.rs
90
src/lib.rs
@ -3,8 +3,11 @@ pub mod injector;
|
||||
pub mod frida_handler;
|
||||
// #[cfg(feature = "dotnet")]
|
||||
// pub mod cs;
|
||||
#[cfg(not(windows))]
|
||||
pub mod symbols;
|
||||
|
||||
// #[cfg(not(windows))]
|
||||
// pub mod symbols;
|
||||
// #[cfg(not(windows))]
|
||||
// pub use symbols::*;
|
||||
|
||||
pub use injector::attach_self;
|
||||
|
||||
@ -36,8 +39,10 @@ pub extern "system" fn DllMain(dll_module: *mut c_void, call_reason: u32, _: *mu
|
||||
DLL_PROCESS_ATTACH => {
|
||||
println!("[+] frida-deepfreeze-rs DLL injected");
|
||||
|
||||
unsafe { LoadLibraryA(env!("LIB_NAME").as_ptr() as *const i8); }
|
||||
println!("[+] Original DLL {} loaded", env!("LIB_NAME"));
|
||||
if let Some(lib_name) = option_env!("LIB_NAME") {
|
||||
unsafe { LoadLibraryA(lib_name.as_ptr() as *const i8); }
|
||||
println!("[+] Original DLL {} loaded", lib_name);
|
||||
}
|
||||
|
||||
attach_self();
|
||||
}
|
||||
@ -56,7 +61,7 @@ mod tests {
|
||||
use std::fs;
|
||||
|
||||
#[test]
|
||||
#[cfg(feature = "frida")]
|
||||
// #[cfg(all(unix, feature = "frida"))]
|
||||
fn test_frida_on_load() {
|
||||
let lib_status = Command::new("cargo")
|
||||
.arg("build")
|
||||
@ -71,7 +76,7 @@ mod tests {
|
||||
}, "uint8", []));
|
||||
"#)
|
||||
.status()
|
||||
.expect("Failed to build dynamic library");
|
||||
.unwrap();
|
||||
|
||||
assert!(lib_status.success(), "Failed to build dynamic library");
|
||||
|
||||
@ -88,37 +93,50 @@ mod tests {
|
||||
assert_eq!(bin_status.code().unwrap(), 40, "Failed to replace foo()");
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(all(windows, feature = "frida"))]
|
||||
fn test_frida_on_load() {
|
||||
let bin_exec = Command::new("cargo")
|
||||
.arg("build")
|
||||
.arg("--manifest-path")
|
||||
.arg("tests/mybin/Cargo.toml")
|
||||
.arg("--target-dir")
|
||||
.arg("target/test_frida_on_load");
|
||||
// #[test]
|
||||
// #[cfg(all(windows, feature = "frida"))]
|
||||
// fn test_frida_on_load() {
|
||||
// let mylib_status = Command::new("cargo")
|
||||
// .arg("build")
|
||||
// .arg("--lib")
|
||||
// .arg("--manifest-path")
|
||||
// .arg("tests/mylib/Cargo.toml")
|
||||
// .arg("--target-dir")
|
||||
// .arg("target/test_frida_on_load")
|
||||
// .status()
|
||||
// .expect("Failed to build mylib");
|
||||
// assert!(mylib_status.success(), "Failed to build mylib");
|
||||
|
||||
let lib_status = Command::new("cargo")
|
||||
.arg("build")
|
||||
.arg("--lib")
|
||||
.arg("--target-dir")
|
||||
.arg("target/test_frida_on_load")
|
||||
.env("DLL_PROXY", "target/test_frida_on_load/debug/deps/mylib.dll")
|
||||
.env("FRIDA_CODE", r#"
|
||||
const foo = Module.getExportByName(null, "mylib_foo");
|
||||
Interceptor.replace(foo, new NativeCallback(function () {
|
||||
console.log("replaced foo() called");
|
||||
return 40;
|
||||
}, "uint8", []));
|
||||
"#)
|
||||
.status()
|
||||
.expect("Failed to build dynamic library");
|
||||
// let lib_status = Command::new("cargo")
|
||||
// .arg("build")
|
||||
// .arg("--lib")
|
||||
// .arg("--target-dir")
|
||||
// .arg("target/test_frida_on_load")
|
||||
// .env("DLL_PROXY", "target/test_frida_on_load/debug/deps/mylib.dll")
|
||||
// .env("FRIDA_CODE", r#"
|
||||
// const foo = Module.getExportByName(null, "mylib_foo");
|
||||
// Interceptor.replace(foo, new NativeCallback(function () {
|
||||
// console.log("replaced foo() called");
|
||||
// return 40;
|
||||
// }, "uint8", []));
|
||||
// "#)
|
||||
// .status()
|
||||
// .expect("Failed to build dynamic library");
|
||||
|
||||
assert!(lib_status.success(), "Failed to build dynamic library");
|
||||
// assert!(lib_status.success(), "Failed to build dynamic library");
|
||||
|
||||
fs::rename("target/test_frida_on_load/debug/deps/mylib.dll", "target/test_frida_on_load/debug/mylib-orig.dll").expect("Failed to rename original DLL");
|
||||
fs::rename("target/test_frida_on_load/debug/frida_deepfreeze_rs.dll", "target/test_frida_on_load/debug/mylib.dll").expect("Failed to rename deepfreeze DLL");
|
||||
let bin_status = bin_exec.status().expect("Failed to build mybin");
|
||||
assert_eq!(bin_status.code().unwrap(), 40, "Failed to replace foo()");
|
||||
}
|
||||
// fs::rename("target/test_frida_on_load/debug/deps/mylib.dll", "target/test_frida_on_load/debug/mylib-orig.dll").expect("Failed to rename original DLL");
|
||||
// fs::rename("target/test_frida_on_load/debug/frida_deepfreeze_rs.dll", "target/test_frida_on_load/debug/mylib.dll").expect("Failed to rename deepfreeze DLL");
|
||||
|
||||
// let bin_status = Command::new("cargo")
|
||||
// .arg("run")
|
||||
// .arg("--manifest-path")
|
||||
// .arg("tests/mybin/Cargo.toml")
|
||||
// .arg("--target-dir")
|
||||
// .arg("target/test_frida_on_load")
|
||||
// .status()
|
||||
// .expect("Failed to build mybin");
|
||||
|
||||
// assert_eq!(bin_status.code().unwrap(), 40, "Failed to replace foo()");
|
||||
// }
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user