386 model flat stdcall option casemap none EXTERN GetStdHandle NEAR EX

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
.386
.model flat,stdcall
option casemap:none
EXTERN GetStdHandle@4:NEAR
EXTERN WriteConsoleA@20:NEAR
EXTERN ExitProcess@4:NEAR
; --------------- Includes
include E:\masm32\include\windows.inc
include E:\masm32\include\kernel32.inc
include E:\masm32\include\user32.inc
include E:\masm32\include\masm32.inc
; --------------- Libraries
includelib E:\masm32\lib\kernel32.lib
includelib E:\masm32\lib\user32.lib
includelib E:\masm32\lib\masm32.lib
; --------------- Procedures declarations
Main proto
; --------------- Datas section
.data
names db 'wa7er',0
STR1 DB "This a console application!"
RES DD 0
; --------------- Code section
.data?
ress db ?
LENS DD ? ;количество выведенных символов
.code
; ---------------------
; --- Program start ---
; ---------------------
start: invoke Main
invoke ExitProcess,0
; --------------
; --- Main() ---
; --------------
Main proc
xor EDI,edi
xor ESI,esi
xor ECX,ecx
MOV BL,1Ah
@1:
CMP [names+ESI],0 ; Сравниваем - уже конец строки с именем?
JE @2 ; Если да - выходим из цикла генерации
MOV AL, [names+ESI] ; Берём n-ный символ имени (точнее его ASCII
; значение (Например: A1 - это 'A')
ADD AL,CL ; Прибавляем к A1 значение CL. Здесь CL - это
; порядковый номер тек.символа в строке с именем
; Но здесь следует учесть, что нумерация идёт с 0. Т.е. в слове ViNCE буква 'N' имеет позицию
; не 3, а 2. Предположим что наша буква 'A' имела позицию в слове 3. Так что выполняется следующая
; операция:
; AL:=AL+CL=A1+03=A4
XOR AL,CL ; Здесь делаем операцию XOR над AL и CL.
; AL:=AL xor CL = A4 xor 3 = A0
DIV BL ; Делим значение AL на константу BL. Смотрим
; содержимое регистра EBX и видим в BL=1A
; Здесь не просто команда деления. Она выполняет два действия:
; - Сперва делится всё как положено: AL:=AL div BL = A0 div 1A = 06
; - Теперь вычитаем из A0 значение 1A шесть раз и получаем 04.
; - Записываем 04 в AH. В итоге получаем содержимое EAX: 00000406
SHR AX,8 ; Осуществляем сдвиг вправо в регистре AX
; и получаем из 0406 => 04
ADD AL,41 ; Прибавляем к 04 константу 41 и получаем: AL=45
;MOV [names+ESI],AL ; Из 45 получаем ещё один символ
add ress,al ; регистрационного кода: 45h => 'E'
; Здесь идут всякие счётчики
INC EDI ; CRACKME4.00403286
INC ESI
INC ECX
JMP @1
@2:
;получить HANDLE вывода
PUSH STD_OUTPUT_HANDLE
CALL GetStdHandle@4
;вывести строку
PUSH OFFSET RES ;резерв
PUSH OFFSET LENS ;выведено символов
PUSH 27 ;длина строки
PUSH OFFSET ress ;адрес строки
PUSH EAX ;HANDLE вывода
CALL WriteConsoleA@20
;invoke MessageBox,NULL,ress,"pass",MB_OK
ret
Main endp
invoke ExitProcess,0
end start