Продолжаем нашу эпопею
с полиморфизмом:

; —-[Генерация инструкций MOV, XCHG —
0x87,0x89,0x8b]—-;

__mov_r32_r32:
cmp cl,2 ;
Если длина генерируемой
jge __g6__ ;
инструкции меньше 2, то
ret ;
Возврат из подпрограммы
__g6__:
mov eax,3 ;
Генерируем СЧ в 
call brandom32 ;
диапазоне 0..2

test eax,eax ; Проверяем, какой опкод мы
jnz __ng1__ ;
будем генерировать
;
Если не 0, то 0x8b

mov eax,10 ; Генерируем СЧ в 
call brandom32 ;
диапазоне 0..9

test eax,eax ; Проверяем какой опкод мы
jnz __ng2__ ;
будем генерировать
;
Если не 0, то 0x89

mov al,87h ; Будем генерировать 0x87
jmp __ag1__ ;
Идём дальше
__ng2__:
mov al,89h ;
Будем генерировать 0x89
jmp __ag1__ ;
Идём дальше
__ng1__:
mov al,8bh ;
Помещаем в al — 8bh
__ag1__:
stosb ;
Потом помещаем al в буфер
call free_reg ;
Вызываем подпрограмму 
;
получения свободных 
;
регистров
shl eax,3 ;
Умножаем eax на 8
add al,0c0h ;
Добавляем к al — 0c0h
mov dl,al ;
помещаем в dl — al
call free_reg ;
Получаем случайный регистр
add al,dl ;
Добавляем к al — dl
stosb ;
И помещаем al в буфер
;
В итоге у нас получается
;
случайно выбранная
;
инструкция MOV,
XCHG:

;
…………………………
;
mov eax,esp
;
…………………………
sub ecx,2 ;
Уменьшаем счётчик на 2
ret ;
Возврат из подпрограммы

; —-[Генерация инструкций PUSH/POP — 0x50..0x57;
0x58..0x5f]—-;

__push_r32:
mov eax,10 ;
Генерируем СЧ в
call brandom32 ;
диапазоне 0..9
mov edx,eax ;
Кладём его в edx
add al,2 ;
Добавляем
к al — 2

cmp eax,ecx ; Если длина генерируемой
jle __g7__ ;
инструкции меньше 2
;
и длины мусора ,то
ret ;
Возврат из подпрограммы
__g7__:
call free_reg ;
Получаем случайный регистр
add al,50h ;
Добавляем к al — 50h
stosb ;
Кладём al в буфер

push ecx ; Сохраняем ecx в стэке
mov ecx,edx ;
Генерируем серию
call garbage ;
мусорных инструкций
pop ecx ;
Вынимаем ecx из стэка

call free_reg ; Вызываем подпрограмму 
;
получения свободных 
;
регистров
add al,58h ;
Добавляем к al — 58h
stosb ;
И опять кладём al в буфер
;
В итоге у нас получается
;
случайно выбранная
;
инструкции
PUSH/POP:

;
…………………………
;
push eax
;
mov eax,2
;
pop ecx
;
…………………………
sub ecx,edx ;
Уменьшаем счётчик на edx
sub ecx,2 ;
Уменьшаем счётчик на — 2
ret ;
Возврат из подпрограммы

; —-[Генерация инструкций MOV — 0x0b8]——————-;

__mov_r32_imm32:
cmp cl,5 ;
Если длина генерируемой
jge __g8__ ;
инструкции меньше 5, то
ret ;
Возврат из подпрограммы
__g8__: ;  
call free_reg ;
Вызываем подпрограмму 
;
получения свободных 
;
регистров
add al,0b8h ;
Добавляем к al — 0b8h
stosb ;
И кладём al в буфер
xor eax,eax ;
Обнуляем eax
dec eax ;
Теперь eax = 0ffffffffh
call brandom32 ;
Генерируем случайное
stosd ;
число
;
В итоге у нас получается
;
случайно выбранная
;
инструкции MOV:
;
…………………………
;
mov eax,12345678
;
…………………………
sub ecx,5 ;
Уменьшаем счётчик на 5
ret ;
Возврат из подпрограммы

