Modules 

www.madshi.net

Each process consists of a main module (*.exe most of the time) and some secondary modules (*.dll most of the time). The secondardy modules can be system dlls or application specific dlls. madKernel encapsulates one single module in the "IModule" interface, and a list of modules in the "IModules" interface. See also the IModule Reference and the IModules Reference.

type
  IModule  = interface (IBasic)           ['{F84BE460-C13F-11D3-A530-00005A180D69}'];
  IModules = interface (ICustomBasicList) ['{F84BE461-C13F-11D3-A530-00005A180D69}'];

You can get an IModule or an IModules instance either by calling IProcess.Modules or by using one of the following functions. With "LoadModule" you can directly load a new module into your process (see "LoadLibrary(Ex)" API). You can also work with the "CurrentModule" or with the "MainModule". Furthermore you can convert a module dword handle into an IModule instance or check which module is located at a specific address. Or you can look for a module with a specific file name (in your process). Finally you can enumerate all modules of your own process or all modules of all processes system wide or all modules system wide with a specific file name.

function LoadModule (fileName          : string;
                     autoClose         : boolean = true;
                     withoutReferences : boolean = false;
                     onlyAsDataFile    : boolean = false;
                     alteredSearchPath : boolean = false) : IModule;

function CurrentModule : IModule;
function MainModule    : IModule;

function Module (handle    : cardinal;
                 autoClose : boolean = false) : IModule; overload;
function Module (memory    : pointer;
                 autoClose : boolean = false) : IModule; overload;
function Module (fileName  : string;
                 autoClose : boolean = false) : IModule; overload;

function Modules (systemWide : boolean = false) : IModules; overload;
function Modules (fileName   : string         ) : IModules; overload;

// Examples:
LoadModule('ourOwnPrivate.dll', false);
MessageBox(0, pchar('we have loaded ' + IntToStr(Modules.ItemCount) + 'modules'), 'info', 0);
Assert(MainModule.IsMainModule);

Is this module still loaded?

function IModule.IsStillValid : boolean;

To which process does this module belong?

property IModule.OwnerProcess : IProcess;

// Example:
Assert(CurrentModule.OwnerProcess = CurrentProcess);

Get the module handle or the module's HInstance value or the memory location where the module is loaded. All the 3 values are identical, btw.

property IModule.Handle    : cardinal;
property IModule.HInstance : cardinal;
property IModule.Memory    : pointer;

// Example:
Assert(CurrentModule.HInstance = HInstance);

Which file name does this module have?

property IModule.FileName : string;

// Example:
Assert(IsTextEqual(MainModule.FileName, ParamStr(0)));

Is this the main module (*.exe most of the time)?

function IModule.IsMainModule : boolean;

// Example:
if CurrentModule.IsMainModule then
  MessageBox(0, 'we are in the main module', 'info', 0);

Which address does the entry point function of this module have?

property IModule.EntryPoint : pointer;

The following methods can ask and even change (caution!) the address of this module's exported functions. This is internally realized by parsing the module's internal export tables. As a result IAT patching won't show effect here. Also you can get the address of kernel32 APIs, which are only exported by ordinal. The official API "GetProcAddress" doesn't allow that to make hacking harder.

function IModule.GetProcAddress (name  : string ) : pointer; overload;
function IModule.GetProcAddress (index : integer) : pointer; overload;

function IModule.SetProcAddress (name  : string;  newAddr: pointer) : boolean; overload;
function IModule.SetProcAddress (index : integer; newAddr: pointer) : boolean; overload;

// Example:
LoadLibrary16 := Module(kernel32).GetProcAddress(35);  

Get the full import/export list of this module:

property IModule.ImportList : IXxportList;
property IModule.ExportList : IXxportList;

// Example:
MessageBox(0, pchar('kernel exports ' + IntToStr(Module(kernel32).ExportList.ItemCount) + ' APIs'), 'info', 0);

The following methods return a pointer to some internal data structures of this module:

property IModule.ImageNtHeaders       : PImageNtHeaders;
property IModule.ImageImportDirectory : PImageImportDirectory;
property IModule.ImageExportDirectory : PImageExportDirectory;

// Example:
Assert(CurrentModule.ImageNtHeaders^.Signature = $4550);

Will this module be closed automatically, when the interface gets destroyed?

property IModule.AutoClose : boolean;

The IModules interfaces gives you easy access to it's "Items". Call "RefreshItems" to look for new, deleted and changed modules.

property IModules.Items [index: integer] : IModule;

function IModules.RefreshItems : boolean;

Does this IModules instance only enumerate modules of a specific process or only modules with a specific file name?

property IModules.OwnerProcess : IProcess;
property IModules.FileName     : string;

The "IXxportList" interface is needed for the IModule.ImportList and IModule.ExportList properties. It holds a list of IExportEntry instances. You can access the contained "Items", or search for a specific function address. See also the IXxportList Reference.

type IXxportList = interface (ICustomBasicList) ['{AF45CC02-1296-47C2-B6AE-727B3C82B820}'];

property IXxportList.Items    [index : integer] : IExportEntry;
function IXxportList.FindItem (func  : pointer) : IExportEntry; overload;

The "IExportEntry" interface wraps up a single exported function. It's used in the IXxportList interface. See also the IExportEntry Reference. For each exported function you can ask from which module is was exported under which "Ordinal" and under which "Name" and what the "Address" of the function is.

type IExportEntry = interface (IBasic) ['{64B5B8D1-B4EA-4A13-9D48-CBACF2265882}'];

property IExportEntry.ExportModule : IModule;
property IExportEntry.Ordinal      : cardinal;
property IExportEntry.Name         : string;
property IExportEntry.Address      : pointer;