Easyhook: Как подключить функцию из библиотеки DLL, загруженной с помощью LoadLibrary

Я играл с EasyHook некоторое время и был очень успешным со статически связанными DLL-библиотеками. Теперь я попытался подключить функцию из DLL, которая динамически загружается из хост-приложения, используя тот же подход, что и для статически связанных DLL.

В этом случае крюк не работает. Я получил следующее исключение при попытке создать хук:

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

Исключение очень правильно в том, что библиотека еще не загружена, но процесс Host/hooked собирается загрузить ее через несколько нс / мс после ее запуска (что совершенно не имеет значения).

Обучающие программы и результаты моих поисков в Интернете охватывали только подключение статически связанной DLL. Я не нашел ничего о динамически загружаемых DLL. Одно решение, которое приходит на ум: Крюк LoadLibrary а также GetProcAddress и дождитесь правильного вызова winapi, чтобы сделать желаемую замену.

Есть ли другой / более простой способ перехвата функций из динамически загружаемой DLL?

Есть одно ограничение: внешняя программа не может быть изменена для статического использования DLL.


Чтобы облегчить возможное решение, вот несколько фрагментов, которые показывают, что я хочу подключить:

Во-первых, это DLL с AddIntegers функция, которую я хочу заменить (код в 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.

1 ответ

Решение

Это заняло у меня некоторое время, но я наконец понял: вы можете подключить что-то только тогда, когда оно есть. Пока модуль не загружен, вы не сможете подключить его.

Как загружаются модули?

Как из кода в вопросе 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 может не знать, что подключенная библиотека выгружается.

Другие вопросы по тегам