Dynamic C

January 31st, 2010

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

January 28th, 2010

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

July 7th, 2009

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

Blog Up Again

July 6th, 2009

Finally, my blog is back up again. The VPS provider I use was having some “issues”. Anyway, it’s back up and I’ll be updating again soon.

PHP JavaScript unescape Function

June 15th, 2009

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

June 15th, 2009

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