|
1 | 1 | //! Support for parsing MachO files |
2 | 2 |
|
3 | | -use crate::Process; |
| 3 | +use crate::{Process, Address}; |
4 | 4 |
|
5 | 5 | use core::mem; |
6 | 6 |
|
7 | | -use std::{fs::File, io::Read}; |
| 7 | +// Magic mach-o header constants from: |
| 8 | +// https://opensource.apple.com/source/xnu/xnu-4570.71.2/EXTERNAL_HEADERS/mach-o/loader.h.auto.html |
| 9 | +const MH_MAGIC_32: u32 = 0xfeedface; |
| 10 | +const MH_CIGAM_32: u32 = 0xcefaedfe; |
| 11 | +const MH_MAGIC_64: u32 = 0xfeedfacf; |
| 12 | +const MH_CIGAM_64: u32 = 0xcffaedfe; |
8 | 13 |
|
9 | 14 | struct MachOFormatOffsets { |
10 | 15 | number_of_commands: usize, |
@@ -35,20 +40,29 @@ impl MachOFormatOffsets { |
35 | 40 | } |
36 | 41 | } |
37 | 42 |
|
38 | | -/// Determines whether a MachO process is 64-bit or 32-bit |
39 | | -pub fn is_64_bit(process: &Process) -> Option<bool> { |
40 | | - // Magic mach-o header constants from: |
41 | | - // https://opensource.apple.com/source/xnu/xnu-4570.71.2/EXTERNAL_HEADERS/mach-o/loader.h.auto.html |
42 | | - const MH_MAGIC_32: u32 = 0xfeedface; |
43 | | - const MH_CIGAM_32: u32 = 0xcefaedfe; |
44 | | - const MH_MAGIC_64: u32 = 0xfeedfacf; |
45 | | - const MH_CIGAM_64: u32 = 0xcffaedfe; |
| 43 | +/// Scans the range for a page that begins with MachO Magic |
| 44 | +pub fn scan_macho_page(process: &Process, range: (Address, u64)) -> Option<Address> { |
| 45 | + const PAGE_SIZE: u64 = 0x1000; |
| 46 | + let (addr, len) = range; |
| 47 | + // negation mod PAGE_SIZE |
| 48 | + let distance_to_page = (PAGE_SIZE - (addr.value() % PAGE_SIZE)) % PAGE_SIZE; |
| 49 | + // round up to the next multiple of PAGE_SIZE |
| 50 | + let first_page = addr + distance_to_page; |
| 51 | + for i in 0..((len - distance_to_page) / PAGE_SIZE) { |
| 52 | + let a = first_page + (i * PAGE_SIZE); |
| 53 | + match process.read::<u32>(a) { |
| 54 | + Ok(MH_MAGIC_64 | MH_CIGAM_64 | MH_MAGIC_32 | MH_CIGAM_32) => { |
| 55 | + return Some(a); |
| 56 | + } |
| 57 | + _ => () |
| 58 | + } |
| 59 | + } |
| 60 | + None |
| 61 | +} |
46 | 62 |
|
47 | | - let process_path = process.get_path().ok()?; |
48 | | - let mut process_file = File::open(process_path).ok()?; |
49 | | - let mut buffer: [u8; 4] = [0; 4]; |
50 | | - process_file.read_exact(&mut buffer).ok(); |
51 | | - let magic: u32 = bytemuck::checked::try_from_bytes(&buffer).ok().cloned()?; |
| 63 | +/// Determines whether a MachO header at the address is 64-bit or 32-bit |
| 64 | +pub fn is_64_bit(process: &Process, address: Address) -> Option<bool> { |
| 65 | + let magic: u32 = process.read(address).ok()?; |
52 | 66 | match magic { |
53 | 67 | MH_MAGIC_64 | MH_CIGAM_64 => Some(true), |
54 | 68 | MH_MAGIC_32 | MH_CIGAM_32 => Some(false), |
|
0 commit comments