[英]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
/ LOCAL
和DEFAULT
/ HIDDEN
,這可能是一個標志或其他東西的翻轉,但我現在不知道該怎么做。 如果我這樣做,我會更新這個答案。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.