C 如何通过名称获取函数地址?

C 如何通过名称获取函数地址?,c,function,dynamic-linking,C,Function,Dynamic Linking,我想按名称获取函数的地址 例如,目前我正在使用dlsym: unsigned long get_func_addr(const char *func_name) { return (unsigned long)dlsym(NULL, func_name); } 但是,dlsym仅适用于外部功能。它不适用于静态函数。我知道在不同的文件中可能有多个同名的静态函数。但我需要至少获得一个静态函数的地址和名称。有时静态函数将被内联。但若C文件是用debug编译的,那个就没问题了。我认为使用-g

我想按名称获取函数的地址

例如,目前我正在使用
dlsym

unsigned long get_func_addr(const char *func_name)
{
     return (unsigned long)dlsym(NULL, func_name);
}
但是,
dlsym
仅适用于外部功能。它不适用于静态函数。我知道在不同的文件中可能有多个同名的静态函数。但我需要至少获得一个静态函数的地址和名称。有时静态函数将被内联。但若C文件是用debug编译的,那个就没问题了。我认为使用
-g
,静态函数的符号表是存在的,但是如何访问它呢


我不想创建一个将字符串映射到函数地址的表。我需要找到一种动态执行的方法。

如果不创建一些可用于查找的外部文件,这是不可能的。。。例如,正如您所提到的,静态函数的符号表是存在的,但它是在编译/链接时生成的。。。它不能从非编译代码模块访问


因此,基本上您可以从编译和链接的可执行文件中生成符号表并将其导出为外部文件,然后在外部文件中动态查找函数名,该文件将提供获取编译器和链接器编译/链接到的函数地址所需的信息。

a
static
函数甚至不需要存在于二进制文件中,因此无法获取其地址。即使它确实存在,编译器可能已经根据某些参数只能接受特定值的知识对其进行了修改,或者可能已经对调用约定进行了调整,使其不可从外部调用,等等。这是确保“真实”的唯一方法静态函数的存在版本取决于其地址是否通过函数指针对其他模块可见。

如果要查找的所需函数位于DLL中,则可以使用Windows API
getprocaddress()
,它将函数名和DLL名作为参数

如果要查找用户定义的函数,我建议使用查找表,因为这些函数的名称不存储

对于用户定义的函数,可以强制每个函数在开始时将其名称导出到另一个函数。i、 e:

void my_func()
{
    register(my_func,"my_func");// the address and the name
    // ...
}

因此,您可以稍后按名称查找函数。

使用
stdint.h
中的
uintptr\u t
而不是
无符号long
。为什么要这样做?如果您能够保证在调试模式下编译带有静态的模块,那么您应该能够使函数成为非静态的,或者为它添加一个简单的非静态包装器。因此,这个问题有一些关于如何读取调试符号的信息:“我不想创建一个表来将字符串映射到函数地址。”你要找的东西叫做magic。
nm
会给你符号地址(包括函数),如果你在文件中有调试符号。我想这是可能的。要知道,backtrace()可以从地址中获取函数名。扩展backtrace以支持从name获取地址应该不太困难。是的,但是
backtrace()
是由
libc
实现的函数,因此是运行可执行文件的操作系统运行时的一部分。如果您有另一个程序正在为您的C可执行文件创建虚拟运行时,那么您还可以创建可从您的可执行文件调用的函数,其中运行时可以检查您的进程,然后将信息返回给您(即ptrace、调试器等)。但是,除非运行时在可执行文件和自身之间创建了一种通信方法,否则从您自己的代码中就不可能实现这一点。