64位内核第七讲.内核中字符串编程注意事项

内存中字符串编程

一丶UNICODE_STRING讲解

1.1简介

在内核中.我们的字符有 char类型的.也有wchar_t类型的.分别是宽字符
跟窄字符.但是这种都不建议使用了.而内核提供了两个新的结构体让我们使用
分别别:
UNICODE_STRING
ANSI_STRING

随便哪个结构体进行简介.

typedef struct _UNICODE_STRING {
  USHORT  Length;
  USHORT  MaximumLength;
  PWSTR  Buffer;
} UNICODE_STRING, *PUNICODE_STRING;

内核中的UNICODE_STRING其实是个结构体.
简介一下:
参数一: 字符串的字节数.不带\0结尾的字节数. 注意是字节
参数二: Buffer的最大字节数.如果Buffer存储字符串.那么字节数就是
wcslen(Buffer)+sizeof(wchar_t)也就是说说带\0结尾.
参数三: Buffer缓冲区.存放字符串的指针.

1.2字符串的操作函数

既然有了这些结构体.那么就会有相应的提供操作字符串的函数.
如我们在WDK文档查询这个结构体的时候.
下面就会有个 See Also告诉我们字符串操作相关的一系列函数.

函数名 作用
RtlUnicodeStringInit 安全的初始化UNICODE_STRING.不安全的有RtlinitUnicodeString.安全的动词放后面
RtlStringCbCopyUnicodeString 将UNICODE_STRING按照字节大小,拷贝到一个wchar_t的缓冲区中
RtlUnicodeStringCat 拼接一个UNICODE_STRIGN
RtlUnicodeStringCatString 将UNICODE_STRING 拼接一个PCTSTR的字符串.
RtlUnicodeStringCbCatN 都是传入两个UNICODE_STRING结构体.多了一个参数.这个参数指定你要拼接的字节数进行拼接.不用完整拼接了.

具体函数查询WDK帮助文档即可.

1.3UNICODE_STRING的使用

说的UNICODE_STRING的使用.这里需要注意一下.

1.3.1 在栈上初始化一个Buffer

UNICODE_STRING TestUCString = [0];
WCHAR wzData[0x100] = L"Hello World""

RtlInitUnicodeString(&TetUCString,wzData);

这样初始化的方式.是将UNICODE_STRING的 Buffer指针指向栈内存.

伪代码:
Buffer = wzData;
最重要的一点就是此时你可以使用Rtl拷贝函数对这个UNICODE_STRING进行操作了.
因为内存是有的.

RtlUnicodeStringCopyString是可以对这个内存进行拷贝的.

1.3.2 全局初始化

UNICODE_STRING ustr;
RtlUnicodeStringInit(&ustr,L"HelloWorld");

此时的UNICODE_STRING里面的Buffer指针是指向全局常量区的 HelloWorld的.所以此时你使用拷贝函数就会出错.很可能就会蓝屏

1.3.3堆上初始化一个缓冲区.

UNICODE_STRING ustr = {0};
ULONG length = (wcslen(L"HelloWorld") + ) * sizeof(WCHAR);
ustr.Buffer = ExAllocatePoolWithTag(PagedPool,MAX_PATH 8 sizeof(WCHAR),"niBI");

if (ustr.Buffer == NULL)
    return ;

清空缓存
RtlZeroMemory(ustr.Buffer,MAX_PATH *sizeof(WCHAR));

wcscpy(ustr.Buffer,L"HelloWorld");
ustr.length = length;
ustr.Maximumlength = MAX_PATH * sizeof(WCHAR);

DbgPrint("%wZ",&ustr);
ExFreePool(ustr.Buffer); 

上面的UNICODE_STRING 的Buffer指向一个堆内存.这个内存是我们分配的.

猜你喜欢

转载自www.cnblogs.com/iBinary/p/10990678.html
今日推荐