all*_*mon 8 c++ reverse-engineering ld readelf nm
我有一些.fic专有格式的二进制文件,我有一个wd250hf64.so来自该供应商的包含 C++ 方法的文件 CComposanteHyperFile::HExporteXML(wchar_t* const path)
我可以使用 nm 看到
$ nm --demangle wd250hf64.so --defined-only
0000000000118c90 t CComposanteHyperFile::HExporteXML(wchar_t const*)
Run Code Online (Sandbox Code Playgroud)
未损坏的版本_ZN20CComposanteHyperFile11HExporteXMLEPKw与我使用本地 g++ 版本的版本相同
雷德夫给出
readelf -Ws wd250hf64.so | grep _ZN20CComposanteHyperFile11HExporteXMLEPK
19684: 0000000000118c90 119 FUNC LOCAL DEFAULT 11 _ZN20CComposanteHyperFile11HExporteXMLEPKw
Run Code Online (Sandbox Code Playgroud)
现在我尝试编写一个非常简单的程序
$ nm --demangle wd250hf64.so --defined-only
0000000000118c90 t CComposanteHyperFile::HExporteXML(wchar_t const*)
Run Code Online (Sandbox Code Playgroud)
但是当我用它编译时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);
}
Run Code Online (Sandbox Code Playgroud)
gcc -rdynamic -o foo toto.c -ldl
./foo
wd250hf64.so: undefined symbol: _ZN20CComposanteHyperFile11HExporteXMLEPKw
Run Code Online (Sandbox Code Playgroud)
我明白,因为 nm 没有显示--extern-only它,所以这个符号可能没有“导出”,所以它不应该正常工作
我的问题是
无论如何,即使这意味着手动修补 .so 文件,使程序编译的黑客方法是什么?
如果您确实希望能够以任何可能的方式获取该符号,您可以尝试获取其相对于已知导出符号的地址,假设它们位于同一部分。例如,我制作了一个简单的虚拟库,其中包含一个导出函数和一个非导出函数。
0x0000000000003890 12 FUNC GLOBAL DEFAULT 16 function_we_exported
0x00000000000038a0 12 FUNC LOCAL HIDDEN 16 function_we_forgot_to_export
Run Code Online (Sandbox Code Playgroud)
因为这个库是为了这个答案而设计的,所以非导出函数恰好就在它旁边,0x10在function_we_exported. 使用这些信息,我们可以轻松地做到这一点。
const auto address = reinterpret_cast<char*>(dlsym(library, "function_we_exported"));
reinterpret_cast<your_function_type>(address + 0x10)(...);
Run Code Online (Sandbox Code Playgroud)
正如您可能会说的那样,这非常hacky,但如果您没有其他选择,我想这可能是一种方法。另一种方法可能是修补库并强制导出它。考虑到它们显示为GLOBAL/LOCAL和DEFAULT/ HIDDEN,这可能是翻转旗帜或其他东西,但我目前不知道该怎么做。如果我这样做,我会更新这个答案。
| 归档时间: |
|
| 查看次数: |
923 次 |
| 最近记录: |