Skip to content

Instantly share code, notes, and snippets.

@leptos-null
Last active September 15, 2023 05:21
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save leptos-null/beab304b2c6b829577f9232ff2ff32d2 to your computer and use it in GitHub Desktop.
Save leptos-null/beab304b2c6b829577f9232ff2ff32d2 to your computer and use it in GitHub Desktop.
Function to get the image_vmaddr_slide of a mach_header
//
// mach_slide.c
//
// This code was based on functions from https://opensource.apple.com/source/dyld
// See the Apple Public Source License https://www.opensource.apple.com/apsl
//
// Created by Leptos on 5/11/19.
//
#include <string.h>
#include <mach-o/loader.h>
/* modified from dyld/src/ImageLoaderMachO.cpp
*
* these functions are almost identitical, so notes are here:
* the first load command immediate follows the header
* to access that location, dyld does `(char *)mh + sizeof(struct mach_header[_64])`
* to be more generic, I would write this as `(char *)mh + sizeof(*mh)`
* the other thing you can do is `mh + 1`, because it's compiled equivalent to the above line
* that's also equivalent to `&mh[1]` ("expands" to `&(*(mh + 1))` which is `mh + 1`)
* because `&mh[1]` doesn't require additional parentheses to cast, it's the one used below
*/
/// The address slide of an image for a given mach_header
intptr_t mach_header_compute_slide(struct mach_header const *const mh) {
struct segment_command const *seg = (__typeof(seg))&mh[1];
for (uint32_t cmdi = 0; cmdi < mh->ncmds; seg = (void *)seg + seg->cmdsize, cmdi++) {
if ((seg->cmd == LC_SEGMENT) && (strcmp(seg->segname, SEG_TEXT) == 0)) {
return (intptr_t)mh - seg->vmaddr;
}
}
return 0;
}
/// The address slide of an image for a given mach_header_64
intptr_t mach_header_compute_slide_64(struct mach_header_64 const *const mh) {
struct segment_command_64 const *seg = (__typeof(seg))&mh[1];
for (uint32_t cmdi = 0; cmdi < mh->ncmds; seg = (void *)seg + seg->cmdsize, cmdi++) {
if ((seg->cmd == LC_SEGMENT_64) && (strcmp(seg->segname, SEG_TEXT) == 0)) {
return (intptr_t)mh - seg->vmaddr;
}
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment