概述
学习自:
B站:写驱动的女装大佬 《–从零开始造核弹—windows驱动程序开发(中级篇-4课)》
感谢大佬制作高水准视频!!
学习笔记
一、初始化字符串 :
RtlInitUnicodeString(&deviceanme, DEVICE_NAME)
#define DEVICE_NAME L"\Device\MyfirstDevice" //定义一个驱动的名字
UNICODE_STRING deviceanme = { 0 };//初始一个存储设备名字的内存空间
RtlInitUnicodeString(&deviceanme, DEVICE_NAME);//初始化一个字符串
DbgPrint("--:%wZ--n",&deviceanme);
二、初始化字符串2:
RTL_CONSTANT_STRING(DEVICE_NAME);
此方法有局限性,如果确定字符100%不能进行修改就可以用这个
#define DEVICE_NAME L"\Device\MyfirstDevice" //定义一个驱动的名字
UNICODE_STRING deviceanme = RTL_CONSTANT_STRING(DEVICE_NAME);//初始一个字符串
DbgPrint("--:%wZ--n",&deviceanme);
三、初始化字符串3:
PWCHAR testbuffer = ExAllocatePool(NonPagedPool, 0x1000);//创建一个空指针
RtlZeroMemory(testbuffer, 0x1000);// 缓冲区清零
RtlCopyMemory(testbuffer, L'FFFFFFFFFF', sizeof(L'FFFFFFFFFF'));//拷贝一个字符串到缓冲区
RtlInitUnicodeString(&deviceanme, testbuffer);//初始字符串
DbgPrint("--:%wZ--n",&deviceanme);
四、窄字符转宽字符:
RtlAnsiStringToUnicodeString(&deviceanme, &str, TRUE);//窄字符转宽字符
UNICODE_STRING deviceanme = { 0 };//初始一个存储宽字符的内存空间
PCHAR tempbuffer = "C:\123\321\567\123.txt"; //赋值一个字符串
STRING str = { 0 };//定义一个窄字符存储空间
RtlInitString(&str,tempbuffer);//把字符串初始到窄字符空间
//参数1:宽字符存储位置
//参数2:需要转换的字符
//参数3:是否给参数1申请一个内存空间
RtlAnsiStringToUnicodeString(&deviceanme, &str, TRUE);//把窄字符转换到宽字符
DbgPrint("--:%wZ--n",&deviceanme);
RtlFreeUnicodeString(&deviceanme);//使用完后要释放掉空间
五、字符串之间的复制,及小写字母转大写字母
RtlCopyUnicodeString(&targeunicode,&deviceanme); 字符串拷贝
RtlUpcaseUnicodeString(&deviceanme, &deviceanme, FALSE); 小写字符转大写
UNICODE_STRING targeunicode = { 0 };//定义一个缓冲区
targeunicode.Buffer = ExAllocatePool(NonPagedPool, 0x1000);//给缓存区分配一个指针
targeunicode.MaximumLength = 0x1000;//设置缓冲区的长度
PCHAR tempbuffer = "C:\123\321\567\123.txt";
STRING str = { 0 };
RtlInitString(&str,tempbuffer);
RtlAnsiStringToUnicodeString(&deviceanme, &str, TRUE);
//参数1:目标
//参数2:源字符串
RtlCopyUnicodeString(&targeunicode,&deviceanme);
//参数1可以与参数2相同,也可以是另外一个地址空间
//参数1是被转换后的大写字母存放位置
//参数2是需要进行转换的小写字母
//参数3:是否需要为参数一的地址分配一个空间 FALSE 是不要分配空间,TRUE是要分配空间
RtlUpcaseUnicodeString(&deviceanme, &deviceanme, FALSE);//小写字符串转换为大写
RtlFreeUnicodeString(&deviceanme);//使用完后要释放掉空间
ExFreePool(targeunicode.Buffer);//释放空间,一般要先清零后再释放,这里没有写清零
六、字符串安全的复制,追加, 查找前缀,比较两个字符是否相等,查找字符串
需要引用这个头文件 #include <ntstrsafe.h>
RtlStringCbCopyW(tempbuffer2, 0x1000, L"??");拷贝函数
RtlStringCbCatW(tempbuffer2, 0x1000, L"C:123AAAbbbaaa.txt"); 追加字符
RtlPrefixUnicodeString(&temp2, &temp1, FALSE)// 前缀,判断参数1是否是参数2的前缀
FsRtlIsNameInExpression(&temp5, &temp4, TRUE, NULL))//搜索字符串
//这个是关键,这里就是搜索条件,*表示其余字符,可以放在前或后,或者前后都放,一定要大写
RtlInitUnicodeString(&temp5, L"AAA");//设置查找条件
在参数2中查找是否包含参数1
使用FsRtlIsNameInExpression需要引入#include <ntifs.h> 而且要放在 #include <ntddk.h>前面,否则会报错
PWCHAR tempbuffer2 = ExAllocatePool(NonPagedPool, 0x1000);
RtlZeroMemory(tempbuffer2, 0x1000);//得到一片被清空的内存
//拷贝字符串
//参数1:一个内存空间
//参数2:一个缓冲区的长度,就是参数1空间的长度
//参数3:要复制的内容
RtlStringCbCopyW(tempbuffer2, 0x1000, L"\??\");//安全的字符拷贝
//参数3:要追加的字符串
RtlStringCbCatW(tempbuffer2, 0x1000, L"C:\123\AAA\bbb\aaa.txt");//追加字符串
UNICODE_STRING temp1 = { 0 }, temp2 = { 0 };
RtlInitUnicodeString(&temp1, tempbuffer2);
RtlInitUnicodeString(&temp2, L"\??\");
//字符串前缀判断
//判断一个字符串是否是另外一个字符串的头部,或者说是前缀
//判断参数1是否是参数2的前缀
//参数3是大小写是否敏感
if (RtlPrefixUnicodeString(&temp2, &temp1, FALSE))
{
//如果是前缀就打印这个
DbgPrint("Be Finden");
}
UNICODE_STRING temp3 = { 0 }, temp4 = { 0 };
RtlInitUnicodeString(&temp3, L"D:\ABc\AAA\ddd\aaa.txt");
RtlInitUnicodeString(&temp4, L"D:\ABc\AAA\DDD\aaa.txt");
//字符串比较
//参数1与参数2进行比较
//参数3是大小写是否敏感
if (RtlEqualUnicodeString(&temp3, &temp4, TRUE))
{
//字符串比较
DbgPrint("temp3=temp4n");
}
//搜索字符串
UNICODE_STRING temp5 = { 0 };
//这个是关键,这里就是搜索条件,*表示其余字符,可以放在前或后,或者前后都放,一定要大写
RtlInitUnicodeString(&temp5, L"*AAA*");
//查找字符串
//参数1就是搜索条件
//在参数2中查找是否包含参数1
//如果第三个参数是TRUE ,搜索条件字母必须全部大写,这样就能做到精准搜索
if (FsRtlIsNameInExpression(&temp5, &temp4, TRUE, NULL))
{
//查找到了就打印下面
DbgPrint("Searchedn");
}
DbgPrint("--%ws--n", tempbuffer2);//大于出追加的字符串
完整测试代码
#include <ntifs.h>//必须放在前面
#include <ntddk.h>
#include <windef.h>
#include <ntstrsafe.h>//提供以下比较安全的函数
NTSTATUS DriverEntry(PDRIVER_OBJECT driver, PUNICODE_STRING reg_path)
{
NTSTATUS status = STATUS_SUCCESS; //定义一个返回值
UNICODE_STRING deviceanme = { 0 };//初始一个存储设备名字的内存空间
//UNICODE_STRING deviceanme = RTL_CONSTANT_STRING(DEVICE_NAME);//初始一个存储设备名字的内存空间 (方式二)
PDEVICE_OBJECT pdevice = NULL; //设备创建后的输出参数,如果不为NULL就表示设备创建成功了
driver->DriverUnload = DrvUnload;
//------字符串的操作测试开始--------
UNICODE_STRING targeunicode = { 0 };//定义一个缓冲区
targeunicode.Buffer = ExAllocatePool(NonPagedPool, 0x1000);//给缓存区分配一个指针
targeunicode.MaximumLength = 0x1000;//设置缓冲区的长度
PCHAR tempbuffer = "C:\123\AAA\bbb\aaa.txt";
STRING str = { 0 }; //定义一个窄字符串
RtlInitString(&str, tempbuffer);//初始化一个字符串
RtlAnsiStringToUnicodeString(&deviceanme, &str, TRUE);//窄字符转换为宽字符
RtlCopyUnicodeString(&targeunicode, &deviceanme);//复制字串
RtlUpcaseUnicodeString(&deviceanme, &deviceanme, FALSE);//小写字符串转换为大写
DbgPrint("--%wZ--n", &deviceanme);
ExFreePool(targeunicode.Buffer);//释放空间,一般要先清零后再释放,这里没有写清零
RtlFreeUnicodeString(&deviceanme);//使用完后要释放掉空间
//------字符串的操作测试结尾--------------
//------字符串安全操作测试开始-----------
PWCHAR tempbuffer2 = ExAllocatePool(NonPagedPool, 0x1000);
RtlZeroMemory(tempbuffer2, 0x1000);//得到一片被清空的内存
//拷贝字符串
//参数1:一个内存空间
//参数2:一个缓冲区的长度,就是参数1空间的长度
//参数3:要复制的内容
RtlStringCbCopyW(tempbuffer2, 0x1000, L"\??\");//安全的字符拷贝
//参数3:要追加的字符串
RtlStringCbCatW(tempbuffer2, 0x1000, L"C:\123\AAA\bbb\aaa.txt");//追加字符串
UNICODE_STRING temp1 = { 0 }, temp2 = { 0 };
RtlInitUnicodeString(&temp1, tempbuffer2);
RtlInitUnicodeString(&temp2, L"\??\");
//字符串前缀判断
//判断一个字符串是否是另外一个字符串的头部,或者说是前缀
//判断参数1是否是参数2的前缀
//参数3是大小写是否敏感
if (RtlPrefixUnicodeString(&temp2, &temp1, FALSE))
{
//如果是前缀就打印这个
DbgPrint("Be Finden");
}
UNICODE_STRING temp3 = { 0 }, temp4 = { 0 };
RtlInitUnicodeString(&temp3, L"D:\ABc\AAA\ddd\aaa.txt");
RtlInitUnicodeString(&temp4, L"D:\ABc\AAA\DDD\aaa.txt");
//字符串比较
//参数1与参数2进行比较
//参数3是大小写是否敏感
if (RtlEqualUnicodeString(&temp3, &temp4, TRUE))
{
//字符串比较
DbgPrint("temp3=temp4n");
}
//搜索字符串
UNICODE_STRING temp5 = { 0 };
//这个是关键,这里就是搜索条件,*表示其余字符,可以放在前或后,或者前后都放,一定要大写
RtlInitUnicodeString(&temp5, L"*AAA*");
//查找字符串
//参数1就是搜索条件
//在参数2中查找是否包含参数1
//如果第三个参数是TRUE ,搜索条件字母必须全部大写,这样就能做到精准搜索
if (FsRtlIsNameInExpression(&temp5, &temp4, TRUE, NULL))
{
//查找到了就打印下面
DbgPrint("Searchedn");
}
DbgPrint("--%ws--n", tempbuffer2);//大于出追加的字符串
//------字符串安全操作结尾-----------
RtlInitUnicodeString(&deviceanme, DEVICE_NAME);//初始化一个字符串,这个是符合连接用的
/*
* IoCreateDevice创建设备
参数1:driver 设备对象;
参数2:0 设备扩展的大小;
参数3:&deviceanme 设备名字;
参数4:FILE_DEVICE_UNKNOWN(未知设备) 设备类型
参数5:0 默认参数
参数6:TRUE 默认参数
参数7:&pdevice 输出参数,设备创建成功后,会把设备对象传出来
*/
status = IoCreateDevice(driver,200, &deviceanme, FILE_DEVICE_UNKNOWN,0,TRUE,&pdevice);
if (!NT_SUCCESS(status))
{
//如果设备创建设备就打印下面的信息
DbgPrint("Create Device Failed:%xn",status);
//返回错误信息
return status;
}
//设备的读写方式(必须设置,否则蓝屏)
pdevice->Flags |= DO_BUFFERED_IO;
//到这里 设备就创建成功了
UNICODE_STRING symname = { 0 };//定义一个符号连接名称
RtlInitUnicodeString(&symname, SYM_NAME);//初始化一个字符串
/*IoCreateSymbolicLink创建符号连接
参数1:&symname 符号连接名字
参数2:&deviceanme 设备名字
*/
status = IoCreateSymbolicLink(&symname, &deviceanme);
if (!NT_SUCCESS(status))
{
//如果创建符号连接失败就打印下面的信息
DbgPrint("Create SymbolicLink Failed:%xn", status);
//既然创建符号连接失败,就要删除这个设备
IoDeleteDevice(pdevice);
//返回错误信息
return status;
}
//到这里 符号连接就创建成功了
//驱动的功能都写在下面,派遣函数
//打开设备
driver->MajorFunction[IRP_MJ_CREATE] = MyCreate;
//关闭设备
driver->MajorFunction[IRP_MJ_CLOSE] = MyClose;
//清理设备
driver->MajorFunction[IRP_MJ_CLEANUP] = MyCleanUp;
//读取,应用层把内核数据读取出去
driver->MajorFunction[IRP_MJ_READ] = MyRead;
//写入取,应用层把数据写入内核
driver->MajorFunction[IRP_MJ_WRITE] = MyWrite;
//自定义控制
driver->MajorFunction[IRP_MJ_DEVICE_CONTROL] = MyControl;
return 0;
}
最后
以上就是高高短靴为你收集整理的内核模块字符相关处理的全部内容,希望文章能够帮你解决内核模块字符相关处理所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复