Since I provided a ready-to-be-assembled virus in the "'Ambulance Car'
Disassembly" article, I decided to also write a bonus article with a basic
disinfector for it. Please note that this disinfector doesn't locate and clean
all existing 'Ambulance Car' strains, though it does work on more than half of
the strains I have (thanks Cicatrix). It is only intended to work with the
strain I provided, so no assurances are given as to whether it will do the job
or not with other strains (it also works with the 'RedXAny' strain look-alike
and with the tamed version that only displays the payload - this tamed version
really isn't a virus since it doesn't replicate and so F-PROT won't report it;
the disinfector does report and clean it though).
An infected file can easily be cleaned by hand, so you should try that first.
The disinfector will scan all .COM files in the current directory for three
things: 1. the '0E9h' near jump code (other strains may have the '0EBh' jump
code - this won't detect them!); 2. the delta offset calculation routine
pointed to by the near jump; 3. the ambulance data at the end of the virus (if
you change this into something else the disinfector will report this file as
suspicious). Upon a suspicious or infected file report the user will be given a
chance to clean it or continue on to the next file.
And here is the disinfector:
[NOTE: F-PROT will report this as a new or modified variant of SillyC - go
figure!]
--8<---------------------------------------------------------------------------
; 'Ambulance Car' Disinfector
; KILLREDX by Chili for APJ #6
; Assemble with (TASM 4.1):
; tasm /ml /m2 killredx.asm
; tlink /t killredx.obj
LF equ 0Ah ; 'Line Feed' ASCII code
CR equ 0Dh ; 'Carriage Return' ASCII code
TEXT segment word public 'code'
assume cs:TEXT, ds:TEXT, es:TEXT, ss:_TEXT
org 100h
killredx proc far
;--- Print program identification message
lea si, killredx_msg
call print_ASCIIZ
;--- Find first .COM file
lea dx, com_mask
xor cx, cx
mov ah, 4Eh
int 21h
jnc open_file
jmp exit
- open file
;--- Print found file's name
lea si, newline_msg
call print_ASCIIZ
mov si, 9Eh
call print_ASCIIZ
;--- Open found file
mov dx, 9Eh
mov ax, 3D02h
int 21h
jnc read_jump
;--- Print open error message
lea si, open_msg
call print_ASCIIZ
jmp find_next
- read jump
;--- Read jump code
xchg ax, bx
mov cx, 3
lea dx, jump_code
mov ah, 3Fh
int 21h
jc read_error
cmp ax, cx
je check_jump
jmp close_file
- check jump
;--- Compare with known virus' jump code
cmp byte ptr [jump_code], 0E9h
je read_displacement
jmp close_file
- read displacement
;--- Move file pointer to jump offset
mov dx, word ptr [jump_code+1]
add dx, 3
xor cx, cx
mov ax, 4200h
int 21h
;--- Read displacement calculation code
mov cx, 7
lea dx, displace_code
mov ah, 3Fh
int 21h
jc read_error
cmp ax, cx
je check_displacement
jmp close_file
- check displacement
;--- Compare with known virus' displacement calculation code
cmp word ptr [displace_code], 01E8h
jne exit_check
cmp word ptr [displace_code+2], 0100h
jne exit_check
cmp word ptr [displace_code+4], 815Eh
jne exit_check
cmp byte ptr [displace_code+6], 0EEh
jne exit_check
jmp read_data
exit_check:
jmp close_file
- read data
;--- Move file pointer to supposed data location
mov cx, 0FFFFh
mov dx, 0FFF1h
mov ax, 4202h
int 21h
;--- Read ambulance data
mov cx, 2
lea dx, ambulance_data
mov ah, 3Fh
int 21h
jc read_error
cmp ax, cx
je check_data
jmp close_file
- read error
;--- Print read error message
lea si, read_msg
call print_ASCIIZ
jmp close_file
- check data
;--- Compare with know virus' ambulance data
cmp word ptr [ambulance_data], 0F434h
jne suspicious
;--- Print file infected or suspicious message
lea si, infected_msg
jmp askto_clean
suspicious:
lea si, suspicious_msg
- askto clean
;--- Print and read answer to whether clean file or not
call print_ASCIIZ
mov ah, 08h
int 21h
cmp al, 'y'
je clean_file
cmp al, 'Y'
je clean_file
jmp close_file
- clean file
;--- Move file pointer to supposed original bytes location
mov cx, 0FFFFh
mov dx, 0FFFDh
mov ax, 4202h
int 21h
;--- Read host's original (first 3) bytes
mov cx, 3
lea dx, original_bytes
mov ah, 3Fh
int 21h
jc read_error
cmp ax, cx
je write_original
jmp close_file
- write original
;--- Move file pointer to beginning of file
xor cx, cx
xor dx, dx
mov ax, 4200h
int 21h
;--- Write original bytes
mov cx, 3
lea dx, original_bytes
mov ah, 40h
int 21h
jc write_error
cmp ax, cx
je truncate_file
- write error
;--- Print write error message
lea si, write_msg
call print_ASCIIZ
jmp close_file
- truncate file
;--- Move file pointer to virus' jump offset (real virus start)
mov dx, word ptr [jump_code+1]
add dx, 3
xor cx, cx
mov ax, 4200h
int 21h
;--- Truncate file
mov cx, 0
mov ah, 40h
int 21h
jc write_error
cmp ax, cx
jne write_error
lea si, disinfected_msg
call print_ASCIIZ
- close file
;--- Close file
mov ah, 3Eh
int 21h
- find next
;--- Find next matching file
mov ah, 4Fh
int 21h
jc exit
jmp open_file
- exit
;--- Exit to DOS
lea si, newline_msg
call print_ASCIIZ
retn
killredx endp
print_ASCIIZ proc near
;--- Print an ASCIIZ string
lodsb
cmp al, 0
je end_ASCIIZ
xchg al, dl
mov ah, 02h
int 21h
jmp print_ASCIIZ
end_ASCIIZ:
retn
print_ASCIIZ endp
killredx_msg db "'Ambulance Car' Disinfector", LF, CR
db "KILLREDX by Chili for APJ #6", LF, CR, 0
newline_msg db LF, CR, 0
infected_msg db " Infected. Clean [y/n]?", 0
suspicious_msg db " Suspicious. Attempt to cleanû (û WARNING: file may "
db "be corrupted if infected by an unknown/unsupported "
db "strain of Ambulance Car) [y/n]?", 0
disinfected_msg db LF, CR, " Disinfected.", 0
open_msg db LF, CR, " [ERROR: opening file]", 0
read_msg db LF, CR, " [ERROR: reading from file]", 0
write_msg db LF, CR, " [ERROR: writing to file]", 0
com_mask db "*.COM", 0
jump_code db 3 dup (?)
displace_code db 7 dup (?)
ambulance_data dw ?
original_bytes db 3 dup (?)
_TEXT ends
end killredx
---------------------------------------------------------------------------8<--
|