簡體   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