mirror of
https://github.com/vxunderground/MalwareSourceCode.git
synced 2026-06-16 15:59:24 +00:00
Add files via upload
This commit is contained in:
@@ -0,0 +1,327 @@
|
||||
INTERRUPTS SEGMENT AT 0H
|
||||
ORG 9H*4 ;holds the address of its service routine
|
||||
KEYBOARD_INT LABEL DWORD
|
||||
ORG 21H*4 ;This is to use INT 21H
|
||||
INT_21H LABEL DWORD ;which is the DOS function call interrupt
|
||||
INTERRUPTS ENDS
|
||||
|
||||
ROM_BIOS_DATA SEGMENT AT 40H ;BIOS statuses held here, also keyboard buffer
|
||||
|
||||
ORG 1AH
|
||||
HEAD DW ? ;Unread chars go from Head to Tail
|
||||
TAIL DW ?
|
||||
BUFFER DW 16 DUP (?) ;The buffer itself
|
||||
BUFFER_END LABEL WORD
|
||||
|
||||
ROM_BIOS_DATA ENDS
|
||||
|
||||
CODE_SEG SEGMENT
|
||||
ASSUME CS:CODE_SEG
|
||||
ORG 100H ;ORG = 100H to make this into a
|
||||
;".com" file
|
||||
FIRST: JMP LOAD_INT_21H
|
||||
|
||||
COPY_RIGHT DB '(C)1985 S Holzner'
|
||||
BYPASS_FLAG DB 0 ;Bypass our checking for #? 1=Yes
|
||||
ZERO_FLAG DB 0 ;Was there a zero in filename? 1=Yes
|
||||
CR_FLAG DB 0
|
||||
DTA DD ? ;The old disk transfer area address
|
||||
OLD_INT_21H DD ? ;Address INT 21H uses normally
|
||||
OLD_KEYBOARD_INT DD ? ;Location of old kbd interrupt
|
||||
COUNT DW ?
|
||||
FCB_OFFSET DW ? ;Offset of given filename to be deleted
|
||||
FCB_SEG DW 0 ;Segment address of the same.
|
||||
COMMAND_INDEX DW 0
|
||||
DEL_Z DB 'DEL/Z',0
|
||||
CRLF DB 13,10,'$' ;Carriage return, linefeed for messages
|
||||
MSG DB ' ZEROED AND DELETED.',13,10,'$' ;The message
|
||||
ERR DB 'Error deleting $' ;Error message
|
||||
|
||||
DELZ PROC FAR ;The function call interrupt will now come here.
|
||||
|
||||
PUSHF ;Save flags first (will get changed by CMPs)
|
||||
CMP AH,13H ;Are we deleting?
|
||||
JNE JUMP ;No, jump to function call Int and do not return
|
||||
CMP ZERO_FLAG,1 ;Are we supposed to zero?
|
||||
JNE JUMP ;If not, don't
|
||||
TEST BYPASS_FLAG,1 ;We are deleting. Is bypass on?
|
||||
JZ DEL_CHECK ;No, check if we should delete file.
|
||||
JUMP: POPF ;Restore flags
|
||||
JMP OLD_INT_21H ;Jump to function call Int. (CALL won't work).
|
||||
DEL_CHECK: ;DS:DX are pointing to filename to be deleted (from delete call)
|
||||
PUSH BX ;Save all used registers to be polite
|
||||
PUSH CX
|
||||
PUSH DX
|
||||
PUSH SI
|
||||
PUSH DI
|
||||
PUSH AX ;Save AX last since will pop first and return status in it
|
||||
|
||||
MOV FCB_OFFSET,DX ;Save address of the file-to-be-deleted's FCB
|
||||
MOV FCB_SEG,DS ;Ditto for the segment address
|
||||
|
||||
MOV AH,2FH ;Now get Disk Transfer Area (DTA) address
|
||||
INT 21H ;This will work since AH is not equal to 13H
|
||||
|
||||
MOV DTA,BX ;Store DTA address Low part
|
||||
MOV DTA[2],ES ;Ditto High part
|
||||
PUSH DS ;Save file-to-be-deleted's FCB's Segment address
|
||||
MOV AH,1AH ;Put the new DTA in our Program Segment Prefix,
|
||||
MOV DX,80H ; CS:0080H (CS came from INT 21H vector we set)
|
||||
PUSH CS ;Now move DS into CS to set DTA
|
||||
POP DS
|
||||
INT 21H ;Set Disk Transfer Area (DTA)
|
||||
POP DS ;Restore Segment address of given file's FCB
|
||||
|
||||
MOV DX,FCB_OFFSET ;Restore the given file's FCB's address low part
|
||||
MOV AH,11H ;Ask for DOS service 11H, which asks for the
|
||||
INT 21H ; first match to the given file's FCB
|
||||
|
||||
TEST AL,1 ;Was a match found?
|
||||
JZ TOP ;Yes, start checking if we should delete.
|
||||
POP AX ;No, return status 0FF (not found) in AL
|
||||
MOV AL,0FFH
|
||||
JMP NONE_FOUND ;Over and out.
|
||||
TOP:
|
||||
MOV SI,81H ;the matching file's FCB is in DTA from search
|
||||
MOV DI,0C0H ;We will move the name to print and scan for #
|
||||
MOV CX,0BH ;11 characters per file
|
||||
PUSH DS ;Get ready for string move, set up DS and ES
|
||||
PUSH CS ;Set them both to CS (use program segment
|
||||
POP DS ; prefix area)
|
||||
MOV DX,80H ;Point to match to open file
|
||||
MOV AH,0FH ;Select the correct DOS call
|
||||
INT 21H
|
||||
CMP AL,0 ;If error opening file, exit
|
||||
JNE ERROR
|
||||
MOV BX,80H ;Set record size to 512
|
||||
MOV WORD PTR [BX+14],512
|
||||
MOV AX,[BX+16] ;Find the file's size in sectors
|
||||
XOR DX,DX
|
||||
TEST AX,511 ;Do we have to add an add'l sector?
|
||||
JZ SHIF ;No, do the shift
|
||||
INC DX ;Yes, add 1
|
||||
SHIF: MOV CL,9 ;Divide by 512
|
||||
SHR AX,CL
|
||||
MOV COUNT,AX ;Store in Count
|
||||
ADD COUNT,DX ;And add possible add'l sector
|
||||
MOV AX,[BX+18] ;Now for the high part of size
|
||||
MOV CL,7 ;Mult by 65536 div by 512
|
||||
SHL AX,CL
|
||||
ADD COUNT,AX ;And add to what we already have
|
||||
MOV DX,80H ;Now prepare for sequential write
|
||||
MOV CX,COUNT ;Do COUNT sectors
|
||||
MOV AH,15H
|
||||
FILL: INT 21H ;Fill with copies of this prog.
|
||||
CMP AL,0 ;Error writing?
|
||||
JNE ERROR ;Yes, jump to ERROR
|
||||
LOOP FILL ;No, go back for next one
|
||||
MOV AH,10H ;Close the file now.
|
||||
INT 21H
|
||||
CMP AL,0 ;Error closing?
|
||||
JNE ERROR ;Yep, go to ERROR
|
||||
MOV AH,13H ;No, delete the file at last (Whew)
|
||||
MOV BYPASS_FLAG,1 ;Don't intercept this call
|
||||
INT 21H
|
||||
MOV BYPASS_FLAG,0
|
||||
CMP AL,0 ;Everything OK?
|
||||
JNE ERROR ;No, go to ERROR
|
||||
CALL PRINT_NAME ;Yes, print the name
|
||||
LEA DX,MSG ;And the zeroed message
|
||||
MOV AH,9
|
||||
INT 21H
|
||||
JMP SAVE
|
||||
ERROR: MOV AH,10H ;First make sure file is closed
|
||||
INT 21H
|
||||
LEA DX,ERR ;Then print error message and go on
|
||||
MOV AH,9 ; to next file
|
||||
INT 21H
|
||||
CALL PRINT_NAME
|
||||
SAVE: POP DS ;Get segment of original given file's FCB
|
||||
MOV DX,FCB_OFFSET ;Search for next match -- point to original FCB
|
||||
MOV AH,12H ;Search for next match
|
||||
INT 21H
|
||||
TEST AL,1 ;Was a match found?
|
||||
JNZ OUT
|
||||
JMP TOP
|
||||
|
||||
OUT: POP AX ;At least one file deleted, set AL acordingly,
|
||||
MOV AL,0 ; which means set it to 0
|
||||
NONE_FOUND:
|
||||
PUSH DS ;Now we have to reset the Disk Transfer Area
|
||||
PUSH AX ;Save AX since it contains success status
|
||||
MOV AH,1AH ;Function call 1AH will do want we want
|
||||
MOV DX,DTA[2] ;Get original DTA's segment into DS
|
||||
MOV DS,DX
|
||||
MOV DX,DTA ;Now get offset inside that segment of same
|
||||
INT 21H ;And reset DTA
|
||||
POP AX ;Restore AX with status
|
||||
POP DS ;And DS with original DS
|
||||
|
||||
POP DI ;And restore the other registers
|
||||
POP SI
|
||||
POP DX
|
||||
POP CX
|
||||
POP BX
|
||||
POPF ;We musn't forget our original PUSHF
|
||||
IRET ;An interrupt deserves an IRET
|
||||
|
||||
DELZ ENDP ;And that's it
|
||||
|
||||
PRINT_NAME PROC NEAR ;This small subroutine just prints
|
||||
MOV BX,80H+1 ; file's name from the FCB
|
||||
MOV AH,2 ;Use DOS service 2
|
||||
MOV CX,11 ;Print all 11 letters
|
||||
PRINT: MOV DL,[BX] ;Printing loop
|
||||
INT 21H
|
||||
INC BX ;Get next letter
|
||||
LOOP PRINT
|
||||
RET ;And return
|
||||
PRINT_NAME ENDP
|
||||
|
||||
READ_KEY PROC NEAR ;The keyboard interrupt will now come here.
|
||||
ASSUME CS:CODE_SEG
|
||||
PUSH AX ;Save the used registers for good form
|
||||
PUSH BX
|
||||
PUSH CX
|
||||
PUSH DX
|
||||
PUSH DI
|
||||
PUSH SI
|
||||
PUSH DS
|
||||
PUSHF ;First, call old keyboard interrupt
|
||||
CALL OLD_KEYBOARD_INT
|
||||
|
||||
ASSUME DS:ROM_BIOS_DATA ;Examine the char just put in
|
||||
MOV BX,ROM_BIOS_DATA
|
||||
MOV DS,BX
|
||||
MOV BX,TAIL ;Point to current tail
|
||||
CMP BX,HEAD ;If at head, kbd int has deleted char
|
||||
JNE CR ;So leave
|
||||
JMP NOCR
|
||||
CR: SUB BX,2 ;Point to just read in character
|
||||
CMP BX,OFFSET BUFFER ;Did we undershoot buffer?
|
||||
JAE NO_WRAP ;Nope
|
||||
MOV BX,OFFSET BUFFER_END ;Yes -- move to buffer top
|
||||
SUB BX,2
|
||||
NO_WRAP:MOV DX,[BX] ;Char in DX now
|
||||
|
||||
CMP DL,'Z' ;Make sure we are in upper case
|
||||
JBE CHAROK
|
||||
SUB DL,'a'-'A' ;Make REALLY sure.
|
||||
CHAROK: PUSH CS
|
||||
POP DS ;Point to Code Seg with DS
|
||||
ASSUME DS:CODE_SEG
|
||||
CMP CR_FLAG,1 ;CR_Flag resets Zero_Flag
|
||||
JNE CHECK
|
||||
MOV CR_FLAG,0 ;Reset CR_Flag
|
||||
MOV ZERO_FLAG,0 ;And Zero_Flag
|
||||
MOV COMMAND_INDEX,0 ;As well as Command_Index
|
||||
CHECK: LEA SI,DEL_Z ;Check the typed character
|
||||
ADD SI,COMMAND_INDEX ;Find place in test string
|
||||
CMP DL,[SI] ;Match?
|
||||
JNE NOSET ;If not, forget it
|
||||
INC COMMAND_INDEX ;Match! Move to next char next time
|
||||
|
||||
CMP DL,'/' ;For DOS 3+, delete the /Z from buffer
|
||||
JNE NOTSLSH
|
||||
ASSUME DS:ROM_BIOS_DATA ;Examine the char just put in
|
||||
MOV CX,ROM_BIOS_DATA
|
||||
MOV DS,CX
|
||||
MOV TAIL,BX ;Erase character from buffer
|
||||
MOV AH,10 ;Get ready to print the character
|
||||
MOV CX,1
|
||||
MOV AL,DL
|
||||
XOR BX,BX ;Display page 0
|
||||
INT 10H ;Print the '/'
|
||||
MOV AH,3 ;Now prepare to move cursor over 1
|
||||
INT 10H ;Get present position
|
||||
ADD DX,1 ;Add 1
|
||||
MOV AH,2 ;And reset cursor
|
||||
INT 10H
|
||||
|
||||
NOTSLSH:CMP DL,'Z' ;For DOS 3+, delete the /Z from buffer
|
||||
JNE NOTZ
|
||||
ASSUME DS:ROM_BIOS_DATA ;Examine the char just put in
|
||||
MOV CX,ROM_BIOS_DATA
|
||||
MOV DS,CX
|
||||
MOV TAIL,BX ;Erase character from the buffer
|
||||
MOV AH,10 ;Prepare to type the 'Z'
|
||||
MOV CX,1
|
||||
MOV AL,DL
|
||||
XOR BX,BX
|
||||
INT 10H
|
||||
MOV AH,3 ;And now adjust the cursor
|
||||
INT 10H ;Moving it to the left 1 space
|
||||
ADD DX,1
|
||||
MOV AH,2
|
||||
INT 10H
|
||||
|
||||
NOTZ: ASSUME DS:CODE_SEG
|
||||
PUSH CS
|
||||
POP DS
|
||||
|
||||
CMP BYTE PTR [SI+1],0
|
||||
JNE NOSET
|
||||
MOV ZERO_FLAG,1
|
||||
MOV COMMAND_INDEX,0
|
||||
NOSET: MOV CR_FLAG,0
|
||||
CMP DX,1C0DH
|
||||
JNE NOCR
|
||||
MOV CR_FLAG,1
|
||||
NOCR: POP DS
|
||||
POP SI
|
||||
POP DI
|
||||
POP DX
|
||||
POP CX
|
||||
POP BX
|
||||
POP AX
|
||||
IRET
|
||||
READ_KEY ENDP
|
||||
|
||||
LOAD_INT_21H PROC NEAR ;This subroutine installs DELZ
|
||||
|
||||
ASSUME DS:INTERRUPTS ;Now set DS to point to INTERRUPTS seg.
|
||||
MOV AX,INTERRUPTS
|
||||
MOV DS,AX
|
||||
|
||||
MOV AX,KEYBOARD_INT ;Get the old interrupt service routine
|
||||
MOV OLD_KEYBOARD_INT,AX ;address and put it into our location
|
||||
MOV AX,KEYBOARD_INT[2] ;OLD_KEYBOARD_INT so we can call it.
|
||||
MOV OLD_KEYBOARD_INT[2],AX
|
||||
|
||||
MOV KEYBOARD_INT,OFFSET READ_KEY
|
||||
MOV KEYBOARD_INT[2],CS ;routine into the keyboard interrupt
|
||||
|
||||
MOV AX,INT_21H ;Get the original function call INT's
|
||||
MOV OLD_INT_21H,AX ;address and put it into our location
|
||||
MOV AX,INT_21H[2] ;OLD_INT_21H so we can still jump there
|
||||
MOV OLD_INT_21H[2],AX
|
||||
|
||||
MOV INT_21H[2],CS ;Install our delete filter's address
|
||||
MOV INT_21H,OFFSET DELZ ; as new function call INT
|
||||
|
||||
PUSH CS ;Now point to CS in preparation for
|
||||
POP DS ; terminate and stay resident call
|
||||
|
||||
MOV DX,OFFSET LOAD_INT_21H ;Set up everything but LOAD_INT_21H to
|
||||
INT 27H ;stay and attach itself to DOS
|
||||
|
||||
LOAD_INT_21H ENDP ;End of loading subroutine
|
||||
|
||||
CODE_SEG ENDS ;End of Code Segment
|
||||
|
||||
END FIRST ;END "FIRST" so 8088 will go to FIRST first.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user