2

Scene:

I was trying to reverse engineer a mobile substrate dylib. Via IDA, the dylib called MSHookFunction() inside the constructor, and the arguments were from dlopen and dlsym. IDA failed to show the symbols of dlopen and dlsym, so I had to turn to gdb, which could possibly print the 2nd arg of dlsym, a char*, at run time.

Goal:

Break at the very beginning of the constructor of this dylib with gdb.

First Thought:

The constructor of a dylib is executed right after it's loaded, doing all the necessary initializations (Correct me if I'm wrong). So I wrote a command line tool which simply dlopen the dylib and then dlclose it, to run the constructor. FYI, here's the code of the dylib and the command line tool:

// iOSTestDylib.dylib: I'm using [Logos][1] here
%ctor
{
  %init;
  NSLog(@"snakeninny: ctor of dylib");
}

// iOSTestTool
#include <mach-o/dyld.h>
#include </usr/include/dlfcn.h>

int main(int argc, char **argv, char **envp)
{
  NSLog(@"snakeninny: line 6 of command line tool");
  void *handle = dlopen("pathOfTheAboveDylib", RTLD_LAZY);
  NSLog(@"snakeninny: line 8 of command line tool");
  dlclose(handle);

  return 0;
}

As you can guess, once I run iOSTestTool, it printed:

  1. snakeninny: line 6 of command line tool
  2. snakeninny: ctor of dylib
  3. snakeninny: line 8 of command line tool

Then setting a break point inside iOSTestDylib.dylib seemed to solve the problem. But I suddenly realized that, before dlopen iOSTestDylib.dylib, the ASLR offset of iOSTestDylib.dylib was unknown, therefore the address of the bp was uncertain. Meanwhile, after dlopen, though we could figure out the ASLR offset, the ctor was already executed, so bp became meaningless. In either situation, I couldn't break inside the constructor of a dylib. Mission failed, and neither did I have a second thought, nor a plan B :(

Question:

What should I do to reach my goal?

snakeninny
  • 213
  • 4
  • 8
  • Nice question, even better goal, +1. If I'm not indiscrete, which tweak are you trying to reverse engineer? (No, it's not a trap, all my tweaks are free ;-) –  May 22 '13 at 16:18
  • Also, I don't see what the problem with ASLR is. Just list the symbols (`nm`, `otool`, etc.) in the binary to seaech for something like `void init(void)` or if it's stripped, ask IDA for its entry point, and set a breakooint there. –  May 22 '13 at 16:19
  • @H2CO3 I don't know if it's an offense to the author, so I'd better keep it private and just sent you an email :P – snakeninny May 22 '13 at 16:26
  • Thanks, I understand your point. –  May 22 '13 at 16:28
  • @H2CO3 I'm pretty new to reverse engineering, and here is what I do to reverse an executable, say SpringBoard: 1. run gdb; 2. attach SpringBoard; 3. run "info sh" to get the ASLR offset of SpringBoard; 4. get the address of my target instruction inside SB with IDA; 5. b *(the offset got in step 3 + the address got in step 4); 6. c. If I understand you correctly, you're suggesting what step 4 does, missing step 3, and that's the real question. Correct me if anything is wrong :P – snakeninny May 23 '13 at 05:10
  • I mean if you're inside SpringBoard with GDB anyway, then you have virtual addresses only and the kernel does the rest for you, ASLR is transparent. –  May 23 '13 at 05:24
  • @H2CO3 Oh really? So I can actually ignore step 3 if I'm debugging SpringBoard? Does the same rule apply to my situation, i.e. gdb run a command line tool, which dlopens a dylib? – snakeninny May 23 '13 at 06:37
  • I think so, why not try it? –  May 23 '13 at 06:39

0 Answers0