【问题标题】:How to dynamically interpose C functions from Python on Linux (without LD_PRELOAD)?如何在 Linux 上从 Python 动态插入 C 函数(没有 LD_PRELOAD)?
【发布时间】:2011-02-03 23:28:10
【问题描述】:

我如何在运行时(没有LD_PRELOAD)在Linux 上拦截/挂钩像fopen() 这样的C 函数,就像Windows 的Detours 一样?我想从 Python 执行此操作(因此,我假设该程序已经在运行 CPython VM)并且还重新路由到 Python 代码。我只需要挂钩共享库函数就可以了。我也想这样做,而不必改变程序的运行方式。

一个想法是基于ptrace() 推出我自己的工具,或者重写在dlsym() 或PLT 中找到的代码,并以ctypes 生成的C 可调用函数为目标,但我想我会问先到这里。谢谢。

【问题讨论】:

  • 你会如何使用 LD_PRELOAD?
  • 您需要编写一个本地模块来为您完成底层工作。即使您设法从 Python 访问和修改 PLT(这很可能),您也需要代码来启动 Python VM。
  • @Matt Joiner:顺便说一句,你问你的问题,我认为你不喜欢我说的话,在这种情况下,如果你能更具体一些,它将是富有成效/建设性的。但如果你真的只是在问,这就是你如何以非动态方式进行函数插入:stackoverflow.com/questions/426230/what-is-the-ld-preload-trick(是的,我之前已经应用过很多次了)
  • @Glenn Maynard:抱歉,如果我的问题不清楚 - 我提到我想从 Python 中执行此操作,因此假设 VM 已经在运行。但无论如何,我调整了问题以澄清这一点。从 Python 操作 PLT 正是我和我的稻草人的目的。
  • 这不是创建虚拟机实例,而是调用它;您不能将 PLT 指向 Python 函数,毕竟您需要将其指向调用 Python 运行时并运行所需函数的本机代码。

标签: python linux library-interposition


【解决方案1】:

你会从一个 ltrace 开发者那里找到一种方法来做到这一点。请参阅this post,其中包括一个完整的补丁程序以捕获动态加载的库。为了从 python 中调用它,你可能需要创建一个 C 模块。

【讨论】:

    【解决方案2】:

    google-perftools 在 src/windows/preamble_patcher* 下有自己的 Detour 实现。目前这是仅限于 Windows 的,但我看不出有任何理由它不能在任何 x86 机器上运行,除了它使用 win32 函数来查找符号地址这一事实。

    快速扫描代码,我看到使用了这些 win32 函数,所有这些函数都有 linux 版本:

    • GetModuleHandle/GetProcAddress : 获取函数地址。 dlsym 可以做到这一点。
    • VirtualProtect:允许修改程序集。保护。
    • GetCurrentProcess:getpid
    • FlushInstructionCache(根据 cmets 显然是一个 nop)

    将其编译并链接到 python 似乎并不难,但我会向 perftools 开发人员发送一条消息,看看他们的想法。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-19
    • 2014-03-18
    • 2011-04-06
    • 2015-01-17
    相关资源
    最近更新 更多