Linux cracking
How to crack in Linux without a disassembler
student
Not Assigned
26th October 1998
by adq
Courtesy of Fravia's page of reverse engineering
fra_00xx
98xxxx
handle
1100
NA
PC
Well, well: adq is back with a Linux reversing essay that will surely be welcome among the rapidly growing community of Linux users among my readers (I wonder how comes that noone that made the 'great sprung' and went from windoze to Linux, happened to go back to Windoze :-) As a matter of fact many good reversers are (almost) not publishing essays any more because they have lost any interest whatsoever in windozed targets... in fact -as you should know- if you'r seriously working (and not just playing with a mouse) you can work in Linux QUICKER, BETTER, and with a greater efficacity... I guess that the last one of my readers remaining in windoze will have soon to turn the lights off in an empty room... you don't believe me? Look better around you: see Micro$oft's building over there? Getting dark isn't it? That's because there are less and less people behind its windows... :-)
There is a crack, a crack in everything That's how the light gets in
Rating
( )Beginner (x)Intermediate ( )Advanced ( )Expert

This is for anyone running linux with gcc and who knows a bit of C.
Linux cracking
How to crack in Linux without a disassembler
Written by adq


Introduction
The following describes how to modify the behaviour of a linux program by replacing any external library functions it uses.

Tools required
Linux, gcc, emacs

Essay
I have been reading the various other essays on linux, but no one else seems to have mentioned this very easy way of modifying a compiled program's behaviour... without even looking at a disassembly.

First of all, write a demo program, called timetest:

                   #include <stdio.h>
                   #include <time.h>

                   int main(int argc, char* argv[])
                   {
                     time_t curTime;
                     struct tm *curTimeDecoded;

                     time(&curTime);
                     curTimeDecoded = localtime(&curTime);
                  
                     if (curTimeDecoded->tm_year > 95)
                       printf("Too late\n");
                     else
                       printf("In time\n");
                   }
                 
Put this in a file, "timetest.c", and compile as follows:
                         gcc -o timetest timetest.c
                 
You will end up with a program which checks the year. If the year is more than 1995, it will print "Too late". If less than or equal to 1995, it prints "In time". To patch this in windows so that it always prints "In time", would be a simple matter of loading the thing into a debugger, tracing through it to find the call & patching it. Or perhaps you prefer to use a dead-listing and IDA.

On linux, there is another, much easier way. Edit a new file, this time called "time.c", and put the following in it: called "time.c", and put the following in it:

                   #include <time.h>
                   #include <stdio.h>

                   time_t time(time_t* tp)
                   {
                     printf("haha\n");
                   
                     return(2000);
                   }
                 
As you can see, this is a replacement time() function, which prints "haha", and returns a system time of 2000.

This time, compile it as follows:

                         gcc -c time.c -o time.o
                         ld -shared -o time.so time.o
                 
The second line transforms the normal object file produced by the first line into a shared object library. This step is essential, or you will end up with strange errors such as "ELF file's phentsize not the expected size".

Now, to fix the program, type "export LD_PRELOAD=./time.so". This instructs the linux runtime linker (ld.so* or ld-linux.so*) to look in this library for functions before consulting the normal system libraries, when it is attempting to satisfy the program's dependencies.

Run the program, and it will print "haha", followed by "In time", no matter what the system time is. Be warned though... since you exported LD_PRELOAD, this will affect every program in your current shell until you either unset LD_PRELOAD, or exit the shell.

However, there is a slight problem. If you only want to fiddle the times on certain occasions, but use the normal time() call on others, you cannot simply call time() - that will call yourself and you will end up with a nasty recursive loop. The way I got round this was by finding the import table in the ELF binary, and changing the name of the function it imports from "time" to something like "Xime". Then, I wrote my own version of Xime, which is obviously then free to call the real time() function, since we haven't overridden it. This can all be done within emacs, using normal text search & replace. There is probably a better way to do this though.



Final Notes
I wish windows could do this :)

Ob Duh

doesn't apply

You are deep inside fravia's page of reverse engineering, choose your way out:

redhomepage redlinks redsearch_forms red+ORC redstudents' essays redacademy database
redreality cracking redhow to search redjavascript wars
redtools redanonymity academy redcocktails redantismut CGI-scripts redmail_fravia+
redIs reverse engineering legal?