UPDATE: For patched binaries, please check AppSupport Page. This article only analyzes the dynamic library loading mechanism in the patch, not the patch itself.
I’ve decided to reverse the AppSupport patch (for 1.1.2) because I wanna know how it is written, more ever, it was said there’re some tricks inside the code which deals with dynamic shared library manipulation, and this is exactly what I’m interested in.
So I fire up my IDA Pro, load in the patched AppSupport, then check from _decomposePhoneNumber. Here’s the disassembly:

NOTE: I add some labels/comments in the listing to make it easier to understand. The routine is simple:
- Locate the _decomposePhoneNumber method in external library
- Call the method
Nothing special here, so let’s go ahead to the locate_external_decomposePhoneNumber routine:

The instructions till LDMNEFD is easy to understand, it ensures we don’t load the library for twice, and you’ll see similar code block repeats from time to time in the following disassemblies.
There’re 3 calls in the above code snippet:
BL locate_dyld_dlsym BL load_PhoneNumber_dylib BLX R4
The first call gets the __dyld_dlsym’s address, the second call loads the external dynamic library, then the third one gets the decomposePhoneNumber method’s address from the loaded library.
Since I’m interested in the dynamic library loading, so let’s check the load_PhoneNumber_dylib first:

From the disassembly, the routine gets the address of __dyld_dlopen, then call it to load the external library, and store the handle for later use. This handle is important as we need it to get the address of a method in the loaded library.
Now let’s see how it get the address of __dyld_dlopen:

So it calls __dyld_func_lookup to get the method’s address. From Apple’s reference, the dyld_func_lookup has the following prototype:
int _dyld_func_lookup(const char* dyld_func_name, void** address);
Feed it with a method name, and it’ll store the method’s address into *address, and that’s exactly what the routine does.
Now get back to the beginning, there’s another routine named locate_dyld_dlsym, let’s check it:

Roll back some lines, you’ll notice it’s similar to the locate_dyld_dlopen: gets the dyld_dlsym’s address and saves it.
From all the above, it’s easy to tell that the way to load and use the dynamic library is pretty straight forward. To load an external library:
- Get the address of __dyld_func_dlopen
- Call __dyld_func_dlopen to load the external library
- Save the handle for later use
To call the method in loaded library:
- Get the address of __dyld_dlsym
- Call __dyld_dlsym with the saved handle to get the method’s address in the loaded library
- Call the address
From what I have got by reversing the patch loader, there seems no special magics, the way to use the dynamic shared libraries is standard. Although this way to patch an application is good, as it allows to use customized methods to replace the application’s methods, it is not perfect yet, as it requires to manually patch each to-be-replaced method to call the method in external library.
If there’s a way to insert the library directly into mach-o header and to simulate the DYLD_INSERT_LIBRARIES operation, then it would be perfect for general purpose patches because it allows override any method in the application and will in turn greatly simplify the patch, but I have no idea if this is possible or not.

8 Comments
Can you make a patch for 1.1.3?
thanks
Mark, I know someone is working on it, just wait for some time :)
> If there’s a way to insert the library directly into mach-o header and to simulate the DYLD_INSERT_LIBRARIES operation, then it
> would be perfect for general purpose patches because it allows override any method in the application and will in turn greatly simplify
> the patch, but I have no idea if this is possible or not.
If function X calls function Y directly (eg. BL function_y) and you want to change the behaviour of function Y then the only way you can do this is by overwriting the code of function Y.
NumberSix, yeah I know OS X allows overriding a function using external dynamic libraries, however, this will not work without the help of ‘dyld’ loader thru the environment variable DYLD_INSERT_LIBRARIES, I didn’t mean I didn’t know how to override it, I was talking about whethere there’s a way to implement this overriding mechanisms by own code or by modifying header so that I don’t have to touch the environment variables.
The AppSupport patch does not override the funtions, it patches the functions directly.
i have noticed that change in the header area of the file in address 0×39C what this change needed for?
@waleed, the patch needs to store some variables so it has to reserve some memory in (writable) data section. The offset 0×39C stores the section size (segment “_DATA”, section “_bss”), the original value 0×48 defines the memory range for _bss from 0×381E0F38 to 0×381E0F7F, the patch (0xC8) extends it to 0×381E0F38 – 0×381E0FFF, the extended space (128 bytes) is used for variable storage.
George, I’m trying to patch the webcore but i found the _bss have no space can i use _common instead and change the value in the address 0×600 of the webcore to the value (0×648) and extend the _common from 0×39595D30 to 0×39596377 is this acceptable
George, i did what i mention b4 and it worked thank u for ur help