Sebbene Windows supporti la memoria condivisa tramite il suo file mapping API, non è possibile iniettare facilmente un mapping di memoria condivisa in un altro processo direttamente, poiché MapViewOfFileEx non accetta un argomento di processo.
Tuttavia, è possibile iniettare alcuni dati allocando memoria in un altro processo utilizzando VirtualAllocEx e WriteProcessMemory. Se dovessi copiare in una maniglia usando DuplicateHandle, quindi iniettare uno stub che chiama MapViewOfFileEx, potresti stabilire una mappatura della memoria condivisa in un altro processo. Dal momento che sembra che ti stia iniettando del codice comunque, questo dovrebbe funzionare bene per te.
In sintesi, è necessario:
- Creare un anonimo maniglia segmento di memoria condivisa chiamando CreateFileMapping con INVALID_HANDLE_VALUE per hFile e NULL per lpName.
- Copia questo handle nel processo di destinazione con DuplicateHandle
- Allocare po 'di memoria per il codice usando VirtualAllocEx, con flAllocationType = MEM_COMMIT | MEM_RESERVE e flProtect = PAGE_EXECUTE_READWRITE
- Scrive il tuo codice stub in questa memoria, utilizzando WriteProcessMemory. Probabilmente questo stub dovrà essere scritto in assembler. Passa la MANIGLIA da DuplicateHandle scrivendola qui da qualche parte.
- Esegui lo stub utilizzando CreateRemoteThread. Lo stub deve quindi utilizzare la MANIGLIA ottenuta per chiamare MapViewOfFileEx. I processi avranno quindi un segmento di memoria condivisa comune.
Si può trovare un po 'più facile se il vostro stub carica una libreria esterna - che è, hanno semplicemente chiamare LoadLibrary (trovare l'indirizzo del LoadLibrary viene lasciato come esercizio per il lettore) e fare il vostro lavoro dalla punto di ingresso del dllmain della biblioteca. In questo caso è probabile che l'utilizzo della memoria condivisa denominata sia più semplice di quello di andare avanti con DuplicateHandle.Vedere l'articolo MSDN su CreateFileMapping per ulteriori dettagli, ma, in sostanza, passare INVALID_HANDLE_VALUE per hFile e un nome per lpName.
Modifica: Poiché il problema sta passando i dati e non l'effettiva iniezione di codice, qui ci sono alcune opzioni.
- Utilizzare la memoria condivisa di dimensioni variabili. Il tuo stub prende la dimensione e il nome o un handle nella memoria condivisa. Questo è appropriato se hai bisogno solo di scambiare dati una volta. Si noti che la dimensione di un segmento di memoria condivisa non può essere facilmente modificata dopo la creazione.
- Utilizzare un named pipe. Il tuo stub prende il nome o un handle per la pipe. È quindi possibile utilizzare un protocollo appropriato per scambiare blocchi di dimensioni variabili, ad esempio scrivere un size_t per la lunghezza, seguito dal messaggio effettivo. In alternativa, utilizza PIPE_TYPE_MESSAGE e PIPE_READMODE_MESSAGE e osserva ERROR_MORE_DATA per determinare dove terminano i messaggi. Questo è appropriato se è necessario scambiare dati più volte.
Edit 2: Ecco un abbozzo di come si potrebbe implementare la maniglia o la conservazione puntatore per il vostro stub:
.db B8 ;; mov eax, imm32
.dl handle_value ;; fill this in (located at the start of the image + one byte)
;; handle value is now in eax, do with it as you will
;; more code follows...
Si potrebbe anche solo usare un nome fisso, che è probabilmente più semplice.
Che tipo di programma? Windows, GUI, console? –
tutti loro. Posso eseguire da un servizio, una GUI o una console – wonderer
C'è un bel wrapper C++ facile da usare per i file mappati in memoria nel progetto POCO. http://pocoproject.org/download/index.html L'ho trovato dopo aver ripetutamente cercato dolorosamente di usare la roba Boost, che altre persone potrebbero trovare facile da usare, ma ho trovato brutalmente difficile da usare correttamente. –