februar 10, 2022

Reverse engineering dongle beskyttet program

jeg var ung, internettet lige begyndt, og vi kunne få tonsvis af programmer gratis. Det var gratis, fordi nogen derude var “venlig” nok til at knække/lappe .eks fil.

jeg har sat “kind” mellem citater, fordi det var den opfattelse, jeg havde, da jeg var barn. Nu er jeg ingeniør, og jeg ved, hvor meget arbejde det kræver at bygge programmer. Så vær venlig, ikke hente revnet programmel. Støt udvikleren og køb en licens!

anvendelse af en sådan revne, patching Eksen, jeg har altid ønsket at vide, hvordan man gør sådan en ting. Det viser sig, at du er nødt til at forstå assembler, et maskinsprog, som kun din CPU forstår (og nogle andre nørder derude). Da det var for svært, kom jeg aldrig rundt for at lære det. Indtil for nylig (som 20 år senere).

foto af Patrick Hendry på Unsplash

for et år siden købte jeg programmer (med licens!) der har brug for en USB-dongle for at arbejde. Det er virkelig besværligt at have den dongle med dig hele tiden. Især når man er på farten. Så jeg ledte efter måder omkring det. Den første ting, jeg stødte på, var denne nøgleemulator kaldet MultiKey. Det dumper hukommelsen til din dongle til dit register og emulerer derefter din dongle ved at læse fra dit register. Det fungerede OK, indtil jeg ønskede at køre det på Vinduer 10. Tilsyneladende er Microsoft ikke så stor fan af MultiKey. I virkeligheden er det ikke en stor fan af usignerede drivere, og MultiKey bruger en usigneret driver. Så jeg havde brug for en anden løsning. Tid til at dykke ned i den ting, der hedder assembly code!

jeg vidste altid, at der var et værktøj derude til reverse engineering, kaldet IDA. Det er i stand til at dekompilere din .fil og vis, hvad der foregår. Desværre er grænsefladen virkelig svært at forstå. Jeg vidste også om OllyDbg. Det er en debugger. En debugger giver dig mulighed for at gå gennem assembler-koden, mens programmet kører! Betydning, for eksempel, hvis du debugger lommeregnerapplikationen, kunne du faktisk se den håndtere et knaptryk, udføre beregningen og vise resultatet på skærmen. Helvede, du kan endda pause og ændre dens hukommelse, så lommeregneren vender tilbage 5, Når du spørger, Hvad 2 + 2 er!

men jeg er ikke her for at ændre calculus (selvom det ville være cool). Jeg vil være fri for donglen. Så jeg åbnede min app med OllyDbg.

OllyDbg

det var virkelig overvældende. Jeg anede ikke, hvad alle disse koder betød. Lad være med at vide, hvor du skal starte. Så jeg gik tilbage til tegnebrættet. Det viser sig, at der er noget, der hedder RetDec, en decompiler, der forsøger at lave C-kode ud af maskinkode. Det tog mig lidt tid at sætte det op og køre dekompilering, men indsatsen betalt af. Resultatet var en enorm .c-fil, over 2 millioner linjer kode med semi-læsbar kode.

faktisk kunne jeg finde koden, der læste bytes af donglen, ret let:

RetDec output: jeg har allerede ændret nogle af variabelnavnene til noget mere læsbart.

med disse oplysninger vendte jeg tilbage til min debugger. I mellemtiden fandt jeg ud af, at OllyDbg er rigtig gammel (fra år 2000) og ikke er blevet opdateret siden 2013. Så jeg fandt denne nye, forbedrede debugger, kaldet h64dbg. Det er open source og har et stort fællesskab af udviklere, der arbejder på det.

læsning maskine sprog

i maskinen sprog hver instruktion har en hukommelse adresse. Så med de adresser, der findes i RetDec-koden, vendte jeg mig til 64dbg og se, koden, der læser donglen:

Assembler kode læsning ud 2 bytes af dongle hukommelse.

i samlingskode indlæses funktionens argumenter i hukommelsen ved hjælp af stakpegeren esp. I vores kode sker dette lige før opkaldet til funktionen. (de 3 mov instruktioner angiver opkaldet tager 3 argumenter). Efter opkaldet nulstilles vores stakpeger, og en kontrol (test) udføres, hvis opkaldet til funktionen var vellykket. Hvis ikke, ser vi koden lave et spring (jne). Dette spring peger på et stykke kode, der angiver, at donglen ikke er til stede.

som du kan se, er der et opkald til en bestemt funktion for at læse donglen. Jeg kiggede op referencevejledningen for at finde ud af, hvad denne funktion gør:

funktionen læser en 2 bytes hukommelse (et ord) fra donglen. Som gættet tager funktionen 3 argumenter, hvor det sidste argument er en markør til 2 byte, der vil indeholde nogle data fra donglen.

i samlingskode indlæses argumenterne i omvendt rækkefølge. Passerer i det sidste argument er denne:

det sidste argument peger på esi, hvilket betyder, at dataene fra donglen vil blive gemt på den hukommelsesadresse, esi peger på.

når vi holder pause lige efter opkaldet, kan vi faktisk se resultatet i hukommelsen:

0h74. Det er det, der læses ud fra donglen og gemmes i hovedprogrammets hukommelse.

for at springe over dette opkald skal jeg bare skrive 0h74 til hukommelsen, hvor esi peger på. Dette er så simpelt som at erstatte de 7 linjer ovenfor med:

som du kan se, har jeg også nop-ed resten af assemblerinstruktionerne, herunder testen, hvis opkaldet til funktion var gyldigt. Dette betyder, at springet ikke vil blive taget, og programmet vil fortsætte med at arbejde uden checken.

efter at have lappet alle opkald, der involverede donglen, reddede jeg det nye .eks. Jeg trak donglen ud, kørte min skik .til min egen forbløffelse virkede det! Jeg havde med succes knækket et stykke program.

en anden ting jeg krydser af min bucket list list

Ps: De fleste af de ting var tilsløret, ligesom 0h74 og navnet på den app. Dette er ikke at skade de hårdtarbejdende udviklere, der skabte dette program på nogen måde. Også jeg var meget heldig, at donglen kun returnerede bytes og ikke gjorde nogen kryptering alene.

Skriv et svar

Din e-mailadresse vil ikke blive publiceret.