EvoCorp Home    IridiumX Assist Home   

 
Using Library Broker
A Practical Example

Let's assume that you wanted to proxy (intercept, monitor, scan) calls to the Kernels LoadLibraryA method - perhaps you want to prevent certain libraries from being loaded or maybe you're keen to send LoadLibraryA debug information to the event log.

There are 3 things that you are required to do to accomplish this task:

  1. Create a method that will act as the proxy for the original method. This method must have, excepting the first parameter of type pDetourHeader, the same parameter list and calling convention as the original method. In this instance, that method is stubLoadLibraryA.
  2. Register your proxy method, along with the procedure and the library that owns that procedure with the Library Server, a global library manager instantiated by IridiumX Assist. In this instance, LoadLibraryA is the method and is defined in the library Kernel32.DLL.
  3. When finished, even if that's when your application or library is closing, deregister your handler. This ensures that once your code is unloaded from the process space of the current application, any outstanding calls to the original method will succeed.

The following unit provides a working example of proxying calls to the LoadLibraryA function.

unit MyLoadLibraryUnit;

interface
uses
  SysUtils, Windows;

// These methods would be called by your application
// as the LoadLibrary handler is required.
procedure InstallLoadLibraryHandler;
procedure UninstallLoadLibraryHandler;

implementation

uses
  AssistLibraryDetours, AssistLibraryServer;

type
  // Define the structure of the function passed
  // to our handler in the previous method field
  // of the LIBBROKERHEADER record.
  TLoadLibraryA = function(
    lpLibFileName: PAnsiChar): HMODULE; stdcall;

// stubLoadLibraryA
// ----------------
// stubLoadLibraryA is our proxy method handler. This is
// the function that will get called whenever another
// library uses the LoadLibraryA method.
//
// Note that the FIRST parameter declared is the detour
// header - a parameter put there on purpose by IridiumX
// Assist to help you identify more information regarding
// the method currently being called.
//
// All other parameters and the methods original calling
// convention (i.e., stdcall) MUST remain the SAME and
// be presented in the SAME order.
function stubLoadLibraryA(const pHeader: pDetourHeader;
  lpLibFileName: PAnsiChar): HMODULE; stdcall;
begin
  // The detour header contains a pointer to the
  // library broker header identifying the original
  // method handler. In this example we're only out
  // to prove that we can intercept calls to LoadLibraryA,
  // so we'll do nothing except call the original handler.
  //
  // pHeader^.LibBrokerHeader.lpPreviousInstance identifies
  // the address of the original method. Because we know the
  // calling structure of the original method we can typecast
  // the function call and use it without problem.

  // Call the original handler.
 
Result := TLoadLibraryA(
    pHeader^.LibBrokerHeader.lpPreviousInstance)(lpLibFileName);
end;

procedure InstallLoadLibraryHandler;
begin
  // Inform the Library Broker engine that we have a method
  // that we would like to proxy. We're proxying the Kernel32
  // method "LoadLibraryA" so that instead of the original
  // method being called, our proxy method "stubLoadLibraryA"
  // is called instead.
  LibraryBrokerRegisterProxy(kernel32,
    'LoadLibraryA'
, @stubLoadLibraryA);
end;

procedure UninstallLoadLibraryHandler;
begin
  // Once we've finished with our method handlers, we'll
  // shut them down (even though any outstanding handlers
  // are shut down when IridiumX Assist shuts down the
  // library server, it makes good programming sense).
 
LibraryBrokerUnregisterProxy(kernel32,
    'LoadLibraryA'
, @stubLoadLibraryA);
end;

end.