Har du nogensinde haft lyst til at skille en eller anden mekanisme ad for at finde ud af, hvordan den fungerer? Tja, hvem har ikke det? Dette ønske er den ledende kraft i reverse engineering. Denne færdighed er nyttig til at analysere produktsikkerhed, finde ud af formålet med en mistænkelig .exe-fil uden at køre den, genfinde tabt dokumentation, udvikle en ny løsning baseret på ældre software osv.

I denne artikel diskuterer vi det vidensgrundlag, der er nødvendigt for at udføre reverse engineering, grundlæggende principper for reverse engineering af et stykke Windows-software, disassemblere og værktøjer. Vi giver også et trin-for-trin eksempel på reverse engineering af et program.

Skrevet af

Sergii Bratus,

Udviklingskoordinator,

Network Security Team

og

Anton Kukoba,

Security Research Leader

Indhold

Hvad er software reversing?

Hvad har vi brug for til reverse engineering?

Theoretisk viden. Software Reverse Engineering-processen

Nyttige værktøjer til Reverse Engineering af Windows-software

Disassemblers

Windows Sysinternals

Netværksovervågningsværktøjer

Debuggers

Real-life software reverse engineering eksempel

Hvordan man reverse engineer en driver

Slutning

Hvad er software reverse engineering?

Reverse engineering er processen med at afdække principperne bag et stykke hardware eller software, f.eks. dets arkitektur og interne struktur. Det spørgsmål, der driver reverse engineering, er: Hvordan virker det?

Det er indlysende, at hvis du har dokumentation, bliver hele processen meget enklere. Men det sker ofte, at der ikke er nogen dokumentation, og at man er nødt til at finde en anden måde at lære, hvordan et stykke software fungerer.

Hvornår kan det være nødvendigt at reverse engineer et stykke software, og hvordan kan det hjælpe dig?

Der er mange anvendelsesmuligheder for reverse engineering inden for datalogi, herunder:

  • Forskning af netværkskommunikationsprotokoller
  • Findelse af algoritmer, der anvendes i malware som f.eks. computervirus, trojanere, ransomware osv.
  • Undersøgelse af det filformat, der anvendes til lagring af enhver form for information, f.eks. e-mail-databaser og diskbilleder
  • Kontrol af din egen softwares evne til at modstå reverse engineering
  • Forbedring af softwares kompatibilitet med platforme og tredjepartssoftware
  • Anvendelse af udokumenterede platformsfunktioner

Legaliteten af reverse engineering afhænger af formålet, og hvordan softwaren vil blive anvendt. Alle de formål, der er nævnt ovenfor, er helt legitime, forudsat at du har fået en kopi af softwaren på lovlig vis. Men hvis du f.eks. har til hensigt at reverse engineere en bestemt funktion i et lukket program og derefter implementere den i et andet program, vil du sandsynligvis komme i problemer.

Med hensyn til juridisk dokumentation er reverse engineering ofte forbudt i slutbrugerlicensaftaler (EULA’er). Men den amerikanske Digital Millennium Copyright Act angiver, at reverse engineering af et stykke software er lovligt, hvis det”’ sker for at forbedre kompatibiliteten med andre produkter.

De juridiske krav varierer fra land til land, så tag dig tid til at undersøge dem, før du går i gang.

Nu skal vi se, hvordan man reverse engineer software.

Hvad har vi brug for til reverse engineering?

For at begynde at reverse engineering software har du brug for:

  1. viden inden for det område, hvor du ønsker at anvende reverse engineering
  2. værktøjer, der gør det muligt for dig at anvende din viden, mens du forsøger at demontere software.

Lad os se på et generisk eksempel, der ikke er forbundet med software. Lad os sige, at du har et ur, og at du vil finde ud af, om det er mekanisk, kvarts eller automatisk.

Hvis du har viden om området, bør du vide, at der findes tre typer ure. Derudover bør du vide, at hvis der er et batteri, er det placeret inde i uret, og du kan se det, hvis du åbner det. Du bør også have grundlæggende viden om et urets indre opbygning, hvordan batteriet ser ud, og hvilket værktøj du skal bruge for at åbne en urkasse. At have værktøjet til at anvende din viden betyder, at du skal have en skruetrækker eller et andet dedikeret værktøj, der giver dig mulighed for at åbne uret.

Sådan som reverse engineering af et ur kræver et specifikt sæt færdigheder og værktøjer, kræver reverse engineering af software sin egen feltspecifikke viden og værktøjer.

Teoretisk viden. Software Reverse Engineering-processen

For forskellige software reverse engineering-opgaver har du brug for forskellige typer viden. Selvfølgelig er der fælles viden, som vil hjælpe dig med de fleste reverse engineering-opgaver: viden om almindelige applikationsstrukturer, programmeringssprog, compilere osv. Men uden særlig teoretisk viden kan du ikke løse specifikke reverse engineering-opgaver.

Hvis du…

Du har brug for viden om…

reverse engineer alle netværksapplikationer

principper for kommunikation mellem processer, strukturen af netværk, forbindelser, netværkspakker osv.

omvendte kryptografiske algoritmer

kryptografi og de mest populære algoritmer, der anvendes på området

efterforskningsfil strukturer

grundlæggende filkoncepter og hvordan forskellige systemer eller komponenter arbejder med filer

Specielle teknikker kan spare meget tid, når man vender særlige typer af software. I tilfælde af filinteraktioner kan det at lave en test, der skriver unikke typeværdier til en fil, mens du logger forskydningerne og datastørrelsen til den faktiske lagringsfil, hjælpe dig med at finde fælles mønstre i forskydningerne. Dette vil give dig et hint om de interne strukturer i disse filer.

Når man starter en reverse engineering-proces, bruger softwareudviklere generelt en disassembler for at finde algoritmer og programlogik på plads. Der findes mange forskellige eksekverbare filformater, kompilatorer (som giver forskellige output) og styresystemer. Denne mangfoldighed af teknologier udelukker brugen af én enkelt teknologi til reverseing af alle typer software.

For at forstå den dekompilerede kode skal man have et vist kendskab til assembler-sproget, konventioner for funktionskald, stack-struktur, stack frames-begrebet osv.

Kendskab til assembler-output for forskellige kodeeksempler kan hjælpe dig med at afdække den oprindelige funktionalitet. Lad os overveje nogle eksempler for Windows x86-platformen.

Lad os sige, at vi har følgende kode:

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

Hvis vi kompilerer denne kode til en eksekverbar fil, vil vi se dette i disassembleren:

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 

Som vi kan se, er den almindelige cyklus blevet til assemblerkode med sammenligninger og hop. Bemærk, at assemblerkoden ikke bruger den almindelige assemblerloop med tælleren i ecx-registeret. Desuden omtales lokale variabler her som og tilsvarende.

Lad os se, hvad der sker, hvis vi kompilerer denne kode med release-build’et:

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

Dette stykke kode ligner ikke noget som det foregående. Det skyldes den måde, som koden blev optimeret på. Teknisk set blev løkken fjernet, da den ikke gør noget værdifuldt andet end at øge tællevariablen til 10. Så optimeringen besluttede bare at beholde den endelige værdi af count-variablen og placere værdien direkte som et argument for count-udgangsoperatoren.

De compilere, vi bruger i dag, er meget gode til at optimere kode. Derfor er det ved reverse engineering bedre at forstå ideen bag koden (principperne for koden) end at forsøge at få fat i selve den originale kode. Hvis du forstår ideen bag koden, kan du bare skrive din egen prototype, der passer til den oprindelige opgave.

Det vil være meget nyttigt at vide, hvilken assemblerkode du får, hvis du kompilerer forskellige operatorer, strukturer og andre sprogkonstruktioner. Forståelse af den resulterende assemblerkode er en god måde at starte C++ reverse engineering-processen på, men vi vil ikke komme ind på de tekniske detaljer om det her.

Nyttige værktøjer til reverse engineering af Windows-software

Vi har allerede beskrevet flere reverse engineering-værktøjer, herunder ProcessMonitor og ProcessExplorer, i vores undersøgelse af applikationsarkitektur. Disse værktøjer er absolut uundværlige til reverse engineering.

I dette afsnit vil vi gennemgå de mest populære disassemblere og nogle få andre værktøjer, som vi bruger til vores reverse engineering-projekter.

Du kan få flere detaljer og eksempler på brug i vores artikel om de bedste værktøjer til reverse engineering af software.

Disassemblere

En disassembler er et program, der oversætter en eksekverbar fil til assemblagesprog. Den mest populære er IDA Pro

IDA Pro

IDA Pro

IDA Pro er et praktisk og kraftfuldt værktøj til disassemblering. Det har et stort antal instrumenter, der giver dig mulighed for hurtigt at adskille et stykke software. Det kan vise funktionskaldstræet, parse import og eksport af den eksekverbare fil og vise oplysninger om dem. Den kan endda vise koden i C. Desuden understøtter den flere CPU-arkitekturer, så det er muligt at bruge IDA Pro til at reverse engineer kode til ARM, AVR, M68k og mange andre arkitekturer.

Radare

Radare

Disassembler Radare er et alternativ til IDA. Den har stort set alle IDA-funktionerne uden at være lige så robust og stabil. Men den er gratis og open source. Radare er i sig selv et konsolværktøj, men det har en Cutter-frontend, hvilket gør det til et ægte alternativ til IDA.

