HTCinside


5 Anti-fejlretningsteknikker, der vil beskytte din software

Når vi udgiver vores softwareprodukter, bruger vi alle at skrive i EULA'er 'Du må ikke reverse engineering, dekompilere eller adskille softwaren'. Men i mange situationer er ord ikke den bedste beskyttelse, og du er virkelig nødt til at introducere nogle tekniske værktøjer for at forhindre softwareinvertering og beskytte din knowhow mod at blive afsløret.

Der er flere teknologiske tilgange til at forhindre software reverse engineering: anti-debug, anti-dump og andre. I dette indlæg vil vi fokusere på nogle anti-debug-metoder, da de er i kernen af ​​anti-reverse-engineering beskyttelse. At knytte en debugger til den undersøgte proces for at udføre den trin for trin er et meget vigtigt trin i ethvert vendearbejde - så lad os tage et kig på, hvilke værktøjer vi kan bruge til at gøre reversernes liv sværere.

Der er et par ting, jeg gerne vil nævne i begyndelsen. Den første er, at der ikke er nogen universel eller 100 % skudsikker beskyttelse mod software reverse engineering. Der er altid en måde for reverser at komme ind på, den eneste strategi vi har er at gøre hans arbejde så hårdt og indsatskrævende som muligt.

Dernæst er der en del anti-reverse engineering-teknikker og især anti-debug-metoder, herunder tidsbaseret beskyttelse eller endda specifikke kode-indlejrede teknologier som nanomitter. I dette indlæg vil vi kun overveje flere standardtilgange, der er specifikke for Windows-baserede systemer, de mest populære.

Nedenstående fremgangsmåder er beskrevet generelt.

Indhold

Indhold

  1. Indbyggede funktioner til at kontrollere tilstedeværelsen af ​​debugger
  2. Tråd gemmer sig
  3. Flagkontrol
  4. Detektion af brudpunkt
  5. Undtagelseshåndtering: SEH
  6. Konklusion

1 – Indbyggede funktioner til at kontrollere tilstedeværelsen af ​​debugger

Windows-systemer giver os nogle færdige værktøjer til at opbygge enkel anti-debug-beskyttelse. En af de enkleste anti-debugging-teknikker er baseret på at kalde IsDebuggerPresent-funktionen. Denne funktion returnerer TRUE, hvis en bruger-mode debugger i øjeblikket fejlfinder processen.

Denne funktion refererer til PEB (Process Environment Block, en lukket systemstruktur) og især dets BeingDebugged-felt. Reversere, når de omgår en sådan beskyttelsesteknik, bruger dette faktum: f.eks. ved at anvende DLL-injektion satte de BeingDebugged-værdien til 0 lige før denne kontrol udføres i den beskyttede kode.

Et par ord om, hvor man skal udføre en sådan kontrol. Hovedfunktionen er ikke den bedste mulighed: reversere tjekker det normalt først i adskilt liste. Det er bedre at udføre anti-debug-tjek i TLS Callback, som det kaldes før indgangskaldpunktet for det eksekverbare hovedmodul.

En anden funktionel kontrolmulighed er CheckRemoteDebuggerPresent. I modsætning til funktionen beskrevet ovenfor, kontrollerer den, om en anden parallel proces i øjeblikket fejlretter en proces. Den er baseret på NtQueryInformationProcess-funktionen og især ProcessDebugPort-værdien.

2 – Trådskjul

Mens den tidligere gruppe af metoder blev bygget på at kontrollere tilstedeværelsen af ​​debugger, vil denne give aktiv beskyttelse mod det.

Fra Windows 2000 modtager funktionen NtSetInformationThread det nye flag med navnet ThreadHideFromDebugger. Dette er en meget effektiv anti-fejlretningsteknik, der leveres i Windows OS. En tråd med dette flagsæt stopper med at sende fejlretningsbegivenheder, inklusive brudpunkter og andre, og skjuler sig således for enhver debugger. Opsætning af ThreadHideFromDebugger for hovedtråden vil betydeligt komplicere processen med at knytte debugger til en tråd.

Den logiske fortsættelse blev introduceret i Windows Vista med NtCreateThreadEx-funktionen. Den har parameteren CreateFlags, som blandt andet opsætter flaget THREAD_CREATE_FLAGS_HIDE_FROM_DEBUGGER. Processen med dette flagsæt vil blive skjult for debugger.

3 – Flagkontrol

Løbende debugging kan detekteres af de ændrede værdier af forskellige flag i forskellige system- og processtrukturer.

Windows NT indeholder en global variabel ved navn NtGlobalFlag med et sæt flag, der bruges til systemsporing og fejlretning. Ovennævnte PEB-struktur inkluderer sit eget NtGlobalFlag-felt. Under debug ændres denne feltværdi med flere specifikke flag sat. Kontrol af disse flag kan producere triggere til anti-fejlretningsbeskyttelse.

