Reindirizzamento DLL tramite manifest

Devo redirect in modo affidabile una ricerca delle applicazioni di una specifica DLL. L’utilizzo dell’approccio app.exe.local non funziona perché i file locali vengono ignorati se l’applicazione ha manifest (file incorporato o separato). Quindi sto cercando di fare il reindirizzamento DLL definendo la DLL come un assembly privato nei manifesti.

Ho un’applicazione di test, LoadDll.exe che semplicemente chiama

LoadLibrary("C:\\EmptyDll.dll"); 

LoadDll.exe ha manifest (come file separato, LoadDll.exe.manifest)

          

La cartella dell’applicazione che contiene LoadDll.exe (NON c: \) contiene il file EmptyDll.dll con il manifest incorporato.

     

Tuttavia, LoadDll.exe va avanti e carica C: \ EmptyDll.dll e non EmptyDll.dll nella cartella dell’applicazione.

Se si interrompe un manifest (ad esempio, modifica il numero di versione nell’id quadro manifest EmptyDll.dll), LoadDll.exe non viene caricato, quindi i file manifest vengono letti ed elaborati da Windows, ma semplicemente ignorati.

Qualcuno ha qualche idea?

Grazie!

Toby

Quindi sembra imansible redirect le chiamate a LoadLibrary con percorsi assoluti usando manifest.

Dopo aver giocato molto con i manifesti, sembra che una volta superati tutti i manifesti della ctriggers documentazione siano in realtà stupidamente semplici.

Fondamentalmente, quando l’eseguibile viene caricato, Windows raccoglie tutti i manifesti correlati che sono collegati usando gli elementi di id quadro e dipendenza. Quindi, per ogni elemento file contenuto nei file manifest, aggiunge una voce nel contesto di triggerszione:

 'name attribute of file element' -> 'absolute path of manifest file' + 'name attribute of file element' 

Ora, quando viene effettuata una chiamata a una libreria di carico, ricerca la mappa di contesto di triggerszione per una chiave che corrisponde all’argomento di percorso della libreria di caricamento, quindi esegue la loadlibrary con il valore per quella chiave.

Quindi se la mia applicazione c: \ foo \ foo.exe ha una dipendenza dal manifest in c: \ foo \ baa \ baa.manifest, e baa.manifest contiene un elemento , quindi il contesto di triggerszione avrà una mapping: "empty.dll" -> "c:\foo\baa\empty.dll"

Quindi tutte le chiamate a LoadLibrary("empty.dll") verranno reindirizzate a LoadLibrary("C:\foo\baa\empty.dll") .

Tuttavia, LoadLibrary("c:\anotherpath\empty.dll") non verrà reindirizzato!

Ora per dimostrare il mio punto di quanto siano stupidamente semplici file manifest e contesti di triggerszione. Se l’elemento file di baa.manifest era e hai fatto una chiamata LoadLibrary("C:\anotherpath\empty.dll") , la chiamata LoadLibrary verrà reindirizzata a LoadLibrary("C:\foo\baa\C:\anotherpath\empty.dll") , sì, un percorso LoadLibrary("C:\foo\baa\C:\anotherpath\empty.dll")

L’elemento file ha un attributo non documentato chiamato “loadFrom”, che fa quello che sembra, e sembra che sia perfetto per risolvere questo problema. Usando loadFrom, sono stato in grado di redirect una chiamata di loadlibrary path assoluto, ma sembrava rovinare altre dipendenze dell’eseguibile in modi strani. Se qualcuno sapesse di più su come funziona “loadFrom”, sarei molto interessato.

Quindi come ho risolto il mio problema alla fine? Utilizzando un approccio incredibilmente pesante di DLL Trojan descritto da Ethical Hacker . Fondamentalmente si crea un dummy kernel32.dll che reindirizza tutte le chiamate al kenerl32.dll originale, ad eccezione delle chiamate LoadLibrary, in cui si inserisce la propria logica di reindirizzamento. Quindi nel manifest delle applicazioni, si posiziona un elemento file che reindirizza il kernel32.dll al proprio manichino. Divertimento.

Tutto questo descrive i miei esperimenti su Windows Xp Sp2. Per divertimento in più, sono portato a credere che i manifesti si comportino diversamente su quasi tutte le versioni di Windows.

Ok, devi configurarlo in questo modo:

  • c:\apppath\testapp.exe – il tuo file exe di test
  • c:\apppath\testapp.exe.manifest – il – file manifest dell’applicazione potenzialmente incorporato
  • c:\apppath\EmptyAssm\EmptyAssm.manifest – Un manifest che descrive il nuovo assembly.
  • c:\apppath\EmptyAssm\empty.dll – la DLL di assemblaggio
  • c:\apppath\EmptyAssm\empty.dll.2.manifest – il manifest incorporato nella dll

