___ ___ ___ ___ ___ ___ ___ / /\ /__/\ / /\ /__/\ / /\ / /\ / /\ / /:/ \ \:\ / /::\ \ \:\ / /::\ / /::\ / /::| / /:/ \ \:\ / /:/\:\ \ \:\ / /:/\:\ / /:/\:\ / /:|:| / /::\ ___ \__\:\ / /::\ \:\ \__\:\ / /::\ \:\ / /::\ \:\ / /:/|:|__ /__/:/\:\ /\ / /::\/__/:/\:\ \:\ / /::\/__/:/\:\ \:/__/:/\:\_\:/__/:/_|::::\ \__\/ \:\/:// /:/\:\ \:\ \:\/:// /:/\:\ \:\ \:\_\\__\/ \:\/:\__\/ /~~/:/ \__\::// /:/\ \:\ \:\ \::// /:/\ \:\ \:\ \:\ \__\::/ / /:/ / /:// /:/ \_\/\ \:\/:// /:/ \_\/\ \:\_\/ / /:/ / /:/ /__/://__/:/ \ \:://__/:/ \ \:\ /__/:/ /__/:/ \__\/ \__\/ \__\/ \__\/ \__\/ \__\/ \__\/ www.htb.team.prv.pl Title: [Tworzymy.pierwszego.keygena........................................] Topic: [Coding.............................................................] Author: [FiNS.......................] E-mail: [finsss@wp.pl...............] Packager: [FiNS.......................] Date: [2003.......................] D O N ' T T R Y T O B E A T U S ! _______________________________________________________________________________ 1. Wstęp Jak się pewnie domyślasz, ten tekst jest o tworzeniu keygenów. Piszę go z myślą o początkujących, którzy często nie wiedzą jak się do tego zabrać. Jeżeli nie masz z tym żadnych problemów, to raczej nie dowiesz się niczego nowego z tego tutka. Długo myślałem do czego by tu zrobić tego keygena i doszedłem do wniosku, że na początek należy wziąć coś prostego. Poszukałem na dysku i znalazłem: CrackMe2 by massh^CookieCrK. Bardzo prościutkie CrackMe generujące seriala na podstawie nicka i równocześnie pierwsze CrackMe tego typu, które złamałem :), miło powspominać. Ale dobra, koniec tego ględzenia i zabieramy się do roboty. 2. Zabezpieczenie Pewnie złamiesz to szybko i bez żadnych problemów. Prog używa GetWindowTextA, a najważniejsze instrukcje znajdują się w tym callu: 0040117D CALL 00401261 Jest tam taki kod: 00401261 MOV EAX,[00402060] 00401266 CMP [00402064],EAX ;długość name i serial 0040126C JNZ 0040129D ;musi być taka sama 0040126E XOR EAX,EAX 00401270 MOV EDI,[ESP+04] ;adres name do edi 00401274 MOV ESI,[ESP+08] ;adres seriala do esi 00401278 MOVZX EBX,BYTE PTR [EDI] ;bajt z name do ebx 0040127B MOVZX EDX,BYTE PTR [ESI] ;bajt z seriala do esi 0040127E CMP DL,30 00401281 JL 0040129D 00401283 CMP DL,39 00401286 JG 0040129D ;czy serial składa się z liczb 00401288 SUB DL,30 0040128B AND EBX,0F ;obrabianie litery z name 0040128E SHR BL,1 00401290 SUB BL,DL ;litera po przeróbce musi być 00401292 JNZ 0040129D ;taka sama jak cyfra z seriala 00401294 INC EDI 00401295 INC ESI 00401296 CMP BYTE PTR [EDI],00 ;powtarzaj ze 00401299 JNZ 00401278 ;wszystkimi znakami 0040129B JMP 004012A1 0040129D XOR EAX,EAX 0040129F JMP 004012A6 004012A1 MOV EAX,00000001 004012A6 RET Poprawny serial dla mojego name to 3471. Jak widać 1 cyfra seriala odpowiada 1 literze z name. Teraz wiemy jak generowany jest serial, więc pora zabrać się za keygena... 3. Algo obliczające seriala Na początku opracujemy algorytm generujący seriala (w tym przypadku 1 min :)), a później napiszemy resztę kodu. Załóżmy, że w DL mamy literę z name. Aby znaleźć cyfrę z seriala odpowiadającą tej literze, możemy użyć takiego kodu: and edx, 0Fh shr edx, 1 add edx, 30h Trzeba to zmodyfikować tak, aby zastosować to do każdej litery z nicka. Całość wygląda tak: mov ebx, offset serial ;tu zapiszemy wygenerowanego seriala mov eax, offset myname ;tu jest nasze name nastepny: movzx edx, byte ptr [eax] ;litera z name do edx and edx, 0Fh ;obrabianie name shr edx, 1 add edx, 30h mov [ebx], dl ;kolejne cyfry seriala idą do ebx inc eax inc ebx cmp byte ptr [eax], 0 ;sprawdź czy koniec name jne nastepny ;jeśli nie to obrób następną literę Ten kod będzie najważniejszą częścią naszego proga. 4. Wygląd keygena Teraz musimy zabrać się za okienko dialogowe. Najpierw zrobimy plik z zasobami, który odpowiada za jego wygląd. Może bawiłeś się kiedyś programikiem takim jak Restorator, czy Resource Hacker. Pozwalają one zmieniać wygląd innych progów, a nam mogą nieco ułatwić ustalenie wyglądu okna keygena. Ja używam tych dwóch progów o których wspomniałem wcześniej i polecam je również tobie. Jak chcesz zmieniać wygląd okna to odpalasz ResHackera i ładujesz jakiś programik który jest okienkiem dialogowym, np. calc.exe. Klikasz np. na Dialog i na 104. Na początku wywalasz wszystko co jest w tym oknie. Później klikasz prawym na puste okno i ustawiasz jego właściwości w "Edit Dialog". Później znowu prawym na puste okno i "Insert control". Tu możesz dodawać przyciski, pola edycyjne i inne bajery. Rozmiary kontrolek i okna zmieniasz myszką, rozciągając to co chcesz do odpowiednich rozmiarów. Jak już wszystko pozmieniasz to zapisujesz to okno w pliku res. Później w Restoratorze możesz to sobie zamienić na rc i jeszcze wprowadzić jakieś zmiany. Nie polecam zapisywania zasobów w ResHackerze do plików rc, bo nie są one kompatybilne z masm32, właśnie dlatego przydaje się Restorator, który generuje pliki rc kompatybilne z tym kompilatorem. Właściwie to ResHacker nie jest wcale potrzebny, bo wszystko można zrobić w drugim progu, ale mi się wydaje, że ResHacker jest wygodniejszy w obsłudze. Wybór pozostawiam tobie. Jak chcesz, to możesz wcale nie używać tego typu progów. Ja ułatwiam ci sprawę i daje gotowy plik rc z opisem zasobów do naszego keygena. Wygląda on tak: #include 10 DIALOGEX 11, 11, 213, 74, 0 STYLE DS_SETFONT | DS_SETFOREGROUND | DS_CENTER | WS_MINIMIZEBOX | WS_POPUPWINDOW | WS_VISIBLE | WS_CAPTION CAPTION "CrackMe2 by massh^CookieCrK - keygen" FONT 8, "MS SANS SERIF" { GROUPBOX "", 0, 2, -1, 209, 72 EDITTEXT 100, 6, 16, 201, 12, NOT WS_BORDER | WS_GROUP, WS_EX_STATICEDGE EDITTEXT 101, 6, 38, 201, 12, ES_READONLY | NOT WS_BORDER | WS_GROUP, WS_EX_STATICEDGE CTEXT "Name:", 309, 6, 7, 22, 8 CTEXT "Serial:", 309, 5, 29, 22, 8 PUSHBUTTON "&Generate", 1, 6, 55, 44, 12, BS_CENTER | WS_GROUP, WS_EX_STATICEDGE PUSHBUTTON "&About", 103, 55, 55, 44, 12, BS_CENTER | WS_GROUP, WS_EX_STATICEDGE PUSHBUTTON "&Exit", 104, 104, 55, 44, 12, BS_CENTER | WS_GROUP, WS_EX_STATICEDGE LTEXT "Created by FiNS", 0, 154, 56, 53, 10, WS_DISABLED } 30 ICON "fins.ico" Ikonkę daj taką jaką masz i zmień tu jej nazwę. Popraw też ścieżkę do kompilatora (jeżeli jest taka potrzeba). Całość zapisz w pliku o nazwie np. keygen.rc. To by było na tyle w sprawie wyglądu naszego proga. 5. Piszemy kod Otwórz sobie dowolny edytor tekstu np. notepad albo Quick Editor dołączony do masma i napisz to, co zwykle jest na początku proga: .486 .model flat, stdcall option casemap:none include \masm32\include\windows.inc include \masm32\include\kernel32.inc include \masm32\include\user32.inc include \masm32\include\gdi32.inc includelib \masm32\lib\kernel32.lib includelib \masm32\lib\user32.lib includelib \masm32\lib\gdi32.lib I jeszcze sekcję .const: .const DIALOG_ID =10 ICON_ID =30 EDITN_ID =100 EDITS_ID =101 GENERATE_ID =1 ABOUT_ID =103 EXIT_ID =104 Właściwie to deklaracja stałych nie jest konieczna, ale to bardzo ułatwia dalsze pisanie. Nie musisz pamiętać liczb tylko nazwy, które sam nadajesz. Dzięki temu, że przycisk Generate ma ID=1, to naciśnięcie entera zadziała tak, jakbyśmy nacisnęli właśnie ten przycisk. Mam nadzieję, że wiesz, o co mi chodzi. Teraz piszemy sekcje z danymi: .data? hInstance dd 4 dup (?) myname db 64 dup (?) serial db 64 dup (?) .data tytulmsgbox db 'About',0 tekstmsgbox db 'CrackMe2 by massh^CookieCrK - keygen',13,10 db ' ',13,10 db 'Created by:',13,10 db 'FiNS - finsss@wp.pl',0 hInstance jest nam potrzebne do utworzenia okienka dialogowego. Do myname będziemy pobierać podanego nicka, a w serial zapisywać wygenerowany numerek. Po kliknięciu na About będzie się pokazywać messagebox z infem z sekcji .data. To wszystkie dane jakie są nam potrzebne. Możemy już przystąpić do pisania kodu: .code start: push 0 call GetModuleHandleA mov hInstance, eax push 0 push offset DlgProc push 0 push DIALOG_ID push hInstance call DialogBoxParamA push 0 call ExitProcess Jeżeli nie pisałeś wcześniej żadnego proga, to może teraz pomyślisz, że coś ten ExitProcess za szybko. Nie ma niczego, co by generowało seriala, właściwie to niczego nie ma. Tak naprawdę wszystko dzieje się w DlgProc, którą zaraz napiszemy. DlgProc proc uses esi edi ebp ebx, hDlg:DWORD, uMsg:DWORD, wParam:DWORD, lParam:DWORD ;...tu będziemy pisać resztę kodu... powrot: xor eax, eax ret DlgProc endp end start Jeżeli w tej chwili masz zrobione wszystko, co opisałem do tej pory, to możesz zapisać obecny kod w pliku np. keygen.asm (proponuję dać taką samą nazwę jaką dałeś plikowi .rc) i skompilować całość. W tej chwili nasz prog powinien się już uruchomić, ale nic nie będzie robił, nawet nie będzie się go dało normalnie zamknąć, jedynie przez ctrl+alt+del. Warto jednak zobaczyć jak wygląda i czy rzeczywiście się uruchamia (będziesz wiedział, czy czegoś nie namieszałeś po drodze :)). Całość moim skromnym zdaniem najlepiej kompilować plikiem wsadowym makeit.bat, który zawiera takie instrukcje: set file=keygen \masm32\bin\rc /v %file%.rc \masm32\bin\ml /c /coff /Cp %file%.asm \masm32\bin\link.exe /SUBSYSTEM:WINDOWS /LIBPATH:\masm32\lib %file%.obj %file%.res del *.obj del *.res %file%.exe Jeżeli musisz, to popraw ścieżkę do masma i nazwę pliku (tu: "keygen"). Jeśli prog się nie kompiluje, to sprawdź, czy nie znalazło ci jakichś błędów przy kompilacji. Jak znalazło, to przeczytaj w której lini, porównaj z tym co ja tu napisałem i popraw błąd. Zakładam, że wszystko się udało i program jest włączony. Możesz się napatrzeć i posprawdzać jak wszystko działa (a raczej jak nie działa ;)) Zamknij keygena i wracamy do pisania kodu. Ustaw kursor linijkę przed retem, w miejscu gdzie napisałem ;...tu będziemy... (chyba nie muszę mówić, że to masz usunąć) i piszemy w tym miejscu taki kod: cmp uMsg, WM_INITDIALOG jz initdlg cmp uMsg, WM_CLOSE jz close cmp uMsg, WM_COMMAND jz wmcommand cmp uMsg, WM_MOUSEMOVE je move Nie wiesz, co to jest? Nie przejmuj się, bo ja też nie wiem ;) a tak na serio, to tu jest sprawdzane zdarzenie jakie zostało wykonane (np. czy kliknięto na przycisk Generate itp.). WM_INITDIALOG wykonuje się podczas włączania okienka. Będzie nam potrzebne, bo my chcemy mieć na pasku tytułowym naszą ikonkę, a nie jakiś śmieć z wina. WM_CLOSE służy do zamykania proga. WM_COMMAND to np. naciśnięcie jakiegoś przycisku. WM_MOUSEMOVE posłuży nam do zrobienia takiej małej i fajnej rzeczy, mianowicie będziemy mogli poruszać oknem łapiąc je w dowolnym miejscu (poza przyciskami i polem edit), a nie tylko za pasek tytułowy. Po tych instrukcjach zostawiamy naszego xora i reta, a za nim piszemy dalszy kod: initdlg: push ICON_ID push hInstance call LoadIconA push eax push 1 push WM_SETICON push hDlg ;ten kod wrzuca naszą call SendMessageA ;ikonkę na pasek tytułowy jmp powrot close: push 0 push hDlg call EndDialog ;zamykanie okna jmp powrot move: cmp wParam, 1 je moveform jmp powrot moveform: call ReleaseCapture push 0 push 0F012h push WM_SYSCOMMAND push hDlg ;poruszanie oknem, call SendMessageA ;o którym mówiłem wcześniej jmp powrot wmcommand: cmp wParam, GENERATE_ID jz go cmp wParam, ABOUT_ID jz about cmp wParam, EXIT_ID ;sprawdza czy naciśnięto jz close ;któryś z przycisków jmp powrot about: push MB_ICONINFORMATION push offset tytulmsgbox push offset tekstmsgbox push hDlg call MessageBoxA ;wyświetlanie okienka about jmp powrot Teraz jest najważniejsza część proga. Wykonuje się ona po naciśnięciu Generate lub entera. Jej główną część napisaliśmy już wcześniej, w trzecim punkcie. Teraz dodajemy przed nią pobranie tekstu z pierwszego pola edit i wpisanie wyniku do drugiego, nieaktywnego pola edit. go: push 255 push offset myname push EDITN_ID push hDlg call GetDlgItemTextA ;pobieranie name test eax, eax ;czy coś wpisano jz koniec ;jeśli nie to nie obliczaj cmp eax, 64 ;nasze name nie może być większe jge koniec ;ani równe niż 64 znaki ;jeżeli by tego nie było, a user wpisałby ;za długiego nicka, to program by się wiechnął mov ebx, offset serial ;algorytm obliczający seriala mov eax, offset myname ;był on opisany wcześniej nastepny: movzx edx, byte ptr [eax] and edx, 0Fh shr edx, 1 add edx, 30h mov [ebx], dl inc eax inc ebx cmp byte ptr [eax], 0 jne nastepny xor eax, eax mov [ebx], eax push offset serial push EDITS_ID push hDlg ;wpisz wygenerowanego call SetDlgItemTextA ;seriala do pola edit koniec: jmp powrot DlgProc endp ;jak już to masz, to nie pisz drugi raz end start To by było na tyle. Właśnie skończyłeś pisać swojego pierwszego keygena :D Pewnie się cieszysz, ja też. Chyba nie było to wcale takie trudne :) Teraz możesz to skompilować i wypróbować jak działa. Spakowana całość (keygen.asm, keygen.rc, makeit.bat, fins.ico i wersja skompilowana) powinna być dołączona do tego tekstu. Jeżeli masz jakieś problemy ze zrobieniem tego keygena, albo jakieś pytanka, to mail me finsss@wp.pl.