UNICODE_STRING(用户模式 内核模式)
UNICODE_STRING结构:
typedef struct _UNICODE_STRING {
USHORT Length; //字节长度,不包括终止符“NULL”
USHORT MaximumLength; //字符串所能占的最大字节数字符串的指针
PWCH Buffer; //字符串的地址,也即指针
} UNICODE_STRING;
一.用户模式初始化,拷贝操作
// UnicodeString(User).cpp : 定义控制台应用程序的入口点。 // #include <windows.h> #include <iostream> using namespace std; #define BUFFER_SIZE 0x400 typedef struct _UNICODE_STRING { USHORT Length; USHORT MaximumLength; PWCHAR Buffer; }UNICODE_STRING,*PUNICODE_STRING; /************************************************************************/ /* 初始化 */ /************************************************************************/ void InitUNICODESTRING_1(); VOID SeRtlInitUnicodeString( OUT PUNICODE_STRING DestinationString, IN PCWSTR SourceString OPTIONAL); void InitUNICODESTRING_2(); void InitUNICODESTRING_3(); void InitUNICODESTRING_4(); VOID SeRtlCopyUnicodeString( OUT PUNICODE_STRING DestinationString, IN PUNICODE_STRING SourceString OPTIONAL); VOID SeRtlFreeUnicodeString( IN OUT PUNICODE_STRING UnicodeString); /* typedef struct _UNICODE_STRING { USHORT Length; //UNICODE占用的内存字节数,个数*2; USHORT MaximumLength; PWSTR Buffer; } UNICODE_STRING ,*PUNICODE_STRING; */ int main() { InitUNICODESTRING_1(); InitUNICODESTRING_2(); InitUNICODESTRING_3(); InitUNICODESTRING_4(); printf("Input AnyKey To Exit\r\n"); getchar(); return 0; } void InitUNICODESTRING_1() { UNICODE_STRING v1; SeRtlInitUnicodeString(&v1, L"HelloWorld"); printf("%wZ\r\n", &v1); //ASCI_STRING %Z UNICODE_STRING %wZ } VOID SeRtlInitUnicodeString( OUT PUNICODE_STRING DestinationString, IN PCWSTR SourceString OPTIONAL) { USHORT Length = 0; DestinationString->Length = 0; DestinationString->Buffer = (PWSTR)SourceString; if (SourceString!=NULL) { while (*SourceString++) { Length += sizeof(*SourceString); } DestinationString->Length = Length; DestinationString->MaximumLength = Length + (USHORT)sizeof(UNICODE_NULL); } else { DestinationString->MaximumLength = 0; } } void InitUNICODESTRING_2() { UNICODE_STRING v1; WCHAR BufferData[] = L"HelloWorld"; v1.Buffer = BufferData; v1.Length = wcslen(BufferData) * sizeof(WCHAR); v1.MaximumLength = (wcslen(BufferData) + 1) * sizeof(WCHAR); printf("%wZ\r\n", &v1); } void InitUNICODESTRING_3() { UNICODE_STRING v1; WCHAR BufferData[] = L"HelloWorld"; v1.Length = wcslen(BufferData) * sizeof(WCHAR); v1.MaximumLength = (wcslen(BufferData) + 1) * sizeof(WCHAR); v1.Buffer = (WCHAR*)malloc(v1.MaximumLength); RtlZeroMemory(v1.Buffer, v1.MaximumLength); RtlCopyMemory(v1.Buffer, BufferData, v1.Length); printf("%wZ\r\n", &v1); if (v1.Buffer != NULL) { free(v1.Buffer); v1.Buffer = NULL; v1.Length = v1.MaximumLength = 0; } } void InitUNICODESTRING_4() { UNICODE_STRING SourceString; SeRtlInitUnicodeString(&SourceString, L"HelloWorld"); UNICODE_STRING DestinationString = { 0 }; DestinationString.Buffer = (PWSTR)malloc(BUFFER_SIZE); DestinationString.MaximumLength = BUFFER_SIZE; SeRtlCopyUnicodeString(&DestinationString, &SourceString); printf("SourceString:%wZ\n", &SourceString); printf("DestinationString:%wZ\n", &DestinationString); SeRtlFreeUnicodeString(&DestinationString); } VOID SeRtlCopyUnicodeString( OUT PUNICODE_STRING DestinationString, IN PUNICODE_STRING SourceString OPTIONAL ) { WCHAR *v1, *v2; ULONG SourceStringLength = 0; if (SourceString!=NULL) { v2 = DestinationString->Buffer; v1 = SourceString->Buffer; SourceStringLength = SourceString->Length; if ((USHORT)SourceStringLength > DestinationString->MaximumLength) { SourceStringLength = DestinationString->MaximumLength; } DestinationString->Length = (USHORT)SourceStringLength; RtlCopyMemory(v2, v1, SourceStringLength); if (DestinationString->Length < DestinationString->MaximumLength) { v2[SourceStringLength / sizeof(WCHAR)] = UNICODE_NULL; } } else { DestinationString->Length = 0; } return; } VOID SeRtlFreeUnicodeString( IN OUT PUNICODE_STRING UnicodeString ) { if (UnicodeString->Buffer) { free(UnicodeString->Buffer); memset( UnicodeString, 0, sizeof( *UnicodeString ) ); } }
二.内核模式初始化,拷贝操作
初始化UNICODE_STRING:
1.常量内存,RtlInitUnicodeString 函数Buffer指针指向字符串的首地址,然后对Length和 MaximumLength成员赋值为字符串的字节数。
2.动态内存,ExAllocatePool函数动态分配。
3.栈区内存,局部变量手动赋值。
#include <ntifs.h> #define MAX_PATH 260 #define BUFFER_SIZE 0x400 /************************************************************************/ /* 初始化 */ /************************************************************************/ void Sub_1(); //常量内存 void Sub_2(); //栈区内存 void Sub_3(); //动态内存 /************************************************************************/ /* 拷贝操作 */ /************************************************************************/ void Sub_4(); VOID DriverUnload(PDRIVER_OBJECT DriverObject); //bp UnicodeString(Kernel)!DriverEntry NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegisterPath) { NTSTATUS Status = STATUS_SUCCESS; PDEVICE_OBJECT DeviceObject = NULL; DriverObject->DriverUnload = DriverUnload; Sub_1(); return Status; } //初始操作 void Sub_1() { UNICODE_STRING v1; RtlInitUnicodeString(&v1, L"HelloWorld"); DbgPrint("%wZ\r\n", &v1); } void Sub_2() { UNICODE_STRING v1; WCHAR BufferData[] = L"HelloWorld"; v1.Buffer = BufferData; v1.Length = wcslen(BufferData)*sizeof(WCHAR); v1.MaximumLength = (wcslen(BufferData)+1)*sizeof(WCHAR); DbgPrint("%wZ\r\n", &v1); } void Sub_3() { UNICODE_STRING v1; WCHAR BufferData[] = L"HelloWorld"; v1.Length = wcslen(BufferData) * sizeof(WCHAR); v1.MaximumLength = (wcslen(BufferData) + 1) * sizeof(WCHAR); v1.Buffer = ExAllocatePool(PagedPool, v1.MaximumLength); RtlZeroMemory(v1.Buffer, v1.MaximumLength); RtlCopyMemory(v1.Buffer,BufferData,v1.Length); DbgPrint("%wZ\r\n", &v1); if (v1.Buffer!=NULL) { ExFreePool(v1.Buffer); v1.Buffer = NULL; v1.Length = v1.MaximumLength = 0; } } //拷贝操作 void Sub_4() { UNICODE_STRING SourceString; RtlInitUnicodeString(&SourceString, L"HelloWorld"); UNICODE_STRING DestinationString = { 0 }; DestinationString.Buffer = (PWSTR)ExAllocatePool(PagedPool, BUFFER_SIZE); DestinationString.MaximumLength = BUFFER_SIZE; RtlCopyUnicodeString(&DestinationString, &SourceString); KdPrint(("SourceString:%wZ\n", &SourceString)); KdPrint(("DestinationString:%wZ\n", &DestinationString)); RtlFreeUnicodeString(&DestinationString); } VOID DriverUnload(PDRIVER_OBJECT DriverObject) { DbgPrint("DriverUnload()\r\n"); }