📄 hookcommon.c
字号:
/******************************************************************//* *//* Winpooch : Windows Watchdog *//* Copyright (C) 2004-2006 Benoit Blanchon *//* *//* This program is free software; you can redistribute it *//* and/or modify it under the terms of the GNU General Public *//* License as published by the Free Software Foundation; either *//* version 2 of the License, or (at your option) any later *//* version. *//* *//* This program is distributed in the hope that it will be *//* useful, but WITHOUT ANY WARRANTY; without even the implied *//* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR *//* PURPOSE. See the GNU General Public License for more *//* details. *//* *//* You should have received a copy of the GNU General Public *//* License along with this program; if not, write to the Free *//* Software Foundation, Inc., *//* 675 Mass Ave, Cambridge, MA 02139, USA. *//* *//******************************************************************//******************************************************************//* Build configuration *//******************************************************************/#define TRACE_LEVEL 2#define ONLY_DEFAULT_FILTER 0/******************************************************************//* Includes *//******************************************************************/// module's interface#include "HookCommon.h"// project's headers#include "FileInfo.h"#include "FiltCond.h"#include "DrvInterface.h"#include "DrvFilter.h"#include "Link.h"#include "Malloc.h"#include "NtUndoc.h"#include "ProcInfo.h"#include "ProcList.h"#include "ScanCache.h"#include "strlcpy.h"#include "Trace.h"#include "Wildcards.h"/******************************************************************//* Internal constants *//******************************************************************/#define DEFAULT_REACTION RULE_ACCEPT#define DEFAULT_VERBOSITY RULE_SILENT#define MAX_SERIAL_SIZE 1024/******************************************************************//* Internal data types *//******************************************************************/typedef struct { struct { KMUTEX mutex ; UINT nLength ; LPCWSTR *pszArray ; BYTE *pBuffer ; UINT nBufferSize ; } scanfilters ;} INTERNAL_DATA ;/******************************************************************//* Internal data *//******************************************************************/static LPCWSTR g_szUnknownFile = L"!! Unknown file !!" ;static INTERNAL_DATA g_data ;/******************************************************************//* Exported function *//******************************************************************/NTSTATUS HookCommon_Init () { KeInitializeMutex (&g_data.scanfilters.mutex, 0) ; return STATUS_SUCCESS ;}/******************************************************************//* Exported function *//******************************************************************/NTSTATUS HookCommon_Uninit () { FREE (g_data.scanfilters.pszArray) ; FREE (g_data.scanfilters.pBuffer) ; g_data.scanfilters.pszArray = NULL ; g_data.scanfilters.nLength = 0 ; g_data.scanfilters.pBuffer = NULL ; g_data.scanfilters.nBufferSize = 0 ; return STATUS_SUCCESS ; }/******************************************************************//* Internal function *//******************************************************************/NTSTATUS _HookCommon_Ask (PCFILTCOND pCond, DWORD * pnReaction){ SDNASK *pReq ; UINT nSerialSize ; DWORD nRequestSize, nResponseSize ; NTSTATUS nStatus ; TRACE_INFO ("-- ASK --\n") ; pReq = (SDNASK*) MALLOC (sizeof(SDNASK)+MAX_SERIAL_SIZE) ; if( pReq == NULL ) { TRACE_ERROR (TEXT("Failed to allocate structure SDNASK (%u bytes)\n"), sizeof(SDNASK)+MAX_SERIAL_SIZE) ; return STATUS_INSUFFICIENT_RESOURCES ; } pReq->hdr.dwCode = SDN_ASK ; pReq->nProcessAddress = (PROCADDR)PsGetCurrentProcess() ; pReq->nDefReaction = *pnReaction ; nSerialSize = FiltCond_Serialize (pCond, pReq->data, MAX_SERIAL_SIZE) ; if( ! nSerialSize ) { TRACE_ERROR (TEXT("FiltCond_Serialize failed\n")) ; FREE (pReq) ; return STATUS_UNSUCCESSFUL ; } nRequestSize = sizeof(SDNASK) + nSerialSize ; nStatus = Link_QueryServer (pReq, nRequestSize, pnReaction, &nResponseSize, sizeof(DWORD)) ; if( nStatus==STATUS_PORT_DISCONNECTED ) TRACE_INFO (TEXT("App-link disconnected\n")) ; else if( nStatus!=STATUS_SUCCESS ) TRACE_ERROR (TEXT("Failed to query server\n")) ; else if( nResponseSize!=sizeof(DWORD) ) TRACE_ERROR (TEXT("Invalid response size\n")) ; FREE (pReq) ; return nStatus ;}/******************************************************************//* Internal function *//******************************************************************/NTSTATUS _HookCommon_Log (PCFILTCOND pCond, DWORD nReaction, BOOL bAlert){ SDNLOG *pReq ; UINT nSerialSize ; DWORD nRequestSize ; NTSTATUS nStatus ; TRACE_INFO ("-- LOG (addr=0x%08X, pid=%u) --\n", ProcInfo_GetCurrentProcessAddress(), ProcInfo_GetCurrentProcessId()) ; pReq = (SDNLOG*) MALLOC (sizeof(SDNLOG)+MAX_SERIAL_SIZE) ; if( pReq == NULL ) { TRACE_ERROR (TEXT("Failed to allocate structure SDNLOG (%u bytes)\n"), sizeof(SDNLOG)+MAX_SERIAL_SIZE) ; return STATUS_INSUFFICIENT_RESOURCES ; } pReq->hdr.dwCode = bAlert ? SDN_ALERT : SDN_LOG ; pReq->nProcessAddress = (PROCADDR)PsGetCurrentProcess() ; pReq->dwReaction = nReaction ; nSerialSize = FiltCond_Serialize (pCond, pReq->data, MAX_SERIAL_SIZE) ; if( ! nSerialSize ) { TRACE_ERROR (TEXT("FiltCond_Serialize failed\n")) ; FREE (pReq) ; return STATUS_UNSUCCESSFUL ; } nRequestSize = sizeof(SDNLOG) + nSerialSize ; nStatus = Link_QueryServer (pReq, nRequestSize, NULL, NULL, 0) ; if( nStatus==STATUS_PORT_DISCONNECTED ) { TRACE_INFO (TEXT("App-link disconnected\n")) ; return FALSE ; } FREE (pReq) ; return STATUS_SUCCESS ;}/******************************************************************//* Exported function *//******************************************************************/NTSTATUS HookCommon_ShouldScanFile (LPCWSTR szFilePath){ UINT i ; BOOL bShouldScan = FALSE ; if( ProcList_GetScannerExePath()==NULL || ProcList_GetScannerExePath()[0]==0 || !wcsicmp(ProcList_GetScannerExePath(),szFilePath) ) return FALSE ; KeWaitForMutexObject (&g_data.scanfilters.mutex, Executive, KernelMode, FALSE, NULL) ; for( i=0 ; i<g_data.scanfilters.nLength ; i++ ) { LPCWSTR szFilter = g_data.scanfilters.pszArray[i] ; if( Wildcards_CompleteStringCmp(szFilter,szFilePath) ) { bShouldScan = TRUE ; break ; } } KeReleaseMutex (&g_data.scanfilters.mutex, FALSE) ; return bShouldScan ;}/******************************************************************//* Exported function *//******************************************************************/NTSTATUS HookCommon_ScanFile (UINT * pnReaction, LPCWSTR szFilePath, LARGE_INTEGER * pliFileTime){ SDNSCANFILE req ; DWORD nResponseSize ; NTSTATUS nStatus ; SCANCACHEID nCacheId ; SCANRESULT nScanResult ; LARGE_INTEGER liScanTime ; ASSERT (szFilePath!=NULL) ; ASSERT (pliFileTime!=NULL) ; nStatus = ScanCache_Lock () ; if( nStatus != STATUS_SUCCESS ) { TRACE_ERROR (TEXT("ScanCache_Lock() failed (status = 0x%08X)\n"), nStatus) ; return nStatus ; } // // 1. Get file identifier in scan cache // nStatus = ScanCache_GetFileId (szFilePath, &nCacheId) ; if( nStatus != STATUS_SUCCESS ) { TRACE_ERROR (TEXT("ScanCache_GetFileId() failed (status = 0x%08X)\n"), nStatus) ; ScanCache_Unlock () ; return nStatus ; } // // 2. Get scan cache status // getstatus: nStatus = ScanCache_GetStatus (nCacheId, &nScanResult, &liScanTime) ; if( nStatus != STATUS_SUCCESS ) { TRACE_ERROR (TEXT("ScanCache_GetStatus() failed (status = 0x%08X)\n"), nStatus) ; ScanCache_Unlock () ; return nStatus ; } checkstatus: switch( nScanResult ) { case SCAN_NO_VIRUS: case SCAN_VIRUS_ACCEPTED: case SCAN_FAILED_ACCEPTED: *pnReaction = RULE_ACCEPT ; ScanCache_Unlock () ; return STATUS_SUCCESS ; case SCAN_VIRUS: case SCAN_FAILED: *pnReaction = RULE_REJECT ; ScanCache_Unlock () ; return STATUS_SUCCESS ; case SCAN_BEING_SCANNED: TRACE_WARNING (TEXT("%ls is already being scanned\n"), szFilePath) ; nStatus = ScanCache_WaitChange (nCacheId) ; if( nStatus != STATUS_SUCCESS ) { ScanCache_Unlock () ; TRACE_ERROR (TEXT("ScanCache_WaitChange() failed (status = 0x%08X)\n"), nStatus) ; return nStatus ; } goto getstatus ; case SCAN_NOT_SCANNED: break ; } if( ! Link_IsConnected() ) { *pnReaction = DEFAULT_REACTION ; ScanCache_Unlock () ; return STATUS_SUCCESS ; } KeQuerySystemTime (&liScanTime) ; ExSystemTimeToLocalTime (&liScanTime, &liScanTime) ; ScanCache_SetStatus (nCacheId, SCAN_BEING_SCANNED, &liScanTime) ; ScanCache_Unlock () ; TRACE_INFO (TEXT("Scan file %ls\n"), szFilePath) ; if( pliFileTime->QuadPart == 0 ) TRACE_WARNING (TEXT("File time is null.\n")) ; req.hdr.dwCode = SDN_SCANFILE ; req.nProcessAddress = (DWORD)PsGetCurrentProcess() ; wcslcpy (req.wszFilePath, szFilePath, MAX_PATH) ; req.liFileTime = *pliFileTime ; nStatus = Link_QueryServer (&req, sizeof(SDNSCANFILE), &nScanResult, &nResponseSize, sizeof(SCANRESULT)) ; if( nStatus!=STATUS_SUCCESS ) TRACE_ERROR (TEXT("Link_QueryServer failed (status=0x%08X)\n"), nStatus) ; else TRACE_INFO (TEXT("Scan result %u\n"), nScanResult) ; KeQuerySystemTime (&liScanTime) ; ExSystemTimeToLocalTime (&liScanTime, &liScanTime) ; ScanCache_Lock () ; ScanCache_SetStatus (nCacheId, nScanResult, &liScanTime) ; goto checkstatus ;}/******************************************************************//* Exported function *//******************************************************************/NTSTATUS HookCommon_CatchCall (UINT* pnReaction, UINT* pnOptions, UINT nReason, LPCTSTR szFormat, ...) { DWORD nReaction, nVerbosity, nOptions ; BOOL bResult ; va_list va ; FILTCOND cond ; PROCADDR nProcessAddress = ProcInfo_GetCurrentProcessAddress() ; PROCID nProcessId = ProcInfo_GetCurrentProcessId() ; ULONG nProcFlags = 0 ; BOOL bUnknownProcess = FALSE ; BOOL bPidChanged = FALSE ; TRACE_INFO (TEXT("Process address = 0x%08X\n"), nProcessAddress) ; TRACE_INFO (TEXT("Process id = %d\n"), nProcessId) ; // set function result to default values // in case it returns prematurely
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -