Source: http://blog.csdn.net/jazzyfree/
All real-time monitoring anti-virus software called "Virtual Machine" and "_ blank"> firewall "on the market use IFSHOOK technology. at the same time, some friends kept writing emails to ask me how to implement read/write monitoring. the following code is written using VTOOLSD. this is the secret of all real-time anti-virus software. at the same time, many software that intercepts file operations, such as Directory encryption and file encryption, also adopt the same technology.
Because the code is very simple, do not analyze it.
// ================================================ ========================================================
//
// By Lu Lin 2000.5.10
// Apply with VtoolsD 3.01.
// DDK version is available if requested.
// Abstract:
// Install a IFS hook, monitoring any read and write access
//
// ================================================ ========================================================
// IFSHOOK. c-main module for IFSHOOK
# Define DEVICE_MAIN
# Include "ifshook. h"
# Undef DEVICE_MAIN
// Typedef EventHdl (pevent pev, pioreq pir );
Typedef struct _ Monitored_Files {
Struct _ Monitored_Files * pNext_Monitored_Files; // pointer to next struct
Struct _ Monitored_Files * pPre_Monitored_Files; // pointer to previous struct
Int sfn; // system file number
Int open_count;
Char path [260]; // ansi path name
} _ Monitored_Files, * pMonitored_Files;
//
// Declare virtual device
//
Declare_Virtual_Device (IFSHOOK)
_ Monitored_Files;
PpIFSFileHookFunc PrevHook;
DefineControlHandler (SYS_VM_INIT, OnSysVMInit );
DefineControlHandler (SYS_DYNAMIC_DEVICE_INIT, OnSysDynamicDeviceInit );
DefineControlHandler (SYS_DYNAMIC_DEVICE_EXIT, OnSysDynamicDeviceExit );
DefineControlHandler (SYS_VM_TERMINATE, OnSysVMTerminate );
PCHAR ConvertPath (int drive, path_t ppath, PCHAR fullpathname)
{
Int I = 0;
_ QWORD result;
//
// Stick on the drive letter if we know it.
//
If (drive! = 0xFF ){
Fullpathname [0] = drive + A-1;
Fullpathname [1] = :;
I = 2;
}
UniToBCSPath (& fullpathname [I], ppath-> pp_elements, 260, BCS_WANSI, & result );
Return (fullpathname );
}
PMonitored_Files IsFileOpened (int I ){
PMonitored_Files p = & Monitored_Files;
While (p ){
If (I = p-> sfn ){
Return p;
}
P = p-> pNext_Monitored_Files;
}
Return 0;
}
BOOL ControlDispatcher (
DWORD dwControlMessage,
Dword ebx,
Dword edx,
Dword esi,
Dword edi,
Dword ecx)
{
START_CONTROL_DISPATCH
ON_SYS_VM_INIT (OnSysVMInit );
ON_SYS_DYNAMIC_DEVICE_INIT (OnSysDynamicDeviceInit );
ON_SYS_DYNAMIC_DEVICE_EXIT (OnSysDynamicDeviceExit );
END_CONTROL_DISPATCH
Return TRUE;
}
Int _ cdecl MyIfsHook (pIFSFunc pfn, int fn, int Drive, int ResType,
Int CodePage, pioreq pir)
{
Int retvar, I;
Char fullpathname [260];
_ Monitored_Files * FileEntry;
Switch (fn ){
Case IFSFN_OPEN :{
Retvar = (* PrevHook) (pfn, fn, Drive, ResType, CodePage, pir );
ConvertPath (Drive, pir-> ir_ppath, fullpathname );
FileEntry = IsFileOpened (pir-> ir_sfn );
If (FileEntry ){
FileEntry-> open_count ++;
} Else {
FileEntry = & Monitored_Files;
While (1 ){
If (FileEntry-> pNext_Monitored_Files ){
FileEntry = FileEntry-> pNext_Monitored_Files;
}
Else {
Break;
}
}
FileEntry-> pNext_Monitored_Files =
HeapAllocate (sizeof (_ Monitored_Files), HEAPZEROINIT );
FileEntry-> pNext_Monitored_Files-> pPre_Monitored_Files = FileEntry;
FileEntry = FileEntry-> pNext_Monitored_Files;
FileEntry-> sfn = pir-> ir_sfn;
FileEntry-> open_count = 1;
Memcpy (FileEntry-> path, fullpathname, 260 );
}
Return retvar;
}
Case IFSFN_READ :{
// Do something here,
// Eg. Decrypt the file.
Char * str;
Int j;
Str = pir-> ir_data;
J = pir-> ir_length;
Retvar = (* PrevHook) (pfn, fn, Drive, ResType, CodePage, pir );
FileEntry = IsFileOpened (pir-> ir_sfn );
If (! Stricmp ("c: \ test.txt", FileEntry-> path )){
For (I = 0; I <j; I ++ ){
Str [I] --;
}
}
Return retvar;
}
Case IFSFN_WRITE :{
// Do something here
// Eg. Encrypt the file
FileEntry = IsFileOpened (pir-> ir_sfn );
If (FileEntry ){
If (! Stricmp ("c: \ test.txt", FileEntry-> path )){
For (I = 0; I <pir-> ir_length; I ++ ){
(Char *) pir-> ir_data) [I]) ++;
}
}
}
Return (* PrevHook) (pfn, fn, Drive, ResType, CodePage, pir );
}
Case IFSFN_CLOSE :{
FileEntry = IsFileOpened (pir-> ir_sfn );
If (FileEntry ){
FileEntry-> open_count --;
If (! FileEntry-> open_count ){
FileEntry-> pPre_Monitored_Files-> pNext_Monitored_Files =
FileEntry-> pNext_Monitored_Files;
FileEntry-> pNext_Monitored_Files-> pPre_Monitored_Files =
FileEntry-> pPre_Monitored_Files;
HeapFree (FileEntry, 0 );
}
}
Return (* PrevHook) (pfn, fn, Drive, ResType, CodePage, pir );
}
}
Return (* PrevHook) (pfn, fn, Drive, ResType, CodePage, pir );
}
BOOL OnSysVMInit (VMHANDLE hVM ){
Return OnSysDynamicDeviceInit ();
}
BOOL OnSysDynamicDeviceInit ()
{
PrevHook = IFSMgr_InstallFileSystemApiHook (MyIfsHook );
Monitored_Files.pNext_Monitored_Files = 0;
Monitored_Files.pPre_Monitored_Files = 0;
Monitored_Files.sfn =-1;
Monitored_Files.open_count = 0;
Monitored_Files.path [0] = 0;
Return TRUE;
}
BOOL OnSysDynamicDeviceExit ()
{
IFSMgr_RemoveFileSystemApiHook (MyIfsHook );
Return TRUE;
}
Void OnSysVMTerminate (VMHANDLE hVM ){
Return OnSysDynamicDeviceExit ();
}