14 December 2010

Wstęp do crackingu

Programy, które likwidują zabezpieczenia w oprogramowaniu, ogólnie nazywa się crackami. Przedstawię dwa sposoby na nielegalne zarejestrowanie aplikacji dla zabezpieczenia, które jest zawarte w programie CrackMe2. Autorem zabezpieczenia jest polski cracker - massh z grupy CookieCrK. Programy tego typu, są pisane przez crackerów, w celu zdobywania doświadczenia. Łamaniem takich programów również zajmują się crackerzy - dla chwały i kasy ;-) Lekcje crackingu często są wstępem, do pisania wirusów ukierunkowanych na określony cel. W tekście skoncentrowałem się na popularnym przed kilkoma latami narzędziu SoftICE, prudukt nie jest już rozwijany, ale równie skutecznym narzędziem jest OllyDBG, który spełni wymagania początkujących crackerów.



Aby zarejestrować program, należy wpisać nazwę użytkownika (okno edycyjne- user) oraz klucz rejestrujący (okno edycyjne - serial). Dla każdego użytkownika w procesie rejestracji powstaje inny klucz. Zadaniem crackera jest zarejestrowanie programu bez poprawnego klucza rejestrującego lub stworzenie go dla danego użytkownika. Rejestracja bez właściwego klucza wymaga modyfikacji procedury rejestrującej lub całkowitego jej usunięcia. Można tego dokonać, kiedy klucz rejestrujący nie jest jednocześnie kluczem deszyfrującym instrukcje w zabezpieczonej aplikacji. Kiedy w zabezpieczonej aplikacji istnieją zaszyfrowane instrukcje, a kluczem, który je deszyfruje jest wartość wyliczana na podstawie nazwy użytkownika, należ stworzyć generator kluczy.

PIERWSZE KROKI

Nie ma określonego przepisu na cracka, ponieważ każde zabezpieczenie wymaga indywidualnego podejścia. Pierwszym krokiem, jest analiza zabezpieczonej aplikacji, która polega na zebraniu jak najwięcej informacji o programie. Język w jakim został napisany program, format nagłówka wykonywalnego pliku programu, wykorzystywane zasoby zewnętrzne, odwołania do rejestrów systemu oraz do plików to informacje podstawowe ułatwiające dalsze działanie. Najpopularniejszym narzędziem crackera, jest debugger SoftICE, ale gdy zabezpieczona aplikacja jest napisana w języku VisualBasic, to odpowiednim narzędziem będzie program SmartCheck. Format wykonywalnego pliku programu, najczęściej jest to PE (opis według Microsoft ang. Portable Executable), określa, w jaki sposób ułożone są poszczególne sekcje oraz tabele importowanych i eksportowanych funkcji. Najważniejszymi informacjami o zasobach wykorzystywanych przez program, są importowane funkcje. Jeśli program importuje funkcje związane z pomiarem czasu w systemie, można się spodziewać zabezpieczenia w postaci ograniczeń czasowych. Kiedy program odwołuje się do plików i rejestrów systemu jest możliwość, że zapisuje w nich ważne, z punktu widzenia crackera, informacje, takie jak data instalacji, nazwa użytkownika lub klucz rejestrujący. Odwołania do plików i rejestrów wykrywa monitor Process Monitor.
Po zebraniu niezbędnych informacji można przejść do próby złamania zabezpieczenia w pamięci komputera. Najczęściej śledzenie programu w pamięci rozpoczyna się w miejscu gdzie użytkownik podaje klucz rejestrujący. Zastawianie pułapek na wywoływane funkcje jest możliwe dzięki znajomości importowanych zasobów. Dla crackera najważniejsze są funkcje odpowiedzialne za obsługę kontrolek edycyjnych - okienek z miejscem na hasło. O tym czy program zostanie zarejestrowany decydują instrukcje wykonywane po wpisaniu klucza. Cracker musi usunąć, zmodyfikować lub odwrócić funkcję odpowiedzialną za rejestrację.

WSTĘPNA ANALIZA

 Ilość informacji jakie można wydobyć z programu, jest bardzo duża. Niewielki rozmiar CrackMe2 wskazuje na to, że program powstał w asemblerze. Przy pomocy programu PE Explorer sprawdzamy, jaki jest format pliku. Uruchamiamy program PE Explorer, w menu File -> Open File wybieramy program CrackMe2 i natychmiast pokazują nam się wszystkie informacja zawarte w nagłówku pliku. Aby obejrzeć importowane funkcje wybieramy menu View -> Imports.





Funkcja GetWindowTextA importowana z biblioteki User32.dll, jest to funkcją kopiująca do pamięci tekst z okna edycyjnego. Posłuży ona do zastawienia pułapki na CrackMe2.
Debugger pozwala śledzić instrukcje wykonywane przez procesor, dane zapisywane do pamięci oraz rejestry procesora. Dokładna wiedza o aktualnie wykonywanych przez procesor instrukcjach daje możliwość ingerencji w program. W praktyce najlepiej działa SoftICE 4.05 pod systemem Windows98. W przypadku debuggera SoftICE bardzo ważna jest jego odpowiednia instalacja i konfiguracja. Po zainstalowaniu programu należy otworzyć plik konfiguracyjny winice.dat i poprzez usunięcie średników wybrać biblioteki, z których pobierane są funkcje eksportowane do plików (np.: EXP=c:\windows\system\user32.dll).
Aby była możliwość śledzenia programu w debuggerze SofIce, należy wykonać następujące kroki:
- uruchamiamy CrackMe2 i wpisujemy dowolne dane w oknach edycyjnych.
- wyświetlamy okno debuggera poprzez wciśnięcie klawiszy [Ctrl+d].
- w linii komend wpisujemy bpx GetWindowTextA, komendę zatwierdzamy klawiszem [Enter]. Jest to instrukcja, która spowoduje przerwanie działania programów i przejście procesora w tryb pracy krokowej, w przypadku, kiedy jakiś program wywoła funkcję GetWindowTextA.
- wciskamy klawisz [F5], aby zamknąć okno debuggera.
- wciskamy przycisk [ok] w CrackMe2 i automatycznie pojawia się okno debuggera z zaznaczoną instrukcją. SoftICE pokazuje instrukcje tworzące funkcję GetWindowTextA. Pomiędzy linią komend, a oknem z kodem programu jest nazwa biblioteki, z której pochodzi funkcja. Crackera nie interesuje budowa funkcji, ale parametry jakie zwraca do programu, który ją wywołał.
- wciskamy klawisz [F11], aby znaleźć się w miejscu, z którego funkcja została wywołana. Teraz pomiędzy linią komend i oknem z kodem znajduje się nazwa programu, który wywołał funkcję GetWindowTextA, czyli CrackMe2.
Kolejnym zadaniem crackera jest analiza instrukcji odpowiedzialnych za rejestrację programu.
W listingach, używane są liczby zapisane w postaci szesnastkowej. Znaki oraz cyfry kodowane są według standardu ASCII. Cyfry poprzedzające instrukcje programu, są opkodami instrukcji maszynowych.

LISTING 1
6A1F            PUSH 1F
6824214000      PUSH 00402104
FF354C204000    PUSH DWORD PTR [0040204C]
E81C020000      CALL USER32!GetWindowTextA
85C0            TEST EAX,EAX
744D            JZ 00401260
A360204000      MOV [00402060], EAX
6A1F            PUSH 1F
6824214000      PUSH 00402124
FF3550204000    PUSH DWORD PTR [00402050]
E81C020000      CALL USER32!GetWindowTextA
85C0            TEST EAX,EAX
7432            JZ 00401260

