|
... Masm Tutorial #2 ... |
Pulse Reversing Force |
Вие сте с вторият туториал от поредицата за MASM на Pulse Team. В него ще направите нещо далеч по-интересно от миналия MessageBox - ще направите keygen. Ще коментирам написания код отдолу за да Ви стане ясно всичко. Ако не Ви е ясно нещо, значи го има в миналия туториал или не съм го обяснил добре :), но не мисля, че съм пропуснал нещо. В този туториал има много повече API функций отколкото в миналия, затова ако нямате win32.hlp (help за всички api-ta), моля изтеглете го от тук. Отворете kgn.asm (който идва с този zip) с Qedit.exe. Сега трябва да разгледате следния код. В бяло е самият код, а в сиво коментарът: --------------------------------------------------------------------------------------------------------- .386
.model flat, stdcall
option casemap :none
include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
WndProc PROTO :DWORD,:DWORD,:DWORD,:DWORD ; Горният ред представлява прототип на процедура. ; За разлика от езиците от високо ниво MASM задължава потребителя да прави прототипи на ; процедурите за да покаже на компилатора колко параметъра да търси и от какъв тип са те. ; Синтаксис: Име PROTO :Тип на параметър1[,:Тип на параметър2] .const ; Тук са константите за идентификаторите на контролите в диалога. Константите се означават така: ; Име equ Стойност ID_GEN equ 201 ID_EXIT equ 202 ID_TXTUSER equ 101 ID_TXTSERIAL equ 102 ; Сега вместо да помните ID-тата можете да ползвате готовите константи .data ; Тук са инициализираните променливи (с начална стойност) dlgname db "keygen",0 hInstance dd 0 cnt dd 0 strlen dd 0 err db "Enter more than 5 charz",0 err2 db "Error",0 .data? ; За разлика от миналия път, сега ще използвам секцията за неинициализирани промнеливи ; за да отделя място в паметта за серииния номер и буфера за низа по който се пресмята serial dd 5 dup(?) buff db 100 dup(?) .code start:
invoke GetModuleHandle,0
mov hInstance, eax
invoke DialogBoxParam,hInstance,offset dlgname,0,offset WndProc,0 ; Тази функция вика диалога dlgname от ресурсите към програмата. ; Процедурите в MASM (като тази отдолу) се записват по следния начин (не забравяйте за прототипа): ; ; Име_на_процедурата proc [параметър1:ТИП, параметър2:ТИП] ; ..код.. ; ret ; Име_на_процедурата endp WndProc proc hWin:DWORD,uMsg:DWORD,wParam:DWORD,lParam:DWORD ; Това е най-важната част от програмата. Когато нещо стане свързано с Вашия диалог тази процедура ; се вика. Тя има 4 параметъра: hWin, uMsg, wParam и lParam. ; hWin - това е handle-a на създадения прозорец (handle е уникален идентификатор във windows) ; uMsg - типа съобщение пратено към прозореца ex. WM_COMMAND ; wParam и lParam се променят спрямо типа пратено съобщение. За да ви стане по-ясно вижте win32.hlp ; wParam - идентификатора към който било пратено съобщението (при WM_COMMAND) ; lParam - handle-a на клик-натия конторол (при WM_COMMAND) .if uMsg == WM_COMMAND ; Тук използвам макроса .if (за улеснение :) за да сравня дали съобщението към диалога е за кликване. ; За тези които не са наясно с C++ синтаксиса има пример: ; == - равно, ! - не, != - не е равно, > - по-голямо, < - по-малко и тн... .if wParam == ID_GEN ; Ако съобщението пратено към диалога е WM_COMMAND проверява по идентификатор (ID) дали бутона за ; генериране на серииния номер е този към когото е било пратено съобщението mov serial, 0 ; Нулира всеки път серииния номер за да не се променя при повече от една калкулация invoke GetDlgItemText,hWin,ID_TXTUSER,offset buff,100 mov strlen, eax ; Взима текста въведен в текстовото поле и го слага в buff. Дължината е върната в EAX .if eax < 5 ; Ако дължината на въведеното име е по-малка от 5 символа показва съобщение и се връща invoke MessageBox,hWin,offset err,offset err2,MB_OK+MB_ICONEXCLAMATION ret .endif dec strlen ; Ако дължината на въведеното име е по-голяма или равна на 5 символа продължава, като намаля ; дулжината с 1, защото низа е нулево терминиран, а на Вас не Ви трябва нулата все пак :) mov cnt, 0 ; Нулира брояча на поредни байтове и автоматично скача на label-a отдолу. l00p: ; Следва един прост алгоритъм на пресмятане на серииния код (edx е ascii-то на поредния символ) mov ecx, cnt movsx edx, [buff+ecx] add edx, 3 dec edx xor edx, 2 imul edx, 7 add serial, edx ; Добавя измененият ascii код на поредният символ в променливата serial и inc cnt ; Увеличава брояча mov eax, strlen cmp eax, cnt ; Сравнява брояча на поредни байтове с дължината на низа. Ако не е равен повтаря всичко отново. jne l00p invoke SetDlgItemInt,hWin,ID_TXTSERIAL,serial,FALSE ; След като програмата е сумирала променените ascii кодове на символите ги ; изписва в второто текстово поле .elseif wParam == ID_EXIT ; Ако съобщението пратено към диалога е WM_COMMAND и идентификатора на бутона за ; излизане е равен на wParam - програмата излиза. invoke ExitProcess,0 .endif .elseif uMsg == WM_CLOSE invoke ExitProcess,0 ; Ако потребителят иска да затвори програмата излиза .endif xor eax, eax
ret
; Нулира eax и се връща
WndProc endp end start ; Край на програмният label и на програмата --------------------------------------------------------------------------------------------------------- Сега трябва само да натиснете Project->Build All и сте готови. Ако в папката съществува файл с името rsrc.rc MASM автоматично го свързва с програмата. Към .asm файла идва и .rc файл който можете да разгледате в notepad или направo с ms visual c++ :). Следващият туториал ще бъде за nfo viewer, така че проверявайте страницата на pulse по-често, ако ви интересува :). --------------------------------------------------------------------------------------------------------- greetz goin to : ..shade......... ..dim_cr........ ..pumqara....... ..nre........... ..sometimes..... ..buko.......... ..jeux.......... ---------------------------------------------------------------------------------------------------2k3--- Дата : 15.1о.2оо3 Автор : plux ~ PuLSe Поща : p.l.u.x@mail.bg Сайт : www.pulse-team.tk
| |