内存复制功能

标签 c linux assembly

我正在尝试 Hook 一个 linux 程序的函数。 基本上是使用 mprotect 搜索解除对函数的保护,然后将 jmp 放入原始函数地址中,重定向到我的函数 Hook 。

但是我想复制原始函数,以便在不需要修改后的函数时调用它。 我会有一种像这样的钩子(Hook)

int CallHookedFunctionFoobar(int param1, int param2)
{
      if (g_somevariable)
           Foobar_original(param1, param2);
      else
           Foobar_modified(param1, param2);
}

所以我的问题是......我怎么知道一个函数的大小(以字节为单位),以便我可以将它 memcpy() 到一个动态分配的缓冲区来执行它?

我考虑过可能嵌入一个小长度的反汇编器并解析操作码,直到找到 RETN 光码,但我不确定它是否适用于所有情况(例如,如果多个 RETN 驻留在同一函数中:[ )

我想这样做的另一个原因是因为同一个函数可能已经被另一个库 Hook 了..

最佳答案

首先,如果这是特定于 Linux 的,那么您的可执行文件很可能是 ELF 二进制文件。因此,您可以只解析 ELF header (例如,使用 libelf)来查找/计算函数的长度。

但是,我不明白您为什么需要这个。我能想到的一种更简单的方法是即时修补函数,用 JMPCALL 替换它的前几条指令到钩子(Hook)函数,同时保存那些被覆盖的指令稍后修补它。像这样的东西:

void call_hooked(void (*fn)(), unsigned char *ctx, size_t *n)
{
    unsigned char hook_patch[] = { 0x15, 0x20, 0x7f, 0x48 }; // I bluffed
    *n = sizeof(hook_patch);
    memcpy(ctx, fn, sizeof(hook_patch));
    memcpy(fn, hook_patch, sizeof(hook_patch));
    fn();
}

void call_orig(void (*fn)(), unsigned char *ctx, size_t n)
{
    memcpy(fn, ctx, n);
    fn();
}

关于内存复制功能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15933992/

相关文章:

c - 内联 asm 代码组织

windows - 如何在 Windows 上的 x86-64 架构上的程序集中注册结构化异常处理程序?

c - Linux 内核模块 - 生成两个具有共享本地 header 的模块

c - 没有递归调用的递归?

c - 使用 fscanf() 读取文件的下一行

c - 从 TCP 套接字接收到的错误文件描述符

c - 链接 c 和程序集

c - 为什么有些函数不涉及内核?

linux - docker run 的命令行参数

python - 如何在 Linux 中显示进程状态(阻塞、非阻塞)