Skip to content

Instantly share code, notes, and snippets.

@JackoPlane
Forked from steventroughtonsmith/main.m
Created March 24, 2016 14:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JackoPlane/486d1b37695f1cbad353 to your computer and use it in GitHub Desktop.
Save JackoPlane/486d1b37695f1cbad353 to your computer and use it in GitHub Desktop.
Load Mach-O executable at runtime and execute its entry point
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);
}
@gordidon
Copy link

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

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