This is my first windows driver, I want to protect some directory. so I hook the ZwCreateFile, ZwSetInformationFile and ZwWriteFile functions in the SDT table.
But when I run the driver for some days, The Kernel Memory become more and more…
I think there is some memory leak in my code, but I check it many times. I coundn’t find it.
Can somebody help me…, I have little experience on windows driver development, this is my first windows system driver programe. thx …
#include <ntifs.h>
#include <ntddk.h>
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
typedef struct _SDT
{
PULONG ServiceTableBase;
PULONG ServiceCounterTableBase;
ULONG NumberOfService;
PUCHAR ParamTableBase;
}SDT, *PSDT;
extern PSDT KeServiceDescriptorTable; //ntoskrnl.exe???
#define NT_PROCNAMELEN 128
#define NT_FILENAMELEN 2048
#define FILTER_LEN 10240
#define LOGINF_LEN 102400
#define MUTEX_INIT(v) KeInitializeMutex( &v, 0 )
#define MUTEX_ACQUIRE(v) KeWaitForMutexObject( &v, Executive, KernelMode, FALSE, NULL )
#define MUTEX_RELEASE(v) KeReleaseMutex( &v, FALSE )
#define FILE_DEVICE_MON 0x00008405
#define IOCTL_FILEM_HOOK (ULONG) CTL_CODE( FILE_DEVICE_MON, 0x00, METHOD_BUFFERED, FILE_WRITE_ACCESS )
#define IOCTL_FILEM_UNHOOK (ULONG) CTL_CODE( FILE_DEVICE_MON, 0x01, METHOD_BUFFERED, FILE_WRITE_ACCESS )
#define IOCTL_FILEM_GETLOG (ULONG) CTL_CODE( FILE_DEVICE_MON, 0x03, METHOD_NEITHER, FILE_WRITE_ACCESS )
#define IOCTL_FILEM_SETFILTER (ULONG) CTL_CODE( FILE_DEVICE_MON, 0x04, METHOD_BUFFERED, FILE_WRITE_ACCESS )
#define IOCTL_FILEM_SETEXCLUDE (ULONG) CTL_CODE( FILE_DEVICE_MON, 0x05, METHOD_BUFFERED, FILE_WRITE_ACCESS )
#define IOCTL_FILEM_SETPROCESS (ULONG) CTL_CODE( FILE_DEVICE_MON, 0x06, METHOD_BUFFERED, FILE_WRITE_ACCESS )
#define IOCTL_TRANSFER_TYPE( _iocontrol) (_iocontrol & 0x3)
//ZwSetInformationFile
//-------------------------------------------------------------------------
typedef NTSTATUS (__stdcall ZWSETINFORMATIONFILE)(IN HANDLE FileHandle,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN PVOID FileInformation,
IN ULONG Length,
IN FILE_INFORMATION_CLASS FileInformationClass);
NTSTATUS NewZwSetInformationFile(IN HANDLE FileHandle,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN PVOID FileInformation,
IN ULONG Length,
IN FILE_INFORMATION_CLASS FileInformationClass);
PULONG pZwSetInformationFileSDT; //???SSDT???
ZWSETINFORMATIONFILE OldZwSetInformationFile; //???
VOID HookZwSetInformationFile();
VOID UnHookZwSetInformationFile();
//-------------------------------------------------------------------------
//ZwWriteFile
//-------------------------------------------------------------------------
typedef NTSTATUS (__stdcall ZWWRITEFILE)(IN HANDLE FileHandle,
IN HANDLE Event OPTIONAL,
IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
IN PVOID ApcContext OPTIONAL,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN PVOID Buffer,
IN ULONG Length,
IN PLARGE_INTEGER ByteOffset OPTIONAL,
IN PULONG Key OPTIONAL);
NTSTATUS NewZwWriteFile(IN HANDLE FileHandle,
IN HANDLE Event OPTIONAL,
IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
IN PVOID ApcContext OPTIONAL,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN PVOID Buffer,
IN ULONG Length,
IN PLARGE_INTEGER ByteOffset OPTIONAL,
IN PULONG Key OPTIONAL);
PULONG pZwWriteFileSDT; //???SSDT???
ZWWRITEFILE OldZwWriteFile; //???
VOID HookZwWriteFile();
VOID UnHookZwWriteFile();
//-------------------------------------------------------------------------
//ZwQuerySystemInformation
//-------------------------------------------------------------------------
struct _SYSTEM_THREADS
{
LARGE_INTEGER KernelTime;
LARGE_INTEGER UserTime;
LARGE_INTEGER CreateTime;
ULONG WaitTime;
PVOID StartAddress;
CLIENT_ID ClientIs;
KPRIORITY Priority;
KPRIORITY BasePriority;
ULONG ContextSwitchCount;
ULONG ThreadState;
KWAIT_REASON WaitReason;
};
struct _SYSTEM_PROCESSES
{
ULONG NextEntryDelta;
ULONG ThreadCount;
ULONG Reserved[6];
LARGE_INTEGER CreateTime;
LARGE_INTEGER UserTime;
LARGE_INTEGER KernelTime;
UNICODE_STRING ProcessName;
KPRIORITY BasePriority;
ULONG ProcessId;
ULONG InheritedFromProcessId;
ULONG HandleCount;
ULONG Reserved2[2];
VM_COUNTERS VmCounters;
IO_COUNTERS IoCounters;
struct _SYSTEM_THREADS Threads[1];
};
NTSYSAPI NTSTATUS NTAPI ZwQuerySystemInformation(
IN ULONG SystemInformationClass,
IN PVOID SystemInformation,
IN ULONG SystemInformationLength,
OUT PULONG ReturnLength);
typedef NTSTATUS (ZWQUERYSYSTEMINFORMATION)(
IN ULONG SystemInformationClass,
IN PVOID SystemInformation,
IN ULONG SystemInformationLength,
OUT PULONG ReturnLength);
NTSTATUS NewZwQuerySystemInformation(
IN ULONG SystemInformationClass,
IN PVOID SystemInformation,
IN ULONG SystemInformationLength,
OUT PULONG ReturnLength);
unsigned long OldCr0;
PULONG pZwQuerySystemInformationSDT;
ZWQUERYSYSTEMINFORMATION OldZwQuerySystemInformation;
VOID HookZwQuerySystemInformation();
VOID UnHookZwQuerySystemInformation();
//------------------------------------------------------------------------
//ZwCreateFile
//-------------------------------------------------------------------------
typedef NTSTATUS (__stdcall ZWCREATEFILE)(OUT PHANDLE FileHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN PLARGE_INTEGER AllocationSize,
IN ULONG FileAttributes,
IN ULONG ShareAccess,
IN ULONG CreateDisposition,
IN ULONG CreateOptions,
IN PVOID EaBuffer,
IN ULONG EaLength);
NTSTATUS NewZwCreateFile(OUT PHANDLE FileHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN PLARGE_INTEGER AllocationSize,
IN ULONG FileAttributes,
IN ULONG ShareAccess,
IN ULONG CreateDisposition,
IN ULONG CreateOptions,
IN PVOID EaBuffer,
IN ULONG EaLength);
PULONG pZwCreateFileSDT; //???SSDT???
ZWCREATEFILE OldZwCreateFile; //???
VOID HookZwCreateFile();
VOID UnHookZwCreateFile();
//-------------------------------------------------------------------------
NTSTATUS DriverControlDispatch(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
BOOLEAN DeviceControlDipatch(IN PFILE_OBJECT FileObject,
IN BOOLEAN Wait,
IN PVOID InputBuffer,
IN ULONG InputBufferLength,
OUT PVOID OutputBuffer,
IN ULONG OutputBufferLength,
IN ULONG IoControlCode,
OUT PIO_STATUS_BLOCK IoStatus,
IN PDEVICE_OBJECT DeviceObject);
VOID DriverUnload(IN PDRIVER_OBJECT pDriverObject);
VOID HookAll();
VOID UnHookAll();
ULONG GetProcessNameOffset();
PCHAR GetProcess(PCHAR Name);
NTSTATUS AccessFilter(PUNICODE_STRING FileName);
PCHAR LowStr(PCHAR str);
VOID LogRecord(const PCHAR format,…);
ULONG GetLogTxt(IN PCHAR LogTxt);
PDRIVER_OBJECT pGDriverObject;
PDEVICE_OBJECT pGControlDevice;
ULONG ProcessNameOffset;
BOOLEAN bProtect=TRUE;
BOOLEAN bHooked=FALSE;
CHAR ProtectPath[FILTER_LEN]={0};
CHAR ExcludePath[FILTER_LEN]={0};
CHAR ExcludeProcess[FILTER_LEN]={0};
CHAR LogInf[LOGINF_LEN]={0};
PCHAR pLogInfStart=LogInf;
PCHAR pLogInfEnd=LogInf;
KMUTEX ProtectPathMutex;
KMUTEX ExcludePathMutex;
KMUTEX ExcludeProcessMutex;
KMUTEX LogInfMutex;
NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObject,
IN PUNICODE_STRING pRegPath)
{
//__asm int 3
NTSTATUS status;
UNICODE_STRING DeviceName, LinkName;
int i=0;
ProcessNameOffset=GetProcessNameOffset();
//init filter
MUTEX_INIT(ProtectPathMutex);
MUTEX_INIT(ExcludePathMutex);
MUTEX_INIT(ExcludeProcessMutex);
MUTEX_INIT(LogInfMutex);
pGDriverObject=pDriverObject;
#if DBG
pDriverObject->DriverUnload = DriverUnload;
strcpy(ProtectPath,“;c:\1;”);
#endif
pDriverObject->MajorFunction[IRP_MJ_SHUTDOWN] =DriverControlDispatch;
pDriverObject->MajorFunction[IRP_MJ_CREATE]=DriverControlDispatch;
pDriverObject->MajorFunction[IRP_MJ_CLOSE]=DriverControlDispatch;
pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]=DriverControlDispatch;
RtlInitUnicodeString(&DeviceName, L"\Device\FileM");
status = IoCreateDevice( pDriverObject,0,&DeviceName,0,0,TRUE,&pGControlDevice); // exclusive! only one control app!
if ( !NT_SUCCESS(status) )
{
KdPrint((“DriverEntry: IoCreateDevice(control) failure\n”));
DriverUnload(pDriverObject);
return status;
}
RtlInitUnicodeString(&LinkName, L"\DosDevices\FileM");
status = IoCreateSymbolicLink(&LinkName, &DeviceName);
if ( !NT_SUCCESS(status) )
{
KdPrint((“DriverEntry: IoCreateSymbolicLink failure\n”));
DriverUnload(pDriverObject);
return status;
}
HookAll();
return STATUS_SUCCESS;
}
NTSTATUS DriverControlDispatch(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{
NTSTATUS status=STATUS_SUCCESS;
PIO_STACK_LOCATION irpStack;
PVOID inputBuffer;
PVOID outputBuffer;
ULONG inputBufferLength;
ULONG outputBufferLength;
ULONG ioControlCode;
WORK_QUEUE_ITEM workItem;
//
// Go ahead and set the request up as successful
//
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
//
// Get a pointer to the current location in the Irp. This is where
// the function codes and parameters are located.
//
irpStack = IoGetCurrentIrpStackLocation (Irp);
//have a test
//LogRecord(“CurrentStackLocation Offset: %d”,(UCHAR)&(Irp->Tail.Overlay.CurrentStackLocation)-(UCHAR)Irp);
//LogRecord(“DeviceObject Offset: %d”,(UCHAR)&(irpStack->FileObject)-(UCHAR)irpStack);
//
//
// Get the pointer to the input/output buffer and its length
//
inputBuffer = Irp->AssociatedIrp.SystemBuffer;
inputBufferLength = irpStack->Parameters.DeviceIoControl.InputBufferLength;
outputBuffer = Irp->AssociatedIrp.SystemBuffer;
outputBufferLength = irpStack->Parameters.DeviceIoControl.OutputBufferLength;
ioControlCode = irpStack->Parameters.DeviceIoControl.IoControlCode;
switch (irpStack->MajorFunction)
{
case IRP_MJ_CREATE:
break;
case IRP_MJ_SHUTDOWN:
break;
case IRP_MJ_CLOSE:
break;
case IRP_MJ_DEVICE_CONTROL:
KdPrint ((“[FileM]: IRP_MJ_DEVICE_CONTROL\n”));
//
// See if the output buffer is really a user buffer that we
// can just dump data into.
//
if( IOCTL_TRANSFER_TYPE(ioControlCode) == METHOD_NEITHER )
{
outputBuffer = Irp->UserBuffer;
}
//
// Its a request from the GUI
//
DeviceControlDipatch( irpStack->FileObject, TRUE,
inputBuffer, inputBufferLength,
outputBuffer, outputBufferLength,
ioControlCode, &Irp->IoStatus, DeviceObject );
break;
}
IoCompleteRequest( Irp, IO_NO_INCREMENT );
return status;
}
BOOLEAN DeviceControlDipatch(IN PFILE_OBJECT FileObject,
IN BOOLEAN Wait,
IN PVOID InputBuffer,
IN ULONG InputBufferLength,
OUT PVOID OutputBuffer,
IN ULONG OutputBufferLength,
IN ULONG IoControlCode,
OUT PIO_STATUS_BLOCK IoStatus,
IN PDEVICE_OBJECT DeviceObject)
{
IoStatus->Status = STATUS_SUCCESS; // Assume success
IoStatus->Information = 0; // Assume nothing returned
switch ( IoControlCode )
{
case IOCTL_FILEM_HOOK:
KdPrint ((“[FileM]: hook\n”));
HookAll();
break;
case IOCTL_FILEM_UNHOOK:
KdPrint((“[FileM]: unhook\n”));
UnHookAll();
break;
case IOCTL_FILEM_GETLOG:
KdPrint((“[FileM]: getlog\n”));
if (OutputBufferLength==LOGINF_LEN && OutputBuffer!=NULL)
{
IoStatus->Information=GetLogTxt(OutputBuffer);
}
else
{
IoStatus->Status = STATUS_INVALID_PARAMETER;
}
break;
case IOCTL_FILEM_SETFILTER:
KdPrint((“[FileM]: SetProtectPath\n”));
if( InputBufferLength>FILTER_LEN || InputBuffer == NULL )
{
IoStatus->Status = STATUS_INVALID_PARAMETER;
break;
}
MUTEX_ACQUIRE(ProtectPathMutex);
RtlFillMemory(ProtectPath,FILTER_LEN,0);
RtlCopyMemory(ProtectPath,InputBuffer,InputBufferLength);
LowStr(ProtectPath);
MUTEX_RELEASE(ProtectPathMutex);
break;
case IOCTL_FILEM_SETEXCLUDE:
KdPrint((“[FileM]: SetExcludePath\n”));
if( InputBufferLength>FILTER_LEN || InputBuffer == NULL )
{
IoStatus->Status = STATUS_INVALID_PARAMETER;
break;
}
MUTEX_ACQUIRE(ExcludePathMutex);
RtlFillMemory(ExcludePath,FILTER_LEN,0);
RtlCopyMemory(ExcludePath,InputBuffer,InputBufferLength);
LowStr(ExcludePath);
MUTEX_RELEASE(ExcludePathMutex);
break;
case IOCTL_FILEM_SETPROCESS:
KdPrint((“[FileM]: SetExcludePath\n”));
if( InputBufferLength>FILTER_LEN || InputBuffer == NULL )
{
IoStatus->Status = STATUS_INVALID_PARAMETER;
break;
}
MUTEX_ACQUIRE(ExcludeProcessMutex);
RtlFillMemory(ExcludeProcess,FILTER_LEN,0);
RtlCopyMemory(ExcludeProcess,InputBuffer,InputBufferLength);
LowStr(ExcludeProcess);
MUTEX_RELEASE(ExcludeProcessMutex);
break;
default:
KdPrint((“Regmon: invalid request\n”));
IoStatus->Status = STATUS_INVALID_DEVICE_REQUEST;
break;
}
return TRUE;
}
VOID DriverUnload(IN PDRIVER_OBJECT pDriverObject)
{
if (bHooked)
{
UnHookAll();
}
if (pGControlDevice!=NULL)
{
UNICODE_STRING LinkName;
RtlInitUnicodeString(&LinkName, L"\??\FileM");
IoDeleteSymbolicLink(&LinkName);
IoDeleteDevice(pGControlDevice);
}
}
VOID HookAll()
{
if (!bHooked)
{
HookZwSetInformationFile();
HookZwWriteFile();
HookZwCreateFile();
#if DBG
#else
HookZwQuerySystemInformation();
#endif
bHooked=TRUE;
LogRecord(“[FileM]: ???\r\n”);
}
}
VOID UnHookAll()
{
if (bHooked)
{
UnHookZwSetInformationFile();
UnHookZwWriteFile();
UnHookZwCreateFile();
#if DBG
#else
UnHookZwQuerySystemInformation();
#endif
bHooked=FALSE;
LogRecord(“[FileM]: ???\r\n”);
}
}
VOID HookZwSetInformationFile()
{
UNICODE_STRING strFuncName;
RtlInitUnicodeString(&strFuncName, L"ZwSetInformationFile");
pZwSetInformationFileSDT = KeServiceDescriptorTable->ServiceTableBase + *(PULONG)((PUCHAR)MmGetSystemRoutineAddress(&strFuncName) + 1);
OldZwSetInformationFile = (ZWSETINFORMATIONFILE)pZwSetInformationFileSDT;
__asm
{
cli
mov eax,cr0
and eax,not 10000h //??cr0?WP?
mov cr0,eax
}
*pZwSetInformationFileSDT = (ULONG)NewZwSetInformationFile;
__asm
{
mov eax,cr0
or eax,10000h //??cr0?WP?
mov cr0,eax
sti
}
}
VOID HookZwWriteFile()
{
UNICODE_STRING strFuncName;
RtlInitUnicodeString(&strFuncName, L"ZwWriteFile");
pZwWriteFileSDT = KeServiceDescriptorTable->ServiceTableBase + *(PULONG)((PUCHAR)MmGetSystemRoutineAddress(&strFuncName) + 1);
OldZwWriteFile = (ZWWRITEFILE)pZwWriteFileSDT;
__asm
{
cli
mov eax,cr0
and eax,not 10000h //??cr0?WP?
mov cr0,eax
}
*pZwWriteFileSDT = (ULONG)NewZwWriteFile;
__asm
{
mov eax,cr0
or eax,10000h //??cr0?WP?
mov cr0,eax
sti
}
}
VOID HookZwCreateFile()
{
UNICODE_STRING strFuncName;
RtlInitUnicodeString(&strFuncName, L"ZwCreateFile");
pZwCreateFileSDT = KeServiceDescriptorTable->ServiceTableBase + *(PULONG)((PUCHAR)MmGetSystemRoutineAddress(&strFuncName) + 1);
OldZwCreateFile = (ZWCREATEFILE)pZwCreateFileSDT;
__asm
{
cli
mov eax,cr0
and eax,not 10000h //??cr0?WP?
mov cr0,eax
}
*pZwCreateFileSDT = (ULONG)NewZwCreateFile;
__asm
{
mov eax,cr0
or eax,10000h //??cr0?WP?
mov cr0,eax
sti
}
}
VOID HookZwQuerySystemInformation()
{
UNICODE_STRING strFuncName;
RtlInitUnicodeString(&strFuncName, L"ZwQuerySystemInformation");
pZwQuerySystemInformationSDT = KeServiceDescriptorTable->ServiceTableBase + (PULONG)((PUCHAR)MmGetSystemRoutineAddress(&strFuncName) + 1);
OldZwQuerySystemInformation = (ZWQUERYSYSTEMINFORMATION)pZwQuerySystemInformationSDT;
__asm
{
cli
mov eax,cr0
and eax,not 10000h //??cr0?WP?
mov cr0,eax
}
pZwQuerySystemInformationSDT = (ULONG)NewZwQuerySystemInformation;
__asm
{
mov eax,cr0
or eax,10000h //??cr0?WP?
mov cr0,eax
sti
}
}
VOID HookZwQuerySystemInformation_org()
{
_asm{
cli;
mov eax,cr0
mov OldCr0,eax
and eax,0fffeffffh
mov cr0,eax
}
_asm{
mov ecx, dword ptr [ZwQuerySystemInformation];
mov edx, [ecx+1];
mov eax, dword ptr [KeServiceDescriptorTable];
mov esi, [eax];
mov edx, [esi+edx4];
mov dword ptr [OldZwQuerySystemInformation], edx
mov ecx, [ecx+1]
mov eax, [eax]
mov dword ptr [eax+ecx4], offset NewZwQuerySystemInformation;
}
_asm
{
mov eax,OldCr0
mov cr0,eax
sti;
}
}
VOID UnHookZwSetInformationFile()
{
__asm
{
cli
mov eax,cr0
and eax,not 10000h
mov cr0,eax
}
*pZwSetInformationFileSDT = (ULONG)OldZwSetInformationFile;
__asm
{
mov eax,cr0
or eax,10000h
mov cr0,eax
sti
}
}
VOID UnHookZwWriteFile()
{
__asm
{
cli
mov eax,cr0
and eax,not 10000h
mov cr0,eax
}
*pZwWriteFileSDT = (ULONG)OldZwWriteFile;
__asm
{
mov eax,cr0
or eax,10000h
mov cr0,eax
sti
}
}
VOID UnHookZwCreateFile()
{
__asm
{
cli
mov eax,cr0
and eax,not 10000h
mov cr0,eax
}
pZwCreateFileSDT = (ULONG)OldZwCreateFile;
__asm
{
mov eax,cr0
or eax,10000h
mov cr0,eax
sti
}
}
VOID UnHookZwQuerySystemInformation()
{
__asm
{
cli
mov eax,cr0
and eax,not 10000h
mov cr0,eax
}
pZwQuerySystemInformationSDT = (ULONG)OldZwQuerySystemInformation;
__asm
{
mov eax,cr0
or eax,10000h
mov cr0,eax
sti
}
}
VOID UnHookZwQuerySystemInformation_org()
{
_asm{
cli;
mov eax,cr0
mov OldCr0,eax
and eax,0fffeffffh
mov cr0,eax
}
_asm{
mov ecx, dword ptr [ZwQuerySystemInformation];
mov edx, [ecx+1];
mov eax, dword ptr [KeServiceDescriptorTable];
mov esi, [eax];
mov ebx, dword ptr [OldZwQuerySystemInformation];
mov [esi+edx4],ebx;
}
_asm
{
mov eax,OldCr0
mov cr0,eax
sti;
}
}
NTSTATUS NewZwSetInformationFile(IN HANDLE FileHandle,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN PVOID FileInformation,
IN ULONG Length,
IN FILE_INFORMATION_CLASS FileInformationClass)
{
PFILE_OBJECT pFileObject=NULL;
UNICODE_STRING uDosName;
NTSTATUS ret = STATUS_SUCCESS;
UNICODE_STRING PreNameFtdisk;
UNICODE_STRING PreNameVolmgr;
CHAR ProcName[NT_PROCNAMELEN]={0};
ret=ObReferenceObjectByHandle(FileHandle, GENERIC_READ, IoFileObjectType, KernelMode, (PVOID)&pFileObject, 0);
if (NT_SUCCESS(ret) && pFileObject!=NULL)
{
RtlInitUnicodeString(&PreNameFtdisk,L"\Driver\Ftdisk");
RtlInitUnicodeString(&PreNameVolmgr,L"\Driver\Volmgr");
if (pFileObject->Type==IO_TYPE_FILE && pFileObject->DeviceObject!=NULL && pFileObject->DeviceObject->DriverObject!=NULL && pFileObject->FileName.Buffer!=NULL && <br> (RtlCompareUnicodeString(&(pFileObject->DeviceObject->DriverObject->DriverName),&PreNameFtdisk,TRUE)==0 || <br> RtlCompareUnicodeString(&(pFileObject->DeviceObject->DriverObject->DriverName),&PreNameVolmgr,TRUE)==0))
{
uDosName.Buffer=NULL;
ret = IoVolumeDeviceToDosName(pFileObject->DeviceObject, &uDosName);
if (NT_SUCCESS(ret) && uDosName.Buffer!=NULL)
{
UNICODE_STRING FileName;
CHAR szFileName[NT_FILENAMELEN]={0};
FileName.Length=0;
FileName.MaximumLength=NT_FILENAMELEN;
FileName.Buffer=(PWCHAR)szFileName;
RtlCopyUnicodeString(&FileName,&uDosName);
RtlAppendUnicodeStringToString(&FileName,&(pFileObject->FileName));
if ((FileInformationClass==FileDispositionInformation && ((PFILE_DISPOSITION_INFORMATION)FileInformation)->DeleteFile) || <br> FileInformationClass==FileRenameInformation)
{
if (!NT_SUCCESS((AccessFilter(&FileName))))
{
ANSI_STRING as;
RtlUnicodeStringToAnsiString(&as, &FileName, TRUE);
if (FileInformationClass==FileRenameInformation)
{
KdPrint((“[%s] ReName File: %Z\r\n”,GetProcess(ProcName),&as));
LogRecord(“<modify_alarm>[%s]\tReName\t%Z\r\n”,GetProcess(ProcName),&as);
}
else
{
KdPrint((“[%s] Delete File: %Z\r\n”,GetProcess(ProcName),&as));
LogRecord(“<modify_alarm>[%s]\tDelete\t%Z\r\n”,GetProcess(ProcName),&as);
}
RtlFreeAnsiString(&as);
ExFreePool(uDosName.Buffer);
ObDereferenceObject(pFileObject);
return STATUS_ACCESS_DENIED;
}
}
}
if (uDosName.Buffer!=NULL)
{
ExFreePool(uDosName.Buffer);
}
}
ObDereferenceObject(pFileObject);
}
return OldZwSetInformationFile(FileHandle, IoStatusBlock, FileInformation,Length, FileInformationClass);
}
NTSTATUS NewZwWriteFile(IN HANDLE FileHandle,
IN HANDLE Event OPTIONAL,
IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
IN PVOID ApcContext OPTIONAL,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN PVOID Buffer,
IN ULONG Length,
IN PLARGE_INTEGER ByteOffset OPTIONAL,
IN PULONG Key OPTIONAL)
{
PFILE_OBJECT pFileObject=NULL;
UNICODE_STRING uDosName;
NTSTATUS ret = STATUS_SUCCESS;
UNICODE_STRING PreNameFtdisk;
UNICODE_STRING PreNameVolmgr;
CHAR ProcName[NT_PROCNAMELEN]={0};
ret=ObReferenceObjectByHandle(FileHandle, GENERIC_READ, IoFileObjectType, KernelMode, (PVOID)&pFileObject, 0);
if (NT_SUCCESS(ret) && pFileObject!=NULL)
{
RtlInitUnicodeString(&PreNameFtdisk,L"\Driver\Ftdisk");
RtlInitUnicodeString(&PreNameVolmgr,L"\Driver\Volmgr");
if (pFileObject->Type==IO_TYPE_FILE && pFileObject->DeviceObject!=NULL && pFileObject->DeviceObject->DriverObject!=NULL && pFileObject->FileName.Buffer!=NULL && <br> (RtlCompareUnicodeString(&(pFileObject->DeviceObject->DriverObject->DriverName),&PreNameFtdisk,TRUE)==0 || <br> RtlCompareUnicodeString(&(pFileObject->DeviceObject->DriverObject->DriverName),&PreNameVolmgr,TRUE)==0))
{
uDosName.Buffer=NULL;
ret = IoVolumeDeviceToDosName(pFileObject->DeviceObject, &uDosName);
if (NT_SUCCESS(ret) && uDosName.Buffer!=NULL)
{
UNICODE_STRING FileName;
CHAR szFileName[NT_FILENAMELEN]={0};
FileName.Length=0;
FileName.MaximumLength=NT_FILENAMELEN;
FileName.Buffer=(PWCHAR)szFileName;
RtlCopyUnicodeString(&FileName,&uDosName);
RtlAppendUnicodeStringToString(&FileName,&(pFileObject->FileName));
if (!NT_SUCCESS((AccessFilter(&FileName))))
{
ANSI_STRING as;
RtlUnicodeStringToAnsiString(&as, &FileName, TRUE);
KdPrint((“[%s] Write File: %Z\r\n”,GetProcess(ProcName),&as));
LogRecord(“<modify_alarm>[%s]\tWrite\t%Z\r\n”,GetProcess(ProcName),&as);
RtlFreeAnsiString(&as);
ExFreePool(uDosName.Buffer);
ObDereferenceObject(pFileObject);
return STATUS_ACCESS_DENIED;
}
}
if (uDosName.Buffer!=NULL)
{
ExFreePool(uDosName.Buffer);
}
}
ObDereferenceObject(pFileObject);
}
return OldZwWriteFile(FileHandle, Event,ApcRoutine,ApcContext,IoStatusBlock,Buffer,Length,ByteOffset,Key);
}
NTSTATUS NewZwCreateFile(OUT PHANDLE FileHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN PLARGE_INTEGER AllocationSize,
IN ULONG FileAttributes,
IN ULONG ShareAccess,
IN ULONG CreateDisposition,
IN ULONG CreateOptions,
IN PVOID EaBuffer,
IN ULONG EaLength)
{
CHAR ProcName[NT_PROCNAMELEN]={0};
KdPrint((“[NewZwCreateFile] Enter–%wZ CreateDisposition: %d ShareAccess: %d CreateOptions: %d DesiredAccess: %d\n “,ObjectAttributes->ObjectName,CreateDisposition,ShareAccess,CreateOptions,DesiredAccess));
if (ObjectAttributes->ObjectName->Length>4 && _wcsnicmp(ObjectAttributes->ObjectName->Buffer,L”\??\”,4)==0)
{
UNICODE_STRING FileName;
RtlInitUnicodeString(&FileName,ObjectAttributes->ObjectName->Buffer+4);
/
KdPrint((“[%s] Create File: %wZ DeiredAccess: 0x%08X ShareAccess: 0x%08X CreateDisposition: 0x%08X CreateOptions: 0x%08X\r\n”,
GetProcess(ProcName),&FileName,DesiredAccess,ShareAccess,CreateDisposition,CreateOptions));
*/
if (CreateDisposition == FILE_CREATE || CreateDisposition == FILE_SUPERSEDE || CreateDisposition == FILE_OVERWRITE || CreateDisposition == FILE_OVERWRITE_IF || (DesiredAccess &(GENERIC_WRITE | FILE_WRITE_DATA | FILE_WRITE_ATTRIBUTES | FILE_WRITE_EA | FILE_APPEND_DATA))!=0)
{
if (!NT_SUCCESS((AccessFilter(&FileName))))
{
ANSI_STRING as;
RtlUnicodeStringToAnsiString(&as, &FileName, TRUE);
KdPrint((“[%s] Create File: %Z DeiredAccess: 0x%08X ShareAccess: 0x%08X CreateDisposition: 0x%08X CreateOptions: 0x%08X\r\n”,
GetProcess(ProcName),&as,DesiredAccess,ShareAccess,CreateDisposition,CreateOptions));
LogRecord(“<modify_alarm>[%s]\tCreate\t%Z\r\n”,GetProcess(ProcName),&as);
RtlFreeAnsiString(&as);
return STATUS_ACCESS_DENIED;
}
}
}
return OldZwCreateFile(FileHandle,DesiredAccess,ObjectAttributes,IoStatusBlock,AllocationSize,
FileAttributes,ShareAccess,CreateDisposition,CreateOptions,EaBuffer,EaLength);
}
NTSTATUS NewZwQuerySystemInformation(
IN ULONG SystemInformationClass,
IN PVOID SystemInformation,
IN ULONG SystemInformationLength,
OUT PULONG ReturnLength)
{
NTSTATUS rc;
UNICODE_STRING process_name;
//KdPrint((“[NewZwQuerySystemInformation] Enter\n”));
RtlInitUnicodeString(&process_name, L"WPAgent.exe");
rc = (OldZwQuerySystemInformation) (
SystemInformationClass,
SystemInformation,
SystemInformationLength,
ReturnLength);
if(NT_SUCCESS(rc))
{
if(5 == SystemInformationClass)
{
struct _SYSTEM_PROCESSES *curr = (struct _SYSTEM_PROCESSES *)SystemInformation;
struct _SYSTEM_PROCESSES *prev = NULL;
if(curr->NextEntryDelta)((char *)curr += curr->NextEntryDelta);
while(curr)
{
if (RtlEqualUnicodeString(&process_name, &curr->ProcessName, 1))
{
if(prev)
{
if(curr->NextEntryDelta)
{
prev->NextEntryDelta += curr->NextEntryDelta;
}
else
{
prev->NextEntryDelta = 0;
}
}
else
{
if(curr->NextEntryDelta)
{
(char *)SystemInformation += curr->NextEntryDelta;
}
else
{
SystemInformation = NULL;
}
}
if(curr->NextEntryDelta)((char *)curr += curr->NextEntryDelta);
else
{
curr = NULL;
break;
}
}
if(curr != NULL)
{
prev = curr;
if(curr->NextEntryDelta)((char )curr += curr->NextEntryDelta);
else curr = NULL;
}
}
}
}
return rc;
}
VOID LogRecord(const PCHAR format,…)
{
ULONG len;
va_list arg_ptr;
CHAR LogTxt[2048]={0};
/
#define A (&format)
KdPrint(( (char )format, A[1], A[2], A[3], A[4], A[5], A[6] ));
KdPrint(( “\n” ));
#undef A
/
va_start( arg_ptr, format);
len = vsprintf(LogTxt,format,arg_ptr);
va_end( arg_ptr );
MUTEX_ACQUIRE(LogInfMutex);
if (pLogInfEnd+len>=LogInf+LOGINF_LEN)
{
RtlCopyMemory(pLogInfEnd,LogTxt,LogInf+LOGINF_LEN-pLogInfEnd);
RtlCopyMemory(LogInf,LogTxt+(LogInf+LOGINF_LEN-pLogInfEnd),len-(LogInf+LOGINF_LEN-pLogInfEnd));
pLogInfEnd=pLogInfEnd+len-LOGINF_LEN;
*pLogInfEnd=0;
pLogInfEnd++;
}
else
{
RtlCopyMemory(pLogInfEnd,LogTxt,len);
pLogInfEnd+=len;
*pLogInfEnd=0;
pLogInfEnd++;
}
MUTEX_RELEASE(LogInfMutex);
}
ULONG GetLogTxt(IN PCHAR LogTxt)
{
ULONG TotalLen=0;
MUTEX_ACQUIRE(LogInfMutex);
if (pLogInfEnd>pLogInfStart)
{
TotalLen=pLogInfEnd-pLogInfStart;
memcpy(LogTxt,pLogInfStart,pLogInfEnd-pLogInfStart);
pLogInfStart=pLogInfEnd;
*pLogInfEnd=0;
}
else if (pLogInfEnd {
TotalLen=pLogInfEnd+LOGINF_LEN-pLogInfStart;
memcpy(LogTxt,pLogInfStart,LogInf+LOGINF_LEN-pLogInfStart);
memcpy(LogTxt+(LogInf+LOGINF_LEN-pLogInfStart),LogInf,pLogInfEnd-LogInf);
pLogInfStart=pLogInfEnd;
*pLogInfEnd=0;
}
MUTEX_RELEASE(LogInfMutex);
return TotalLen;
}
PCHAR LowStr(PCHAR str)
{
int len=strlen(str);
int i=0;
for (i=0;i {
if(str[i]>=‘A’ && str[i]<=‘Z’)
{
str[i]=str[i]-‘A’+‘a’;
}
}
return str;
}
NTSTATUS InExcludeProcess()
{
CHAR ProcName[NT_PROCNAMELEN]={0};
CHAR PatterStr[1024]={0};
GetProcess(ProcName);
LowStr(ProcName);
strcpy(PatterStr,“;”);
strcat(PatterStr,ProcName);
strcat(PatterStr,“;”);
if (strstr(ExcludeProcess,PatterStr)==NULL)
{
return STATUS_ACCESS_DENIED;
}
return STATUS_SUCCESS;
}
NTSTATUS AccessFilter(PUNICODE_STRING FileName)
{
ANSI_STRING FileNameAnsi;
CHAR DirectoryName[1024]={0};
CHAR PatterStr[1024]={0};
CHAR ExcludePatterStr[1024]={0};
CHAR ExtendPatterStr[32]={0};
PCHAR c=NULL;
int i=0;
KdPrint((“AccessFilter: %wZ”,FileName));
if (!bProtect)
{
return STATUS_SUCCESS;
}
if (NT_SUCCESS(InExcludeProcess()))
{
return STATUS_SUCCESS;
}
RtlUnicodeStringToAnsiString(&FileNameAnsi,FileName,TRUE);
if (FileNameAnsi.Buffer==NULL)
{
return STATUS_SUCCESS;
}
//if (strstr(FileNameAnsi.Buffer,“:\”)==NULL)
if (FileNameAnsi.Length<3 || FileNameAnsi.Buffer[1]!=‘:’ || FileNameAnsi.Buffer[2]!=‘\’)
{
RtlFreeAnsiString(&FileNameAnsi);
return STATUS_SUCCESS;
}
strncpy(DirectoryName,FileNameAnsi.Buffer,1000<filenameansi.length> LowStr(DirectoryName);
RtlFreeAnsiString(&FileNameAnsi);
c=strrchr(DirectoryName,‘.’);
if (c!=NULL)
{
if (strlen(c)<30)
{
strcpy(ExtendPatterStr,“;”);
strcat(ExtendPatterStr,c);
strcat(ExtendPatterStr,“;”);
if (strstr(ExcludePath,ExtendPatterStr)!=NULL)
{
return STATUS_SUCCESS;
}
}
}
strcpy(PatterStr,“;”);
strcat(PatterStr,DirectoryName);
if (PatterStr[strlen(PatterStr)-1]==‘\’)
{
PatterStr[strlen(PatterStr)-1]=‘;’;
}
else
{
strcat(PatterStr,“;”);
}
strcpy(ExcludePatterStr,PatterStr);
if (strstr(ExcludePath,ExcludePatterStr)!=NULL)
{
return STATUS_SUCCESS;
}
while ((c=strrchr(ExcludePatterStr,‘\’))!=NULL)
{
*(c)=‘;’;
*(c+1)=0;
if (strstr(ExcludePath,ExcludePatterStr)!=NULL)
{
return STATUS_SUCCESS;
}
*c=0;
}
if (strstr(ProtectPath,PatterStr)!=NULL)
{
return STATUS_ACCESS_DENIED;
}
while ((c=strrchr(PatterStr,‘\’))!=NULL)
{
*(c)=‘;’;
*(c+1)=0;
if (strstr(ProtectPath,PatterStr)!=NULL)
{
return STATUS_ACCESS_DENIED;
}
c=0;
}
return STATUS_SUCCESS;
}
ULONG GetProcessNameOffset()
{
PEPROCESS curproc;
int i;
curproc = PsGetCurrentProcess();
//
// Scan for 12KB, hopping the KPEB never grows that big!
//
for( i = 0; i < 3PAGE_SIZE; i++ )
{
if( !strncmp( “System”, (PCHAR) curproc + i, strlen(“System”) ))
{
return i;
}
}
//
// Name not found - oh, well
//
return 0;
}
//----------------------------------------------------------------------
//
// GetProcess
//
// Uses undocumented data structure offsets to obtain the name of the
// currently executing process.
//
//----------------------------------------------------------------------
PCHAR GetProcess(PCHAR Name)
{
PEPROCESS curproc;
char *nameptr;
ULONG i;
//
// We only try and get the name if we located the name offset
//
if( ProcessNameOffset)
{
//
// Get a pointer to the current process block
//
curproc = PsGetCurrentProcess();
//
// Dig into it to extract the name. Make sure to leave enough room
// in the buffer for the appended process ID.
//
nameptr = (PCHAR) curproc + ProcessNameOffset;
strncpy( Name, nameptr, NT_PROCNAMELEN-1 );
Name[NT_PROCNAMELEN-1] = 0;
//LogRecord(Name);
}
else
{
strcpy( Name, “???”);
}
return Name;
}</filenameansi.length></modify_alarm></modify_alarm></modify_alarm></modify_alarm></string.h></stdlib.h></stdarg.h></stdio.h></ntddk.h></ntifs.h>