📄 hookfile.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 /* warning *//******************************************************************//* Includes *//******************************************************************/// module's interface#include "HookFile.h"// standard headers#include <tchar.h>#include <winsock2.h>// ddk headers#include <ddk/ntddk.h>// project's headers#include "Assert.h"#include "FileInfo.h"#include "HookCommon.h"#include "Hooks.h"#include "Malloc.h"#include "NtUndoc.h"#include "Strlcpy.h"#include "Trace.h"#include "WatchedObjects.h"/******************************************************************//* Internal data types *//******************************************************************/typedef struct { int nType ; int nProtocol ; SOCKADDR_STORAGE address ;} SOCKETDATA ;/******************************************************************//* Internal macros *//******************************************************************/#define STATIC_UNICODE_STRING(symbol,value) \ static UNICODE_STRING symbol = {sizeof(value)-sizeof(WCHAR),sizeof(value),value} ;/******************************************************************//* Internal data *//******************************************************************/STATIC_UNICODE_STRING (g_usUnknownFile, L"!! Unknown file !!" ) ;/******************************************************************//* Exported function *//******************************************************************/NTSTATUS WINAPI Hook_IoCreateFile (PHANDLE FileHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, PIO_STATUS_BLOCK IoStatusBlock, PLARGE_INTEGER AllocationSize, ULONG FileAttributes, ULONG ShareAccess, ULONG Disposition, ULONG CreateOptions, PVOID EaBuffer, ULONG EaLength, CREATE_FILE_TYPE CreateFileType, PVOID ExtraCreateParameters, ULONG Options){ PROC pfnStub = Hooks_GetStubAddress (HOOKS_IOCREATEFILE) ; UNICODE_STRING usDosPath ; BOOL bIsFile ; NTSTATUS nStatus ; UINT nReaction = RULE_ACCEPT ; UINT nOptions = 0 ; LARGE_INTEGER liFileTime = {{0}} ; if( ObjectAttributes ) TRACE_INFO (TEXT("%ls (0x%X)\n"), ObjectAttributes->ObjectName->Buffer, DesiredAccess) ; else TRACE_WARNING (TEXT("ObjectAttributes==NULL\n")) ; usDosPath.Length = 0 ; usDosPath.MaximumLength = sizeof(WCHAR) * MAX_PATH ; usDosPath.Buffer = MALLOC(usDosPath.MaximumLength) ; // allocation failed ? if( usDosPath.Buffer == NULL ) { TRACE_ERROR (TEXT("Failed to allocate buffer for file name (%u bytes)\n"), usDosPath.MaximumLength) ; return STATUS_INSUFFICIENT_RESOURCES ; } if( ObjectAttributes && ObjectAttributes->ObjectName && ObjectAttributes->ObjectName->Buffer ) { nStatus = FileInfo_NtPathToDosPath (NULL, ObjectAttributes->RootDirectory, ObjectAttributes->ObjectName, &usDosPath) ; } else { RtlAppendUnicodeToString (&usDosPath, L"ObjectAttributes=NULL") ; nStatus = STATUS_UNSUCCESSFUL ; } if( CreateOptions & FILE_OPEN_BY_FILE_ID ) TRACE_WARNING (TEXT("IoCreateFile called with flag FILE_OPEN_BY_FILE_ID (file=%ls)\n"), usDosPath.Buffer) ; //TRACE_ALWAYS (TEXT("%ls\n"), usDosPath.Buffer) ; // TO BE CHANGED !!!!!!!!!!!!! bIsFile = nStatus==STATUS_SUCCESS && usDosPath.Buffer[1]==L':' && usDosPath.Buffer[2]==L'\\' ; if( bIsFile ) { // log call if( ( DesiredAccess & (GENERIC_WRITE|GENERIC_ALL|0x10000) ) || ( Disposition==FILE_SUPERSEDE ) || ( Disposition==FILE_CREATE ) || ( Disposition==FILE_OVERWRITE ) || ( Disposition==FILE_OVERWRITE_IF) || ( CreateOptions & (FILE_DELETE_ON_CLOSE)) ) HookCommon_CatchCall (&nReaction, NULL, FILTREASON_FILE_WRITE, TEXT("s"), usDosPath.Buffer) ; if( nReaction==RULE_ACCEPT && (DesiredAccess&(GENERIC_READ|GENERIC_ALL)) ) HookCommon_CatchCall (&nReaction, &nOptions, FILTREASON_FILE_READ, TEXT("s"), usDosPath.Buffer) ; if( nReaction != RULE_ACCEPT ) { IoStatusBlock->Status = STATUS_ACCESS_DENIED ; IoStatusBlock->Information = 0 ; FREE (usDosPath.Buffer) ; return STATUS_ACCESS_DENIED ; } if( (nOptions & RULE_SCAN) && HookCommon_ShouldScanFile(usDosPath.Buffer) ) { TRACE_INFO (TEXT("Gonna scan %ls\n"), usDosPath.Buffer) ; // open the file to get its time nStatus = (NTSTATUS)pfnStub (FileHandle, DesiredAccess, ObjectAttributes, IoStatusBlock, AllocationSize, FileAttributes, ShareAccess, FILE_OPEN, 0, NULL, 0, CreateFileTypeNone, NULL, Options) ; // if we can't open the file, just return if( nStatus == STATUS_SUCCESS ) { // get file time nStatus = FileInfo_GetLastWriteTimeFromHandle (*FileHandle, &liFileTime) ; TRACE_INFO (TEXT("File time = %lu\n"), liFileTime.QuadPart) ; // close the temporary handle, so the antivirus can read the file ZwClose (*FileHandle) ; HookCommon_ScanFile (&nReaction, usDosPath.Buffer, &liFileTime) ; TRACE_INFO (TEXT("Scan result = %d\n"), nReaction) ; if( nReaction!=RULE_ACCEPT ) { TRACE_ALWAYS (TEXT("Denying access to %ls\n"), usDosPath.Buffer) ; FREE (usDosPath.Buffer) ; *FileHandle = NULL ; return STATUS_ACCESS_DENIED ; } } else { TRACE_INFO (TEXT("Failed to open %ls\n"), usDosPath.Buffer) ; } } } //DbgPrint ("Calling IoCreateFile... %ls\n", usDosPath.Buffer); nStatus = (NTSTATUS)pfnStub (FileHandle, DesiredAccess, ObjectAttributes, IoStatusBlock, AllocationSize, FileAttributes, ShareAccess, Disposition, CreateOptions, EaBuffer, EaLength, CreateFileType, ExtraCreateParameters, Options) ; //DbgPrint ("Calling IoCreateFile... result = 0x%08X\n", nStatus); if( SUCCEEDED(nStatus) ) { PVOID pObject = NULL ; if( bIsFile && liFileTime.QuadPart==0 ) { nStatus = FileInfo_GetLastWriteTimeFromHandle (*FileHandle, &liFileTime) ; if( nStatus!=STATUS_SUCCESS ) TRACE_ERROR (TEXT("FileInfo_GetLastWriteTimeFromHandle (file=\"%ls\", status=0x%08X)\n"), usDosPath.Buffer, nStatus) ; } nStatus = ObReferenceObjectByHandle (*FileHandle, GENERIC_ALL, NULL, KernelMode, &pObject, NULL) ; if( nStatus==STATUS_SUCCESS && pObject!=NULL ) { nStatus = WatchObjs_Lock () ; if( nStatus == STATUS_SUCCESS ) { nStatus = WatchObjs_AddWotFile (pObject, &liFileTime, &usDosPath) ; WatchObjs_Unlock () ; } if( FAILED(nStatus) ) TRACE_WARNING (TEXT("WatchObjs_AddWotFile failed (status=0x%08X)\n"), nStatus) ; ObDereferenceObject (pObject) ; } else { TRACE_ERROR (TEXT("ObReferenceObjectByHandle failed (status=0x%08X)\n"), nStatus) ; } nStatus = STATUS_SUCCESS ; } FREE (usDosPath.Buffer) ; return nStatus ;}/******************************************************************//* Exported function : *//******************************************************************/NTSTATUS WINAPI Hook_NtDeleteFile (POBJECT_ATTRIBUTES ObjectAttributes) { PROC pfnStub = Hooks_GetStubAddress (HOOKS_NTDELETEFILE) ; NTSTATUS nStatus ; WCHAR szFilePath[MAX_PATH] ; UNICODE_STRING usDosPath ; BOOL bIsFile ; usDosPath.Length = 0 ; usDosPath.MaximumLength = sizeof(WCHAR) * MAX_PATH ; usDosPath.Buffer = szFilePath ; nStatus = STATUS_UNSUCCESSFUL ; if( ObjectAttributes && ObjectAttributes->ObjectName && ObjectAttributes->ObjectName->Buffer && ObjectAttributes->ObjectName->Buffer[0] ) { nStatus = FileInfo_NtPathToDosPath (NULL, ObjectAttributes->RootDirectory, ObjectAttributes->ObjectName, &usDosPath) ; } else if( ObjectAttributes && ObjectAttributes->RootDirectory ) { WOTFILE *pWotFileData ; ULONG nWotDataSize ; PVOID pObject = NULL ; nStatus = ObReferenceObjectByHandle (ObjectAttributes->RootDirectory, GENERIC_ALL, NULL, KernelMode, &pObject, NULL) ; if( nStatus==STATUS_SUCCESS && pObject!=NULL ) { nStatus = WatchObjs_Lock () ; if( nStatus == STATUS_SUCCESS ) { nStatus = WatchObjs_GetFromPointer (pObject, WOT_FILE, (void**)&pWotFileData, &nWotDataSize) ; if( nStatus==STATUS_SUCCESS ) wcslcpy (szFilePath, pWotFileData->wszFilePath, MAX_PATH) ; WatchObjs_Unlock () ; } ObDereferenceObject (pObject) ; } else { TRACE_ERROR (TEXT("ObReferenceObjectByHandle failed (status=0x%08X)\n"), nStatus) ; return nStatus ; } } if( nStatus!=STATUS_SUCCESS ) { wcslcpy (szFilePath, L"!! Unknown file !!", MAX_PATH) ; } TRACE_INFO (TEXT("Delete file : %ls\n"), szFilePath) ; bIsFile = nStatus==STATUS_SUCCESS && szFilePath[1]==L':' ; if( bIsFile ) { UINT nReaction ; // log call HookCommon_CatchCall (&nReaction, NULL, FILTREASON_FILE_WRITE, TEXT("s"), szFilePath) ; if( nReaction == RULE_FEIGN ) return STATUS_SUCCESS ; if( nReaction != RULE_ACCEPT ) return STATUS_ACCESS_DENIED ; } nStatus = (NTSTATUS) pfnStub (ObjectAttributes) ; TRACE_INFO (TEXT("NtDeleteFile result = 0x08X\n"), nStatus) ; return nStatus ;}/******************************************************************//* Exported function *//******************************************************************/NTSTATUS WINAPI Hook_NtSetInformationFile (HANDLE FileHandle, PIO_STATUS_BLOCK IoStatusBlock, PVOID FileInformation, ULONG Length, ULONG FileInformationClass){ { UINT nReaction = RULE_ACCEPT ; TRACE_INFO ("FileInformationClass = %d\n", FileInformationClass) ; if( FileInformationClass==FileRenameInformation || FileInformationClass==FileLinkInformation ) { // // Original file name // if( nReaction == RULE_ACCEPT ) { NTSTATUS nStatus ; WCHAR szFilePath[MAX_PATH] ; PVOID pObject = NULL ; nStatus = ObReferenceObjectByHandle (FileHandle, GENERIC_ALL, NULL, KernelMode, &pObject, NULL) ; if( nStatus==STATUS_SUCCESS && pObject!=NULL ) { WOTFILE *pWotFileData ; ULONG nWotDataSize ; nStatus = WatchObjs_Lock () ; if( nStatus == STATUS_SUCCESS ) { nStatus = WatchObjs_GetFromPointer (pObject, WOT_FILE, (void**)&pWotFileData, &nWotDataSize) ; if( nStatus==STATUS_SUCCESS ) wcslcpy (szFilePath, pWotFileData->wszFilePath, MAX_PATH) ; WatchObjs_Unlock () ; } else wcslcpy (szFilePath, g_usUnknownFile.Buffer, MAX_PATH) ; ObDereferenceObject (pObject) ; HookCommon_CatchCall (&nReaction, NULL, FILTREASON_FILE_WRITE, TEXT("s"), szFilePath) ; } else { TRACE_ERROR (TEXT("ObReferenceObjectByHandle failed (status=0x%08X)\n"), nStatus) ; return nStatus ; } } if( nReaction == RULE_ACCEPT ) { WCHAR szFilePath[MAX_PATH] ; FILE_LINK_RENAME_INFORMATION *pInfo = FileInformation ; UNICODE_STRING usDosPath, usNtPath ; NTSTATUS nStatus ; BOOL bIsFile ; usDosPath.Length = 0 ; usDosPath.MaximumLength = sizeof(WCHAR) * MAX_PATH ; usDosPath.Buffer = szFilePath ; usNtPath.Length = pInfo->FileNameLength ; usNtPath.MaximumLength = pInfo->FileNameLength ; usNtPath.Buffer = pInfo->FileName ; nStatus = FileInfo_NtPathToDosPath (NULL, pInfo->RootDirectory, &usNtPath, &usDosPath) ; bIsFile = nStatus==STATUS_SUCCESS && szFilePath[1]==L':' ;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -