运行中的C程序可以访问自己的符号表吗?

我有一个处理发送到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)

如果您希望这样做是安全的,您应该创建许可符号的白名单.

相关文章

本程序的编译和运行环境如下(如果有运行方面的问题欢迎在评...
水了一学期的院选修,万万没想到期末考试还有比较硬核的编程...
补充一下,先前文章末尾给出的下载链接的完整代码含有部分C&...
思路如标题所说采用模N取余法,难点是这个除法过程如何实现。...
本篇博客有更新!!!更新后效果图如下: 文章末尾的完整代码...
刚开始学习模块化程序设计时,估计大家都被形参和实参搞迷糊...