Ce petit prog montre comment injecter une dll dans un processus avec les fonctions de l'api WIN32, ça permet donc d'executer du code dans un autre processus.
Voici les étapes de l'injection :
On ouvre d'abord le processus avec OpenProcess,
on alloue de la mémoire pour écrire le nom de la DLL à charger dans le processus avec VirtualAllocEx,
on écrit le nom de la dll avec WriteProcessMemory,
on recherche la fonction LoadLibrary qui permet de charger une DLL avec GetProcAddress,
on lance le thread qui va s'executer dans l'espace mémoire du processus et charger la dll avec CreateRemoteThread,
on libère la mémoire allouée avec VirtualFreeEx,
on ferme l'handle du thread ouvert avec CloseHandle().
L'injection est impossible dans certains processus(système, av...)(c'est possible en passant par les privilège de debug).
Voilà c'est tout :).
Source / Exemple :
public static bool StartInjection(string DllName, uint ProcessID)
{
try
{
IntPtr hProcess = new IntPtr(0); //openprocess
IntPtr hModule = new IntPtr(0); //vritualAllocex
IntPtr Injector = new IntPtr(0); //getprocadress
IntPtr hThread = new IntPtr(0); //createremotethread
int LenWrite = DllName.Length + 1;
//on ouvre le processus avec tout les droits d'accés
hProcess = OpenProcess(PROCESS_ALL_ACCESS, false, ProcessID);
//si il a bien été ouvert
if (hProcess != IntPtr.Zero)
{
//on va allouer de la mémoire
hModule = VirtualAllocEx(hProcess, IntPtr.Zero, (UIntPtr)LenWrite, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
//si on a bien alloué de la mémoire
if (hModule != IntPtr.Zero)
{
//on va écrire le nom de la dll dans le process
ASCIIEncoding Encoder = new ASCIIEncoding();
//nombre de bytes écrits
int Written = 0;
//si on a bien écrit dans le process
if (WriteProcessMemory(hProcess, hModule, Encoder.GetBytes(DllName), LenWrite, Written))
{
//on va rechercher la fonction LoadLibrary qui va charger la dll
Injector = GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA");
//si on a bien trouvé l'adresse
if (Injector != IntPtr.Zero)
{
//on lance le thread qui va s'executer dans l'espace mémoire du processus et charger la dll
hThread = CreateRemoteThread(hProcess, IntPtr.Zero, 0, Injector, hModule, 0, 0);
//pas d'erreur avec le lancement du thread
if (hThread != IntPtr.Zero)
{
//10 secondes
uint Result = WaitForSingleObject(hThread, 10 * 1000);
//...
if (Result != WAIT_FAILED || Result != WAIT_ABANDONED
|| Result != WAIT_OBJECT_0 || Result != WAIT_TIMEOUT)
{
//on désalloc la mémoire allouée
if (VirtualFreeEx(hProcess, hModule, 0, MEM_RELEASE))
{
//on regarde si l'handle du thread retourné n'est pas null
if (hThread != IntPtr.Zero)
{
//injection réussie :]
CloseHandle(hThread);
MessageBox.Show("Injection réussie !", "Succés", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
return true;
}
else throw new Exception("Mauvais Handle du thread...injection échouée");
}
else throw new Exception("Problème libèration de mémoire...injection échouée");
}
else throw new Exception("WaitForSingle échoué : " + Result.ToString() + "...injection échouée");
}
else throw new Exception("Problème au lancement du thread...injection échouée");
}
else throw new Exception("Adresse LoadLibraryA non trouvée...injection échouée");
}
else throw new Exception("Erreur d'écriture dans le processus...injection échouée");
}
else throw new Exception("Mémoire non allouée...injection échouée");
}
else throw new Exception("Processus non ouvert...injection échouée");
}
catch (Exception e)
{
//en cas d'erreur on affiche l'erreur et on arrête la fonction(pas d'injection)
MessageBox.Show(e.Message, e.Source);
return false;
}
}
Conclusion :
J'ai aussi mis une dll que j'ai programmée en c++ que vous pouvez utiliser pour tester le prog.
J'ai modifié la DLL, toujours en c++ mais elle affiche juste une messagebox
"Hello World" lorsque elle est injectée et lorsque elle est détachée.
Source dll ici :
http://misugipr0ject.free.fr/myDll.rar
En aucun cas je n'incite au hacking / cracking, l'injection de dll permet de faire plein d'autre choses.
Bonne prog :).
Vous n'êtes pas encore membre ?
inscrivez-vous, c'est gratuit et ça prend moins d'une minute !
Les membres obtiennent plus de réponses que les utilisateurs anonymes.
Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.
Le fait d'être membre vous permet d'avoir des options supplémentaires.