Instrukcje z listingu 1, wykonywane bezpośrednio po wpisaniu danych i wciśnięciu przycisku [ok], są odpowiedzialne, za kopiowanie danych do pamięci. Parametry odkładane na stos, przed wywołaniem funkcji, określają adresy w pamięci gdzie znajdą się dane, długości zmiennych oraz uchwyty do okien edycyjnych. Dzięki temu wiemy gdzie w pamięci szukać nazwy użytkownika oraz klucza rejestrującego. W linii poleceń debuggera wpisz „d 00402104”, to w oknie danych zobaczysz nazwę użytkownika, natomiast po wpisaniu „d 00402124” w oknie danych pojawi się klucz rejestrujący. Wartość 1F hex. jest długością zmiennych i oznacza, że nazwa oraz klucz nie mogą być dłuższe niż 31 znaków. Po skopiowaniu danych do pamięci, następuje sprawdzenie ich długości. Jest to możliwe, ponieważ funkcja, GetWindowTextA zwraca w rejestrze EAX długość skopiowanego ciągu znaków. Jeśli długość, danych jest równa 0, to procedura rejestrująca jest przerywana.
Aby w debuggerze SoftIce wykonywać kolejne instrukcje należy wcisnąć klawisz [F10]. Wciskamy [F10], aż dojdziemy do instrukcji:


E8DF000000     CALL 00401261 

Jest to wywołanie funkcji wewnętrznej programu, z pod adresu 00401261 (adresy również zapisywane są postaci szesnastkowej). Aby zobaczyć instrukcje tworzące funkcję należy wcisnąć klawisz [F8].
Po wejściu do funkcji widzimy:

LISTING 2
A160204000      MOV EAX, [00402060]
390564204000    CMP [00402064], EAX
752F            JNZ 0040129D
33C0            XOR EAX, EAX

Instrukcje z listingu 2, sprawdzają czy długość nazwy użytkownika jest taka sama jak długość klucza rejestrującego. Jeśli długości obu zmiennych są różne wyświetlany jest komunikat o niepoprawnym kluczy rejestrującym. Ostatnia instrukcja zeruje rejestr EAX. Wnioskiem z listingu 2 jest to, że długość klucza rejestrującego musi być taka sama jak długość nazwy użytkownika
Kolejnymi instrukcjami procedury rejestrującej są:

8B7C2404     MOV EDI, [ESP+04]
8B742408     MOV ESI, [ESP+08]

 

Pierwsza instrukcja kopiuje do rejestru EDI adres z nazwą użytkownika, a druga do rejestru ESI adres z kluczem rejestrującym.
Instrukcje z listingu 3, są sercem zabezpieczenia. Na ich podstawie będziemy w stanie stwierdzić, w jaki sposób powstaje klucz rejestrujący i jaki wpływ na niego ma nazwa użytkownika.


LISTING 3
0FB61F          MOVZX EBX, BYTE PTR [EDI]
0FB616          MOVZX EDX, BYTE PTR [ESI]
80FA30          CMP DL, 30
7C1A            JL 0040129D
80FA39          CMP DL, 39
7F15            JG 0040129D
80EA30          SUB DL, 30
83E30F          AND EBX, 0F
D0EB            SHR BL, 01
2ADA            SUB BL, DL
7509            JNZ 0040129D
47              INC EDI
46              INC ESI
803F00          CMP BYTE PTR [EDI], 00
75DD            JNZ 00401278
EB04            JMP 004012A1
Do rejestru EBX kopiowany jest pierwszy znak nazwy użytkownika, w rzeczywistości znajduje się on w najmniej znaczącej części tego rejestru, czyli w BL. Do rejestru EDX kopiowany jest pierwszy znak z klucza rejestrującego, również jest umieszczany w najmniej znaczącej części rejestru czyli DL. Kolejne cztery instrukcje są odpowiedzialne za sprawdzenie czy znak klucza jest cyfrą z zakresu 0-9 (wartość 0 jest reprezentowana w standardzie ASCII przez liczbę 30 hex, a cyfra 9 w tym standardzie to 39 hex). Jeśli znak nie jest cyfrą, następuje skok do procedury wyświetlającej okno o niepoprawnej rejestracji. Jak zapewne już zauważyłeś, adres 0040129D kryje za sobą procedurę z informacją, o niepoprawnej rejestracji programu. 

 
 
