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幫助文檔便可.code

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指針指向棧內存.unicode

僞代碼:
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指向一個堆內存.這個內存是咱們分配的.

相關文章
相關標籤/搜索