Skip to content

Instantly share code, notes, and snippets.

@littledivy
Created August 24, 2024 06:59
Show Gist options
  • Save littledivy/d95f94cb0d19079a812766cfb22ce87d to your computer and use it in GitHub Desktop.
Save littledivy/d95f94cb0d19079a812766cfb22ce87d to your computer and use it in GitHub Desktop.
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))
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment