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

216 lines
7.0 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.

; 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