- 浏览: 39502 次
- 性别:
- 来自: 珠海
最新评论
Windows内核函数(1) - 字符串处理函数
- 博客分类:
- 技术杂绘
1.ASCII字符串和宽字符串
打印一个ASCII字符串:
CHAR* string = "Hello";
KdPrint(("%s\n", string)); //s为小写
打印一个宽字符字符串
WCHAR* string = L"Hello";
KdPrint(("%S\n",string)); //s为大写
2.ANSI_STRING字符串与UNICODE_STRING字符串
ANSI_STRING:
typedef struct _STRING {
USHORT Length;
USHORT MaximumLength;
PCHAR Buffer;
} ANSI_STRING *PANSI_STRING;
UNICODE_STRING:
typedef struct _UNICODE_STRING {
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
} UNICODE_STRING *PUNICODE_STRING;
打印ANSI_STRING
ANSI_STRING ansiString;
//省略对ansiString的初始化
KdPrint(("%Z\n",&ansiString)); //注意是大写的Z
打印UNICODE_STRING
UNICODE_STRING unicodeString;
//省略对unicodeString的初始化
KdPrint(("%wZ",&unicodeString)); //注意是小写的w和大写的Z
3.字符串的初始化与销毁
(1)方法一是使用DDK提供的相应的函数。
初始化ANSI_STRING字符串: VOID
RtlInitAnsiString(
IN OUT PANSI_STRING DestinationString,
IN PCSZ SourceString
); 初始化UNICODE_STRING字符串 VOID
RtlInitUnicodeString(
IN OUT PUNICODE_STRING DestinationString,
IN PCWSTR SourceString
); 使用方法(以ANSI_STRING为例):
ANSI_STRING ansiString;
CHAR* string = "Hello";
RtlInitAnsiString(&ansiString, string);
注意:
这种方法是将ANSI_STRING结构体中的Buffer指针等于string指针。
这种初始化的优点是操作简单,用完后不用清理内存。但是带来另外一个问题,如果修改string,同时会导致ansiString字符串发生变化。
(2)方法2是程序员自己申请内存,并初始化内存,当不用字符串时,需要回收字符串占用的内存。
示例代码:
#pragmaINITCODE
VOIDTestUnicodeString()
{
KdPrint(("1.利用DDK函数进行初始化UNICODE_STRING!\n"));
UNICODE_STRINGustrTest1;
WCHAR* wstring = L"Hello";
//用DDK宏进行初始化
RtlInitUnicodeString(&ustrTest1, wstring);
KdPrint(("%wZ", &ustrTest1));
KdPrint(("2.自己初始化UNICODE_STRING!\n"));
UNICODE_STRINGustring2 = {0};
//设置缓冲区大小
ustring2.MaximumLength = BUFFER_SIZE;
//申请内存
ustring2.Buffer = (PWSTR)ExAllocatePool(PagedPool, BUFFER_SIZE);
WCHAR* string2 = L"hello";
//两倍字符的长度
ustring2.Length = 2*wcslen(string2);
RtlCopyMemory(ustring2.Buffer, string2, ustring2.Length);
KdPrint(("%wZ", &ustring2));
//清理内存
ExFreePool(ustring2.Buffer);
ustring2.Buffer = NULL;
ustring2.Length = ustring2.MaximumLength = 0;
//RtlFreeUnicodeString(&ustring2);
}
对于最后一步清理内存,DDK给出了简化函数,分别是RtlFreeAnsiString和RtlFreeUnicodeString,这两个函数内部调用了ExFreePool去回收内存。
所以最后的三行代码也可替换成最后的一行注释代码。
4.字符串复制
ANSI_STRING字符串复制函数 VOID
RtlCopyString(
IN OUT PSTRING DestinationString,
IN PSTRING SourceString OPTIONAL
); UNICODE_STRING字符串复制函数 VOID
RtlCopyUnicodeString(
IN OUT PUNICODE_STRING DestinationString,
IN PUNICODE_STRING SourceString
); 示例代码:
#pragma INITCODE
void TestCopy()
{
//初始化string1
UNICODE_STRING string1;
RtlInitUnicodeString(&string1, L"fuckzq");
//初始化string2
UNICODE_STRING string2;
string2.Buffer = (PWSTR)ExAllocatePool(PagedPool, BUFFER_SIZE);
string2.MaximumLength = BUFFER_SIZE;
string2.Length = string1.Length;
//开始复制
RtlCopyUnicodeString(&string2, &string1);
KdPrint(("%wZ\n", &string1));
KdPrint(("%wZ\n", &string2));
//销毁string2。
//注意:string1不用销毁
RtlFreeUnicodeString(&string2);
}
5.字符串比较
ANSI_STRING比较函数 LONG
RtlCompareString(
IN PSTRING String1,
IN PSTRING String2,
BOOLEAN CaseInSensitive //是否对大小写敏感
); BOOLEAN
RtlEqualString(
IN PSTRING String1,
IN PSTRING String2,
IN BOOLEAN CaseInSensitive
); UNICODE_STRING比较函数 LONG
RtlCompareUnicodeString(
IN PUNICODE_STRING String1,
IN PUNICODE_STRING String2,
IN BOOLEAN CaseInSensitive
); BOOLEAN
RtlEqualUnicodeString(
IN CONST UNICODE_STRING *String1,
IN CONST UNICODE_STRING *String2,
IN BOOLEAN CaseInSensitive
); 示例代码:
#pragma INITCODE
VOID TestCmpSting()
{
UNICODE_STRING string1;
RtlInitUnicodeString(&string1, L"fuckyouzq");
UNICODE_STRING string2;
string2.Buffer = (PWSTR)ExAllocatePool(PagedPool, BUFFER_SIZE);
string2.MaximumLength = BUFFER_SIZE;
RtlCopyUnicodeString(&string2, &string1);
if (RtlCompareUnicodeString(&string1, &string2, TRUE) == 0)
{
KdPrint(("1.相等\n"));
}
if (RtlEqualUnicodeString(&string1, &string2, TRUE))
{
KdPrint(("相等!\n"));
}
else
{
KdPrint(("不相等\n"));
}
}
6.字符串转化成大写
ANSI_STRING: VOID
RtlUpperString(
IN OUT PSTRING DestinationString,
IN PSTRING SourceString
); UNICODE_STRING: NTSTATUS
RtlUpcaseUnicodeString(
IN OUT PUNICODE_STRING DestinationString OPTIONAL,
IN PCUNICODE_STRING SourceString,
IN BOOLEAN AllocateDestinationString //是否为目的字符串分配内存
); 注意:DDK虽然提供了转化成大写的函数,但是却没有提供转化为小写的函数。
示例代码:
#pragma INITCODE
VOID TestUpperString()
{
UNICODE_STRING string1;
RtlInitUnicodeString(&string1, L"Hello World");
KdPrint(("%wZ\n",&string1));
UNICODE_STRING string2;
//RtlUpcaseUnicodeString最后一个参数为TRUE,表示为目标字符串分配内存,因此我们不需要手动分配了。
RtlUpcaseUnicodeString(&string2, &string1, TRUE);
KdPrint(("%wZ\n", &string2));
//目标字符串和源字符串可以是同一个字符串
RtlUpcaseUnicodeString(&string1, &string1, FALSE);
KdPrint(("%wZ\n",&string1));
RtlFreeUnicodeString(string2);
}
7.字符串与整形数字相互转换
将UNICODE_STRING字符串转换成整数 NTSTATUS
RtlUnicodeStringToInteger(
IN PUNICODE_STRING String, //字符串
IN ULONG Base OPTIONAL, //转换的数的进制
OUT PULONG Value //转换后的数字
); 将整数转换成UNICODE_STRING NTSTATUS
RtlIntegerToUnicodeString(
IN ULONG Value,
IN ULONG Base OPTIONAL,
IN OUT PUNICODE_STRING String
); 示例代码:
VOID TestStringToInt()
{
UNICODE_STRING string1;
RtlInitUnicodeString(&string1, L"-100");
ULONG i;
NTSTATUS status = RtlUnicodeStringToInteger(&string1, 10, &i);
if (!NT_SUCCESS(status))
{
KdPrint(("转换失败!\n"));
}
else
{
KdPrint(("%d", i));
}
UNICODE_STRING string2 = {0};
string2.Buffer = (PWSTR)ExAllocatePool(PagedPool, BUFFER_SIZE);
string2.MaximumLength = BUFFER_SIZE;
status = RtlIntegerToUnicodeString(200, 10, &string2);
if (!NT_SUCCESS(status))
{
KdPrint(("转换失败!\n"));
}
else
{
KdPrint(("%wZ\n", &string2));
}
RtlFreeUnicodeString(&string2);
}
8.ANSI_STRING 和 UNICODE_STRING字符串相互转换
UNICODE_STRING转换为ANSI_STRING字符串 NTSTATUS
RtlUnicodeStringToAnsiString(
IN OUT PANSI_STRING DestinationString,
IN PUNICODE_STRING SourceString,
IN BOOLEAN AllocateDestinationString
); ANSI_STRING 转为 UNICODE_STRING 字符串 NTSTATUS
RtlAnsiStringToUnicodeString(
IN OUT PUNICODE_STRING DestinationString,
IN PANSI_STRING SourceString,
IN BOOLEAN AllocateDestinationString
); 示例代码:
#pragma INITCODE
VOID TestStringToString()
{
UNICODE_STRING unicodeString;
RtlInitUnicodeString(&unicodeString, L"fuckyou!\n");
ANSI_STRING ansiString;
NTSTATUS status = RtlUnicodeStringToAnsiString(&ansiString, &unicodeString, TRUE); //为ansiString分配内存
if(NT_SUCCESS(status))
{
KdPrint(("%Z",&ansiString));
}
//销毁ansiString
RtlFreeAnsiString(&ansiString);
}
更多驱动编程文章 http://mzf2008.blog.163.com/blog/static/3559978620 101112115510592/
发表评论
-
匹配汉字的正则表达式
2012-07-06 09:45 799匹配汉字的表达式: [^x00-xff]。 附:正则表 ... -
Java正则表达式匹配使用实例
2012-07-06 09:37 642实例一: 正则 ... -
完美解决Panel设置了borderSkin后内容体与标题栏重叠的问题
2012-07-06 09:30 553如果您做过Flex皮肤方面的工作,并且想自定义Panel及 ... -
firstChild, className,childNodes,parentNode的简单实用
2012-07-05 20:45 653function showmsg(obj) { docum ... -
用纯粹的C++编写COM组件
2012-07-03 13:43 778本文提供一个完全用C++实现的进程内(DLL)COM服 ... -
flex list/tilelist drag scroll的speed移动太快
2012-07-02 10:47 478最近项目中遇到tilelist中拖拽的时scroll的移动 ... -
flex4:中DataGroup组件获取数据源(ArrayCollection方式)实例
2012-07-02 10:47 501flex/spark" xmlns:mx=&q ... -
[ActionScript3.0][My flex]读书笔记三之 模块化编程
2012-07-02 10:47 5391.加载mxml模块 第一步: 新建mxml模块:Data ... -
Flex:在有序DataGrid顶部添加新行
2012-07-02 10:47 434w ... -
B2B2C网上商城开发指南――基于SaaS和淘宝API开放平台
2012-07-01 00:25 608B2B2C网上商城开发指南--基于SaaS和淘宝AP ... -
拥抱RIA拥抱未来
2012-07-01 00:25 603学习和使用RIA已有一段时间了,结合实际工作、谈谈自己的见 ... -
基于WebService+Flex的B/S系统架构
2012-07-01 00:25 635系统采用标准的三层架构 展现层/业务逻辑/数据层 展 ... -
屏蔽Flex右键的一些解决方案
2012-07-01 00:25 516一直以来对Flex或者说Flash的右键就存在一些不好的印 ... -
学习Flex,都学些什么
2012-07-01 00:25 549学习Flex,都学些什么呢? 1、首先是事件机制,整 ...
相关推荐
15.2.5 字符串表 469 15.3 安装程序setup.exe的编号 469 15.4 使用msi文件进行安装 472 15.4.1 Windows Installer Service 472 15.4.2 msi文件的创建与修改工具orca.exe 474 15.4.3 准备工作 475 15.4.4...
2.2.3 字符串 23 2.3 重要的数据结构 23 2.3.1 驱动对象 23 2.3.2 设备对象 25 2.3.3 请求 26 2.4 函数调用 28 2.4.1 查阅帮助 28 2.4.2 帮助中有的几类函数 30 2.4.3 帮助中没有的函数 32 2.5 Windows的驱动开发...
16.2 隐藏内核函数 244 16.3 混淆流程与数据操作 251 16.3.1 混淆函数出口 251 16.3.2 插入有意义的花指令 253 第17章 用VMProtect保护代码 258 17.1 安装VMProtect 259 17.2 使用VMProtect 261 ...
16.2 隐藏内核函数 244 16.3 混淆流程与数据操作 251 16.3.1 混淆函数出口 251 16.3.2 插入有意义的花指令 253 第17章 用VMProtect保护代码 258 17.1 安装VMProtect 259 17.2 使用VMProtect 261 ...
2.2.3 字符串 23 2.3 重要的数据结构 23 2.3.1 驱动对象 23 2.3.2 设备对象 25 2.3.3 请求 26 2.4 函数调用 28 2.4.1 查阅帮助 28 2.4.2 帮助中有的几类函数 30 2.4.3 帮助中没有的函数 32 2.5 Windows的驱动开发...
15.2.5 字符串表 469 15.3 安装程序setup.exe的编号 469 15.4 使用msi文件进行安装 472 15.4.1 Windows Installer Service 472 15.4.2 msi文件的创建与修改工具orca.exe 474 15.4.3 准备工作 475 15.4.4...
2.2.3 字符串 23 2.3 重要的数据结构 23 2.3.1 驱动对象 23 2.3.2 设备对象 25 2.3.3 请求 26 2.4 函数调用 28 2.4.1 查阅帮助 28 2.4.2 帮助中有的几类函数 30 2.4.3 帮助中没有的函数 32 2.5 Windows的驱动开发...
2.2.3 字符串 23 2.3 重要的数据结构 23 2.3.1 驱动对象 23 2.3.2 设备对象 25 2.3.3 请求 26 2.4 函数调用 28 2.4.1 查阅帮助 28 2.4.2 帮助中有的几类函数 30 2.4.3 帮助中没有的函数 32 2.5 Windows的驱动开发...
第1章 内核上机指导 2 1.1 下载和使用WDK 2 1.1.1 下载并安装WDK 2 1.1.2 编写第一个C文件 4 1.1.3 编译一个工程 5 1.2 安装与运行 6 1.2.1 下载一个安装工具 6 1.2.2 运行与查看输出信息 7 1.2.3 在虚拟机...
2.2.3 字符串 23 2.3 重要的数据结构 23 2.3.1 驱动对象 23 2.3.2 设备对象 25 2.3.3 请求 26 2.4 函数调用 28 2.4.1 查阅帮助 28 2.4.2 帮助中有的几类函数 30 2.4.3 帮助中没有的函数 32 2.5 Windows的驱动开发...
第4章 内核字符串与内存 4.1 字符串的处理 4.1.1 使用字符串结构 4 1 2 字符串的初始化 4.1.3 字符串的拷贝 4.1.4 字符串的连接 4.1.5 字符串的打印 4 2 内存与链表 4 2.1 内存的分配与释放 4.2.2 使用LIST_ENTRY ...
这本质上是一个以 null 结尾的 Unicode 字符数组,字符串长度(以字节为单位)存储在内存中字符数组开始之前的 4 个字节处。 * 性能监视器:运行对话框中键入 perfmon * 调试内核配置:srv*c:\symbols*...
16.2 隐藏内核函数 244 16.3 混淆流程与数据操作 251 16.3.1 混淆函数出口 251 16.3.2 插入有意义的花指令 253 第17章 用VMProtect保护代码 258 17.1 安装VMProtect 259 17.2 使用VMProtect 261 ...
2.2.3 字符串 23 2.3 重要的数据结构 23 2.3.1 驱动对象 23 2.3.2 设备对象 25 2.3.3 请求 26 2.4 函数调用 28 2.4.1 查阅帮助 28 2.4.2 帮助中有的几类函数 30 2.4.3 帮助中没有的函数 32 2.5 Windows的驱动开发...
2.2.3 字符串 23 2.3 重要的数据结构 23 2.3.1 驱动对象 23 2.3.2 设备对象 25 2.3.3 请求 26 2.4 函数调用 28 2.4.1 查阅帮助 28 2.4.2 帮助中有的几类函数 30 2.4.3 帮助中没有的函数 32 2.5 Windows的驱动开发...
第1章 内核上机指导 2 1.1 下载和使用WDK 2 1.1.1 下载并安装WDK 2 1.1.2 编写第一个C文件 4 1.1.3 编译一个工程 5 1.2 安装与运行 6 1.2.1 下载一个安装工具 6 1.2.2 运行与查看输出信息 7 1.2.3 在虚拟机...
本章介绍了Windows内核模式下的一些常用内核函数,这些函数在驱动程序的开发中将会经常用到。 6.1 内核模式下的字符串操作 6.1.1 ASCII字符串和宽字符串 6.1.2 ANSI_STRING字符串与UNICODE_STRING字符串 ...
第一章 字符串 6 1.1 使用字符串结构 6 1.2 字符串的初始化 7 1.3 字符串的拷贝 8 1.4 字符串的连接 8 1.5 字符串的打印 9 第二章 内存与链表 11 2.1内存的分配与释放 11 2.2 使用LIST_ENTRY 12 2.3 使用长长整型...
第6章windows内核函数 第十七课 内核模式下的字符串操作1 第十八课 内核模式下的字符串操作 第十九课 内核模式下的字符串操作 第二十课 内核模式下的文件操作 第二十一课 内核模式下的文件操作 第二十二课 ...