8

I'm a beginner to reverse engineering, I've read through a few tutorials and know my way around some basic GDB and assembly code. After working my way through a few trivial examples I'd like to try something a bit more 'real-world'. My goal is to reverse-engineer and 'crack' Introversion Software / Ambrosia Software's game 'Uplink'.

Note that I am only doing this for the challenge, if I just wanted to play the game for free I would find a crack, not make one. The demo is freely available at http://www.ambrosiasw.com/games/uplink/.

Now, I have learned a few important things through static-analysis, using the tools Hopper and class-dump. It soon became clear that the registration-related functions lived in ASWRegistration.framework, but after trying some static analysis, to no avail, I decided it would be best to throw GDB at it. Loaded it up, tried to set a breakpoint on one of the interesting-looking functions.

(gdb) b +[ASWRegistration isRegistered:]
Function "+[ASWRegistration isRegistered:]" not defined.
Make breakpoint pending on future shared library load? (y or [n]) n

Aw, that's annoying. Let's try something else.

(gdb) b isRegistered
Function "isRegistered" not defined.
Make breakpoint pending on future shared library load? (y or [n]) n

Hm, maybe I'm doing something wrong...

(gdb) b isRegistered:
No symbol table is loaded.  Use the "file" command.
Make breakpoint pending on future shared library load? (y or [n]) n
(gdb)

Well, that give me a different error message, it's still not working though...

Upon further examination, I've found that I can't even properly break on functions inside the executable itself.

(gdb) b applicationDidFinishLaunching:
[0] cancel
[1] all

Non-debugging symbols:
[2]    -[SUStatusChecker applicationDidFinishLaunching:]
[3]    -[SUUpdater applicationDidFinishLaunching:]
> 0
canceled

Two possible applicationDidFinishLaunchings, not one of them come from the actual game (I suspect they're from Sparkle.framework). It WOULD seem as though Ambrosia was smart and stripped all debugging symbols, but class-dump gives me full headers, nm gives me a bunch of symbols, and Hopper finds all sorts of methods. So I don't see why GDB can't use that. Again, I'm a beginner in all of this, maybe I'm doing something blatantly wrong. I also tried the same thing with a Mac App Store games, "Hack RUN Free", and got the same No symbol table is loaded. Use the "file" command error. Of course, the file command doesn't help at all.

Does anybody know how to fix this? I'd like to advance beyond the purely theoretical level in this ?

11
  • Have you tried info functions to display all function symbols within the executable ? Hopper seems to have a different (more efficient) method to extract the symbol table. It might be a GDB limit here.
    – perror
    Nov 26, 2013 at 16:53
  • 1
    Also, note that GDB can break anywhere in the executable. You just need to use one of the following: b *0xdeadbeef or b *myfunction.
    – perror
    Nov 26, 2013 at 17:00
  • Indeed, GDB doesn't find the symbols for ASWRegistration functions. Unfortunately, I don't know how to manually calculate shared library offsets. Any other debuggers for OS X that do this?
    – SlEePlEs5
    Nov 26, 2013 at 19:13
  • And, are you finding this symbol when trying objdump -x (look at the export table)?
    – perror
    Nov 26, 2013 at 19:59
  • @perror Not as far as I can see. The output from objdump is here if you're interested. I know it's possible to figure out the symbols, since both Hopper and a demo version of IDA seem to be able to do this. I've gotten to a point with static analysis where while I'm pretty sure I'm in the right place, my assembly skills aren't good enough that I can follow what's going on once Hopper is no longer able to find the methods for me. There are some obvious _objc_msgSend calls going on but I don't know how to find the actual code those point to.
    – SlEePlEs5
    Nov 26, 2013 at 20:55

1 Answer 1

2

Objective-C works a bit different than most languages. You have selectors in the _ObjC section which are used as arguments to obj_msgSend (which is how just about everything is invoked). There are no direct calls between functions. I suggest starting off with the Cameron Hotchkies slides on this topic from REcon 2008.

1
  • I understand that, the issue I was having here was that I couldn't find what what actual code was being called as a result of the obj_msgSend call. This was a while ago, but I believe a combination of live debugging and otool -ov helped me find what I was looking for.
    – SlEePlEs5
    Jul 16, 2014 at 21:20

Your Answer

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

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