Home | Chi sono | Contattami
 

Progr. lineare

Delphi
 
Componenti
  Database
 
Miei articoli

Windows

Miei articoli 

 

Esplorare il Protected storage (utenze e password memorizzate dei moduli web, etc...)


Oggi mi sono costruito un applicativo per prelevare i dati contenuti nel Protected Storage. Cosaaa???? Si beehhh in pratica li dentro ci sono ad esempio i nomi utente e le password dei moduli delle pagine web (naturalmente nel caso in cui il salvataggio delle informazioni sui moduli sia abilitato: Internet Explorer -> Strumenti -> Opzioni internet -> Contenuto -> Informazioni personali).

1. Concetti base

Il servizio di Protected Storage viene usato da Windows per salvare in forma criptata informazioni quali ad esempio password in Internet Explorer, etc.. Chiaramente non vi una documentazione ufficiale delle librerie che si occupano di tali operazione ma fortunatamente l'obiettivo non cos ostico come potrebbe sembrare. Nel seguito vedremo appunto come decriptare le informazioni contenute nel Protected Storage.

1.1 Struttura del Protected Storage

La figura seguente esprime in maniera chiara l'organizzazione del Protected Storage

Protected storage provider contiene vari elementi della categoria Type. Ogni elemento della categoria Type contiene elementi della categoria SubType. Ogni elemento della categoria SubType contiene elementi della categoria Item. Ogni elemento della categoria Item contiene i dati (tra i quali ci sono ad esempio utenze e password, etc...)

2. Implementazione

Il fulcro di tutto la dll pstorec.dll che implementa la COM Interface denominata IPStore. Inoltre esporta le seguenti 2 funzioni:

PStoreCreateInstance
PStoreEnumProviders

N.B. useremo solo PStoreCreateInstance.

2.1 Importare la Type Library relativa alla dll pstorec.dll

Come prima cosa occorre eseguire

regsvr32 pstorec.dll

e poi si pu procedere alla solita maniera ossia da Delphi: Project --> Import Type Library

ed otteniamo la Unit di Import il cui nome di default PSTORECLib_TLB.pas.

2.2 Inizio

Come prima cosa dobbiamo crearci una Unit che contiene la dichiarazione della funzione PStoreCreateInstance (funzione esportata da pstorec.dll). Nella stessa Unit inseriremo anche la dichiarazione dell'api CoTaskMemFree (deallocazione di memoria nel contesto della tecnologia COM; opposto di CoTaskMemAlloc che effettua una allocazione) esportata da ole32.dll.

unit Pstoreclib; interface uses Windows, PSTORECLib_TLB; function PStoreCreateInstance( var ppProvider: IPStore; pProviderID: PGUID; pReserved: Pointer; dwFlags: DWORD): HRESULT; stdcall; procedure CoTaskMemFree( pv: Pointer); stdcall; var DLLHandle: THandle; implementation const pstorec = 'pstorec.dll'; ole32 = 'ole32.dll'; {$IFDEF DYNAMIC_LINK} var _PStoreCreateInstance: Pointer; function PStoreCreateInstance; begin GetProcedureAddress(_PStoreCreateInstance, pstorec, 'PStoreCreateInstance'); asm mov esp, ebp pop ebp jmp [_PStoreCreateInstance] end; end; {$ELSE} function PStoreCreateInstance; external pstorec name 'PStoreCreateInstance'; {$ENDIF DYNAMIC_LINK} {$IFDEF DYNAMIC_LINK} var _CoTaskMemFree; function CoTaskMemFree; begin GetProcedureAddress(_CoTaskMemFree, ole32, 'CoTaskMemFree'); asm mov esp, ebp pop ebp jmp [_CoTaskMemFree] end; end; {$ELSE} procedure CoTaskMemFree; external ole32 name 'CoTaskMemFree'; {$ENDIF DYNAMIC_LINK} end.

Bene, la Unit di import della type library e questa Unit: si pu dire che abbiamo tutto. Andiamo quindi direttamente ai paragrafi successivi per vedere finalmente come ottenere le informazioni sul Protected Storage.

2.3 Operazione base

La prima cosa da fare quando si vuole esplorare il Protected Storage chiamare la funzione PStoreCreateInstance

var FProvider: IPStore; ProviderID: PGUID; ... PStoreCreateInstance(FProvider, ProviderID, nil, 0);

Otteniamo in questo modo un reference alla IPStore Interface (FProvider) ed il GUID del Protected Storage Provider (ProviderId). Una volta fatto questo si possono ottenere tutte le altre informazioni.

2.4 Informazioni sul Protected Storage Provider

Per ottenere informazioni sul Provider possiamo usare la seguente procedura

