H头文件:
#pragma once //只要在头文件的最开始加入这条杂注, //就能够保证头文件只被编译一次 #ifdef __cplusplus extern "C" { #endif #include <ntddk.h> #ifdef __cplusplus } #endif #define PAGECODE code_seg("PAGE") #define LOCKEDCODE code_seg() #define INITCODE code_seg("INIT") #define PAGEDATA data_seg("PAGE") #define LOCKEDDATA data_seg() #define INITDATA data_seg("INIT") #define arraysize(p) (sizeof(p)/sizeof((p)[0])) typedef struct _DEVICE_EXTENSION { PDEVICE_OBJECT pDevice; UNICODE_STRING uStrDeviceName; UNICODE_STRING uStrSymLinkName; } DEVICE_EXTENSION,*PDEVICE_EXTENSION; #define PRINTF(msg) { KdPrint(("\\\\\\\\\\\\\\\ ")); KdPrint((msg)); KdPrint(("\\\\\\\\\\\\\\\ ")); } VOID LookasideTest(); VOID LinkListTest(); VOID NewTest(); NTSTATUS CreateDevice(IN PDRIVER_OBJECT pDriverObject); VOID HelloDDKUnload(IN PDRIVER_OBJECT pDriverObject); NTSTATUS HelloDDKDispatchRoutine(IN PDEVICE_OBJECT pDevObj, IN PIRP pIrp); VOID DisPlayItsProcessName();
CPP文件:
#include "DriverMemory.h" typedef struct _MYDATASTRUCT { CHAR buffer[64]; } MYDATASTRUCT, *PMYDATASTRUCT; #pragma INITCODE VOID LookasideTest()//管理内存的系列函数 { KdPrint(("初始化Lookaside对象 ")); PAGED_LOOKASIDE_LIST pageList; ExInitializePagedLookasideList(&pageList,NULL,NULL,0, sizeof(MYDATASTRUCT),'1234',0); PMYDATASTRUCT MyData[50]; KdPrint(("模拟频繁申请内存 ")); for (int i=0;i<50;i++) { MyData[i] = (PMYDATASTRUCT)ExAllocateFromPagedLookasideList(&pageList); } //这里可以对内存进行操作了 for (int i=0;i<50;i++) { strcpy(MyData[i]->buffer,"实验"); } for (int i=0;i<50;i++) { KdPrint(("%s",MyData[i]->buffer)); } KdPrint(("模拟频繁回收内存")); for (int i=0;i<50;i++) { ExFreeToPagedLookasideList(&pageList,MyData[i]); } KdPrint(("删除Lookaside对象")); ExDeletePagedLookasideList(&pageList); PRINTF("RTL 内存函数 开始 "); PUCHAR PData = (PUCHAR)ExAllocatePool(PagedPool,1024); RtlZeroMemory(PData,1024); PUCHAR PData2 = (PUCHAR)ExAllocatePool(PagedPool,1024); RtlFillMemory(PData2,1024,0x31); RtlCopyBytes(PData2,PData,1024); ULONG FLAG = RtlCompareMemory(PData,PData2,1024); if (FLAG == 1024) { PRINTF("RtlCopyBytes 复制成功 "); } else PRINTF("RtlCopyBytes 复制不成功 "); } typedef struct _MYDATASTRUCT2 { ULONG number; LIST_ENTRY ListEntry; }MYDATASTRUCT2,*PMYDATASTRUCT2; #pragma INITCODE VOID LinkListTest() { LIST_ENTRY linkListHead; InitializeListHead(&linkListHead); KdPrint(("我的实验:定义10个pData ")); PMYDATASTRUCT2 pData[10]; //在链表中插入10个元素 KdPrint(("在链表中插入10个元素 ")); for (int i =0;i<10;i++) { pData[i] = (PMYDATASTRUCT2)ExAllocatePool(PagedPool,sizeof(MYDATASTRUCT2)); pData[i]->number =i; InsertHeadList(&linkListHead,&pData[i]->ListEntry); } KdPrint(("读取这10个元素 ")); for (int i =0;i<10;i++) { KdPrint(("pData 的 number = %d ",pData[i]->number)); } //从链表中取出,并显示 KdPrint(("从链表中取出数据 显示,并销毁 ")); int i=0; while (!IsListEmpty(&linkListHead)) { KdPrint(("从链表头部删除 ")); PLIST_ENTRY pEntry = RemoveHeadList(&linkListHead); //只获得了PLIST_ENTRY 想要得到数据 就必须要这个函数: 第三个参数是我定义的结构体中的元素 pData[i] = CONTAINING_RECORD(pEntry,MYDATASTRUCT2,ListEntry); KdPrint(("%d ",pData[i]->number)); ExFreePool(pData[i]); i++; } KdPrint(("书上实验:定义1个pMyData ")); PMYDATASTRUCT2 pMyData; //在链表中插入10个元素 KdPrint(("在链表中插入10个元素 ")); for (int i =0;i<10;i++) { pMyData = (PMYDATASTRUCT2)ExAllocatePool(PagedPool,sizeof(MYDATASTRUCT2)); pMyData->number =i; InsertHeadList(&linkListHead,&pMyData->ListEntry); } //从链表中取出,并显示 KdPrint(("从链表中取出数据 显示,并销毁 ")); while (!IsListEmpty(&linkListHead)) { KdPrint(("从链表尾部删除 ")); PLIST_ENTRY pEntry = RemoveTailList(&linkListHead); //只获得了PLIST_ENTRY 想要得到数据 就必须要这个函数: 第三个参数是我定义的结构体中的元素 pMyData = CONTAINING_RECORD(pEntry,MYDATASTRUCT2,ListEntry); KdPrint(("%d ",pMyData->number)); ExFreePool(pMyData); } } void * __cdecl operator new(size_t size,POOL_TYPE PoolType=PagedPool) { KdPrint(("global operator new ")); KdPrint(("Allocate size : %d ",size)); return ExAllocatePool(PoolType,size); } void __cdecl operator delete(void * pointer) { KdPrint(("Global delete operator ")); ExFreePool(pointer); } class TestClass { public: TestClass() { KdPrint(("TestClass:TestClass() ")); } ~TestClass() { KdPrint(("TestClass:~TestClass() ")); } void * operator new(size_t size, POOL_TYPE PoolType = PagedPool) { KdPrint(("TestClass:new ")); KdPrint(("Allocate size : %d ",size)); return ExAllocatePool(PoolType,size); } void operator delete(void * pointer) { KdPrint(("TestClass:delete ")); return ExFreePool(pointer); } public: char buffer[1024]; }; #pragma INITCODE VOID NewTest() { KdPrint(("进入 NewText ")); KdPrint(("类中 new delte: ")); TestClass *MyNewTest = new TestClass; strcpy(MyNewTest->buffer,"第一次的buffer "); KdPrint(("%s ",MyNewTest->buffer)); delete MyNewTest; MyNewTest = new(NonPagedPool) TestClass; strcpy(MyNewTest->buffer,"第二次的buffer "); KdPrint(("%s ",MyNewTest->buffer)); delete MyNewTest; KdPrint(("全局重载 new delete: ")); char *pBuffer = new(PagedPool) char[100]; strcpy(pBuffer,"第一次的pBuffer "); KdPrint(("%s ",pBuffer)); delete [] pBuffer; pBuffer = new(NonPagedPool) char[100]; strcpy(pBuffer,"第二次的pBuffer "); KdPrint(("%s ",pBuffer)); delete [] pBuffer; } #pragma INITCODE extern "C" NTSTATUS DriverEntry( IN PDRIVER_OBJECT pDriverObject, IN PUNICODE_STRING pRegistryPath ) { NTSTATUS status; KdPrint(("进入 DriverEntry ")); pDriverObject->DriverUnload = HelloDDKUnload; pDriverObject->MajorFunction[IRP_MJ_CREATE] = HelloDDKDispatchRoutine; pDriverObject->MajorFunction[IRP_MJ_CLOSE] = HelloDDKDispatchRoutine; pDriverObject->MajorFunction[IRP_MJ_WRITE] = HelloDDKDispatchRoutine; pDriverObject->MajorFunction[IRP_MJ_READ] = HelloDDKDispatchRoutine; status = CreateDevice(pDriverObject); PRINTF("显示进程 "); DisPlayItsProcessName(); PRINTF("内存管理 "); LookasideTest(); PRINTF("链表操作 "); LinkListTest(); PRINTF("new delte 重载学习 "); NewTest(); KdPrint(("DriverEntry end ")); return status; } #pragma INITCODE VOID DisPlayItsProcessName()//得到当前进程名称 { PEPROCESS PeProcess = PsGetCurrentProcess(); PTSTR ProcessName = (PTSTR)((ULONG)PeProcess + 0x174); KdPrint(("%s ",ProcessName)); } #pragma INITCODE NTSTATUS CreateDevice(IN PDRIVER_OBJECT pDriverObject) { NTSTATUS status; PDEVICE_OBJECT pDevObj; PDEVICE_EXTENSION pDevExt; UNICODE_STRING strDev; RtlInitUnicodeString(&strDev,L"\Device\MyDDK"); status = IoCreateDevice(pDriverObject, sizeof(DEVICE_EXTENSION), &(UNICODE_STRING)strDev, FILE_DEVICE_UNKNOWN, 0, TRUE, &pDevObj); if (!NT_SUCCESS(status)) { KdPrint(("创建设备失败! ")); return status; } pDevObj->Flags |= DO_BUFFERED_IO; pDevExt = (PDEVICE_EXTENSION)pDevObj->DeviceExtension; pDevExt->pDevice = pDevObj; pDevExt->uStrDeviceName = strDev; UNICODE_STRING strSymLinkName; RtlInitUnicodeString(&strSymLinkName,L"\??\MyDDK"); pDevExt->uStrSymLinkName = strSymLinkName; status = IoCreateSymbolicLink(&strSymLinkName,&strDev); if (!NT_SUCCESS(status)) { KdPrint(("创建符号失败! ")); IoDeleteDevice(pDevObj); return status; } return STATUS_SUCCESS; } #pragma PAGECODE VOID HelloDDKUnload(IN PDRIVER_OBJECT pDriverObject) { PDEVICE_OBJECT pNextObj; KdPrint(("Enter DriverUnload ")); pNextObj = pDriverObject->DeviceObject; while (pNextObj != NULL) { PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION) pNextObj->DeviceExtension; UNICODE_STRING pLinkName = pDevExt->uStrSymLinkName; IoDeleteSymbolicLink(&pLinkName); pNextObj = pNextObj->NextDevice; IoDeleteDevice(pDevExt->pDevice); } } #pragma PAGECODE NTSTATUS HelloDDKDispatchRoutine(IN PDEVICE_OBJECT pDevObj, IN PIRP pIrp) { NTSTATUS status = STATUS_SUCCESS; KdPrint(("Enter HelloDDKDispatchRoutine ")); pIrp->IoStatus.Status = status; pIrp->IoStatus.Information = 0; IoCompleteRequest(pIrp, IO_NO_INCREMENT); KdPrint(("Leave HelloDDKDispatchRoutine ")); return status; }
下面是DriverMonitor 记录的 调试信息:
00000000 0.00000000进入 DriverEntry
00000001 0.00025925\\\\\\\00000002 0.00026791显示进程
00000003 0.00027657\\\\\\\
00000004 0.00028551System
00000005 0.00029389\\\\\\\
00000006 0.00035284内存管理
00000007 0.00036122\\\\\\\
00000008 0.00037016初始化Lookaside对象
00000009 0.00037938模拟频繁申请内存
00000052 0.00093252实验//`````````````
00000053 0.00093978实验
00000058 0.00097554实验
00000059 0.00098253实验//`````````````一共50个 “实验” 这里省略显示
00000060 0.00101577模拟频繁回收内存
00000061 0.00112221删除Lookaside对象
00000062 0.00113674\\\\\\\
00000063 0.00114540RTL 内存函数 开始
00000064 0.00115350\\\\\\\
00000065 0.00117417\\\\\\\
00000066 0.00118339RtlCopyBytes 复制成功
00000067 0.00119149\\\\\\\
00000068 0.00119987\\\\\\\
00000069 0.00120742链表操作
00000070 0.00121580\\\\\\\
00000071 0.00122502我的实验:定义10个pData
00000072 0.00123368在链表中插入10个元素
00000073 0.00127111读取这10个元素
00000074 0.00128117pData 的 number = 0
00000075 0.00129039pData 的 number = 1
00000076 0.00134123pData 的 number = 2
00000077 0.00135213pData 的 number = 3
00000078 0.00136107pData 的 number = 4
00000079 0.00137001pData 的 number = 5
00000080 0.00137895pData 的 number = 6
00000081 0.00138761pData 的 number = 7
00000082 0.00139655pData 的 number = 8
00000083 0.00140549pData 的 number = 9
00000084 0.00141526从链表中取出数据 显示,并销毁
00000085 0.00142337从链表头部删除
00000086 0.001431199
00000087 0.00144013从链表头部删除
00000088 0.001447678
00000089 0.00145605从链表头部删除
00000090 0.001463317
00000091 0.00147142从链表头部删除
00000092 0.001478686
00000093 0.00148706从链表头部删除
00000094 0.001494325
00000095 0.00150270从链表头部删除
00000096 0.001510254
00000097 0.00151835从链表头部删除
00000098 0.001525893
00000099 0.00153399从链表头部删除
00000100 0.001541542
00000101 0.00154992从链表头部删除
00000102 0.001557181
00000103 0.00156584从链表头部删除
00000104 0.001573100
00000105 0.00158288书上实验:定义1个pMyData
00000106 0.00159154在链表中插入10个元素
00000107 0.00161250从链表中取出数据 显示,并销毁
00000108 0.00162060从链表尾部删除
00000109 0.001627860
00000110 0.00163596从链表尾部删除
00000111 0.001643231
00000112 0.00165161从链表尾部删除
00000113 0.001658872
00000114 0.00166725从链表尾部删除
00000115 0.001674513
00000116 0.00168262从链表尾部删除
00000117 0.001689884
00000118 0.00169854从链表尾部删除
00000119 0.001705805
00000120 0.00171391从链表尾部删除
00000121 0.001721456
00000122 0.00172955从链表尾部删除
00000123 0.001736817
00000124 0.00174519从链表尾部删除
00000125 0.001752468
00000126 0.00176084从链表尾部删除
00000127 0.001829569
00000128 0.00184074\\\\\\\
00000129 0.00184968new delte 重载学习
00000130 0.00185778\\\\\\\
00000131 0.00186616进入 NewText
00000132 0.00187454类中 new delte:
00000133 0.00188264TestClass:new
00000134 0.00189270Allocate size : 1024
00000135 0.00190695TestClass:TestClass()
00000136 0.00191589第一次的buffer
00000137 0.00192231
00000138 0.00193153TestClass:~TestClass()
00000139 0.00194019TestClass:delete
00000140 0.00194857TestClass:new
00000141 0.00195751Allocate size : 1024
00000142 0.00199858TestClass:TestClass()
00000143 0.00200724第二次的buffer
00000144 0.00201366
00000145 0.00202288TestClass:~TestClass()
00000146 0.00203126TestClass:delete
00000147 0.00204020全局重载 new delte:
00000148 0.00204886global operator new
00000149 0.00205808Allocate size : 100
00000150 0.00206730第一次的pBuffer
00000151 0.00207373
00000152 0.00208267Global delete operator
00000153 0.00209161global operator new
00000154 0.00210055Allocate size : 100
00000155 0.00210949第二次的pBuffer
00000156 0.00211591
00000157 0.00212485Global delete operator
00000158 0.00213351DriverEntry end
00000159 97.35410309Enter DriverUnload