覆盖 DLL 的反参数

Posted

技术标签:

【中文标题】覆盖 DLL 的反参数【英文标题】:Counter argument to overwrite a DLL 【发布时间】:2019-05-28 13:18:25 【问题描述】:

我们想要热重载一个 DLL。第一个想法是覆盖 .dll 文件,然后从应用程序重新加载它。但是该文件是写保护的。

是否有(记录在案的)反对论点不删除此文件保护并覆盖文件? 如果不存在这样的反论点,我们如何绕过这种保护?

编辑:在 Internet 上找到的参考资料指出 mmap 以及 DLL 可能尚未加载的事实。就我而言,(仅导出的)方法已被调用,因此我可以合理地认为 DLL 已完全加载。

【问题讨论】:

Can I load a dll in such a way that it can be deleted while it's loaded?的可能重复 "我可以合理地认为 DLL 已完全加载。"但这不是你想要的相反吗?您想重新加载 DLL,但替换文件不会有任何效果,因为它已经完全加载。 (当然,真正的问题是当内存被分页并需要重新分页时。此外,导入的函数现在会指向错误的位置。) 你这样做有点太热了,你必须先使用 FreeLibrary()。由于无论如何您都必须重新绑定导出,所以没有理由让它比这更热。考虑 ReadDirectoryChangesW() 以检测更新被丢弃在指定位置。 @Raymond,该 DLL 已经被应用程序使用了一段时间,但是已经编译了一个新版本,应该会替换当前运行的行为。 @HansPassant,这实际上是一个很好的答案,只是我的问题有点复杂。 dll 在应用程序运行时由另一个应用程序构建。所以我们还不能释放它。到目前为止,我正在探索的解决方案是先重命名文件(似乎我可以从第三个应用程序执行此操作,而第一个应用程序仍在访问它)。 【参考方案1】:

在我们的情况下,我们有一个加载并使用 DLL 的程序。 对这个 DLL 的源代码进行了编辑,我们需要重新编译它并让程序热重载它。问题是 DLL 被锁定以防写入。

我们有另一个程序监视对源文件的任何修改(这实际上是一个自定义脚本编译器)并且需要编译一个 DLL(通过将源脚本翻译成 c++ 代码并调用 clang)。

我们几个月来的解决方案(并且运行良好)是让我们的脚本编译器检查文件是否受到写保护,如果是,则使用临时名称重命名此 dll 并最终编译。

主程序捕捉到这个 dll 的变化并且能够重新加载它。

额外步骤 在编译器启动时,我们检查是否有任何临时 dll 并尝试删除它们。如果删除失败可能是因为 DLL 正在使用中,我们忽略它。

注意:我们需要将 .dll 和 .pdb 移动到一个临时文件中。我们删除 .exp、.ilk 和 .lib 以防万一。

【讨论】:

以上是关于覆盖 DLL 的反参数的主要内容,如果未能解决你的问题,请参考以下文章

结构体作为参数的反汇编

windbg:进入进程的 dll

使用 Jackson 从 XML 到 POJO 的反序列化问题:没有从字符串值反序列化的字符串参数构造函数/工厂方法

我的反病毒软件整天弹出msplus.dll和quartz32.dll有病毒,怎样处理才是最好的杀毒方法?

将函数指针作为参数传递给 dll 函数并从 dll 内部调用它们是不是安全?

java调用dll怎么处理指针参数