; —-[Генерация инструкций JMP SHORT — 0xeb]—————;

__jmp_short:
cmp cl,2 ;
Если длина генерируемой 
jg __g9__ ;
инструкции меньше 2, то
ret ;
Возврат из подпрограммы
__g9__:
mov eax,50 ;
Генерируем случайное число
call brandom32 ;
в диапазоне 0..49
push eax ;
Сохраняем его в стэке
add eax,2 ;
Добавляем длину перехода
cmp eax,ecx ;
Проверяем не больше длины
pop eax ;
Восстанавливаем из стэка
jle __gen3__ ;
Если число превышает длину
ret ;
то выходим из подпрограммы
__gen3__: ;
push eax ;
Сохраняем в стэке eax
mov al,0ebh ;
Кладём в al — 0ebh
stosb ;
И кладём al в буфер
pop eax ;
Восстанавливаем из стэка
stosb ;
Помещаем его в буфер
mov edx,eax ;
Кладём в edx — eax
push ecx ;
Сохраняем ecx в стэке
mov ecx,edx ;
Генерируем рекурсивно
call garbage ;
мусор между переходом
pop ecx ;
Восстанавливаем ecx
;
В итоге у нас получается
;
случайно выбранная
;
инструкции JMP
SHORT:

;
…………………………
;
jmp next
;
mov ax,22
;
next: nop
;
…………………………
sub ecx,2 ;
Уменьшаем счётчик на 2
sub ecx,edx ;
И на длину инструкций
;
ret ;
Возврат из подпрограммы

; —-[Генерация инструкций ADD — 0x81]———————;

__add_r32_imm32:
cmp cl,6 ;
Если длина генерируемой
jge g10__ ;
инструкции меньше 6, то
ret ;
Возврат из подпрограммы
g10__:
mov al,81h ;
Кладём в al — 81h
stosb ;
И помещаем al в буфер
mov eax,4 ;
Получаем случайное число
call brandom32 ;
в диапазоне от 0..9
add al,0ch ;
Добавляем к нему — 0ch
shl al,4 ;
Умножаем al на 16
mov dl,al ;
Кладём в dl — al
mov eax,2 ;
Получаем случайное число
call brandom32 ;
в диапазоне от 0..1
shl al,3 ;
Умножаем al на 8
add dl,al ;
Добавляем к dl — al
call free_reg ;
Вызываем подпрограмму 
;
получения свободных 
;
регистров
add al,dl ;
Добавляем к al — dl
stosb ;
И кладём al в буфер
xor eax,eax ;
Обнуляем eax
dec eax ;
Теперь eax = 0ffffffffh
call brandom32 ;
Генерируем случайное
stosd ;
число и кладём его в буфер
;
В итоге у нас получается
;
случайно выбранная
;
инструкции ADD:
;
…………………………
;
add eax,12345678
;
…………………………
sub ecx,6 ;
Уменьшаем счётчик на 6
ret ;
Возврат из подпрограммы

; —-[Генерация инструкций LEA — 0x8d]———————;

__lea_r32_imm32:
cmp cl,6 ;
Если длина генерируемой
jge __g11__ ;
инструкции меньше 6, то
ret ;
Возврат из подпрограммы
__g11__:
mov al,8dh ;
Кладём в al — 8dh
stosb ;
И помещаем al в буфер
call free_reg ;
Вызываем подпрограмму 
;
получения свободных 
;
регистров
shl eax,3 ;
Умножаем eax на — 8
add al,5 ;
Добавляем к al — 5
stosb ;
И кладём al в буфер
xor eax,eax ;
Обнуляем eax
dec eax ;
Теперь eax = 0ffffffffh
call brandom32 ;
Генерируем случайное число
stosd ;
И кладём его в буфер
;
В итоге у нас получается
;
случайно выбранная
;
инструкции LEA:
;
…………………………
;
lea eax,[12345678]
;
…………………………
sub ecx,6 ;
Уменьшаем счётчик на 6
ret ;
Возврат из подпрограммы

