我有一个处理发送到TCP套接字(绑定到特定端口)的请求的
linux C程序.我想通过对该端口的请求来查询C程序的内部状态,但是我不想硬编码可以查询哪些全局变量.因此,我希望查询包含全局的字符串名称和C代码,以便在符号表中查找该字符串,以查找其地址,然后通过TCP套接字发送其值.当然,符号表不能被剥离. C程序甚至可以找到自己的符号表,还有一个用于查找符号的库界面?这是一个使用gcc构建的ELF可执行程序C程序.
解决方法
这其实很容易.您可以使用dlopen / dlsym来访问符号.为了使其工作,符号必须存在于动态符号表中.有多个符号表!
#include <dlfcn.h> #include <stdio.h> __attribute__((visibility("default"))) const char A[] = "Value of A"; __attribute__((visibility("hidden"))) const char B[] = "Value of B"; const char C[] = "Value of C"; int main(int argc,char *argv[]) { void *hdl; const char *ptr; int i; hdl = dlopen(NULL,0); for (i = 1; i < argc; ++i) { ptr = dlsym(hdl,argv[i]); printf("%s = %s\n",argv[i],ptr); } return 0; }
为了将所有符号添加到动态符号表中,请使用-Wl,– export-dynamic.如果要从符号表中删除大多数符号(推荐),请设置-fvisibility = hidden,然后使用__attribute __((visibility(“default”)))或其他方法之一显式添加所需的符号.
~ $gcc dlopentest.c -Wall -Wextra -ldl ~ $./a.out A B C A = (null) B = (null) C = (null) ~ $gcc dlopentest.c -Wall -Wextra -ldl -Wl,--export-dynamic ~ $./a.out A B C A = Value of A B = (null) C = Value of C ~ $gcc dlopentest.c -Wall -Wextra -ldl -Wl,--export-dynamic -fvisibility=hidden ~ $./a.out A B C A = Value of A B = (null) C = (null)
安全
请注意,存在很多不良行为的空间.
$./a.out printf printf = ▯▯▯▯ (garbage)
如果您希望这样做是安全的,您应该创建许可符号的白名单.