【问题标题】:Problems on injecting into printf using LD_PRELOAD method使用 LD_PRELOAD 方法注入 printf 的问题
【发布时间】:2009-10-16 07:51:05
【问题描述】:

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

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

  1. 编译main.c gcc –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”而不是“within my own printf”。破解 malloc/free 函数时,没关系。

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

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

【问题讨论】:

    标签: hook code-injection glibc


    【解决方案1】:

    然而,这个问题很古老:

    在您的main.c 中,最后有一个换行符,并且没有使用printf 的任何格式化功能。

    如果我查看LD_DEBUG=all LD_PRELOAD=./printhack.so hello 2&gt;&amp;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]
    

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

    为了使您的示例正常工作,我从printf 中删除了\n,这给了我如下输出:

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

    【讨论】:

    • 有没有办法关闭 gcc 将函数 printf() 更改为 puts() ?
    【解决方案2】:

    检查 1)预处理器输出。 printf 可以改成别的东西

    gcc -E main.c
    

    2) 关于 printf 符号和预加载的 ld_debug 信息

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

    【讨论】:

      【解决方案3】:

      改变

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-07-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-15
        • 1970-01-01
        • 1970-01-01
        • 2011-03-25
        相关资源
        最近更新 更多