; —-[Генерация инструкций CALL NEAR — 0xe8]—————;

__call_near:
mov eax,50 ;
Генерируем случайное число
call brandom32 ;
в диапазоне 0..49
mov edx,eax ;
И кладём его в edx

mov eax,50 ; Генерируем случайное число
call brandom32 ; в диапазоне 0..49

push eax ; Сохраняем его в стэке

add eax,11 ; Добавляем длину перехода

add eax,edx ;
Добавляем к eax — edx
cmp eax,ecx ;
Проверяем не больше длины
pop eax ;
Восстанавливаем из стэка
jle __gen4__ ;
Если число превышает длину, то
ret ;
Возврат из подпрограммы
__gen4__: 
push edx ;
Сохраняем в стэке edx
push eax ;
Сохраняем в стэке eax
mov al,0e8h ; Кладём в al — 0e8h
stosb ; И помещаем al в буфер
mov eax,[esp] ; Восстанавливаем eax
inc eax ; Увеличиваем eax на — 1
stosd ; Кладём eax в буфер
xor eax,eax ; Обнуляем eax
dec eax ; Теперь в eax — 0ffffffffh
call brandom32 ; Генерируем СЧ и
stosb ; Кладём его в буфер
pop edx ; Вынимаем из стэка в edx
push ecx ; Сохраняем ecx в стэке
mov ecx,edx ; Генерируем рекурсивно
call garbage ; мусор между переходом
pop ecx ; Восстанавливаем ecx

mov al,55h ;  
stosb ; Кладём в буфер 055h
mov ax,0ec8bh ;  
stosw ; Кладём в буфер 0ec8bh

push edx ; Кладём edx в стэк

mov edx,[esp+4] ; Вынимаем из стэка в edx
push ecx ; Сохраняем ecx в стэке
mov ecx,edx ; Генерируем рекурсивно
call garbage ; мусор между переходом
pop ecx ; Восстанавливаем ecx

mov al,5dh ; Кладём в буфер 05dh
stosb ;  

call free_reg ; Вызываем подпрограмму 
; получения свободных 
; регистров
add al,58h ; Добавляем к al — 58
stosb ; И опять кладём al в буфер
; В итоге у нас получается
; случайно выбранная
; инструкция CALL NEAR:
; …………………………
; mov eax,12345678h
; call next
; add edx,34567h
; next:
; push ebp
; mov ebp,esp
; xor eax,edx
; pop ebp
; pop edx
; …………………………
sub ecx,11 ; Уменьшаем счётчик на 11
pop edx ; Вынимаем из стэка в edx
sub ecx,edx ; Уменьшаем на длину инструкций
pop edx ; Вынимаем из стэка в edx
sub ecx,edx ; Уменьшаем на длину инструкций
;
ret ; Возврат из подпрограммы

; —-[Генерация инструкций SHL — 0xc1]———————;

__shl_r32_imm8:
cmp cl,3 ; Если длина генерируемой
jge __g12__ ; инструкции меньше 3, то
ret ; Возврат из подпрограммы
__g12__:
mov al,0c1h ; Кладём в al — 0c1h
stosb ; И помещаем al в буфер
mov eax,6 ; Генерируем случайное число
call brandom32 ; в диапазоне 0..5
shl eax,3 ; Умножаем его на 8
add al,0c0h ; Добавляем к нему — 0c0h
mov dl,al ; Помещаем в dl — al
call free_reg ; Вызываем подпрограмму 
; получения свободных 
; регистров
add al,dl ; Добавляем к al — dl
stosb ; И помещаем al в буфер
mov eax,256 ; Генерируем случайное число
call brandom32 ; в диапазоне 0..255
stosb ; И кладём его в буфер
; В итоге у нас получается
; случайно выбранная
; инструкции SHL,ROL, …:
; …………………………
; shl ebp,04
; …………………………
sub ecx,3 ; Уменьшаем счётчик на 3
ret ; Возврат из подпрограммы

; —-[Генерация иструкций XADD — 0x0f 0x0a3 …]———-;

