-
-
Save JackoPlane/486d1b37695f1cbad353 to your computer and use it in GitHub Desktop.
Load Mach-O executable at runtime and execute its entry point
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
void callEntryPointOfImage(char *path, int argc, char **argv) | |
{ | |
void *handle; | |
int (*binary_main)(int binary_argc, char **binary_argv); | |
char *error; | |
int err = 0; | |
printf("Loading %s…\n", path); | |
handle = dlopen (path, RTLD_LAZY); | |
if (!handle) { | |
fputs (dlerror(), stderr); | |
err = 1; | |
} | |
uint64_t entryoff = 0; | |
/* Find LC_MAIN, entryoff */ | |
uint32_t count = _dyld_image_count(); | |
BOOL didFind = NO; | |
for(uint32_t i = 0; i < count; i++) | |
{ | |
//Name of image (includes full path) | |
const char *dyld = _dyld_get_image_name(i); | |
if (strcmp(dyld, path) == 0) | |
{ | |
didFind = YES; | |
const struct mach_header *header = (struct mach_header *)_dyld_get_image_header(i); | |
if (header->magic == MH_MAGIC_64) | |
{ | |
printf("MH_MAGIC_64\n"); | |
const struct mach_header_64 *header64 = (struct mach_header_64 *)_dyld_get_image_header(i); | |
uint8_t *imageHeaderPtr = (uint8_t*)header64; | |
typedef struct load_command load_command; | |
imageHeaderPtr += sizeof(struct mach_header_64); | |
load_command *command = (load_command*)imageHeaderPtr; | |
for(int i = 0; i < header->ncmds > 0; ++i) | |
{ | |
if(command->cmd == LC_MAIN) | |
{ | |
struct entry_point_command ucmd = *(struct entry_point_command*)imageHeaderPtr; | |
entryoff = ucmd.entryoff; | |
printf("LC_MAIN EntryPoint offset: 0x%llX\n", entryoff); | |
didFind = YES; | |
break; | |
} | |
imageHeaderPtr += command->cmdsize; | |
command = (load_command*)imageHeaderPtr; | |
} | |
} | |
else | |
{ | |
printf("MH_MAGIC\n"); | |
const struct mach_header *header = (struct mach_header *)_dyld_get_image_header(i); | |
uint8_t *imageHeaderPtr = (uint8_t*)header; | |
typedef struct load_command load_command; | |
imageHeaderPtr += sizeof(struct mach_header); | |
load_command *command = (load_command*)imageHeaderPtr; | |
for(int i = 0; i < header->ncmds > 0; ++i) | |
{ | |
if(command->cmd == LC_MAIN) | |
{ | |
struct entry_point_command ucmd = *(struct entry_point_command*)imageHeaderPtr; | |
entryoff = ucmd.entryoff; | |
printf("LC_MAIN EntryPoint offset: 0x%llX\n", entryoff); | |
didFind = YES; | |
break; | |
} | |
imageHeaderPtr += command->cmdsize; | |
command = (load_command*)imageHeaderPtr; | |
} | |
} | |
printf("Found %s\n", dyld); | |
if (didFind) | |
{ | |
break; | |
} | |
} | |
} | |
if (didFind) | |
{ | |
binary_main = dlsym(handle, "_mh_execute_header")+entryoff; | |
if ((error = dlerror()) != NULL) { | |
fputs(error, stderr); | |
err = 1; | |
} | |
if (err == 0) | |
{ | |
printf ("exit(%i)\n", (*binary_main)(argc, argv)); | |
dlclose(handle); | |
} | |
} | |
else | |
{ | |
printf("\nDidn't find image to load.\n\n"); | |
} | |
} | |
int main(int argc, char * argv[]) { | |
callEntryPointOfImage("/System/Library/PrivateFrameworks/PrintKit.framework/printd", argc, argv); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Greetings,
I was trying to compile it in Xcode for me to run it in my iPad but it has not work for me. I have a free developer account, I thought I could use it for this. Please Advice.
Best Regards