I have 2 MH_EXECUTE iOS binary files (compiled, no source code).
Lets name them binary1
and binary2
.
I try to switch between them before UIApplicationMain
is called!
I successfully do this with binary1
and one dylib
. So I try to convert MH_EXECUTE to MH_DYLIB.
step 1
creating iOS Application binary1
#import <dlfcn.h>
int main(int argc, char * argv[])
{
NSLog(@"binary1 -> Hello, World!");
void *handle = dlopen([[[NSBundle mainBundle] pathForResource:@"binary2" ofType:nil] cStringUsingEncoding:NSUTF8StringEncoding], RTLD_NOW);
if (handle)
{
NSLog(@"DLOPEN is OK!");
}
else
{
NSLog(@"!OK ... --> %s", dlerror());
}
return 0;
}
creating iOS Application binary2
int main(int argc, char * argv[])
{
NSLog(@"binary2 -> Hello, World!");
return 0;
}
When I run binary1
I get:
Lets see the difference MH_EXECUTE vs MH_DYLIB
fullscreen
Lets change them and run binary1
again.
After change the result was out of address space
Lets see Load Commands
fullscreen
* in dylib
there is NO __PAGEZERO
segment
* dylib
__TEXT
segment VM address
== 0 but in binary2
== 0000000100000000
So lets patch them too ... (patched: __TEXT
, ___DATA
and __LINKEDIT
)
After run binary1
i get malformed mach-o image: segment __PAGEZERO overlaps load commands
I successfully removed __PAGEZERO
from Load Commands now binary looks like dylib:
fullscreen
But on start binary1
I get BAD_ACCESS
Exception Type: EXC_BAD_ACCESS (SIGBUS)
Exception Subtype: KERN_PROTECTION_FAILURE at 0x00000001019e0010
Triggered by Thread: 0
Thread 0 name: Dispatch queue: com.apple.main-thread
Thread 0 Crashed:
0 dyld 0x0000000120016d78 ImageLoaderMachOCompressed::rebase(ImageLoader::LinkContext const&) + 892
1 dyld 0x0000000120016c24 ImageLoaderMachOCompressed::rebase(ImageLoader::LinkContext const&) + 552
2 dyld 0x0000000120010c8c ImageLoader::recursiveRebase(ImageLoader::LinkContext const&) + 132
3 dyld 0x000000012001039c ImageLoader::link(ImageLoader::LinkContext const&, bool, bool, bool, ImageLoader::RPathChain const&) + 176
4 dyld 0x00000001200088e0 dyld::link(ImageLoader*, bool, bool, ImageLoader::RPathChain const&) + 180
5 dyld 0x000000012000df68 dlopen + 684
6 libdyld.dylib 0x0000000194e65b94 dlopen + 68
7 binary1 0x00000001000b7e18 main (main.m:16)
8 libdyld.dylib 0x0000000194e66a04 start + 0
You're getting BAD_ACCESS
because you removed __PAGEZERO
and thus invalidated the rebasing opcodes. Keep __PAGEZERO but nullify it. I similarly converted an executable into a shared library and it's loading fine on iOS and macOS.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With