RE FORUM
[REVERSE ENGINEERING] => Programming => Topic started by: NeptuN on September 22, 2010, 11:32:24 PM
-
Ahoj lidi, mam par dalsich dotazu. Zacal jsem psat keygen (ano, driv jsem se uchyloval k potupnemu patchovani ci jen generovani hesla pro svuj nickname :-[ ) a narazil jsem na nasledujici elementarni problemy, ktery asi resil kdysi kazdy z vas.
1. V cem je vlastne nejlepsi keygeny psat?
2. Znate nejake dobre finty/rady/zasady pro psani keygenu?
Ja jsem pouzil C++ implementovane v DevC++. Potiz je v tom, ze jsem pak ze zvedavosti nakouknul do ollyho a malem me trefilo. Jeden maly cyklus s jednim xorovanim byl zkompilovan do neceho odpornyho, malem jsem ani ten svuj extremne primitivni program nepoznal. Vazne, nic sloziteho, i/o pomoci prikazove radky, takze zadna graficka byrokracie apod. Presto to zkompilovalo do programu s padesati cally a subcally, a navic kdyz jsem se podival po svych prommennych a do pameti ... no proste des a hruza. Samozrejme chapu, ze kazdy program musi obsahovat dalsi balast a byrokracii, ktera ma sve opodstatneni a kterou ja nyni nechapu, ale tohle? Kdyz jsem se zameril konkretne na ten jeden muj malinkatej cyklus, katastrofa. Pro ilustraci ho zde uvadim ve trech verzich: cme, moje c++, muj keygen v ollym. Za kazdou radu ci pripominku budu vdecny. :)
Cyklus ze cme (pravdepodobne psane v masm, k tomu bych se chtel priblizit)(za zminku stoji fakt, ze promenne jsou ulozeny v DS)
Address Hex dump Command Comments
00401176 |. 33F6 XOR ESI,ESI
00401178 |. 33C0 XOR EAX,EAX
0040117A |> 8A0C16 /MOV CL,BYTE PTR DS:[EDX+ESI]
0040117D |. 8AD9 |MOV BL,CL
0040117F |. 3298 28634000 |XOR BL,BYTE PTR DS:[EAX+406328]
00401185 |. 40 |INC EAX
00401186 |. 83F8 05 |CMP EAX,5
00401189 |. 881C32 |MOV BYTE PTR DS:[ESI+EDX],BL
0040118C |. 8888 27634000 |MOV BYTE PTR DS:[EAX+406327],CL
00401192 |. 75 02 |JNE SHORT 00401196
00401194 |. 33C0 |XOR EAX,EAX
00401196 |> 46 |INC ESI
00401197 |. 3BF5 |CMP ESI,EBP
00401199 |.^ 72 DF \JB SHORT 0040117A
DS[EDX] obsahuje nickname o delce ulozene v EBP
DS[406328] obsahuje specifickej retezec zadany programatorem
Ten samy cyklus z meho keygenu v Dev C++
char cStringForEncryption[19] = {'\xaa','\x89',...'\x73'};
int iNicknameLength = 0;
char *pNickname;
pNickname = &(sNickname[0]);
iNicknameLength = lstrlen(pNickname);
int iI = 0,iJ = 0;
char cTemp;
do{
cTemp = sNickname[1+iJ];
sNickname[1+iI] = sNickname[1+iI]^cStringForEncryption[0+iJ];
cStringForEncryption[0+iJ] = cTemp;
iI++;
if(iI==5) iI=0;
iJ++;
}while(iJ < iNicknameLength);
Ten samy cyklus z meho keygenu v Ollym (preskocil jsem umornou inicializaci prommenych v SS)
Address Hex dump Command Comments
0040141F |> /8B45 C8 /MOV EAX,DWORD PTR SS:[EBP-38]
00401422 |. |40 |INC EAX
00401423 |. |894424 04 |MOV DWORD PTR SS:[ESP+4],EAX
00401427 |. |8B45 0C |MOV EAX,DWORD PTR SS:[EBP+0C]
0040142A |. |890424 |MOV DWORD PTR SS:[ESP],EAX
0040142D |. |E8 3EDC0200 |CALL 0042F070
00401432 |. |0FB600 |MOVZX EAX,BYTE PTR DS:[EAX]
00401435 |. |8845 C7 |MOV BYTE PTR SS:[EBP-39],AL
00401438 |. |8B45 CC |MOV EAX,DWORD PTR SS:[EBP-34]
0040143B |. |40 |INC EAX
0040143C |. |894424 04 |MOV DWORD PTR SS:[ESP+4],EAX
00401440 |. |8B45 0C |MOV EAX,DWORD PTR SS:[EBP+0C]
00401443 |. |890424 |MOV DWORD PTR SS:[ESP],EAX
00401446 |. |E8 25DC0200 |CALL 0042F070
0040144B |. |89C3 |MOV EBX,EAX
0040144D |. |8B45 CC |MOV EAX,DWORD PTR SS:[EBP-34]
00401450 |. |40 |INC EAX
00401451 |. |894424 04 |MOV DWORD PTR SS:[ESP+4],EAX
00401455 |. |8B45 0C |MOV EAX,DWORD PTR SS:[EBP+0C]
00401458 |. |890424 |MOV DWORD PTR SS:[ESP],EAX
0040145B |. |E8 10DC0200 |CALL 0042F070
00401460 |. |89C2 |MOV EDX,EAX
00401462 |. |8D45 F8 |LEA EAX,[EBP-8]
00401465 |. |0345 C8 |ADD EAX,DWORD PTR SS:[EBP-38]
00401468 |. |83E8 20 |SUB EAX,20
0040146B |. |0FB600 |MOVZX EAX,BYTE PTR DS:[EAX]
0040146E |. |3202 |XOR AL,BYTE PTR DS:[EDX]
00401470 |. |8803 |MOV BYTE PTR DS:[EBX],AL
00401472 |. |8D45 F8 |LEA EAX,[EBP-8]
00401475 |. |0345 C8 |ADD EAX,DWORD PTR SS:[EBP-38]
00401478 |. |8D50 E0 |LEA EDX,[EAX-20]
0040147B |. |0FB645 C7 |MOVZX EAX,BYTE PTR SS:[EBP-39]
0040147F |. |8802 |MOV BYTE PTR DS:[EDX],AL
00401481 |. |8D45 CC |LEA EAX,[EBP-34]
00401484 |. |FF00 |INC DWORD PTR DS:[EAX]
00401486 |. |837D CC 05 |CMP DWORD PTR SS:[EBP-34],5
0040148A |. |75 07 |JNE SHORT 00401493
0040148C |. |C745 CC 00000 |MOV DWORD PTR SS:[EBP-34],0
00401493 |> |8D45 C8 |LEA EAX,[EBP-38]
00401496 |. |FF00 |INC DWORD PTR DS:[EAX]
00401498 |. |8B45 C8 |MOV EAX,DWORD PTR SS:[EBP-38]
0040149B |. |3B45 D4 |CMP EAX,DWORD PTR SS:[EBP-2C]
0040149E |. |7D 05 |JGE SHORT 004014A5
004014A0 |.^\E9 7AFFFFFF \JMP 0040141F
Komentar k cyklum: mam dva retezce, jednim je zadany nick, druhy je specifickej retezec zadanej programatorem. Po bitu je mezi sebou xoruji, ze specifickeho retezce pouzivam jen prvnich pet znaku, pak jedu znova. Vysledek prepisuje nickname pote, co nickname prepsal specifickej retezec (proste oba retezce se meni, ani jeden z nich neni nemenny)
Nevim, jestli jsem to napsal blbe ja nebo to lepsi proste nebude. Uprimne doufam v prvni moznost.
Neexistuji nejake figly, jak kompileru rici, ze se jedna o opravdu jednoduchy program a neni treba brat na vrabce delo? Dale me dost vytaci, ze program uklada zminovane retezce v SS (zaplatpanbuh ze aspon citace cyklu uklada do registru). Cmecko to ukladalo do DS, s cimz se dobre pracovalo a bylo to tisickrat prehlednejsi. Konkretne pro tento keygen je to prkotina, ale v budoucnu se chci vyvarovat moznym problemum a psat sve programy pokud co mozna nejjednoduseji a nejcitelneji a obecne nejlepe (uz nyni se snazim je vystizne komentovat, vystizne pojmenovavat promenne apod.). Ukladani vetsich promennych do zasobniku se mi vubec nelibi (ten retezec byl mnohem delsi nez 5 znaku ). Uz na vysce do nas tloukli, ze zasobnik muze zradit, koneckoncu pro to existuji pseudozasobniky tvorene spojovymi seznamy...
Vazne uvazuji o tom, ze zacnu psat keygeny v starym dobrym assm... ???
-
1. V cem je vlastne nejlepsi keygeny psat?
Podla toho kolko mas casu :-) v asm ti to zabere asi najviac casu, v prog. jazykoch (C#,VB,DELPHI) to mas natukane za chvilu (aspon co sa tyka designu)
2. Znate nejake dobre finty/rady/zasady pro psani keygenu?
skus si stiahnut dake templaty a tie modifikovat, na nete je toho plno, nebudes stracat cas s niecim co uz je. Zaklad je aby kg isiel na vacsine masin. Stretol som sa s tym, ze stare kg nesli na novsich win alebo boli spravene v .NET frameworku 1.0 a v dnesnej dobe su nespustitelne ...
Presto to zkompilovalo do programu s padesati cally a subcally
pokial to nerobis v asm tak nic nove :-))
Neexistuji nejake figly, jak kompileru rici, ze se jedna o opravdu jednoduchy program
vacsinou sa daju nastavit rozne optimalizacie pri kompilaci (v zavislosti od jazyka, rozne overflow checky, speed/size optimization atd)
uvazuji o tom, ze zacnu psat keygeny v starym dobrym asm
toto ma vyhodu v tom ze sa daju vyuzit rozne rippery, a teda s original app si ripnes cele procky, kt vlozis do tvojeho kg, prisposobis a uz len zavolas - usetris cas s pisanim kedze vyuzijes na kontrolu/generovanie original proceduru
-
na nete mas x asm keygen templatov, nahodis to tam a mas. dobra rada, ze?? :D :D
-
Dik za rady. Rozhodl jsem se. Algoritmus budu psavat v assm (napr. jako knihovnu) a ostatni balast a byrokracii (napr. GUI, pokud bude treba) budu psavat v C++, ze ktere budu tech par procek volat. Tim padem zkombinuji vyhody obou: ripovani z cmecek i jednoduchost vyssiho programovaciho jazyka. :)
Jeste se mrknu na ty templaty, ty me nenapadly. Rozhodne ze zacatku nejaky pouziju a casem si z nich vytvorim vlastni template. :)
-
ja pisu zasadne v ASM , na ruzne gui mam template akorat vyripuju procedury na generovani cisla aje vymalovano :)
-
tak tak, naripuj nieco v asme(uprav si to podla svojej potreby), buchni to do masmu a je to. neni o com, no a, alga sa vzdy pisu lepsie v asme(aspon pre mna urcite) ;)
-
Dulezity je pochopit vo cem zkoumany algo je. V cem pak vytvoris KG je uplne jedno. Nejlepsi je stejne nakonec pouzit obycejny patchovani (nebo jen zmenu priznakovyho registru), nic se mu nevyrovna. Vzdycky jsem se vod srdce zasmal, kdyz jsem videl pouzite API ve stylu CreateCipher, InitCipher, CipherIsManFromMatrixMovie,... (viz. treba Excel a jeho ochrana Add-ins), kdyz se na koncu objevi rozhodovacka JZ ;D.
Ve vysledku stejne neni dulezity pochopit kazdou instrukci, ale mit pri dnesnim zaprasenym kodu prehled a po rychlym precteni kodu zmenit par instrukci. Navic se cim dal casteji objevuji (aspon teda doufam) "po nekolika letech vypoctu prolomitelna" alga, a v tuhle chvili stejne prichazi patchovani. Na KG se vykasli. Venuj se programovani uzitecnejsich veci.
-
Nejlepsi je stejne nakonec pouzit obycejny patchovani
Nejhorsi veta kterou jsem za posledni dobu cetl, Cracking neni o produkovani patchovani, to uz se na to muzes uplne vysrat. sKAMERa na tebe !! :-).
howg
-
.sKAMERa na tebe !! :-).
Novacci nevi "co to je" ;) (abys je zbytecne nedesil............. ;D )
-
sK je uz po smrti.
-
Novacci nevi "co to je" ;) (abys je zbytecne nedesil............. ;D )
Co to tedy je? ??? (pan google nepomohl :-\ )
-
Spatne si hledal - napis to takto "sKAMER DeLEBRE" .
btw - pr0p4g4nd4 tos myslel jak?
-
Co to tedy je? ??? (pan google nepomohl :-\ )
je to druh syra.
btw - pr0p4g4nd4 tos myslel jak?
ja nemyslim - proste sa mi to ziadalo poznamenat.
-
Spatne si hledal - napis to takto "sKAMER DeLEBRE" .
Dik za napovedu. Udelal jsem svuj du (alespon doufam, to zhodnotte vy ostatni :-\ ), tedy shrnuti i pro ostatni (ne pr0pi, druh syra to opravdu asi nebude, jedna se totiz o druh čočky ;D )
Prvni zminku jsem (resp. strejda google) nasel na e-zinu crypto-world cisla 4/2005 [1]. V obsahu je zminen rozhovor s nasim clovekem. Stoji za zminku, ze v oficialni databazi tohoto casopisu [2] tak nejak tato polozka v obsahu zmineneho cisla zahadne zmizela ... ::)
Dalsi zminku jsem nasel v jiz o neco mladsi diskuzi z roku 2008 o unpackeru pro armadillo [3][4]. Jeden z komentujicich naznacil, ze tenhle chlapik dokazal rozlustit tuto ochranu. Na exetools jsem nasel dokonce jeho prispevek z roku 2003 prave s resenim armadilla [5]. Takze clovek z branze s dobrymi znalostmi ohledne crypto a jineho packovani.
Posledni zminku jsem nasel o slovniku Diderot, ktery byl pravdepodobne "vylusten" opet timto chlapikem [5].
Suma sumarum, ohledne pouziti strejdou Hypnotixem bych tipoval asi na znamou autoritu v oblasti crypto a packovani?
[1] http://crypto-world.info/klima/2005/crypto_world_2005_04_02_11.pdf
[2] http://crypto-world.info/casop7/crypto04_05.pdf
[3] https://www.openrce.org/blog/view/1073/Armadillo_v.5_x64_Unpacking_tutorial
[4] http://www.woodmann.com/crackz/Packers.htm
[5] http://forum.exetools.com/showthread.php?t=2144
[6] http://www.harryho.info/diderot.htm
-
haha, mna si nevsimajte, mam svoje dni ;D
-
Par poznámek k tomu tvojemu rozčilování.
Neexistuji nejake figly, jak kompileru rici, ze se jedna o opravdu jednoduchy program a neni treba brat na vrabce delo?
Ten "odpornej" kód, do kterýho se ti to skompilovalo, je nejspíš inicializace CRT (na Windows msvcr*.dll). Možná jde nějak kompileru říct, ať CRT nepoužívá, ale nikdy jsem to nezkoušel.
Dale me dost vytaci, ze program uklada zminovane retezce v SS (zaplatpanbuh ze aspon citace cyklu uklada do registru). Cmecko to ukladalo do DS, s cimz se dobre pracovalo a bylo to tisickrat prehlednejsi.
To je tím, že používáš auto proměnný, který mají platnost jenom v daným bloku (u tebe to bude nejspíš main()). Z toho důvodu kompiler používá zásobník (aspoň na architektuře x86), protože přes ten toho jde docílit nejjednodušším a nejrychlejším způsobem. Počítám, že kdybys tam našel na začátku každé funkce volání alokace paměti a na konci dealokace, taky by se ti to nelíbílo. Pokud to nutně potřebuješ uložit "do DS" (nechápu ale proč - chceš to snad debugovat na úrovni asm?), použij třídu static. Tím ale zase zvětšuješ paměťový nároky programu v době jeho spouštění.
Ukladani vetsich promennych do zasobniku se mi vubec nelibi (ten retezec byl mnohem delsi nez 5 znaku ). Uz na vysce do nas tloukli, ze zasobnik muze zradit, koneckoncu pro to existuji pseudozasobniky tvorene spojovymi seznamy...
Že zásobník může zradit je pravda, ale je to hlavně teorie. Většina programů je napsaná "normálním" způsobem, a kolikrát zažils, že by ti nějakej program spadnul se STATUS_STACK_OVERFLOW (http://msdn.microsoft.com/en-us/library/ff558784%28VS.85%29.aspx)? Já za posledních několik let ani jednou. (Je pravda, že nějaký unixový tooly skompilovaný pro Windows mě občas padají dost záhadně, ale tam to spíš bude narušením paměti, než přeplněním zásobníku).
Tím "normálním" způsobem myslím to, že každá funkce si pro svoje auto proměnný ukousne pořádnej kus stacku; navíc auto proměnný vytváří kompiler sám pro svoje potřeby, protože registrů je relativně málo.
-
Ten "odpornej" kód, do kterýho se ti to skompilovalo, je nejspíš inicializace CRT (na Windows msvcr*.dll). Možná jde nějak kompileru říct, ať CRT nepoužívá, ale nikdy jsem to nezkoušel.
Asi to tim bude. Tento problem, vlastne tak jako vsechny ostatni, odpada programovanim v assmu, jak jsem avizoval. Spis jsem asi naivne predpokladal, ze dnesni automaticka optimalizace dokaze prekonat cloveka. Ocividne to v pripade kompileru z devc++ neplati.
Pokud to nutně potřebuješ uložit "do DS" (nechápu ale proč - chceš to snad debugovat na úrovni asm?), použij třídu static. Tím ale zase zvětšuješ paměťový nároky programu v době jeho spouštění.
Samozrejme jsem si vedom, ze to zabere pamet, nicmene pri dnesnich technickych parametrech pocitacu v tom nevidim (pro keygen) problem. Duvod je presne ten, ktery jsi zminil: chci to debuggovat na urovni assm. Koneckoncu pri psani keygenu se to da ocekavat, nebot v pripade, ze prime ripovani procedury z nejakeho duvodu nebude mozne (a i kdyby bylo, tak pro kontrolu se to hodi), pak pri rucnim psani je u slozitejsich algoritmu temer nemozne to trefit napoprve. A pak hledej chybky pri nejakem sifrovani ci jinych hratkach s binarnimi retezci. Ve vyssich jazcich prakticky nemozne. Rozhodne promenne v DS usetri spoustu neprijemnosti. Ten trik se static me nenapadl (i kdyz toto klicove slovo obcas pouzivam), vyzkousim. :)