- Co je to cracking
- Cíle seriálu
- Nejčastěji používané ochrany, jejich slabiny a přednosti
- Rady jak lépe chránit svůj software
Crackingem je označován soubor mnoha postupů, při kterých dochází ke zkoumání nebo k úpravám programového kódu bez možnosti použít zdrojový kód programu. Cílem tohoto seriálu je seznámit vás se základními praktikami crackerů, naučit vás ovládat programy nezbytné pro crackery a naučit vás chránit svůj software. Při crackingu je naprosto nezbytná alespoň základní znalost Assembleru a API funkcí.
Ochrany programů před crackery
- Registrační číslo (serial number)
- Časové omezení (time trial)
- Klíčový soubor (key file)
- Hardwarový klíč (dongle)
- Kontrola originálního CD (CD-check)
- Demo
- Ochrana naprogramovaná ve Visual Basicu nebo Delphi
- Komprese a kódování programů
Registrační číslo
Toto je nejčastější typ ochrany. Setkáte se s ním skoro všude, ale také je nejméně spolehlivý. Největší chybou při ochraně registračním číslem je, když je registrační číslo pořád stejné. Potom není problém si číslo najít na internetu. Rozhodně bych nedoporučoval. Druhým způsobem jak chránit program pomocí sériového čísla je změna sériového čísla podle zadaných položek. Obecně platí čím více položek, tím líp, takže ideální by byly položky: jméno, firma, (oblíbený film), registrační číslo. Další, a dle mého názoru nejlepší, ochrana sériovým číslem je, že se číslo mění podle stroje, na kterém běží. Často se používá sériové číslo pevného disku. V současné době se ale začíná na úkor ostatních prosazovat kontrola registračního čísla on-line přes internet. Osobně tento postup považuju za diskriminující. Podstatně to znevýhodňuje uživatele, kteří nemají připojení k internetu. Dalším neférovou funkcí, kterou několik programů provozuje je zaslání IP adresy a různých údajů vlastníkovi programu, když se nepovede program zaregistrovat.
Často používané API funkce v této ochraně: GetWindowText, GetDlgItem, SendDlgItemMessage, SendMessage
Časové omezení
Tento typ ochrany je velice často kombinován s ochranou registračním číslem. Po zadání správného registračního čísla se omezení zruší. Opět se jedná o velmi nespolehlivý a snadno překonatelný typ ochrany. Tento typ ochrany má dvě slabiny. První je, že není těžké najít kód, který kontroluje jestli už vypršela časová lhůta. Většinou si program schovává čas, kdy se nainstaloval do registru a nebo do nějakého souboru na pevném disku. Logicky to musí znamenat, že někde v programu nebo v instalačním souboru se nalézá API funkce, která toto zprostředkovává, a když ji najdete, tak není problém úložiště najít a modifikovat. Druhým problémem je, že program musí nějakým způsobem získávat aktuální datum a čas, takže není problém tuto rutinu najít a změnit návratovou hodnotu nebo pozměnit instrukci skoku, která zde zákonitě někde musí být. Velkou chybou by bylo použít takovouto kontrolu:
MOV EAX, [004030FF] ; z paměti nahraju mezní hodnotu
CMP EAX, 1Eh ; porovnám s hodnotou 30
JLE PLAY ; jestli je menší nebo rovno, tak spusť aplikaci
Možná, že se tomu zasmějete, ale už jsem narazil na program, který obsahoval tentýž kód. Vždy používejte pro kontrolu rafinovanější metody nebo alespoň používejte nějakou kontrolní rutinu proti změně kódu, která by mohla vypadat například takto:
mov ebx, offset kontrola
; ebx = adresa návěstí kontrola
mov eax, [ebx]
; eax = to, co se nalázá na adrese, na kterou ukazuje ebx
cmp al, 75h
; je zde instrukce jnz?
jnz KOD_BYL_MODIFIKOVAN
; pokud není, tak skoč
; nějaký kód
; nějaký kód
cmp eax, 1Eh
; porovnání dvou časů
kontrola:
jle PLAY
; pokud platí, že čas v eax je menší nebo roven 30, tak spusť hru
; nějaký kód
S touto kontrolní rutinou se můžete setkat často, ale většinou je velice dobře ukryta. Ukrýt ji je docela lehké, protože neobsahuje žádnou API funkci ani přerušení, takže najít ji je dost obtížné. Časové omezení nemusí být pouze na počet dnů, ale také na počet spuštění nebo na omezenou dobu od spuštění systému. Například rezidentní ochrana zkušební verze nějakého antiviru běží jen určitou dobu, než se vypne, a poté by bylo nutné restartovat systém. I když jsem se s tímto typem ochrany nikdy nesetkal, tak jsem četl, že existuje.Často používané API funkce: GetLocalTime, GetSystemTime, GetFileTime, CompareFileTime, GetTickCount
Klíčový soubor
Toto je velice silná ochrana a překonat ji je velice těžké. V klíčovém souboru mohou být části vlastního programu nebo klíč pro dekomprimování programu při spuštění. Ochrana klíčovým souborem může být také kombinována s časovým omezením, které se zruší při nahrání klíčového souboru. Vytvořit klíčový soubor k programu, který ho vyžaduje je opravdu tvrdý oříšek.
Často používané API funkce: CreateFile, ReadFile, WriteFile, SetFilePointer
Hardwarový klíč
Pokud je tato ochrana správě naprogramována, tak je téměř nepřekonatelná. Cracker by musel buď dokonale simulovat hardwarový klíč softwarovými prostředky a nebo by musel hardwarový klíč začít vyrábět. Proti prvnímu případu se dá účinně bránit a v druhém případě by crackera zkopírování struktury hardwarového klíče a vytvoření stejného stálo víc peněz než si koupit legální verzi programu. Nejznámějšími typy hardwarových klíču jsou HASP a Sentinel. Rozdíly mezi nimi jsou jen minimální. Pro hardwarový klíč se v současnosti používá nejvíce USB port a dříve to byl paralelní port.
Kontrola originálního CD
Když se začaly distribuovat aplikace na CD, tak stálo prázdné CD 150 Kč a vypalovací mechanika až 10 000 Kč. V této době byla kontrola originálního CD zbytečná, ale postupem času se začaly ceny vypalovacích mechanik i médií rapidně zmenšovat a začalo se s vypalováním CD, řekl bych, jak ho známe dnes. Začal se také velice rychle rozvíjet Internet a připojení bylo čím dál rychlejší, a to byl signál, aby se začaly kopie her šířit přes Internet. Většinou se jednalo o tzv. ripy her (hry jejichž velikost byla minimalizována). V této chvíli začala být kotrola originálního CD opravdu důležitá, protože vývojáři přicházeli o miliardy. Proti ripům her bojovali vývojáři tím, že kontrolovali přítomnost těch částí programu, které považovali za zbytné, pro crackery tedy kořist. Druhou možností boje proti ripům her bylo vytvořit na CD jeden gigantický soubor, ze kterého se vše instalovalo. Postupem času začal boj proti ripům her ztrácet smysl, protože připojení k Internetu začala být velice rychlá a nějakých 100 MB navíc znamená jen několik desítek minut. Proti vypalování CD je velké množství technik, ale pravděpodobně nejúčinnější jsou errory na CD. Jedná se o úmyslně vytvořené chyby, které ztěžují vypalovacím mechanikám práci. Program pak kontroluje přítomnost těchto errorů a záludnost spočívá v tom, že je může kotrolovat náhodně (třeba během hraní hry). Například zkuste vytvořit zálohu hry Diablo II. Šanci na úspěch máte, pokud budete vypalovat rychlostí 1x (úspěch jsem měl až na třetí pokus). Pokud se vám to podaří, tak jste překonali SecuRom. Tato ochrana byla vytvořena firmou Sony a je předchůdcem SafeDiscu.
SafeDisc
V současnosti je to nejrozšířenější typ ochrany CD. Tato komerční ochrana pochází z dílny společnosti C-Dilla. Před vydáním první hry chráněné SafeDiscem tvrdili její tvůrci, že je nepřekonatelná, ale již týden na to se objevila její pirátská verze, ale v současnosti neexistuje adekvátní náhrada. Přítomnost SafeDiscu se dá zjistit přítomností souborů 00000001.TMP, CLCD16.DLL, CLCD32.DLL, DPLAYERX.DLL a CLOKSPL.EXE na CD. Dále je na CD hlavní EXE soubor a ještě soubor s příponou ICD. V souboru EXE se nachází samotná ochrana, která dekomprimuje soubor ICD. Dále obsahuje několik anti-debugových triků, ale na ochranu takového formátu jsou dost slabé. Většina se zaměřuje na debugger Soft-Ice (blíže v další lekci). Velice silným anti-debugovým prvkem byl trik s debug registrem, ale ten musel být kvůli nekompatibilitě s Windows XP odstraněn. Na CD chráněném SafeDiskem se nalézá velké množství errorů.
Další ochrany už jen jmenovitě: VOB (nejvážnější konkurent SafeDiscu), LaserLoc, SafeCast, CD-Cops, DiscGuard
Často používané API funkce: CreateFile, GetDiskFreeSpace, GetDriveType, GetFullPathName, GetLogicalDrives, GetLogicalDriveStrings, GetVolumeInformation
Demo
Asi každý z nás zná klasická demíčka her, kdy si zahrajete jednu misi s jedním autem a konec. Jedninou možností je si koupit plnou verzi aplikace.
Ochrana naprogramovaná ve Visual Basicu nebo Delphi
V tomto případě je ochranou samotný programovací jazyk. Pokud se budete snažit v debugeru krokovat kód napsaný ve Visual Basicu, tak budete potřebovat velice pevné nervy a dostatek času. Kód Visual Basicu je v debugeru převeden do pseudoinstrukcí a většinu času budete trávit v systémových knihovnách. Část crackerů, když vidí kód ve Visual Basicu, tak radši zklamaně nechá program na pokoji. Zde je ukázka zdrojového kódu.
CALL NEAR DWORD PTR DS:[<&MSVBVM60.__>; MSVBVM60.__vbaHresultCheckObj
XOR EAX, EAX
CMP WORD PTR SS:[EBP-3C], 1
LEA ECX, DWORD PTR SS:[EBP-18]
SETE AL
NEG EAX
MOV EDI, EAX
CALL NEAR DWORD PTR DS:[<&MSVBVM60.__>; MSVBVM60.__vbaFreeObj
CMP DI, BX
MOV DWORD PTR SS:[EBP-30], 1
MOV DWORD PTR SS:[EBP-38], 2
JE SHORT IDCrackM.0040E6EA
ADD ESI, 44
LEA ECX, DWORD PTR SS:[EBP-38]
PUSH ESI
LEA EDX, DWORD PTR SS:[EBP-28]
PUSH ECX
PUSH EDX
CALL NEAR DWORD PTR DS:[<&MSVBVM60.__>; MSVBVM60.__vbaVarAdd
MOV EDX, EAX
MOV ECX, ESI
CALL NEAR DWORD PTR DS:[<&MSVBVM60.__>; MSVBVM60.__vbaVarMove
LEA ECX, DWORD PTR SS:[EBP-28]
CALL NEAR DWORD PTR DS:[<&MSVBVM60.__>; MSVBVM60.__vbaFreeVar
JMP SHORT IDCrackM.0040E706
ADD ESI, 44
LEA EAX, DWORD PTR SS:[EBP-38]
PUSH ESI
LEA ECX, DWORD PTR SS:[EBP-28]
PUSH EAX
PUSH ECX
CALL NEAR DWORD PTR DS:[<&MSVBVM60.__>; MSVBVM60.__vbaVarSub
MOV EDX, EAX
MOV ECX, ESI
CALL NEAR DWORD PTR DS:[<&MSVBVM60.__>; MSVBVM60.__vbaVarMove
MOV DWORD PTR SS:[EBP-4], EBX
PUSH IDCrackM.0040E724
JMP SHORT IDCrackM.0040E723
LEA ECX, DWORD PTR SS:[EBP-18]
CALL NEAR DWORD PTR DS:[<&MSVBVM60.__>; MSVBVM60.__vbaFreeObj
LEA ECX, DWORD PTR SS:[EBP-28]
CALL NEAR DWORD PTR DS:[<&MSVBVM60.__>; MSVBVM60.__vbaFreeVar
RETN
RETN
MOV EAX, DWORD PTR SS:[EBP+8]
PUSH EAX
; atd.
Pravda, debugování ve Visual Basicu se dá zjednodušit pomocí speciálních debugerů, které dokáží převést kód zpět do Visual Basicu, ale výsledek bývá velice často nepřesný. Jak vidíte v ukázce zdrovového kódu, tak i na věci, které by zvládl Assembler nebo C bez jakékoliv API, je VB používá. Ochrana ve Visual Basicu má také stinné stránky. Tou největší je jednoduchost odstranění ochrany pokud se vám povede ji nalézt. Visual Basic vás většinou o špatně zadaném registračním čísle informuje pomocí API funkce rtcMsgBox (v debugeru může být označena i jako #595). Pokud ji naleznete, tak není problém se vrátit v kódu zpět a najít API, která porovnává proměnné (nejčastěji používané: vbastrcomp, vbastrcmp, vbavartsteq). V tvorbě ochran platí pravidlo, že čím nižší programovací jazyk, tím lepší ochrana. Je to vcelku logické. Assembler postupuje po malých krůčcích, zato třeba C postupuje mílovými kroky.
// kód v jazyce C
for (int i=0; i < 20; i++) {
// nějaký kód
}
; tentýž kód v jazyce Assembler
MOV EAX, 0
FOR_CYKLUS:
CMP EAX, 20
JNL KONEC
INC EAX
; nějaký kód
JMP FOR_CYKLUS
KONEC:
; nějaký kód
Komprese a kódování programů
V současné době je téměř každý program, který není freeware nebo OpenSource chráněn PE šifrérem/kompresorem. Na téma PE šifrérů/kompresorů věnuji samostatnou kapitolu, až budete znát něco o PE souborovém systému, protože do té doby nemá cenu něco o této ochraně vysvětlovat. Zatím se spokojte s neobratným vysvětlením, že PE šifrér/kompresor šifruje kód programu.
Několik rad pro lepší ochranu programů
› Neupozorňujte uživatele o špatně napsaném registračním čísle hlášením, ale raději způsobte pád programu (například pomocí dělení nulou) nebo počkejte tak deset sekund než uživateli sdělíte jestli je registrační číslo správné.
› Svůj program šifrujte a používejte vlastní anticrackingové metody (nespoléhejte se na ty, co nabízí PE šifrér/kompresor).
› Používejte v aplikacích kontrolní součet programu a zabráníte tak změnám kódu (můžete použít API funkci MapFileandCheckSum, která je v knihovně imagehlp.dll)
› Používejte více kontrolních bodů. Například při ochraně časovým limitem si vytvořte více úložišť data instalace.
› Důležité je, aby registrační číslo nikdy nebylo volně v paměti.
› Nepřehánějte to s ochranami a dávejte pozor, aby ochrany nezpůsobovaly bezdůvodně chybová hlášení.
› Pokud program zjistí, že je aktivní debugger, tak nejdřív slušně požádejte o deaktivaci a uložte si někam, že je debuger aktivní, a pokud ho najdete znova, tak už to není náhoda a způsobte pád programu (metody nalezení debuggeru budeme zkoumat v další lekci).
Tak toto by byl úvod k problematice crackingu. Seznámil jsem vás s nejrozšířenějšími typy ochran a snažil jsem se vám ukázat nějaké ochranné prvky, které v nich mohou být. Mým cílem je, aby tento kurz byl užitečný jak vývojářům, kteří chtějí chránit svůj software, tak těm, kteří chtějí začít s crackingem. V příští lekci se naučíte zacházet s debuggerem v praxi (speciálně pro příští lekci vytvořím nějaké crackme).