Kolejna instrukcja odejmuje od pierwszego znaku klucza wartość 30 hex, dzięki temu w rejestrze DL zostają tylko ostatnie cztery bity znaku z klucza. Dzięki instrukcji AND EBX, 0F program nie będzie rozróżniał czy nazwa użytkownika jest napisana wielkimi czy małymi literami, ponieważ instrukcja AND EBX, 0F, usuwa pierwsze cztery bity rejestru BL. W ten sposób w rejestrze EBX znajdują się tylko ostatnie cztery bity znaku nazwy użytkownika. Instrukcja SHR, to operacja przesunięcia bitowego w prawo, jej działanie modyfikuje rejestr BL. Operacja SUB to odejmowanie arytmetyczne. W naszym przypadku oznacza to, że odejmowane są wartości umieszczone w rejestrach BL i DL. Należy pamiętać, że w BL znajduje się to, co zostało ze znaku nazwy użytkownika, a w DL ostatnie cztery bity znaku z klucza.
Kolejna instrukcja jest kluczowa dla procesu rejestracji. Instrukcja JNZ 0040129D to skok do procedury z informacją o niepoprawnej rejestracji. Skok zostanie wykonany tylko wtedy, gdy w rejestrach BL i DL będą różne wartości. Dla nas oznacza to, że odkryliśmy sposób, w jaki powstaje klucz rejestrujący oraz zależność między nim, a nazwą użytkownika. Dzięki temu wiemy jak dla danego użytkownika stworzyć klucz. Każda litera z nazwy użytkownika ma przypisaną cyfrę reprezentującą ją w kluczu rejestrującym. Nie trudno policzyć kolejne cyfry odpowiadające znakom z nazwy użytkownika, ponieważ: np.: litera „b” to w standardzie ASCII - 62 hex. i 0110 0010 binarnie. Instrukcja AND BL, 0F zeruje pierwsze cztery bity, więc otrzymujemy, 02 hex i 0000 0010 binarnie, po przesunięciu bitowym w prawo o jedną pozycję (instrukcja SHR BL, 01) otrzymujemy 0000 0001, czyli cyfrę 1. Aby zamienić tą cyfrę na znak 1 zapisany w standardzie ASCII należy do niej dodać dokładnie tyle ile zostało odjęte od rejestru DL, czyli 30 hex. W rezultacie dla litery „b” otrzymujemy 31 hex, czyli cyfrę 1. Należy pamiętać, że program nie rozróżnia małych i wielkich liter, więc dla litery „B” cyfrą w kluczu również będzie 1. Instrukcja JNZ 0040129D jest decydującą w porównaniu znaków nazwy użytkownika i klucza rejestrującego. Kolejne instrukcje są odpowiedzialne za zwiększenie rejestrów z adresami nazwy użytkownika i klucza oraz za skok do początku listingu 3. W przypadku, kiedy klucz rejestrujący jest poprawny, operacje z listingu 3, są wykonywane tyle razy ile jest znaków w nazwie użytkownika. Przerwanie pętli następuje, kiedy znak klucza nie odpowiada znakowi nazwy użytkownika lub gdy zostały sprawdzone wszystkie znaki nazwy użytkownika. Znakom nazwy użytkownika, przyporządkowane są następujące cyfry klucza:
Dla liter a,A,p,P,q,Q cyfra klucza to 0
Dla liter b,B,c,C,r,R,s,S cyfra klucza to 1
Dla liter d,D,e,E,t,T,u,U cyfra klucza to 2
Dla liter f,F,g,G,w,W,v,V cyfra klucza to 3
Dla liter h,H,i,I,x,X,y,Y cyfra klucza to 4
Dla liter j,J,k,K,z,Z cyfra klucza to 5
Dla liter l,L,m,M cyfra klucza to 6
Dla liter n,N,o,O cyfra klucza to 7
Program sprawdzał czy klucz składa się z cyfr mieszczących się w zakresie 0-9. W żadnym kluczu nie pojawią się cyfry 8 i 9, ponieważ największa cyfra, jaką można opisać na trzech bitach to 7.
Aby jak najlepiej zilustrować działanie procedury rejestrującej na rysunku przedstawiam schemat. Na jego podstawie możemy określić słabe punkty procedury rejestrującej.


 
 Jeśli chcemy usunąć zabezpieczenie i napisać cracka dla programu CrackMe2 musimy dokładnie poznać strukturę zabezpieczenia. Istnieją dwie metody, aby zarejestrować nielegalnie program CrckMe2. Za legalną rejestrację uznaje się przypadek, kiedy to producent oprogramowania podaje nam klucz rejestrujący.
