驱动中的字符串操作
2019-11-22 本文已影响0人
温柔倾怀
#include <ntddk.h>
VOID DriverUnlode(PDRIVER_OBJECT pDriverObject)
{
//指明这个参数是我故意不用的,不是我忘了,告知编译器不要警告我
UNREFERENCED_PARAMETER(pDriverObject);
//DriverUnlode 驱动的卸载函数,负责清理资源,在驱动卸载的时候调用
//驱动里的资源是真实的系统里的资源,搞不明白分分钟给你蓝屏
DbgPrint("Unlode success");
//打印成功证明我们成功的卸载了这个驱动
}
//DriverEntry 相当于三环程序,也就是应用程序的main函数
//两个参数,PDRIVER_OBJECT 驱动对象指针 ;PUNICODE_STRING pRegPath 注册表的路径指针
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegPath)
{
UNREFERENCED_PARAMETER(pRegPath);
//制定驱动卸载函数
pDriverObject->DriverUnload = DriverUnlode;
DbgPrint("Hello World!");
//ANS_STRING 1.缓冲区 2.字符串长度 3. 最大长度 几乎用不到ascii
//UNICODE_STRING 1.缓冲区 2.字符串长度 3. 最大长度
//1.字符串常量方式初始化
//1.1 使用WCHAR类型变量初始化
UNICODE_STRING usStr1 = { 0 };
WCHAR * szHello = L"Hi , nihao.";
RtlInitUnicodeString(&usStr1, szHello);
KdPrint(("%wS", usStr1.Buffer));
//1.2 直接使用字符串初始化
DECLARE_CONST_UNICODE_STRING(usTest, L"hello wenrou");
KdPrint(("%wS", usTest.Buffer));
//2.栈空间初始化
//2.1 定义一个字符串结构体
UNICODE_STRING usTest2 = { 0 };
//2.2 在栈上定义一个WCHAR类型的字符串
WCHAR szHello2[512] = L"hello 512";
//2.3 字符串结构体指向栈上面的WCHAR类型的字符串
usTest2.Buffer = szHello2;
//2.4 设置字符串的实际长度(字符个数*字符宽度)
usTest2.Length = wcslen(L"hello 512") * sizeof(WCHAR);
//2.5 设置字符串的最大长度
usTest2.MaximumLength = sizeof(szHello2);
KdPrint(("%wS", usTest2.Buffer));
//驱动中的内存分配与释放
ExAllocatePoolWithTag
1:PagedPool->分页内存,NonPagedPool->不内页内存
2:内存长度,字符个数*字符宽度=实际所占的字节数
3:内存标识符,用于发生内存泄漏后标识哪一个驱动哪一个模块造成的内存泄漏,其实是一个32位的随机数
RtlZeroMemory 内存初始化,缓冲区,长度
1:申请的内存缓冲区
2:内存长度
ExFreePool
1:所要释放的内存空间指针
//3.堆空间初始化(涉及到驱动的内存管理)
//3.1 定义一个字符串结构体
UNICODE_STRING usTest3 = { 0 };
//3.2 设置字符串长度
ULONG length = (wcslen(L"hello 1024") * sizeof(WCHAR));
//3.3 在分页内存中申请一块内存
usTest3.Buffer = ExAllocatePoolWithTag(PagedPool, 256 * sizeof(WCHAR), "POCU");
//3.4 内存初始化
RtlZeroMemory(usTest3.Buffer, 256 * sizeof(WCHAR));
//3.5 内存拷贝字符串
memcpy(usTest3.Buffer, L"hello 1024",length);
//3.6 设置字符串长度
usTest3.Length = length;
//3.7 设置字符串最大长度
usTest3.MaximumLength = 256 * sizeof(WCHAR);
//3.8 打印验证
KdPrint(("%wS", usTest3.Buffer));
//3.9 释放内存
ExFreePool(usTest3.Buffer);
//驱动中的的字符串拷贝
//1. 定义一个目标字符串
UNICODE_STRING dst = { 0 };
//2. 定义一个WCHAR类型的变量,目的是预分配内存
WCHAR dst_buf[256];
//3. 初始化目标字符串,使用 RtlInitEmptyUnicodeString,而不是 RtlInitUnicodeString
RtlInitEmptyUnicodeString(&dst, dst_buf,256*sizeof(WCHAR));
//4. 定义一个源字符串
UNICODE_STRING src = { 0 };
//5. 初始化源字符串
RtlInitUnicodeString(&src, L"nihao wenrou!");
//6. 使用 RtlCopyUnicodeString 进行内存拷贝
RtlCopyUnicodeString(&dst, &src);
KdPrint(("%wS", dst.Buffer));
//字符串拼接
//1. 驱动中的字符串拼接
UNICODE_STRING dst2 = {0};
//2. 定义一个WCHAR类型的的变量,用于预分配
WCHAR dst_buf[256];
//3. 定义源字符串1
UNICODE_STRING src1 = { 0 };
//4. 定义源字符串2
UNICODE_STRING src2 = { 0 };
//5. 把目的字符串初始化为空字符串
RtlInitEmptyUnicodeString(&dst2, &dst_buf, 256 * sizeof(WCHAR));
//6. 把两个源字符串初始化
RtlInitUnicodeString(&src1, L"hi ");
RtlInitUnicodeString(&src2, L"wenrou");
//7. 把源字符串1拷贝到目标字符串中,使得目标字符串有值
RtlCopyUnicodeString(&dst2, &src1);
//8. 进行字符串拼接,使用
RtlAppendUnicodeStringToString(&dst2, &src2);
//9. 打印拼接之后的字符串
KdPrint(("%wS", dst2.Buffer));
//返回值
return STATUS_SUCCESS; //实际这里返回的是0,在驱动里返回0是成功,跟三环应用程序相反
}