c# - Easyhook:如何从使用 LoadLibrary 加载的 DLL 中 Hook 函数

标签 c# dll loadlibrary easyhook

我一直在玩EasyHook已经有一段时间了,并且在静态链接 DLL 方面取得了非常成功的成果。现在,我尝试使用与静态链接 DLL 相同的方法从主机应用程序动态加载的 DLL 中 Hook 函数。

在这种情况下, Hook 无法工作。尝试创建钩子(Hook)时出现以下异常:

System.DllNotFoundException: The given library is not loaded into the current process.

异常非常正确地表明库尚未加载,但主机/ Hook 进程将在启动后几纳秒/毫秒内加载它(这完全没有)没关系)。

教程和我在互联网上搜索的结果仅涵盖了 Hook 静态链接的 DLL。我还没有找到任何关于动态加载 DLL 的信息。我想到的一个解决方案是: Hook LoadLibraryGetProcAddress 并等待正确的 winapi 调用来执行所需的替换。

有没有其他/更简单的方法来从动态加载的 DLL 中 Hook 函数?

有一个限制:外部程序不能更改为以静态方式使用 DLL。


为了促进可能的解决方案,这里有一些片段显示了我想要 Hook 的内容:

首先,这是我要替换的带有 AddIntegers 函数的 DLL(代码在 Delphi 中)

library Calculate;

function AddIntegers(_a, _b: integer): integer; stdcall;
begin
  Result := _a + _b;
end;

exports
   AddIntegers;

begin
end.

第二,这是使用上述 DLL 并使用导出的 AddIntegers 函数的程序。

program HostConsole;
{$APPTYPE CONSOLE}

uses
  Winapi.Windows, System.SysUtils;

var
  n1, n2, sum: Int32;

  // Variables for DLL Loading
  h: HMODULE;
  AddIntegers: function(_a, _b: integer): integer; stdcall;

begin
  try
    // Load Library
    h := LoadLibrary('Calculate.dll');
    if h = 0 then
    begin;
      raise Exception.Create('Cannot load DLL');
    end;

    // Load function
    AddIntegers := GetProcAddress(h, 'AddIntegers');

    if not Assigned(AddIntegers) then
    begin
      raise Exception.Create('Cannot find function');
    end;

    Write('Enter first number: ');
    Readln(n1);

    Write('Enter second number: ');
    Readln(n2);

    // To the calculation
    sum := AddIntegers(n1, n2);

    Writeln('The sum is ', sum);
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;

  // Unload Library
  FreeLibrary(h);

  Readln;

end.

最佳答案

我花了一些时间,但我终于想通了:只有当某物存在时,你才能钩住它。只要模块未加载,您就无法 Hook 它。

模块如何加载?

从问题 LoadLibrary() 中的代码来看,使模块可用。这意味着,为了获得模块可用的第一个时间点,您需要 Hook LoadLibrary()!

Hook LoadLibrary()

如果有人正在寻找调用该函数的方法,这里是一种可能的方法:

[UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet = CharSet.Unicode, SetLastError = true)]
delegate IntPtr LoadLibrary_Delegate(string lpFileName);


[DllImport("kernel32", CharSet = CharSet.Unicode, SetLastError = true)]
internal static extern IntPtr LoadLibrary(string lpFileName);

IntPtr LoadLibrary_Hook(string lpFileName)
{
    IntPtr result = LoadLibrary(lpFileName);

    if (lpFileName == "<FILENAME HERE>")
    {
        // Apply hook
    }
    return result;
}

现在您知道了库何时加载,您可以 Hook 它的函数。您现在还可以 Hook 与检查的库一起静态加载的任何函数。

提示:在我的实际用例中,.dll 在启动后立即加载,并在应用程序终止后释放。如果库被加载和卸载多次,则应该检查是否存在内存泄漏。是的,EasyHook 可能不知道 Hook 的库已卸载。

关于c# - Easyhook:如何从使用 LoadLibrary 加载的 DLL 中 Hook 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47713987/

相关文章:

c# - 您推荐使用哪种客户端工具与 Subversion 存储库一起使用

c# - WCF 服务引用中的接口(interface)参数/返回类型

delphi - 尝试从 dll 加载过程时 Delphi 中出现错误

dll - VB6:获取DLL的当前路径

c++ - GetProcAddress 用于将修饰的 C++ 函数导入到 C++ 中

C++ Loadlibrary() 错误 3765269347

c# - 将事件处理程序作为参数传递

c# - Int64 导致错误的结果,为什么?

java - jni4net 无法在 Java 应用程序中加载 DLL

c++ - 未使用 GetProcAddress() C++ VBexpress 13 查找函数