|
Negli articoli precedenti si è parlato di dll
injection e intercettazione delle api di Windows tramite il componente TJclPeMapImgHooks
che consente la rilevazione delle api di Windows e la loro rapida sostituzione
con versioni personalizzate che ne modifichino il comportamento. Soprattutto
nell' articolo36 si è applicato il componente in
questione alla tecnica di dll injection descritta nell'
articolo34 consentendo l' intercettazione di determinate api di Windows su
un processo specificato. Ora completiamo l' opera utilizzando il componente in
questione nel contesto descritto nell' articolo35
ossia il caricamento automatico di una dll nello spazio di memoria di tutti i
processi (sia su quelli già presenti sia su quelli che verranno creati)
utilizzando gli Hook di Windows. In parole povere il nostro obiettivo
sarà quello di intercettare determinate api di Windows a livello di tutti i
processi. Per l' esempio ho deciso di utilizzare l' api RegEnumValueW
che consente l' enumerazione dell' elenco dei valori di una chiave di registro:
la versione personalizzata di tale api (che verrà chiamata in corrispondenza di
ogni chiamata dell' api originale) ci consentirà di nascondere un determinato
valore; si pensi ad esempio ad un programma che va in esecuzione automatica all'
apertura di ogni sessione: uno dei metodi per ottenere ciò è l' aggiunta di un
valore nella chiave
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run]
Se non vogliamo che risulti che tale programma viene eseguito,
possiamo ricorrere all' intercettazione dell' api RegEnumValueW.
Vediamo come procedere: innanzitutto ci creiamo un
valore "zzhide" nella chiave suddetta e poi implementiamo la dll che verrà
mappata tramite l' hook di sistema su tutti i processi: procediamo nella stessa
maniera in cui abbiamo proceduto nell' articolo36
ed otteniamo
library HookDll;
uses
Windows,
SysUtils,
Classes,
JclPeImage, JclSysUtils;
{$R *.RES}
var
PeImportHooks: TJclPeMapImgHooks;
OldRegEnumValueW: function(hKey: HKEY;
dwIndex: DWORD;
lpValueName: PWideChar;
var lpcbValueName: DWORD;
lpReserved: Pointer;
lpType: PDWORD;
lpData: PByte;
lpcbData: PDWORD
): Longint; stdcall = nil;
function NewRegEnumValueW(hKey: HKEY;
dwIndex: DWORD;
lpValueName: PWideChar;
var lpcbValueName: DWORD;
lpReserved: Pointer;
lpType: PDWORD;
lpData: PByte;
lpcbData: PDWORD
): Longint; stdcall;
begin
Result := OldRegEnumValueW(hKey,
dwIndex,
lpValueName,
lpcbValueName,
lpReserved,
lpType,
lpData,
lpcbData
);
if string(lpValueName) = 'zzhide' then
Result := 1;
end;
procedure EntryPointProc(reason: integer);
var
str: pChar;
begin
case reason of
DLL_PROCESS_ATTACH:
begin
PeImportHooks := TJclPeMapImgHooks.Create;
PeImportHooks.HookImport(Pointer(GetModuleHandle(nil)),
advapi32,
'RegEnumValueW',
@NewRegEnumValueW,
@OldRegEnumValueW);
end;
DLL_THREAD_ATTACH:
begin
end;
DLL_PROCESS_DETACH:
begin
FreeAndNil(PeImportHooks);
end;
DLL_THREAD_DETACH:
begin
end;
end;
end;
function HookProcedure(ncode: integer; wParam: WPARAM; lParam: LPARAM): integer; stdcall;
begin
Result := 0;
end;
exports
HookProcedure;
begin
DllProc := @EntryPointProc;
EntryPointProc(DLL_PROCESS_ATTACH);
end.
In pratica facendo restituire 1 (result=1) nell' implementazione
della NewRegEnumValueW nel caso in cui si sia incontrato il valore in
questione, vado a bloccare l' enumerazione; è chiaro che, a questo punto,
neanche gli eventuali valori successivi non vengono visualizzati. Per questo
motivo è opportuno dare un nome che risulti l' ultimo nell' ordine dei valori
enumerati (è l' ordine alfabetico) ed è proprio per questo che ho scelto il nome
"zzhide". Ho provato ad analizzare le altre api di windows per la manipolazione
del registro ma non sono riuscito a trovare una soluzione pulita perfetta che
consenta di nascondere il valore senza nascondere anche i successivi (un metodo
che non si basi sul blocco dell' enumerazione dei valori). A corredo chiaramente
la unit HookUnit (con l' implementazione delle funzioni SetHook e
RemoveHook di settaggio e rimozione dell' hook) che varrà inclusa dall'
applicativo che si occuperà di settare e rimuovere il mapping della dll su tutti
i processi. Nella demo vi è la dll con sorgente ed un applicativo che imposta e rimove il mapping a livello di sistema della dll in questione (anch' esso con sorgente). RegistryHook
|