Createremotethread

mercoledì 18 febbraio 2009 - 15.56

ciccioherz Profilo | Junior Member

su questo blog http://blogs.msdn.com/jmstall/articles/sample_create_remote_thread.aspx
ho trovato un esempio molto interessante su come scrivere nella memoria di un processo.

l'esempio pero scrive nella sua stessa memoria, mentre io ho provato a modificarlo tentando ad esempio
di scrivere in un altro processo, come notepad.exe o altri ancora.

il risultato è che ottengo sempre errore, qualcuno ha qualche buon esempio scritto in .net
da poter postare?

P.s. l'errore generato dal sistema operativo è sempre lo stesso e cioè: access violation,
quindi l'errore si verifica proprio nella chiamata alla funzione
createremotethread.
grazie

aiedail92 Profilo | Expert

Ciao

La funzione CreateRemoteThread in realtà non serve a scrivere la memoria di un processo, ma serve a creare un thread facendolo eseguire da un altro processo. Ora, non è possibile creare in un processo differente un thread passando come indirizzo del metodo un'indirizzo che risiede nella memoria di un altro processo, perchè per esso quella memoria non ha alcun significato.

Mi spiego megio: il parametro hProcess della funzione CreateRemoteThread identifica il processo su cui verrà creato il thread, mentre il parametro lpStartAddress contiene un puntatore al punto di avvio della funzione che il thread deve eseguire.

Ora, finchè hProcess coincide col processo corrente, problemi non ce ne sono, ma se hProcess identifica un altro processo, il puntatore lpStartAddress farà riferimento come indice all'area dove sta la funzione da eseguire, però su un altro processo, dove quell'area di memoria avrà tutt'altro significato (sempre che ne abbia). Questo fa sì che il processo tenti di eseguire un thread dandogli come punto di avvio un'area di memoria non valida, e generando così l'acces violation (e generalmente il crash del processo di destinazione).

Pertanto non puoi usare questo metodo, anche se in combinazione con altre funzioni avanzate è possibile creare un thread su un processo differente, ma comunque la cosa è impossibile da realizzare in .net perchè non puoi scrivere una funzione in memoria e comunque il programma di destinazione dovrebbe usare anch'esso il framework.

Luca

ciccioherz Profilo | Junior Member

Ok, questo è ciò che ho ipotizzato per quanto riguarda l'impossibilità di far eseguire un thread su un altro processo scritto in codice non gestito, motivo per cui ho anche provato lo stesso metodo, questa volta però tentando di far eseguire il mio thread su un processo scritto in codice gestito (una mia applicazione .net) e anche in questo caso il risultato non cambia.

Detto questo, hai accennato al fatto che in combinazione con altre funzioni tutto ciò sarebbe possibile.
Stiamo parlando sempre di codice .Net, oppure no?
E in ogni caso, sapresti indicarmi quali sono queste funzioni?
hai link con degli esempi che facciano al casomio?
codice in c++ va benissimo.
Grazie

aiedail92 Profilo | Expert

Il concetto di fondo è questo:

Per far sì che un processo remoto possa eseguire una funzione a tuo piacere, quel processo deve avere la funzione scritta da qualche parte nella sua memoria, infatti non è possibile per lui accedere alla memoria del tuo processo.

Quindi ti vengono in aiuto le API di Windows, e in particolare la funzione VirtualAllocEx, che consente di allocare della memoria su un processo diverso dal chiamante.

Una volta allocata la memoria sull'altro processo, puoi scrivere su quella memoria la funzione che vuoi eseguire, e qui viene il problema con il .net: dato che siamo in ambito gestito, non puoi copiare direttamente il "contenuto" di una funzione (cioè il suo codice, che non è altro che un insieme di istruzioni binarie interpretabili dal processore), perchè evidentemente in ambito gestito queste istruzioni non sono codice macchina. Ed è per questo che devi usare del codice C o C++, o comunque codice non gestito.

Ora che hai allocato la memoria, devi soltanto copiare la funzione; questo lo puoi fare molto semplicemente in C++ usando l'API WriteProcessMemory; l'area di memoria da copiare la prendi dal puntatore alla funzione da iniettare nel processo remoto.

Adesso puoi finalmente usare il metodo CreateRemoteThread per creare il thread sul processo remoto; l'indirizzo della funzione è quello ottenuto con VirtualAllocEx, e il processo avrà la funzione da utilizzare come thread.

Se ti può interessare, qui ho utilizzato questo metodo per ottenere la riga di comando di un qualsiasi processo avviato; il codice è in C++ ed è ben commentato: http://procoder.forumfree.net/?t=32455175

Luca

ciccioherz Profilo | Junior Member

sei stato molto chiaro.
ottimo, grazie

aiedail92 Profilo | Expert

Di niente; se hai risolto accetta il thread, se poi ti vengono altri dubbi scrivi pure ancora qui

Luca

luigidibiasi Profilo | Guru

Riapro un attimo questo post perché credo manchi un'informazione importante:

Se da processo A inietto codice in B seguendo correttamente tutte le procedure e poi avvio con createremotethread un thread su B (che parte e funziona), se termino A il thread in B rimane in esecuzione?



Luigi Di Biasi


http://www.dibiasi.it/
http://netsell.dibiasi.it - ecomm software -
http://blogs.dotnethell.it/luigidibiasi/

aiedail92 Profilo | Expert

Non ho verificato, ma sì, dovrebbe continuare la sua esecuzione anche se il processo che l'ha creato termina.

Luca

luigidibiasi Profilo | Guru

Ma se ho una dll e me la carico in memoria tramite LoadModule riesco a prendere un puntatore ad una funzione che magari sta dentro quella dll per poi spararla in un altro processo?
Luigi Di Biasi


http://www.dibiasi.it/
http://netsell.dibiasi.it - ecomm software -
http://blogs.dotnethell.it/luigidibiasi/

aiedail92 Profilo | Expert

>Ma se ho una dll e me la carico in memoria tramite LoadModule
>riesco a prendere un puntatore ad una funzione che magari sta
>dentro quella dll per poi spararla in un altro processo?

Per una dll generica, se la carichi nel tuo processo la risposta è no, perché non puoi usare lo stesso puntatore alla funzione, che nell'altro processo non avrebbe significato.

Quello che puoi fare è invece chiamare CreateRemoteThread passando come funzione un puntatore a LoadLibrary (che ha un indirizzo fisso) e come argomento della funzione una stringa, creata nel processo remoto con VirtualAllocEx, contenente il nome della dll da caricare. A questo punto la dll è caricata nel processo remoto, e con simili accorgimenti puoi caricare la funzione dalla dll e richiamarla nel processo remoto.

Luca

luigidibiasi Profilo | Guru

Non posso mettere accetta risposta ma grazie comunque
Luigi Di Biasi


http://www.dibiasi.it/
http://netsell.dibiasi.it - ecomm software -
http://blogs.dotnethell.it/luigidibiasi/
Partecipa anche tu! Registrati!
Hai bisogno di aiuto ?
Perchè non ti registri subito?

Dopo esserti registrato potrai chiedere
aiuto sul nostro Forum oppure aiutare gli altri

Consulta le Stanze disponibili.

Registrati ora !
Copyright © dotNetHell.it 2002-2024
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5