

Basic OSX Cracking   

Introduction  

So here it is, a whole new OS.  Your favorite tools are useless (with the exception of HexEdit) and you don't know where to begin.  Although this tutorial will go through the basics, it is aimed at people who at least have a little knowledge about cracking under PPC and OS9.  It's a shame that there isn't a decent file for beginners on PPC cracking.  For those of you who are complete beginners, I can recommend that you read one of the dozen of tutorials on 68k cracking.  Get the general idea about what it's all about and then move over to PPC (my previous file on PPC cracking might help you in the transition).  Then finally, read this file.     


Tools  

With MacsBug and ResEdit out of the way (including the resource fork too), the only old tool that you still need is a hex editor (HexEdit 1.7.4 works just fine under OSX).  Of course if you have a gentle mind and do not support brute force cracking (patches) and only go for serial numbers then you do not need a hex editor.  What you do need on the other hand is a copy of GDB.  GDB is the replacement for MacsBug.  From what I gather it's a standard *NIX debugger.  It's COMPLETELY different from MacsBug and trust me, the transition will be painful for all hardcore MacsBug fans (like myself).  Luckily Apple has made some macros that give GDB some MacsBug properties, but still...  

If you do not have GDB then you can download it from Apple's developer's homepage.  It is included with the Developer Tools package for OSX (connect.apple.com).  To find out whether GDB is installed or not launch the Terminal (you might as well put it in the Dock since its going to be your interface for the debugger) type GDB and press return.  If you get an error then it's not installed.  If it launched enter "quit" and press return.   


GDB and CFM conflicts  

