【问题标题】:Access a global static variable from a .so file without modifying library在不修改库的情况下从 .so 文件访问全局静态变量
【发布时间】:2019-01-11 10:47:34
【问题描述】:

我在一个库(.so 文件)中定义了一个全局静态变量,我想从我的应用程序中访问它。应用程序在运行时加载.so 库。

有没有办法在不修改库代码的情况下访问静态变量?我知道这并不简单,因为我看到一旦编译完成,变量符号本身就会从符号表中消失。我仍然认为可能有一些 hacky 方式(通过爬取符号表等)来访问这个变量。有什么帮助吗?

lib.c -> static struct Abc abc --> compiled to a.so
app.c ->loads a.so and need to access abc variable?

更新:a.so 使用 gcc -O2 option 编译。

【问题讨论】:

    标签: c compiler-construction


    【解决方案1】:

    这是不可能的,因为static 全局变量的想法是让它对除当前编译单元之外的任何东西都不可见

    如果库开发人员将对象设为静态,可能是出于某种原因,并且他不希望在库代码之外访问该对象

    【讨论】:

    • 这个答案错误的结论是,因为 C 的语义排除了 C 语义内的解决方案,所以没有解决方案是可能的。但是,该问题要求采用“hacky way”,这意味着 C 语义之外的解决方案是可以接受的,而这个答案没有考虑到这一点。
    【解决方案2】:

    一般来说,静态全局变量不能被访问是正确的。在某些情况下,它甚至可能被优化掉,因此根本不存在固定的内存位置。

    但如果它没有被优化掉,那么当然总会有“hackish”的方式来访问它。然而,爬取符号表不是一种选择,因为符号通常不在那里列出。您必须更深入地研究汇编代码。此示例适用于具有 gcc 和 x86_64 cpu 的 linux。它假定源可用,以识别汇编代码中的变量访问。

    想象以下共享对象源文件:

    static int bar = 31337;
    
    int foo (void) {
        bar = getpid();
    }
    

    bar 是你的静态变量。现在,您可以通过检查反汇编的源代码,从函数 foo 中找出 bar 的偏移量 - 尽管整个库已重新定位,但它始终保持不变:

    objdump -x shared.so

    00000000000006a0 <foo>:
     6a0:   48 83 ec 08             sub    $0x8,%rsp
     6a4:   31 c0                   xor    %eax,%eax
     6a6:   e8 c5 fe ff ff          callq  570 <getpid@plt>
     6ab:   89 05 c7 02 20 00       mov    %eax,0x2002c7(%rip)        # 200978 <_fini+0x2002c0>
     6b1:   48 83 c4 08             add    $0x8,%rsp
     6b5:   c3                      retq  
    

    在这里,您看到函数foo 的地址为6a0(稍后会重新定位),静态全局变量bar 在地址200978 上被访问,这使得总偏移量为200978-6a0 = 2002D8。所以如果你打开共享库

    void *h = dlopen("shared.so", RTLD_LAZY);
    

    并查找符号foo

    void *foo = dlsym(h, "foo");
    

    你可以通过添加计算出的偏移量来计算bar的地址:

    int *a = foo + 0x2002D8;
    printf("%d\n", *a);
    

    根据要求,一种骇人听闻的方式;)

    【讨论】:

    • 但它需要修改 OP 想要避免的库源代码
    • @P__J__ 不,此方法不需要更改库源代码。那应该是哪一步?
    • @P__J__ 来吧,给我一个库和一个静态变量,我会在几分钟内为你完成
    • 此答案省略了两个步骤:(a) 识别对源代码中变量的访问,(b) 识别相应的目标代码。问题并没有说源代码可用,所以(a)可能是不可能的。
    • @EricPostpischil 问题暗示,源是可用的,因为静态变量的存在及其相关性/语义根本不知道。
    猜你喜欢
    • 2022-11-07
    • 1970-01-01
    • 2010-12-30
    • 1970-01-01
    • 2012-08-11
    • 1970-01-01
    • 2014-04-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多