Search This Blog

Wednesday, October 7, 2009

DLL Injection

DLL Injection is a method by which some code is run within the address space of any process by forcing it to load a dynamic-link library.

Library interposition is a useful technique for tuning performance, collecting runtime statistics, or debugging applications. With dynamic linking, you can intercept any function call an application makes to any shared library. Once you intercept it, you can do whatever you want in that function, as well as call the real function the application originally intended to call.

However this feature may also be exploited for some malicious use.

In Linux, the environment variable LD_PRELOAD allows specified libraries to be loaded before any other code.

This variable if set to some code which has a function in it with the constructor attribute, then the control will always go the library code first and then to any other code.

lets look at an example,
The code which will be loaded dynamically :


//demo.c

void __attribute__((constructor)) init() {
printf("How did it come to me??? ;) ;) ");
}

//End of file demo.c

$ gcc -shared demo.c -o demo.so -fPIC
$ export LD_PRELOAD=$PWD/demo.so true

Now execute any command :

$ ls
How did it come to me??? ;) ;) a aj.c a.out arr.s demo.so demo.c

$ gcc a.c
How did it come to me??? ;) ;) How did it come to me??? ;) ;) How did it come to me??? ;) ;) How did it come to me??? ;) ;) How did it come to me??? ;) ;)

$ ps
How did it come to me??? ;) ;) PID TTY TIME CMD
24126 pts/61 00:00:00 ps
28996 pts/61 00:00:00 bash



It doesnt end here...There is something more to it.
As the man page for LD_PRELOAD states "This can be used to selectively override functions in other shared libraries."

see this :

// --- demo.c ---

int printf(char *s, ...) {
fprintf(stdout, "Where is ur printf??? ;) ;) ");
}

// End of demo.c

// --- a.c ----

int main()
{
printf("Hello world");
}

// End of a.c

$ gcc a.c
$ ./a.out
Where is ur printf??? ;) ;)



One way out is.... using static-linking.....
eg :
For the above printf wala code

$ gcc -static a.c
$ ./a.out
Hello



This is because if static linking is done, the control never goes to the dynamic linker as u see below :

$ readelf -d a.out

There is no dynamic segment in this file.

Sunday, October 4, 2009

Allocating memory on heap and stack

The very famous "malloc" allocates space on the heap and returns a pointer to the allocated space.

But there also exists a function which can allocate space on stack frame.

The "alloca" function allocates size bytes of space in the stack frame of the caller. This temporary space is automatically freed when the function that called alloca returns to its caller.

The alloca function returns a pointer to the beginning of the allocated space. However, if the allocation causes stack overflow, program behaviour is undefined.

Allocation on the stack is more convenient and cheaper, but the maximum stack size is limited. It may cause stack overflow if your program allocates large memory on the stack. In addition, allocating large arrays on the stack may fool valgrind . Usually, large arrays should be allocated on the heap.


example :
With malloc :

#include

int main()
{
char *str = (char *)malloc(sizeof(char) * 10);
printf("%p\n",str);
printf("PID = %d\n",getpid());
getchar();
}



$ ./a.out
0x804a008
PID = 16637



$ cat /proc/16637/maps
08048000-08049000 r-xp 00000000 00:15 18172215 /home/fshaikh/trial/a.out
08049000-0804a000 rwxp 00000000 00:15 18172215 /home/fshaikh/trial/a.out
0804a000-0806b000 rwxp 0804a000 00:00 0 [heap]
f7e3d000-f7e3e000 rwxp f7e3d000 00:00 0
f7e3e000-f7f68000 r-xp 00000000 fe:00 1509438 /lib/tls/libc-2.3.2.so
f7f68000-f7f71000 rwxp 00129000 fe:00 1509438 /lib/tls/libc-2.3.2.so
f7f71000-f7f73000 rwxp f7f71000 00:00 0
f7f79000-f7f7c000 rwxp f7f79000 00:00 0
f7f7c000-f7f92000 r-xp 00000000 fe:00 1474565 /lib/ld-2.3.2.so
f7f92000-f7f93000 rwxp 00015000 fe:00 1474565 /lib/ld-2.3.2.so
ffb03000-ffb05000 rw-p ffb03000 00:00 0 [stack]
ffffe000-fffff000 r-xp ffffe000 00:00 0 [vdso]



With alloca :

#include

int main()
{
char *str = (char *)alloca(sizeof(char) * 10);
printf("%p\n",str);
printf("PID = %d\n",getpid());
getchar();
}

$ ./a.out
0xfff26c08
PID = 1324

$ cat /proc/1324/maps
08048000-08049000 r-xp 00000000 00:15 18172215 /home/fshaikh/trial/a.out
08049000-0804a000 rwxp 00000000 00:15 18172215 /home/fshaikh/trial/a.out
f7df0000-f7df1000 rwxp f7df0000 00:00 0
f7df1000-f7f1b000 r-xp 00000000 fe:00 1509438 /lib/tls/libc-2.3.2.so
f7f1b000-f7f24000 rwxp 00129000 fe:00 1509438 /lib/tls/libc-2.3.2.so
f7f24000-f7f26000 rwxp f7f24000 00:00 0
f7f2c000-f7f2f000 rwxp f7f2c000 00:00 0
f7f2f000-f7f45000 r-xp 00000000 fe:00 1474565 /lib/ld-2.3.2.so
f7f45000-f7f46000 rwxp 00015000 fe:00 1474565 /lib/ld-2.3.2.so
fff26000-fff28000 rw-p fff26000 00:00 0 [stack]
ffffe000-fffff000 r-xp ffffe000 00:00 0 [vdso]