En eksekverbar kan nulstille PEB-strukturens NtGlobalFlag-flag ved hjælp af en specifik struktur kaldet IMAGE_LOAD_CONFIG_DIRECTORY, som indeholder specifikke konfigurationsparametre for systemindlæseren. Den har GlobalFlagsClear-feltet, som nulstiller PEBs NtGlobalFlag-flag. Som standard føjes denne struktur ikke til en eksekverbar, men kan tilføjes senere. Det faktum, at en eksekverbar ikke har denne struktur eller GlobalFlagsClear-værdi er lig med 0, mens det tilsvarende felt, der er gemt på disken eller i hukommelsen af ​​den kørende proces, ikke er nul, indikerer tilstedeværelsen af ​​en skjult debugger. Denne kontrol kan implementeres i den eksekverbare kode.

En anden gruppe af flag er procesbunken. Der er to felter i den tilsvarende _HEAP-struktur: Flag og ForceFlags. Begge ændrer deres værdier, når den tilsvarende proces debugges og kan således være grundlaget for anti-debug-kontrollen og beskyttelsen.

Endnu en flagkontrol, som kan bruges til at detektere debugger, er Trap Flag-kontrollen (TF). Det er i EFLAGS-registret. Når TF er lig med 1, genererer CPU INT 01h («Single Step» undtagelse) efter hver instruktionsudførelse, der understøtter debugging-processen.

4 – Breakpoint detektion

Breakpoints er den væsentlige del af enhver fejlretningsproces, og ved at detektere dem kan vi detektere og neutralisere en debugger. Anti-fejlretningstaktikker baseret på breakpoint-detektion er en af ​​de mest kraftfulde og svære at omgå.

Der er to typer brudpunkter: software og hardware.

Software breakpoints indstilles af debugger ved at injicere int 3h instruktionen i koden. Debuggerdetektionsmetoder er således baseret på beregning og kontrol af kontrolsummen for den tilsvarende funktion.

Der er ingen universel metode til at bekæmpe denne beskyttelse - en hacker bliver nødt til at finde det stykke kode, der beregner kontrolsummen(e) og erstatte de returnerede værdier af alle tilsvarende variabler.

Hardware-breakpoints indstilles ved hjælp af specifikke debug-registre: DR0-DR7. Ved at bruge dem kan udviklere afbryde udførelsen af ​​et program og overføre kontrol til en debugger. Anti-debug-beskyttelse kan bygges på at kontrollere værdierne af disse registre eller være mere proaktiv og tvunget nulstille deres værdier for at stoppe fejlretningen ved hjælp af SetThreadContext-funktionen.

5 – Undtagelseshåndtering: SEH

Structured Exception Handling eller SEH er en mekanisme, der gør det muligt for en applikation at modtage meddelelser om ekstraordinære situationer og håndtere dem i stedet for operativsystem. Pointere til SEH-handlere kaldes SEH-rammer og placeres på stakken. Når en undtagelse genereres, håndteres den af ​​den første SEH-ramme i stakken. Hvis den ikke ved, hvad den skal gøre med den, sendes den til den næste i stakken og så videre til systembehandleren.

Når applikationen debugges, bør en debugger opsnappe kontrol efter int 3 timers generation, ellers vil en SHE-handler tage den. Dette kan bruges til at organisere anti-debug-beskyttelse: vi kan oprette vores egen SEH-handler og lægge den øverst på stakken og derefter tvinge den int 3 timers generation. Hvis vores handler får kontrollen, bliver processen ikke debugget – ellers kan vi gennemtvinge anti-debug-foranstaltninger, efterhånden som vi har opdaget en debugger.

Konklusion

Dette er blot nogle få anti-debugging-teknikker fra en lang række af dem.

En god praksis er at kombinere forskellige anti-bakketeknikker, hvilket gør det meget sværere at omgå beskyttelsen. Yderligere kontroller kan bremse en applikationsudførelse, og derfor anvendes de stærkeste beskyttelsesteknikker normalt på kernemodulerne, der indeholder patenterede teknologier og knowhow. Endelig er det en afvejning mellem niveauet for kodesikkerhed og applikationsydelse.

Jeg vil gerne nævne, at reverse engineering af software ikke altid er ulovlig og nogle gange kan anvendes under forskningsprocessen til sådanne opgaver som kompatibilitetsforbedring, patching, udokumenteret brug af systemgrænseflader osv. Juridiske reverse engineering-tjenester leveret af fagfolk beskæftiger sig også med anti-debugging-beskyttelse, men fra anden side - omgå det.