MalwareSourceCode/MSDOS/Virus.MSDOS.Unknown.move.asm
2021-01-12 17:49:21 -06:00

150 lines
8.6 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.

CODE_SEG SEGMENT
ORG 100H ;ORG 100H for a .com file
ASSUME CS:CODE_SEG,DS:CODE_SEG
FIRST: JMP ENTRY ;Skip over data area
COPYRIGHT DB '(C) S. HOLZNER 1984'
TARGET_FCB DB 37 DUP(0) ;FCB at 6CH will be written over
END_FLAG DW 0 ;Flag set after everything read
FILE_SIZE_LO DW 0 ;Low word of file size, in bytes
FILE_SIZE_HI DW 0 ;High word of same
FILE_SIZE_K DW 0 ;Number of Clusters to write
DTA_OFFSET DW 0 ;Used for 1K increments into DTA
COPY_MSG_1 DB 13,10,'Copy $' ;Part 1 of the copy prompt
COPY_MSG_2 DB ' (Y/N)?$' ;And part 2
FULL_MSG DB 13,10,'Disk Full$' ;Trouble message
MOVE PROC NEAR ;The main (and only) procedure
ENTRY: MOV CX,32 ;Copy over 1st 32 bytes of default DTA
MOV SI,6CH ; from 6CH into Target_FCB area for
LEA DI,TARGET_FCB ; later use as new file name
REP MOVSB
MOV DX,5CH ;The source FCB
MOV AH,11H ;Check if there is match to source file
INT 21H
CMP AL,0FFH ;0FFH -> No match
JNE QUERY ;Match
JMP OUT ;No Match
QUERY: MOV AH,9H ;Print out prompt message
LEA DX,COPY_MSG_1
INT 21H
MOV CX,11 ;Print out 11 letters of found file name
MOV BX,81H ;Point to match in default DTA
MOV AH,2
QLOOP: MOV DL,[BX] ;Get letter of found file's name
INC BX ;Point to next letter
INT 21H
LOOP QLOOP ;Keep going until all 11 printed
MOV AH,9H ;Print out 2nd half of prompt message
LEA DX,COPY_MSG_2
INT 21H
MOV AH,1 ;Get a 1 character response
INT 21H
CMP AL,'Y' ;Was it a 'Y'?
JE DO_COPY ;Yes, copy the file
CMP AL,'y' ;No...perhaps a 'y'?
JE DO_COPY ;Yes, copy the file
JMP NEXT ;Get next match (if none, leave)
DO_COPY:MOV CX,37 ;Using given target file as a template,
LEA SI,TARGET_FCB ; load its 37 characters into the FCB
MOV DI,0C0H ; for use as real target FCB, checking
CMP BYTE PTR [SI+1],' ' ; for wildcards. First, was DRIVE: given
JNE NLOOP ; as target? No, check wildcards.
PUSH DI ;Yes, fill Target_FCB with wildcard ?'s
PUSH CX ; so found filename will be used
LEA DI,TARGET_FCB
INC DI
MOV CX,11 ;Put in 11 ?'s
MOV AL,'?'
REP STOSB ;Do the fill
POP CX ;Restore counter and dest. pointer
POP DI
NLOOP: MOV BX,0 ;Move given target name into real used
CMP BYTE PTR [SI],'?' ; target FCB at 0C0H. If a wildcard is
JNE CHAR_OK ; found in given filename use corres-
MOV BX,80H ; ponding character in found filename
SUB BX,OFFSET TARGET_FCB ;Wildcard found, adjust source (SI) to
ADD SI,BX ; point to the found filename
CHAR_OK:MOVS [DI],[SI]
SUB SI,BX ;Restore SI if necessary
LOOP NLOOP ;Loop back until for all 11 name char.s
MOV DX,80H ;Target FCB now at 0C0H, source at 80H
MOV AH,0FH ;Use DOS service 15 to open source
INT 21H ;Open source FCB
MOV DX,0C0H ;Use DOS service 12 to create target
MOV AH,16H
INT 21H ;Create target FCB (or if the file
AND END_FLAG,0 ; already exists, zero it and refill it)
MOV BX,80H + 14
MOV WORD PTR [BX],8000H ;Set record size for source (32K)
MOV BX,80H + 16 ;Get file size from opened source FCB
MOV AX,[BX]
MOV FILE_SIZE_LO,AX ;Store low word of size in FILE_SIZE_LO
ADD BX,2 ;Point to high word
MOV DX,[BX]
MOV FILE_SIZE_HI,DX ;Store high word of size in FILE_SIZE_HI
MOV CX,1024 ;Div DX:AX (High:Low of size) by 1024
DIV CX
MOV FILE_SIZE_K,AX ;Get file size in rounded-up K (1024)
TEST DX,0FFFFH ;Was it an even K file:Mod(size,1024)=0?
JZ ROUND ;Yes, don't add cluster for file remnant
INC FILE_SIZE_K ;No, add 1 more cluster for remainder
ROUND: MOV BX,0C0H + 14
MOV WORD PTR [BX],400H ;Set record size for target (1K)
READ: LEA DX,DATA_POINT ;Set up the 32K DTA we'll use
MOV AH,1AH ; at the end of this program
INT 21H
MOV DX,80H ;Point to source FCB to prepare for read
MOV AH,14H
INT 21H ;Do the read of 32K bytes
CMP AL,0 ;AL = 0 if end of file not yet reached
JLE READ_OK
OR END_FLAG,1 ;Have read in the whole file, DTA is
READ_OK:MOV CX,20H ; stuffed with zeroes after end of file
LEA DX,DATA_POINT ;Reset our offset into 32K DTA to the
MOV DTA_OFFSET,DX ; start
WLOOP: MOV DX,0C0H ;Point to target FCB, prepare for write
MOV AH,15H
INT 21H ;Do the write 1K at a time
CMP AL,0 ;Was the write a success?
JE COPY_OK ;Yes, check if done writing
LEA DX,FULL_MSG ;No, assume the disk was full and say so
MOV AH,9H ;Print error string
INT 21H
JMP OUT ;Exit
COPY_OK:DEC FILE_SIZE_K ;Decrement number of clusters to write
JZ FINISH ;Done?
ADD DTA_OFFSET,400H ;No, point to next 1K chunk of DTA
MOV DX,DTA_OFFSET
MOV AH,1AH ;Set DTA to match
INT 21H
LOOP WLOOP ;Repeat until 32K written or end of file
TEST END_FLAG,1 ;Have we read in the end of file?
JZ READ ;No, get next 32K block from source
FINISH: MOV AX,FILE_SIZE_LO ;Now adjust written file's size
MOV BX,0C0H + 16 ;Point to low word of size
MOV WORD PTR [BX],AX ;And set it to the correct value
ADD BX,2 ;Point to high word of size
MOV AX,FILE_SIZE_HI ;And set it too
MOV WORD PTR [BX],AX
MOV AH,10H ;Request DOS service 16, close files
MOV DX,0C0H ;Point to target file's FCB
INT 21H ;Close target with correct size
MOV DX,80H ;Point to source file's FCB
INT 21H ;Close source
NEXT: MOV DX,80H ;Start looking for the next match
MOV AH,1AH ;First, reset DTA to 80H for found file's FCB
INT 21H
MOV AH,12H ;Now search for next match-service 18
MOV DX,5CH ;Use given filename to match to
INT 21H
CMP AL,0 ;Match found?
JNE OUT ;No, exit.
JMP QUERY ;Yes, ask if it should be copied
OUT: RET
MOVE ENDP
DATA_POINT: ;The 32K DTA starts here
CODE_SEG ENDS
END FIRST ;'END FIRST' so entry point set to FIRST