繁体   English   中英

如何修补 3rd party.so 文件,以访问非导出符号 (C++)

[英]How to patch 3rd party .so file, to access non-exported symbol (C++)

我有一些专有格式的二进制.fic文件,我有一个来自该供应商的wd250hf64.so ,其中包含 C++ 方法CComposanteHyperFile::HExporteXML(wchar_t* const path)

我可以看到使用 nm

$ nm  --demangle   wd250hf64.so  --defined-only 


0000000000118c90 t CComposanteHyperFile::HExporteXML(wchar_t const*)

未损坏的版本_ZN20CComposanteHyperFile11HExporteXMLEPKw与我使用本地 g++ 版本的版本相同

readelf 给

readelf -Ws wd250hf64.so  | grep _ZN20CComposanteHyperFile11HExporteXMLEPK

 19684: 0000000000118c90   119 FUNC    LOCAL  DEFAULT   11 _ZN20CComposanteHyperFile11HExporteXMLEPKw

现在我尝试编写一个非常简单的程序

class CComposanteHyperFile {
    public:
    static void  HExporteXML(wchar_t const*);
};



int main() {
    CComposanteHyperFile::HExporteXML(L"file.fic");
    return 0;
}

但是当我用g++ toto.cpp -L. -l:wd250hf64.so g++ toto.cpp -L. -l:wd250hf64.so

我得到了toto.cpp:(.text+0x10): undefined reference to 'CComposanteHyperFile::HExporteXML(wchar_t const*)'

我对dlopen没有更多的运气

#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>

int
main(int argc, char **argv)
{
    void *handle;
    void (*exportXML)(wchar_t const*);
    char *error;

   handle = dlopen("wd250hf64.so", RTLD_LAZY);
   *(void **) (&exportXML) = dlsym(handle, "_ZN20CComposanteHyperFile11HExporteXMLEPKw");

   if ((error = dlerror()) != NULL)  {
        fprintf(stderr, "%s\n", error);
        exit(EXIT_FAILURE);
    }

    dlclose(handle);
    exit(EXIT_SUCCESS);
}
gcc -rdynamic -o foo toto.c -ldl
./foo
wd250hf64.so: undefined symbol: _ZN20CComposanteHyperFile11HExporteXMLEPKw

我知道,由于 nm 没有用--extern-only显示它,可能是这个符号没有“导出”,所以它不应该正常工作

我的问题是

无论如何,即使这意味着手动修补.so文件,使程序编译的黑客方式是什么?

如果您真的希望能够以任何可能的方式获取该符号,则可以尝试获取其相对于已知导出符号的地址,假设它们位于同一部分中。 例如,我制作了一个简单的虚拟库,其中一个导出的 function 和一个未导出的 function。

0x0000000000003890    12 FUNC    GLOBAL DEFAULT    16 function_we_exported
0x00000000000038a0    12 FUNC    LOCAL  HIDDEN     16 function_we_forgot_to_export

因为这个库只是为了这个答案而设计的,所以未导出的 function 恰好在它旁边,在function_we_exported之后的0x10处。 使用这些信息,我们可以巧妙地做到这一点。

const auto address = reinterpret_cast<char*>(dlsym(library, "function_we_exported"));
reinterpret_cast<your_function_type>(address + 0x10)(...);

正如您可能会说的那样,这很hacky,但是如果您别无选择,我想这可能是一种方法。 另一种方法可能是修补库并强制导出它。 考虑到它们显示为GLOBAL / LOCALDEFAULT / HIDDEN ,这可能是一个标志或其他东西的翻转,但我现在不知道该怎么做。 如果我这样做,我会更新这个答案。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM