mirror of
https://github.com/vxunderground/MalwareSourceCode.git
synced 2026-06-16 07:49:24 +00:00
Add files via upload
This commit is contained in:
@@ -0,0 +1,312 @@
|
||||
; NO.ASM -- Hides specified files from command that follows
|
||||
; ======
|
||||
|
||||
CSEG Segment
|
||||
Assume CS:CSEG, DS:CSEG, ES:CSEG, SS:CSEG
|
||||
Org 002Ch
|
||||
Environment Label Word ; Segment of Environment is here
|
||||
Org 0080h
|
||||
Parameter Label Byte ; Parameter is here
|
||||
Org 0100h
|
||||
Entry: Jmp Begin ; Entry Point
|
||||
|
||||
; Most Data (some more at end of program)
|
||||
; ---------------------------------------
|
||||
|
||||
db "Copyright 1986 Ziff-Davis Publishing Co.",1Ah
|
||||
db " Programmed by Charles Petzold ",1Ah
|
||||
SyntaxMsg db "Syntax: NO filespec command [parameters]$"
|
||||
DosVersMsg db "NO: Needs DOS 2.0 +$"
|
||||
FileSpecMsg db "NO: Incorrect File Spec$"
|
||||
TooManyMsg db "NO: Too many files to hide$"
|
||||
MemAllocMsg db "NO: Allocation Problem$"
|
||||
CommandMsg db "NO: COMMAND Problem$"
|
||||
Delimiters db 9,' ,;='
|
||||
FileList dw ? ; Storage of found files
|
||||
FileCount dw 0 ; Count of found files
|
||||
FileListEnd dw ? ; End of storage of found files
|
||||
BreakState db ? ; Store original break state here
|
||||
Comspec db 'COMSPEC=' ; String for Environment search
|
||||
ParamBlock dw ? ; Parameter block for EXEC call
|
||||
dw ?, ?
|
||||
dw 5Ch, ?
|
||||
dw 6Ch, ?
|
||||
StackPointer dw ? ; Save SP during EXEC call
|
||||
|
||||
; 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 NO File specification
|
||||
; -----------------------------------------------
|
||||
|
||||
ScanParam: Lodsb ; SUBROUTINE: Get byte
|
||||
Cmp AL, 13 ; See if end of parameter
|
||||
Je ErrorExit ; If so, exit
|
||||
Mov DI, Offset Delimiters ; Check if delimiter
|
||||
Mov CX, 5 ; There are 5 of them
|
||||
Repne Scasb ; Scan the string
|
||||
Ret ; And return
|
||||
|
||||
DosVersOK: Mov DX, Offset SyntaxMsg ; Possible error msg
|
||||
Mov SI, 1+Offset Parameter ; NO Parameter string
|
||||
Cld ; Directions forward
|
||||
|
||||
BegSearch: Call ScanParam ; Check byte in subroutine
|
||||
Je BegSearch ; If delimiter, keep searching
|
||||
Mov BX, SI ; Save pointer in BX
|
||||
Dec BX ; BX points to NO file spec
|
||||
|
||||
EndSearch: Call ScanParam ; Check byte in subroutine
|
||||
Jne EndSearch ; If not delimiter, keep going
|
||||
|
||||
; Construct full FilePath and save down at end of program
|
||||
; -------------------------------------------------------
|
||||
|
||||
Dec SI ; Points after NO file spec
|
||||
Xchg SI, BX ; SI points to beg, BX to end
|
||||
Mov DI, Offset FullPath ; Points to destination
|
||||
Cmp Byte Ptr [SI + 1], ':' ; See if drive spec included
|
||||
Jnz GetDrive ; If not, must get the drive
|
||||
Lodsw ; Otherwise, grab drive spec
|
||||
And AL, 0DFh ; Capitalize drive letter
|
||||
Jmp Short SaveDrive ; And skip next section
|
||||
|
||||
GetDrive: Mov AH, 19h ; Get current drive
|
||||
Int 21h ; through DOS
|
||||
Add AL, 'A' ; Convert to letter
|
||||
Mov AH, ':' ; Colon after drive letter
|
||||
|
||||
SaveDrive: Stosw ; Save drive spec and colon
|
||||
Mov AL, '\' ; Directory divider byte
|
||||
Cmp [SI], AL ; See if spec starts at root
|
||||
Jz HaveFullPath ; If so, no need to get path
|
||||
Stosb ; Store that character
|
||||
Push SI ; Save pointer to parameter
|
||||
Mov SI, DI ; Destination of current path
|
||||
Mov DL, [SI - 3] ; Drive letter specification
|
||||
Sub DL, '@' ; Convert to number
|
||||
Mov AH, 47h ; Get current directory
|
||||
Int 21h ; through DOS
|
||||
Mov DX, Offset FileSpecMsg ; Possible error message
|
||||
Jc ErrorExit ; Exit if error
|
||||
Sub AL, AL ; Search for terminating zero
|
||||
Cmp [SI], AL ; Check if Root Directory
|
||||
Jz RootDir ; If so, don't use it
|
||||
Mov CX, 64 ; Number of bytes to search
|
||||
Repnz Scasb ; Do the search
|
||||
Dec DI ; DI points to last zero
|
||||
Mov AL, '\' ; Put a backslash in there
|
||||
Stosb ; So filespec can follow
|
||||
RootDir: Pop SI ; Get back SI
|
||||
|
||||
HaveFullPath: Mov CX, BX ; End of NO file spec
|
||||
Sub CX, SI ; Number of bytes to transfer
|
||||
Rep Movsb ; Transfer them
|
||||
Sub AL, AL ; Terminating zero
|
||||
Stosb ; Save it
|
||||
Mov [FileList], DI ; Repository for found files
|
||||
|
||||
; Fix up parameter and ParamBlock for eventual COMMAND load
|
||||
; ---------------------------------------------------------
|
||||
|
||||
Sub BX, 4 ; Points to new param begin
|
||||
Mov AL, [Parameter] ; Old byte count of parameter
|
||||
Add AL, 80h ; Add beginning of old param
|
||||
Sub AL, BL ; Subtract beginning of new
|
||||
Mov AH, ' ' ; Space separator
|
||||
Mov Word Ptr [BX], AX ; Store it
|
||||
Mov Word Ptr [BX + 2], 'C/' ; Add /C to beginning of rest
|
||||
Mov AX, [Environment] ; Get environment segment
|
||||
Mov [ParamBlock], AX ; Save it
|
||||
Mov [ParamBlock + 2], BX ; Save parameter pointer
|
||||
Mov [ParamBlock + 4], CS ; Save segment of ParamBlock
|
||||
Mov [ParamBlock + 8], CS
|
||||
Mov [ParamBlock + 10], CS
|
||||
|
||||
; Find Files from NO File Specification
|
||||
; -------------------------------------
|
||||
|
||||
Mov DX, Offset DTABuffer ; Set File Find buffer
|
||||
Mov AH, 1Ah ; by calling DOS
|
||||
Int 21h
|
||||
|
||||
Mov DI, [FileList] ; Address of destination
|
||||
Mov DX, Offset FullPath ; Search string
|
||||
Sub CX, CX ; Search Normal files only
|
||||
Mov AH, 4Eh ; Find first file
|
||||
|
||||
FindFile: Int 21h ; Call DOS to find file
|
||||
Jnc Continue ; If no error continue
|
||||
Cmp AX, 18 ; If no more files
|
||||
Jz NoMoreFiles ; get out of the loop
|
||||
Mov DX, Offset FileSpecMsg ; Error message otherwise
|
||||
Jmp ErrorExit ; Exit and print message
|
||||
|
||||
Continue: Mov AX, DI ; Address of destination
|
||||
Add AX, 512 ; See if near top of segment
|
||||
Jc TooManyFiles ; If so, too many files
|
||||
Cmp AX, SP ; See if getting too many
|
||||
Jb StillOK ; If not, continue
|
||||
|
||||
TooManyFiles: Mov DX, Offset TooManyMsg ; Otherwise error message
|
||||
Jmp ErrorExit ; And terminate
|
||||
|
||||
StillOK: Mov SI, 30+Offset DTABuffer ; Points to filename
|
||||
Call AsciizTransfer ; Transfer it to list
|
||||
Inc [FileCount] ; Kick up counter
|
||||
Mov AH, 4Fh ; Find next file
|
||||
Jmp FindFile ; By looping around
|
||||
|
||||
NoMoreFiles: Mov [FileListEnd], DI ; Points after last file
|
||||
Mov DI, [FileList] ; Points to end of find string
|
||||
Mov CX, 64 ; Search up to 64 bytes
|
||||
Mov AL, '\' ; For the backslash
|
||||
Std ; Search backwards
|
||||
Repnz Scasb ; Do the search
|
||||
Mov Byte Ptr [DI + 2], 0 ; Stick zero in there
|
||||
Cld ; Fix up direction flag
|
||||
|
||||
; Stop Ctrl-Break Exits and Hide the files
|
||||
; ----------------------------------------
|
||||
|
||||
Mov AX,3300h ; Get Break State
|
||||
Int 21h ; By calling DOS
|
||||
Mov [BreakState],DL ; Save it
|
||||
Sub DL,DL ; Set it to OFF
|
||||
Mov AX,3301h ; Set Break State
|
||||
Int 21h ; By calling DOS
|
||||
Mov BL, 0FFh ; Value to AND attribute
|
||||
Mov BH, 02h ; Value to OR attribute
|
||||
Call ChangeFileMode ; Hide all the files
|
||||
|
||||
; Un-allocate rest of memory
|
||||
; --------------------------
|
||||
|
||||
Mov BX, [FileListEnd] ; Beyond this we don't need
|
||||
Add BX, 512 ; Allow 512 bytes for stack
|
||||
Mov SP, BX ; Set new stack pointer
|
||||
Add BX, 15 ; Prepare for truncation
|
||||
Mov CL,4 ; Prepare for shift
|
||||
Shr BX,CL ; Convert to segment form
|
||||
Mov AH,4Ah ; Shrink allocated memory
|
||||
Int 21h ; By calling DOS
|
||||
Mov DX,Offset MemAllocMsg ; Possible Error Message
|
||||
Jc ErrorExit2 ; Print it and terminate
|
||||
|
||||
; Search for Comspec in Environment
|
||||
; ---------------------------------
|
||||
|
||||
Push ES ; We'll be changing this
|
||||
Mov ES, [Environment] ; Set ES to Environment
|
||||
Sub DI, DI ; Start at the beginning
|
||||
Mov SI, Offset ComSpec ; String to search for
|
||||
Mov DX, Offset CommandMsg ; Possible error message
|
||||
|
||||
TryThis: Cmp Byte Ptr ES:[DI], 0 ; See if points to zero
|
||||
Jz ErrorExit2 ; If so, we can't go on
|
||||
Push SI ; Temporarily save these
|
||||
Push DI
|
||||
Mov CX, 8 ; Search string has 8 chars
|
||||
Repz Cmpsb ; Do the string compare
|
||||
Pop DI ; Get back the registers
|
||||
Pop SI
|
||||
Jz LoadCommand ; If equals, we've found it
|
||||
Sub AL, AL ; Otherwise search for zero
|
||||
Mov CX, -1 ; For 'infinite' bytes
|
||||
Repnz Scasb ; Do the search
|
||||
Jmp TryThis ; And try the next string
|
||||
|
||||
; Load COMMAND.COM
|
||||
; -----------------
|
||||
|
||||
LoadCommand: Add DI, 8 ; so points after 'COMSPEC='
|
||||
Push DS ; Switch DS and ES registers
|
||||
Push ES
|
||||
Pop DS
|
||||
Pop ES
|
||||
Mov [StackPointer],SP ; Save Stack Pointer
|
||||
Mov DX, DI ; DS:DX = Asciiz of COMMAND
|
||||
Mov BX, Offset ParamBlock ; ES:BX = parameter block
|
||||
Mov AX, 4B00h ; EXEC function call
|
||||
Int 21h ; Load command processor
|
||||
|
||||
; Return from COMMAND.COM
|
||||
; -----------------------
|
||||
|
||||
Mov AX, CS ; Current code segment
|
||||
Mov DS, AX ; Reset DS to this segment
|
||||
Mov ES, AX ; Reset ES to this segment
|
||||
Mov SS, AX ; Reset stack segment to it
|
||||
Mov SP, [StackPointer] ; Reset SP
|
||||
Pushf ; Save error flag
|
||||
Sub DL,DL ; Set Ctrl Break to OFF
|
||||
Mov AX,3301h
|
||||
Int 21h ; By calling DOS
|
||||
Popf ; Get back error flag
|
||||
Mov DX,Offset CommandMsg ; Set up possible error msg
|
||||
Jnc Terminate ; And print if EXEC error
|
||||
|
||||
; Unhide the Files, restore Ctrl-Break state, and exit
|
||||
; ----------------------------------------------------
|
||||
|
||||
ErrorExit2: Mov AH,9 ; Will print the string
|
||||
Int 21h ; Print it
|
||||
Terminate: Mov BL, 0FDh ; AND value for change
|
||||
Mov BH, 00h ; OR value for change
|
||||
Call ChangeFileMode ; Change file attributes
|
||||
Mov DL,[BreakState] ; Original break-state
|
||||
Mov AX,3301h ; Change the break-state
|
||||
Int 21h ; by calling DOS
|
||||
Int 20h ; Terminate
|
||||
|
||||
; SUBROUTINE: Change File Mode (All files, BL = AND, BH = OR)
|
||||
; -----------------------------------------------------------
|
||||
|
||||
ChangeFileMode: Mov CX, [FileCount] ; Number of files
|
||||
Jcxz EndOfChange ; If no files, do nothing
|
||||
Mov SI, [FileList] ; Beginning of list
|
||||
Mov DX, [FileListEnd] ; End of List
|
||||
ChangeLoop: Push SI ; Save pointer
|
||||
Mov SI, Offset FullPath ; Preceeding path string
|
||||
Mov DI, DX ; Destination of full name
|
||||
Call AsciizTransfer ; Transfer it
|
||||
Dec DI ; Back up to end zero
|
||||
Pop SI ; Get back pointer to filename
|
||||
Call AsciizTransfer ; Transfer it
|
||||
Push CX ; Save the counter
|
||||
Mov AX, 4300h ; Get attribute
|
||||
Int 21h ; by calling DOS
|
||||
And CL, BL ; AND with BL
|
||||
Or CL, BH ; OR with BH
|
||||
Mov AX, 4301h ; Now set attribute
|
||||
Int 21h ; by calling DOS
|
||||
Pop CX ; Get back counter
|
||||
Loop ChangeLoop ; And do it again if necessary
|
||||
EndOfChange: Ret ; End of subroutine
|
||||
|
||||
; SUBROUTINE: Asciiz String Transfer (SI, DI in, returned incremented)
|
||||
; --------------------------------------------------------------------
|
||||
|
||||
AsciizTransfer: Movsb ; Transfer Byte
|
||||
Cmp Byte Ptr [DI - 1], 0 ; See if it was end
|
||||
Jnz AsciizTransfer ; If not, loop
|
||||
Ret ; Or leave subroutine
|
||||
|
||||
; Variable length data stored at end
|
||||
; ----------------------------------
|
||||
|
||||
DTABuffer Label Byte ; For file find calls
|
||||
FullPath equ DTABuffer + 43 ; For file path and names
|
||||
CSEG EndS ; End of the segment
|
||||
End Entry ; Denotes entry point
|
||||
|
||||
Reference in New Issue
Block a user