Heb je ooit de behoefte gehad om een mechanisme uit elkaar te halen om uit te vinden hoe het werkt? Nou, wie niet. Dat verlangen is de drijvende kracht achter reverse engineering. Deze vaardigheid is nuttig voor het analyseren van productbeveiliging, het achterhalen van het doel van een verdacht .exe bestand zonder het uit te voeren, het terugvinden van verloren documentatie, het ontwikkelen van een nieuwe oplossing op basis van verouderde software, enz.

In dit artikel bespreken we de kennisbasis die nodig is om reverse engineering uit te voeren, de basisprincipes van reverse engineering van een stuk Windows software, disassemblers, en gereedschappen. We geven ook een stap-voor-stap voorbeeld van reverse engineering van een applicatie.

Geschreven door

Sergii Bratus,

Ontwikkelings Coördinator,

Netwerk Beveiligingsteam

en

Anton Kukoba,

Security Research Leader

Contents

Wat is software reversing?

Wat hebben we nodig voor reverse engineering?

Theoretische kennis. Software Reverse Engineering Proces

Gebruiksvolle hulpmiddelen voor Reverse Engineering Windows Software

Disassemblers

Windows Sysinternals

Network Monitoring Tools

Debuggers

Real-life software reverse engineering voorbeeld

Hoe een driver reverse engineeren

Conclusie

Wat is software omkeren?

Reverse engineering is het proces van het blootleggen van principes achter een stuk hardware of software, zoals de architectuur en de interne structuur. De vraag bij reverse engineering is: hoe werkt het?

Het spreekt voor zich dat als je documentatie hebt, het hele proces veel eenvoudiger wordt. Maar het komt vaak voor dat er geen documentatie is en dat je een andere manier moet vinden om te leren hoe een stuk software werkt.

Wanneer zou je een stuk software moeten reverse-engineeren en hoe zou dat je kunnen helpen?

Er zijn veel toepassingen van reverse engineering op het gebied van computerwetenschap, waaronder:

  • Onderzoek naar netwerkcommunicatieprotocollen
  • Het vinden van algoritmen die worden gebruikt in malware, zoals computervirussen, trojans, ransomware, enz.
  • Opsporen van het bestandsformaat dat wordt gebruikt om informatie op te slaan, bijvoorbeeld e-mails, databases en disk images
  • Controleren of uw eigen software bestand is tegen reverse engineering
  • Verbeteren van de compatibiliteit van software met platforms en software van derden
  • Gebruik maken van niet-gedocumenteerde platformeigenschappen

De legaliteit van reverse engineering hangt af van het doel en de manier waarop de software zal worden gebruikt. Alle hierboven genoemde doeleinden zijn volkomen legitiem, ervan uitgaande dat u op legale wijze een kopie van de software hebt verkregen. Maar als u bijvoorbeeld van plan bent om een bepaalde functie van een gesloten toepassing te reverse engineeren en deze vervolgens in een andere toepassing te implementeren, komt u waarschijnlijk in de problemen.

Wat betreft de juridische documentatie: reverse engineering wordt vaak verboden door licentieovereenkomsten voor eindgebruikers (EULA’s). Maar de Amerikaanse Digital Millennium Copyright Act specificeert dat het omkeren van een stuk software legaal is als het” wordt gedaan om de compatibiliteit met andere producten te verbeteren.

Wettelijke eisen verschillen van land tot land, dus neem de tijd om ze te onderzoeken voordat je begint.

Nu laten we eens kijken hoe je software kunt reverse engineeren.

Wat hebben we nodig voor reverse engineering?

Om te beginnen met reverse engineering van software, heb je nodig:

  1. kennis op het gebied waar je reverse engineering wilt toepassen
  2. gereedschap waarmee je je kennis kunt toepassen terwijl je probeert software te demonteren.

Laten we eens kijken naar een algemeen voorbeeld dat niet aan software is gekoppeld. Laten we zeggen dat je een horloge hebt en dat je wilt weten of het mechanisch, quartz of automatisch is.

