I have been playing with EasyHook for a while now and have been very successfull with statically linked DLLs. Now I tried to hook a function from a DLL that is dynamically loaded from the Host Application using the same approach as with the statically linked DLLs.
In this scenario, the hook failed to work. I got the following exception when trying to create the hook:
System.DllNotFoundException: The given library is not loaded into the current process.
The Exception is very correct in stating that the library is not yet loaded, but the Host/hooked Process is about to load it in a few ns/ms after it started (which totally doesn't matter).
The tutorials and the results from my searches on the internet only covered hooking a statically linked DLL. I haven't found anything about dynamically loaded DLLs. One solution that comes to mind: Hook LoadLibrary
and GetProcAddress
and wait for the right winapi call to do the desired replacement.
Is there any other/an easier way to hook functions from a dynamically loaded DLL?
There is one constraint: The external program cannot be changed to use the DLL in a static way.
To facilitate a possible solution, here are some snippets that show what I want to hook:
First, this is the DLL with the AddIntegers
function that I want to replace (Code is in Delphi)
library Calculate;
function AddIntegers(_a, _b: integer): integer; stdcall;
begin
Result := _a + _b;
end;
exports
AddIntegers;
begin
end.
Second, this is the program using the above DLL using the exported AddIntegers
function.
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.