在Windows NT中,80386保護模式的“保護”比Windows 95中更堅固,這個“鍍金的籠子”更加結實,更加難以打破。在Windows 95中,至少應用程序I/O操作是不受限制的,而在Windows NT中,我們的應用程序連這點權限都被剝奪了。在NT中幾乎不太可能進入真正的ring0層。?
在Windows NT中,存在三種Device Driver:
? 1.“Virtual device Driver” (VDD)。通過VDD,16位應用程序,如DOS 和Win16應用程序可以訪問特定的I/O端口(注意,不是直接訪問,而是要通過VDD來實現訪問)。
? 2.“GDI Driver”,提供顯示和打印所需的GDI函數。
? 3.“Kernel Mode Driver”,實現對特定硬件的操作,比如說CreateFile, CloseHandle (對于文件對象而言), ReadFile, WriteFile, DeviceIoControl 等操作。“Kernel Mode Driver”還是Windows NT中唯一可以對硬件中斷和DMA進行操作的Driver。SCSI 小端口驅動和 網卡NDIS 驅動都是Kernel Mode Driver的一種特殊形式。
Visual studio2012與Windows8帶來格外不同的新體驗
1.啟動Vs2012

2.看見滿目的驅動開發模板

3.選擇一個驅動模式,有內核模式與用戶模式兩種的驅動

?
4.創建一個驅動程序,KMDF DriverMVP

?
5.我們選擇的是內核模式的驅動程序,下面是創建成功后的界面,分別是驅動程序本身,與驅動安裝包

6.按下F5,選擇驅動編譯,
?

