Created
August 24, 2024 06:59
-
-
Save littledivy/d95f94cb0d19079a812766cfb22ce87d to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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