在运行时有条件地替换C函数

6vl6ewon  于 2023-03-01  发布在  其他
关注(0)|答案(2)|浏览(109)

在C语言中,是否可以在运行时有条件地替换函数(特别是动态加载库中的函数)?
我知道您可以使用LD_PRELOAD或创建一个同名函数,例如:

// Silly example intercepting exit
typedef void (*exit_func)(int code);

void exit(int code)
{
    exit_func orig_exit = (exit_func)dlsym(RTLD_NEXT, "exit");

    NSLog(@"EXIT CALLED WITH CODE %d!!!!", code);

    orig_exit(code);
}

然而,在程序加载并运行之后,是否有可能在运行时有条件地替换函数?

if(some_condition)
{
    swap_impementations(exit, my_exit);
}

编辑:这有点类似于Is it possible to swap C functions?,但具体来说,我试图拦截对操作系统加载的另一个库中的函数的调用。
这意味着,例如,如果我从stdlib截取exit()函数,那么从ANYWHERE对exit()的任何调用都会调用我的实现,而不是原来的实现,这与我上面的示例非常相似,只是在运行时可控。
有人建议通过使用跳转指令覆盖原始函数来钩住调用,但我希望有一些不需要占用可执行内存的东西,比如我可以在动态链接器中调用一些东西,以便在程序启动后“重新链接”函数并将其指向其他地方。

vqlkdk9b

vqlkdk9b1#

为此,请使用函数指针。

svmlkihl

svmlkihl2#

其他人说你可以用函数指针来完成这个任务,这是正确的。
1.为要替换的函数定义一个存根(以确保它始终被定义)
1.定义与签名匹配的类型
1.创建指向存根的指针
1.使用宏替换存根指针对function_to_replace的所有调用

#include <stdio.h>

void
function_to_replace (char * message)
{
  printf ("%s\n", message);
}

/* 1. Define a stub for the library function */
void stub_for_function_to_replace(char * message)
{
  printf ("the function was replaced!\n");
}

/* 2. Define a new type for the function pointer */
typedef void function_to_replace_t(char * message);

/* 3. Create a function pointer to the stub */
function_to_replace_t * function_to_replace_ = stub_for_function_to_replace;

/* 4. Replace all instances of the original function call with the function pointer */
#define function_to_replace function_to_replace_

int
main (void)
{
  char * message = "hello, world!";

  function_to_replace(message);

  return (0);
}

相关问题