Jump to content
zbeng

Procese in Windows

Recommended Posts

Posted

Procese in Windows

O aplicatie bazata pe Win32 consta din unul sau mai multe procese. Un proces, in cei mai simpli termeni, este un program executat. Modul oferit de Windows 9x pentru a avea control asupra aplicatiilor active este boxa de dialog "Close program" iar de Windows NT este "Task Manager". Citind acest eseu veti afla metodele de a evita aparitia programului in aceasta lista, si, din alta parte, o sa invatati cum sa scrieti un program ce va da controlul asupra proceselor in sistem.

Enumarare procese

Terminare procese

Ascundere procese

Links

Enumarare procese

Sa incepem de la urma, invatind modul de a enumera procesele. Pentru aceasta sint folosite functiile Tool Help ce se gasesc in kernel. Inainte de a incepe parcurgerea, trebuie facut un snapshot al sistemului. Aceasta este o necesitate datorita naturei multitasking a lui Windows.

Un snapshot este o copie read-only a starii unui sau mai multor obiecte din memoria sistemului: procese, threads, module si heaps. Procesele ce folosesc functiile Tool Help citesc listele din snapshot in locul accesarii directe a  listelor sistemului de operare (SO). Listele obiectelor din memoria SO se schimba cind procese, threaduri, module, heaps sint create sau distruse, cind aplicatii sint executate sau terminate. Folosirea informatiei din snapshot previne aparitia inconsistentelor. Altfel, aceste schimbari in timpul enumararii elementelor ar putea duce la traversarea incorecta a listei sau sa cauzeze access violation.

HANDLE WINAPI CreateToolhelp32Snapshot(

  DWORD dwFlags,

  DWORD th32ProcessID

);

In parametrul dwFlags specificam ce elemente trebuie sa fie incluse in snapshot. In cazul dat ne intereseaza numai procesele, deci transmitem TH32CS_SNAPPROCESS. Parametrul th32ProcessID este identificatorul de proces si este folosit in cazul cind este nevoie de a include elemente specifice unui proces. Ca rezultat, functia intoarce un handle la snapshotul creat, pe care putem sa il folosim in functiile de enumarare. Acest handle trebuie sa fie inchis cu CloseHandle dupa ce nu mai este nevoie de el.

typedef struct tagPROCESSENTRY32 {

    DWORD dwSize;

    DWORD cntUsage;

    DWORD th32ProcessID;

    DWORD th32DefaultHeapID;

    DWORD th32ModuleID;

    DWORD cntThreads;

    DWORD th32ParentProcessID;

    LONG  pcPriClassBase;

    DWORD dwFlags;

    char szExeFile[MAX_PATH];

} PROCESSENTRY32;

typedef PROCESSENTRY32 *  PPROCESSENTRY32;

typedef PROCESSENTRY32 *  LPPROCESSENTRY32;

In functiile urmatoare va fi folosita structura PROCESSENTRY32, in care va fi introdusa informatia despre proces. Inainte de a transmite structura la functie, trebuie initializat membrul dwSize cu sizeof(PROCESSENTRY32).

BOOL WINAPI Process32First(

  HANDLE hSnapshot,

  LPPROCESSENTRY32 lppe

);

Deci, hSnapshot este handle la snapshot, lppe este un pointer la o structura PROCESSENTRY32. Functia intoarce TRUE, daca datele despre primul proces au fost copiate in buffer, sau FALSE in caz contrar. Eroarea ERROR_NO_MORE_FILES este intoarsa de GetLastError daca nu exista nici un proces sau snapshotul nu contine informatie despre procese.

BOOL WINAPI Process32Next(

  HANDLE hSnapshot,

  LPPROCESSENTRY32 lppe

);

Parametrii si valorile intoarse au aceeasi semnificatie ca si in cazul precedent. Chemam in ciclu aceasta functie, pina cind lista nu se va epuiza (va intoarce FALSE).

Nota

Referitor la functiile Tool Help:

Windows NT: Requires version 5.0 or later.

