在内核中.我们的字符有 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缓冲区.存放字符串的指针.
既然有了这些结构体.那么就会有相应的提供操作字符串的函数.
如我们在WDK文档查询这个结构体的时候.
下面就会有个 See Also告诉我们字符串操作相关的一系列函数.
函数名 | 作用 | |
---|---|---|
RtlUnicodeStringInit | 安全的初始化UNICODE_STRING.不安全的有RtlinitUnicodeString.安全的动词放后面 | |
RtlStringCbCopyUnicodeString | 将UNICODE_STRING按照字节大小,拷贝到一个wchar_t的缓冲区中 | |
RtlUnicodeStringCat | 拼接一个UNICODE_STRIGN | |
RtlUnicodeStringCatString | 将UNICODE_STRING 拼接一个PCTSTR的字符串. | |
RtlUnicodeStringCbCatN | 都是传入两个UNICODE_STRING结构体.多了一个参数.这个参数指定你要拼接的字节数进行拼接.不用完整拼接了. |
具体函数查询WDK帮助文档即可.
说的UNICODE_STRING的使用.这里需要注意一下.
UNICODE_STRING TestUCString = [0];
WCHAR wzData[0x100] = L"Hello World""
RtlInitUnicodeString(&TetUCString,wzData);
这样初始化的方式.是将UNICODE_STRING的 Buffer指针指向栈内存.
伪代码:
Buffer = wzData;
最重要的一点就是此时你可以使用Rtl拷贝函数对这个UNICODE_STRING进行操作了.
因为内存是有的.
RtlUnicodeStringCopyString是可以对这个内存进行拷贝的.
UNICODE_STRING ustr;
RtlUnicodeStringInit(&ustr,L"HelloWorld");
此时的UNICODE_STRING里面的Buffer指针是指向全局常量区的 HelloWorld的.所以此时你使用拷贝函数就会出错.很可能就会蓝屏
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指向一个堆内存.这个内存是我们分配的.
原文:https://www.cnblogs.com/iBinary/p/10990678.html