//dalla Unit di import PSTORECLib_TLB (* PUserType1 = ^_PST_PROVIDERINFO; {*} _PST_PROVIDERINFO = packed record cbSize: LongWord; ID: TGUID; Capabilities: LongWord; szProviderName: PWideChar; end;*) // procedure ProviderInfo(FProvider: IPStore); var ppInfo: PUserType1; begin FProvider.GetInfo(ppInfo); //scrivo l'informazione ottenuta ad esempio in un campo Memo su una Form Form1.Memo1.Lines.Add(ppInfo.szProviderName); end;

2.5 Enumerare i TYPE

I TYPE possono essere rappresentati in 2 modi:

1) GUID
2) Nome

Di seguito la procedura per enumerare i TYPE rappresentandoli sia tramite GUID sia tramite Nome

function Type_Name(pType: TGUID): string; var pst: PUserType3; begin pst := nil; FProvider.GetTypeInfo(0, pType, pst, 0); Result := String(pst^.szDisplayName); CoTaskMemFree(pst); end; procedure ElencoTypes(FProvider: IPStore); var ppEnumTypes: IEnumPStoreTypes; NroElementiRestituiti: Cardinal; GUID_Type: TGUID; begin FProvider.EnumTypes(0, 0, ppEnumTypes); NroElementiRestituiti := 0; repeat ppEnumTypes.Next(1, GUID_Type, NroElementiRestituiti); if NroElementiRestituiti > 0 then begin Form1.Memo1.Lines.Add(GUIDToString(GUID_Type)+ '---' + Type_Name(GUID_Type)); end; until NroElementiRestituiti = 0; end;

2.6 Enumerare i SUBTYPE

Come nel caso dei TYPE, anche i SUBTYPE sono rappresentabili sia tramite GUID sia tramite Nome

function SubType_Name(pType, pSubType: TGUID): string; var pst: PUserType3; begin pst := nil; FProvider.GetSubtypeInfo(0, pType, pSubType, pst, 0); Result := String(pst^.szDisplayName); CoTaskMemFree(pst); end; procedure ElencoSubTypes(FProvider: IPStore; GUID_Type: TGUID); var ppEnumSubTypes: IEnumPStoreTypes; NroElementiRestituiti: Cardinal; GUID_SubType: TGUID; begin FProvider.EnumSubTypes(0, GUID_Type, 0, ppEnumSubTypes); NroElementiRestituiti := 0; repeat ppEnumSubTypes.Next(1, GUID_SubType, NroElementiRestituiti); if NroElementiRestituiti > 0 then begin Form1.Memo1.Lines.Add(' ' + GUIDToString(GUID_SubType)+ '---' + SubType_Name(GUID_Type, GUID_SubType)); end; until NroElementiRestituiti = 0; end;

2.7 Enumerare gli ITEM e DATA associato ad ognuno di essi

function Item_Data(FProvider: IPStore; GUID_Type: TGUID; GUID_SubType: TGUID; Item_Name: PWideChar): string; var DimData: Cardinal; Data: PByte1; pstpi: _PST_PROMPTINFO; i: Cardinal; StringaDati: string; begin DimData := 0; Data := nil; pstpi.cbSize := SizeOf(_PST_PROMPTINFO); pstpi.dwPromptFlags := 4; pstpi.hwndApp := 0; pstpi.szPrompt := ''; FProvider.ReadItem(0, GUID_Type, GUID_SubType, StringToOleStr(Item_Name), DimData, Data, pstpi, 0); while i < DimData do begin if (PByte(Integer(Data) + i)^ < $20) or (PByte(Integer(Data) + i)^ > $7F) then StringaDati := StringaDati + '*' else StringaDati := StringaDati + pChar(Integer(Data) + i)^; Inc(i, 2); end; CoTaskMemFree(Data); Result := StringaDati; end; procedure ElencoItems(FProvider: IPStore; GUID_Type: TGUID; GUID_SubType: TGUID); var ppEnumItems: IEnumPStoreItems; NroElementiRestituiti: Cardinal; Item_Name: PWideChar; begin FProvider.EnumItems(0, GUID_Type, GUID_SubType, 0, ppEnumItems); NroElementiRestituiti := 0; repeat ppEnumItems.Next(1, Item_Name, NroElementiRestituiti); if NroElementiRestituiti > 0 then begin Form1.Memo1.Lines.Add(' ' + ' ' + String(Item_Name)); Form1.Memo1.Lines.Add(' ' + ' ' + ' ' + Item_Data(FProvider, GUID_Type, GUID_SubType, Item_Name)); end; until NroElementiRestituiti = 0; end;

3. Locazione del Protected Storage

Come ultima cosa doveroso dire che il Protected Storage contenuto nel registro nella chiave seguente

HKCU\Software\Microsoft\Protected Storage System Provider

Si fa riferimento al Current User: infatti il Protected Storage associato all'utente e ne esiste uno per ogni account.

ProtStorageViewer.7z

 

 

 

 

 

 

 

 

 

 




 


 

 

 

 

 
 
Your Ad Here