Dla tego zabezpieczenia najprostszą metodą będzie usunięcie jednej instrukcji: JNZ 0040129D. To jest zadanie, które musi realizować crack.
Ostatnim etapem jest napisanie cracka. Szybkość działania, mała objętość wykonywalnego kodu oraz pełna kontrola nad wykonywanymi instrukcjami są powodem, dla którego cracki powstają w asemblerze.


JAK DZIAŁA CRACK 

Crack wczytuje do pamięci plik z programem, w którym ma usunąć zabezpieczenie. Następnie wyszukuje odpowiedni ciąg bajtów i zamienia go.
Zadaniem crackera jest odnalezienie w pliku programu opkodów instrukcji JNZ 0040129D. Jest to możliwe dzięki temu, że SoftIce pokazuje wszystkie opkody instrukcji w programie. Czyli szukaną wartością będą dwa bajty: 7509 hex, ta wartość jest opkodem instrukcji JNZ 0040129D. W praktyce poszukuje się większej ilości bajtów, ponieważ bajty 7509 hex. mogą w programie występować wielokrotnie. Dlatego podając w hexedytorze poszukiwane bajty, wpiszemy również po dwa opkody sąsiadujące z poszukiwanymi bajtami. Wpisujemy 2ADA 7509 4746 i edytor, automatycznie podświetla znalezione wartości. Aby można było je zlokalizować w programie należy otworzyć plik CrackMe2 w hexedytorze. 



Zaznaczone opkody instrukcji JNZ 0040129D, które wynoszą 7509 hex. Teraz należy się zastanowić się, czym zastąpić dwa bajty, aby usunąć instrukcję JNZ 0040129D i nie zniszczyć całego programu. W asemblerze istnieje instrukcja NOP (No Operation), która nie robi nic. Jest to jedno bajtowa instrukcja, której opkodem jest wartość 90 hex. Jak wiemy, musimy zmienić dwa bajty, więc zastępujemy bajty 7509 hex. bajtami 9090 hex. i program działa tak jak życzy sobie tego cracker, czyli rejestruje się nawet przy podaniu złego klucza. Teraz pozostaje spisanie adresu, pod jakim występuje instrukcja JNZ 0040129D po to aby crack „wiedział”, które instrukcje należy zmienić. Adres ten jest przesunięciem, szukanej instrukcji, względem początku pliku programu i w przypadku CrackMe2 wynosi: 0892 hex. Adres ten można zobaczyć na rysunku 6. Pierwsza, ośmiocyfrowa kolumna liczb to adresy opkodów instrukcji w pliku. Dla wiersza z opkodami 7509 hex. adres wynosi 0890 hex. i do tej liczby należy dodać 2, ponieważ opkody są na trzeciej pozycji w wierszu. Dzięki temu otrzymujemy właściwy adres opkodów w pliku, czyli 0892 hex. Właśnie pod ten adres zostaną zapisane opkody instrukcji NOP. Istnieje jeszcze jedno zabezpieczenie w CrakMe2. Program jest zabezpieczony przed zmianami w pliku programu, oznacza to, że ma ustawiony atrybut: Tylko do odczytu, aby zmienić opkody w hexedytorze należ usunąć ten atrybut z pliku. Najprościej można go usunąć, wyświetlając właściwości pliku w menu podręcznym Windows i odznaczając okienko „Tylko do odczytu”.

LISTING 4 – Fragment programu crack – składnia języka asembler dla kompilatora MASM32
 

invoke GetFileName,hWin,SADD("Otwórz plik"), SADD("CrackMe2.exe",0,"CrackMe2.exe",0)
invoke CreateFile,ADDR szFileName,GENERIC_READ or GENERIC_WRITE,NULL,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL
   .if eax == -01
      invoke MessageBox,hWnd,SADD ("Nie można otworzyć pliku !!!"), ADDR szDisplayName,MB_OK
      ret
   .endif