Windows Sysinternals

Windows Sysinternals-værktøjerne bruges generelt til administration, diagnosticering, fejlfinding og overvågning af Microsoft Windows-miljøet. Men de er også velegnede til reverse engineering af Windows-software.

TCPView er en netværkssniffer, der viser alle oplysninger om TCP/UDP-pakker fra alle processer. Dette værktøj er nyttigt til reverseing af netværksprotokoller.

PortMon er en fysisk systemportovervågning. Det overvåger serielle og parallelle porte og al trafik, der går gennem dem.

WinObj viser alle globale objekter i systemet i en hierarkisk struktur. Dette værktøj kan være nyttigt ved reverse engineering af et program, der arbejder med synkroniseringsprimitiver som f.eks. mutexes og semaforer, og også ved reverse engineering af kernetilstandsdrivere.

Netværksovervågningsværktøjer

Wireshark

Wireshark

Wireshark er en af de mest kraftfulde netværkssniffere. Den giver dig ikke kun mulighed for at optage netværkstrafik, men indeholder også parsere til forskellige netværksprotokoller, lige fra virkelig lavt niveau som Ethernet, TCP og IP til applikationsspecifikke protokoller som WebSockets og XMPP.

Fiddler

Fiddler

Fiddler er en webproxy, der registrerer trafik fra browsere og giver dig mulighed for at analysere HTTP/HTTPS-forespørgsler. I modsætning til Wireshark viser den HTTP-sessioner i stedet for separate netværkspakker. Fiddler giver dig også mulighed for at analysere komprimerede data sendt over HTTP og analysere JSON- og XML-data, når du overvåger SOAP-, REST- og AJAX-anmodninger.

API Monitor

API Monitor

API Monitor er et nyttigt værktøj til at opdage, hvilke API’er der kaldes af et program, og hvilken adfærd programmet forventer af disse API’er. Dette værktøj har en kraftig database og giver dig mulighed for at se kald til et stort antal API-funktioner af ikke kun kernel32 og ntdll, men også COM, managed environment og andre. API Monitor giver også praktiske filtreringsmekanismer.

Debuggere

En debugger er uvurderlig for enhver udvikler for at se, hvad et program gør lige nu. Du får det samme udbytte af debugging, når du vender programmer, som du får af debugging af live-programmer.

De mest populære debuggere er OllyDbg, WinDbg og Windbg Preview.

OllyDbg

OllyDBG

OllyDbg (og dens efterfølger x64dbg) er nok den bedste debugger, når det drejer sig om reverse engineering af software. Den blev specielt udviklet til behovet for reverseing og har alle de værktøjer, der er nødvendige til dette formål:

  • en indbygget disassembler med mulighed for at analysere og identificere vigtige datastrukturer
  • en import- og eksportanalysefunktion
  • en indbygget assemblerings- og patchingmotor

Muligheden for at parse API-funktioner og deres parametre gør det nemt at reverse interaktioner med et system. Stackvisningen giver en masse oplysninger om call stack’en. En anden vigtig fordel er, at du kan bruge OllyDbg med debug-beskyttede programmer, når sædvanlige debuggere bare ikke kan gøre noget.

WinDbg

Windbg

Trods sin enkle grænseflade har WinDbg kraftige værktøjer til debugging. Det har en indbygget disassembler, forskellige kommandoer, der giver dig mulighed for at vide næsten alt om den proces/det system, du debugger, og muligheden for at lave debugging i kernel-mode, hvilket nok er den mest værdifulde funktion. Det er en stor fordel, når man skal vende drivere, især kernel-mode-drivere.

Windbg Preview

Windbg Preview

Windbg Preview er en ny version af Windbg, som er udviklet af Microsoft. Den distribueres kun via Windows Store. Den har alle funktionerne fra den klassiske Windbg kombineret med en ny brugergrænseflade og flere nye funktioner. En af disse nye funktioner er Time Travel Debugging, som giver dig mulighed for at optage en vis periode af programudførelsen og derefter afspille den så mange gange, som du har brug for. På denne måde kan du udføre de interessante dele af koden trinvis, uden at være bange for at køre noget kode ved et uheld og miste konteksten eller alle data.

Læs også:
9 bedste reverse engineering-værktøjer til 2018

Eksempel på reelt software reverse engineering

Nu skal vi se et eksempel på, hvordan man reverse engineer et stykke software. Lad os forestille os, at du har en mistænkelig eksekverbar fil. Du skal finde ud af, hvad dette program gør, og om det er sikkert for brugerne.

Med tanke på scenariet er det en god idé ikke at køre denne eksekverbare fil på din arbejdscomputer, men i stedet at bruge en virtuel maskine. Lad os starte programmet i vores virtuelle maskine.

