Skip to content

Instantly share code, notes, and snippets.

@leptos-null
Last active May 16, 2024 01:41
Show Gist options
  • 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;
}
@andrep
Copy link

andrep commented May 15, 2024

I'd love to use this code snippet in something I'm working on - would you be okay with explicitly putting this under an open-source license, such as the Simplified BSD license? https://opensource.org/license/BSD-2-Clause

Also, I think it's better for void* on lines 27 and 38 to char* (for pointer arithmetic). void* is technically illegal, even though it's widely supported by all compilers.

@leptos-null
Copy link
Author

@andrep thanks for your interest in the project.
Because this is based on Apple's dyld, I appear to have licensed this code (at the top of the file) using the same license as that project: Apple Public Source License.

See sections 2.1 and 2.2 for the conditions that should be relevant to you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment