使用LD_PRELOAD方法注入printf时出现问题
我在我的一个项目中破解了 glibc 的 printf() 并遇到了一些问题。您能提供一些线索吗?我关心的问题之一是为什么同样的 malloc/free 解决方案可以完美地工作!
如附件所示,“PrintfHank.c”包含我自己的 printf() 解决方案,它将在标准库之前预加载;而“main.c”只是使用 printf() 输出一个句子。编辑两个文件后,我发出以下命令:
- compile main.c gcc –Wall –o main main.c
- 创建我自己的库 gcc –Wall –fPIC –shared –o PrintfHank.so PrintfHank.c –ldl
- 测试新库 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");
}
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:
- compile main.c
gcc –Wall –o main main.c - create my own library
gcc –Wall –fPIC –shared –o PrintfHank.so PrintfHank.c –ldl - 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");
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
然而,这个问题很古老:
在您的
main.c
中,您的末尾有一个换行符,并且没有使用printf
的任何格式化功能。如果我查看
LD_DEBUG=all LD_PRELOAD=./printhack.so hello 2>&1
的输出(我已经稍微重命名了你的文件),那么在底部附近我可以看到并没有实际的提到
printf
。puts
基本上是没有格式的 printf,并且在末尾有一个自动换行符,所以这显然是 gcc 通过用printf
替换printf
来“帮助”的结果>放置。为了使您的示例正常工作,我从
printf
中删除了\n
,它给出的输出如下:现在我可以看到
printhack.so
确实是被它的自定义printf
拖进来的。或者,您也可以定义自定义
puts
函数: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 ofprintf
.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 seeand 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 theprintf
with aputs
.To make your example work, I removed the
\n
from theprintf
, which gives me output like:Now I can see that
printhack.so
is indeed being dragged in with its customprintf
.Alternatively, you can define a custom
puts
function as well:查看
1) 预处理器输出。 printf 可以更改为 smth else
2) 有关 printf 符号和预加载的 ld_debug 信息
Check
1) preprocessor output. printf can be changed to smth else
2) ld_debug info about printf symbol and preloading
更改
为
Change
to