⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 keeper.asm

📁 一些病毒源代码
💻 ASM
📖 第 1 页 / 共 2 页
字号:
VECTORS SEGMENT AT 0H           ;Set up segment to intercept Interrupts
        ORG     9H*4            ;The keyboard Interrupt
KEYBOARD_INT     LABEL   DWORD
        ORG     1CH*4           ;Timer Interrupt
TIMER_VECTOR      LABEL   DWORD
VECTORS ENDS

SCREEN  SEGMENT AT 0B000H       ;A dummy segment to use as the
SCREEN  ENDS                    ;Extra Segment 

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_KEEPER        ;First time through 

        COPY_RIGHT      DB      '(C)1985 S.HOLZNER' ;Ascii autograph
        PAD             DB      20*102 DUP(0)       ;Memory storage for pad  
        PAD_CURSOR      DW      9*102               ;Current position in pad
        ATTRIBUTE       DB      112             ;Pad Attribute -- reverse video
        LINE_ATTRIBUTE  DB      240             ;Flashing Rev video
        OLD_ATTRIBUTE   DB      7               ;Original screen attrib: normal
        PAD_OFFSET      DW      0               ;Chooses 1st 250 bytes or 2nd
        FIRST_POSITION  DW      ?               ;Position of 1st char on screen
        TRIGGER_FLAG    DW      0               ;Trigger on or off
        FULL_FLAG       DB      0               ;Buffer Full Flag
        LINE            DW      9               ;Line number, 0-9
        SCREEN_SEG_OFFSET       DW      0       ;0 for mono, 8000H for graphics
        IO_CHAR         DW      ?               ;Holds addr of Put or Get_Char
        STATUS_PORT     DW      ?               ;Video controller status port
        OLD_KEYBOARD_INT        DD      ?       ;Location of old kbd interrupt
        FINISHED_FLAG           DB      1       ;If not finished,f buffer 
        COMMAND_INDEX           DW      1       ;Stores positior timer)
        ROM_TIMER               DD      1       ;The Timer interrupt's address
        OLD_HEAD        DW      0

KEEPER   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
        PUSH    ES
        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
        JE      BYE                     ;So leave 
        MOV     DX,HEAD
        SUB     DX,2                    ;Point to just read in character
        CMP     DX,OFFSET BUFFER        ;Did we undershoot buffer?
        JAE     NOWRAP                  ;Nope
        MOV     DX,OFFSET BUFFER_END    ;Yes -- move to buffer top
        SUB     DX,2                    ;Compare two bytes back from head
NOWRAP: CMP     DX,TAIL                 ;If it's the tail, buffer is full
        JNE     NOTFULL                 ;We're OK, jump to NotFull
        CMP     FULL_FLAG,1             ;Check if keyboard buffer full
        JE      BYE                     ;Yep, leave
        MOV     FULL_FLAG,1             ;Oops, full, set flag and take
        JMP     CHK                     ; this last character
NOTFULL:MOV     FULL_FLAG,0             ;Always reset Full_Flag when buff clears
CHK:    CMP     TRIGGER_FLAG,0          ;Is the window on (triggered?)
        JNE     SUBT                    ;Yep, keep going
        MOV     DX,OLD_HEAD             ;Check position of buffer head
        CMP     DX,HEAD
        JNE     CONT
        MOV     OLD_HEAD,0
BYE:    JMP     OUT
CONT:   MOV     DX,HEAD
        MOV     OLD_HEAD,DX
SUBT:   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        
        ;------ CHAR IN DX NOW -------
        CMP     FINISHED_FLAG,0
        JE      IN             
        CMP     DX,310EH                ;Default trigger is a ^N here.
        JNE     NOT_TRIGGER             ;No
        MOV     TAIL,BX
        NOT     TRIGGER_FLAG            ;Switch Modes
        CMP     TRIGGER_FLAG,0          ;Trigger off?
        JNE     TRIGGER_ON              ;No, only other choice is on
TRIGGER_OFF:
        MOV     OLD_HEAD,0              ;Reset old head
        MOV     AH,OLD_ATTRIBUTE        ;Get ready to restore screen
        MOV     ATTRIBUTE,AH            ;Pad and blinking line set to orig.
        MOV     LINE_ATTRIBUTE,AH       ; values
        MOV     PAD_OFFSET,10*102       ;Point to 2nd half of pad
        LEA     AX,PUT_CHAR             ;Make IO call Put_Char as it scans
        MOV     IO_CHAR,AX              ;over all locations in pad on screen
        CALL    IO                      ;Restore screen
        CMP     LINE,9                  ;Was the window turned off without
        JE      IN                      ; using up-down keys? If so, exit
        MOV     AX,LINE                 ;No, there is a line to stuff in
        MOV     CL,102                  ; keyboard buffer
        MUL     CL                      ;Find its location in Pad
        MOV     COMMAND_INDEX,AX        ;And send to Put
        CALL    PUT                     ;Which will do actual stuffing
IN:     JMP     OUT                     ;Done
TRIGGER_ON:                             ;Window just turned on
        MOV     LINE,9                  ;Set blinking line to bottom
        MOV     PAD_OFFSET,10*102       ;Point to screen storage part of pad
        LEA     AX,GET_CHAR             ;Make IO use Get_char so current screen
        MOV     IO_CHAR,AX              ;is stored
        CALL    IO                      ;Store Screen
        CALL    DISPLAY                 ;And put up the pad
        JMP     OUT                     ;Done here.
NOT_TRIGGER:
        TEST    TRIGGER_FLAG,1          ;Is Trigger on?
        JZ      RUBOUT_TEST
        MOV     TAIL,BX                 ;Yes, delete this char from buffer
UP:     CMP     DX,4800H                ;An Up cursor key?
        JNE     DOWN                    ;No, try Down
        DEC     LINE                    ;Move blinker up one line
        CMP     LINE,0                  ;At top? If so, reset
        JGE     NOT_TOP
        MOV     LINE,9
NOT_TOP:CALL    DISPLAY                 ;Display result
        JMP     OUT                     ;And leave
DOWN:   CMP     DX,5000H                ;Perhaps Down cusor key pushed
        JNE     IN                      ;If not, ignore key
        INC     LINE                    ;If so, move down one
        CMP     LINE,9                  ;If at bottom, wrap to top
        JLE     NOT_BOT
        MOV     LINE,0
NOT_BOT:CALL    DISPLAY                 ;Show results
        JMP     OUT                     ;And exit
RUBOUT_TEST:
        CMP     DX,0E08H                ;Is it a Rubout?
        JNE     CHAR_TEST               ;No -- try carriage return-line feed
        MOV     BX,PAD_CURSOR           ;Yes -- get current pad location
        CMP     BX,9*102                ;Are we at beginning of last line?
        JLE     NEVER_MIND              ;Yes -- can't rubout past beginning
        SUB     PAD_CURSOR,2            ;No, rubout this char
        MOV     PAD[BX-2],20H           ;Move a space in instead (3920H)
        MOV     PAD[BX-1],39H
NEVER_MIND:
        JMP     OUT                     ;Done here.
CHAR_TEST:
        CMP     DL,13                   ;Is this a carriage return?
        JE      PLUG                    ;If yes, plug this line into Pad
        CMP     DL,32                   ;If this char < Ascii 32, delete line
        JGE     PLUG
        MOV     PAD_CURSOR,9*102        ;Clear the current line
        MOV     CX,51
        MOV     BX,9*102
CLEAR:  MOV     WORD PTR PAD[BX],0
        ADD     BX,2
        LOOP    CLEAR
        JMP     OUT                     ;And exit

PLUG:   MOV     BX,PAD_CURSOR           ;Get current pad location
        CMP     BX,10*102-2             ;Are we past the end of the pad?
        JGE     CRLF_TEST               ;Yes -- throw away char
        MOV     WORD PTR PAD[BX],DX     ;No -- move ASCII code into pad
        ADD     PAD_CURSOR,2            ;Increment pad location
CRLF_TEST:
        CMP     DX,1C0DH                ;Is it a carriage return-line feed?
        JNE     OUT                     ;No -- put it in the pad
        CALL    CRLF                    ;Yes -- move everything up in pad
OUT:    POP     ES                      ;Having done Pushes, here are the Pops
        POP     DS
        POP     SI
        POP     DI
        POP     DX
        POP     CX
        POP     BX
        POP     AX     
        IRET                    ;An interrupt needs an IRET
KEEPER   ENDP

DISPLAY PROC    NEAR                    ;Puts the whole pad on the screen
        PUSH    AX
        MOV     ATTRIBUTE,112           ;Use reverse video
        MOV     LINE_ATTRIBUTE,240
        MOV     PAD_OFFSET,0            ;Use 1st 250 bytes of pad memory
        LEA     AX,PUT_CHAR             ;Make IO use Put-Char so it does
        MOV     IO_CHAR,AX              
        CALL    IO                      ;Put result on screen
        POP     AX
        RET                             ;Leave
DISPLAY ENDP

CRLF    PROC    NEAR                    ;This handles carriage returns
        PUSH    BX                      ;Push everything conceivable
        PUSH    CX           
        PUSH    DI
        PUSH    SI
        PUSH    DS
        PUSH    ES   
        ASSUME  DS:CODE_SEG             ;Set DS to Code_Seg here
        PUSH    CS
        POP     DS
        ASSUME  ES:CODE_SEG             ;And ES too
        PUSH    DS
        POP     ES
        LEA     DI,PAD                  ;Get ready to move contents of Pad
        MOV     SI,DI                   ; up one line
        ADD     SI,102                  ;DI-top line, SI-one below top line
        MOV     CX,9*51
        MOV     BX,PAD_CURSOR           ;But first finish line with a 0        
        CMP     BX,9*102+2              ; as a flag letting Put know line is
        JE      POPS                    ; done.
        MOV     WORD PTR PAD[BX],0
REP     MOVSW                           ;Move up Pad contents
        MOV     CX,51                   ;Now fill the last line with spaces
        MOV     AX,3920H
REP     STOSW                           ;Using Stosw
POPS:   MOV     PAD_CURSOR,9*102        ;And finally reset Cursor to beginning
        POP     ES                      ; of the last line again.
        POP     DS
        POP     SI
        POP     DI
        POP     CX
        POP     BX
DONE:   RET                             ;And out.
CRLF    ENDP

GET_CHAR        PROC    NEAR    ;Gets a char from screen and advances position
        ASSUME  ES:SCREEN,DS:ROM_BIOS_DATA
        PUSH    DX
        MOV     SI,2            ;Loop twice, once for char, once for attribute
        MOV     DX,STATUS_PORT  ;Get ready to read video controller status
G_WAIT_LOW:                     ;Start waiting for a new horizontal scan -

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -