samedi 12 janvier 2008

Injection de dll dans un processus

Aujourd'hui je vais vous présenter une méthode plutot connue pour injecter une dll dans un processus. Pour celà on va d'abord faire un loader qui s'ocuppera de charger notre dll dans un processus puis on construira ensuite celle-ci.
Pour le loaders on distingue 5 étapes :

1.Récupérer l'adresse de LoadLibraryA()
Pour récupérer l'adresse de LoadLibraryA() il suffit d'utiliser la fonction GetModuleHandleA(). Le prototype de la fonction :

HMODULE WINAPI GetModuleHandle(
__in_opt LPCTSTR lpModuleName
);


2.Ouvrir le processus voulu
Pour celà on créera une liste de tous les processus actifs et on récupèrera l'id de celui voulu. On ouvrira simplement le processus avec OpenProcess(). Le prototype de la fonction :
HANDLE WINAPI OpenProcess(
__in DWORD dwDesiredAccess,
__in BOOL bInheritHandle,
__in DWORD dwProcessId
);


3.Allouer un espace de mémoire dans le processus
Pour allouer un espace de mémoire on utilisera VirtualAllocEx(). Le prototype de la fonction :
LPVOID WINAPI VirtualAllocEx(
__in HANDLE hProcess,
__in_opt LPVOID lpAddress,
__in SIZE_T dwSize,
__in DWORD flAllocationType,
__in DWORD flProtect
);


4.Ecrire les donnes necessaires au chargement de la dll
Pour ceci on va utiliser WriteProcessMemory(). On pourrait écrire quelque chose du genre LoadLibraryA("dll.dll") dans le processus, ce qui donne en assembleur :
PUSH offset_nom_dll
CALL LoadLibraryA
RET
Mais pour faire simple on se contentera d'écrire seulement le nom de la dll dans l'espace de mémoire et on éxecutera LoadLibraryA() grace à notre thread.
Le prototype de la fonction WriteProcessMemory est :
BOOL WINAPI WriteProcessMemory(
__in HANDLE hProcess,
__in LPVOID lpBaseAddress,
__in LPCVOID lpBuffer,
__in SIZE_T nSize,

__out SIZE_T* lpNumberOfBytesWritten
);

5.Créer un thread dans le processus afin d'excuter le code écris dans l'espace de mémoire alloué
C'est l'étape la plus importante, ici on utilisera CreateRemoteThread() pour créer un thread dans le processus qui executera LoadLibraryA() avec en parametre le nom de notre dll. Le prototype de la fonction :
HANDLE WINAPI CreateRemoteThread(
__in HANDLE hProcess,
__in LPSECURITY_ATTRIBUTES lpThreadAttributes,
__in SIZE_T dwStackSize,
__in LPTHREAD_START_ROUTINE lpStartAddress,
__in LPVOID lpParameter,
__in DWORD dwCreationFlags,
__out LPDWORD lpThreadId
);

Viens ensuite notre dll. Je vais faire simple pour bien montrer le concept.
Lorsqu'on va charger notre dll avec LoadLibaryA(), la fonction va ensuite appeler la fonction main de la Dll avec DLL_PROCESS_ATTACH comme second parametre. On vérifiera donc que le seconde parametre est bien à cette valeur et le tour est joué.
Vous trouverez plus d'info ici : http://msdn2.microsoft.com/en-us/library/ms684175(VS.85).aspx
et ici :
http://msdn2.microsoft.com/en-us/library/ms682583(VS.85).aspx

Le code de la dll : Injectme.cpp
Le code du loader : DllInjector.cpp

Voilà ce sera tout pour aujourd'hui.
Have Fun :)
lilxam.

1 commentaire:

C.Courtot a dit…

je nai pas comris a quel moment et quel ID on inject c'est a dire je veut injecter xx.exe a quel moment on l'inject et que remplace ton dans le code SVP.
reponds moi
Courtot.C@gmail.com