__xadd_r32_r32:
cmp cl,3 ; Если длина генерируемой
jge __g13__ ; инструкции меньше 6, то
ret ; Возврат из подпрограммы
__g13__:
mov al,0fh ; Кладём в al — 0fh
stosb ; И помещаем al в буфер
lea esi,[ebp+__3_byte_opcode]; Кладём в esi указатель на
; таблицу частей 3-х байтных
; инструкций
mov eax,14 ; Генерируем случайное число
call brandom32 ; в диапазоне 0..13
add esi,eax ; Прибавляем к esi — eax 

movsb ; Перемещаем байт в буфер

mov dl,0c0h ; Кладём в dl — 0с0h

call free_reg ; Вызываем подпрограмму 
; получения свободных 
; регистров
shl eax,3 ; Умножаем eax на 8
add dl,al ; Добавляем к dl — al
call free_reg ; Вызываем подпрограмму 
; получения свободных 
; регистров
add al,dl ; Добавляем к al — dl
stosb ; И помещаем al в буфер
; В итоге у нас получается
; случайно выбранная
; инструкции XADD,IMUL, …:
; …………………………
; xadd eax,eax
; …………………………
sub ecx,3 ; Уменьшаем счётчик на 3
ret ; Возврат из подпрограммы

; —-[Генерация инструкций MOV — 0x66 0xb8..0xbf]———;

__mov_r16_imm16:
cmp cl,4 ; Если длина генерируемой
jge __g14__ ; инструкции меньше 4, то
ret ; Возврат из подпрограммы
__g14__:
mov al,066h ; Кладём в al — 066h
stosb ; И помещаем al в буфер
mov dl,0b8h ; Помещаем в dl — 0b8h
call free_reg ; Вызываем подпрограмму 
; получения свободных 
; регистров
add al,dl ; Добавляем к al — dl
stosb ; И помещаем al в буфер
xor eax,eax ; Обнуляем eax
dec eax ; Теперь в eax — 0ffffffffh
call brandom32 ; Генерируем СЧ
stosw ; И помещаем его в буфер
; В итоге у нас получается
; случайно выбранная
; инструкции MOV:
; …………………………
; mov ax,3452
; …………………………
sub ecx,4 ; Уменьшаем счётчик на 4
ret ; Возврат из подпрограммы

; —-[Генерация инструкций CMOVA — 0x0f 0x40..0x4f]——-;

__cmova_r32_r32:
cmp cl,3 ; Если длина генерируемой
jge __g15__ ; инструкции меньше 6, то
ret ; Возврат из подпрограммы
__g15__:
mov al,0fh ; Кладём в al — 0fh
stosb ; И помещаем al в буфер
mov eax,15 ; Генерируем случайное число
call brandom32 ; в диапазоне 0..14
add al,40h ; Добавляем к al — 40h
stosb ; И помещаем al в буфер
call free_reg ; Берём случайный регистр
shl eax,3 ; Умножаем его на 8
add al,0c0h ; Добавляем к нему — 0c0h
mov dl,al ; Помещаем в dl — al
call rnd_reg ; Вызываем подпрограмму 
; получения свободных 
; регистров
add al,dl ; Добавляем к al — dl
stosb ; И помещаем al в буфер
; В итоге у нас получается
; случайно выбранная
; инструкции CMOVA:
; …………………………
; cmova eax,edx
; …………………………
sub ecx,3 ; Уменьшаем счётчик на 3
ret ; Возврат из подпрограммы

; —-[Генерация инструкций PUSH/POP — 0x6a, 0x0ff 0x0f0..0x0f7;
0x58..0x5f]——;

__push_r32_2:
mov eax,10 ; Генерируем СЧ
call brandom32 ; в диапазоне 0..9
mov edx,eax ; Кладём в edx — eax
add al,3 ; Добавляем к al — 3

cmp eax,ecx ; Если длина генерируемых
jle __g16__ ; инструкций меньше ,то
ret ; Возврат из подпрограммы
__g16__:
mov eax,4 ; Генерируем СЧ
call brandom32 ; в диапазоне 0..3
test eax,eax ; Если оно не равно 0, то
jnz __ng3__ ; Переходим на метку __ng3__

mov al,6ah ; Кладём в al — 06ah
stosb ; Помещаем al в буфер
xor eax,eax ; Обнуляем eax
dec eax ; Теперь в eax — 0ffffffffh
call brandom32 ; Генерируем СЧ
stosb ; Кладём в буфер
jmp __gen5__ ; Идём на генерацию мусора
__ng3__:
push edx ; Сохраняем в стэке edx

mov al,0ffh ; Кладём в al — 0ffh
stosb ; И помещаем al в буфер
mov dl,0f0h ; Кладём в dl — 0f0h
call free_reg ; Получаем свободный регистр 
add al,dl ; Добавляем к al — dl
stosb ; И помещаем al в буфер

pop edx ; Вынимаем из стэка edx
__gen5__:
push ecx ; Сохраняем ecx в стэке
mov ecx,edx ; Кладём в ecx — edx
call garbage ; Генерируем серию мусора
pop ecx ; Восстанавливаем ecx из стэка

call free_reg ; Вызываем подпрограмму 
; получения свободных 
; регистров
add al,58h ; Добавляем к al — 58h
stosb ; И опять кладём al в буфер
; В итоге у нас получается
; случайно выбранная
; инструкции PUSH/POP:
; …………………………
; push eax
; mov eax,2345
; pop ecx
; …………………………
sub ecx,edx ; Уменьшаем счётчик на edx
sub ecx,3 ; Уменьшаем счётчик на 3
ret ; Возврат из подпрограммы

; —-[Генерация инструкций PUSH — 0x68,0x58..0x5f]———;

__push_imm32:
mov eax,10 ; Генерируем СЧ в
call brandom32 ; диапазоне 0..9
mov edx,eax ; Помещаем в edx — eax
add al,6 ; Добавляем к al — 6

cmp eax,ecx ; Если длина генерируемых
jle __g17__ ; инструкций меньше, то
ret ; Возврат из подпрограммы
__g17__:
mov al,68h ; Кладём в al — 68h
stosb ; Помещаем al в буфер 
xor eax,eax ; Обнуляем eax
dec eax ; Теперь в eax — 0ffffffffh
call brandom32 ; Генерируем СЧ
stosd ; Кладём его в буфер

push ecx ; Сохраняем ecx в стэке
mov ecx,edx ; Кладём в ecx — edx
call garbage ; Генерируем серию мусора
pop ecx ; Восстанавливаем ecx из стэка

call free_reg ; Вызываем подпрограмму 
; получения свободных 
; регистров
add al,58h ; Добавляем к al — 58h
stosb ; И опять кладём al в буфер
; В итоге у нас получается
; случайно выбранная
; инструкции PUSH/POP:
; …………………………
; push eax
; add eax,42346
; pop ecx
; …………………………
sub ecx,edx ; Уменьшаем счётчик на edx
sub ecx,6 ; Уменьшаем счётчик на 6
ret ; Возврат из подпрограммы

; —-[Генерация однобайтовых инструкций — 0x40..0x4f;
0x0f2; 0x0f3…]————;

__one_byte:
mov eax,3 ; Генерируем случайное число
call brandom32 ; в диапазоне 0..2

cmp al,1 ; Если число = 1, то 
jne __not_inc_ ; генерируем инструкцию INC

call free_reg ; Вызываем подпрограмму 
; получения свободных 
; регистров
add al,40h ; Добавляем к al — 40h
stosb ; Помещаем al в буфер
; В итоге у нас получается
; случайно выбранная
; инструкции INC:
; …………………………
; inc eax
; inc ebp
; …………………………
jmp __q__ ; Идём на выход
__not_inc_:

cmp al,2 ; Если число = 2, то
jne __not_dec_ ; Идём на выход

call free_reg ; Вызываем подпрограмму 
; получения свободных 
; регистров
add al,48h ; Добавляем к al — 48h
stosb ; Помещаем al в буфер
; В итоге у нас получается
; случайно выбранная
; инструкции DEC:
; …………………………
; dec eax
; …………………………
jmp __q__ ; Идём на выход
__not_dec_:

lea esi,[ebp+__1_byte_opcode]; Кладём в esi указатель на
; таблицу однобайтных
; инструкций
mov eax,8 ; Генерируем случайное число
call brandom32 ; в диапазоне 0..7
add esi,eax ; Прибавляем к esi — eax 
movsb ; Помещаем инструкцию
; из таблицы в буфер
; В итоге у нас получается
; случайно выбранная
; инструкция из таблицы:
; ………………………..
; cld 
; nop 
__q__: ; ………………………..
dec ecx ; Уменьшаем ecx на единицу
ret ; Возврат из подпрограммы

; —-[Подпрограмма получающая случайный свободный регистр]———————;

free_reg: 
; Подпрограмма получения
; свободного регистра

push edx ecx ; Сохраняем в стэке edx, ecx
another: ;

call rnd_reg ;
bt ebx, eax ; Определяем используемый
jc another ; случайный регистр

pop ecx edx ; Восстанавливаем ecx, edx
ret ; Возврат из подпрограммы

; —-[Подпрограмма получающая случайный регистр]———-;

rnd_reg: 
; Подпрограмма получения
; случайного регистра

mov eax,8 ; Получаем случайное число
call brandom32 ; в диапазоне 0..7
ret ; Возврат из подпрограммы

; —-[Таблица смещений на подпрограммы]——————-;

mega_table:
dw __x87 -__st__ ;
dw __mov_r32_r32 -__st__ ;  
dw __push_r32 -__st__ ;  
dw __push_r32_2 -__st__ ;  
dw __push_imm32 -__st__ ;  
dw __shl_r32_imm8 -__st__ ;  
dw __cmp_r32_r32 -__st__ ;
dw __xor_r32_r32 -__st__ ;
dw __one_byte -__st__ ;
dw __mov_r32_imm32 -__st__ ;
dw __jxx_short -__st__ ; Таблица относительных
dw __jxx_near -__st__ ; смещений от метки 
dw __add_r32_imm32 -__st__ ; delta_offset
dw __jmp_short -__st__ ;
dw __lea_r32_imm32 -__st__ ;
dw __test_r32_r32 -__st__ ;
dw __not_r32 -__st__ ;
dw __xadd_r32_r32 -__st__ ;
dw __mov_r16_imm16 -__st__ ;
dw __cmova_r32_r32 -__st__ ;  
dw __call_near -__st__ ;

; —-[Таблица однобайтовых опкодов]————————;

__1_byte_opcode:
std ;
cld ; Таблица однобайтовых
nop ; инструкций
clc ;
stc ;
cmc ;
db 0f2h ; rep
db 0f3h ; repnz

; —-[Таблица трёхбайтовых опкодов]————————;

__3_byte_opcode:
db 0a3h,0abh,0adh,0b3h,0bbh,0bdh,0bfh ; Таблица трёхбайтовых
db 0b6h,0b7h,0beh,0afh,0bch,0c1h,0bdh ; инструкций

; —-[Таблица мат. ожиданий опкодов]———————-;

__freq_table:
dw 10 ; x87(0xdc)
dw 209 ; mov r32,r32(0x8b)
dw 107 ; push r32/pop r32(0x50)
dw 147 ; push r32(0xff,0x6a)
dw 32 ; push imm32(0x68)
dw 6 ; ror/shl r32,imm8(0xc1)
dw 5 ; cmp r32,r32(0x3ah)
dw 43 ; xor r32,r32(0x33)
dw 8 ; rep/repnz(0xf3)
dw 22 ; mov r32,imm32(0xb8)
dw 82 ; je short(0x70..0x7fh)
dw 18 ; je near(0x0f)
dw 78 ; add/or r32,imm32(0x81..0x85)
dw 30 ; jmp short(0xeb)
dw 63 ; lea r32,imm32(0x8d)
dw 1 ; test r32/r8,r32/r8(0x84,0x85)
dw 1 ; not/neg(0xf7)
dw 23 ; xadd/imul r32,r32(0x0f)
dw 6 ; mov r16,imm16(0x66)
dw 13 ; cmova r32,r32(0x0f)
dw 95 ; call near(0xe8)

