首页
社区
课程
招聘
[原创]发两个监测小工具~~
发表于: 2011-10-14 08:46 12739

[原创]发两个监测小工具~~

2011-10-14 08:46
12739
#ifndef IMAGELOADMONITOR_H
#define IMAGELOADMONITOR_H
#endif

#include <ntddk.h>
#include <ntstrsafe.h>


DRIVER_INITIALIZE DriverEntry;
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegPath);

__drv_dispatchType(IRP_MJ_DEVICE_CONTROL)
DRIVER_DISPATCH DispatchDeviceIoControl;
NTSTATUS DispatchDeviceIoControl(PDEVICE_OBJECT pDeviceObject, PIRP pIrp);

__drv_dispatchType_other
DRIVER_DISPATCH DispatchCompletion;
NTSTATUS DispatchCompletion(PDEVICE_OBJECT pDeviceObject, PIRP pIrp);

DRIVER_UNLOAD Unload;
VOID Unload(PDRIVER_OBJECT pDriverObject);
#include "imageLoadMonitor.h"

#pragma alloc_text (INIT,DriverEntry)
#pragma alloc_text (PAGE,DispatchDeviceIoControl)
#pragma alloc_text (PAGE,Unload)
#pragma alloc_text (PAGE,DispatchCompletion)

#define DEVICE_NAME L"\\Device\\imageLoadMonitory"
#define DEVICE_SYMBOLICLINK_NAME L"\\DosDevices\\imageLoadMonitorSymLink"

#define IOCTL_BEGIN_MONITOR (CTL_CODE(FILE_DEVICE_UNKNOWN,0x801,FILE_ANY_ACCESS,METHOD_BUFFERED))
#define IOCTL_STOP_MONITOR  (CTL_CODE(FILE_DEVICE_UNKNOWN,0X802,FILE_ANY_ACCESS,METHOD_BUFFERED))

BOOLEAN	NotifyHasBeenSet = FALSE;

VOID
LoadImageNotifyRoutine( PUNICODE_STRING FullImageName, HANDLE ProcessId, PIMAGE_INFO ImageInfo )
{
	HANDLE				hSourceFile;
	HANDLE				hDestFile;
	HANDLE				hSection;
	PVOID				pvSectionBase = NULL;
	PVOID				pBuf = NULL;
	OBJECT_ATTRIBUTES	fileObject;
	UNICODE_STRING		DestString;
	NTSTATUS			status;
	IO_STATUS_BLOCK     ioStatusBlock;
	LARGE_INTEGER		sectionSize;

	if ( !(ImageInfo->SystemModeImage) )		//检测第9位即是否是载入了系统空间
	{
		return ;
	}
	if ( ImageInfo->ImageSize == 0 ) return ;

	KdPrint(("%wZ",FullImageName));

	InitializeObjectAttributes(&fileObject,FullImageName,OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,NULL,NULL);

	//打开驱动的源文件
	status = ZwCreateFile(&hSourceFile,
		GENERIC_READ | SYNCHRONIZE,
		&fileObject,
		&ioStatusBlock,
		NULL,
		FILE_ATTRIBUTE_NORMAL,
		FILE_SHARE_READ,
		FILE_OPEN,		//存在则打开 不存在则返回错误码
		FILE_SYNCHRONOUS_IO_NONALERT,
		NULL,0);
	if (!NT_SUCCESS(status)) return ;

#define SEC_COMMIT        0x8000000 
	sectionSize.HighPart = 0;
	sectionSize.LowPart = (ULONG)ImageInfo->ImageSize;
	//映射文件
	status = ZwCreateSection(&hSection,
		SECTION_MAP_READ | SECTION_MAP_WRITE,
		NULL,
		&sectionSize,
		PAGE_READWRITE,
		SEC_COMMIT,
		hSourceFile);
	if (!NT_SUCCESS(status))
	{
		ZwClose(hSourceFile);
		return ;
	}

	//创建映射视图
	status = ZwMapViewOfSection(hSection,
		ZwCurrentProcess(),
		&pvSectionBase,		//接受映射的基址
		0,		
		(ULONG)ImageInfo->ImageSize,	//节区大小
		NULL,				//section起始至这里的偏移
		&(ULONG)ImageInfo->ImageSize,
		ViewUnmap,
		MEM_TOP_DOWN,
		PAGE_READWRITE);

	pBuf = ExAllocatePoolWithTag(PagedPool,64,645212);		//准备文件名缓冲

	if ( !NT_SUCCESS(status)||(pvSectionBase == NULL)||(pBuf == NULL) )
	{
		ZwClose(hSection);
		ZwClose(hSourceFile);
		return ;
	}

	RtlZeroMemory(pBuf,64);
	RtlStringCchPrintfW(pBuf,64,L"\\DosDevices\\C:\\%x",(ULONG)ImageInfo->ImageBase);
	RtlInitUnicodeString(&DestString,(PWCHAR)pBuf);

	InitializeObjectAttributes(&fileObject,&DestString,OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,NULL,NULL);

	//打开目标文件
	status = ZwCreateFile(&hDestFile,
		GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE,
		&fileObject,
		&ioStatusBlock,
		NULL,
		FILE_ATTRIBUTE_NORMAL,
		FILE_SHARE_READ | FILE_SHARE_WRITE,
		FILE_SUPERSEDE,		//存在则覆盖 不存在则创建
		FILE_SYNCHRONOUS_IO_NONALERT,
		NULL,0);
	if (!NT_SUCCESS(status)) goto __exit1;


	status = ZwWriteFile(hDestFile,NULL,NULL,NULL,&ioStatusBlock,pvSectionBase,(ULONG)ImageInfo->ImageSize,NULL,NULL);
	if (!NT_SUCCESS(status)) goto __exit2;

__exit2:
	ZwClose(hDestFile);
__exit1:
	ExFreePool(pBuf);
	pBuf = NULL;
	ZwUnmapViewOfSection(hSection,pvSectionBase);
	pvSectionBase = NULL;
	ZwClose(hSection);
	ZwClose(hSourceFile);
	return ;
}

NTSTATUS
DispatchDeviceIoControl(PDEVICE_OBJECT pDeviceObject, PIRP pIrp)
{
	ULONG                ulIoControlCode;     //控制代码
	PVOID                pvBuf = NULL;
	PIO_STACK_LOCATION   pIrpStatck = NULL;
	NTSTATUS             status = STATUS_SUCCESS;

	pIrpStatck      = IoGetCurrentIrpStackLocation(pIrp);
	ulIoControlCode = pIrpStatck->Parameters.DeviceIoControl.IoControlCode;        //取IO 控制代码
	pvBuf           = pIrp->AssociatedIrp.SystemBuffer;                            //取缓冲指针

	switch ( ulIoControlCode )
	{
		case IOCTL_BEGIN_MONITOR:
			if (NotifyHasBeenSet == TRUE) break;

			status = PsSetLoadImageNotifyRoutine(LoadImageNotifyRoutine);
			if ( NT_SUCCESS(status) )
			{
				NotifyHasBeenSet = TRUE;
			}
			else
			{
				NotifyHasBeenSet = FALSE;
				status = STATUS_UNSUCCESSFUL;
			}

			break;

		case IOCTL_STOP_MONITOR:
			if (NotifyHasBeenSet == FALSE) break;

			status = PsRemoveLoadImageNotifyRoutine(LoadImageNotifyRoutine);
			if ( (NT_SUCCESS(status))||(status = STATUS_PROCEDURE_NOT_FOUND ) )
			{
				NotifyHasBeenSet = FALSE;
				status = STATUS_SUCCESS;
			}
			else
			{
				status = STATUS_UNSUCCESSFUL;
			}

			break;
		default:
			KdPrint(("接收到非法命令\n"));
			pIrp->IoStatus.Information = 0;
			pIrp->IoStatus.Status = status = STATUS_INVALID_DEVICE_REQUEST;

			break;
	}

	IoCompleteRequest(pIrp,IO_NO_INCREMENT);
	return status;
}



VOID
Unload(PDRIVER_OBJECT pDriverObject)
{
	UNICODE_STRING		SymLinkName;

	RtlInitUnicodeString(&SymLinkName,DEVICE_SYMBOLICLINK_NAME);
	IoDeleteSymbolicLink(&SymLinkName);
	IoDeleteDevice(pDriverObject->DeviceObject);
}

NTSTATUS
DispatchCompletion(PDEVICE_OBJECT pDeviceObject, PIRP pIrp)
{
	pIrp->IoStatus.Status = STATUS_SUCCESS;
	pIrp->IoStatus.Information = 0;
	IoCompleteRequest(pIrp,IO_NO_INCREMENT);

	return STATUS_SUCCESS;
}

NTSTATUS
DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegPath)
{
	PDEVICE_OBJECT     pMyDeviceObject = NULL;
	PWSTR              pBuf = NULL;

	UNICODE_STRING	   SymLinkName;
	UNICODE_STRING     MyDeviceName;
	NTSTATUS           status = STATUS_SUCCESS;
	ULONG              i;

	UNREFERENCED_PARAMETER(pRegPath);

	for(i=0; i<IRP_MJ_MAXIMUM_FUNCTION; i++)
	{
		pDriverObject->MajorFunction[i] = DispatchCompletion;

	}

	pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchDeviceIoControl;
	pDriverObject->DriverUnload = Unload;

	//创建设备对象
	RtlInitUnicodeString(&MyDeviceName,DEVICE_NAME);
	status = IoCreateDevice(pDriverObject,0,&MyDeviceName,FILE_DEVICE_UNKNOWN,FILE_DEVICE_SECURE_OPEN,FALSE,&pMyDeviceObject);
	if (!NT_SUCCESS(status)){
		KdPrint(("创建设备对象失败\n"));
		return status;
	}

	//创建符号链接
	RtlInitUnicodeString(&SymLinkName,DEVICE_SYMBOLICLINK_NAME);
	status = IoCreateSymbolicLink(&SymLinkName,&MyDeviceName);
	if (!NT_SUCCESS(status)){
		IoDeleteDevice(pMyDeviceObject);
		KdPrint(("创建符号链接失败\n"));
		return status;
	}

	pMyDeviceObject->Flags |= DO_BUFFERED_IO;
	pMyDeviceObject->Flags  = pMyDeviceObject->Flags &~ DO_DEVICE_INITIALIZING;

	return status;

}
VOID
(*PLOAD_IMAGE_NOTIFY_ROUTINE) (
    IN PUNICODE_STRING  FullImageName,
    IN HANDLE  ProcessId,
    IN PIMAGE_INFO  ImageInfo
    );
typedef struct  _IMAGE_INFO {
    union {
        ULONG  Properties;
        struct {
            ULONG ImageAddressingMode  : 8;
            ULONG SystemModeImage      : 1;
            ULONG ImageMappedToAllPids : 1;
            ULONG Reserved             : 22;
        };
    };
    PVOID  ImageBase;
    ULONG  ImageSelector;
    ULONG  ImageSize;
    ULONG  ImageSectionNumber;
} IMAGE_INFO, *PIMAGE_INFO;
#include "deviceControlIoMonitor.h"

#pragma alloc_text (INIT,DriverEntry)
#pragma alloc_text (PAGE,DispatchDeviceIoControl)
#pragma alloc_text (PAGE,Unload)
#pragma alloc_text (PAGE,DispatchCompletion)

#define DEVICE_NAME L"\\Device\\deviceIoControlMonitor"
#define DEVICE_SYMBOLICLINK_NAME L"\\DosDevices\\deviceIoControlMonitorSymLink"

#define IOCTL_BEGIN_HOOK (CTL_CODE(FILE_DEVICE_UNKNOWN,0x801,FILE_ANY_ACCESS,METHOD_BUFFERED))
#define IOCTL_STOP_HOOK (CTL_CODE(FILE_DEVICE_UNKNOWN,0x802,FILE_ANY_ACCESS,METHOD_BUFFERED))


BOOLEAN	globe_HookInstalled = FALSE;

NTSTATUS
DispatchDeviceIoControl(PDEVICE_OBJECT pDeviceObject, PIRP pIrp)
{
	ULONG				IoControlCode = 0;
	PIO_STACK_LOCATION	pIrpStatck = NULL;
	NTSTATUS			status = STATUS_UNSUCCESSFUL;

	pIrpStatck = IoGetCurrentIrpStackLocation(pIrp);
	IoControlCode = pIrpStatck->Parameters.DeviceIoControl.IoControlCode;

	pIrp->IoStatus.Information = 0;
	pIrp->IoStatus.Status = status;

	//DbgBreakPoint();
	switch ( IoControlCode )
	{
	case IOCTL_BEGIN_HOOK:

		if ( globe_HookInstalled == TRUE )
		{
			pIrp->IoStatus.Status = status = STATUS_SUCCESS;
			break;
		}

		if ( Hook() ) 
		{
			pIrp->IoStatus.Status = status = STATUS_SUCCESS;
			KdPrint(("成功Hook \n"));

			globe_HookInstalled = TRUE;
		}

		break;

	case IOCTL_STOP_HOOK:

		if ( globe_HookInstalled == FALSE )
		{
			pIrp->IoStatus.Status = status = STATUS_SUCCESS;
			break;
		}

		if ( RestoreHook() )
		{
			pIrp->IoStatus.Status = status = STATUS_SUCCESS;
			KdPrint(("成功恢复Hook \n"));

			globe_HookInstalled = FALSE;
		}

		break;


	default:

		KdPrint(("接收到非法命令\n"));
		pIrp->IoStatus.Information = 0;
		pIrp->IoStatus.Status = status = STATUS_INVALID_DEVICE_REQUEST;

		break;
	}

	IoCompleteRequest(pIrp,IO_NO_INCREMENT);
	return status;
}


VOID
Unload(PDRIVER_OBJECT pDriverObject)
{
	UNICODE_STRING		SymLinkName;

	RtlInitUnicodeString(&SymLinkName,DEVICE_SYMBOLICLINK_NAME);
	IoDeleteSymbolicLink(&SymLinkName);
	IoDeleteDevice(pDriverObject->DeviceObject);
}

NTSTATUS
DispatchCompletion(PDEVICE_OBJECT pDeviceObject, PIRP pIrp)
{
	pIrp->IoStatus.Status = STATUS_SUCCESS;
	pIrp->IoStatus.Information = 0;
	IoCompleteRequest(pIrp,IO_NO_INCREMENT);

	return STATUS_SUCCESS;
}

NTSTATUS
DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegPath)
{
	PDEVICE_OBJECT     pMyDeviceObject = NULL;
	UNICODE_STRING	   SymLinkName;
	UNICODE_STRING     MyDeviceName;
	NTSTATUS           status = STATUS_SUCCESS;
	ULONG              i;

	for(i=0; i<IRP_MJ_MAXIMUM_FUNCTION; i++)
		pDriverObject->MajorFunction[i] = DispatchCompletion;

	pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchDeviceIoControl;
	pDriverObject->DriverUnload = Unload;

	//创建设备对象
	RtlInitUnicodeString(&MyDeviceName,DEVICE_NAME);
	status = IoCreateDevice(pDriverObject,0,&MyDeviceName,FILE_DEVICE_UNKNOWN,FILE_DEVICE_SECURE_OPEN,FALSE,&pMyDeviceObject);
	if (!NT_SUCCESS(status)){
		KdPrint(("创建设备对象失败\n"));
		return status;
	}

	//创建符号链接
	RtlInitUnicodeString(&SymLinkName,DEVICE_SYMBOLICLINK_NAME);
	status = IoCreateSymbolicLink(&SymLinkName,&MyDeviceName);
	if (!NT_SUCCESS(status)){
		IoDeleteDevice(pMyDeviceObject);
		KdPrint(("创建符号链接失败\n"));
		return status;
	}

	pMyDeviceObject->Flags |= DO_BUFFERED_IO;
	pMyDeviceObject->Flags  = pMyDeviceObject->Flags & ~ DO_DEVICE_INITIALIZING;

	return status;
}

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

上传的附件:
收藏
免费 6
支持
分享
最新回复 (12)
雪    币: 25
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
其实可以简单的hook xxxDeleteFile,判断如果是驱动就copy一下
2011-10-14 08:59
0
雪    币: 1233
活跃值: (907)
能力值: ( LV12,RANK:750 )
在线值:
发帖
回帖
粉丝
3
其实有现成的文件删除查看器,机器上要常备哦
2011-10-14 09:46
0
雪    币: 149
活跃值: (171)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
4
来学习驱动。。留名。
2011-10-14 10:14
0
雪    币: 2503
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
谢谢楼主的分享!!!!
2011-10-14 10:19
0
雪    币: 839
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
来学习的!谢谢分享!
2011-10-14 10:23
0
雪    币: 27
活跃值: (831)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
7
记录一下留着以后慢慢学习。
2011-10-14 12:26
0
雪    币: 116
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
学习一下
2011-10-14 12:35
0
雪    币: 8107
活跃值: (1955)
能力值: ( LV8,RANK:122 )
在线值:
发帖
回帖
粉丝
9
楼主应该把源码直接也打个包嘛
2011-10-15 00:03
0
雪    币: 33
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
..........在哪
2011-10-15 03:15
0
雪    币: 34
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
谢谢 楼主  用用看
2011-10-19 14:55
0
雪    币: 244
活跃值: (32)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
很好的代码,学习了
2011-10-19 15:17
0
雪    币: 8733
活跃值: (18485)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
13
谢谢分享,学习学习
2011-10-19 17:00
0
游客
登录 | 注册 方可回帖
返回
//