在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,選擇驅動編譯,
?

插入下列代碼實現ring0層驅動監視創建線程,請見代碼分析
~~~
#include "ThreadMon.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 ThreadEventString;
PDEVICE_EXTENSION deviceExtension;
PDEVICE_OBJECT deviceObject = NULL;
KdPrint(("[ThreadMon] DriverEntry: %wZ\n", RegistryPath));
//
// 創建設備對象
//
RtlInitUnicodeString(&ntDeviceName, THREADMON_DEVICE_NAME_W);
Status = IoCreateDevice(
DriverObject,
sizeof(DEVICE_EXTENSION), // DeviceExtensionSize
&ntDeviceName, // DeviceName
FILE_DEVICE_THREADMON, // DeviceType
0, // DeviceCharacteristics
TRUE, // Exclusive
&deviceObject // [OUT]
);
if(!NT_SUCCESS(Status))
{
KdPrint(("[ThreadMon] 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, THREADMON_DOS_DEVICE_NAME_W);
Status = IoCreateSymbolicLink(&dosDeviceName, &ntDeviceName);
if(!NT_SUCCESS(Status))
{
KdPrint(("[ThreadMon] IoCreateSymbolicLink Error Code = 0x%X\n", Status));
IoDeleteDevice(deviceObject);
return Status;
}
//
// 分發IRP
//
DriverObject->MajorFunction[IRP_MJ_CREATE] = ThreadMonDispatchCreate;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = ThreadMonDispatchClose;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = ThreadMonDispatchDeviceControl;
DriverObject->DriverUnload = ThreadMonUnload;
//
// 保存設備對象指針
//
g_pDeviceObject = deviceObject;
//
// 創建事件對象與應用層通信
//
RtlInitUnicodeString(&ThreadEventString, EVENT_NAME);
deviceExtension->ThreadEvent = IoCreateNotificationEvent(&ThreadEventString, &deviceExtension->ThreadHandle);
KeClearEvent(deviceExtension->ThreadEvent); // 非受信狀態
//
// 設置回調例程
//
Status = PsSetCreateThreadNotifyRoutine(ThreadCallback);
return Status;
}
NTSTATUS
ThreadMonDispatchCreate(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
NTSTATUS Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
KdPrint(("[ThreadMon] IRP_MJ_CREATE\n"));
Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return Status;
}
NTSTATUS
ThreadMonDispatchClose(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
NTSTATUS Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
KdPrint(("[ThreadMon] IRP_MJ_CLOSE\n"));
Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return Status;
}
NTSTATUS
ThreadMonDispatchDeviceControl(
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_THREAD_MON:
{
KdPrint(("[ThreadMon] IOCTL: 0x%X", ioControlCode));
if (outBufLength >= sizeof(PCALLBACK_INFO))
{
pCallbackInfo->ProcessId = deviceExtension->ProcessId;
pCallbackInfo->ThreadId = deviceExtension->ThreadId;
pCallbackInfo->Create = deviceExtension->Create;
Irp->IoStatus.Information = outBufLength;
}
break;
}
default:
{
Status = STATUS_INVALID_PARAMETER;
Irp->IoStatus.Information = 0;
KdPrint(("[ThreadMon] 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
ThreadMonUnload(
IN PDRIVER_OBJECT DriverObject
)
{
UNICODE_STRING dosDeviceName;
//
// Free any resources
//
// 卸載回調例程
PsRemoveCreateThreadNotifyRoutine(ThreadCallback);
//
// Delete the symbolic link
//
RtlInitUnicodeString(&dosDeviceName, THREADMON_DEVICE_NAME_W);
IoDeleteSymbolicLink(&dosDeviceName);
//
// Delete the device object
//
IoDeleteDevice(DriverObject->DeviceObject);
KdPrint(("[ThreadMon] Unloaded"));
}
VOID
ThreadCallback(
IN HANDLE ProcessId, // 進程ID
IN HANDLE ThreadId, // 線程ID
IN BOOLEAN Create // 創建還是終止
)
{
PDEVICE_EXTENSION deviceExtension = (PDEVICE_EXTENSION)g_pDeviceObject->DeviceExtension;
deviceExtension->ProcessId = ProcessId;
deviceExtension->ThreadId = ThreadId;
deviceExtension->Create = Create;
// 觸發事件,通知應用程序
KeSetEvent(deviceExtension->ThreadEvent, 0, FALSE);
KeClearEvent(deviceExtension->ThreadEvent);
}
//
//////////////////////////////////////////////////////////////////////////
~~~
ring3層調用代碼如下
~~~
#include "windows.h"
#include "winioctl.h"
#include "stdio.h"
#include "../inc/ioctls.h"
#define SYMBOL_LINK "\\\\.\\ThreadMon"
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;
// printf("收到事件通知!\n");
bRet = ::DeviceIoControl(
hDriver,
IOCTL_THREAD_MON,
NULL,
0,
&cbkinfo,
sizeof(cbkinfo),
&dwRet,
NULL);
if (bRet)
{
if (cbkinfo.ProcessId != cbktemp.ProcessId || \
cbkinfo.ThreadId != cbktemp.ThreadId || \
cbkinfo.Create != cbktemp.Create)
{
if (cbkinfo.Create)
{
printf("有線程被創建,PID = %d,TID = %d\n", cbkinfo.ProcessId, cbkinfo.ThreadId);
}
else
{
printf("有線程被終止,PID = %d,TID = %d\n", cbkinfo.ProcessId, cbkinfo.ThreadId);
}
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