Zpět na seznam článků     Číst komentáře (7)     Verze pro tisk

Cracking4neWBies - Lekce č.15

Autor: DjH   
19.10.2007

Cracking pro začátečníky...popatnácté :-)


Cracking4neWBies

Lekce č.15

Cracknutí dalšího prográmku - VirtualDj



Balík zde (VirtualDj 4.2 si stáhnete třeba ze Stahuj.cz)

Asi tři díly jsme probíraly patchy a programování cracků, jako takových. Dlouho jsme si ale nic necrackli, hm, co říkáte? :)
Tak to teď jdu napravit. Znáte prográmek VirtualDj od firmy AtomiX? Je to paráda, po spuštění se před Vámi objeví mixážní pult, a je jen na Vás, co budete mixovat. Nebo můžete jen experimentovat, nebo si jen tak přehrávat hudby :). Myslím, že by tento program měla znát většina z Vás. Jinak ještě neplacená reklama: www.virtualdj.com :). (jen tak mimochodem…byl i na CD od Světa počítačů(5/2oo7)…)
Tento program je vyvíjen poměrně již dlouhou dobu, možná i přes 5 let. Aktuální je verze 4.3 (v době psaní článku). Tu já bohužel nemám, ale mám verze 2.0;2.1;3.0;3.1;4.0;4.1;4.2. Proč to říkám, se dozvíte za chvíli :)
Vše co tady budu provádět, bude na verzi 4.2. Instalační program VDJ zabírá 18.9 MB.
Takže…
Pokud bude pátrat po informacích o VDJ, zjistíte, že Atomix vydává VDJ jako 20ti denní trial. Po uplynutí této doby program sice spustíte, ale po dvou minutách se automaticky vypne.
Snad už máte VDJ v4.2 nainstalovaný, jestli ne, učiňte tak prosím =). V licenčních podmínkách ignorujte prosím tyto řádky:
This license does NOT allow you to:
- decompile, reverse engineer, disassemble, or otherwise reduce the Software to a human-perceivable form.
=) a klikněte na „I accept“ =)…
Po nainstalování zjistíme, že už jen samotná binárka virtualdj_trial.exe má 8.81 MB. Bude to teda pěkný maso vyznat se v 9 milionech znaků :).
(btw: zkoušel jsem to packovat UPXem, packovalo se to asi minutu a soubor se zkomprimoval na 1.7 MB (--best), potom ještě Upackem, to je podle mě nejlepší z nejlepších EXE packerů, je i v balíku, tím se to zkomprimovalo na 1.56MB. Nevím proč ten soubor nezkomprimovali, ale je to jen můj názor který jsem chtěl mermomoci prosadit :))
Podíváme se, co nám ukáže PEiD, a hle, je to jak jinak než Visual C++. Nyní si už konečně soubor otevřeme v Ollym. Jak již jsem říkal, program se po uplynutí 20ti zkušebních dnů po DVOU minutách sám vypne. Jelikož nám to ani žádná message neoznámí, že jsme už „vyčerpali“ všechny dny, budeme muset najít funkci, tedy nastavení nějakého časového intervalu. Tu má na starost WinAPI „SetTimer“, v knihovně USER32.DLL. Pokud chceme Timer zrušit, použijeme WinAPI KillTimer, najdete to ve WinAPI příručce, ale to teď není důležité :), teď je důležité najít ten hlavní „SetTimer“. Takže hon na SetTimer začneme asi takto: Klikneme v Ollym na asm kód pravým myšítkem, a zvolíme „Search for“ -> „All intermodular calls“. Bingo, objeví se nám všechny cally a WinApi, na které program volá. Seřadíme si je podle „Destination“ a sjedeme dolů, někam k „S“, a tam už SetTimer najdeme :). No jo, SetTimer se tu ale objevil 34x! Vezmeme to teoreticky… Můžeme předpokládat, že se timer spustí hned při startu, nebo hned po něm. Můžeme tedy nastavit BP na všechny CALLy, které volají Api „SetTimer“. Uděláme to tak, že na obrazovce s asm kódem [C], stiskněte kombinaci [Ctrl + N]. Najděte si Call na USER32.SetTimer, označte ho, klikněte na něj „pravým“, a klikněte na „Set breakpoint on every reference“. Teď se Vám na všechny cally na tuto api, nastavily breakpointy. Nezbývá nám nic jiného, než aplikaci spustit, a doufat, že se nějaký breakpoint „chytne“ :)…
Po chvilce se vážně Olly zastavil na breakpointu. Není to vlastně ani call, je to přesun adresy callu na SetTimer, do registru ESI:

0041868E |. 57 PUSH EDI ; |hWnd
0041868F |. FF15 D8836E00 CALL NEAR DWORD PTR DS:[<&SHELL32.Dra>; \DragAcceptFiles
00418695 |. 8B15 947CB100 MOV EDX, DWORD PTR DS:[B17C94]
0041869B |. 8B35 24846E00 MOV ESI, DWORD PTR DS:[<&USER32.SetT>; USER32.SetTimer
004186A1 |. 6A 00 PUSH 0 ; /Timerproc = NULL
004186A3 |. 6A 32 PUSH 32 ; |Timeout = 50. ms
004186A5 |. 68 A0000000 PUSH 0A0 ; |TimerID = A0 (160.)
004186AA |. 52 PUSH EDX ; |hWnd => 003F0922 ('VirtualDJ',class='VIRTUALDJ')
004186AB |. FFD6 CALL NEAR ESI ; \SetTimer
004186AD |. A1 947CB100 MOV EAX, DWORD PTR DS:[B17C94]
004186B2 |. 6A 00 PUSH 0 ; /Timerproc = NULL
004186B4 |. 68 C1D40100 PUSH 1D4C1 ; |Timeout = 120001. ms
004186B9 |. 68 9F000000 PUSH 9F ; |TimerID = 9F (159.)
004186BE |. 50 PUSH EAX ; |hWnd => 003F0922 ('VirtualDJ',class='VIRTUALDJ')
004186BF |. FFD6 CALL NEAR ESI ;\SetTimer
004186C1 |. 833D 647DA400>CMP DWORD PTR DS:[A47D64], 0
004186C8 |. 74 04 JE SHORT virtuald.004186CE
004186CA |. 33C0 XOR EAX, EAX


Takže je to přece jenom ono :), je to trochu skrytější funkce, protože to není přímý call, ale oklikou přes adresu v ESI. Na adrese 004186B4 můžeme vidět, jak se PUSHuje ten dvouminutový interval, resp. 120 tisíc tisícin :), a na adrese 004186BF se už z ESI volá Api SetTimer.
Teď ale jak to patchnout. Máme více možností, můžeme třeba všechny pushování a následný CALL ESI vyNOPovat, ale je to zbytečně složité. Myslím si, že lepší by bylo si na adrese 004186B2 udělat odskok až za CALL ESI, takže se vlastně timer nenastaví. Poklepeme na instrukci „PUSH 0“ na adrese 004186B2 a přepíšeme ji na „JMP 004186C1“. Bajty 6A 00 (PUSH 0) se nahradily za EB 0A (JMP +$0D (+14)). Nyní restartujeme aplikaci [Ctrl + F2], najedeme do záložky Patches [/], dáme naše patchlé byty do stavu [Active], odstraníme všechny breakpointy, a necháme jen ten na adrese 0041869B. Spustíme aplikaci [F9]. A hle! Ani po dvou minutách se nevypne :). Docela to ale pořád kazí po spuštění ten nápis „Trial: X days left“. Co si tam napsat něco jako „Cracked by DjH2oo7“?! Jak to udělat? Klikněte do oblasti RamDump pravým tlačítkem, a zvolte „Search For“ -> „Binary String“. Nebo můžete použít klávesovou zkratku [Ctrl + B] :). Tam zadejte třeba slova „days left“ a klikněte na tlačítko OK. Pokud se nic nenajde, asi nejste v oblasti s daty. V tom případě klikněte pravým na RamDump, a zvolte „Go to“ -> „Expression“, a zadejte „006E8000“ bez uvozovek. Zde začínají data. Jak jsem k tomu došel? Podívejte se v části s asm kódem, úplně dolů. Co vidíte za adresu? „006E7FFF“. No a hned bajt za tím jsou data :)… Pokud jste string našli, označte ho celý:

006F2CB6 54 72 69 61 6C 3A 20 25 69 20 Trial: %i
006F2CC6 64 61 79 73 20 6C 65 66 74 00 days left.

Až ho označíte, klikněte na něj pravým, a zvolte „Binary“ -> „Edit“ popřípadě [Ctrl + E]. Místo stringu Trial…blabla… Napište třeba „Cracked by DjH2oo7“. Ovšem string musí končit hexnulou. Takže po znaku „7“ najeďte do části kde se zapisují data hexadecimálně, a za „sedmičku“ napište „00“. Může to vypadat třeba takto:

006F2CB6 43 72 61 63 6B 65 64 20 62 79 Cracked by
006F2CC6 20 44 6A 48 32 6F 6F 37 00 00 DjH2oo7..

Pokud bychom si vybrali třeba kratší string, např.: „DjH“, nebyl by problém, kdyby to bylo třeba takto:

006F2CB6 43 72 61 63 6B 65 64 20 62 79 Cracked by
006F2CC6 20 44 6A 48 00 6C 65 66 74 00 DjH.left.

Protože za „H“ je hexnula, tudíž tam string končí, a nikoho to nezajímá =)… S delším stringem by byl už ale problém…

Nyní jdeme na patch, jak jinak než s&r, podle mé Delphi šablony :). Zkusíme si vybrat kus kódu, do toho podle minulého článku přidat na správná místa otazníky ‚??‘ a patch otestovat. Vyberu třeba tento kód:

004186B2 6A 00 PUSH 0
004186B4 |. 68 C1D40100 PUSH 1D4C1 ; |Timeout = 120001. ms
004186B9 |. 68 9F000000 PUSH 9F ; |TimerID = 9F (159.)
004186BE |. 50 PUSH EAX ; |hWnd => NULL
004186BF |. FFD6 CALL NEAR ESI ; \SetTimer
004186C1 |. 833D 647DA400>CMP DWORD PTR DS:[A47D64], 0
004186C8 |. 74 04 JE SHORT virtuald.004186CE
004186CA |. 33C0 XOR EAX, EAX


