Required tools: Numega's Softice 3.xx
W32Dasm 8.9
Mlotek, przecinak i obcegi ;)
Dzien Dobry! Na dzisiejszych zajeciach dowiemy sie czegos o Terminal Overdrive 98. Jest to program reklamowany jako 'Internet accelerator'. Mozna go spotkac na plycie ze stycznia 1999 magazynu PC World Computer lub pod URL: http://www.digitalrobotics.com Jest to przypadek dosc ciekawy, poniewaz jest to wersja 15-dniowa programu i nigdzie nie ma informacji o tym, ze mozna go zarejestrowac. Dopiero po 15 dniach od zainstalowania (lub po przestawieniu zegara systemowego ;-) po uruchomieniu komputera pojawia sie na ekranie okno :
'The trial period has ended. Please register this software!'
Po czym pojawia sie nastepne:
Please enter the unlock information Name: Company Name: Unlock Code:
Musze sie przyznac, ze nie mialem zbytniej ochoty zajmowac sie tym przypadkiem, ale pewna sprawa poruszyla mnie do zywego. Po wpisaniu falszywych danych wyskoczylo okienko z nastepujaca trescia: 'Would you like to keep using Terminal Overdrive 98?' Po wcisnieciu OK program sie odinstalowal, i zdazyl zakomunikowac: 'Please contact www.digitalrobotics.com', a w dodatku prawie zawiesil mi komputer. (ALT+CTRL+DEL i po 20 sek. pomoglo). Tego juz za wiele! Zrobimy tu 'total unlock code reverse', napiszemy KeyGenerator, a nastepnie wyslemy do DigitalRobotics!
Oczywiscie nie zrobilem tego ostatniego, chociaz bardzo mnie korcilo ;)
Tak jak w poprzednim tutorialu, nie powiem Wam dokladnie co macie robic, a jedynie wyjasnie jak moze wygladac kod przy 'paper protection' (Nie moge sie uwolnic od angielskiego, sorry :)))
Zaczynamy: Po zalozeniu 'bpx Hmemcpy' (nie dziala nic innego) doszedlem do nastepujacego kawalka kodu:
0137:0049FC12 8B45FC MOV EAX,[EBP-04] <-- Twój 'unlock code' 0137:0049FC15 E82E3CFDFF CALL 00473848 <-- ile znaków? 0137:0049FC1A 83F80E CMP EAX,0E <-- porównaj z 0Eh=14 0137:0049FC1D 0F8CEA000000 JL 0049FD0D <-- mniej = bye, bye 0137:0049FC23 8D55E8 LEA EDX,[EBP-18] 0137:0049FC26 8B45FC MOV EAX,[EBP-04] 0137:0049FC29 E8C268FDFF CALL 004764F0 0137:0049FC2E 8B55E8 MOV EDX,[EBP-18] 0137:0049FC31 8D45FC LEA EAX,[EBP-04]
Wiemy, ze 'unlock code' musi sie skladac conajmniej z 14 cyfr/liter... to juz cos!
BTW. 1: Na pytanie 'Would you keep using...' zawsze odpowiadaj NIE, wtedy program sie nie odinstaluje (swoja droga, podchwytliwie sformulowane ;)
2:W32Dasm'a uzyjesz tylko wtedy, gdy przestawisz date systemowa i program nie bedzie chcial sie uruchomic (jeden jnz zalatwi sprawe...)
Patrzcie na ten trick:
0137:0049FC54 B901000000 MOV ECX,00000001 0137:0049FC59 BA02000000 MOV EDX,00000002 0137:0049FC5E E8293EFDFF CALL 00473A8C 0137:0049FC63 8D45FC LEA EAX,[EBP-04] 0137:0049FC66 B901000000 MOV ECX,00000001 0137:0049FC6B BA04000000 MOV EDX,00000004 0137:0049FC70 E8173EFDFF CALL 00473A8C 0137:0049FC75 8D45FC LEA EAX,[EBP-04] 0137:0049FC78 B901000000 MOV ECX,00000001 0137:0049FC7D BA04000000 MOV EDX,00000004 0137:0049FC82 E8053EFDFF CALL 00473A8C 0137:0049FC87 33C0 XOR EAX,EAX 0137:0049FC89 8AC3 MOV AL,BL
Powiedzmy, ze jako Unlock Code wpiszesz '123456789abcdef'. Powyzsze 3 CALLs przeksztalcaja go na '134789abcdef' - zniknela 2, 5 i 6 litera. Co to za obyczaje? Patrz ponizej, co robi z druga i piata litera:
0137:0049FC87 33C0 XOR EAX,EAX <-- czysc EAX 0137:0049FC89 8AC3 MOV AL,BL <-- druga litera 0137:0049FC8B 83E841 SUB EAX,41 <-- odejmij od niej 41 0137:0049FC8E 6BC01A IMUL EAX,EAX,1A <-- mnozymy 0137:0049FC91 33D2 XOR EDX,EDX 0137:0049FC93 8A55EF MOV DL,[EBP-11] <-- piata litera 0137:0049FC96 83EA41 SUB EDX,41 <-- odejmowanie 0137:0049FC99 03C2 ADD EAX,EDX <-- dodaj wynik z 49fc8e 0137:0049FC9B 8B5508 MOV EDX,[EBP+08] 0137:0049FC9E 8902 MOV [EDX],EAX 0137:0049FCA0 33DB XOR EBX,EBX 0137:0049FCA2 8D55F0 LEA EDX,[EBP-10] 0137:0049FCA5 A184574A00 MOV EAX,[004A5784] 0137:0049FCAA E84168FDFF CALL 004764F0
Na co i po co? A co z szósta litera? Jesli chcesz sie dowiedziec, czytaj dalej... A raczej obserwuj kod ;)
0137:0049FCD9 8B45E4 MOV EAX,[EBP-1C] 0137:0049FCDC 8D4DE8 LEA ECX,[EBP-18] 0137:0049FCDF 8BD3 MOV EDX,EBX 0137:0049FCE1 E8BA070000 CALL 004A04A0 0137:0049FCE6 8B55E8 MOV EDX,[EBP-18] <-- twój szczerbaty kod :-) 0137:0049FCE9 8B45FC MOV EAX,[EBP-04] <-- poprawny szczerbaty kod 0137:0049FCEC E8673CFDFF CALL 00473958 <-- porównaj... 0137:0049FCF1 7506 JNZ 0049FCF9 <-- czyzby rózne?!? 0137:0049FCF3 8B45F4 MOV EAX,[EBP-0C] 0137:0049FCF6 C60001 MOV BYTE PTR [EAX],01 0137:0049FCF9 8B4508 MOV EAX,[EBP+08] <-- (*) 0137:0049FCFC 833800 CMP DWORD PTR [EAX],00 0137:0049FCFF 750C JNZ 0049FD0D 0137:0049FD01 807DEE43 CMP BYTE PTR [EBP-12],43<-- (**) 0137:0049FD05 7406 JZ 0049FD0D 0137:0049FD07 8B45F4 MOV EAX,[EBP-0C] 0137:0049FD0A C60000 MOV BYTE PTR [EAX],00 0137:0049FD0D 33C0 XOR EAX,EAX
Ten 'szczerbaty' kod to twój 'unlock code' bez drugiej, piatej i szóstej litery... Bardzo wazna jest linia (*). Porównywana jest wartosc w EAX i 0. Gdy nie sa sobie równe, a szczerbaty kod sie zgadza, twój 'unlock code' jest tzw. 'extended evaluation'- mozesz korzystac dluzej z programu, ale nie jest to wersja w pelni zarejestrowana. W EAX znajduje sie wynik operacji na drugiej i piatej literze, co jest opisane powyzej... Trzeba sie zastanowic, jakie maja byc wartosci tych liter.
Nic trudnego, wymyslilem to po 3 sekundach... przedstawie to jeszcze raz:
Niech x=2 litera, y=5 litera:
1.x-41h = z
2. y-41h=n
z*z*1a = m
Z 1 i 2 'm+n' musi sie równac 0. Najprosciej gdy m i n sa równe 0... zatem: x=41h i y=41h. 41h jest symbolem litery 'A', wiec 2 i 5 litera zawsze beda 'A' - mam nadzieje, ze zrozumieliscie :-)
Linia (**) sprawdza, czy szósta litera to 'C' (a wiec tu to schowali...)
Teraz zajmiemy sie procedura kodujaca: (to bedzie jeszcze trudniejsze) :->
Oto I-sza czesc:
0137:004A04DB 8D45F4 LEA EAX,[EBP-0C] 0137:004A04DE 33D2 XOR EDX,EDX 0137:004A04E0 8AD3 MOV DL,BL 0137:004A04E2 8B4DFC MOV ECX,[EBP-04] 0137:004A04E5 8A5411FF MOV DL,[EDX+ECX-01] <-- kolejne litery twojego Name 0137:004A04E9 0FB7CE MOVZX ECX,SI 0137:004A04EC C1E908 SHR ECX,08 0137:004A04EF 32D1 XOR DL,CL 0137:004A04F1 E87A32FDFF CALL 00473770 0137:004A04F6 8B55F4 MOV EDX,[EBP-0C] 0137:004A04F9 8BC7 MOV EAX,EDI 0137:004A04FB E85033FDFF CALL 00473850 0137:004A0500 33C0 XOR EAX,EAX 0137:004A0502 8AC3 MOV AL,BL 0137:004A0504 8B17 MOV EDX,[EDI] 0137:004A0506 0FB64402FF MOVZX EAX,BYTE PTR [EAX+EDX-01] 0137:004A050B 6603F0 ADD SI,AX 0137:004A050E 6669C603D9 IMUL AX,SI,D903 0137:004A0513 6605672B ADD AX,2B67 0137:004A0517 8BF0 MOV ESI,EAX 0137:004A0519 43 INC EBX 0137:004A051A FE4DFB DEC BYTE PTR [EBP-05] 0137:004A051D 75BC JNZ 004A04DB
Bede sie streszczal:
1. si=016Ch (jest jedno przeliczenie wczesniej na podstawie stalego ciagu liczb A7B9C6) (wskazówka - dodaj hexy...)
2. mov dl,[EDX+ECX-01]; w przypadku Name: MateMagik, najpierw 'M', potem 'a' itd.
3. mov ecx, si;
4. shr ecx,08;
5. xor cl,dl = A;
6. A + si = B;
7. A * B * D903 + 2B67 = C;
8. goto 1 - w SI sa wstawiane kolejne wartosci C
W moim przypadku z "MATEMAGIK'99" (c) ;) normalnie w postaci hex'owej:
4d,41,54,45,5d,41,47,49,4b,27,39,39 powstalo4c,69,8a,fd,bd,06,06,5a,3b,c1,31,b7 <-- nazwijmy to 'abecadlo'
A oto II czesc - kilkanascie procedur dalej :->
0137:004A0403 33DB XOR EBX,EBX 0137:004A0405 8A5C02FF MOV BL,[EAX+EDX-01] <-- podobnie jak wyzej, brana jest 0137:004A0409 C1EB04 SHR EBX,04 po kolei litera z 'abecadla' 0137:004A040C 80C331 ADD BL,31 0137:004A040F 80FB39 CMP BL,39 0137:004A0412 7603 JBE 004A0417 0137:004A0414 80C307 ADD BL,07 0137:004A0417 8D45F4 LEA EAX,[EBP-0C] ; niewazne 0137:004A041A 8BD3 MOV EDX,EBX; tu jest tylko przepisywanie 0137:004A041C E84F33FDFF CALL 00473770 ; kodu do innych obszarów 0137:004A0421 8B55F4 MOV EDX,[EBP-0C]; pamieci 0137:004A0424 8BC6 MOV EAX,ESI; nie interesuje nas to 0137:004A0426 E82534FDFF CALL 00473850; przeciez .... 0137:004A042B 33C0 XOR EAX,EAX; 0137:004A042D 8A45FB MOV AL,[EBP-05] 0137:004A0430 8B55FC MOV EDX,[EBP-04] 0137:004A0433 8A5C02FF MOV BL,[EAX+EDX-01] 0137:004A0437 80E30F AND BL,0F 0137:004A043A 80C331 ADD BL,31 0137:004A043D 80FB39 CMP BL,39 0137:004A0440 7603 JBE 004A0445 0137:004A0442 80C307 ADD BL,07 0137:004A0445 8D45F4 LEA EAX,[EBP-0C] 0137:004A0448 8BD3 MOV EDX,EBX 0137:004A044A E82133FDFF CALL 00473770 0137:004A044F 8B55F4 MOV EDX,[EBP-0C] 0137:004A0452 8BC6 MOV EAX,ESI 0137:004A0454 E8F733FDFF CALL 00473850 0137:004A0459 FE45FB INC BYTE PTR [EBP-05] 0137:004A045C 807DFB07 CMP BYTE PTR [EBP-05],07 <-- juz 7 liter? 0137:004A0460 7599 JNZ 004A03FB
Znowu sie streszczam - tym razem kazda litera 'abecadla' jest przerabiana dwukrotnie, powyzej siódmej litery Name jest bez znaczenia - równie dobrze moge wpisac: Name : MateMagik'99 lub Name : Matemagik ma sie dobrze ;)
Schemat :
1. mov bl, Z; gdzie Z to kolejna litera 'abecadla'
2. shr ebx,04;
3. add bl, 31h;
4. if bl > 39h then bl=bl+9;
5. bl = X;
6. mov bl, Z;
7. and bl, 0fh;
8. add bl, 31h;
9. if bl > 39h then bl=bl+9;
10. bl = Y;
11. goto 1
Powinien powstac kod postaci: XYXYXYXYXY..., który jest niczym innym, jak szczerbatym, poprawnym 'Unlock Code', który ostatecznie powinien miec postac:
X A Y X A C X Y X Y X Y X Y
_ _ _ _ _ _ _ _ _ _ _ _ _ _
np. 1 A 2 3 A C 5 6 7 8 9 8 7 6
No, to juz chyba wszystko, co powinno wystarczyc do napisania KeyGeneratora. Na koncu znajdziecie listing procedury w Delphi. Nie jest to zbyt dobry sposób, bo program wyjdzie ok.200kb, podczas gdy w assemblerze ok.4kb. Trzeba sie tylko tego nauczyc :-) Delphi jest zreszta 'user friendly' i mozna go latwo zrozumiec.
Jak widzicie, opisywany program jest doskonalym przykladem tego, ze nie zawsze znajdziesz porównanie eax, ebx i to wystarczy... Tutaj usunieto kilka liter, które sa sprawdzane pod koniec, ale widzialem juz wieksze manewry (o ile dobrze pamietam, spróbuj WEBZipa, wygenerowanie numeru zajelo mi troche czasu...)
Nie zawsze nalezy sie poddawac i robic od razu patch'a - ja stosuje to tylko w ostatecznosci.
Trzeci sposób to zrobienie pliku 'x.reg', na przyklad tego: ;)
REGEDIT4 [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Setup\OptionalComponents\ClipBrd] @="Ēüé:gk?jmlEoutsvCJlōöLlSsÖÜTtL×cįķóśAaEeyÄóö}lÖtc\\opĀES¦»cózLÄ"
dzieki któremu program jest automatycznie zarejestrowany... Widzicie teraz co mozna zrobic, gdy jakis program was zdenerwuje ;) Ja mialem prawdopodobnie wersje BETA i dlatego musialem walczyc, aby nie zawiesilo mi komputera. Odwiedzilem ostatnio specjalnie strone www.digitalrobotics.com i sciagnalem najnowsza wersje - wszystko dziala nadal.
Mam nadzieje, ze czegos sie nauczyles, a jezeli nie, to nic nie szkodzi - teoria teoria, tylko praktyka czyni mistrza.
<<EMO>>emo@viper.pl
!UWAGA - Tekst powstal tylko w celach edukacyjnych i autor nie ponosi odpowiedzialnosci za szkody wynikle z niewlasciwego stosowania porad tu zamieszczonych. W przypadku uzywania programu przez dluzszy czas nalezy go zarejestrowac.
Greetings : Sir_THomasRE, Monter, MAX, CrackPL za inspiracje
A oto i KeyGen. Moze nie byc zrozumialy, bo uzywalem wstawek w assemblerze i dziwnych oznaczen, ale dziala...
procedure TForm1.button1click(Sender: TObject);
var si,eax,ebx,dl,ter,numer:longint;
rd,dobrze:byte;
temp:dword;
temp2:word;
comp, name,sn,wynik,wynik2:string;
i,j:byte;
begin
name:=edit1.text;
comp:=edit2.Text;
name:=uppercase(name);
j:=1;
sn:=' ';
wynik:=' ';
wynik2:=' ';
temp:=$016c;
for i:= 1 to length(name) do
begin;
rd:=ord(name[i]);
ter:=temp;
temp:=temp shr $08;
asm
mov eax, temp
mov dobrze, al
end;
numer:=dobrze xor rd;
sn[i] := chr(numer);
temp:=ter;
asm
xor eax, eax
mov eax, numer
mov ecx, temp
add cx, ax
imul al,ecx,$d903
mov temp, eax
end;
temp:=temp+$2b67;
temp2:=temp;
asm
mov ax, temp2
mov temp2, ax
end;
temp:=temp2;
end;
{------------------------------part2------------------}
si:=1;
for i:=1 to 6 do
begin;
dl:=ord(sn[i]);
eax:=dl shr $04;
ebx:=eax+$31;
if ebx > $39 then ebx:=ebx+7;
wynik [si] := chr(ebx);
si:=si+1;
eax:=dl and $f;
ebx:=eax+$31;
if ebx > $39 then ebx:=ebx+7;
wynik[si]:= chr(ebx);
si:=si+1;
end;
{ ----------- teraz dodamy 2,5 i 6 litere -------- }
for i:=1 to 12 do
begin;
dl:=ord(wynik[i]);
wynik2[j]:=chr(dl);
if j=1 then begin; j:=j+1; wynik2[j]:=chr(65); end;
if j=4 then begin; j:=j+1; wynik2[j]:=chr(65); end;
if j=5 then begin; j:=j+1; wynik2[j]:=chr(67); end;
j:=j+1;
end;
edit3.text:= sn;
edit4.text:= wynik2;
end;