mov hFile,eax
invoke GetFileSize,hFile,ADDR FileSize
mov FileSize,eax
   .if eax != 02000h
      invoke MessageBoxA,hWnd,SADD("To nie jest CrackMe2.exe !!!"),ADDR szDisplayName,MB_OK
      ret
   .endif
invoke SetFilePointer,hFile,0892h,NULL,FILE_BEGIN
invoke WriteFile,hFile,ADDR Text1,2,ADDR ByteWrite,NULL
invoke MessageBoxA,hWnd,SADD ("Operacja zakończona pomyślnie !!!"),ADDR szDisplayName,MB_OK
invoke CloseHandle,hFile

W listingu 4, znajdują się wszystkie operacje jakie wykonuje crack na pliku CrackMe2. Na początku następuje otwarcie pliku – funkcje GetFileName oraz CreateFile, jeśli funkcje zwrócą błąd wyświetlany jest komunikat „Nie można otworzyć pliku !”. Następnie pobierany jest rozmiar pliku – funkcja GetFileSize. Rozmiar jest wykorzystywany do sprawdzenia czy otwarty plik jest na pewno programem CrackMe2, takie procedury często stosowane są w crackach, ponieważ wykorzystanie cracka do innych programów może zniszczyć modyfikowany program. W przypadku CrackMe2 jego rozmiar wynosi 02000 hex. czyli 8192 bajtów. Kolejną operacją jest znalezienie w CrackMe2 adresu, pod który będą zapisane opkody 9090hex. Tą operację
wykonuje funkcja SetFilePointer, której drugim argumentem jest interesujący nas adres czyli 0892hex. Najważniejszą operacją jest zastąpienie opkodów 7509 hex. wartościami 9090 hex. Realizuje to funkcja WriteFile, której trzecim argumentem jest adres z opkodami instrukcji NOP, czyli 9090 hex. W naszym przypadku wartość 9090 hex. jest zapisana w dwubajtowej zmiennej Text1. Ostatnia funkcja CloseHandle, zamyka plik CrackMe2.
Do tekstu, załączone kody źródłowe (pliki crack1.asm i crack.inc). Crack powstał w asemblerze, a kompilatorem był MASM32 v7.0 – polecam ten kompilator, ponieważ składnia języka jest bardziej czytelna, niż np.: TASM32, i mniej czasu zajmuje pisanie instrukcji.
Większość kodów źródłowych stworzył bardzo „przyjazny” generator, oczywiście instrukcje odpowiedzialne za zmianę opkodów w łamanym programie należy napisać samemu. Przy pomocy generatora można stworzyć okno cracka, przyciski oraz menu. Jeśli uznasz, że pomimo usunięcia najważniejszej instrukcji w programie, nadal istnieje ograniczenie w postaci konieczności wpisania klucza, takiej samej długości, jak nazwa użytkownika, polecam napisanie cracka likwidującego tą niedogodność. Powinien być skonstruowany w analogiczny sposób jak mój.


 

ROZWIĄZANIE DLA AMBITNYCH

 Napisanie cracka nie jest jedynym sposobem na złamanie tego zabezpieczenia. Cracki to droga na skróty, w łamaniu zabezpieczeń. W miarę zbierania doświadczeń przekonasz się, że nie zawsze jest to dobra droga. Crack nie jest dobrym rozwiązaniem, jeśli zabezpieczenie sprawdza sumę kontrolną (ang. checksum) procedury rejestrującej. A jeśli jakieś funkcje zabezpieczonego programu, są zaszyfrowane kluczem wyliczanym z nazwy użytkownika? W przypadku sumy kontrolnej można zmodyfikować również procedurę liczącą tą wartość i program będzie działał poprawnie, ale należy liczyć się z wieloma godzinami poświęconymi na szukanie tej procedury.
