jjzjj

c++ - 检测 DLL 的卸载

coder 2024-06-13 原文

我有一个特殊的要求,我相信没有别的办法, 即:检测 DLL 的卸载。我用谷歌搜索并发现 a four-years old SO对这个。我选择了相同的 解决方案: Hook FreeLibrary

当代码进入 MyFreeLibrary 时,我将钩住入口点 指定的模块以相同的方式(内联钩子(Hook))。而在 MyEntryPoint,我会先调用原来的入口点,然后 检查 reason 参数 - 如果值等于 DLL_PROCESS_DETACH,表示这个DLL的清理工作是 刚刚完成,它将从地址空间中卸载。 在这一点上,我有机会做我的工作。它有效。

就这样?不幸的是,它还没有完成。一个非常重要的 事情被忽略了:依赖。

例如,a.dll 链接到 b.dllc.dll。当你加载 a.dllb.dllc.dll 将首先加载(初始化)。这个 是因为b.dllc.dll在导入表中列出 a.dll,它们是a.dll的依赖。同样,当你卸载 a.dllb.dllc.dll 如果它们的引用也可能被卸载 计数减少到零。我不知道关于如何的细节 加载器找出一个DLL的依赖并卸载它们, MSDN FreeLibrary 的页面没有谈到这个,我很高兴 明白这一点,但我没有找到信息。

所以主要的问题是如何检测依赖的卸载 一个 DLL 模块。我希望有同样的机会完成我的工作。

一个可能的解决方案可能是导入表,找出 从其导入表中查找 DLL 的依赖项,并找出 来自其导入表的依赖项等的依赖项, 找出所有依赖项, Hook 所有入口点,我不 知道,这听起来很疯狂,我需要一些建议。

最佳答案

我贡献了旧 SO 问题的答案。你现在写:

And in MyEntryPoint, I will call the original entry point first, then check the reason argument - if the value equals to DLL_PROCESS_DETACH, it means that the cleanup work of this DLL is just done, and it's going to be unloaded from the address space.

你发现这不是真的。但最简单的解决方法是什么?如果发现原因是 DLL_PROCESS_DETACH 后,您测试 hModule 是否仍然有效怎么办?见:

How can I tell if a Windows module handle is still valid?

您可以跳过 Hook DLL 入口点,不检查 DLL_PROCESS_DETACH 并始终只测试 hModule 是否仍然有效。这让我意识到,最好在调用原始 FreeLibrary 之前检查 hModule 是否有效,然后再测试有效到无效的转换:

if (moduleWasValid && !moduleStillValid)
{
    // process module unloaded
}

希望对您有所帮助。

关于c++ - 检测 DLL 的卸载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32288601/

有关c++ - 检测 DLL 的卸载的更多相关文章

  1. ruby-on-rails - 如何优雅地重启 thin + nginx? - 2

    我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server

  2. ruby - RuntimeError(自动加载常量 Apps 多线程时检测到循环依赖 - 2

    我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("

  3. c# - 如何在 ruby​​ 中调用 C# dll? - 2

    如何在ruby​​中调用C#dll? 最佳答案 我能想到几种可能性:为您的DLL编写(或找人编写)一个COM包装器,如果它还没有,则使用Ruby的WIN32OLE库来调用它;看看RubyCLR,其中一位作者是JohnLam,他继续在Microsoft从事IronRuby方面的工作。(估计不会再维护了,可能不支持.Net2.0以上的版本);正如其他地方已经提到的,看看使用IronRuby,如果这是您的技术选择。有一个主题是here.请注意,最后一篇文章实际上来自JohnLam(看起来像是2009年3月),他似乎很自在地断言RubyCL

  4. ruby - 在不使用 RVM 的情况下在 Mac 上卸载和升级 Ruby - 2

    我最近决定从我的系统中卸载RVM。在thispage提出的一些论点说服我:实际上,我的决定是,我根本不想担心Ruby的多个版本。我只想使用1.9.2-p290版本而不用担心其他任何事情。但是,当我在我的Mac上运行ruby--version时,它告诉我我的版本是1.8.7。我四处寻找如何简单地从我的Mac上卸载这个Ruby,但奇怪的是我没有找到任何东西。似乎唯一想卸载Ruby的人运行linux,而使用Mac的每个人都推荐RVM。如何从我的Mac上卸载Ruby1.8.7?我想升级到1.9.2-p290版本,并且我希望我的系统上只有一个版本。 最佳答案

  5. ruby - 使用 `+=` 和 `send` 方法 - 2

    如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:

  6. ruby - 如何计算 Liquid 中的变量 +1 - 2

    我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我

  7. arrays - Ruby 数组 += vs 推送 - 2

    我有一个数组数组,想将元素附加到子数组。+=做我想做的,但我想了解为什么push不做。我期望的行为(并与+=一起工作):b=Array.new(3,[])b[0]+=["apple"]b[1]+=["orange"]b[2]+=["frog"]b=>[["苹果"],["橙子"],["Frog"]]通过推送,我将推送的元素附加到每个子数组(为什么?):a=Array.new(3,[])a[0].push("apple")a[1].push("orange")a[2].push("frog")a=>[[“苹果”、“橙子”、“Frog”]、[“苹果”、“橙子”、“Frog”]、[“苹果”、“

  8. += 的 Ruby 方法 - 2

    有没有办法让Ruby能够做这样的事情?classPlane@moved=0@x=0defx+=(v)#thisiserror@x+=v@moved+=1enddefto_s"moved#{@moved}times,currentxis#{@x}"endendplane=Plane.newplane.x+=5plane.x+=10putsplane.to_s#moved2times,currentxis15 最佳答案 您不能在Ruby中覆盖复合赋值运算符。任务在内部处理。您应该覆盖+,而不是+=。plane.a+=b与plane.a=

  9. ruby - 检测由 RSpec、Ruby 运行的代码 - 2

    我想知道我的代码是否在rspec下运行。这可能吗?原因是我正在加载一些错误记录器,这些记录器在测试期间会被故意错误(expect{x}.toraise_error)弄得乱七八糟。我查看了我的ENV变量,没有(明显的)测试环境变量的迹象。 最佳答案 在spec_helper.rb的开头添加:ENV['RACK_ENV']='test'现在您可以在代码中检查RACK_ENV是否经过测试。 关于ruby-检测由RSpec、Ruby运行的代码,我们在StackOverflow上找到一个类似的问题

  10. ruby - 使用 Ruby Daemons gem 检测停止 - 2

    我正在使用rubydaemongem。想知道如何向停止操作添加一些额外的步骤?希望我能检测到停止被调用,并向其添加一些额外的代码。任何人都知道我如何才能做到这一点? 最佳答案 查看守护程序gem代码,它似乎没有用于此目的的明显扩展点。但是,我想知道(在守护进程中)您是否可以捕获守护进程在发生“停止”时发送的KILL/TERM信号...?trap("TERM")do#executeyourextracodehereend或者你可以安装一个at_exit钩子(Hook):-at_exitdo#executeyourextracodehe

随机推荐