Last active
May 16, 2024 01:41
-
-
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 hidden or 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; | |
} |
@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
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.