; —-[Количество поколений]——————————-;

__generation dd 9

; —-[Наследственность]————————————;

__cross1 dd 0
__cross2 dd 0

; —-[Определения регистров]——————————;

_eax equ 00000001h ;
_ecx equ 00000002h ;
_edx equ 00000004h ;
_ebx equ 00000008h ;
_esp equ 00000010h ; Определения регистров
_ebp equ 00000020h ; спасибо Z0MBiE 🙂
_esi equ 00000040h ;
_edi equ 00000080h ;
; ————;

Для работы данного движка необходима новая версия — ГЕНЕРАТОР СЛУЧАЙНОГО ЧИСЛА.

; ;
; %%%%%;
; ГЕНЕРАТОР СЛУЧАЙНОГО ЧИСЛА V. 0.3 (x) 2004 СЛОН http://slon.wronger.com ;
; %%%%%;
; Интервал: [0..eax-1] ;
; ————;
; Использование: call r_init ;
; mov eax,ГРАНИЦА ИНТЕРВАЛА ;
; call brandom32 ;
; ————;
; Результат: число в интервале [0..ГРАНИЦА ИНТЕРВАЛА]
;
; %%%%%;

; —-[Подпрограмма инициализации генератора случайных чисел]—-;

r_init:
push ebp eax edx ; Сохраняем в стэке ebp,eax,edx

call __delta1_ ;
__delta1_: pop ebp ; Получение дельта смещения
sub ebp,offset __delta1_ ;

db 0fh,031h ; Получаем случайное зерно
mov rand_seed,eax ;

pop edx eax ebp ; Восстанавливаем edx,eax,ebp

ret ; Возврат из подпрограммы


; —-[Подпрограмма генерации случаного чмсла в диапазоне]—-;

brandom32: ; Эта подпрограмма 
; возвращает случайное число
; в диапазоне 0..eax-1

push edx ecx ebp ; Сохраняем в стэке edx,ecx,ebp

call __delta2_ ;
__delta2_: pop ebp ; Получение дельта смещения
sub ebp,offset __delta2_ ;

imul eax,eax,100 ; Умножаем eax на 100
push eax ; и сохраняем eax в стэке

call random32 ; Вызываем подпрограмму
; генерации случайного числа
xor edx,edx ; Обнуляем edx
pop ecx ; Восстанавливаем значение
; из стэка в ecx
div ecx ; Делим eax на ecx
xchg eax,edx ; Помещаем остаток в eax
xor edx,edx ; Обнуляем edx
push 100 ; Помещаем в ecx — 100
pop ecx ;
div ecx ; Делим eax на ecx
pop ebp ecx edx ; Восстанавливаем ebp,ecx,edx,
ret ; Возврат из подпрограммы

; —-[Подпрограмма генерации случайного числа]—-;

random32:
push ebp

call __delta3_ ;
__delta3_: pop ebp ; Получение дельта смещения
sub ebp,offset __delta3_ ;

mov eax,12345678h ;
rand_seed= dword ptr $-4 ;  
imul eax,00019660Dh ;  
add eax,03C6EF35Fh ; Математические операции для
mov [ebp+rand_seed],eax ; получения случайного числа
shr eax,16 ;
imul eax,[esp+4] ;

pop ebp

retn ; Возврат из подпрограммы

; ————;

Последние две техники нигде мной ранее не встречались. И хочется верить, что
разработаны они мной.

Для чего это всё может быть использовано? Об этом каждый ответит для себя сам.
Я например собираюсь на базе данного движка создать программную защиту.
После всего этого, хочется задаться закономерным вопросом: «Полиморфизм мёртв?».

Оставить мнение

Check Also

Как крадут деньги при ICO. Разбираем типовые сценарии похищения средств и самих ICO

В 2017 году киберпреступникам удалось украсть 10% всех средств, инвестированных в ICO чере…