[英]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.