EvoCorp Home    IridiumX Assist Home   

 

Using Library Broker...

Brokering a method from any library is a simple three-step process:

You must first develop your proxy method, then register and use it and when finished, deregister it.

Developing Your Proxy Method

A proxy method is simply a method you create that will be used to replace the original. A proxy method:

  • Takes the same parameters as the method you intend on replacing
    (Excluding the LIBBROKERHEADER parameter, see below)
  • Produces the same results as the method you intend on replacing,
  • Implements the same calling convention as the method you intend on replacing (stdcall, cdecl, pascal etc.), and
  • Cleans up the stack in the same way as the method you intend on replacing.

LIBBROKERHEADER

There is however one fundamental difference between the declaration of your proxy method and that of the original method. To enable identification of any given proxy method, Library Broker introduces a new parameter for each proxy - a pointer to a LIBBROKERHEADER data structure. The LIBBROKERHEADER data structure is used to identify the previous instance of this method, thereby enabling you to call the original implementation of this method if you so require. For more information on how Library Broker introduces the LIBBROKERHEADER parameter, refer to the LIBBROKERHEADER definition.

Proxy Method Registration

Once you've created your proxy method you must register it. Registering a proxy method notifies Library Broker that you have defined a new implementation for a particular library method so that from that point on, whenever an attempt is made to call the original method your proxy is called instead. Before your application shuts down you are responsible for deregistering any proxy methods you have registered. Proxy method registration is done by calling the Library Broker method "LibraryBrokerRegisterProxy", and proxy method deregistration is done by calling the Library Broker method "LibraryBrokerUnregisterProxy".

When to Register Your Proxy Method

Perhaps the most important requirement in brokering a library method is that your proxy method gets registered BEFORE the rest of the application uses it via "GetProcAddress". Whilst statically linked methods will be brokered regardless, once an application has called "GetProcAddress" Library Broker has no way of alerting the rest of the application that this method has now been brokered.

One way around this is to ensure that you register your proxy method before any libraries that might potentially access this function are loaded. This might not always be the case however, for example an Internet Explorer Browser Helper Object is loaded well and truly after the Internet Explorer had initialized its core libraries. So, how do you get around this?

Another IridiumX Assist technology, "Injector", contains the facilities required for "injecting" your code into a target process. The Injector methods "CreateInjectedProcess" and "CreateInjectedProcessAsUser" are functionally similar to the Kernel32 methods CreateProcess and CreateProcessAsUser except that before the new process is executed, your injected library code is run. This provides you with the ideal opportunity to register your library methods before the specified process begins execution, thus ensuring that any calls by the rest of the application to GetProcAddress return your proxy method instead. Obviously requires a little more development, and involves the introduction of a proxy application to execute the real application via "CreateInjectedProcess".

Example Proxy Method

The following example highlights the steps required for implementing a proxy method handler. For a more detailed example, please refer to the complete example.

Let's say that you wanted to replace the Kernel32 function "GetVersionExA":

 

Delphi
The original definition from Windows.pas function GetVersionExA(var lpVersionInformation: TOSVersionInfo): BOOL; stdcall;
Your proxy implementation would resemble...

type
  TGetVersionEx = function(var lpVersionInformation: TOSVersionInfo): BOOL; stdcall;

function MyGetVersionExA(
  // lpBrokerHeader MUST be the first parameter in
  // all stdcall and cdecl proxy methods !!

  const lpBrokerHeader: LPLIBBROKERHEADER;
  // And then we continue with the original parameter list.
  var lpVersionInformation: TOSVersionInfo): BOOL; stdcall;
begin
  ...
  // Call the previous implementation of this method
  // (whether that be a proxy or the original Kernel32
  // implementation, it doesn't matter)

  Result := TGetVersionEx(lpBrokerHeader^.lpPreviousInstance)(lpVersionInformation);
  // Update Result as necessary
  ...
end;

And you would register and unregister it like this...

...
LibraryBrokerRegisterProxy('kernel32.dll', 'GetVersionExA', @MyGetVersionExA);
...
LibraryBrokerUnregisterProxy('kernel32.dll', 'GetVersionExA', @MyGetVersionExA);
...