HTCinside
Kada objavljujemo svoje softverske proizvode, svi mi pišemo u EULA ugovorima 'Ne smijete raditi obrnuti inženjering, dekompilirati ili rastavljati softver'. Ali u mnogim situacijama riječi nisu najbolja zaštita i stvarno morate uvesti neke tehničke alate kako biste spriječili softversko invertiranje i zaštitili svoje znanje i iskustvo od otkrivanja.
Postoji nekoliko tehnoloških pristupa za sprječavanje obrnutog inženjeringa softvera: anti-debug, anti-dump i drugi. U ovom ćemo se postu usredotočiti na neke metode za uklanjanje pogrešaka jer su one u srži zaštite od obrnutog inženjeringa. Priključivanje programa za ispravljanje pogrešaka istraženom procesu kako bi se izvršilo korak po korak vrlo je važna faza svakog rada na poništavanju - pa pogledajmo koje alate možemo koristiti da otežamo život poništavačima.
Postoji nekoliko stvari koje bih želio spomenuti na samom početku. Prvi je da ne postoji univerzalna ili 100% neprobojna zaštita od obrnutog inženjeringa softvera. Uvijek postoji način da reverser uđe, jedina strategija koju imamo je učiniti njegov rad što napornijim i napornijim.
Dalje, postoji dosta tehnika protiv obrnutog inženjeringa, a posebice metoda protiv ispravljanja pogrešaka, uključujući zaštitu koja se temelji na vremenu ili čak specifične tehnologije ugrađene u kod, poput nanomita. U ovom ćemo postu razmotriti samo nekoliko standardnih pristupa specifičnih za Windows temeljene sustave, one najpopularnije.
Pristupi prikazani u nastavku opisani su općenito.
Sadržaj
Windows sustavi pružaju nam neke gotove alate za izgradnju jednostavne zaštite od ispravljanja pogrešaka. Jedna od najjednostavnijih tehnika za uklanjanje pogrešaka temelji se na pozivanju funkcije IsDebuggerPresent. Ova funkcija vraća TRUE ako program za ispravljanje pogrešaka u korisničkom načinu rada trenutno otklanja pogreške procesa.
Ova se funkcija odnosi na PEB (blok okruženja procesa, struktura zatvorenog sustava), a posebno na njegovo polje BeingDebugged. Reverzeri kada zaobilaze takvu tehniku zaštite koriste ovu činjenicu: npr. primjenjujući DLL injekciju, postavljaju vrijednost BeingDebugged na 0 neposredno prije nego što se ova provjera izvrši u zaštićenom kodu.
Nekoliko riječi o tome gdje izvršiti takvu provjeru. Glavna funkcija nije najbolja opcija: reverzeri je obično prvo provjeravaju u rastavljenom popisu. Bolje je izvršiti provjeru protiv otklanjanja pogrešaka u TLS povratnom pozivu, jer se poziva prije ulazne pozivne točke glavnog izvršnog modula.
Još jedna opcija funkcionalne provjere je CheckRemoteDebuggerPresent. Za razliku od gore opisane funkcije, ona provjerava radi li neki drugi paralelni proces trenutno otklanjanje pogrešaka u procesu. Temelji se na funkciji NtQueryInformationProcess i posebno na vrijednosti ProcessDebugPort.
Dok je prethodna skupina metoda bila izgrađena na provjeri prisutnosti programa za ispravljanje pogrešaka, ova će pružiti aktivnu zaštitu od toga.
Počevši od sustava Windows 2000, funkcija NtSetInformationThread dobiva novu oznaku pod nazivom ThreadHideFromDebugger. Ovo je vrlo učinkovita tehnika za uklanjanje pogrešaka dostupna u Windows OS-u. Nit s ovom postavljenom zastavicom prestaje slati obavijesti o događajima otklanjanja pogrešaka, uključujući prijelomne točke i druge, čime se skriva od bilo kojeg programa za ispravljanje pogrešaka. Postavljanje ThreadHideFromDebuggera za glavnu nit značajno će komplicirati proces pripajanja programa za ispravljanje pogrešaka na nit.
Logičan nastavak uveden je u Windows Vista s funkcijom NtCreateThreadEx. Ima parametar CreateFlags, koji između ostalog postavlja oznaku THREAD_CREATE_FLAGS_HIDE_FROM_DEBUGGER. Proces s ovom postavljenom zastavicom bit će skriven od programa za ispravljanje pogrešaka.
Pokrenuto otklanjanje pogrešaka može se otkriti promijenjenim vrijednostima različitih zastavica u različitim strukturama sustava i procesa.
Windows NT uključuje globalnu varijablu pod nazivom NtGlobalFlag sa skupom oznaka, koje se koriste za praćenje sustava i otklanjanje pogrešaka. Gore spomenuta PEB struktura uključuje vlastito polje NtGlobalFlag. Tijekom otklanjanja pogrešaka, vrijednost ovog polja mijenja se s nekoliko postavljenih specifičnih zastavica. Provjera ovih oznaka može proizvesti okidače za zaštitu od ispravljanja pogrešaka.
Izvršna datoteka može resetirati zastavice NtGlobalFlag PEB strukture pomoću specifične strukture pod nazivom IMAGE_LOAD_CONFIG_DIRECTORY, koja sadrži specifične konfiguracijske parametre za učitavač sustava. Ima polje GlobalFlagsClear, koje resetira NtGlobalFlag zastavice PEB-a. Prema zadanim postavkama, ova se struktura ne dodaje u izvršnu datoteku, ali se može dodati kasnije. Činjenica da izvršna datoteka nema ovu strukturu ili da je vrijednost GlobalFlagsClear jednaka 0, dok odgovarajuće polje pohranjeno na disku ili u memoriji pokrenutog procesa nije nula, ukazuje na prisutnost skrivenog programa za ispravljanje pogrešaka. Ova se provjera može implementirati u izvršni kod.
Druga skupina zastavica je ona gomile procesa. Postoje dva polja u odgovarajućoj _HEAP strukturi: Flags i ForceFlags. Oba mijenjaju svoje vrijednosti kada se odgovarajući proces otkloni i stoga mogu biti temelj provjere i zaštite protiv otklanjanja pogrešaka.
Još jedna provjera zastavice, koja se može koristiti za otkrivanje debuggera, je provjera zastavice zamke (TF). Nalazi se u registru EFLAGS. Kada je TF jednak 1, CPU generira INT 01h (iznimka «Single Step») nakon svakog izvršavanja instrukcija koje podržavaju proces otklanjanja pogrešaka.
Prijelomne točke bitan su dio svakog procesa ispravljanja pogrešaka i stoga ih otkrivamo, možemo otkriti i neutralizirati program za ispravljanje pogrešaka. Taktike za uklanjanje pogrešaka temeljene na otkrivanju prijelomne točke jedna su od najmoćnijih i teško ih je zaobići.
Postoje dvije vrste prijelomnih točaka: softverske i hardverske.
Prijelomne točke softvera postavlja program za ispravljanje pogrešaka umetanjem instrukcije int 3h u kod. Stoga se metode otkrivanja programa za ispravljanje pogrešaka temelje na izračunavanju i kontroli kontrolne sume odgovarajuće funkcije.
Ne postoji univerzalna metoda borbe protiv ove zaštite – haker će morati pronaći dio koda koji izračunava kontrolni zbroj(ove) i zamijeniti vraćene vrijednosti svih odgovarajućih varijabli.
Prijelomne točke hardvera postavljaju se korištenjem posebnih registara za ispravljanje pogrešaka: DR0-DR7. Koristeći ih, programeri mogu prekinuti izvođenje programa i prenijeti kontrolu na program za ispravljanje pogrešaka. Zaštita od ispravljanja pogrešaka može se izgraditi na provjeravanju vrijednosti ovih registara ili biti proaktivniji i prisilno resetirati njihove vrijednosti kako bi se zaustavilo ispravljanje pogrešaka pomoću funkcije SetThreadContext.
Structured Exception Handling ili SEH mehanizam je koji aplikaciji omogućuje primanje obavijesti o iznimnim situacijama i rukovanje njima umjesto operativnog sustava. Pokazivači na SEH rukovatelje nazivaju se SEH okviri i postavljaju na stog. Kada se generira iznimka, njome upravlja prvi SEH okvir u stogu. Ako ne zna što bi s njim, prosljeđuje se sljedećem u stogu i tako dalje do rukovatelja sustava.
Kada se aplikacija ispravlja, program za ispravljanje pogrešaka trebao bi presresti kontrolu nakon generiranja int 3h ili će je preuzeti SHE rukovatelj. Ovo se može koristiti za organiziranje zaštite od ispravljanja pogrešaka: možemo kreirati vlastiti SEH rukovatelj i staviti ga na vrh stoga, a zatim prisiliti generiranje int 3h. Ako naš rukovatelj dobije kontrolu, proces se ne otklanja pogreška – u protivnom možemo prisiliti mjere protiv ispravljanja pogreške kad otkrijemo program za ispravljanje pogrešaka.
Ovo je samo nekoliko tehnika za uklanjanje pogrešaka iz velikog broja njih.
Dobra praksa je kombinirati različite tehnike protiv preokreta što znatno otežava zaobilaženje zaštite. Dodatne provjere mogu usporiti izvođenje aplikacije, stoga se najjače tehnike zaštite obično primjenjuju na osnovne module koji sadrže patentirane tehnologije i know-how. Konačno, to je kompromis između razine sigurnosti koda i izvedbe aplikacije.
Želio bih napomenuti da obrnuto inženjerstvo softvera nije uvijek protuzakonito i ponekad se može primijeniti tijekom procesa istraživanja za zadatke kao što su poboljšanje kompatibilnosti, krpanje, nedokumentirano korištenje sučelja sustava itd. Usluge pravnog obrnutog inženjeringa koje isporučuju profesionalci također se bave zaštitom od ispravljanja pogrešaka, ali s druge strane – zaobilaze je.