Fix frida_code_file, initial config support
Signed-off-by: Dimitris Zervas <dzervas@dzervas.gr>
This commit is contained in:
parent
7f9a223c61
commit
b6a48d5155
75
Cargo.lock
generated
75
Cargo.lock
generated
@ -160,6 +160,12 @@ version = "1.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a"
|
||||
|
||||
[[package]]
|
||||
name = "equivalent"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
|
||||
|
||||
[[package]]
|
||||
name = "errno"
|
||||
version = "0.3.8"
|
||||
@ -231,6 +237,7 @@ dependencies = [
|
||||
"pretty_assertions",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"toml",
|
||||
"winapi",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
@ -329,6 +336,12 @@ dependencies = [
|
||||
"scroll",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.14.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604"
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.3.8"
|
||||
@ -450,6 +463,16 @@ dependencies = [
|
||||
"unicode-normalization",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "2.2.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26"
|
||||
dependencies = [
|
||||
"equivalent",
|
||||
"hashbrown",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ipnet"
|
||||
version = "2.9.0"
|
||||
@ -913,6 +936,15 @@ dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_spanned"
|
||||
version = "0.6.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eb3622f419d1296904700073ea6cc23ad690adbd66f13ea683df73298736f0c1"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_urlencoded"
|
||||
version = "0.7.1"
|
||||
@ -1058,6 +1090,40 @@ dependencies = [
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml"
|
||||
version = "0.8.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e9dd1545e8208b4a5af1aa9bbd0b4cf7e9ea08fabc5d0a5c67fcaafa17433aa3"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"serde_spanned",
|
||||
"toml_datetime",
|
||||
"toml_edit",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml_datetime"
|
||||
version = "0.6.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml_edit"
|
||||
version = "0.22.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8e40bb779c5187258fd7aad0eb68cb8706a0a81fa712fbea808ab43c4b8374c4"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"serde",
|
||||
"serde_spanned",
|
||||
"toml_datetime",
|
||||
"winnow",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tower"
|
||||
version = "0.4.13"
|
||||
@ -1416,6 +1482,15 @@ version = "0.52.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0770833d60a970638e989b3fa9fd2bb1aaadcf88963d1659fd7d9990196ed2d6"
|
||||
|
||||
[[package]]
|
||||
name = "winnow"
|
||||
version = "0.6.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f0c976aaaa0e1f90dbb21e9587cdaf1d9679a1cde8875c0d6bd83ab96a208352"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winreg"
|
||||
version = "0.50.0"
|
||||
|
@ -30,6 +30,8 @@ ctor = "0.2.7"
|
||||
[build-dependencies]
|
||||
goblin = "0.8.0"
|
||||
build-target = "0.4"
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
toml = "0.8.12"
|
||||
|
||||
[dev-dependencies]
|
||||
pretty_assertions = "1.4.0"
|
||||
|
92
build.rs
92
build.rs
@ -1,26 +1,79 @@
|
||||
use serde::Deserialize;
|
||||
|
||||
use std::env;
|
||||
use std::path::Path;
|
||||
|
||||
fn main() {
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct Hook {
|
||||
pub name: String,
|
||||
pub args: Vec<String>,
|
||||
pub ret: String,
|
||||
pub code: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct Config {
|
||||
pub dll_proxy: Option<String>,
|
||||
pub frida_code: Option<String>,
|
||||
pub frida_code_file: Option<String>,
|
||||
pub target_exec: Option<String>,
|
||||
pub target_process: Option<String>,
|
||||
|
||||
pub hooks: Vec<Hook>,
|
||||
}
|
||||
|
||||
impl Default for Config {
|
||||
fn default() -> Self {
|
||||
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");
|
||||
println!("cargo:rerun-if-env-changed=TARGET_PROCESS");
|
||||
println!("cargo:rerun-if-env-changed=TARGET_SPAWN");
|
||||
|
||||
if env::var("FRIDA_CODE").is_err() && env::var("FRIDA_CODE_FILE").is_err() {
|
||||
panic!("No FRIDA_CODE or FRIDA_CODE_FILE set. Please set one of them.");
|
||||
Self {
|
||||
dll_proxy : env::var("DLL_PROXY").ok(),
|
||||
frida_code : env::var("FRIDA_CODE").ok(),
|
||||
frida_code_file: env::var("FRIDA_CODE_FILE").ok(),
|
||||
target_exec : env::var("TARGET_SPAWN").ok(),
|
||||
target_process : env::var("TARGET_PROCESS").ok(),
|
||||
|
||||
hooks: Vec::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if env::var("FRIDA_CODE").is_ok() && env::var("FRIDA_CODE_FILE").is_ok() {
|
||||
panic!("Both FRIDA_CODE and FRIDA_CODE_FILE set. Please set one of them.");
|
||||
impl Config {
|
||||
pub fn get_frida_code(&self) -> String {
|
||||
if self.frida_code.is_some() && self.frida_code_file.is_some() {
|
||||
panic!("Both frida_code and frida_code_file set. Please set one of them.");
|
||||
}
|
||||
|
||||
if let Ok(frida_code_file) = env::var("FRIDA_CODE_FILE") {
|
||||
let frida_code = std::fs::read_to_string(frida_code_file).expect("Failed to read FRIDA_CODE_FILE");
|
||||
println!("cargo:rustc-env=FRIDA_CODE={}", frida_code);
|
||||
let code = if let Some(frida_code) = &self.frida_code {
|
||||
frida_code.clone()
|
||||
} else if let Some(frida_code_file) = &self.frida_code_file {
|
||||
std::fs::read_to_string(frida_code_file).expect("Failed to read frida_code_file")
|
||||
} else {
|
||||
panic!("No frida_code or frida_code_file set. Please set one of them.");
|
||||
};
|
||||
|
||||
code.replace("\n", "\\n")
|
||||
}
|
||||
}
|
||||
|
||||
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/process");
|
||||
fn main() {
|
||||
println!("cargo:rerun-if-env-changed=CONFIG_FILE");
|
||||
|
||||
let config = if let Ok(config_file) = env::var("CONFIG_FILE") {
|
||||
let config_file = std::fs::read_to_string(config_file).expect("Failed to read CONFIG_FILE");
|
||||
toml::from_str::<Config>(&config_file).expect("Failed to parse CONFIG_FILE")
|
||||
} else {
|
||||
Config::default()
|
||||
};
|
||||
|
||||
println!(r#"cargo:rustc-env=FRIDA_CODE={}"#, config.get_frida_code());
|
||||
|
||||
let Some(lib_path) = config.dll_proxy else {
|
||||
println!("cargo:warning=No dll_proxy set, the resulting library has to be manually injected or compiled into the target binary/process");
|
||||
return;
|
||||
};
|
||||
|
||||
@ -28,14 +81,19 @@ fn main() {
|
||||
panic!("Dll proxying mode is only supported on Windows.");
|
||||
}
|
||||
|
||||
dll_proxy_linker_flags(&lib_path, config.hooks);
|
||||
}
|
||||
|
||||
fn dll_proxy_linker_flags(lib_path: &str, _hooks: Vec<Hook>) {
|
||||
use goblin::Object;
|
||||
println!("cargo:rerun-if-changed={}", &lib_path);
|
||||
|
||||
println!("cargo:rerun-if-changed={lib_path}");
|
||||
|
||||
let path = Path::new(&lib_path);
|
||||
let lib_filename = path.file_name().unwrap().to_str().unwrap();
|
||||
|
||||
let lib_bytes = std::fs::read(path).expect(format!("Failed to open given library file {}", &lib_filename).as_str());
|
||||
let object = Object::parse(&lib_bytes).expect(format!("Failed to parse given libary file {}", &lib_filename).as_str());
|
||||
let lib_bytes = std::fs::read(path).expect(format!("Failed to open given library file {lib_filename}").as_str());
|
||||
let object = Object::parse(&lib_bytes).expect(format!("Failed to parse given libary file {lib_filename}").as_str());
|
||||
|
||||
let Object::PE(pe) = object else {
|
||||
panic!("Only PE (.dll) files are supported in this mode.");
|
||||
@ -45,10 +103,10 @@ fn main() {
|
||||
let lib_name = pe.name.expect("Couldn't read the name of the DLL. Is it a .NET DLL? It's not supported").replace(".dll", "");
|
||||
|
||||
for e in exports.iter() {
|
||||
println!("cargo:warning=Exported function: {} => {}-orig.{}", e, lib_name, e);
|
||||
println!("cargo:rustc-link-arg=/export:{}={}-orig.{}", e, lib_name, e);
|
||||
println!("cargo:warning=Exported function: {e} => {lib_name}-orig.{e}");
|
||||
println!("cargo:rustc-link-arg=/export:{e}={lib_name}-orig.{e}");
|
||||
}
|
||||
|
||||
println!("cargo:warning=Expected library name: {}-orig.dll", lib_name);
|
||||
println!("cargo:rustc-env=LIB_NAME={}-orig.dll", lib_name);
|
||||
println!("cargo:warning=Expected library name: {lib_name}-orig.dll");
|
||||
println!("cargo:rustc-env=LIB_NAME={lib_name}-orig.dll");
|
||||
}
|
||||
|
@ -1,48 +0,0 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.0.31903.59
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MyClass", "My\MyClass.csproj", "{F480EEA9-B211-4BDF-A364-8B8D1B6F4FCE}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OtherClass", "Other\OtherClass.csproj", "{EAA4714F-3F2E-4801-81B7-9BC502347B53}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Debug|x64 = Debug|x64
|
||||
Debug|x86 = Debug|x86
|
||||
Release|Any CPU = Release|Any CPU
|
||||
Release|x64 = Release|x64
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{F480EEA9-B211-4BDF-A364-8B8D1B6F4FCE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{F480EEA9-B211-4BDF-A364-8B8D1B6F4FCE}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{F480EEA9-B211-4BDF-A364-8B8D1B6F4FCE}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{F480EEA9-B211-4BDF-A364-8B8D1B6F4FCE}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{F480EEA9-B211-4BDF-A364-8B8D1B6F4FCE}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{F480EEA9-B211-4BDF-A364-8B8D1B6F4FCE}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{F480EEA9-B211-4BDF-A364-8B8D1B6F4FCE}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{F480EEA9-B211-4BDF-A364-8B8D1B6F4FCE}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{F480EEA9-B211-4BDF-A364-8B8D1B6F4FCE}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{F480EEA9-B211-4BDF-A364-8B8D1B6F4FCE}.Release|x64.Build.0 = Release|Any CPU
|
||||
{F480EEA9-B211-4BDF-A364-8B8D1B6F4FCE}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{F480EEA9-B211-4BDF-A364-8B8D1B6F4FCE}.Release|x86.Build.0 = Release|Any CPU
|
||||
{EAA4714F-3F2E-4801-81B7-9BC502347B53}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{EAA4714F-3F2E-4801-81B7-9BC502347B53}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{EAA4714F-3F2E-4801-81B7-9BC502347B53}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{EAA4714F-3F2E-4801-81B7-9BC502347B53}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{EAA4714F-3F2E-4801-81B7-9BC502347B53}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{EAA4714F-3F2E-4801-81B7-9BC502347B53}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{EAA4714F-3F2E-4801-81B7-9BC502347B53}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{EAA4714F-3F2E-4801-81B7-9BC502347B53}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{EAA4714F-3F2E-4801-81B7-9BC502347B53}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{EAA4714F-3F2E-4801-81B7-9BC502347B53}.Release|x64.Build.0 = Release|Any CPU
|
||||
{EAA4714F-3F2E-4801-81B7-9BC502347B53}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{EAA4714F-3F2E-4801-81B7-9BC502347B53}.Release|x86.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
EndGlobal
|
@ -1,19 +0,0 @@
|
||||
using System;
|
||||
using OtherNamespace;
|
||||
|
||||
namespace MyNamespace {
|
||||
public class MyClass {
|
||||
// This method will be called by native code inside the target process…
|
||||
public static int MyMethod(String pwzArgument) {
|
||||
System.Console.WriteLine("Hello World from C# {0}", pwzArgument);
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static void Main() {
|
||||
int my = MyMethod("from Main()");
|
||||
System.Console.WriteLine("MyMethod returned {0}", my);
|
||||
int other = OtherNamespace.OtherClass.OtherMethod();
|
||||
System.Console.WriteLine("OtherMethod returned {0}", other);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,10 +0,0 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<OutputType>Exe</OutputType>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Other\OtherClass.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
@ -1,11 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace OtherNamespace {
|
||||
public class OtherClass {
|
||||
// This method will be called by native code inside the target process…
|
||||
public static int OtherMethod() {
|
||||
System.Console.WriteLine("Goodbye World from C#");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<OutputType>Library</OutputType>
|
||||
<RootNamespace>OtherNamespace</RootNamespace>
|
||||
</PropertyGroup>
|
||||
</Project>
|
@ -1,17 +0,0 @@
|
||||
# C# Example
|
||||
|
||||
To compile:
|
||||
|
||||
```sh
|
||||
sudo pacman -S dotnet-host dotnet-runtime dotnet-sdk
|
||||
dotnet build
|
||||
```
|
||||
|
||||
To run:
|
||||
|
||||
```sh
|
||||
./My/bin/Debug/net8.0/MyClass
|
||||
# or
|
||||
sudo pacman -S mono
|
||||
mono My/bin/Debug/net8.0/MyClass.dll
|
||||
```
|
@ -9,11 +9,11 @@ use crate::frida_handler::attach_pid as frida_attach_pid;
|
||||
pub extern "C" fn attach(pid: u32) {
|
||||
#[cfg(feature = "frida")]
|
||||
{
|
||||
let frida_code = env!("FRIDA_CODE");
|
||||
let frida_code = env!("FRIDA_CODE").replace("\\n", "\n");
|
||||
#[cfg(windows)]
|
||||
std::thread::spawn(move || frida_attach_pid(frida_code, pid));
|
||||
std::thread::spawn(move || frida_attach_pid(&frida_code, pid));
|
||||
#[cfg(not(windows))]
|
||||
frida_attach_pid(frida_code, pid);
|
||||
frida_attach_pid(&frida_code, pid);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user