3

I'm trying to reverse a compiled tweak. As a first step, I want to find out all the functions it hooks. I can find all the calls to substrate framework functions, but I didn't figure out which functions are hooked (r0). What is the best way to do this?

  1. How can I start an app using gdb instead of attaching to a running process. The straightforward way results in a SIGABRT and the call stacks look something like

    #0  0x39ee91f0 in __pthread_kill ()
    #1  0x39f53796 in pthread_kill ()
    #2  0x39e99fdc in abort ()
    #3  0x33bdec10 in GSRegisterPurpleNamedPort ()
    #4  0x33bde890 in _GSEventInitialize ()
    #5  0x31604f38 in UIApplicationMain ()
    #6  0x0022d97c in ?? ()
    #7  0x000910c8 in ?? ()
    
  2. I tried to write a tweak to hook into the substrate framework functions, e.g. MSHookFunction.

    #include <CydiaSubstrate.h>
    
    void (*oldMSHookFunction)(void *, void *, void **);
    
    void newMSHookFunction(void *symbol, void *hook, void **old) {
        printf("CC_HOOKED\n");
        oldMSHookFunction(symbol, hook, old); 
     }
    
    __attribute__((constructor)) static void initialize() {
        NSLog(@"CC_LOADED");
        MSHookFunction(MSHookFunction, &newMSHookFunction, &oldMSHookFunction);
     }
    

With syslog, I found that my tweak is successfully loaded with CC_LOADED printed and there were other tweaks loaded after mine. However, no CC_HOOKED is printed out. What happened ?

1
  • The second way hooks successfully. printf doesn't print to syslog. Still don't know how to fix the first way.
    – c c
    Commented Sep 1, 2014 at 21:55

2 Answers 2

1
#include "substrate.h"
#include <dlfcn.h>

void resolveSymbol(const void *addr) {
    Dl_info info;
    if (dladdr(addr, &info)) {
        NSLog(@"<hooksubstrate> Resolved symbol at address %p: dli_fname %s, dli_fbase %p, dli_sname %s, dli_saddr %p", addr, info.dli_fname, info.dli_fbase, info.dli_sname, info.dli_saddr);
    }
    else {
        NSLog(@"<hooksubstrate> Can't resolve symbol at address %p", addr);
    }
}

void (*oldMSHookFunction)(void *, void *, void **);

void newMSHookFunction(void *symbol, void *hook, void **old) {
    NSLog(@"<hooksubstrate> MSHookFunction: symbol %p, new %p, old %p", symbol, hook, old);
    resolveSymbol(symbol);
    resolveSymbol(hook);
    resolveSymbol(old);
    oldMSHookFunction(symbol, hook, old);
}

void (*oldMSHookMessageEx)(Class, SEL, IMP, IMP *);

void newMSHookMessageEx(Class c/*lass*/, SEL s/*elector*/, IMP replacement, IMP *result) {
    NSLog(@"<hooksubstrate> MSHookMessageEx: class %@, selector %@, new %p, old %p", NSStringFromClass(c/*lass*/), NSStringFromSelector(s/*elector*/), replacement, result);
    resolveSymbol((const void *) *replacement);
    resolveSymbol((const void *) result);
    oldMSHookMessageEx(c/*lass*/, s/*elector*/, replacement, result);
}

__attribute__((constructor))
static void initialize() {
    MSHookFunction(MSHookMessageEx, &newMSHookMessageEx, &oldMSHookMessageEx);
    MSHookFunction(MSHookFunction, &newMSHookFunction, &oldMSHookFunction);
    NSLog(@"<hooksubstrate> Hooked into MSHookFunction & MSHookMessageEx");
}

With sample output (for an old version)

> cat /dev/null > /var/log/syslog
> cat /var/log/syslog | grep "Loading"
Sep 12 17:06:54 iPad Clash of Clans[2372]: MS:Notice: Loading: /Library/MobileSubstrate/DynamicLibraries/HookSubstrate.dylib
Sep 12 17:06:54 iPad Clash of Clans[2372]: MS:Notice: Loading: /Library/MobileSubstrate/DynamicLibraries/xxCOCPlugin.dylib
> cat /var/log/syslog | grep "<cc>"
Sep 12 17:06:54 iPad Clash of Clans[2372]: <cc> Hooked into MSHookFunction & MSHookMessageEx
Sep 12 17:06:54 iPad Clash of Clans[2372]: <cc> MSHookFunction: old 0x845fd, new 0x3af4fd
Sep 12 17:06:54 iPad Clash of Clans[2372]: <cc> Resolved symbol at address 0x845fd: dli_fname /var/mobile/Applications/1A631C27-CE93-4845-B7FB-0637D600E10C/Clash of Clans.app/Clash of Clans, dli_fbase 0x4000, dli_sname (null), dli_saddr 0x0
Sep 12 17:06:54 iPad Clash of Clans[2372]: <cc> Resolved symbol at address 0x3af4fd: dli_fname /Library/MobileSubstrate/DynamicLibraries/xxCOCPlugin.dylib, dli_fbase 0x3a7000, dli_sname _Z20func_hook_new_searchi, dli_saddr 0x3af4fd
Sep 12 17:06:54 iPad Clash of Clans[2372]: <cc> MSHookMessageEx: class AppController, selector application:didFinishLaunchingWithOptions:, new 0x3afdb5
Sep 12 17:06:54 iPad Clash of Clans[2372]: <cc> Resolved symbol at address 0x3afdb5: dli_fname /Library/MobileSubstrate/DynamicLibraries/xxCOCPlugin.dylib, dli_fbase 0x3a7000, dli_sname _Z60hook_AppController_application_didFinishLaunchingWithOptionsP11objc_objectP13objc_selectorS0_S0_, dli_saddr 0x3afdb5
1
  • I find that MSHookFunction sets it's symbol pointer to NULL if it's trying to hook its own address, and forces a crash. Is this a recent safety feature? Commented Apr 12, 2015 at 10:17
0

You can find all the hooked Objective C methods in a tweak by first doing a cross reference of _MSHookMessageEx in IDA Pro. In the functions which call _MSHookMessageEx, the method name can be seen loaded into R1, just before the call to _MSHookMessageEx.

To launch an app with gdb, use debugserver. It acts as an endpoint for remote gdb or lldb on iOS. You can find more information about debugserver on this page - http://iphonedevwiki.net/index.php/Debugserver

Also, I would recommend using Theos (http://iphonedevwiki.net/index.php/Theos) to do the function hooking. It makes development of MobileSubtrate tweaks a lot easier.

Judging by your question, I seem to get the idea that you're trying to hook MobileSubtrate's own functions like MSHookFunction. MobileSubstrate is only designed to hook other functions and not itself.

1
  • 1
    Thanks for your answer. The cool thing about MobileSubstrate is it can hook everything, including MSHookFunction. The problem of the original code is that I should use NSLog instead of printf, and everything else works just fine.
    – c c
    Commented Sep 28, 2014 at 1:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.