如何拦截dll方法调用?

15

如何拦截dll方法调用?

  • 有哪些可用的技术?
  • 它只能在C/C++中完成吗?
  • 如何拦截所有运行中进程对给定dll的方法调用?
  • 如何拦截一个给定进程对给定dll的方法调用?

从加载DLL的应用程序内部拦截,还是从外部拦截?是针对特定进程还是所有进程?你可以更好地表达你的问题!;) - TheSoftwareJedi
你希望针对哪种编程语言和Windows平台进行开发? - Chris Pietschmann
4个回答

12

我能想到两种标准方法来完成这个任务:

  • DLL导入表钩子。
    对于这种方式,您需要解析DLL的PE头,找到导入表并将自己函数的地址写入到原本的位置中。您可以保存原始函数的地址以便稍后调用它。此Wikipedia文章中的外部链接引用可以提供您所需的所有信息。

  • 直接修改代码。找到要挂钩的函数的实际代码,并修改其第一条操作码以跳转到您自己的代码。您需要保存原始的操作码,以便最终执行。这比听起来简单得多,因为甚至微软自己在Detours库中已经实现了此功能。
    这真是一件很棒的事情。只需几行代码,您就可以替换例如outlook.exe中所有对GetSystemMetrics()的调用,看看发生的奇迹。

一个方法的优点就是另一个方法的缺点。第一种方法允许您精确添加到您想要的DLL中,而其他所有DLL都不会被挂钩。第二种方法允许您拦截所有调用该函数的全局挂钩。


这不是一个巨大的安全风险吗?它基本上给了任何人在应用程序中执行任何操作的能力,对吧? - Micah
我尝试修改一个函数的代码,但是这引发了访问冲突错误。在此之前是否有任何需要修复的细节? - Emmanuel Caradec

9

假设您事先知道所有DLL函数,一种技术是编写自己的包装器DLL,将所有函数调用转发到真正的DLL。这个DLL不必用C/C++编写。您需要做的就是匹配原始DLL的函数调用约定。


好的...但是,如何强制正在运行的进程调用我的dll而不是原始的那一个? - Daniel Silveira
3
如果您将包装DLL放在可执行文件的同一文件夹中,可执行文件应该会选择您的DLL,而不是选择Windows / System32等文件夹下的DLL。 - Ates Goral
系统 DLL 也是这样吗,比如 user32.dll 和其他相关的 DLL? - Demiurg
就我所见,对于所有的DLL都是正确的。 - Ates Goral
1
您可以使用Process Monitor检查进程正在查找dll的位置。如果您将恶意dll放在它查找真实dll之前查找的任何地方,则您的dll将被优先加载。 - RJFalconer

3

请查看Microsoft Detours,它是一个具有C/C++ API的库,与所有其他程序相比,将其注入到这些程序中可能会触发病毒扫描器/恶意软件检测器,但是您自己的进程可以使用。


0
在Linux上,可以使用LD_PRELOAD环境变量来实现。将此变量设置为指向包含要覆盖的符号的共享库,然后启动您的应用程序。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接