2010-01-17 16 views
14

Mi piacerebbe simulare un file senza scriverlo su disco. Ho un file alla fine del mio eseguibile e vorrei dare il suo percorso a una DLL. Certo, dal momento che non ha una vera strada, devo fingere.Come creare un file virtuale?

Prima ho provato a utilizzare pipe denominate in Windows per farlo. Ciò consentirebbe un percorso come \\. \ Pipe \ mymemoryfile ma non riesco a farlo funzionare, e non sono sicuro che la dll possa supportare un percorso come questo.

In secondo luogo, ho trovato CreateFileMapping e GetMappedFileName. Possono essere usati per simulare un file in un frammento di un altro? Non sono sicuro che questo sia ciò che fa questa API.

Quello che sto cercando di fare sembra simile a boxedapp. Qualche idea su come lo fanno? Suppongo che sia qualcosa come l'intercettazione delle API (Like Detour), ma sarebbe molto lavoro. C'è un altro modo per farlo ?

Perché? Sono interessato a questa soluzione specifica perché mi piacerebbe nascondere i dati e per il beneficio di distribuire solo un file ma anche per motivi geniali di farlo funzionare in questo modo;) Sono d'accordo che copiare i dati in un file temporaneo sarebbe lavorare ed essere una soluzione molto più semplice.

risposta

4

È possibile memorizzare i dati in un flusso NTFS. In questo modo si può ottenere un vero e proprio percorso che punta ai dati che si può dare al vostro dll in forma di

x:\myfile.exe:mystreamname 

Questo funziona esattamente come un normale file, ma funziona solo se il file system utilizzato è NTFS. Questo è standard in Windows al giorno d'oggi, ma ovviamente non è un'opzione se si desidera supportare i sistemi più vecchi o si desidera essere in grado di eseguirlo da una chiavetta USB o simili. Notare che i corsi d'acqua presenti in un file saranno persi se il file viene inviato come allegato in posta elettronica o semplicemente copiato da una partizione NTFS in una partizione FAT32.

direi che il modo più compatibile sarebbe quello di scrivere i dati in un file vero e proprio, ma si può naturalmente farlo in un modo su sistemi NTFS e un altro sul system FAT. Lo raccomando a causa della complessità aggiunta. Il modo appropriato sarebbe quello di distribuire i file separatamente, ovviamente, ma poiché hai indicato che non vuoi questo, dovresti in quel caso scriverlo in un file temporaneo e dare alla DLL il percorso per quel file. Assicurati di scrivere il file temporaneo nella directory temporanea degli utenti (puoi trovare il percorso usando GetTempPath in C/C++).

L'altra opzione sarebbe quella di scrivere un driver di filtro del file system, ma che è una strada che mi consiglia vivamente contro. Questo tipo di sconfigge lo scopo di utilizzare un singolo file ...

Inoltre, nel caso in cui si desideri solo un singolo file per la distribuzione, che ne dici di utilizzare un file zip o un programma di installazione?

+0

E come si distribuisce esattamente il file? Direi che zippare o copiare l'exe farà svanire il flusso NTFS? –

+0

@ Gregory: Sì. Il caso d'uso non è chiaro nella domanda, ma sono d'accordo sul fatto che l'utilizzo degli stream potrebbe non essere un'opzione per l'OP - si spera che anche questo sia chiaramente indicato nella mia risposta. Il punto principale su cui sto cercando di battere a casa nella risposta è che l'utilizzo di un file reale è l'opzione migliore. – villintehaspam

+0

Questa è un'idea molto interessante. Peccato che funzioni solo su ntfs. Poiché non esiste una risposta perfetta, questa è la migliore. –

4

I tubi sono per la comunicazione tra processi in esecuzione contemporaneamente. Non memorizzano i dati per l'accesso successivo e non hanno la stessa semantica dei file (non è possibile cercare o riavvolgere una pipe, ad esempio).

Se si sta cercando un comportamento simile a un file, la soluzione migliore è sempre quella di utilizzare un file. Sotto Windows, è possibile passare FILE_ATTRIBUTE_TEMPORARY a CreateFile come suggerimento al sistema per evitare di scaricare dati sul disco se c'è sufficiente memoria.

Se si è preoccupati per l'impatto sulle prestazioni della scrittura su disco, quanto sopra dovrebbe essere sufficiente per evitare l'impatto sulle prestazioni nella maggior parte dei casi. (Se il sistema ha abbastanza memoria insufficiente per forzare i dati del file sul disco, è probabile che si verifichi anche lo swapping in ogni caso - hai già avuto un problema di prestazioni.)

Se stai cercando di evitare di scrivere sul disco per qualche altra ragione, puoi spiegare perché? In generale, è abbastanza difficile impedire ai dati di colpire il disco - l'utente può sempre ibernare la macchina, ad esempio.

+0

I file verranno incorporati direttamente nell'exe, ma la dll accetta solo un percorso come input (non può essere caricato da un istream o qualcosa di simile) –

3

Dato che non si ha il controllo della DLL, si suppone che la DLL si aspetti un file vero e proprio. Probabilmente, a un certo punto, questo presupposto è il motivo per cui le pipe denominate non funzionano su di te.

La soluzione più semplice consiste nel creare un file temporaneo nella directory temporanea, scrivere i dati dal file EXE nel file temporaneo e quindi eliminare il file temporaneo.

C'è un motivo per cui si incorpora questo "pseudo-file" alla fine del file EXE invece di distribuirlo con la nostra applicazione? Ovviamente stai già distribuendo questa DLL di terze parti con la tua applicazione in modo che un altro file non sembri che possa farti del male?

Un'altra domanda, questi dati cambieranno? Cioè ti aspetti di riscrivere i dati di questo "pseudo-file" nel tuo EXE? Non penso che funzionerà bene. Gli utenti standard potrebbero non avere accesso in scrittura all'EXE e questo probabilmente guiderà i virus dell'antivirus.

E no CreateFileMapping e GetMappedFileName sicuramente non funzioneranno poiché non ti danno un nome di file che può essere passato a CreateFile. Se si potesse in qualche modo ottenere questa DLL per accettare una MANIGLIA, allora funzionerebbe.

E non vorrei nemmeno preoccuparmi dell'intercettazione API. Basta dare alla DLL un percorso per un file acutale.

1

Leggere la tua domanda mi ha fatto pensare: se puoi fingere un'area di memoria è un file e avere una specie di "percorso virtuale", allora questo permetterebbe di caricare una DLL direttamente dalla memoria che è ciò che LoadLibrary proibisce dal design chiedendo un nome di percorso. Ed è per questo che le persone scrivono il proprio caricatore di PE quando vogliono ottenerlo.

Direi che non è possibile ottenere ciò che si desidera con la mappatura dei file: lo scopo della mappatura dei file è trattare una parte di un file come se si trattasse di memoria fisica e si desidera il reciproco.

L'utilizzo di Detours implica che è necessario replicare tutto ciò che la funzione intercettata della DLL fa tranne che ottenere dati da un file reale; quindi non è generico. Oppure, ancora più complicato, facciamo finta che la DLL usi fopen; quindi fornisci il tuo fopen che rileva uno schema speciale nel percorso e mimmica gli interni del runtime C ... Hmm vale davvero tutto il dolore? : D

+0

poiché c runtime è una facciata per le funzioni w32, I wouldn È necessario sovrascrivere ogni funzione che utilizza il file, ma quella di basso livello. –

0

Che ne dici di utilizzare una sorta di RamDisk e scrivere il file su questo disco? Ho provato personalmente alcuni ramdisk, anche se non ne ho mai trovato uno buono, dimmi se hai successo.

0

Bene, se è necessario avere il file virtuale allocato nel proprio exe, sarà necessario creare un vettore, un flusso o un array di caratteri sufficientemente grande da contenere tutti i dati virtuali che si desidera scrivere.

questa è l'unica soluzione a cui riesco a pensare senza eseguire alcun I/O su disco (anche se non si scrive su file).

Se è necessario mantenere un file come la sintassi del percorso, è sufficiente scrivere una classe che riproduca tale comportamento e invece di scrivere in un file di scrittura nel buffer di memoria. È così semplice come si arriva. Ricorda BACIO.

Acclamazioni

0

Si prega di spiegare il motivo per cui non è possibile estrarre i dati dal EXE e scrivere in un file temporaneo. Molte applicazioni lo fanno: è la soluzione classica a questo problema.

Se davvero necessario fornire un "file virtuale", la soluzione più pulita è probabilmente un driver di filtro del file system. "Pulite" non significa "buono" - un filtro è una soluzione completamente documentata e supportata, quindi è più pulito di aggancio API, iniezione, ecc Tuttavia, filtri file system non sono facili.

OSR Online è il posto migliore per trovare informazioni filesystem di Windows. Il NTFSD mailing list è dove gli sviluppatori filesystem appendere fuori.

0

Aprire il file "NUL:" per la scrittura. È scrivibile, ma i dati vengono scartati in silenzio. Un po 'come/dev/null di * nix fame.

Non è possibile mapparlo in memoria. La mappatura della memoria implica l'accesso in lettura/scrittura e NUL è solo in scrittura.

0

Sto indovinando che questa DLL può giocare un torrente? È quasi semplice da chiedere, MA se si può semplicemente usare quello.

+0

È una DLL che non possiedo, né ho un codice sorgente per questo, ha solo un file di caricamento con un percorso. Quindi non posso cambiarlo. –

3

Usa BoxedApp e non preoccuparti.

+2

Cool app! Funziona anche con il registro virtuale! –