Problems on injecting into printf using LD_PRELOAD method

廉价感情. 提交于 2019-12-10 11:31:08

问题


I was hacking printf() of glibc in one of my project and encountered some problem. Could you please give some clues? And one of my concern is why the same solution for malloc/free works perfect!

As attached, “PrintfHank.c” contains my own solution of printf() which will be preloaded before standard library; and “main.c” just outputs a sentence using printf(). After editing two files, I issued following commands:

  1. compile main.c gcc –Wall –o main main.c
  2. create my own library gcc –Wall –fPIC –shared –o PrintfHank.so PrintfHank.c –ldl
  3. test the new library LD_PRELOAD=”$mypath/PrintfHank.so” $mypath/main

But I received “hello world” instead of “within my own printf” in the console. When hacking malloc/free functions, it’s okay.

I log in my system as “root” and am using 2.6.23.1-42.fc8-i686. Any comments will be highly 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");
}

回答1:


This question is ancient, however:

In your main.c, you've got a newline at the end and aren't using any of the formatting capability of printf.

If I look at the output of LD_DEBUG=all LD_PRELOAD=./printhack.so hello 2>&1 (I've renamed your files somewhat), then near the bottom I can 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 of printf. puts is basically printf without the formatting and with an automatic line break at the end, so this evidently the result of gcc being "helpful" by replacing the printf with a puts.

To make your example work, I removed the \n from the printf, which gives me output like:

 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 that printhack.so is indeed being dragged in with its custom printf.

Alternatively, you can define a custom puts function as well:

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



回答2:


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

gcc -E main.c

2) ld_debug info about printf symbol and preloading

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



回答3:


Change

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

to

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


来源:https://stackoverflow.com/questions/1576689/problems-on-injecting-into-printf-using-ld-preload-method

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!