Injection problems in printf using LD_PRELOAD method
I hacked printf () glibc in one of my projects and ran into some problems. Can you provide some hints? And one of my problems is why the same malloc / free solution works great!
As stated, "PrintfHank.c" contains my own printf () solution, which will be preloaded before the standard library; and "main.c" just prints out the statement using printf (). After editing two files, I issued the following commands:
- compile main.c gcc -Wall -o main main.c
- create your own library gcc -Wall -fPIC -shared -o PrintfHank.so PrintfHank.c -ldl
- check out new library LD_PRELOAD = "$ mypath / PrintfHank.so" $ mypath / main
But I got "hello world" instead of "in my own printf" in the console. When hacking malloc / free functions, everything is fine.
I am logged in as "root" and am using 2.6.23.1-42.fc8-i686. Any comments would be much appreciated!
main.c
#include <stdio.h>
int main(void)
{
printf("hello world\n");
return 0;
}
PrintfHank.c
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#include <stdio.h>
#include <dlfcn.h>
static int (*orig_printf)(const char *format, ...) = NULL;
int printf(const char *format, ...)
{
if (orig_printf == NULL)
{
orig_printf = (int (*)(const char *format, ...))dlsym(RTLD_NEXT, "printf");
}
// TODO: print desired message from caller.
return orig_printf("within my own printf\n");
}
source to share
This question is ancient, however:
In main.c
you have a newline at the end and does not use the formatting capabilities printf
.
If I look at the output LD_DEBUG=all LD_PRELOAD=./printhack.so hello 2>&1
(I renamed your files somewhat), then closer to the bottom I see
17246: transferring control: ./hello
17246:
17246: symbol=puts; lookup in file=./hello [0]
17246: symbol=puts; lookup in file=./printhack.so [0]
17246: symbol=puts; lookup in file=/lib/x86_64-linux-gnu/libc.so.6 [0]
17246: binding file ./hello [0] to /lib/x86_64-linux-gnu/libc.so.6 [0]: normal symbol `puts' [GLIBC_2.2.5]
and no actual mention printf
. puts
basically printf without formatting and with automatic line break at the end, so obviously the gcc output is "useful" replacing printf
with puts
.
To make your example work, I removed \n
from printf
which gives me the output, for example:
17114: transferring control: ./hello
17114:
17114: symbol=printf; lookup in file=./hello [0]
17114: symbol=printf; lookup in file=./printhack.so [0]
17114: binding file ./hello [0] to ./printhack.so [0]: normal symbol `printf' [GLIBC_2.2.5]
Now I can see what is printhack.so
actually being dragged with my custom printf
.
Alternatively, you can also define a custom function puts
:
static int (*orig_puts)(const char *str) = NULL;
int puts(const char *str)
{
if (orig_puts == NULL)
{
orig_puts = (int (*)(const char *str))dlsym(RTLD_NEXT, "puts");
}
// TODO: print desired message from caller.
return orig_puts("within my own puts");
}
source to share