在内核中.咱们的字符有 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帮助文档便可.code
说的UNICODE_STRING的使用.这里须要注意一下.内存
UNICODE_STRING TestUCString = [0]; WCHAR wzData[0x100] = L"Hello World"" RtlInitUnicodeString(&TetUCString,wzData);
这样初始化的方式.是将UNICODE_STRING的 Buffer指针指向栈内存.unicode
伪代码:
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指向一个堆内存.这个内存是咱们分配的.