Easyhook:如何从加载了LoadLibrary

时间:2017-12-08 12:00:15

标签: c# dll loadlibrary easyhook

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

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

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

异常是非常正确的说明库尚未加载,但主机/钩子进程将在启动后以几ns / ms的速度加载它(完全没有'重要)。

我在互联网上搜索的教程和结果仅涉及挂钩静态链接的DLL。我还没有找到任何有关动态加载的DLL的信息。我想到一个解决方案:挂钩LoadLibraryGetProcAddress并等待正确的winapi呼叫以进行所需的替换。

是否有其他/更简单的方法从动态加载的DLL中挂钩函数?

有一个约束:无法更改外部程序以静态方式使用DLL。

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

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

library Calculate;

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

exports
   AddIntegers;

begin
end.

其次,这是使用导出的AddIntegers函数使用上述DLL的程序。

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.

1 个答案:

答案 0 :(得分:0)

我花了一些时间,但是我终于想通了:您只能钩住那里的东西。只要不加载模块,就无法钩住它。

如何加载模块?

从问题LoadLibrary()中的代码开始,使该模块可用。这意味着,为了有一个模块可用的第一个时间点,您需要挂钩LoadLibrary()

挂钩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;
}

现在,您知道加载库时,就可以挂钩其功能。现在,您还可以将任何静态加载的函数与选中的库一起挂钩。

提示:在我的实际用例中,.dll在启动后立即加载,并且在应用程序终止后将被释放。如果库已多次加载和卸载,则应检查内存泄漏。是的,EasyHook可能没有意识到挂钩的库已卸载。