В свое время я не нашел статей на эту тему, а писать на Delphi или СРР не очень удобно(по крайней мере мне), да и размер файла получается большой. Пришлось разбираться самому. Это не сложно, когда знаешь как. Эта статья для тех, кто еще не знает :) Итак. Нам понадобится Masm32, который можно скачать с: http://www.protools.cjb.net/ Я предполагаю, что читатель знает ассемблер и способен вычислить алгоритм регистрации программы, или хотя бы найти байт, который надо заменить, чтобы избавить программу от такого бага, как регистрация. Предположим, что я вычислил алгоритм регистрации: регномер это длина имени, умноженаая на 1000. Тупо? Да, но это я встретил в программе, автор которой хотел 95.95$ за свое творение :) Так обломаем его! ;-)) Кстати, если кто думает что все кейгены такие простые то он оооооочень сильно ошибается. Итак, вот образец кейгена : ________________________начало keygen.asm__________________________________ .486 .model flat, stdcall option casemap :none ; case sensitive ; ######################################################################### ; здесь подключаются стандартные библиотеки include \masm32\include\windows.inc include \masm32\include\user32.inc include \masm32\include\kernel32.inc include \masm32\include\gdi32.inc include \masm32\include\masm32.inc includelib \masm32\lib\user32.lib includelib \masm32\lib\kernel32.lib includelib \masm32\lib\gdi32.lib includelib \masm32\lib\masm32.lib ; ######################################################################### szText MACRO Name, Text:VARARG LOCAL lbl jmp lbl Name db Text,0 lbl: ENDM ;########################################################################## WndProc PROTO :DWORD,:DWORD,:DWORD,:DWORD Edit1Proc PROTO :DWORD,:DWORD,:DWORD,:DWORD ;Edit1Proc - процедура для ограничения длины вводимой строки .data w1 db "This keygen was written for education purpose and for learning programming tricks only. Not for cracking, not for something else ;) You may use it only if you legally bought the software.",0 ;Все в w1 должно быть в ОДНУ строчку! Я поставил в несколько строк только для ; удобства чтения. w2 db "READ IT FIRST - IT IS IMPORTANT",0 a db "Hey",0 b db "Did you forgot something?",0 b1 db "String must be 10 symbols long!",0 hWnd dd 0 hEdit1 dd 0 ; EditBox1 hEdit2 dd 0 ; EditBox2 hButn1 dd 0 ; Button1 hButn2 dd 0 ; Button2 hButn3 dd 0 ; Button3 hInstance dd 0 hIconImage dd 0 ;для иконки hIcon dd 0 ;для иконки lpfnEdit1Proc dd 0 dlgname db "TESTWIN",0 fMtStrinG db "%lu",0 ; ######################################################################### .code start: invoke GetModuleHandle, NULL mov hInstance, eax invoke DialogBoxParam,hInstance,ADDR dlgname,0,ADDR WndProc,0 invoke ExitProcess,eax ; ######################################################################### WndProc proc hWin :DWORD, uMsg :DWORD, wParam :DWORD, lParam :DWORD ; Сейчас будут обьявляться переменные: LOCAL Lon :DWORD LOCAL SerB[64] :BYTE ;буфер для реномера LOCAL NameB[64] :BYTE ;буфер для имени pusha ;это должно быть для win2k .if uMsg == WM_INITDIALOG mov eax, hWin mov hWnd, eax szText dlgTitle,"KEY GENERATOR for" ;это у меня будет заголовок invoke SendMessage,hWin,WM_SETTEXT,0,ADDR dlgTitle ;программы - title invoke LoadIcon,hInstance,200 mov hIcon, eax invoke SendMessage,hWin,WM_SETICON,1,hIcon ;рисуем иконку invoke GetDlgItem,hWin,100 mov hEdit1, eax ;---------------------------------------- invoke SetWindowLong,hEdit1,GWL_WNDPROC,Edit1Proc ;вызов процедуры Edit1Proc mov lpfnEdit1Proc, eax invoke GetDlgItem,hWin,101 mov hEdit2, eax invoke GetDlgItem,hWin,1000 mov hButn1, eax invoke GetDlgItem,hWin,1001 mov hButn2, eax invoke GetDlgItem,hWin,1002 mov hButn3, eax .elseif uMsg == WM_COMMAND ;если нажата button3 то появляется MessageBox .if wParam == 1002 invoke MessageBox,0,ADDR w1,ADDR w2,MB_OK .endif .if wParam == 1000 ;------------------------------------------------------ invoke GetWindowText,hEdit1,ADDR NameB,40 ;содержимое EditBox1 переносится ;в NameB invoke lnstr,ADDR NameB ;функция masm32.lib, возвращает ;длину строки в EAX mov Lon,eax cmp eax,0 jz _short ;проверка на пустую строку ;---------------------ALGO----------------------------- ;тут будет алгоритм imul eax,1000 ;в Masm32 можно ставить десятичные значения, но без h на конце mov Lon,eax invoke dwtoa,Lon,ADDR SerB ;dwtoa - преобразует dw значение в строку ;Все! Вот и весь кейген. Правда просто? :) ; --------------------ALGO----------------------------- jmp _cool _cool: invoke SetWindowText,hEdit2,ADDR SerB ; в EditBox2 помещаем SerB jmp _end _short: invoke MessageBox,0,ADDR b,ADDR a,MB_OK _end: .elseif wParam == 1001 ; the exit button jmp GetOutaHere .endif .elseif uMsg == WM_CLOSE ; for system close button GetOutaHere: invoke EndDialog,hWin,0 .endif popa ;для вин2к, xor eax, eax ;для NT4, рекомендую всегда ставить эти две инструкции ret WndProc endp ; ######################################################################### Edit1Proc proc hCtl :DWORD, uMsg :DWORD, wParam :DWORD, lParam :DWORD LOCAL tl:DWORD LOCAL testBuffer[16]:BYTE ; ----------------------------- ; Process control messages here ; ----------------------------- .if uMsg == WM_CHAR .if wParam == 8 ; allow backspace jmp @F ; jump FORWORD to next @@: .endif invoke GetWindowText,hCtl,ADDR testBuffer,16 invoke lnstr,ADDR testBuffer .if eax >= 10 ; ограничение до десяти символов xor eax, eax ret .endif ; ------------------ ; ; .if wParam < 30h ограничение - можно вводить только цифры ; xor eax, eax В данном случае не нужно ; ret ; .elseif wParam > 39h ; xor eax, eax ; ret ; .endif @@: .endif invoke CallWindowProc,lpfnEdit1Proc,hCtl,uMsg,wParam,lParam ret Edit1Proc endp end start _____________________________конец keygen.asm________________________________________ Вот файл с параметрами окошек и кнопочек: Меняйте числа, смотрите что происходит и вам станет ясно какой параметр за что отвечает. _____________________________начало rsrc.rc___________________________________________ #include "\masm32\include\resource.h" ;основное окно 170 в длину и 120 в ширину TESTWIN DIALOGEX MOVEABLE IMPURE LOADONCALL DISCARDABLE 10, 10, 170, 120, 0 STYLE 0x0004 | DS_CENTER | WS_CAPTION | WS_SYSMENU | WS_VISIBLE | WS_POPUP CAPTION "Dialog" FONT 8, "MS Sans Serif", 700, 0 /*FALSE*/ BEGIN EDITTEXT 100,39,25,90,13, ES_AUTOHSCROLL | ES_MULTILINE | ES_LEFT, , 0 EDITTEXT 101,19,50,130,13, ES_AUTOHSCROLL | ES_LEFT, , 0 CTEXT "Click on 'Generate' and see for the serial",20,12,38,130,8,SS_LEFT, ,0 CTEXT "* Some Proggy v.Unknown *",20,12,2,130,8,SS_CENTER, ,0 CTEXT "Enter your name please ",20,1,14,160,8,SS_LEFT, , 0 CTEXT "[Cracker/Coder] --- Corbio",20,20,65,130,8,SS_LEFT, , 0 PUSHBUTTON "Generate the code", 1000, 7,80,71,15, 0, , 0 PUSHBUTTON "I'm out of here! ", 1001, 90,80,71,15, 0, , 0 PUSHBUTTON "Read is first - it is important!" , 1002, 5,100,160,15,0, ,0 END 200 ICON MOVEABLE PURE LOADONCALL DISCARDABLE "my.ico" ______________________________конец rsrc.rc___________________________________________ А теперь исходник крака: ______________________________начало крака____________________________________________ ; ######################################################################### .586 .model flat, stdcall option casemap :none ; case sensitive ; ######################################################################### include \masm32\include\windows.inc include \masm32\include\user32.inc include \masm32\include\kernel32.inc include \masm32\include\gdi32.inc include \masm32\include\masm32.inc includelib \masm32\lib\user32.lib includelib \masm32\lib\kernel32.lib includelib \masm32\lib\gdi32.lib includelib \masm32\lib\masm32.lib ; ######################################################################### ;============= ; Local macros ;============= szText MACRO Name, Text:VARARG LOCAL lbl jmp lbl Name db Text,0 lbl: ENDM ;================= ; Local prototypes ;================= WndProc PROTO :DWORD,:DWORD,:DWORD,:DWORD Edit1Proc PROTO :DWORD,:DWORD,:DWORD,:DWORD .data _filename db "fignya.exe",0 _filesize dd 1143808 ;для проверки размера файла _byte1 db 040h,090h,0 ;байты которые будем вставлять b db "Enjoy",0 a db "File cracked!",0 bN db "Error!",0 aN db "File not found!",0 bW db "Error!",0 aW db "Wrong file size. Get correct version!",0 bytes_written dd 1 hWnd dd 0 hFile dd 0 hButn1 dd 0 hButn2 dd 0 hInstance dd 0 hIconImage dd 0 hIcon dd 0 dlgname db "TESTWIN",0 ; fMtStrinG db "%lu",0 ; this is for wsprintf ; ######################################################################### .code start: invoke GetModuleHandle, NULL mov hInstance, eax ; ------------------------------------------- ; Call the dialog box stored in resource file ; ------------------------------------------- invoke DialogBoxParam,hInstance,ADDR dlgname,0,ADDR WndProc,0 invoke ExitProcess,eax ; ######################################################################### WndProc proc hWin :DWORD, uMsg :DWORD, wParam :DWORD, lParam :DWORD pusha .if uMsg == WM_INITDIALOG ; -------------------------------- ; set up required items at startup ; -------------------------------- mov eax, hWin mov hWnd, eax szText dlgTitle," CRACK for:" invoke SendMessage,hWin,WM_SETTEXT,0,ADDR dlgTitle invoke LoadIcon,hInstance,200 mov hIcon, eax invoke SendMessage,hWin,WM_SETICON,1,hIcon ; ----------------- ; subclass 1st one so text can be filtered ; ---------------------------------------- ; -------------- ; button handles ; -------------- invoke GetDlgItem,hWin,1000 mov hButn1, eax invoke GetDlgItem,hWin,1001 mov hButn2, eax ; ----------------------------------------- ; process the messages from the two buttons ; ----------------------------------------- .elseif uMsg == WM_COMMAND .if wParam == 1000 invoke exist,ADDR _filename cmp eax,0 ;проверка наличия файла jz _notfound invoke filesize,ADDR _filename cmp eax,_filesize ;проверка размера jnz _wrongsize ;откравыем файл invoke CreateFileA, offset _filename,0C0000000h,1,0,3,80h,0 mov hFile,eax ;ставим указатель на нужный адрес (075A81h) invoke SetFilePointer, hFile, 075A81h,0,FILE_BEGIN ;пишем 2 байта(02h) invoke WriteFile, hFile, OFFSET _byte1,02h, OFFSET bytes_written, 0 invoke MessageBox,0, ADDR a, ADDR b,MB_OK jmp _cool _notfound: invoke MessageBox,0,ADDR aN, ADDR bN,MB_OK jmp _cool _wrongsize: invoke MessageBox,0, ADDR aW, ADDR bW,MB_OK _cool: .elseif wParam == 1001 ; the exit button jmp GetOutaHere .endif .elseif uMsg == WM_CLOSE ; for system close button GetOutaHere: invoke EndDialog,hWin,0 .endif popa xor eax, eax ; this must be here in NT4 ret WndProc endp end start _____________________________________конец крака______________________________ ну и файлик с кнопочками: ____________________________начало rsrc.rc____________________________________ #include "\masm32\include\resource.h" TESTWIN DIALOGEX MOVEABLE IMPURE LOADONCALL DISCARDABLE 10, 10, 170, 80, 0 STYLE 0x0004 | DS_CENTER | WS_CAPTION | WS_SYSMENU | WS_VISIBLE | WS_POPUP CAPTION "Dialog" FONT 8, "MS Sans Serif", 700, 0 /*FALSE*/ BEGIN CTEXT "* Some proggy v.Unknown *",20,12,2,150,8,SS_CENTER, ,0 CTEXT "[Cracker/Coder] --- Corbio",20,20,15,115,8,SS_LEFT, , 0 CTEXT "Time limit is the history now. ;-] ",20,20,35,150,8,SS_LEFT, , 0 CTEXT "Enjoy fine release. ",20,20,45,150,8,SS_LEFT, , 0 PUSHBUTTON "Let's crack it...", 1000, 7,55,71,15, 0, , 0 PUSHBUTTON "I'm out of here! ", 1001, 90,55,71,15, 0, , 0 END 200 ICON MOVEABLE PURE LOADONCALL DISCARDABLE "my.ico" ____________________________конец rsrc.rc_____________________________________ Теперь, я надеюсь, всем все понятно. Ну вот и все. До скорых встреч. Corbio [DARKSiDE iNC] member uinC Member
[c]uinC