插入下列代碼實現內核的進程創建
~~~
#include "ProcMon.h"
#include "../inc/ioctls.h"
//
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//
// 全局變量
//
PDEVICE_OBJECT g_pDeviceObject;
//
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//
// 函數實現
//
NTSTATUS
DriverEntry(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
)
{
NTSTATUS Status = STATUS_SUCCESS;
UNICODE_STRING ntDeviceName;
UNICODE_STRING dosDeviceName;
UNICODE_STRING ProcessEventString;
PDEVICE_EXTENSION deviceExtension;
PDEVICE_OBJECT deviceObject = NULL;
KdPrint(("[ProcMon] DriverEntry: %wZ\n", RegistryPath));
//
// 創建設備對象
//
RtlInitUnicodeString(&ntDeviceName, PROCMON_DEVICE_NAME_W);
Status = IoCreateDevice(
DriverObject,
sizeof(DEVICE_EXTENSION), // DeviceExtensionSize
&ntDeviceName, // DeviceName
FILE_DEVICE_PROCMON, // DeviceType
0, // DeviceCharacteristics
TRUE, // Exclusive
&deviceObject // [OUT]
);
if(!NT_SUCCESS(Status))
{
KdPrint(("[ProcMon] IoCreateDevice Error Code = 0x%X\n", Status));
return Status;
}
//
// 設置擴展結構
//
deviceExtension = (PDEVICE_EXTENSION)deviceObject->DeviceExtension;
//
// Set up synchronization objects, state info,, etc.
//
deviceObject->Flags |= DO_BUFFERED_IO;
//
// 創建符號鏈接
//
RtlInitUnicodeString(&dosDeviceName, PROCMON_DOS_DEVICE_NAME_W);
Status = IoCreateSymbolicLink(&dosDeviceName, &ntDeviceName);
if(!NT_SUCCESS(Status))
{
KdPrint(("[ProcMon] IoCreateSymbolicLink Error Code = 0x%X\n", Status));
IoDeleteDevice(deviceObject);
return Status;
}
//
// 分發IRP
//
DriverObject->MajorFunction[IRP_MJ_CREATE] = ProcmonDispatchCreate;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = ProcmonDispatchClose;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = ProcmonDispatchDeviceControl;
DriverObject->DriverUnload = ProcmonUnload;
//
// 保存設備對象指針
//
g_pDeviceObject = deviceObject;
//
// 創建事件對象與應用層通信
//
RtlInitUnicodeString(&ProcessEventString, EVENT_NAME);
deviceExtension->ProcessEvent = IoCreateNotificationEvent(&ProcessEventString, &deviceExtension->hProcessHandle);
KeClearEvent(deviceExtension->ProcessEvent); // 非受信狀態
//
// 設置回調例程
//
Status = PsSetCreateProcessNotifyRoutine(ProcessCallback, FALSE);
return Status;
}
NTSTATUS
ProcmonDispatchCreate(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
NTSTATUS Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
KdPrint(("[ProcMon] IRP_MJ_CREATE\n"));
Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return Status;
}
NTSTATUS
ProcmonDispatchClose(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
NTSTATUS Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
KdPrint(("[ProcMon] IRP_MJ_CLOSE\n"));
Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return Status;
}
NTSTATUS
ProcmonDispatchDeviceControl(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
NTSTATUS Status = STATUS_SUCCESS;
PIO_STACK_LOCATION irpStack;
PDEVICE_EXTENSION deviceExtension;
ULONG inBufLength, outBufLength;
ULONG ioControlCode;
PCALLBACK_INFO pCallbackInfo;
// 獲取當前設備棧
irpStack = IoGetCurrentIrpStackLocation(Irp);
deviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
// 提取信息
pCallbackInfo = Irp->AssociatedIrp.SystemBuffer;
inBufLength = irpStack->Parameters.DeviceIoControl.InputBufferLength;
outBufLength = irpStack->Parameters.DeviceIoControl.OutputBufferLength;
ioControlCode = irpStack->Parameters.DeviceIoControl.IoControlCode;
// 處理不同的IOCTL
switch (ioControlCode)
{
case IOCTL_PROC_MON:
{
KdPrint(("[ProcMon] IOCTL: 0x%X", ioControlCode));
if (outBufLength >= sizeof(PCALLBACK_INFO))
{
pCallbackInfo->hParentId = deviceExtension->hParentId;
pCallbackInfo->hProcessId = deviceExtension->hProcessId;
pCallbackInfo->bCreate = deviceExtension->bCreate;
Irp->IoStatus.Information = outBufLength;
}
break;
}
default:
{
Status = STATUS_INVALID_PARAMETER;
Irp->IoStatus.Information = 0;
KdPrint(("[ProcMon] Unknown IOCTL: 0x%X (%04X,%04X)", \
ioControlCode, DEVICE_TYPE_FROM_CTL_CODE(ioControlCode), \
IoGetFunctionCodeFromCtlCode(ioControlCode)));
break;
}
}
Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return Status;
}
VOID
ProcmonUnload(
IN PDRIVER_OBJECT DriverObject
)
{
UNICODE_STRING dosDeviceName;
//
// Free any resources
//
// 卸載回調例程
PsSetCreateProcessNotifyRoutine(ProcessCallback, TRUE);
//
// Delete the symbolic link
//
RtlInitUnicodeString(&dosDeviceName, PROCMON_DOS_DEVICE_NAME_W);
IoDeleteSymbolicLink(&dosDeviceName);
//
// Delete the device object
//
IoDeleteDevice(DriverObject->DeviceObject);
KdPrint(("[ProcMon] Unloaded"));
}
VOID
ProcessCallback(
IN HANDLE ParentId, // 父進程ID
IN HANDLE ProcessId, // 發生事件的進程ID
IN BOOLEAN Create // 進程是創建還是終止
)
{
PDEVICE_EXTENSION deviceExtension = (PDEVICE_EXTENSION)g_pDeviceObject->DeviceExtension;
deviceExtension->hParentId = ParentId;
deviceExtension->hProcessId = ProcessId;
deviceExtension->bCreate = Create;
// 觸發事件,通知應用程序
KeSetEvent(deviceExtension->ProcessEvent, 0, FALSE);
KeClearEvent(deviceExtension->ProcessEvent);
}
//
//////////////////////////////////////////////////////////////////////////
~~~
ring3實現應用層的調用,搞定進程創建的監視
~~~
#include "windows.h"
#include "winioctl.h"
#include "stdio.h"
#include "../inc/ioctls.h"
#define SYMBOL_LINK "\\\\.\\ProcMon"
//#define SYMBOL_LINK "\\\\.\\slNTProcDrv"
int main()
{
CALLBACK_INFO cbkinfo, cbktemp = {0};
// 打開驅動設備對象
HANDLE hDriver = ::CreateFile(
SYMBOL_LINK,
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (hDriver == INVALID_HANDLE_VALUE)
{
printf("打開驅動設備對象失敗!\n");
return -1;
}
// 打開內核事件對象
HANDLE hProcessEvent = ::OpenEventW(SYNCHRONIZE, FALSE, EVENT_NAME);
while (::WaitForSingleObject(hProcessEvent, INFINITE))
{
DWORD dwRet;
BOOL bRet;
bRet = ::DeviceIoControl(
hDriver,
IOCTL_PROC_MON,
NULL,
0,
&cbkinfo,
sizeof(cbkinfo),
&dwRet,
NULL);
if (bRet)
{
if (cbkinfo.hParentId != cbktemp.hParentId || \
cbkinfo.hProcessId != cbktemp.hProcessId || \
cbkinfo.bCreate != cbktemp.bCreate)
{
if (cbkinfo.bCreate)
{
printf("有進程被創建,PID = %d\n", cbkinfo.hProcessId);
}
else
{
printf("有進程被終止,PID = %d\n", cbkinfo.hProcessId);
}
cbktemp = cbkinfo;
}
}
else
{
printf("\n獲取進程信息失敗!\n");
break;
}
}
::CloseHandle(hDriver);
return 0;
}
~~~
- 前言
- Visual Studio 11開發指南(1) Visual Studio 11簡介與新特性
- Visual Studio 11開發指南(2) Visual Studio 11放棄宏處理
- Visual Studio 11開發指南(3)Visual Studio 11開發SharePoint 2011程序
- Visual Studio 11開發指南(4)Visual Studio 11編程語言發展
- Visual Studio 11開發指南(5)Visual Studio 11 IDE增強
- Visual Studio 11開發指南(6)Visual Studio 11平臺改進
- Visual Studio 11開發指南(7)NET 4.5的改善
- Visual Studio 11開發指南(8)Visual C++ 11新特色
- Visual Studio 11開發指南(9)Visual C++ 新功能體驗
- Visual Studio 11開發指南(10)Visual C++11 IDE 新功能體驗
- Visual Studio 11開發指南(11)Visual Studio 11調試游戲
- Visual Studio 11開發指南(12)Visual Studio 11可視化多核多線程編程的行為
- Visual Studio 11開發指南(13)C++11語言新特性
- Visual Studio 11開發指南(14)C++11---C++/ CX設計
- Visual Studio 11開發指南(15)C++11單元測試
- Visual Studio 11開發指南(16)C++11更新-多線程和異步操作管理
- Visual Studio 11開發指南(17)C++11更新- Lambda表達式
- Visual Studio 11開發指南(18)C++11更新-自動矢量器使用
- Visual Studio 11開發指南(19)C++11更新-并行模式庫和代理庫
- 在 C++ 中使用 PPL 進行異步編程
- 基于VisualStudio11開發Windows8的Metro sample講解(1)MessageBox
- Visual C++ 11 中新的并發功能
- 基于Windows8與Visual Studio2012開發內核隱藏注冊表
- 基于VC++2012在Windows8上實現文件隱藏
- 實現諾基亞 lumia Windows phone 的手機通話記錄截取
- 最短代碼實現windows8下的下載器-下載安裝執行一體化
- 用Visual studio2012在Windows8上開發內核驅動監視線程創建
- 用Visual studio2012在Windows8上開發內核驅動監視進程創建
- 基于Windows8與Visual Studio2012實現殺毒通用模塊
- 用Visual studio2012在Windows8上開發內核中隱藏進程
- 用Visual studio11在Windows8上開發內核枚舉注冊表
- 用Visual studio11在Windows8上開發內核驅動隱藏注冊表
- 用Visual studio11在Windows8上開發驅動實現注冊表監控和過濾
- 用Visual studio11在Windows8上開發驅動實現內存填0殺進程
- 【CSDN2012年度博客之星】喜歡本博客的讀者,投票贈送《visual C++2010開發權威指南》電子稿--感謝支持 ~(截至到2012年12月30日)
- 今天在清華圖書館看到我的杰作,感慨萬千,而我要歸零一切 !
- use Visual studio2012 developing kernel driver monitor thread creation on Windows8
- To kernel driver monitoring process developed in Windows8 create using Visual studio2012
- Under Windows8 kernel mode development NDIS application-NDIS Filter explain
- use Visual studio2012 development kernel to hidden process on Windows8