使用LD_PRELOAD方法注入printf时出现问题

2024-01-02

我在我的一个项目中破解了 glibc 的 printf() 并遇到了一些问题。您能提供一些线索吗?我关心的问题之一是为什么同样的 malloc/free 解决方案可以完美地工作!

如附件所示,“PrintfHank.c”包含我自己的 printf() 解决方案,它将在标准库之前预加载;而“main.c”只是使用 printf() 输出一个句子。编辑两个文件后,我发出以下命令:

  1. 编译main.cgcc –Wall –o main main.c
  2. 创建我自己的图书馆gcc –Wall –fPIC –shared –o PrintfHank.so PrintfHank.c –ldl
  3. 测试新库LD_PRELOAD=”$mypath/PrintfHank.so” $mypath/main

但我在控制台中收到“hello world”而不是“在我自己的 printf 中”。当破解 malloc/free 函数时,这是没问题的。

我以“root”身份登录系统并使用 2.6.23.1-42.fc8-i686。任何意见将不胜感激!

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

然而这个问题很古老:

In your main.c,您在末尾有一个换行符,并且没有使用任何格式化功能printf.

如果我看一下输出LD_DEBUG=all LD_PRELOAD=./printhack.so hello 2>&1(我稍微重命名了你的文件),然后在底部附近我可以看到

 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]

并且没有实际提及printf. puts基本上是 printf 没有格式并且在末尾有自动换行符,所以这显然是 gcc 通过替换“有帮助”的结果printf with a puts.

为了使您的示例正常工作,我删除了\n来自printf,这给了我这样的输出:

 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]

现在我可以看到printhack.so确实是被它的习俗所拖累printf.

或者,您可以定义自定义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");
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用LD_PRELOAD方法注入printf时出现问题 的相关文章

随机推荐