Продолжаем нашу эпопею
с полиморфизмом:
; ----[Генерация инструкций 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 ; Возврат из подпрограммы
; ------------;
Последние две техники нигде мной ранее не встречались. И хочется верить, что
разработаны они мной.
Для чего это всё может быть использовано? Об этом каждый ответит для себя сам.
Я например собираюсь на базе данного движка создать программную защиту.
После всего этого, хочется задаться закономерным вопросом: "Полиморфизм мёртв?".