tiechui_lesson04_内核中字符串操作

主要是对宽字符类型的字符串的应用,包括初始化,拷贝,比较,检索,合并等。

字符串的初始化

1.RTL_CONSTANT_STRING宏

RTL_CONSTANT_STRING宏创建一个字符串(char)或Unicode字符串(wchar_t)结构来保存一个计数字符串。

UNICODE_STRING	dst = RTL_CONSTANT_STRING(L"D:\\Projects\\helloworld.c");

使用这个宏定义的时候注意,这个是const,不能释放不能修改。

2.RtlInitUnicodeString

UNICODE_STRING dst;
RtlInitUnicodeString(&dst, L"D:\\Projects\\helloworld2.c");

该方法与第一种方法一样,同样是常量无法被修改。

3.RtlInitEmptyUnicodeString

UNICODE_STRING  dst;

WCHAR wcstr[128] = { 0 };

RtlInitEmptyUnicodeString(&dst, wcstr, sizeof(wcstr));

这种有自己独立的缓冲区,可以被修改,但该缓冲区在栈中,内核中栈非常小,这样会造成栈溢出,应该使用ExAllocatePool或者ExAllocatePoolTag来从堆中分配内存。

#include <ntifs.h>	// 放到ntddk.h前边 否则重定义
#include <ntddk.h>
#include <intrin.h>
#include <ntstrsafe.h>



// 内存操作
void MemoryOperation() {
	PCHAR pcstr;
	DbgPrint("1.内存操作:\n");
	// 1)申请内存
	pcstr = (PCHAR)ExAllocatePoolWithTag(NonPagedPool, 1024, 'abcd');
	if (pcstr == NULL) {
		DbgPrint("内存分配失败\n");
		return;
	}
	// 2)清空内存
	RtlZeroMemory(pcstr, 1024);

	// 3)赋值内存
	strcpy(pcstr, "这是一次内存测试 strcpy赋值");
	DbgPrint("%s\n", pcstr);

	RtlZeroMemory(pcstr, 1024);
	RtlCopyMemory(pcstr, "这是一次内存测试 RtlCopyMemory赋值",
		strlen("这是一次内存测试 RtlCopyMemory赋值"));
	DbgPrint("%s\n", pcstr);


	// 4)释放内存
	ExFreePoolWithTag(pcstr, 'abcd');
	DbgPrint("**************\n");
}

// 使用宏来进行字符串初始化操作
void InitStringByRtl() {
	DbgPrint("2.通过宏来进行字符串初始化操作:\n");
	UNICODE_STRING us = RTL_CONSTANT_STRING(L"RTL_CONSTANT_STRING UnicodeString");
	ANSI_STRING as = RTL_CONSTANT_STRING("RTL_CONSTANT_STRING AnsiString");
	DbgPrint("%wZ\n", &us);
	DbgPrint("%Z\n", &as);
	DbgPrint("**************\n");
}

// 字符串赋值操作
void StringCopy() {
	DbgPrint("3.字符串复制操作:\n");

	// 1)声明目标字符串
	UNICODE_STRING usDest;
	ANSI_STRING asDest;
	WCHAR wcstr[128] = { 0 }; // UnicodeString的缓冲区
	CHAR asstr[128] = { 0 }; // AnsiString的缓冲区

	// 2)初始化原字符串
	UNICODE_STRING us = RTL_CONSTANT_STRING(L"UnicodeString");
	ANSI_STRING as = RTL_CONSTANT_STRING("AnsiString");

	// 3)初始化目标字符串(自定义缓冲区)
	RtlInitEmptyUnicodeString(&usDest, wcstr, sizeof(wcstr));
	RtlInitEmptyAnsiString(&asDest, asstr, sizeof(asstr));

	// 4)复制目标字符串
	RtlCopyUnicodeString(&usDest, &us);
	RtlCopyString(&asDest, &as);

	// 5)输出字符串
	DbgPrint("%wZ\n", &usDest);
	DbgPrint("%Z\n", &asDest);
	DbgPrint("**************\n");
}

// 字符串比较操作
VOID CompareString() {
	DbgPrint("4.字符串比较操作:\n");

	// 1)初始化字符串
	UNICODE_STRING s1 = RTL_CONSTANT_STRING(L"Hello world!");
	UNICODE_STRING s2 = RTL_CONSTANT_STRING(L"Hello world!");

	// 2)字符串比较
	int ret = RtlCompareUnicodeString(&s1, &s2, TRUE);

	// 3)输出字符串比较结果
	if (ret == 0)
	{
		DbgPrint("s1=s2\n");
	}
	else if (ret < 0)
	{
		DbgPrint("s1<s2\n");
	}
	else
	{
		DbgPrint("s1>s2\n");
	}
	DbgPrint("**************\n");
}

// 字符串转换为大写操作
void UpperString() {

	DbgPrint("5.将字符串转换为大写:\n");

	// 1)声明并初始化字符串
	UNICODE_STRING us, usDest;
	RtlInitUnicodeString(&us, L"abcd");
	WCHAR wcstr[128] = { 0 };
	RtlInitEmptyUnicodeString(&usDest, wcstr, sizeof(wcstr));

	// 2)将字符串转换为大写
	RtlUpcaseUnicodeString(&usDest, &us, FALSE);
	DbgPrint("转换为大写:%wZ\n", &usDest);
	DbgPrint("**************\n");
}

// 字符串与数字的转换
void StringToInteger() {
	DbgPrint("6.字符串与数字的转换:\n");

	UNICODE_STRING us, usDest;
	ULONG Value;
	WCHAR wcstr[128] = { 0 };
	RtlInitEmptyUnicodeString(&usDest, wcstr, sizeof(wcstr));

	// 1)字符串转换为数字
	RtlInitUnicodeString(&us, L"-123");
	RtlUnicodeStringToInteger(&us, 10, &Value);
	DbgPrint("%d\n", Value);

	// 2)数字转换为字符串
	RtlIntegerToUnicodeString(123, 10, &usDest);
	DbgPrint("%wZ\n", &us);
	DbgPrint("**************\n");
}

// 格式化输出
void FormatPrint() {
	DbgPrint("7.标准化输出:\n");

	// 1)初始化字符串
	UNICODE_STRING str1 = RTL_CONSTANT_STRING(L"abc");
	UNICODE_STRING us;
	WCHAR wcstr[128] = { 0 };
	RtlInitEmptyUnicodeString(&us, wcstr, sizeof(wcstr));

	// 2)标准化格式输出 ntstrsafe.h 
	RtlUnicodeStringPrintf(&us, L"%d%wZ\n", 10, &str1);

	// 3)输出
	DbgPrint("%wZ", &us);

	DbgPrint("**************\n");
}

// ANSI与UnicodeString之间的转换
void AnsiToUnicode() {
	DbgPrint("8.ANSI与UnicodeString之间的转换:\n");
	// 1)初始化Unicode字符串
	UNICODE_STRING us;
	WCHAR wcstr[128] = { 0 };
	RtlInitEmptyUnicodeString(&us, wcstr, sizeof(wcstr));

	// 2)初始化ANSI字符串
	ANSI_STRING as = RTL_CONSTANT_STRING("Hello World!");

	// 3)ANSI转换为Unicode
	RtlAnsiStringToUnicodeString(&us, &as, FALSE);
	DbgPrint("%wZ\n", &us);
	DbgPrint("**************\n");


}

// 字符串检索
void IndexOfString() {
	DbgPrint("9.在目标字符串中检索特定字符串:\n");
	// 1)初始化Unicode字符串
	UNICODE_STRING dst_str1 = RTL_CONSTANT_STRING(L"D:\\Projects\\helloworld.c");
	UNICODE_STRING str = RTL_CONSTANT_STRING(L"d:");



	// 2) 在字符串中搜索前缀
	DbgPrint("源字符串:%wZ\n", &dst_str1);
	if (RtlPrefixUnicodeString(&str,&dst_str1,FALSE))	
	{
		DbgPrint("设置FALSE 找到 \"D:\"");
	}
	if (RtlPrefixUnicodeString(&str, &dst_str1, TRUE))// TRUE 设置大小写不敏感
	{
		DbgPrint("设置TRUE 找到 \"d:\"");
	}

	// 3)通配符搜索 (需引入ntifs.h)
	UNICODE_STRING str2 = RTL_CONSTANT_STRING(L"*.C");	// 需要搜索的字符串要用大写形式
	if (FsRtlIsNameInExpression(&str2, &dst_str1, TRUE, NULL))
	{
		DbgPrint("通配符 \"*.C\"搜索到 \n");
	}
	UNICODE_STRING str3 = RTL_CONSTANT_STRING(L"*HELLO*");	// 需要搜索的字符串要用大写形式
	if (FsRtlIsNameInExpression(&str3, &dst_str1, TRUE, NULL))
	{
		DbgPrint("通配符 \"*HELLO*\"搜索到 \n");
	}

	DbgPrint("**************\n");


}

VOID DriverUnload(_In_ struct _DRIVER_OBJECT* DriverObject) {
	UNREFERENCED_PARAMETER(DriverObject);
	DbgPrint("%s\r\n", "驱动卸载成功");
}
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriver, PUNICODE_STRING pRegPath) {
	UNREFERENCED_PARAMETER(pRegPath);

	pDriver->DriverUnload = DriverUnload;

	MemoryOperation(); // 内存操作
	InitStringByRtl(); // 字符串初始化操作
	StringCopy(); // 字符串复制操作
	CompareString(); // 字符串比较操作
	UpperString(); // 字符串大写操作
	StringToInteger(); // 字符串与数字的转换
	FormatPrint(); // 标准化格式输出
	AnsiToUnicode(); // Ansi与Unicode字符串之间的转换
	IndexOfString(); // 字符串检索


	return STATUS_SUCCESS;
}

UNICODE_STRING的释放

动态分配的空间需要进行释放,把buffer域空间free掉,然后指向null,将长度置0。注意不能释放常量字符串,否则会直接蓝屏。😢😢😢

    ExFreePoolWithTag( String->Buffer,CTX_STRING_TAG );

    String->Length = String->MaximumLength = 0;
    String->Buffer = NULL;

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值