W takich przypadkach jedynym rozwiązaniem jest napisanie generatora kluczy. Jest to krótki program, który na podstawie nazwy użytkownika tworzy właściwy klucz rejestrujący. Napisałem, że jest to rozwiązanie dla ambitnych, ale niekiedy może być to jedyne rozwiązanie.
Podczas pisania generatora kluczy, należy pamiętać, że sam zabezpieczony program dostarcza rozwiązania. W zabezpieczonej aplikacji znajduje się generator, którego zadaniem jest sprawdzenie poprawności klucza. W naszym przypadku cały listing 3 to generator. Wystarczą niewielkie modyfikacje procedury sprawdzającej i otrzymamy program tworzący klucze dla dowolnych użytkowników. Podobnie jak w przypadku cracka, większość kodu stworzył generator kodu (MASM32 Prostart Code Wizard), ale najważniejszą część należy napisać samemu. Generator napisałem w asemblerze, języku w którym analizowaliśmy CrackMe2. Dzięki temu będzie możliwość wykorzystania instrukcji zawartych w zabezpieczeniu do stworzenia generatora. Listing 5, zawiera całą procedurę generującą klucze dla dowolnych
użytkowników. Kody źródłowe generatora są w plikach keygen.asm i keygen.inc.


LISTING 5
invoke GetDlgItemTextA,hWin,EditID,ADDR Text,31
LEA ESI, Text
LEA EDI ,Key
NextSign:
   MOV BL, BYTE PTR [ESI]
   AND BL, 0Fh
   SHR BL, 01h
   ADD BL, 30h
   MOV [EDI], BL
   INC EDI
   INC ESI
   CMP BYTE PTR [ESI], 0h
   JZ EndLoop
   JMP NextSign
EndLoop:
   XOR BL, BL
   MOV [EDI], BL
   invoke SendMessageA, hEdit1, WM_SETTEXT, EAX, ADDR Key

 

ZŁY CRACKER

Jeśli uznasz, że łamanie programów ćwiczeniowych jest sztuką dla sztuki, możesz spróbować złamać program komercyjny. Jednak programy komercyjne mają często o wiele bardziej złożone procedury rejestrujące. Ten artykuł dostarcza podstawowej wiedzy na temat crackingu. Podczas łamania programów komercyjnych, występują często inne problemy, na które należy zwrócić uwagę:
- większość programów komercyjnych napisanych jest w językach wysokiego poziomu, a to oznacza kilkaset razy więcej kodu, który należy zbadać. Odnalezienie procedury rejestrującej nie będzie takie łatwe jak w przypadku CrackMe2.
- wiele programów ma ograniczenia czasowe, a to zupełnie inne zabezpieczenie. Najczęściej łatwiejsze do usunięcia, ale wymagają zastawiania pułapek na funkcje mierzące czas w systemie. Dzięki programowi PE Explorer będziesz w stanie określić, na jaką funkcję zastawić pułapkę.
- programy komercyjne składają się z wielu plików, zabezpieczenie nie musi być zawarte w pliku programu. W takim przypadku bardzo pomocny jest FileMonitor, który śledzi odwołania do wszystkich plików wykorzystywanych przez dany program.
- w rejestrach systemowych zabezpieczone programy ukrywają często wiele cennych dla crackera informacji, warto korzystać z monitorów rejestrów podczas instalacji programów komercyjnych. Najlepszym monitorem rejestrów jest RegMonitor.
- osobnym rozdziałem w crackingu jest zabezpieczanie programów przed narzędziami crackera. Głównie odnoszą się one do wykrywania debuggerów w systemie – istnieje bardzo dużo metod wykrywania debuggera SoftIce. Ratunkiem dla crackera, są specjalne narzędzia usuwające takie zabezpieczenia.
- zastawianie właściwych pułapek jest trudne. Programy korzystają z różnych funkcji obsługi okien edycyjnych, najpopularniejsze z nich to: GetDlgItemTextA, GetWindowTextA, GetWindowTextLength. Wszystkie funkcje wykorzystywane w systemie Windows, można znaleźć w spisie funkcji API (ang. Application Programing Interface).
- cracking to nie tylko zabezpieczenia programowe, istnieje wiele programów korzystających z zabezpieczeń sprzętowych – klucze sprzętowe. Najczęściej są to małe urządzenia, podłączane do portów równoległych, szeregowych lud USB. Łamania takich zabezpieczeń podejmują się doświadczeni crackerzy.

powodzenia