Windows內核分析索引目錄:https://www.cnblogs.com/onetrainee/p/11675224.html
驅動中常見的字符串操作
驅動中的字符串初始化有三種常見的方法:
1. RTL_UNICODE_STRING:
UNICODE_STRING us = RTL_CONSTANT_STRING(L"RTL_CONSTANT_STRING UnicodeString");
這種定義出來的是常量,無法被修改。
2. RtlInitUnicodeString
UNICODE_STRING us;
RtlInitUnicodeString(&us, L"abcd");
該方法與第一種方法一樣,同樣是常量無法被修改。
3. RtlInitEmptyUnicodeString
UNICODE_STRING usDest;
WCHAR wcstr[128] = { 0 };
RtlInitEmptyUnicodeString(&usDest, wcstr, sizeof(wcstr));
這種有自己獨立的緩沖區,可以被修改,但該緩沖區在棧中,內核中棧非常小,這樣會造成棧溢出,應該使用ExAllocatePool來從堆中分配內存。
#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, "這是一次內存測試"); 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) { KdPrint(("s1=s2\n")); } else if (ret < 0) { KdPrint(("s1<s2\n")); } else { KdPrint(("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; int Value; WCHAR wcstr[128] = { 0 }; RtlInitEmptyUnicodeString(&usDest, wcstr, sizeof(wcstr)); // 1)字符串轉換為數字 RtlInitUnicodeString(&us, L"-123"); RtlUnicodeStringToInteger(&us, 10, &Value); KdPrint(("%d\n", Value)); // 2)數字轉換為字符串 RtlIntegerToUnicodeString(123, 10, &usDest); KdPrint(("%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 DriverUnload(_In_ struct _DRIVER_OBJECT* DriverObject) { DbgPrint("%s\r\n", "驅動卸載成功"); } NTSTATUS DriverEntry(PDRIVER_OBJECT pDriver, PUNICODE_STRING pRegPath) { pDriver->DriverUnload = DriverUnload; MemoryOperation(); // 內存操作 InitStringByRtl(); // 字符串初始化操作 StringCopy(); // 字符串復制操作 CompareString(); // 字符串比較操作 UpperString(); // 字符串大寫操作 StringToInteger(); // 字符串與數字的轉換 FormatPrint(); // 標准化格式輸出 AnsiToUnicode(); // Ansi與Unicode字符串之間的轉換 return STATUS_SUCCESS; }