As I mentioned before, GDB has replaced MacsBug (but unfortunately there's nothing we can do about it, so we might as well get used to it).  Since it is meant to be a debugger for *NIX platforms there are times when it has to be "adopted" to deal with the Mac environment.  In order to be able to debug carbon apps (ones that are not OSX specific) you need to play a trick on GDB.  I'm not going to go into details why this is, but what you have to do is to specify where the lib is that allows GDB to run CFM apps.  Once you have done that, you run the application from GDB and start the debugging  much the same way as you would in OS9.   


First time setup  

The lib that I was referring to above can be found at: /System/Library/Frameworks/Carbon.framework/Versions/A/Support/LaunchCFMApp Now, that's a long thing to write every time you want to debug an application.  So why not create a link of the file in the root folder?  In order to do that, issue the below command in the terminal:  

ln -s /System/Library/Frameworks/Carbon.framework/Versions/A/Support/LaunchCFMApp /LaunchCFMApp  

(NOTE: there is only a space between the two /LaunchCFMApp. Not after -s)  

If you have done everything correctly you should have a new file in your root folder named LaunchCFMApp. While you are at it make a link to the MacsBug macros used by GDB too (more about it later):  

ln -s /usr/libexec/gdb/plugins/MacsBug/gdbinit-MacsBug /MacsBug  

I've also found it useful to make a cracking folder in the root folder.  Saves a lot of typing when issuing commands in the Terminal application.   


Running apps in GDB 

The first thing you have to do is to launch the Terminal application.  Once it's running  launch GDB by typing:  

gdb /LaunchCFMApp  

(If you haven't created the links recommended above you have to use full path names.) 

Then it is time to run the application from gdb by issuing:

run /crackingfolder/appname 

- "run" is the command used to run applications (abbreviated as "r") 
- "crackingfolder" is the folder where the application to be cracked is 
- "appname" is the name of the application you want to run.  You can specify any path to the application you want to crack.  But don't forget to use the initial slash ("/") or you will get an error.  

At this point in time GDB should start to load the application.    

NOTE: if you are running a Mach-O type application (OSX native) then you do not have to use the LaunchCFMApp link.   


Attaching GDB to running processes  

Using the run command presumes that the application is not already running.  There is, however, also a way to debug running programs.  To do this you need to use the "attach" command.  It should be followed either by the running programs name or it's process id.  The process id can be found with the "ProcessViewer" application (included with OSX).  An even easier approach is to use the tab button.  After writing "attach" and hitting the Tab button three times, a complete list of all running processes and their id's appears.     


The MacsBug Macros  

Apple has actually created a set of macros that attempts to give GDB a certain MacsBug look and feel.  It doesn't really work but it's a LOT better then what GDB has to offer on it's own.  The easiest way of activating the MacsBug plugging, presuming you've created the link above, is to issue the following  command in GDB:  

load-plugin /MacsBug  

By using the "help MacsBug" command you can find out which former MacsBug commands are available in GDB.

Once you start tracing through a program you will notice that the list of the registers and their contents has been moved over to the right side of the window (in comparison to the left side of the MacsBug screen).  But none the less it's there!  Make sure your window is large enough to display all registers!  If it just wont fit, change the monitor resolution and make the window larger that way.   


Using GDB (and the MacsBug plugin commands)  

First of all, it is important to notice one big difference between GDB and MacsBug.  While you could invoke MacsBug at any time in OS9, GDB has to be started like a program.   You can't time the activation in the debugger quite the same way as you did with MacsBug.  Therefore, you will most likely be forced to use one of the toolbox (carbon) calls when cracking a program.  But more about this later.  The first thing you have to know about GDB is how to stop the program that is being debugged by GDB.  Once a program has been "run" from GDB or GDB has been "attached" to it, hold down the control key and press 'c'.  This should give you the GDB prompt and the debugged program will "disappear" (all windows will be hidden and the beach ball will be spinning).  Once you have the GDB prompt you can start to issue commands, trace through the code, etc.  To allow the program to resume the "c" or the "g" commands can be used ("g" is actually a MacsBug macro so it won't work if the plugging isn't loaded).  

Now that GDB is ready to go, what commands can be used?  Well, presuming that the MacsBug macros are loaded, the "dm" command (display memory) still works.  However, the '$' sign has to precede every register number.  Meaning that in order to display the contents of r3 the "dm $r3" command has to be issued.  This convention holds true for all registers including the 'pc' and the 'lr' (they become '$pc' and '$lr').  

To examine the contents of a register it is no longer enough to enter the register's number.  However, the "info register" command is a very nice feature that may prove very helpful for such situations.   

The "step" and the "trace" commands are a bit different now.  's' has been replaced by 'si' and 't' has not really been replaced with anything.  The "ni" command can be used if the pc is at a "bl" instruction (that is a function or a subroutine), but the command might screw things up if its used elsewhere.   If you find yourself stuck in a function/subroutine that you want to get out of use the "finish " command.  It should give back control, once the debugger is out of the function.  

Something that has multiple functions in GDB is the "break" command.  It seems like the most useful command in GDB.  It is, however, slightly different from MacsBug.  First of all, the address where the break is supposed to be has to be preceded by "0x" (that is zero and the letter x) which is the standard way of indicating hexadecimal numbers in the C programming language.  Secondly, the address (preceded by 0x) has to be preceded by a "*" (a star sign).  So, to set a breakpoint at address hex 111111, the following command has to be used:  

break *0x11111111

A variation of the break command is "tbreak".  The beauty of this command is that GDB automatically clears the break once it is reached.  This is a great way to compensate for the problems with the "ni" command.  If the pc is at a "bl" instruction just about to branch off to a subroutine/function, set a tbreak at the next instruction ("tbreak *$pc+4 "), allow the program to continue ("c "), and this will give the same effect as the good old "t" did.    

To clear a breakpoint the "delete " command can be used followed by the break's id number.  To find out which id the break has issue the "info break " command.  The delete command by itself gets rid of all set breakpoints.  

Breaks have replaced the "tvb" call in GDB as well.  It is now possible to set a break at ModalDialog ("break ModalDialog") without the system crashing.  

Without getting into the depths of the heap, there is one command that is very useful - "backtrace " (or "bt ").  This command shows exactly where in the program you are.  With other words it shows you what level within the program you currently are; which functions precede the current one.  

In MacsBug the process-counter (pc) could directly be set to a specific address simply by using a command in the form of "pc=address ".  In GDB the "set " command has to be used.  To jump to the next command in line for example the following can be issued:

set $pc=$pc+4

By pressing apple-v MacsBug automatically displayed the last entered command (anyone else notice that it displays a list of previous commands, in a popup menu, if the command field is clicked on whilst the ctrl key is down?).  In GDB you can use the up and down arrows to get the same effect.  This can be very useful since GDB requires a lot more typing to issue commands.   

A really cool feature of GDB is it's ability to figure out your commands through abbreviations.  For example, a simple "b" can be used instead of "break" and "i r" replaces "info register".  This ability does unfortunately not apply to things like registers.  The "$" sign is ALWAYS needed before registers and the "*" sign is always needed before addresses.  

The list of commands would not be complete without the notorious "es" command.  "kill " has replaced "es"  but in reality the Finder's force quit works just as well...    


OSX cracking vs. OS9 cracking  

From what I've seen so far, most applications have refrained from using the WaitNextEvent call and are relying on the Carbon event manager.  This is a completely new approach in order to make multi-threading as efficient as possible.   There is a standard set of event managing functions in Carbon, but programmers also have the possibility of creating their own functions.  For more information on Carbon event handling see the file specified in the "Further reading" section below.  The backtrace command can be useful when finding out your current location within the code, and finding your way out of it.   

It also seems that the applications have moved away from using dialogs to obtain registration information.  They now rely on windows (which is bit of a shame because the new dialog manager is awesome!).  Since the window manager still uses the TextEdit calls, a system call that always seems to work is "TEGetText".  Of course, in the cases where it doesn't work, you can use the methods you've been using so far to crack applications (even if they might need slight modifications).  On the apple dev. homepage there is a nice list of all system calls.  There you can find out if old system calls work in  Carbon or not.     


Further reading 
Carbon Events: http://developer.apple.com/techpubs/macosx/Carbon/pdf/HandlingCarbEvents.pdf  

Tech Note on GDB:  
http://developer.apple.com/technotes/tn/pdf/tn2030.pdf

GDB commands
try the "help "command in gdb   


ProZaq - prozaq@msec.net









