Ați simțit vreodată dorința de a demonta un mecanism pentru a afla cum funcționează? Ei bine, cine nu a simțit așa ceva. Această dorință este forța conducătoare în ingineria inversă. Această abilitate este utilă pentru a analiza securitatea unui produs, pentru a afla scopul unui fișier .exe suspect fără a-l rula, pentru a recupera documentația pierdută, pentru a dezvolta o nouă soluție bazată pe un software moștenit, etc.
În acest articol, discutăm despre baza de cunoștințe necesară pentru a efectua inginerie inversă, principiile de bază ale ingineriei inverse a unei bucăți de software Windows, dezasamblatoare și instrumente. De asemenea, oferim un exemplu pas cu pas de inginerie inversă a unei aplicații.
Scris de
Sergii Bratus,
Coordonator de dezvoltare,
Echipa de securitate a rețelei
și
Anton Kukoba,
Security Research Leader
Contenit
Ce este inversarea software-ului?
De ce avem nevoie pentru inginerie inversă?
Cunoștințe teoretice. Procesul de inginerie inversă a software-ului
Instrumente utile pentru ingineria inversă a software-ului Windows
Disasamblori
Windows Sysinternals
Instrumente de monitorizare a rețelei
Debugger
Real-…life software reverse engineering example
Cum se face reverse engineering unui driver
Concluzie
- Ce este reverse engineering-ul software?
- De ce avem nevoie pentru inginerie inversă?
- Cunoștințe teoretice. Procesul de inginerie inversă a software-ului
- Instrumente utile pentru inginerie inversă a software-ului Windows
- Dezasamblatoare
- Windows Sysinternals
- Instrumente de monitorizare a rețelei
- Depanatoare
- Exemplu real de inginerie inversă a software-ului
- Cum se realizează ingineria inversă a unui driver
- Concluzie
Ce este reverse engineering-ul software?
Ingineria inversă este procesul de descoperire a principiilor care stau la baza unei piese de hardware sau software, cum ar fi arhitectura și structura sa internă. Întrebarea care conduce ingineria inversă este Cum funcționează?
Evident, dacă aveți documentație, întregul proces devine mult mai simplu. Dar de multe ori se întâmplă să nu existe documentație și trebuie să găsiți o altă modalitate de a afla cum funcționează o bucată de software.
Când s-ar putea să aveți nevoie de inginerie inversă a unei bucăți de software și cum v-ar putea ajuta acest lucru?
Există multe utilizări ale ingineriei inverse în domeniul informaticii, inclusiv:
- Cercetarea protocoalelor de comunicare în rețea
- Căutarea algoritmilor utilizați în programele malware, cum ar fi virușii de calculator, troienii, ransomware etc.
- Cercetarea formatului de fișier utilizat pentru a stoca orice tip de informații, de exemplu, baze de date de e-mailuri și imagini de disc
- Verificarea capacității propriului software de a rezista ingineriei inverse
- Îmbunătățirea compatibilității software-ului cu platformele și software-ul terților
- Utilizarea unor caracteristici nedocumentate ale platformei
Legitimitatea ingineriei inverse depinde de scopul acesteia și de modul în care software-ul va fi utilizat. Toate scopurile menționate mai sus sunt complet legitime, presupunând că ați obținut o copie a software-ului în mod legal. Dar dacă intenționați, de exemplu, să faceți inginerie inversă pentru o anumită caracteristică a unei aplicații închise și apoi să o implementați într-o altă aplicație, probabil că veți avea probleme.
În ceea ce privește documentația legală, ingineria inversă este adesea interzisă prin acordurile de licență pentru utilizatorul final (EULA). Dar legea americană Digital Millennium Copyright Act specifică faptul că inversarea unei bucăți de software este legală dacă” se face pentru a îmbunătăți compatibilitatea cu alte produse.
Cerințele legale variază de la o țară la alta, așa că nu vă grăbiți să le cercetați înainte de a începe.
Acum să vedem cum să facem inginerie inversă de software.
De ce avem nevoie pentru inginerie inversă?
Pentru a începe ingineria inversă a software-ului, aveți nevoie de:
- cunoștințe în domeniul în care doriți să aplicați ingineria inversă
- instrumente care vă vor permite să vă aplicați cunoștințele în timp ce încercați să dezasamblați software-ul.
Să luăm în considerare un exemplu generic care nu este legat de software. Să spunem că aveți un ceas și vreți să aflați dacă este mecanic, cu cuarț sau automat.
Cunoașterea domeniului înseamnă că ar trebui să știți că există trei tipuri de ceasuri. În plus, ar trebui să știți că, dacă există o baterie, aceasta se află în interiorul ceasului și o puteți vedea dacă îl deschideți. De asemenea, ar trebui să aveți cunoștințe de bază despre structura internă a unui ceas, cum arată bateria și de ce unelte aveți nevoie pentru a deschide carcasa unui ceas. A avea instrumentele necesare pentru a vă aplica cunoștințele înseamnă că trebuie să aveți o șurubelniță sau o altă unealtă dedicată care să vă ofere șansa de a deschide ceasul.
La fel cum ingineria inversă a unui ceas necesită un set de abilități și instrumente specifice, software-ul de inginerie inversă necesită propriile cunoștințe și instrumente specifice domeniului.
Cunoștințe teoretice. Procesul de inginerie inversă a software-ului
Pentru diferite sarcini de inginerie inversă a software-ului, aveți nevoie de diferite tipuri de cunoștințe. Desigur, există cunoștințe comune care vă vor ajuta în majoritatea sarcinilor de inginerie inversă: cunoașterea structurilor comune ale aplicațiilor, a limbajelor de programare, a compilatoarelor și așa mai departe. Cu toate acestea, fără cunoștințe teoretice speciale, nu puteți rezolva sarcini specifice de inginerie inversă.
Dacă… |
Aveți nevoie de cunoștințe de… |
realizați ingineria inversă a oricăror aplicații de rețea |
principiile comunicațiilor între procese, structura rețelelor, conexiunile, pachetele de rețea, etc. |
întoarceți algoritmii criptografici |
criptografia și cei mai populari algoritmi utilizați în domeniu |
fișier de cercetare structuri de fișiere |
concepte de bază ale fișierelor și modul în care diferite sisteme sau componente lucrează cu fișiere |
Tehnici speciale pot economisi mult timp în timpul inversării unor tipuri speciale de software. În cazul interacțiunilor cu fișiere, realizarea unui test care scrie valori de tip unic într-un fișier, în timp ce se înregistrează decalajele și dimensiunea datelor în fișierul de stocare real, vă poate ajuta să găsiți modele comune în decalaje. Acest lucru vă va da un indiciu cu privire la structurile interne ale acestor fișiere.
Când încep un proces de inginerie inversă, dezvoltatorii de software folosesc în general un dezasamblorator pentru a găsi algoritmi și logica de program la fața locului. Există multe formate diferite de fișiere executabile, compilatoare (care dau ieșiri diferite) și sisteme de operare. Această diversitate de tehnologii exclude utilizarea unei singure tehnologii pentru inversarea tuturor tipurilor de software.
Pentru a înțelege codul descompilat, aveți nevoie de anumite cunoștințe despre limbajul de asamblare, convențiile de apelare a funcțiilor, structura stivei, conceptul de cadre de stivă etc.
Cunoașterea ieșirii asamblorului pentru diferite mostre de cod vă poate ajuta la descoperirea funcționalității originale. Să luăm în considerare câteva exemple pentru platforma Windows x86.
Să spunem că avem următorul cod:
Dacă compilăm acest cod într-un fișier executabil, vom vedea acest lucru în dezasamblator:
După cum putem vedea, ciclul obișnuit s-a transformat în cod de asamblare cu comparații și salturi. Observați că codul de asamblare nu folosește bucla obișnuită de asamblare cu contorul din registrul ecx. În plus, variabilele locale de aici sunt denumite și în mod corespunzător.
Să vedem ce se va întâmpla dacă vom compila acest cod folosind versiunea release build:
Acest fragment de cod nu seamănă deloc cu cel anterior. Acest lucru se datorează modului în care a fost optimizat codul. Tehnic, bucla a fost eliminată, deoarece nu face nimic valoros în afară de a incrementa variabila count la 10. Deci, optimizatorul a decis doar să păstreze valoarea finală a variabilei count și să plaseze valoarea direct ca argument pentru operatorul de ieșire count.
Compilatoarele pe care le folosim în zilele noastre sunt foarte bune la optimizarea codului. De aceea, atunci când se face inginerie inversă, este mai bine să înțelegem ideea din spatele codului (principiile codului) decât să încercăm să obținem codul original în sine. Dacă înțelegeți ideea din spatele codului, puteți pur și simplu să vă scrieți propriul prototip care să se potrivească sarcinii originale.
Vă va fi foarte util să știți ce cod de asamblare veți obține dacă veți compila diferiți operatori, structuri și alte construcții de limbaj. Înțelegerea codului de asamblare rezultat este o modalitate bună de a începe procesul de inginerie inversă C++, dar nu vom intra în detalii tehnice ale acestuia aici.
Instrumente utile pentru inginerie inversă a software-ului Windows
Am descris deja câteva instrumente de inginerie inversă, inclusiv ProcessMonitor și ProcessExplorer, în cercetarea noastră privind arhitectura aplicațiilor. Aceste instrumente sunt absolut indispensabile pentru inginerie inversă.
În această secțiune, vom trece în revistă cele mai populare dezasamblatoare și alte câteva instrumente pe care le folosim pentru proiectele noastre de inginerie inversă.
Puteți obține mai multe detalii și exemple de utilizare în articolul nostru despre cele mai bune instrumente de inginerie inversă software.
Dezasamblatoare
Un dezasamblator este un program care traduce un fișier executabil în limbaj de asamblare. Cel mai popular este IDA Pro
IDA Pro
IDA Pro
IDA Pro este un instrument convenabil și puternic pentru dezasamblare. Dispune de un număr foarte mare de instrumente care vă permit să dezasamblați rapid o bucată de software. Poate afișa arborele de apelare a funcțiilor, poate analiza importul și exportul executabilului și poate afișa informații despre acestea. Poate arăta chiar și codul în C. De asemenea, suportă mai multe arhitecturi de procesoare, astfel încât este posibil să folosiți IDA Pro pentru a face inginerie inversă pentru ARM, AVR, M68k și multe alte arhitecturi.
Radare
Radare
Desasamblatorul Radare este o alternativă la IDA. Practic, are toate caracteristicile IDA fără a fi la fel de robust și stabil. Dar este gratuit și open source. Radare în sine este un instrument de consolă, dar are un frontend Cutter, ceea ce îl face o adevărată alternativă la IDA.
Windows Sysinternals
Utilitățile Windows Sysinternals sunt în general folosite pentru gestionarea, diagnosticarea, depanarea și monitorizarea mediului Microsoft Windows. Dar ele sunt potrivite și pentru inginerie inversă a software-ului Windows.
TCPView este un sniffer de rețea care arată toate informațiile despre pachetele TCP/UDP de la toate procesele. Acest instrument este util pentru inversarea protocoalelor de rețea.
PortMon este un monitor al porturilor sistemului fizic. Acesta monitorizează porturile seriale și paralele și tot traficul care trece prin ele.
WinObj arată toate obiectele globale din sistem într-o structură ierarhică. Acest instrument poate fi util atunci când se inversează o aplicație care lucrează cu primitive de sincronizare, cum ar fi mutexurile și semafoarele și, de asemenea, atunci când se face inginerie inversă a driverelor în modul kernel.
Instrumente de monitorizare a rețelei
Wireshark
Wireshark
Wireshark este unul dintre cele mai puternice sniffer de rețea. Acesta nu numai că vă permite să capturați traficul de rețea, dar conține și analizatori pentru diverse protocoale de rețea, începând de la cele de nivel foarte scăzut, cum ar fi Ethernet, TCP și IP, până la protocoale specifice aplicațiilor, cum ar fi WebSockets și XMPP.
Fiddler
Fiddler
Fiddler este un proxy web care înregistrează traficul de la browsere și vă permite să analizați cererile HTTP/HTTPS. Spre deosebire de Wireshark, acesta arată sesiunile HTTP în loc de pachetele de rețea separate. Fiddler vă permite, de asemenea, să analizați datele comprimate trimise prin HTTP și să analizați datele JSON și XML atunci când monitorizați solicitările SOAP, REST și AJAX.
API Monitor
API Monitor
API Monitor este un instrument util pentru a descoperi ce API-uri sunt apelate de o aplicație și ce comportament așteaptă aplicația de la aceste API-uri. Acest instrument are o bază de date puternică și vă permite să vedeți apelurile la un număr foarte mare de funcții API nu numai ale kernel32 și ntdll, ci și ale COM, ale mediului gestionat și altele. De asemenea, API Monitor oferă mecanisme de filtrare convenabile.
Depanatoare
Un depanator este de neprețuit pentru orice dezvoltator pentru a vedea ce face un program în acest moment. Obțineți același beneficiu de la depanare atunci când inversați aplicații ca și de la depanarea aplicațiilor în direct.
Cele mai populare depanatoare sunt OllyDbg, WinDbg și Windbg Preview.
OllyDbg
OllyDBG
OllyDbg (și succesorul său x64dbg) este probabil cel mai bun depanator atunci când vine vorba de inginerie inversă de software. A fost dezvoltat în mod special pentru nevoile de inversare și dispune de toate instrumentele necesare în acest scop:
- un dezasamblorator încorporat cu capacitatea de a analiza și de a identifica structurile de date cheie
- o funcție de analiză a importurilor și exporturilor
- un motor de asamblare și reparare încorporat
Capacitatea de a analiza funcțiile API și parametrii acestora facilitează inversarea interacțiunilor cu un sistem. Vizualizarea stivei oferă o mulțime de informații despre stiva de apeluri. Un alt avantaj important este că puteți folosi OllyDbg cu aplicații protejate de depanare, atunci când depanatoarele obișnuite pur și simplu nu pot face nimic.
WinDbg
Windbg
În ciuda interfeței sale simple, WinDbg are instrumente puternice pentru depanare. Are un dezasamblorator încorporat, diverse comenzi care vă permit să știți aproape totul despre procesul/sistemul pe care îl depanați și posibilitatea de a face depanare în modul kernel, care este probabil cea mai valoroasă caracteristică. Este un mare avantaj pentru inversarea driverelor, în special a driverelor în modul kernel.
Windbg Preview
Windbg Preview
Windbg Preview este o nouă versiune de Windbg dezvoltată de Microsoft. Este distribuită doar prin intermediul Windows Store. Are toate caracteristicile clasicului Windbg, cuplate cu o nouă interfață de utilizare și câteva caracteristici noi. Una dintre aceste noi caracteristici este Time Travel Debugging, care vă permite să înregistrați o anumită perioadă de execuție a programului și apoi să o redați de câte ori aveți nevoie. În acest fel, puteți executa pas cu pas părțile interesante ale codului, fără să vă fie teamă să executați accidental un anumit cod și să pierdeți contextul sau toate datele.
Citește și: „Cunoașteți și: „Cunoașteți și voi:
9 cele mai bune instrumente de inginerie inversă pentru 2018
Exemplu real de inginerie inversă a software-ului
Acum vom vedea un exemplu de inginerie inversă a unui software. Să ne imaginăm că aveți un fișier executabil suspect. Trebuie să aflați ce face acest program și dacă este sigur pentru utilizatori.
Considerând scenariul, este o idee bună să nu rulați acest executabil pe calculatorul de lucru, ci să folosiți în schimb o mașină virtuală. Să pornim aplicația în mașina noastră virtuală.
Procesul creează un serviciu
După cum putem vedea, acest fișier creează un serviciu Windows numit TestDriver. Acesta are tipul kernel, deci știm că este un driver. Dar de unde ia fișierul driver pentru a putea rula? Putem folosi ProcessMonitor din Sysinternals Suite pentru a afla. Când deschidem ProcessMonitor, putem configura filtre pentru a ne arăta doar activitatea fișierelor din procesul care ne interesează. Jurnalul său de activitate arată astfel:
Informații FileMon
Filierul driver este creat de procesul pe care îl inversăm, iar acest proces pune acest fișier în directorul temporar al utilizatorului. Nu este nevoie să căutăm fișierul în directorul temporar, deoarece vedem că procesul îl șterge imediat după utilizare. Deci, ce face procesul cu acest fișier? Dacă despachetează fișierul, putem încerca să îl găsim în secțiunea de resurse a procesului, deoarece acesta este un loc obișnuit pentru a stoca astfel de date. Să ne uităm acolo. Vom folosi un alt instrument – Resource Hacker – pentru a examina resursele. Să-l rulăm:
Examinați resursele cu Resource Hacker
Bingo! După cum putem vedea din conținutul resurselor găsite, acesta este probabil fișierul executabil Windows, deoarece începe cu o semnătură MZ și are șirul „Acest program nu poate fi rulat în modul DOS”. Să verificăm dacă este fișierul driverului nostru. În acest scop, extragem resursa folosind Resource Hacker și o deschidem în dezasamblorator.
Ecranul dezasamblatorului
După cum știm, DriverEntry este punctul de intrare pentru driverele în modul kernel în sistemele Windows. Putem să ne continuăm cercetările, deoarece se pare că am găsit driverul potrivit.
Cum se realizează ingineria inversă a unui driver
Pentru a începe ingineria inversă a driverului, examinăm funcțiile care sunt apelate din DriverEntry, una câte una. Dacă mergem la sub_14005, nu găsim nimic interesant, așa că continuăm cu sub_110F0 și găsim acest cod:
Piesa de cod 1
Piesa de cod 2
Piesa de cod 3
Piesa de cod 4
Câteva linii sunt omise aici de dragul simplității.
În prima enumerare, este creat un șir unicode, iar acest șir indică calea C:\hello.txt. După aceea, structura OBJECT_ATTRIBUTES este umplută cu valori obișnuite; știm că această structură este adesea necesară atunci când se apelează funcții precum ZwCreateFile.
În a doua listă, vedem că ZwCreateFile este într-adevăr apelat, ceea ce ne face să fim destul de siguri că driverul creează fișierul – și știm unde se află acest fișier după ce a fost creat.
Din a treia și a patra enumerare, putem vedea că driverul ia șirul unicode și îl scrie în buffer (acest lucru se întâmplă în funcția sub_11150), iar bufferul va fi scris în fișier cu ajutorul funcției ZwWriteFile. La sfârșit, driverul închide fișierul folosind API-ul ZwClose.
Să rezumăm. Am aflat că programul original extrage fișierul driverului din resursele sale, îl plasează în folderul temp al utilizatorului curent, creează serviciul Windows pentru acest driver și îl rulează. După aceea, programul se oprește și șterge serviciul și fișierul driver original din directorul temporar. Din acest comportament și din analiza dezasamblării, reiese că driverul nu face nimic altceva decât să creeze un fișier pe unitatea C numit hello.txt și să scrie șirul de caractere „Hello from driver”.
Acum trebuie să verificăm dacă avem dreptate. Să rulăm programul și să verificăm unitatea C:
Ecranul aplicației
Încântător! Am realizat ingineria inversă a acestui program simplu și acum știm că este sigur de utilizat.
Am fi putut obține acest rezultat în multe moduri diferite – folosind depanarea sau API Mon, scriind teste, etc. Puteți găsi propriile modalități de inginerie inversă a software-ului care să funcționeze pentru dumneavoastră.
Concluzie
Inginerie inversă a software-ului Windows necesită o pregătire educațională solidă și experiență în programare. Pentru a efectua inginerie inversă, trebuie să combinați abilități de dezasamblare, monitorizare a rețelei, depanare, integrare API, mai multe limbaje de program, compilatoare etc. De asemenea, trebuie să fiți foarte atent atunci când faceți reversing de software pentru a nu încălca legile privind drepturile de autor sau pentru a nu vă afecta sistemul.
La Apriorit, avem o echipă experimentată de ingineri reversibili. Dacă doriți să aplicați abilitățile de inginerie inversă la proiectul dvs., nu ezitați să ne contactați!
.