Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MobileSubstrate: MSHookFunction example

I am trying to write a MobileSubstrate plugin which hooks into a C-method. I tried to edit the famous "ExampleHook", by just writing a demo MSHook and hook it in the Initialize method. This is probably too optimistic and it doesn't work. But I cannot find anywhere a simple example of a MSHookFunction(). There is barely information about this on the Internet. It might be possible I misunderstood the whole concept of MSHookFunction.

Please, can anybody help me out with a little example code? I would deeply appreciate any help.

Best regards, Marc Backes

like image 644
Marc Backes Avatar asked Dec 21 '22 14:12

Marc Backes


1 Answers

I realize you have found this, but I am posting this answer to help whoever else may be needing this.

A simple example can be found at the MobileSubstrate article on the iPhone Dev Wiki, and an actual example of this in a project is at this bit of User Agent Faker.

But what is an answer without an actual explanation? Therefore, here we go!

void MSHookFunction(void* function, void* replacement, void** p_original); is the function definition for MSHookFunction, the magic function which causes your function X() to be interposed by Y(), for instance.

That is, when a program commonly would call X(), the call will be redirected to Y() instead. This is pretty much a basic explanation of function interposing.

Now, what are the parameters, and their usefulness?

  • function is a function pointer to the function you want to interpose. That would be a function pointer to X(), in our quick explanation.
  • replacement is a function pointer to the function you want function to be interposed with. In our quick explanation, that would be a function pointer to Y().
  • p_original is a pointer to a function pointer, which from now on will point to what function used to be.

    The reason this is there is simple: If you intend to modify behavior, but not suppress it, you'll still need to call what X() used to be. But a common call to X() wouldn't work as intended, as it would end calling Y() instead of the default function.

    Therefore, you have a function pointer to call X() as if it wasn't interposed.

Now, explaining the devwiki example:

static void (*original_CFShow)(CFTypeRef obj);  // a function pointer to store the original CFShow().
void replaced_CFShow(CFTypeRef obj) {           // our replacement of CFShow().
  printf("Calling original CFShow(%p)...", obj);
  original_CFShow(obj);                         // calls the original CFShow.
  printf(" done.\n");
}
...
// hook CFShow to our own implementation.
MSHookFunction(CFShow, replaced_CFShow, &original_CFShow);
// From now on any call to CFShow will pass through replaced_CFShow first.
...
CFShow(CFSTR("test"));

Here, we:

  1. Pass a pointer to CFShow, the function we want to change default behavior from as the function parameter.
  2. Pass a pointer to the function we just created, replaced_CFShow as the replacement parameter. That is, whenever CFShow would be called by default, replaced_CFShow will be called instead.
  3. We pass a pointer to the original_CFShow function pointer as the p_original parameter. Since we still want the things CFShow still does by itself to be done inside our replacement function, we call it.
like image 200
Matoe Avatar answered Jan 09 '23 14:01

Matoe