Injecter une dll dans un processus

Description

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 :).

Codes Sources

A voir également

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.