Quindi, hai l’applicazione di test che contiene un manifest dell’applicazione: che contiene riferimenti all’assembly dipendenti per l’app, incluso uno che aggiungi all’assembly dll personalizzato.

Nella cartella dell’applicazione assm sottocartella della cartella dell’app è presente il assembly-manifest dell’assembly “EmptyAssm”, che contiene un nodo file che fa riferimento alla dll effettiva, “empty.dll”.

empty.dll incorpora il proprio manifest, contenente riferimenti di assembly dipendenti su qualsiasi assembly pubblico o privato richiesto.

Questo è il punto importante: il manifest di assembly “EmptyAssm” e i manifesti di dll “vuoti” sono potenzialmente diversi. Il file manifest dell’assembly (“EmptyAssm”) NON DEVE essere incorporato, ma potrebbe condividere il nome manifest della DLL se scegli di nominare il manifest tramite il nome della dll.

Ora, quando il loader carica il tuo EXE, carica il manifest di EXE e lo aggiunge al contesto di triggerszione. Quando viene elaborata la tabella di importazione dell’EXE, OPPURE si chiama LoadLibrary, il programma di ricerca cerca dapprima il contesto di triggerszione per un manifest di assembly con un nodo di file corrispondente. Se trova un assembly corrispondente, THEN lo processa e carica la DLL dalla posizione dell’assembly (la cartella contenente gli assembly .manifest) e potrebbe, in questo momento, se non ci sono manifest incorporati nella dll E la dll e manifest hanno lo stesso nome, riutilizzare lo stesso file manifest per configurare il contesto di triggerszione della DLL.

SE vuoi mettere il manifest “emptyassm”, e dll, in una cartella diversa alla cartella dell’applicazione, E SE stai mirando a Windows Server 2008, o Windows 7, o successivi, puoi aggiungere un file di configurazione per la tua app: –

  • c:\apppath\testapp.exe.config – file di configurazione dell’app

Il file di configurazione dell’app può contenere un nodo di interrogazione sotto il nodo assemblyBinding (i file di configurazione sono molto simili ai file manifest), con privatePath="some relative path" . In tal caso, la cartella relativa verrà ricercata per gli assembly.


La mia ultima risposta qui ha file di esempio che coprono il processo di creazione di un assembly da una DLL, e il riferimento da un exe: – Un modo per caricare DLL dal repository centrale


Giusto per chiarire: un assembly win32 è (nel modo più semplice) un file manifest che descrive l’assembly e una dll. Sono sempre, in questo modello, situati nella stessa cartella in modo che il nodo file del manifest non possa contenere alcuna informazione di percorso – solo il nome della dll.

Gli assembly possono essere condivisi, dando loro una versione forte (e alcuni digital signing) e installandoli in Windows \ WinSxS, o privati.

Le versioni di Windows precedenti alla 5.1 (Win XP) non cercheranno affatto gli assembly poiché questa tecnologia è stata aggiunta solo in XP. Windows 5.1 thru 6.0 (XP e Vista) cercherà solo gli assembly privati ​​nella cartella dell’object con il contesto di triggerszione attivo: – Se un exe fa riferimento a un assembly, la cartella contenente l’exe. Se il codice in una DLL fa riferimento a un assieme, viene cercata la cartella della DLL.

Se si desidera memorizzare la DLL in una posizione privata condivisa da diverse app (ad esempio), è necessario disporre di un requisito di Windows 7 o successivo: –

Windows versione 6.1 (altrimenti noto come Windows Server 2008 o Windows 7) e versioni successive, oltre alla cartella del modulo, eseguono la ricerca nel percorso specificato come elemento privatePath dell’elemento probing in un file di configurazione dell’applicazione. I file di configurazione dell’applicazione si trovano sempre nella stessa cartella di exe o dll e sono denominati:

.exe.config o .dll.2.config

(La ragione del .2 è che ci sono potenzialmente molti manifesti e config incorporati come risorse, e il caricatore riserva le risorse id 1 … 15. Quando si cerca sul disco un manifest di file di configurazione, se l’id risorsa del la risorsa incorporata sarebbe stata 1, l’ID è stato omesso, ma qualsiasi altro numero indica che diventa parte del nome del file).

Potresti riuscire a ovviare a questo problema utilizzando Detours , avvolgendo LoadLibrary . Il wrapper LoadLibrary sarebbe in grado di riconoscere i tentativi di caricare la DLL e riscrivere il percorso in modo appropriato.