使用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时出现问题 的相关文章

  • 在非标准位置无需 root 即可使用 glibc 构建 GCC

    我有一个没有 root 访问权限的系统 但我需要安装当前版本的 GCC 4 7 2 该系统正在运行 Linux 2 6 18 的 x86 64 版本 并且已经有 GCC 4 1 没有 C 支持 尽管 version 说它是用它构建的 编辑5
  • 在 Codeigniter 中手动调用/调用挂钩

    我搜索了手动调用 调用钩子以及网上类似的东西 但找不到任何东西 codeigniter中有这样的东西吗 我下面有一个钩子 它会按预期触发 但以防万一没有触发 那么我想在代码中手动调用它 Thanks hook post controller
  • 有 2 个构造函数是正确的,一个用于依赖注入,另一个用于解决注入?

    我的类中有 2 个构造函数 public class CacheWebServices ICacheWebService public ICache apiConnector get set public CacheWebServices
  • 参数化语句能阻止所有SQL注入吗?

    如果是的话 为什么还有那么多成功的SQL注入呢 仅仅因为一些开发人员不使用参数化语句 当文章谈论参数化查询阻止 SQL 攻击时 他们并没有真正解释原因 通常是 确实如此 所以不要问为什么 可能是因为他们不了解自己 糟糕的教育者的一个明显标志
  • SpecFlow - 重试失败的测试

    有没有办法实现AfterScenario在失败的情况下重新运行当前测试的钩子 像这样的东西 AfterScenario retry public void Retry if ScenarioContext Current TestError
  • Prestashop - 付款验证后更改订单状态

    付款验证后 订单状态将变为 付款已验证 法语为 付款接受 我想在付款验证时设置另一个状态 因此历史记录将显示以下内容 Current status My personnal status History My personnal statu
  • BitBucket WebHook 詹金斯

    我想配置 bitbucket 来触发 jenkins 构建 我花了一些时间研究这个问题 所有答案都来自几年前 但没有找到任何指南 因为从那以后事情似乎发生了变化 我正在尝试做的事情 将位桶推送到特定分支会触发构建 我有什么 Bitbucke
  • 使用 webView 时是否可以将 HTML 表单中的数据获取到 android 中?

    我正在 HTML 中制作一个非常简单的表单 可以使用 webview 在 android 中查看 该 webview 使用文本框接收您的姓名 当您单击按钮时 它会将其显示到一个段落中 并且它是使用 html 和 javascript 制作的
  • MIPS 寄存器 $0 可以用来存储和检索值吗?

    当我了解 MIPS 处理器时 我的脑海中牢记着读取 0 寄存器总是返回 0 而写入 0 总是被丢弃 来自 MIPS 程序员手册 2 13 4 1 CPU 通用寄存器 r0 被硬连线到一个值 零 并且可以用作任何指令的目标寄存器 结果是被丢弃
  • C++ 代码注入使注入的应用程序崩溃

    我试图将一个简单的可执行文件注入到我制作的另一个可执行文件中 不幸的是 每当我将代码注入到可执行文件中时 它都会说 simpleinjected exe 已停止工作 然后它就会关闭 我在用着CreateRemoteThread来注入代码 这
  • glibc的MALLOC_CHECK_、M_CHECK_ACTION和mcheck有什么区别?

    glibc 似乎有不止一种方法来进行堆检查 mallopt 与 M CHECK ACTION 参数 MALLOC CHECK 环境变量 mcheck 函数系列 我发现可用的文档令人困惑 这manual http www gnu org so
  • Outlook 对象模型 - 连接到对话清理功能

    Outlook 2010 有一个功能称为对话清理 http office microsoft com en us outlook help use conversation clean up to eliminate redundant m
  • Git Server Hooks - 它们是在客户端/克隆机器上本地执行的吗?

    Setup 我在 Windows 计算机上有主存储库 在另一台 Windows 计算机上有一个克隆 在我的里面update钩子 我已经添加了ipconfig打印 IP 地址 我本想看到主机的 IP 地址 但它实际上打印出克隆的 IP 地址
  • pre_controller 钩子不会加载像 docs state 这样的基类?

    根据此处的 Codeigniter 文档 http ellislab com codeigniter user guide general hooks html http ellislab com codeigniter user guid
  • 仅 mysqldump 模式,模式更新不丢失

    我正在考虑在提交更改之前使用 git pre commit hook 导出 MySQL 数据库模式 以便其他开发人员可以使用 git 存储库中的 SQL 脚本更新自己的数据库 默认情况下 mysqldump 我正在使用 no data 会在
  • LD_PRELOAD 和 strace 有什么区别?

    这两种方法都用于收集系统调用及其参数和返回值 当我们更愿意LD PRELOAD为什么 也许我们可以说我们只能通过以下方式收集系统调用strace但我们可以收集图书馆的电话LD PRELOAD诡计 然而 还有另一个库的跟踪器 其名称是ltra
  • JSP 中的 CDI 注入

    在 JSP 中 可以使用 EL 表达式 例如 myBean myAttribute 来使用 CDI 托管 Bean 这里没问题 我想在 JSP 文件中使用 常规注入 即不使用 EL 表达式 和 Inject 例如 然后是 即使该示例可以使用
  • glibc 已弃用的 __malloc_hook 功能的替代方案

    我正在为 C 编写一个内存分析器 并为此拦截对malloc realloc and free通过 malloc hooks 函数 不幸的是 这些已被弃用 因为它们在多线程环境中表现不佳 我找不到描述实现相同目标的替代最佳实践解决方案的文档
  • 低级键盘钩子不在 UI 线程上

    我想为键盘挂钩创建一个好的库 我使用 SetWindowsHookEx 方法 我注意到如果我的应用程序的主线程繁忙 则应在任何系统 KeyDown 事件中调用的方法 hookProc 不会执行 我认为钩子应该这样制作 以便另一个线程负责它
  • git 预提交钩子格式代码 - Intellij/Android Studio

    本要点展示了如何在预提交时使用 Eclipse 格式化程序自动格式化 Java 代码 Source https gist github com ktoso 708972 https gist github com ktoso 708972

随机推荐