I made a mistake in this tutorial! The way to calculate offsets to patch is wrong because I commited an inference error (analysed only a few binaries and assumed it to be correct). Found this while creating a program to calculate everything automatically. Check the code if you are interested in understanding how it’s done. Meanwhile I will update the tutorial…

Without any further delays, I present you with Binary offset calculator. This little program will give you the correct offset to load into the hexeditor, for fat binaries or i386 only binaries. Only 32 bits binaries are supported (for now I don’t think there are any 64 bit binaries, maybe for Snow Leopard release) and calculated offset is for i386 part.

A small example:

$ otx /bin/ls | more
/bin/ls:
md5: af07b42f06eb72336317a1d23c7c4557
(__TEXT,__text) section
+0  000023f0  6a00                    pushl       $0x00
(...)

This is the first line of ls command disassembly list. Assume we want to patch that first instruction. To calculate it’s offset we can use my program:

$ ./offset.pl /bin/ls 23f0
Mach-o Binary Offset Calculator v1.1
.....................................
(c) 2009 fG! - http://reverse.put.as - reverse@put.as

Found a Mach-O fat binary with 2 architectures!
Finding i386 base address...
Reading Mach Header...

Real offset to be patched is: 0x23f0

Now you just need to load the hexeditor and go to offset 0x23f0. In this case there is a coincidence with the address from disassembly output, but play with it and you will see it’s not always like that! If you want to see more info from the binary just edit the code and change the debug variable.

If you find any bugs leave a comment 🙂

fG!

offset.pl.gz
(SHA1(offset.pl)= 5da4ab22ef82c7f7d4740541410e31590990db3e)

P.S.: New version updated to support PPC binaries.

$ ./offset.pl /bin/ls 16a4 ppc
Mach-o Binary Offset Calculator v1.2
.....................................
(c) 2009 fG! - http://reverse.put.as - reverse@put.as

Found a Mach-O fat binary with 2 architectures!
Finding i386 and PPC base address...
Reading Mach Header...

Real offset to be patched: 0xa6a4

Grab it here: offset1.2.pl.gz
(SHA1(offset.pl)= c5d8a11cfb1728747835ca92eb42ca74d01d1ef5)