微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

运行中的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)

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

原文地址:https://www.jb51.cc/c/113587.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