• 【转】Windows内核下操作字符串!


    *
      Windows内核下操作字符串!
    */
    #include <ntddk.h>
    #include <ntstrsafe.h>
    #define  BUFFER_SIZE 1024
    
    VOID DriverUnload(IN PDRIVER_OBJECT pDriverObject)
    {
       KdPrint(("DriverUnload Load...
    "));
    }
    
    //===========================================================================
    // ANSI_STRING结构和UNICODE_STRING结构的使用
    #pragma  code_seg("INIT")
    NTSTATUS StringTest(VOID) 
    {
       ANSI_STRING AStString = { 0 };
       UNICODE_STRING UStString2 = { 0 };
      UNICODE_STRING UStString3 = RTL_CONSTANT_STRING(L"Initialization string directly!");
      CHAR *SzHello = "hello";
      WCHAR *WSzHello = L"hello";
    
      // 初始化ANSI_STRING字符串的做法
      RtlInitAnsiString(&AStString, SzHello);
      // %Z打印ANSI的结构字符串
      KdPrint(("StringTest->ANSI_STRING: %Z
    ", &AStString));
    
      SzHello[0] = 'H';
      SzHello[1] = 'E';
      SzHello[2] = 'L';
      SzHello[3] = 'L';
      SzHello[4] = 'O';
      SzHello[5] = '';
    
      // 改变SzHello, 结构也会发生改变, ANSI_STRING里面拥有的只是指针
      KdPrint(("ANSI_STRING: %Z
    ", &AStString));
    
      // 手工初始化字符串
      UStString2.MaximumLength = BUFFER_SIZE;    // 最大缓冲区
    
      // 分配内存, 在分页内存中
      UStString2.Buffer = (PWSTR)ExAllocatePool(PagedPool, BUFFER_SIZE);
    
      // 设置字符长度,因为是宽字符,所以是字符长度的2倍
      UStString2.Length = 2 * wcslen(WSzHello);
    
      // 保证缓冲区足够大, 否则程序终止
      ASSERT(UStString2.MaximumLength >= UStString2.Length);
    
      // 内存COPY, Copy的长度就是Unicode字符串的长度
      RtlCopyMemory(UStString2.Buffer, WSzHello, UStString2.Length);
    
      // 打印UnicodeString的方法%wZ
      KdPrint(("StringTest->UStString2:%wZ
    ", &UStString2));
      KdPrint(("StringTest->UStString3:%wZ
    ", &UStString3));
    
      // 清理内存
      ExFreePool(UStString2.Buffer);
      UStString2.Buffer = NULL;
      UStString2.Length = UStString2.MaximumLength = 0;
    
      return STATUS_SUCCESS;
    }
    //===========================================================================
    // 字符串测试2, 字符串之间的Copy
    #pragma  code_seg("INIT")
    NTSTATUS StringCopyTest(VOID) 
    {            
       UNICODE_STRING UStString1 = { 0 };
       UNICODE_STRING UStString2 = { 0 };
    
      // RtlInitUnicodeString不用释放
      RtlInitUnicodeString(&UStString1, L"Hello World");
    
      // 这样也是可以初始化的, 不过要记得释放
      UStString2.Buffer = (PWSTR)ExAllocatePool(PagedPool, BUFFER_SIZE);
    
      // Copy字符串之前必须先填写最大长度
      UStString2.MaximumLength = BUFFER_SIZE;
    
      // 将初始化UStString2拷贝到UStString1
      RtlCopyUnicodeString(&UStString2, &UStString1);
    
      // 分别显示UnicodeString1和UnicodeString2
      KdPrint(("StringCopyTest->UnicodeString1:%wZ!
    ", &UStString1));
      KdPrint(("StringCopyTest->UnicodeString2:%wZ!
    ", &UStString2));
    
      // 字符串的连接
      RtlUnicodeStringCatUnicodeString(&UStString2, &UStString1);
      KdPrint(("StringCopyTest->UnicodeString2:%wZ!
    ", &UStString2));
    
      // 销毁UnicodeString2 注意!!UnicodeString1不用销毁
      RtlFreeUnicodeString(&UStString2);
    
      return STATUS_SUCCESS;
    }
    
    //===========================================================================
    // 字符串的比较试验
    #pragma code_seg("INIT")
    VOID StringCompareTest(VOID)
    {
      LONG dwFlags;
      UNICODE_STRING UStString1;
      UNICODE_STRING UStString2;
    
      RtlInitUnicodeString(&UStString1, L"Hello World");
      RtlInitUnicodeString(&UStString2, L"Hello WorlD");
    
      // 比较字符串, 区分大小写(FALSE), 相等返回True
      if (RtlEqualUnicodeString(&UStString1, &UStString2, FALSE)) 
       {
        KdPrint(("StringCompareTest->UStString1 and UStString2 are equal
    "));
      }
       else 
       {
        KdPrint(("StringCompareTest->UStString1 and UStString2 are NOT equal
    "));
      }
    
      // 比较字符串, 不区分大小写(TRUE), 相等返回TRUE
      RtlInitUnicodeString(&UStString2, L"Hello World");
      if (RtlEqualUnicodeString(&UStString1, &UStString2, FALSE)) 
       {
        KdPrint(("StringCompareTest->UStString1 and UStString2 are equal
    "));
      }
       else 
       {
        KdPrint(("StringCompareTest->UStString1 and UStString2 are NOT equal
    "));
      }
    
      // 比较字符串, 不区分大小写(TRUE), 相等返回TRUE
      RtlInitUnicodeString(&UStString2, L"Hello");
      if (RtlEqualUnicodeString(&UStString1, &UStString2, TRUE)) 
       {
        KdPrint(("StringCompareTest->UStString1 and UStString2 are equal
    "));
       }
       else 
       {
        KdPrint(("StringCompareTest->UStString1 and UStString2 are NOT equal
    "));
      }
    
      // 比较字符串大小, 不区分大小写(TRUE)
      dwFlags = RtlCompareUnicodeString(&UStString1, &UStString2, TRUE);
      if (dwFlags == 0) 
       {
        KdPrint(("StringCompareTest->UStString1 == UStString2
    "));
      }
       else if(dwFlags > 0)
       {
        KdPrint(("StringCompareTest->UStString1 > UStString2
    "));
      }
       else 
       {
        KdPrint(("StringCompareTest->UStString1 < UStString2
    "));
      }
    }
    //===========================================================================
      
    // 字符串转整数型试验
    #pragma code_seg("INIT")
    VOID StringToIntegerTest(VOID)
    {
      ULONG uValue;
      NTSTATUS nStatus;
      UNICODE_STRING UStString1 = RTL_CONSTANT_STRING(L"-100");
       UNICODE_STRING UStString2={ 0 };
    
      // 转换正常的十进制数字
      nStatus = RtlUnicodeStringToInteger(&UStString1, 10, &uValue);
      if (NT_SUCCESS(nStatus)) 
       {
        KdPrint(("StringToIntegerTest->Conver to integer succussfully!
    "));
        KdPrint(("Result:%d
    ", uValue));
      }
       else 
       {
        KdPrint(("StringToIntegerTest->Conver to integer unsuccessfully!
    "));
      }
    
      // 转换16进制数据
      RtlInitUnicodeString(&UStString1, L"100");
      nStatus = RtlUnicodeStringToInteger(&UStString1, 16, &uValue);
      if (NT_SUCCESS(nStatus)) 
       {
        KdPrint(("StringToIntegerTest->Conver to integer succussfully!"));
        KdPrint(("Result:%u 0x%X 
    ", uValue,uValue));
      }
       else 
       {
        KdPrint(("StringToIntegerTest->Conver to integer unsuccessfully!
    "));
      }
    
      // 数字转换成字符串, 初始化UnicodeString2
      UStString2.Buffer = (PWSTR)ExAllocatePool(PagedPool, BUFFER_SIZE);
      UStString2.MaximumLength = BUFFER_SIZE;
      nStatus = RtlIntegerToUnicodeString(200, 10, &UStString2);
      if (NT_SUCCESS(nStatus)) 
       {
        KdPrint(("StringToIntegerTest->Conver to string succussfully!"));
        KdPrint(("Result:%wZ
    ", &UStString2));
      }
       else 
       {
        KdPrint(("StringToIntegerTest->Conver to string unsuccessfully!
    "));
      }
    
      // 16进制数字转字符串
      nStatus = RtlIntegerToUnicodeString(300, 16, &UStString2);
      if (NT_SUCCESS(nStatus)) 
       {
        KdPrint(("StringToIntegerTest->Conver to string succussfully!"));
        KdPrint(("Result:%wZ
    ", &UStString2));
      }
       else 
       {
        KdPrint(("StringToIntegerTest->Conver to string unsuccessfully!
    "));
      }
    
      // UStString2, 注意!!UStString1不用销毁
      RtlFreeUnicodeString(&UStString2);
    }
    //===========================================================================
    
    // 字符串变大写实验
    #pragma code_seg("INIT")
    VOID StringToUpperTest(VOID) 
    {
      UNICODE_STRING UStString1 = RTL_CONSTANT_STRING(L"Hello World");
    
      // 变化前
      KdPrint(("StringToUpperTest->UnicodeString1:%wZ
    ", &UStString1));
    
      // 变大写
      RtlUpcaseUnicodeString(&UStString1, &UStString1, FALSE);
    
      // 变化后
      KdPrint(("StringToUpperTest->UnicodeString1:%wZ
    ", &UStString1));
    }
    //===========================================================================
    
    // ANSI_STRING字符串和UNICODE_STRING之间的转换
    #pragma code_seg("INIT")
    VOID StringConverTest(VOID)
    {
       ANSI_STRING StString1 = { 0 };
       UNICODE_STRING UStString2 = { 0 };
      ANSI_STRING StString2 = RTL_CONSTANT_STRING("Hello World");
      UNICODE_STRING UStString1 = RTL_CONSTANT_STRING(L"Hello World");
    
      // (1)将UNICODE_STRING字符串转换成ANSI_STRING字符串
      NTSTATUS nStatus = RtlUnicodeStringToAnsiString(&StString1, &UStString1, TRUE);
      if (NT_SUCCESS(nStatus)) 
       {
        KdPrint(("Conver succussfully!"));
        KdPrint(("Result:%Z
    ",&StString1));
      }
       else 
       {
        KdPrint(("Conver unsuccessfully!
    "));
      }
    
      // 销毁AnsiString1
      RtlFreeAnsiString(&StString1);
    
      // (2)将ANSI_STRING字符串转换成UNICODE_STRING字符串初始化AnsiString2
      nStatus = RtlAnsiStringToUnicodeString(&UStString2, &StString2, TRUE);
      if (NT_SUCCESS(nStatus)) 
       {
        KdPrint(("Conver succussfully!
    "));
        KdPrint(("Result:%wZ
    ",&UStString2));
      }
       else
       {
        KdPrint(("Conver unsuccessfully!
    "));
      }
      // 销毁UnicodeString2
      RtlFreeUnicodeString(&UStString2);
    }
    
    NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObj, PUNICODE_STRING pUSzReg) 
    {
       pDriverObj->DriverUnload = DriverUnload;
       StringTest();          // 字符串初始化试验
      StringCopyTest();        // 字符串Copy试验
      StringCompareTest();     // 字符串的比较试验
      StringToIntegerTest();   // 字符串转整数型试验
      StringToUpperTest();     // 字符串变大写实验
      StringConverTest();     // ANSI和UNICODE之间的转换
    
      return STATUS_SUCCESS;
    }

    原帖:

    Windows内核下操作字符串!

  • 相关阅读:
    C语言中的排序算法--冒泡排序,选择排序,希尔排序
    常见算法:C语言求最小公倍数和最大公约数三种算法
    提高软件测试效率的方法探讨
    面试官询问的刁钻问题——以及如何巧妙地应付它们
    软件测试面试--如何测试网页的登录页面
    如何衡量测试效率,如何提高测试效率!
    利用交叉测试提升软件测试效率
    交叉测试的必要性和遇到的问题
    敏捷测试
    HttpWatch工具简介及使用技巧
  • 原文地址:https://www.cnblogs.com/Lthis/p/4652725.html
Copyright © 2020-2023  润新知