通过 DLL 代理重定向损坏的函数
Posted
技术标签:
【中文标题】通过 DLL 代理重定向损坏的函数【英文标题】:Redirecting mangled functions via DLL proxying 【发布时间】:2022-01-09 18:44:55 【问题描述】:我正在摆弄一个旧游戏,并试图了解它是如何工作的。我目前的实验包括尝试代理游戏的 DLL 之一。
所以我将原来的 DLL.dll
重命名为 trueDLL.dll
,将 DLL 的导出转储为 dumpbin
,并创建了 #pragma
s(现在很好,稍后我会查看 .def 文件)生成一个“空”代理。这按预期工作。
现在,我想将一些函数重定向到我的反向工程实现,以测试它们是否有效。这就是我卡住的地方。这是一个示例:LogDebug
函数。代理 DLL 中的“空”、有效的编译指示如下所示:
#pragma comment(linker, "/export:?LogDebug@@YAXPBDZZ=trueDLL.?LogDebug@@YAXPBDZZ,@504")
我想我可以像这样更改编译指示以将调用重定向到我的实现:
#pragma comment(linker, "/export:?LogDebug@@YAXPBDZZ=LogInfo,@504")
运行程序,由于找不到?LogDebug@@YAXPBDZZ
,无法启动。一些研究表明,@@YAXPBDZZ
部分没有导出到我的 DLL 中。它似乎是在损坏的名称中表示的某种信息,但我无法找出它的实际含义。 Ghidra 和 this demangler 也没有帮助,唯一的搜索结果是俄语。
使用 VS 2019,不会更改任何项目设置。
这里有什么问题,我将如何进行这项工作?还是有更简单/更好的方法来实现这一目标?我现在想避免在程序 exe 中挂钩调用,但如果必须,我会这样做。
编辑 - 修改方案和编译器
我不知道创建 DLL.dll
的确切内容,但根据 Ghidra 的说法,它是 visualstudio:unknown
。我将其解释为 MSVC 的 1998 年(游戏文件日期)版本。我正在使用当前的 MSVC 编译器(CL
ver. 19)。
当前的CL
使用 C++ 方案是有意义的。查看this page,并将其与导出进行比较,DLL.dll
似乎也在使用 C++ 方案,但我可能错了。我如何确定这一点?
【问题讨论】:
DLL.dll
使用什么名称修改方案?您的替换库使用什么名称修改方案? "C"
? "C++"
?在后一种情况下,哪个编译器?
有不同的方案?我会更新问题以添加我所知道的。
“默认”实际上一直是"C"
。这是唯一有可能在编译器更新后幸存下来的合理名称修改。 "C++"
名称修饰很疯狂,每个编译器都发明了自己的名称修饰方案。如果您很难找出正在使用的名称装饰方案,请发布原始导出之一。
原始DLL dumpbin /exports
: pastebin.com/mc6fsKTz
在开发者命令提示符下使用undname.exe utility。向您展示您必须编写一个带有签名 void __cdecl LogDebug(char const *,... ) 的 C++ 函数才能让链接器满意。
【参考方案1】:
事实证明,我的 DLL 中的方法不需要#pragma
,因为它实际上覆盖了所需的行为。如果我像undname.exe
所说的那样定义我的函数并在前面添加一个__declspec(dllexport)
,那么一切都会很好地到位。
【讨论】:
您可能需要考虑通过提供language linkage 来更加明确,即extern "C++"
。这可以防止您意外使用 C 编译器编译代码。
我会调查一下,谢谢!以上是关于通过 DLL 代理重定向损坏的函数的主要内容,如果未能解决你的问题,请参考以下文章
使用 Apache ProxyPass 的反向代理重定向而不是透明地通过