⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 filemon.c

📁 File System Driver for monitorinf File system Activity.
💻 C
字号:
/*
FILEMON.C -- File monitoring VxD for Windows 95
For Win32 app: CONLDR.C
Stan Mitchell

See Stan Mitchell, "Monitoring Windows 95 File Activity in Ring 0,"
Windows/DOS Developer's Journal, July 1995, pp. 6-24.

Also see ftp://ftp.ora.com/pub/examples/windows/win95.update/regwiz.html
*/

/*****    Listing 1    FILEMON.C   *****/
#include <string.h>
#define WANTVXDWRAPS
#include <basedef.h>
#include <vmm.h>
#include <debug.h>
#include <vwin32.h>
#include <winerror.h>
#include <vxdwraps.h>
#include <ifs.h>
enum IFSMGR_SERVICES { __UniToBCSPath=0x00400041,
    __IFSMgr_InstallFileSystemApiHook=0x00400067,
    __IFSMgr_RemoveFileSystemApiHook=0x00400068 };

/* The buffer contains 256 LINEs, the first is reserved */
/* for status, lines 0 through 254 are used for output lines */
#define MAXLINE 254
typedef char LINE[128];

#pragma VxD_LOCKED_DATA_SEG

char* szOp[] = { "Read", "Write", "FndNext", "FcnNext",
  "?","?","?","?","?","?", "Seek", "Close", "Commit",
  "FLocks", "FTimes", "PipeReq", "HdlInfo", "EnumHdl",
  "FndClose", "FcnClose", "?","?","?","?","?","?","?",
  "?","?","?", "Conn", "Delete", "Dir", "FAttrib",
  "Flush", "DiskInfo", "Open", "Rename", "Search",
  "Query", "DisConn", "UNCPipeReq", "Ioctl", "DiskParm",
  "FndOpen", "Dasdio" };

ppIFSFileHookFunc ppPrevHook; /* the previous hooker */
HTIMEOUT hTimeOut  = 0;
DWORD hVMEvent     = 0;
HANDLE hEventRing0 = 0;
HVM hSysVM;
LINE* pLineBuf     = NULL; /* buffer for output lines */
DWORD* pdw         = NULL;
int nLastLine      = -1;

#define DIOC_REQEVENTS 1
#define DIOC_SHUTDOWN  2

#pragma VxD_LOCKED_CODE_SEG

#pragma intrinsic(strcpy,strcat,memcpy)

/* Wrapper for the IFS Mgr Service, UniToBCSPath */
UINT __declspec( naked )
UniToBCSDrvPath( UCHAR* pStr, PathElement* pPth,
                 UINT maxL, int cSet, int drv ) {
    _asm push ebp      _asm mov ebp,esp
    _asm push ebx
    _asm mov  ebx,[pStr]
    _asm mov  eax,[drv]
    _asm cmp  al,0ffh /* UNC volume? */
    _asm jz   skipdrv
    _asm add  al,'@'
    _asm mov  byte ptr [ebx],al
    _asm inc  ebx
    _asm mov  byte ptr [ebx],':'
    _asm inc  ebx
 skipdrv:
    _asm push [cSet]  /* Arguments pushed */
    _asm push [maxL]  /* in cdecl order */
    _asm push [pPth]
    _asm push ebx
    VxDCall( UniToBCSPath );
    _asm add esp,4*4
    _asm pop ebx      /* eax returns byte cnt */
    _asm leave   _asm ret
    }

/* Called as System VM Event */
void __declspec( naked ) SetWin32Event( void ) {
    _asm push ebp   _asm mov ebp,esp
    _asm mov eax,[edx]
    VxDCall( _VWIN32_SetWin32Event );
    hVMEvent = 0;
    _asm leave   _asm ret
    }