Hex. data vypadají takto:
6A 00 68 C1 D4 01 00 68 9F 00 00 00 50 FF D6 83 3D 64 7D A4 00 00 74 04 33 C0
Podle minulé lekce už víme, kam nejlépe otazníky dát. Podle mě by to bylo nejlepší takto:
6A ?? 68 ?? ?? ?? ?? 68 ?? ?? ?? ?? 50 FF D6 83 3D ?? ?? ?? ?? ?? 74 ?? 33 C0
A patch bajty:
EB 0D ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ??
Když toto zadám do mého prográmku BTDP4C, vyplivne mi toto:

//6A ?? 68 ?? ?? ?? ?? 68 ?? ?? ?? ?? 50 FF D6 83 3D ?? ?? ?? ?? ?? 74 ?? 33 C0
//EB 0D ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ??

//Created by DjH's BTP4C v0.6
MaxL := 26;
rasd[1] := $6A; rawd[1] := $EB;
rasd[2] := $FFF; rawd[2] := $0D;
rasd[3] := $68; rawd[3] := $FFF;
rasd[4] := $FFF; rawd[4] := $FFF;
rasd[5] := $FFF; rawd[5] := $FFF;
rasd[6] := $FFF; rawd[6] := $FFF;
rasd[7] := $FFF; rawd[7] := $FFF;
rasd[8] := $68; rawd[8] := $FFF;
rasd[9] := $FFF; rawd[9] := $FFF;
rasd[10] := $FFF; rawd[10] := $FFF;
rasd[11] := $FFF; rawd[11] := $FFF;
rasd[12] := $FFF; rawd[12] := $FFF;
rasd[13] := $50; rawd[13] := $FFF;
rasd[14] := $FF; rawd[14] := $FFF;
rasd[15] := $D6; rawd[15] := $FFF;
rasd[16] := $83; rawd[16] := $FFF;
rasd[17] := $3D; rawd[17] := $FFF;
rasd[18] := $FFF; rawd[18] := $FFF;
rasd[19] := $FFF; rawd[19] := $FFF;
rasd[20] := $FFF; rawd[20] := $FFF;
rasd[21] := $FFF; rawd[21] := $FFF;
rasd[22] := $FFF; rawd[22] := $FFF;
rasd[23] := $74; rawd[23] := $FFF;
rasd[24] := $FFF; rawd[24] := $FFF;
rasd[25] := $33; rawd[25] := $FFF;
rasd[26] := $C0; rawd[26] := $FFF;



Ještě musíme nahradit string „Trial…“ za „Cracked by…“. Takže… Hexhodnoty stringu pro vyhledání (Trial):
54 72 69 61 6C 3A 20 25 69 20 64 61 79 73 20 6C 65 66 74 00


A string „Cracked by“:
43 72 61 63 6B 65 64 20 62 79 20 44 6A 48 32 6F 6F 37 00 00
Záměna stringu je takováto:
//54 72 69 61 6C 3A 20 25 69 20 64 61 79 73 20 6C 65 66 74 00
//43 72 61 63 6B 65 64 20 62 79 20 44 6A 48 32 6F 6F 37 00 00

//Created by DjH's BTP4C v0.6
MaxL := 20;
rasd[1] := $54; rawd[1] := $43;
rasd[2] := $72; rawd[2] := $72;
rasd[3] := $69; rawd[3] := $61;
rasd[4] := $61; rawd[4] := $63;
rasd[5] := $6C; rawd[5] := $6B;
rasd[6] := $3A; rawd[6] := $65;
rasd[7] := $20; rawd[7] := $64;
rasd[8] := $25; rawd[8] := $20;
rasd[9] := $69; rawd[9] := $62;
rasd[10] := $20; rawd[10] := $79;
rasd[11] := $64; rawd[11] := $20;
rasd[12] := $61; rawd[12] := $44;
rasd[13] := $79; rawd[13] := $6A;
rasd[14] := $73; rawd[14] := $48;
rasd[15] := $20; rawd[15] := $32;
rasd[16] := $6C; rawd[16] := $6F;
rasd[17] := $65; rawd[17] := $6F;
rasd[18] := $66; rawd[18] := $37;
rasd[19] := $74; rawd[19] := $00;
rasd[20] := $00; rawd[20] := $00;


Tohle si pastneme do našeho zdrojáku, a ještě v šabloně úplně dole, jak se deklarují stringy, musíte změnit proměnnou „nop“ (number of process) na hodnotu 2 (patchujeme dvakrát – SetTimer a String). A proč jsem na začátku říkal že mám všechny ty verze? Jednoduše, na všechny ty verze můj patch funguje :)

Líbil se Vám článek?
Budeme potěšeni, pokud vás zaujme také reklamní nabídka

Social Bookmarking

     





Hodnocení/Hlasovalo: 1.67/9

1  2  3  4  5    
(známkování jako ve škole)