Processen opretter en tjeneste

Som vi kan se, opretter denne fil en Windows-tjeneste ved navn TestDriver. Den har typen kernel, så vi ved, at det er en driver. Men hvor henter den driverfilen fra for at kunne køre? Vi kan bruge ProcessMonitor fra Sysinternals Suite til at finde ud af det. Når vi åbner ProcessMonitor, kan vi opsætte filtre, så vi kun får vist filaktiviteten fra den proces, vi er interesseret i. Dens aktivitetslog ser således ud:

FileMon information

Driverfilen oprettes af den proces, som vi vender om, og denne proces lægger denne fil i brugerens temp-mappe. Der er ingen grund til at lede efter filen i temp-mappen, da vi kan se, at processen sletter den lige efter brug. Hvad gør processen så med denne fil? Hvis den pakker filen ud, kan vi forsøge at finde den i processens ressourceafsnit, da dette er et almindeligt sted at gemme sådanne data. Lad os kigge der. Vi vil bruge et andet værktøj – Resource Hacker – til at undersøge ressourcerne. Lad os køre det:

Undersøg ressourcerne med Resource Hacker

Bingo! Som vi kan se af det fundne ressourceindhold, er der sandsynligvis tale om den eksekverbare Windows-fil, da den starter med en MZ-signatur og har strengen “This program cannot be run in DOS mode”. Lad os kontrollere, om det er vores driverfil. Til det formål udpakker vi ressourcen ved hjælp af Resource Hacker og åbner den i disassembler.

Disassembler-skærm

Som vi ved, er DriverEntry indgangspunktet for drivere i kernel-mode i Windows-systemer. Vi kan fortsætte vores forskning, da det ser ud til, at vi har fundet den rigtige driver.

Sådan reverse engineer du en driver

For at begynde reverse engineering af driveren undersøger vi de funktioner, der kaldes fra DriverEntry, en efter en. Hvis vi går til sub_14005, finder vi intet interessant, så vi fortsætter med sub_110F0 og finder denne kode:

Kodestykke 1

Kodestykke 2

Kodestykke 3

Kodestykke 4

Nogle linjer er udeladt her af hensyn til enkeltheden.

I den første liste oprettes der en unicode-streng, og denne streng peger på stien C:\hello.txt. Derefter fyldes strukturen OBJECT_ATTRIBUTES med almindelige værdier; vi ved, at denne struktur ofte er nødvendig, når man kalder funktioner som ZwCreateFile.

I det andet opslag ser vi, at ZwCreateFile faktisk kaldes, hvilket gør os ret sikre på, at driveren opretter filen – og vi ved, hvor denne fil befinder sig, efter at den er oprettet.

Fra den tredje og fjerde liste kan vi se, at driveren tager unicode-strengen og skriver den til bufferen (dette sker i funktionen sub_11150), og bufferen vil blive skrevet til filen ved hjælp af funktionen ZwWriteFile. Til sidst lukker driveren filen ved hjælp af ZwClose API’en.

Lad os opsummere. Vi fandt ud af, at det oprindelige program udtrækker driverfilen fra sine ressourcer, placerer den i den aktuelle brugers temp-mappe, opretter Windows-tjenesten for denne driver og kører den. Herefter stopper programmet og sletter tjenesten og den originale driverfil fra temp-mappen. Ud fra denne adfærd og fra analysen af disassemblyen fremgår det, at driveren ikke gør andet end at oprette en fil på C-drevet med navnet hello.txt og skrive strengen “Hello from driver”.

Nu skal vi kontrollere, om vi har ret. Lad os køre programmet og tjekke C-drevet:

Applikationsskærm

Værdifuldt! Vi har reverse engineered dette enkle program, og nu ved vi, at det er sikkert at bruge.

Vi kunne have opnået dette resultat på mange forskellige måder – ved hjælp af debugging eller API Mon, ved at skrive tests osv. Du kan finde dine egne måder at reverse engineer software på, som fungerer for dig.

Konklusion

Windows software reverse engineering kræver en solid uddannelsesmæssig baggrund og programmeringserfaring. For at kunne udføre reverse engineering skal du kombinere færdigheder inden for disassembling, netværksovervågning, fejlfinding, API-integration, flere programsprog, compilere osv. Du skal også være meget forsigtig, når du reverse software, for ikke at bryde ophavsretslove eller skade dit system.

Vi har hos Apriorit et erfarent team af reverse engineers. Hvis du ønsker at anvende reverse engineering-færdigheder til dit projekt, er du velkommen til at kontakte os!

Skriv et svar

Din e-mailadresse vil ikke blive publiceret.