#define LPtr(a)        (&pLineBuf[idx][a])
#ifdef SHOW_HANDLES
#define AddResHdl(a)   _Sprintf(LPtr(a),"{%08lx} ",pir->ir_rh)
#define AddFileHdl(a)  _Sprintf(LPtr(a),"[%08lx] ",pir->ir_fh)
#define SkpFileHdl(a)  _Sprintf(LPtr(a), "%11s"," ")
#else
#define AddResHdl(a)   0
#define AddFileHdl(a)  0
#define SkpFileHdl(a)  0
#endif
#define AddUniPath(a,n) UniToBCSDrvPath( LPtr(a), pUniPath,\
                                       n, BCS_WANSI, drv)
#define CatStr(s)      strcat(pLineBuf[idx],s)

/* The FileSystem Hook Function */
int __cdecl FileHook( pIFSFunc pfn,
    int fn, int drv, int res,
    int cp, pioreq pir )
    {
    int retc, idx, i;
    PathElement* pUniPath;
    unsigned short preOptions;

    /* Go ahead and call down the chain to the FSD ...
     *   we look at the IFSFunc only if it succeeds */
    preOptions = pir->ir_options;

    retc = (*(*ppPrevHook))( pfn, fn, drv, res, cp, pir );
    if ( !hEventRing0 ) return retc;

    // Functions which are included in this switch statement
    //  are not monitored
    switch( fn ) {

        case IFSFN_FILETIMES:   /* "GetFTimes" */
            if ( (pir->ir_flags != GET_MODIFY_DATETIME) &&
                 (pir->ir_flags != GET_LAST_ACCESS_DATETIME) &&
                 (pir->ir_flags != GET_CREATION_DATETIME) )
                break;

        case IFSFN_READ:        /* "Read" */
        case IFSFN_WRITE:       /* "Write" */
        case IFSFN_SEEK:        /* "Seek" */
        case IFSFN_CLOSE:       /* "Close" */
        case IFSFN_FINDCLOSE:
        case IFSFN_FCNCLOSE:
        case IFSFN_FINDNEXT:    /* "Next" */
        case IFSFN_FCNNEXT:
            return retc;
        }

    /* Point to the Unicode path components of the file */
    pUniPath = pir->ir_ppath->pp_elements;

    _asm pushfd
    _asm cli
    if ( ++nLastLine > MAXLINE ) nLastLine=0;
    idx = nLastLine;
    _asm popfd
    i = _Sprintf( pLineBuf[idx], " %3d %c %10s %c ",
            idx, pir->ir_error ? 'e' : ' ', szOp[fn],
            res & IFSFH_RES_CFSD ? 'c' : ' ' );

    switch( fn )
        {
    case IFSFN_READ:    case IFSFN_WRITE:
        i+=AddFileHdl(i); i+=AddResHdl(i);
        _Sprintf( LPtr(i), "leng: %08lx %c%c",
            pir->ir_length,
            (preOptions & R0_SWAPPER_CALL) ? 's' : ' ',
            (preOptions & R0_MM_READ_WRITE) ? 'm' : ' ' );
        break;
    case IFSFN_SEEK:        case IFSFN_CLOSE:
    case IFSFN_FINDNEXT:    case IFSFN_FINDCLOSE:
    case IFSFN_FCNNEXT:     case IFSFN_FCNCLOSE:
    case IFSFN_COMMIT:      case IFSFN_ENUMHANDLE:
    case IFSFN_FILELOCKS:
        i+=AddFileHdl(i);  AddResHdl(i);
        break;
    case IFSFN_IOCTL16DRIVE: case IFSFN_SEARCH:
        i+=SkpFileHdl(i);  i+=AddResHdl(i);
        _Sprintf(LPtr(i),"SubFunction: %04X",pir->ir_flags);
        break;
    case IFSFN_QUERY:
        i+=SkpFileHdl(i);  i+=AddResHdl(i);
        i+=_Sprintf(LPtr(i),"Level %d ",preOptions);
        break;
    case IFSFN_DELETE:  case IFSFN_FINDOPEN:
    case IFSFN_RENAME:
        i+=SkpFileHdl(i);  i+=AddResHdl(i);
        if ( fn == IFSFN_RENAME ) {
            i+=AddUniPath(i,45);
            pUniPath = pir->ir_ppath2->pp_elements;
            if ( drv != 0xff ) i+=2;
            CatStr(" -> "); i+=4;
            AddUniPath(i,45);
            }
        else i+=AddUniPath(i,80);
        break;
    case IFSFN_CONNECT:
        i+=SkpFileHdl(i);  AddResHdl(i);
        switch( pir->ir_flags ) {
        case RESTYPE_WILD:
            CatStr("wild card"); break;
        case RESTYPE_DISK:
            CatStr("disk"); break;
        case RESTYPE_SPOOL:
            CatStr("spooled printer"); break;
        case RESTYPE_CHARDEV:
            CatStr("char device"); break;
        case RESTYPE_IPC:
            CatStr("ipc"); break;
            }
        break;
    case IFSFN_FILEATTRIB:
        if ( pir->ir_flags == GET_ATTRIBUTES )
            memcpy( &pLineBuf[idx][8], "Get", 3 );
        else memcpy( &pLineBuf[idx][8], "Set", 3 );
        i+=SkpFileHdl(i);  i+=AddResHdl(i);
        AddUniPath(i,80);
        break;
    case IFSFN_FILETIMES:
        if ( (pir->ir_flags == GET_MODIFY_DATETIME) ||
             (pir->ir_flags == GET_LAST_ACCESS_DATETIME) ||
             (pir->ir_flags == GET_CREATION_DATETIME) )
            memcpy( &pLineBuf[idx][9], "Get", 3 );
        else memcpy( &pLineBuf[idx][9], "Set", 3 );
        i+=AddFileHdl(i);  i+=AddResHdl(i);
        break;
    case IFSFN_DIR:
        if ( pir->ir_flags == CREATE_DIR )
            memcpy( &pLineBuf[idx][12], "Mk", 2 );
        else if ( pir->ir_flags == DELETE_DIR )
            memcpy( &pLineBuf[idx][12], "Rd", 2 );
        else if ( pir->ir_flags == CHECK_DIR )
            memcpy( &pLineBuf[idx][12], "Ck", 2 );
        else memcpy( &pLineBuf[idx][11], "Qry", 3 );
        i+=SkpFileHdl(i);  i+=AddResHdl(i);
        AddUniPath(i,80);
        break;
    case IFSFN_OPEN:
        i+=AddFileHdl(i); i+=AddResHdl(i);
        AddUniPath(i,80);
        if ( pir->ir_options == ACTION_CREATED )
            memcpy( &pLineBuf[idx][11], "Create", 6 );
        break;
    case IFSFN_DISCONNECT:   case IFSFN_FLUSH:
    case IFSFN_GETDISKINFO:  case IFSFN_GETDISKPARMS:
    case IFSFN_DASDIO:
        i+=SkpFileHdl(i);  AddResHdl(i);
        break;
        }

    _asm pushfd
    _asm cli
    *pdw = idx; /* last completed line */
    _asm popfd

    return retc; /* make sure we return what the FSD did */
    }