Windows: Requires Windows 95 or later.

Windows CE: Unsupported.

Header: Declared in tlhelp32.h.

Import Library: Use kernel32.lib.

Referitor la WinNT:

In versiunile WinNT mai mici decit 5, informatia despre procesele active se pastreaza in registru la HKEY_LOCAL_MACHINESoftwareMicrosoftWindows NTCurrentVersionperflib.

Terminare procese

Identificatorul procesului identifica unic procesul in sistem. Dar pentru a accesa procesul din programul nostru e nevoie de obtinut un handle la el. Pentru aceasta vom folosi functia OpenProcess.

HANDLE OpenProcess(

  DWORD dwDesiredAccess,  // access flag

  BOOL bInheritHandle,    // handle inheritance flag

  DWORD dwProcessId      // process identifier

);

Handle-ul la proces trebuie sa aiba acces PROCESS_TERMINATE la el, ceea ce si indicam in dwDesiredAccess.

BOOL TerminateProcess(

  HANDLE hProcess, // handle to the process

  UINT uExitCode  // exit code for the process

);

TerminateProcess este folosit pentru terminarea neconditionata a procesului. Se recomanda de a fi folosita numai in cazul cind alte metode nu au efect. Toate threadurile din proces sint terminate, dar librariile DLL atasate la proces nu sint notificate de detasare. Terminarea presupune urmatoarele:

Toate handles deschise de proces sint inchise;

Toate threadurile din proces termina executia;

Starea obiectului proces si a obiectelor threads devine semnalata, ceea ce satisface toate threadurile ce asteptau inchiderea lor;

Statusul procesului se schimba de la STILL_ACTIVE la codul de iesire a procesului.

Terminarea unui proces nu cauzeaza terminarea child-proceselor. Terminarea unui proces nu neaparat elimina obiectul procesului din sistem. Un obiect proces este eliminat atunci cind ultimul handle ce indica la el a fost inchis.

Ascundere procese

Cel mai simplu de a exclude aparitia aplicatiei in lista dialogului "Close program" (aceasta nu include ascunderea procesului) este de a chema functia RegisterServiceProcess.

DWORD RegisterServiceProcess(

  DWORD dwProcessId,

  DWORD dwType

);

Daca dwType este 1 atunci ea va inregistra procesul indicat de dwProcessId (daca este NULL, se va subintelege procesul curent) ca un Service Process. Aceste procese nu sint inchise in faza de logoff.

BO2K

Doua moduri interesante sint implementate in BO2K pentru a ascunde procesele in Win9x/WinNT.

In cazul cind este rulat sub Win9x:

Se inregistreaza ca un Service Process;

Schimba protectia tabelului de export al kernel32.dll cu ajutorul functiei nedocumentate VxDCall si o face accesibila pentru modificare;

Aloca memorie shared cu permisiuni RWX (Read/Write/Execute) si copie acolo functiile sale analoage celor din Tool Help;

Memoreaza adresele functiilor reale;

Si in sfirsit, modifica adresele de intrare a functiilor Tool Help cu adresele functiilor sale.

  Deci, cind un program va incerca sa enumere procesele active, de fapt vor fi chemate functiile lui BO2K, care la rindul sau cheama functiile reale, si controleaza sa nu fie intoarsa informatie despre procesul BO2K. La iesire, BO2K nu uita sa restabileze adresele originale, ceea ce este un lucru important.

In cazul cind este rulat sub WinNT:

Gaseste un alt proces pentru "incubatie";

Primeste la el un handle cu PROCESS_ALL_ACCESS;

Aloca spatiu in procesul-victima pentru a injecta codul sau in el;

Creaza un thread in procesul-victima cu ajutorul la CreateRemoteThread ce va executa codul injectat.

Dupa cum va dati seama, nu va mai ramine nici o urma a procesului BO2K.

Daca va intereseaza sursa pentru o studiere mai detailata, o puteti gasi aici - process_hop.cpp. Sursa completa si executabilul le puteti obtine la http://www.bo2k.com/.

Links

