Last active
September 15, 2023 05:21
-
-
Save leptos-null/beab304b2c6b829577f9232ff2ff32d2 to your computer and use it in GitHub Desktop.
Function to get the image_vmaddr_slide of a mach_header
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
// | |
// 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