Debuggers – GDB and Objective C

I have used IDA Pro, OllyDbg and WinDbg, and pretty well understand my way around those debuggers. However, when it comes to Mac OS X debugging I have only ever used IDA Pro and occasionally GDB, in particular debugging my own programs in XCode. However, with with Snow Leopard my copy of IDA Pro (5.1) breaks, which means I either have to pay a good chunk of change to upgrade, or learn how to use GDB. I have to admit that I am really missing IDA and will likely upgrade, however, I am finding GDB’s scripting language to be very powerful, especially with a dynamic language like Objective C. For example, this script will print out all of the currently loaded Objective-C classes. I’ll give the Objective C version, then the GDB version (ported directly Apple’s developer docs site: ObjC Runtime Reference

Obj-C version:

int numClasses;
Class * classes = NULL;
classes = NULL;
numClasses = objc_getClassList(NULL, 0);
if (numClasses > 0 )
{
    classes = malloc(sizeof(Class) * numClasses);
    numClasses = objc_getClassList(classes, numClasses);
    free(classes);
}

GDB version:

set var $numClasses = (int)objc_getClassList(NULL, 0)
set var $classes = (Class*)malloc(sizeof(Class) * $numClasses)
set var $numClasses = (int)objc_getClassList($classes, $numClasses)
set var $count = (int)0
while($count != $numClasses -1)
    printf “%s\n”, (const char*)class_getName($classes[$count])
    set var $count += 1
end

A few things I’ve learned that might be helpful to keep in mind when scripting in GDB. Always remember that you have no header file and that you are actually in the runtime of a program. This means that GDB does not know what type gets returned from a function, it just sees a memory address which means you always have to tell it what you are expecting. If you are in a bash terminal instead of Xcode’s debugger console, tab complete is your friend. You can set what language you are debugging by saying, for example Objective C: “set language objective-c”. I have yet to experience any issues without setting the language on OS X, but it’s something to keep in mind – I have not tested GDB for Objective C on Linux for example-

Overall, learning GDB been something I’ve needed and wanted to do for a while because sometimes that is literally all you have to work with, and GDB has a very powerful scripting language. Next up, programming in D. (No, not the C++ +=1 D, but the D-Trace D. For the love of …. : )

URL Shortener and 302 Redirector

Started an open source URL shortening service/302 redirector: http://github.com/mewz/maudir I mainly did this because I wanted to get a much better understanding of C and C++ string parsing. It was a great experience, still need to add blacklisting URL support, but it’s really fast and now leak free. Thanks to Christian Hergert for the code review and GLib help.

ATOI function

Making your own atoi function seems to come up a lot. This is the standard function – it loops through a char pointer and appends 10 * the next value – 48 (48 as in hex for the number 0, so 48 == 0, 49 == 1) – However, I deal with negative numbers and validate that the string only contains numbers, otherwise it’s zero.

#include <stdio.h>
#include <string.h>

int myatoi(char *s, int *err){
  *err = 1;
  if(!(strlen(s) > 0)){
    return 0;
  }
  int result = 0;
  int numSigned = 1;
  if(s[0] == 45){
    numSigned = -1;
    *s++;
    if(!strlen(s) > 0){
      return 0;
    }
  }
  while(*s){
    if(!(*s >= 48 && *s < 58)){
      return 0;
    }
    result = 10 * result + *s++ - 48;
  }
  *err = 0;
  return result * numSigned;
}

int main(int argc, char **argv){
  int err;
  char *s = (char*)"-1";
  if(argc > 1){
    s = argv[1];
  }

  int i = myatoi(s, &err);
  if(err){
    printf("error converting string to int: %s\n", s);
  }
  else{
    printf("conversion: %i\n", i);
  }
  return 0;
}

Dynamic C

Playing around with dynamic C. I want to be able to reassign functions to different functions at runtime. I came up with the following. I’m not comfortable that this is the best approach, but it was odd enough that I thought I would post it:

#include <stdio.h>

void sayHello(){
        printf("%s\n", "Hello!");
}

void sayBye(){
        printf("%s\n", "Bye!");
}

void saySomething(const char * c){
        printf("Going to say: %s\n", c);
}

void sayNothing(){
        printf("I refuse to say anything\n");
}

int main (int argc, const char * argv[]) {

        //the greeting function pointer
        void (*greeting)(void);

        //assign greeting to the sayHello function
        greeting = sayHello;
        greeting();

        //assign greeting to the sayBye function
        greeting = sayBye;
        greeting();

        //the function pointer for saySomething and sayNothing
        void (*fncPtr)(const char *);
        fncPtr = saySomething;
        fncPtr("Something is being said");

        //Very confused by this. At this point fncPtr is a variable AND a function pointer.
        //By just assigning it the signature as the function sayNothing, it will not compile
        //because it's a variable and needs a variable assigned to it.
        //I assign it the value of NULL (\0) after the function signature of sayNothing,
        //which compiles (anything, such as an int could also be assigned).
        //I then can assign fncPtr to the void argument function sayNothing.
        //At this point, however, it will will not compile. I have to "pretend" it hass the
        //same arguments as it was originally assigned, however,
        //it will instead run the sayNothing(void) function at runtime even though I'm passing
        //in the const char * "this means nothing".
        //I think a lot of the oddness has to do with formating the code to pass through the
        //compiler, while at runtime it's a different story.
        fncPtr = (void (*)())'\0';
        fncPtr = sayNothing;
        fncPtr("this is a useless argument");

    return 0;
}

Converting an NSString to an NSDictionary

I keep having to recreate/find this, so I thought I’d just post it to my blog. This example snippet shows how to convert an NSString into an NSDictionary (saying that your string is in fact the contents of of an NSDictionary):

NSString *src = @"the contents of some plist";
NSData *data = [src dataUsingEncoding:NSUTF8StringEncoding];
NSString *errorDesc = nil;
NSPropertyListFormat format;
NSDictionary *dict = (NSDictionary *)[NSPropertyListSerialization
propertyListFromData:data
mutabilityOption: NSPropertyListMutableContainersAndLeaves
format:&format
errorDescription:&errorDesc];

Frameworks are evil

Awesome post http://maliciousattacker.blogspot.com/2008/04/programmer-brain-soup-rant.html on why frameworks suck.

PHP JavaScript unescape Function

PHP is a great language, but I’ve found that is really needs the equivalent of the JavaScript unescape function. That said, I decided to port WebKit’s JavaScript unescape function to PHP, which you can find here: unescape.php.html This will unescape strings that contain either hex (%3c) or JavaScript unicode escape’s (\u003c).

Function Wrapping

I’ve been trying to find a way in Linux to do something similar to Microsoft’s Detours library that will allow me to inject my own code into a function at runtime. For example, lets say there is a program that uses the rand() function, and I only want even numbers to ever be returned, or for that matter, lets say I want to force the rand() function to not act randomly and always return the same number. Take this program named myrandimpl.cpp as an example:

#include <stdio.h>
#include <stdlib.h>
#include <ctime>

int main(int argc, char **argv)
{
  srand(time(0));
  int m_rand = rand();
  printf("my random number: %i\n", m_rand);
  return 0;
}

Now compile with: g++ myrandimpl.cpp -o myrandimpl

When you run it you will see something similar to the following output:

my random number: 40586137

In order to force rand() in the main program above to only ever return even numbers, a dynamic library must be made, in this case called libmyrand.cpp:

#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>

int rand()
{
  printf("creating random number....\n");
  int (*real_rand)(void) = (int (*)(void))dlsym(RTLD_NEXT, "rand");

  int r = real_rand();
  printf("rand() returned: %i\n", r);
  if( (r % 2) == 1) r++;

  printf("returning an even random number: %i\n", r);

  return r;
}

Now compile to a dynamic lib with:

gcc -fPIC -rdynamic -c libmyrand.cpp
gcc -shared -o libmyrand.so libmyrand.o -lc -ldl

Notice dlsym()’s first argument is RTLD_NEXT. This is the important part because this is telling dlsym to return the address of the next symbol being passed to it. In this case we are saying return the next address of the symbol “rand”, which would be the standard c lib rand() function.

The dynamic libs function’s can now be called first when the original executable is launched by telling it to preload our dynamic library. On the command line, run myrandimpl by doing the following:

LD_LIBRARY_PATH=. LD_PRELOAD=libmyrand.so ./myrandimpl

You will now see something similar to the following output:

creating random number….
rand() returned: 583795133
returning an even random number: 583795134
my random number: 583795134

Now, let’s take this one step further. I assume the game /usr/games/blackjack probably uses the rand() function. If you start the application by saying:

LD_LIBRARY_PATH=. LD_PRELOAD=libmyrand.so /usr/games/blackjack

you will notice right away that the printf()’s in the function rand() from libmyrand.so is being called. I played around with the return value and noticed a few things. By simply returning 1 I had a far better chance of winning. I also noticed that returning -1 created a segfault when the game wanted me to buy insurance.

For more info:
http://www.linuxjournal.com/article/7795
http://lattice.umiacs.umd.edu/files/functions_tr.pdf
http://developers.sun.com/solaris/articles/lib_interposers.html