Skip to content

Commit

Permalink
Mac std attach Module
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexKnauth committed Oct 16, 2023
1 parent bfb7471 commit a17517d
Showing 1 changed file with 49 additions and 2 deletions.
51 changes: 49 additions & 2 deletions src/game_engine/unity/mono.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,19 @@ impl Module {
/// correct for this function to work. If you don't know the version in
/// advance, use [`attach_auto_detect`](Self::attach_auto_detect) instead.
pub fn attach(process: &Process, version: Version) -> Option<Self> {
let module = ["mono.dll", "mono-2.0-bdwgc.dll"]
if let Some(module) = ["mono.dll", "mono-2.0-bdwgc.dll"]
.iter()
.find_map(|&name| process.get_module_address(name).ok())?;
.find_map(|&name| process.get_module_address(name).ok()) {
return Self::attach_dll(process, version, module);
}
#[cfg(feature = "std")]
if let Ok(module_range) = process.get_module_range("libmonobdwgc-2.0.dylib") {
return Self::attach_dylib(process, version, module_range);
}
None
}

fn attach_dll(process: &Process, version: Version, module: Address) -> Option<Self> {
let is_64_bit = pe::MachineType::read(process, module)? == pe::MachineType::X86_64;
let offsets = Offsets::new(version, is_64_bit, BinaryFormat::PE);

Expand Down Expand Up @@ -101,6 +110,44 @@ impl Module {
}
}

#[cfg(feature = "std")]
fn attach_dylib(process: &Process, version: Version, module_range: (Address, u64)) -> Option<Self> {
let is_64_bit = macho::is_64_bit(process, macho::scan_macho_page(process, module_range)?)?;
let offsets = Offsets::new(version, is_64_bit, BinaryFormat::MachO);

let process_path = process.get_path().ok()?;
let contents_path = Path::new(&process_path).parent()?.parent()?;
let mono_module_path = contents_path.join("Frameworks").join("libmonobdwgc-2.0.dylib");
let mono_module_bytes = file_read_all_bytes(mono_module_path).ok()?;

let mono_assembly_foreach_offset: u32 = macho::get_function_offset(&mono_module_bytes, b"_mono_assembly_foreach")?;

let function_array: [u8; 0x100] = macho::slice_read(&mono_module_bytes, mono_assembly_foreach_offset as usize).ok()?;
let sig_function_array: Signature<0x100> = Signature::Simple(function_array);
let mono_assembly_foreach_address = sig_function_array.scan_process_range(process, module_range)?;

let assemblies: Address = match is_64_bit {
true => {
const SIG_MONO_64_DYLIB: Signature<3> = Signature::new("48 8B 3D");
// RIP-relative addressing
// 3 is the offset to the next thing after the signature
let scan_address = SIG_MONO_64_DYLIB.scan_process_range(process, (mono_assembly_foreach_address, 0x100))? + 3;
// 4 is the offset to the next instruction after relative
scan_address + 0x4 + process.read::<i32>(scan_address).ok()?
}
false => {
return None;
}
};

Some(Self {
is_64_bit,
version,
offsets,
assemblies,
})
}

fn assemblies<'a>(&'a self, process: &'a Process) -> impl Iterator<Item = Assembly> + 'a {
let mut assembly = self.assemblies;
let mut iter_break = assembly.is_null();
Expand Down

0 comments on commit a17517d

Please sign in to comment.