Met kennis van zaken zou je moeten weten dat er drie soorten horloges zijn. Bovendien moet u weten dat als er een batterij, het is gelegen in het horloge, en je kunt het zien als je het open. Je moet ook basiskennis hebben van de interne structuur van een horloge, hoe de batterij eruit ziet, en welk gereedschap je nodig hebt om een horlogekast te openen. Het gereedschap hebben om je kennis toe te passen betekent dat je een schroevendraaier of ander speciaal gereedschap moet hebben waarmee je het horloge kunt openen.

Net zoals reverse engineering van een horloge een specifieke vaardigheden en gereedschappen vereist, vereist reverse engineering van software zijn eigen vakspecifieke kennis en gereedschappen.

Theoretische kennis. Software Reverse Engineering Proces

Voor verschillende software reverse engineering taken, heb je verschillende soorten kennis nodig. Natuurlijk is er gemeenschappelijke kennis die je zal helpen bij de meeste reverse engineering taken: kennis van gemeenschappelijke toepassingsstructuren, programmeertalen, compilers, enzovoort. Zonder speciale theoretische kennis kun je echter geen specifieke reverse engineering taken oplossen.

Als je…

Je hebt kennis nodig van…

kennis van netwerktoepassingen

beginselen van inter-procescommunicatie, de structuur van netwerken, verbindingen, netwerkpakketten, enz.

omgekeerde cryptografische algoritmen

cryptografie en de populairste algoritmen die in het veld worden gebruikt

onderzoek naar bestands structuren

basisconcepten van bestanden en hoe verschillende systemen of componenten met bestanden werken

Speciale technieken kunnen veel tijd besparen bij het omkeren van speciale soorten software. In het geval van bestandsinteracties kan het maken van een test die unieke typewaarden naar een bestand schrijft, terwijl de offsets en gegevensgrootte naar het eigenlijke opslagbestand worden gelogd, u helpen gemeenschappelijke patronen in offsets te vinden. Dit zal u een hint geven over de interne structuren van deze bestanden.

Bij het starten van een reverse engineering proces, gebruiken software ontwikkelaars over het algemeen een disassembler om algoritmen en programmalogica op hun plaats te vinden. Er zijn veel verschillende uitvoerbare bestandsformaten, compilers (die verschillende outputs geven), en besturingssystemen. Deze verscheidenheid aan technologieën maakt het gebruik van één enkele technologie voor het omkeren van alle soorten software onmogelijk.

Om de gedecompileerde code te begrijpen, is enige kennis nodig van de assembler taal, functie aanroep conventies, stack structuur, stack frames concept, enz.

Kennis van de assembler output voor verschillende code voorbeelden kan u helpen bij het blootleggen van de oorspronkelijke functionaliteit. Laten we eens kijken naar enkele voorbeelden voor het Windows x86-platform.

Laten we zeggen dat we de volgende code hebben:

int count = 0;for (int i = 0; i < 10; ++i){count++;}std::cout << count;

Als we deze code compileren naar een uitvoerbaar bestand, zien we dit in de disassembler:

004113DE loc_4113DE:004113DE mov eax, 004113E1 add eax, 1004113E4 mov , eax004113E7 loc_4113E7:004113E7 cmp , 0Ah004113EB jge short loc_4113F8004113ED mov eax, 004113F0 add eax, 1004113F3 mov , eax004113F6 jmp short loc_4113DE004113F8 loc_4113F8:004113F8 mov ecx, ds:004113FE push eax00411400 call ds:<<(int)00411404 xor eax, eax00411406 retn 

Zoals we kunnen zien, is de gewone cyclus veranderd in assemblercode met vergelijkingen en sprongen. Merk op dat de assemblagecode niet de reguliere assemblagelus gebruikt met de teller in het ecx-register. Bovendien worden lokale variabelen hier aangeduid als en dienovereenkomstig.

Laten we eens kijken wat er gebeurt als we deze code compileren met behulp van de release build:

00401000 main proc near00401000 mov ecx, ds:00401006 push 0Ah00401008 call ds:<<(int)0040100E xor eax, eax00401010 retn00401010 main endp

Dit stukje code lijkt in niets op het vorige. Dit komt door de manier waarop de code is geoptimaliseerd. Technisch gezien is de lus verwijderd, omdat deze niets anders doet dan de variabele count verhogen tot 10. Dus besloot de optimizer om gewoon de uiteindelijke waarde van de count variabele te behouden en de waarde direct als argument te plaatsen voor de count output operator.

De compilers die we tegenwoordig gebruiken zijn erg goed in het optimaliseren van code. Daarom is het bij reverse engineering beter om het idee achter de code te begrijpen (de principes van de code) dan te proberen de originele code zelf te krijgen. Als je het idee achter de code begrijpt, kun je gewoon je eigen prototype schrijven dat past bij de oorspronkelijke taak.

Het is erg nuttig om te weten welke assemblagecode je krijgt als je verschillende operatoren, structuren, en andere taalconstructies compileert. Het begrijpen van de resulterende assemblagecode is een goede manier om het C++ reverse engineering proces te beginnen, maar we zullen hier niet in technische details treden.

Bruikbare gereedschappen voor reverse engineering van Windows software

We hebben al verschillende reverse engineering gereedschappen beschreven, waaronder ProcessMonitor en ProcessExplorer, in ons applicatie-architectuur onderzoek. Deze tools zijn absoluut onmisbaar voor reverse engineering.

In deze sectie bespreken we de meest populaire disassemblers en nog enkele andere tools die we gebruiken voor onze reverse engineering projecten.

Je kan meer details en gebruiksvoorbeelden krijgen in ons artikel over de beste software reverse engineering tools.

Disassemblers

Een disassembler is een programma dat een uitvoerbaar bestand vertaalt naar assembleertaal. De meest populaire is IDA Pro

IDA Pro

IDA Pro

IDA Pro is een handig en krachtig gereedschap voor disassemblage. Het heeft een groot aantal instrumenten die u in staat stellen om snel een stuk software te disassembleren. Het kan de functie-aanroep boom tonen, import en export van het uitvoerbare bestand parseren, en informatie over hen tonen. Het kan zelfs de code in C laten zien. Ook ondersteunt het meerdere CPU architecturen, dus het is mogelijk om IDA Pro te gebruiken voor reverse-engineering van code voor ARM, AVR, M68k, en vele andere architecturen.

Radare

Radare

De Radare disassembler is een alternatief voor IDA. Het heeft in principe alle mogelijkheden van IDA, maar is niet zo robuust en stabiel. Maar het is gratis en open source. Radare zelf is een console tool, maar het heeft een Cutter frontend, wat het een echt alternatief voor IDA maakt.

Windows Sysinternals

Windows Sysinternals utilities worden over het algemeen gebruikt voor beheer, diagnostiek, troubleshooting, en monitoring van de Microsoft Windows omgeving. Maar ze zijn ook geschikt voor reverse engineering van Windows software.

TCPView is een netwerk sniffer die alle informatie toont over TCP/UDP pakketten van alle processen. Deze tool is nuttig voor het omkeren van netwerk protocollen.

PortMon is een fysieke systeem poort monitor. Het controleert seriële en parallelle poorten en al het verkeer dat er doorheen gaat.

WinObj toont alle globale objecten in het systeem in een hiërarchische structuur. Dit gereedschap kan nuttig zijn bij het omkeren van een applicatie die werkt met synchronisatie-primitieven zoals mutexen en semaforen en ook bij reverse engineering van kernel mode drivers.

Network monitoring tools

Wireshark

Wireshark

Wireshark is een van de krachtigste netwerk sniffers. U kunt er niet alleen netwerkverkeer mee vastleggen, maar het bevat ook parsers voor verschillende netwerkprotocollen, van heel low-level zoals Ethernet, TCP en IP tot applicatiespecifieke protocollen zoals WebSockets en XMPP.

Fiddler

Fiddler

Fiddler is een web proxy die verkeer van browsers registreert en u in staat stelt HTTP/HTTPS-verzoeken te analyseren. In tegenstelling tot Wireshark, toont het HTTP sessies in plaats van afzonderlijke netwerk pakketten. Met Fiddler kunt u ook gecomprimeerde gegevens analyseren die via HTTP worden verzonden en JSON- en XML-gegevens analyseren bij het monitoren van SOAP-, REST- en AJAX-verzoeken.

API Monitor

API Monitor

API Monitor is een handig hulpmiddel om te ontdekken welke API’s door een toepassing worden aangeroepen en welk gedrag de toepassing van die API’s verwacht. Dit gereedschap heeft een krachtige database en laat je aanroepen zien van een enorm aantal API functies van niet alleen kernel32 en ntdll, maar ook COM, beheerde omgeving, en anderen. API Monitor biedt ook handige filter mechanismen.

Debuggers

Een debugger is van onschatbare waarde voor iedere ontwikkelaar om te zien wat een programma op dit moment aan het doen is. Je krijgt hetzelfde voordeel van debuggen bij het omkeren van applicaties als je krijgt van het debuggen van live applicaties.

De meest populaire debuggers zijn OllyDbg, WinDbg, en Windbg Preview.

OllyDbg

OllyDBG

OllyDbg (en zijn opvolger x64dbg) is waarschijnlijk de beste debugger als het aankomt op software reverse engineering. Het is speciaal ontwikkeld voor de behoeften van reverse engineering, en heeft alle gereedschappen die daarvoor nodig zijn:

  • een ingebouwde disassembler met de mogelijkheid om belangrijke datastructuren te analyseren en te identificeren
  • een import en export analyse functie
  • een ingebouwde assemblage en patching engine

De mogelijkheid om API functies en hun parameters te parseren maakt het gemakkelijk om interacties met een systeem te reverse-engineeren. De stackweergave geeft veel informatie over de aanroepstack. Een ander belangrijk voordeel is dat u OllyDbg kunt gebruiken met debug-beveiligde toepassingen, wanneer gebruikelijke debuggers gewoon niets kunnen doen.

WinDbg

Windbg

Ondanks de eenvoudige interface, heeft WinDbg krachtige gereedschappen voor debugging. Het heeft een ingebouwde disassembler, verschillende commando’s die je toestaan om bijna alles te weten te komen over het proces/systeem dat je aan het debuggen bent, en de mogelijkheid om kernel-mode debugging te doen, wat waarschijnlijk de meest waardevolle eigenschap is. Het is een groot voordeel voor het omkeren van drivers, kernel-mode drivers in het bijzonder.

Windbg Preview

Windbg Preview

Windbg Preview is een nieuwe versie van Windbg ontwikkeld door Microsoft. Het wordt alleen gedistribueerd via de Windows Store. Het heeft alle mogelijkheden van het klassieke Windbg gekoppeld aan een nieuwe UI en verschillende nieuwe features. Een van deze nieuwe functies is Time Travel Debugging, waarmee je een bepaalde periode van programma-uitvoering kunt opnemen en vervolgens zo vaak als je wilt opnieuw kunt afspelen. Op deze manier kunt u de interessante delen van de code stapsgewijs uitvoeren, zonder bang te zijn dat u per ongeluk wat code uitvoert en de context of alle gegevens kwijtraakt.

Lees ook:
9 Beste Reverse Engineering Tools voor 2018

Real-life software reverse engineering voorbeeld

Nu zullen we een voorbeeld zien van hoe je een stuk software kunt reverse engineeren. Laten we ons voorstellen dat je een verdacht uitvoerbaar bestand hebt. U moet uitzoeken wat dit programma doet en of het veilig is voor gebruikers.

Gezien het scenario, is het een goed idee om dit uitvoerbare bestand niet op uw werkcomputer te draaien, maar in plaats daarvan een virtuele machine te gebruiken. Laten we de applicatie starten in onze virtuele machine.

Proces maakt een service

Zoals we kunnen zien, maakt dit bestand een Windows service aan met de naam TestDriver. Het heeft het type kernel, dus we weten dat het een driver is. Maar waar haalt het het driver bestand vandaan om te draaien? We kunnen ProcessMonitor van Sysinternals Suite gebruiken om dit uit te zoeken. Wanneer we ProcessMonitor openen, kunnen we filters instellen om ons alleen de bestandsactiviteit te laten zien van het proces waarin we geïnteresseerd zijn. Het activiteiten log ziet er als volgt uit:

FileMon information

