MalwareSourceCode/MSDOS/Virus.MSDOS.Unknown.attr.asm

216 lines
7.0 KiB
NASM
Raw Normal View History

2021-01-12 23:31:39 +00:00
; ATTR.ASM -- File Attribute Utility
; ==================================
CSEG Segment
Assume CS:CSEG, DS:CSEG, ES:CSEG, SS:CSEG
Org 0080h
Parameter Label Byte ; Parameter is here
Org 0100h
Entry: Jmp Begin ; Entry Point
; Most Data (some more at end of program)
; ---------------------------------------
db "ATTR (C) 1986, Ziff-Davis Publishing Co.",1Ah
db " Programmed by Charles Petzold ",1Ah
SyntaxMsg db "Syntax: ATTR [+A|-A] [+S|-S] [+H|-H] [+R|-R] "
db "[drive:][path]filename",13,10
db " Archive System Hidden Read-Only$"
DosVersMsg db "ATTR: Needs DOS 2.0 +$"
FlagErrMsg db "ATTR: Incorrect flag$"
FileSpecMsg db "ATTR: Incorrect File Spec$"
Delimiters db 9,' ,;=',13
FlagList db "ASHR", 20h, 04h, 02h, 01h
AllFlagList db " $Arc $Dir $$$$$$Sys $Hid $R-O$"
ChangeFlag db 0
AndAttrBits db 0
OrAttrBits db 0
SearchString dw ?
AppendFileName dw ?
; Check DOS Version
; -----------------
Begin: Mov AH, 30h ; Check for DOS Version
Int 21h ; through DOS call
Cmp AL, 2 ; See if it's 2.0 or above
Jae DosVersOK ; If so, continue
Mov DX, Offset DosVersMsg ; Error message
ErrorExit: Mov AH, 9 ; Print String function call
Int 21h ; Do it
Int 20h ; And exit prematurely
; Parse Command Line to get file specification
; --------------------------------------------
DosVersOK: Mov SI, 1+Offset Parameter ; Parameter string pointer
Cld ; Directions forward
FlagSearch: Lodsb ; Get Byte
Mov DI, Offset Delimiters ; Check if delimiter
Mov CX, 5 ; Five delimiters to check
Repne Scasb ; Scan the string
Je FlagSearch ; If delimiter, circle back
Mov DX, Offset SyntaxMsg ; Possible error msg
Cmp AL, 13 ; If carriage return, no file
Je ErrorExit ; so exit with message
Mov DI, Offset OrAttrBits ; Pointer to plus flag saver
Cmp AL, '+' ; See if plus sign
Je PlusOrMinus ; If so, save the bit
Mov DI, Offset AndAttrBits ; Pointer to minus flag saver
Cmp AL, '-' ; See if minus sign
Jne MustBeFile ; If not, it must be file name
PlusOrMinus: Mov [ChangeFlag],-1 ; Set for changing
Lodsb ; Get the next byte
And AL, 0DFh ; Capitalize it
Mov BX, Offset FlagList ; List for scanning
Mov CX, 4 ; Scan for A, S, H, and R
SearchList: Cmp AL, [BX] ; See if a match
Jz FoundFlag ; If so, proceed to save
Inc BX ; Kick up pointer
Loop SearchList ; And loop around for next
Mov DX, Offset FlagErrMsg ; Otherwise, set message
Jmp ErrorExit ; And terminate
FoundFlag: Mov AL, [BX + 4] ; Get bit mask
Or [DI], AL ; Turn saved bit on
Jmp FlagSearch ; And continue looking
MustBeFile: Not [AndAttrBits] ; Invert bits for turn off
Mov [SearchString], SI ; Save file name pointer
Dec [SearchString] ; Actually one byte lower
EndSearch: Lodsb ; Get Byte
Mov DI, Offset Delimiters ; Check if delimiter
Mov CX, 6 ; Six delimiters including CR
Repne Scasb ; Scan the string
Jne EndSearch ; If not delimiter, keep going
; Transfer Search String down at end of program
; ---------------------------------------------
Dec SI ; Points after file spec
Mov Byte Ptr [SI], 0 ; Make it ASCIIZ string
Mov CX, SI ; CX points to end
Mov SI, [SearchString] ; SI points to beginning
Sub CX, SI ; Now CX is length of it
Mov DI, Offset PathAndFile ; Destination of string
Mov [AppendFileName], DI ; Save it here also
SearchTrans: Lodsb ; Get byte of search string
Stosb ; And save it down below
Cmp AL, ':' ; See if drive marker
Je PossibleEnd ; If so, take note of it
Cmp AL, '\' ; See if path separator
Jne NextCharacter ; If not, skip next code
PossibleEnd: Mov [AppendFileName], DI ; This is the new end
NextCharacter: Loop SearchTrans ; Do it again until done
; Find Files from Search String
; -----------------------------
Mov DX, Offset DTABuffer ; Set File Find buffer
Mov AH, 1Ah ; by calling DOS
Int 21h
Mov DX, [SearchString] ; Search string
Mov CX, 16h ; Search Everything
Mov AH, 4Eh ; Find first file
FindFile: Int 21h ; Call DOS to find file
Jnc Continue ; If no error continue
Cmp AX, 18 ; If not "no more files" error
Jnz FindError ; print error message
Jmp NoMoreFiles ; Now get out of the loop
FindError: Mov DX, Offset FileSpecMsg ; Error message for file spec
Jmp ErrorExit ; Exit and print message
Continue: Mov SI, 30+Offset DTABuffer ; Points to filename
Cmp Byte Ptr [SI], '.' ; See if "dot" entry
Jnz FileIsOK ; If not, continue
Jmp FindNextFile ; If so, skip it
FileIsOK: Mov DI, [AppendFileName] ; Destination of file name
Mov CX, 14 ; Number of bytes to display
TransferName: Lodsb ; Get the byte in file name
Stosb ; Save it
Or AL, AL ; See if terminating zero
Jz PadWithBlanks ; If so, display blanks
Call DisplayChar ; Display the character
Loop TransferName ; And loop back around
PadWithBlanks: Mov AL, ' ' ; Pad names with blanks
Call DisplayChar
Loop PadWithBlanks ; And loop until CX is zero
; Change And Display File Attributes
; ----------------------------------
Mov DX, Offset PathAndFile ; Points to ASCIIZ string
Test [ChangeFlag], -1 ; See if changing attributes
Jz DisplayIt ; If not, just display them
Mov AX, 4300h ; Get file attribute
Int 21h ; by calling DOS
And CL, 27h ; Zero out some bits
And CL, [AndAttrBits] ; Turn off some bits
Or CL, [OrAttrBits] ; Turn on some bits
Mov AX, 4301h ; Set file attribute
Int 21h ; by calling DOS
DisplayIt: Mov AX, 4300h ; Get file attribute
Int 21h ; by calling DOS
Mov BL, CL ; BL is attributes
Or BL, 08h ; Turn on Volume bit
Shl BL, 1 ; Shift to get rid of
Shl BL, 1 ; unused bits
Mov CX, 6 ; Number of bits left
Mov DX, 5+Offset AllFlagList; Storage of abbreviations
AttrListLoop: Push DX ; Save abbreviation pointer
Shl BL, 1 ; Shift bit into carry
Jc FlagIsOn ; See if it's on
Mov DX, Offset AllFlagList ; If not, print blanks
FlagIsOn: Mov AH, 9 ; Print string
Int 21h ; by calling DOS
Pop DX ; Get back abbreviation ptr
Add DX, 5 ; Kick up for next bit
Loop AttrListLoop ; And loop around
Mov AL, 13 ; Print carriage return
Call DisplayChar
Mov AL, 10 ; Print line feed
Call DisplayChar
FindNextFile: Mov AH, 4Fh ; Find next file
Jmp FindFile ; By looping around
NoMoreFiles: Int 20h ; Terminate
; SUBROUTINE: Display Character in AL
; -----------------------------------
DisplayChar: Push AX
Push DX
Mov DL, AL ; Move character to DL
Mov AH, 2 ; Display it
Int 21h ; by calling DOS
Pop DX
Pop AX
Ret
; Some data stored at end to cut down COM size
; --------------------------------------------
DTABuffer Label Byte ; For file find calls
PathAndFile equ DTABuffer + 43 ; For file path and name
CSEG EndS ; End of the segment
End Entry ; Denotes entry point