void __declspec( naked ) DisplayFSDEvent( void )  {
    _asm push ebp   _asm mov ebp,esp
    hTimeOut = 0;
    if ( hEventRing0 != 0 ) { 
        _asm mov ebx,[hSysVM]
        _asm mov esi,offset SetWin32Event
        _asm mov edx,offset hEventRing0
        VxDCall( Schedule_VM_Event );
        _asm mov [hVMEvent],esi
        }
    _asm leave   _asm ret
    }

DWORD __stdcall W32_RequestEvents( DWORD dwDDB,
                                   PDIOCPARAMETERS pD )
    {
    DWORD* pdwArgs;

    if ( pdw == NULL ) { /* First time */
        /* Check for valid arguments */
        if ( pD->cbInBuffer != sizeof(DWORD)*2 )
            return 1;

        /* Get the parameters passed by the caller */
        pdwArgs = (DWORD*)pD->lpvInBuffer;

        /* hEventRing0, the handle to the ring 0 event */
        hEventRing0 = (HANDLE)pdwArgs[0];

        /* First line reserved for pointers */
        pdw = (DWORD*)pdwArgs[1];
        *pdw = *(pdw+1) = -1;

        /* pLineBuf, circular buffer in which to
         * store the file activity events */
        pLineBuf = ((LINE*)pdwArgs[1])+1;

        if (!_LinPageLock((DWORD)pdw>>12,8,PAGEMAPGLOBAL))
            return 1; /* lock failed */
        }

    hTimeOut = Set_Global_Time_Out( DisplayFSDEvent, 250, 0 );
    return 0;
    }

