Nel precedente articolo (articolo77.htm) abbiamo
tradotto un .exe in un .dll e ci siamo creati un exe che carica nel proprio
spazio di memoria la dll creata riproducendo quindi in tutto e per tutto il .exe
originale. Ora sfrutteremo l'occasione per affrontare un argomento molto
interessante ossia il caricamento di una dll memorizzata in un buffer di memoria
invece che far riferimento al file su disco. 1. LoadLibrary dalla memoria
Nell' articolo articolo75.htm abbiamo visto come
lanciare un .exe memorizzato in un buffer in memoria; in modo analogo si può
caricare una dll: la procedura è complessa (ma non impossibile naturalmente) e
fa riferimento ai concetti teorici (struttura PE) esposti nell'articolo stesso;
diciamo che nel caso della dll dobbiamo anche gestire obbligatoriamente le
problematiche inerenti alla rilocazione (utilizzando la Relocation Table) e
risolvere tutti gli import (utilizzando la Import Address Table). All'indirizzo
seguente c'è un ottimo articolo al riguardo con allegato l'esempio in C
http://www.joachim-bauch.de/tutorials/load_dll_memory.html/en
Ed il bello è che è stato effettuato il porting a
Delphi: una unit .pas che
ci consente di eseguire LoadLibrary (caricare una dll), FreeLibrary (scaricare
una dll) e GetProcAddress (chiamare una funzione della dll) su una dll
memorizzata in un buffer in memoria; ho apportato una piccola modifica al sorgente togliendo il var (passaggio di
un parametro per riferimento) al primo parametro delle funzioni implementate: in
questo modo anche l'utilizzo delle funzioni medesime risulta migliore (posso ad
esempio passare come parametro la property Memory di un oggetto di classe
TStream o derivate); sinceramente non ho capito il motivo per cui ci fosse il
var : del resto quei parametri non vengono modificati all'interno delle
procedure, quindi è inutile ... bahhh.
A questo punto l'unica cosa da fare è modificare il sorgente del .exe dedito
al caricamento della dll
program Runner;
uses
Windows, Classes, SysUtils, BTMemoryModule;
type
TMainProc = procedure(); stdcall;
var
pMemoryModule: PBTMemoryModule;
MainProc: TMainProc;
function LoadDll(const DllName: string): PBTMemoryModule;
var
ms: TMemoryStream;
begin
try
ms := TMemoryStream.Create();
ms.LoadFromFile(DllName);
Result := BTMemoryLoadLibary(ms.Memory, ms.Size);
finally
ms.Free;
end;
end;
begin
pMemoryModule := LoadDll('RegEnum.dll');
if pMemoryModule = nil then
Exit;
MainProc := TMainProc(BTMemoryGetProcAddress(pMemoryModule, 'MainProc'));
MainProc();
BTMemoryFreeLibrary(pMemoryModule);
end.
Fatto. E' anche un ottimo esempio di come usare questa unit per mappare moduli direttamente dalla memoria. Per dovere di cronaca ci sono altre implementazioni della suddetta tecnica: una di queste (in C/C++) si trova all'interno di BackOrifice, l'altra (in Delphi) è stata realizzata da Aphex (che tra l'altro ne ha realizzata un'altra che consente di eseguire il mapping nello spazio di memoria di processi remoti). Behh ... è tutto (per il momento) exe_convertito_dll_memory.7z
|