Skip to content

Instantly share code, notes, and snippets.

@littledivy
Created August 24, 2024 06:59
Show Gist options
  • Select an option

  • Save littledivy/d95f94cb0d19079a812766cfb22ce87d to your computer and use it in GitHub Desktop.

Select an option

Save littledivy/d95f94cb0d19079a812766cfb22ce87d to your computer and use it in GitHub Desktop.

Revisions

  1. littledivy created this gist Aug 24, 2024.
    77 changes: 77 additions & 0 deletions faster-macho-find-section.patch
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,77 @@
    diff --git a/lib.rs b/lib.rs
    index aa9c0fd..0742832 100644
    --- a/lib.rs
    +++ b/lib.rs
    @@ -623,6 +623,29 @@ impl Macho {
    writer.write_all(self.linkedit_cmd.as_bytes())?;
    continue;
    }
    +
    + // Update the static in the __SUI_INTERNAL,__START segment to the address of the
    + // new section
    + const INTERNAL_START: [u8; 16] = *b"__SUI_INTERNAL\0\0";
    + if segcmd.segname[..INTERNAL_START.len()] == INTERNAL_START {
    + // Find the offset of the __SUI_INTERNAL,__START data
    + let start_offset = segcmd.fileoff as usize;
    + let start_addr = self.seg.vmaddr;
    +
    + let orig = u64::from_le_bytes(
    + self.data[start_offset..start_offset + 8]
    + .try_into()
    + .unwrap(),
    + );
    + println!("Original start address: 0x{:x}", orig);
    + println!("New start address: 0x{:x}", start_addr);
    + // Update the data at the offset
    + self.data[start_offset..start_offset + 8]
    + .copy_from_slice(&start_addr.to_le_bytes());
    + // Length of the data
    + self.data[start_offset + 8..start_offset + 16]
    + .copy_from_slice(&(self.sec.size as u64).to_le_bytes());
    + }
    }
    writer.write_all(&self.data[*offset..*offset + *cmdsize as usize])?;
    }
    @@ -665,6 +688,10 @@ mod macho {
    use std::ffi::CString;
    use std::os::raw::c_char;

    + #[link_section = "__SUI_INTERNAL,__START"]
    + #[used]
    + pub static mut START: [usize; 2] = [0, 0];
    +
    extern "C" {
    pub fn getsectdata(
    segname: *const c_char,
    @@ -680,19 +707,29 @@ mod macho {
    let section_name = CString::new(section_name).ok()?;

    unsafe {
    + let vmaddr_slide = _dyld_get_image_vmaddr_slide(0);
    + if START[0] != 0 {
    + // Add the "virtual memory address slide" amount to ensure a valid pointer
    + // in cases where the virtual memory address have been adjusted by the OS.
    + return Some(std::slice::from_raw_parts(
    + (START[0] + vmaddr_slide) as *const u8,
    + START[1],
    + ));
    + }
    +
    let mut ptr = getsectdata(
    SEGNAME.as_ptr() as *const c_char,
    section_name.as_ptr() as *const c_char,
    &mut section_size as *mut usize,
    );

    - if ptr.is_null() {
    + if ptr.is_null() || section_size == 0 {
    return None;
    }

    // Add the "virtual memory address slide" amount to ensure a valid pointer
    // in cases where the virtual memory address have been adjusted by the OS.
    - ptr = ptr.wrapping_add(_dyld_get_image_vmaddr_slide(0));
    + ptr = ptr.wrapping_add(vmaddr_slide);
    Some(std::slice::from_raw_parts(ptr as *const u8, section_size))
    }
    }