Anti-debug trick #1: Abusing Mach-O to crash GDB

I developed this funny trick while trying to find a solution for a problem in a freelance project. It is pretty easy to implement and fun 🙂

The trick consists in abusing the offset field in the dylib_command and pointing it to somewhere else. From the Mach-O File Format Reference, the command structures are:

struct dylib_command              struct dylib                            union lc_str
{                                 {                                       {
 uint_32 cmd;                      union lc_str name;                      uint32_t offset;
 uint_32 cmdsize;                  uint_32 timestamp;                      #ifndef __LP64__
 struct dylib dylib;               uint_32 current_version;                char *ptr;
}                                  uint_32 compatibility_version;          #endif
                                  }                                       }

The definition of the offset field is:
“A long integer. A byte offset from the start of the load command that contains this string to the start of the string data.”

Usually this field is always 0x18 (24 bytes). This means that the library name string is located after the dylib_command command, whose size is 24 bytes. Right now your evil brain should be interpreting that definition as “an offset (anywhere) that contains the start of the string data“. If not, don’t worry, evilness takes practice 🙂

What happens if you put the string somewhere else and change the offset to point there? GDB crashes, otool can’t recognize the offset and so on.

Otool:

Load command 20
          cmd LC_LOAD_DYLIB
      cmdsize 88
         name ?(bad offset 28548)
   time stamp 2 Thu Jan  1 01:00:02 1970
      current version 30.0.0
compatibility version 1.0.0

GDB:

GNU gdb 6.3.50-20050815 (Apple version gdb-1344 + reverse.put.as patches v0.3) (Mon Aug 22 00:31:56 UTC 2011)
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "x86_64-apple-darwin"...gdb-i386-apple-darwin(68831) malloc: *** mmap(size=18446744073709506560) failed (error code=12)
*** error: can't allocate region
*** set a breakpoint in malloc_error_break to debug

Fun stuff, right ? 🙂
The problem with the debugger attach is that I assumed gdb would also crash if attached and forgot to try if it was true. It is a minor problem – the crackme is designed to resist a debugger attach.

The next trick is even more fun but requires some time to write the post. I didn’t took all the notes and I need to “rediscover” it to show you where the problem is.

Enjoy,
fG!

5 thoughts on “Anti-debug trick #1: Abusing Mach-O to crash GDB

    1. You are correct and I forgot to mention this. I tried to fix the codesign problem but it seems to require recompilation of Keychain (besides codesign and codesign_allocate) and that requires private Apple stuff. :-/

  1. Hey,

    anybody with more tricks to crash gdb? I try to reverse an iOS app but gdb keeps crashing on me and it is not exactly a wrong offset as described. I know I have to think more but need a kickstart,

    Thanks, Mirko

Leave a Reply

Your email address will not be published. Required fields are marked *