AppInit_DLL, novità in Windows 7 e 2008 R2

Salve a tutti.

AppInit_DLL è una delle infrastrutture disponibili nel sistema operativo per estendere le funzionalità di un programma, aggiungendo, o meglio, “iniettando” una dll all’interno di un processo.  La AppInit_DLL fornisce in modo semplice ed efficace la possibilità di caricare una dll custom all’interno di tutti i processi, e di rimpiazzare per mezzo di hook, le chiamate API di sistema, aggiungendo funzionalità, o anche solo per scopi di logging e/o tracing applicativo. Tipico esempio di questa funzionalità, gli antivirus.

Come gli antivirus, anche i virus e i malware, hanno sfruttato questo principio, di per se molto semplice ed efficace. Per questo motivo, a partire da Windows Vista l’infrastruttura AppINit_DLL è disabilitata per default. Questo comportamento rimane invariato per Windows 7 e 2008 R2. Ma cosa cambia quando questa viene attivata?

La configurazione della infrastruttura AppInit_DLL è controllata e regolata attraverso le chiavi di registry disponibili sotto:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT \CurrentVersion\Windows\

La seguente tabella mostra i possibili valori delle chiavi, e il loro significato:

Valore

Descrizione

Valori di esempio

LoadAppInit_DLLs (REG_DWORD)

Valore che abilita/disabilita a livello globale AppInit_DLL

0x0 – AppInit_DLL è disabilitata. 0x1 – AppInit_DLL è abilitata.

AppInit_DLLs (REG_SZ)

Lista di dll da caricare, delimitata da spazi o virgole. Il percorso completo deve essere specificato usando lo short file name.

C:\PROGRA~1\Test\Test.dll

RequireSignedAppInit_DLLs (REG_DWORD)

Richiede DLL firmate digitalmente.

0x0 – Carica ogni DLL. 0x1 – Carica solo DLL firmate digitalmente.

Le AppInit_DLL non vengono caricate all’interno dei processi protetti da DRM (Digital Right Management), e questo come è facile intuire non si può modificare/configurare. Inoltre, non verranno caricate in questi processi, considerati processi critici del Sistema:

· Windows Defender.

· Windows Software Licensing service.

· Microsoft Hyper-V (vmms.exe and vmwp.exe).

Durante un Upgrade da Vista a Windows 7, le dll che sono elencate nella chiave ApInit_DLL, non vengono migrate nel registry di Windows 7. Inoltre, durante Upgrade da sistemi operativi precedenti a Vista, le dll elencate non vengono nemmeno copiate nelle cartelle di sistema di Windows.

Per default, Windows 7, per motivi di compatibilità, continuerà a caricare tutte le dll elencate in AppInit_DLL, indipendentemente dal fatto che queste siano firmate digitalmente o meno. Questo perchè per default, RequireSignedAppInit_DLLs è impostato a 0.

Su Windows 2008 R2 invece, RequireSignedAppInit_DLLs è impostato a 1 per default, e quindi solo le librerie firmate digitalmente verranno caricate. Bisogna anche considerare la bitness delle DLL, visto che 2008 R2 è solo a 64 bit. Non si può caricare una dll a 32 bit in un processo a 64 bit e viceversa..

Microsoft raccomanda a tutti gl sviluppatori di estensioni che usano l’infrastruttura AppInit_DLL di iniziare a firmare digitalmente le librerie, perchè in futuro diventerà obbligatorio.

Developer Best Practices

Cosa devono fare gli sviluppatori per assicurarsi che le loro estensioni funzionino al meglio e siano caricate in Windows 7 (e sistemi successivi):

  • Firmare digitalmente le DLL.
    Versioni successive di Windows caricheranno solo DLL firmate digitalmente, e non sarà disponibile una chiave di registry per configurare questo comportamento. Sarà obbligatorio.
  • Caricare le DLL solo nel processo richiesto e non in tutti i processi indistintamente.
    L’infrastruttura AppInit_DLL carica le dll elencate nella chiave di registry in tutti i processi al loro avvio. Se la DLL è pensata per funzonare solo all’interno di un determinato processo, allora bisogna chiamare dall’interno della DLLMain, la GetModuleFileName, per recuperare il nome del processo che ci sta caricando. Se non è quello che ci interessa, bisogna semplicemente ritornare e non proseguire nel caricamento.
  • Durante la fase di inizializzazione, chiamare solo API esportate da Kernel32.dll.
    Ricordando il fatto che questa infrastruttura consente di caricare DLL in “TUTTI” i processi, anche durante l’avvio del sistema operativo stesso, durante la fase di inizializzazione, ci si potrebbe trovare in una fase talmente embrionale del caricamento del sistema operativo, che molte funzionalità non saranno ancora disponibili. Per questo motivo è buona norma chiamare solo API contenute in Kernel32.dll, che sarà probabilmente l’unica dll già caricata in memoria nel processo in cui stiamo venendo caricati. Nulla impedisce di inizializzare un altro thread, la cui prima operazione è una sleep di qualche secondo, dando così modo alla dll di essere caricata senza problemi in qualunque processo senza causare problemi di loader lock durante l’inizializzazione, che come sempre deve essere il più atomica possibile.

Per tutti gli aspetti legati alla firma digitale e al testing nel sistema operativo vi rimando al documento ufficiale:

https://www.microsoft.com/whdc/driver/install/AppInit-Win7.mspx

Siamo così arrivati in prossimità delle festività natalizie. E’ stata una bella corsa. I Vostri feedback ci diranno se interessante o meno. Per il momento grazie per averci seguito e mi raccomando non abbiate paura di fare domande, di dare feedback, di interagire con noi. Siamo qui per aiutarvi possibilmente.

A nome del Supporto Tecnico agli Sviluppatori di Microsoft Italia, auguro a tutti un Buon Natale e un Felice Anno nuovo!

Alla prossima!

Mario Raccagni
Senior Support Engineer
Platform Development Support Team