Het driver bestand is gemaakt door het proces dat we omkeren, en dit proces zet dit bestand in de temp directory van de gebruiker. Het is niet nodig om naar het bestand in de temp folder te zoeken, omdat we zien dat het proces het verwijdert direct na gebruik. Dus wat doet het proces met dit bestand? Als het het bestand uitpakt, kunnen we proberen het te vinden in de resource sectie van het proces, omdat dit een gebruikelijke plaats is om zulke gegevens op te slaan. Laten we daar eens kijken. We zullen een ander gereedschap gebruiken – Resource Hacker – om de bronnen te onderzoeken. Laten we het uitvoeren:

Onderzoek bronnen met Resource Hacker

Bingo! Zoals we kunnen zien aan de gevonden broninhoud, is dit waarschijnlijk het Windows uitvoerbare bestand, aangezien het begint met een MZ handtekening en de string heeft “Dit programma kan niet worden uitgevoerd in DOS modus.” Laten we eens kijken of het ons stuurprogramma bestand is. Daarvoor halen we de bron tevoorschijn met Resource Hacker en openen het in de disassembler.

Disassembler scherm

Zoals we weten, is DriverEntry het ingangspunt voor kernel-mode drivers in Windows systemen. We kunnen verder gaan met ons onderzoek, want het ziet er naar uit dat we de juiste driver gevonden hebben.

Hoe een driver reverse engineeren

Om te beginnen met het reverse engineeren van de driver, onderzoeken we één voor één de functies die aangeroepen worden vanuit DriverEntry. Als we naar sub_14005 gaan, vinden we niets interessants, dus gaan we verder met sub_110F0 en vinden deze code:

Code stuk 1

Code stuk 2

Code stuk 3

Code stuk 4

Enkele regels zijn hier omwille van de eenvoud weggelaten.

In de eerste listing wordt een unicode string aangemaakt, en deze string wijst naar het pad C:\hello.txt. Daarna wordt de structuur OBJECT_ATTRIBUTES gevuld met reguliere waarden; we weten dat deze structuur vaak nodig is bij het aanroepen van functies als ZwCreateFile.

In de tweede listing zien we dat ZwCreateFile inderdaad wordt aangeroepen, wat ons vrij zeker maakt dat de driver het bestand aanmaakt – en we weten waar dit bestand zich bevindt nadat het is aangemaakt.

Uit de derde en vierde listing kunnen we zien dat de driver de unicode string neemt en deze naar de buffer schrijft (dit gebeurt in de sub_11150 functie), en de buffer wordt naar het bestand geschreven met behulp van de ZwWriteFile functie. Aan het eind sluit de driver het bestand met de ZwClose API.

Laten we even samenvatten. We hebben ontdekt dat het originele programma het stuurprogrammabestand uit zijn bronnen haalt, het in de temp folder van de huidige gebruiker zet, de Windows service voor dit stuurprogramma aanmaakt, en het uitvoert. Daarna stopt het programma en verwijdert de service en het originele stuurprogrammabestand uit de temp directory. Uit dit gedrag en uit het analyseren van de demontage, blijkt dat het stuurprogramma niets anders doet dan een bestand maken op de C schijf met de naam hello.txt en de string “Hello from driver” schrijven.

Nu moeten we controleren of we correct zijn. Laten we het programma uitvoeren en de C-schijf controleren:

Toepassingsscherm

Wonderlijk! We hebben dit eenvoudige programma omgekeerd en nu weten we dat het veilig is om te gebruiken.

We hadden dit resultaat op veel verschillende manieren kunnen bereiken – met behulp van debugging of API Mon, het schrijven van tests, enz. U kunt uw eigen manieren vinden om software te reverse engineeren die voor u werken.

Conclusie

Windows software reverse engineering vereist een solide educatieve achtergrond en programmeerervaring. Om reverse engineering uit te voeren, moet je vaardigheden combineren in disassembleren, netwerkmonitoring, debuggen, API-integratie, verschillende programmeertalen, compilers, enz. Je moet ook heel voorzichtig zijn bij het omkeren van software om geen copyright wetten te overtreden of schade aan uw systeem toe te brengen.

Bij Apriorit, hebben we een ervaren team van reverse engineers. Als u wilt reverse engineering vaardigheden toe te passen op uw project, voel je vrij om contact met ons op!

Geef een antwoord

Het e-mailadres wordt niet gepubliceerd.