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");
}

      

+2


source to share


3 answers


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");
}

      

+3


source


Check 1) preprocessor output. printf can be changed to smth else

gcc -E main.c

      



2) ld_debug information about printf symbol and preload

LD_DEBUG=help LD_PRELOAD="$mypath/PrintfHank.so" $mypath/main
LD_DEBUG=all LD_PRELOAD="$mypath/PrintfHank.so" $mypath/main

      

+1


source


Edit

return orig_printf("within my own printf\n");

      

to

return (*orig_printf)("within my own printf\n");

      

+1


source







All Articles