Documentatia referitor la toate functiile WIN API specificate in acest eseu o puteti gasi la

msdn.microsoft.com/library - MSDN Online Library

tlist.rar - Sursa programului TList inclus in MSDN Library ce exemplifica enumararea si terminarea proceselor pe ambele platforme: 9x si NT (VC++, 10 KB).

processhandler.zip - Process Handler by Builtofire, include sursa (BCB, v. 0.99, 350KB)

The Anonymous, mailto:the_a@europe.com?subject=Procese in Windows

--------------------------------------------------------------------------------

COMPLETARE DE SFYNX (WINNT PROBLEM):

... la eseul tau am niste comentarii.

RegisterServiceProcess este foarte buna, insa kernel-ul WinNT-ul nu exporta aceasta functie si atunci cand vei incerca sa executi programul din Windows NT, vei primi eroarea: Application linked to missing export (sau asa ceva).

Pentru a ne asigura ca nu se intampla, uite cum am procedat (prezint codurile in Delphi, pentru ca sunt chiar paste-uite dintr-un program pe care-l scriu (care trebuie sa se ascunda :) :

(vezi explicatia mai jos)

Function WRegisterServiceProcess:Boolean;

type

Proc=procedure(PID,T:DWord); stdcall;

Var

RegProc:proc;

FhLib: hInst;

begin

FhLib:=GetModuleHandle(PChar('kernel32.dll')); ///obtinem handle-ul kernel-ului

If FhLib=0 then Exit;

@RegProc:=GetProcAddress(FhLib,PChar('RegisterServiceProcess')); ///gasim adresa functie noastre

if @RegProc<>nil then RegProc(GetCurrentProcessID, 1); ///daca functia nu este exportata, RegProc va fi null

end;

Iar functia de mai jos ascunde aplicatia si de pe TaskBar si din Alt-Tab

Procedure HideIT(AppHandle:HWnd);

Var

AppWnd:DWord;

begin

WRegisterServiceProcess;

AppWnd:=GetWindowLong(AppHandle,GWL_EXSTYLE);

AppWnd:=AppWnd or WS_EX_TOOLWINDOW;

SetWindowLong(AppHandle,GWL_EXSTYLE,AppWnd);

ShowWindow(AppHandle,SW_HIDE);

end;

WRegisterServiceProcess, dupa cate ati vazut procedeaza astfel:

Ia handle-ul bibliotecii Kernel32 si cauta in el offsetul la functia RegisterServiceProcess. Daca este gasita, atunci o executa.

Metoda este foarte frumoasa, pentru ca astfel putem evita si o alta chestie neplacuta - analiza programului prin disasamblare.

In primul rand la disasamblare programul nu mai are functia RegisterServiceProcess importata. In al doilea rand, daca in loc de PChar('RegisterServiceProcess') punem DecryptString(STRING_REGISTER_SERVICE_PROCESS) (care intoarce un string decriptat dintr-un array de string-uri encriptate, dupa indexul care i-l dam ca parametru), atunci "RegisterServiceProcess" nu va aparea nici in string-table-ul programului disasamblat (adica va aparea, dar encriptat).

Aceeasi metoda poate fi folosita si la chemarea altor functii (ca WNetEnumCachedPasswords, RegOpenKey, sau connect() sau send()) invizibil, astfel incat jertfa sa nu poate intelege ca noi actually chemam aceste functii.

Astfel, cine incearca sa-mi disasambleze programul, nu va vedea decat functii "prietenoase" in el ca gdi32.createbitmap() :), dar de fapt programul face cu totul altceva. Ideal in cazul scrierii Trojan-urilor.

De ce insist asupra ideii - cineva mi-a trimis odata un fisier .exe sustinand ca este fotografia ZIP-uita, dar dupa ce am disasamblat-o si am vazut functiile pe care le importa am hotarat ca este cam complicat ca un self extracting .exe sa aiba importuri din advapi si mpr.dll. De fapt era NetBUS.

Anyways.

cam asta era

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



×
×
  • Create New...