DWORD __stdcall
W32_Shutdown( DWORD dwDDB, PDIOCPARAMETERS pD ) {
    /* Remove our filesystem API hook */
    _asm mov eax,OFFSET FileHook
    _asm push eax
    VxDCall( IFSMgr_RemoveFileSystemApiHook );
    _asm add esp,4
    return 0;
    }

/* Win32 interface for FileMon */
int __stdcall
CtrlMsg_W32DeviceIoControl( DWORD dwIoCtrlCode, /*ecx*/
                            DWORD dwDDB,        /*ebx*/
                            DWORD pDIOCParams ) /*esi*/
    {
    if ( dwIoCtrlCode == DIOC_OPEN ||
         dwIoCtrlCode == DIOC_CLOSEHANDLE)
        return 0L; /* tell Win32, VxD supports DEVIOCTL */

    /* private Win32 API provided by FileMon */
    if ( dwIoCtrlCode == DIOC_REQEVENTS )
        return W32_RequestEvents(dwDDB,(PDIOCPARAMETERS)pDIOCParams);
    if ( dwIoCtrlCode == DIOC_SHUTDOWN )
        return W32_Shutdown(dwDDB,(PDIOCPARAMETERS)pDIOCParams);
    return ERROR_NOT_SUPPORTED;
    }

#pragma VxD_PAGEABLE_CODE_SEG
/*  Called when device is unloaded */
int __stdcall CleanUp( void ) {
    if (hTimeOut) Cancel_Time_Out(hTimeOut);
    if (hVMEvent)  { _asm mov ebx,[hSysVM]
                     _asm mov esi,[hVMEvent]
                     VxDCall(Cancel_VM_Event);
                   }
    if (hEventRing0) { _asm mov eax,[hEventRing0]
                       VxDCall(_VWIN32_CloseVxDHandle);
                     }
    _LinPageUnlock((DWORD)pdw>>12,8,PAGEMAPGLOBAL);
    return(VXD_SUCCESS);
    }

/* Called when device is unloaded by VXDLDR */
int __stdcall CtrlMsg_DynDeviceExit( void ) {
    return CleanUp();
    }

/* Always called when the system is normally shutting down */
int __stdcall
CtrlMsg_SysVMTerminate( DWORD hSysVMHandle ) {
    return CleanUp();
    }

#pragma VxD_ICODE_SEG
/*  Called when Device is loaded by VXDLDR */
int __stdcall CtrlMsg_DynDeviceInit( void ) {
    /* Install the filesystem API hook */
    hSysVM = Get_Sys_VM_Handle();
    _asm mov eax,OFFSET FileHook
    _asm push eax
    VxDCall( IFSMgr_InstallFileSystemApiHook );
    _asm add esp,4
    _asm mov ppPrevHook,eax
    return( ppPrevHook == 0 ? VXD_FAILURE
                            : VXD_SUCCESS );
    }
/***************** end of file ******************/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -