`
wangangie10
  • 浏览: 39502 次
  • 性别: Icon_minigender_1
  • 来自: 珠海
最近访客 更多访客>>
社区版块
存档分类
最新评论

Windows内核函数(1) - 字符串处理函数

阅读更多

  1.ASCII字符串和宽字符串
  打印一个ASCII字符串:
  CHAR* string = "Hello";
  KdPrint(("%s\n", string));        //s为小写
  打印一个宽字符字符串
  WCHAR* string = L"Hello";
  KdPrint(("%S\n",string));         //s为大写
  2.ANSI_STRING字符串与UNICODE_STRING字符串
  ANSI_STRING:
  typedef struct _STRING {
  USHORT  Length;
  USHORT  MaximumLength;
  PCHAR  Buffer;
  } ANSI_STRING *PANSI_STRING;
  UNICODE_STRING:
  typedef struct _UNICODE_STRING {
  USHORT  Length;
  USHORT  MaximumLength;
  PWSTR  Buffer;
  } UNICODE_STRING *PUNICODE_STRING;
  打印ANSI_STRING
  ANSI_STRING ansiString;
  //省略对ansiString的初始化
  KdPrint(("%Z\n",&ansiString));        //注意是大写的Z
  打印UNICODE_STRING
  UNICODE_STRING unicodeString;
  //省略对unicodeString的初始化
  KdPrint(("%wZ",&unicodeString));          //注意是小写的w和大写的Z
  3.字符串的初始化与销毁
  (1)方法一是使用DDK提供的相应的函数。
  初始化ANSI_STRING字符串: VOID 
  RtlInitAnsiString(
  IN OUT PANSI_STRING  DestinationString,
  IN PCSZ  SourceString
  ); 初始化UNICODE_STRING字符串 VOID 
  RtlInitUnicodeString(
  IN OUT PUNICODE_STRING  DestinationString,
  IN PCWSTR  SourceString
  ); 使用方法(以ANSI_STRING为例):
  ANSI_STRING ansiString;
  CHAR* string = "Hello";
  RtlInitAnsiString(&ansiString, string);
  注意:
  这种方法是将ANSI_STRING结构体中的Buffer指针等于string指针。
  这种初始化的优点是操作简单,用完后不用清理内存。但是带来另外一个问题,如果修改string,同时会导致ansiString字符串发生变化。
  (2)方法2是程序员自己申请内存,并初始化内存,当不用字符串时,需要回收字符串占用的内存。
  示例代码:
  #pragmaINITCODE
  VOIDTestUnicodeString()
  {
  KdPrint(("1.利用DDK函数进行初始化UNICODE_STRING!\n"));
  UNICODE_STRINGustrTest1;
  WCHAR* wstring = L"Hello";
  //用DDK宏进行初始化
  RtlInitUnicodeString(&ustrTest1, wstring);
  KdPrint(("%wZ", &ustrTest1));
  KdPrint(("2.自己初始化UNICODE_STRING!\n"));
  UNICODE_STRINGustring2 = {0};
  //设置缓冲区大小
  ustring2.MaximumLength = BUFFER_SIZE;
  //申请内存
  ustring2.Buffer = (PWSTR)ExAllocatePool(PagedPool, BUFFER_SIZE);
  WCHAR* string2 = L"hello";
  //两倍字符的长度
  ustring2.Length = 2*wcslen(string2);
  RtlCopyMemory(ustring2.Buffer, string2, ustring2.Length);
  KdPrint(("%wZ", &ustring2));
  //清理内存
  ExFreePool(ustring2.Buffer);
  ustring2.Buffer = NULL;
  ustring2.Length = ustring2.MaximumLength = 0;
  //RtlFreeUnicodeString(&ustring2);
  }
  对于最后一步清理内存,DDK给出了简化函数,分别是RtlFreeAnsiString和RtlFreeUnicodeString,这两个函数内部调用了ExFreePool去回收内存。
  所以最后的三行代码也可替换成最后的一行注释代码。
  4.字符串复制
  ANSI_STRING字符串复制函数 VOID 
  RtlCopyString(
  IN OUT PSTRING  DestinationString,
  IN PSTRING  SourceString  OPTIONAL
  ); UNICODE_STRING字符串复制函数 VOID 
  RtlCopyUnicodeString(
  IN OUT PUNICODE_STRING  DestinationString,
  IN PUNICODE_STRING  SourceString
  ); 示例代码:
  #pragma INITCODE
  void TestCopy()
  {
  //初始化string1
  UNICODE_STRING string1;
  RtlInitUnicodeString(&string1, L"fuckzq");
  //初始化string2
  UNICODE_STRING string2;
  string2.Buffer = (PWSTR)ExAllocatePool(PagedPool, BUFFER_SIZE);
  string2.MaximumLength = BUFFER_SIZE;
  string2.Length = string1.Length;
  //开始复制
  RtlCopyUnicodeString(&string2, &string1);
  KdPrint(("%wZ\n", &string1));
  KdPrint(("%wZ\n", &string2));
  //销毁string2。
  //注意:string1不用销毁
  RtlFreeUnicodeString(&string2);
  }
  5.字符串比较
  ANSI_STRING比较函数 LONG 
  RtlCompareString(
  IN PSTRING  String1,
  IN PSTRING  String2,
  BOOLEAN  CaseInSensitive                //是否对大小写敏感
  ); BOOLEAN 
  RtlEqualString(
  IN PSTRING  String1,
  IN PSTRING  String2,
  IN BOOLEAN  CaseInSensitive
  ); UNICODE_STRING比较函数 LONG 
  RtlCompareUnicodeString(
  IN PUNICODE_STRING  String1,
  IN PUNICODE_STRING  String2,
  IN BOOLEAN  CaseInSensitive
  ); BOOLEAN 
  RtlEqualUnicodeString(
  IN CONST UNICODE_STRING  *String1,
  IN CONST UNICODE_STRING  *String2,
  IN BOOLEAN  CaseInSensitive
  ); 示例代码:
  #pragma INITCODE
  VOID TestCmpSting()
  {
  UNICODE_STRING string1;
  RtlInitUnicodeString(&string1, L"fuckyouzq");
  UNICODE_STRING string2;
  string2.Buffer = (PWSTR)ExAllocatePool(PagedPool, BUFFER_SIZE);
  string2.MaximumLength = BUFFER_SIZE;
  RtlCopyUnicodeString(&string2, &string1);
  if (RtlCompareUnicodeString(&string1, &string2, TRUE) == 0)
  {
  KdPrint(("1.相等\n"));
  }
  if (RtlEqualUnicodeString(&string1, &string2, TRUE))
  {
  KdPrint(("相等!\n"));
  }
  else
  {
  KdPrint(("不相等\n"));
  }
  }
  6.字符串转化成大写
  ANSI_STRING: VOID 
  RtlUpperString(
  IN OUT PSTRING  DestinationString,
  IN PSTRING  SourceString
  ); UNICODE_STRING: NTSTATUS 
  RtlUpcaseUnicodeString(
  IN OUT PUNICODE_STRING  DestinationString  OPTIONAL,
  IN PCUNICODE_STRING  SourceString,
  IN BOOLEAN  AllocateDestinationString    //是否为目的字符串分配内存
  ); 注意:DDK虽然提供了转化成大写的函数,但是却没有提供转化为小写的函数。
  示例代码:
  #pragma INITCODE
  VOID TestUpperString()
  {
  UNICODE_STRING string1;
  RtlInitUnicodeString(&string1, L"Hello World");
  KdPrint(("%wZ\n",&string1));
  UNICODE_STRING string2;
  //RtlUpcaseUnicodeString最后一个参数为TRUE,表示为目标字符串分配内存,因此我们不需要手动分配了。
  RtlUpcaseUnicodeString(&string2, &string1, TRUE);
  KdPrint(("%wZ\n", &string2));
  //目标字符串和源字符串可以是同一个字符串
  RtlUpcaseUnicodeString(&string1, &string1, FALSE);
  KdPrint(("%wZ\n",&string1));    
  RtlFreeUnicodeString(string2);
  }
  7.字符串与整形数字相互转换
  将UNICODE_STRING字符串转换成整数 NTSTATUS
  RtlUnicodeStringToInteger(
  IN PUNICODE_STRING  String,                             //字符串
  IN ULONG  Base  OPTIONAL,                        //转换的数的进制
  OUT PULONG  Value                                  //转换后的数字
  ); 将整数转换成UNICODE_STRING NTSTATUS 
  RtlIntegerToUnicodeString(
  IN ULONG  Value,
  IN ULONG  Base  OPTIONAL,
  IN OUT PUNICODE_STRING  String
  ); 示例代码:
  VOID TestStringToInt()
  {
  UNICODE_STRING string1;
  RtlInitUnicodeString(&string1, L"-100");
  ULONG i;
  NTSTATUS status = RtlUnicodeStringToInteger(&string1, 10, &i);
  if (!NT_SUCCESS(status))
  {
  KdPrint(("转换失败!\n"));
  }
  else
  {
  KdPrint(("%d", i));
  }
  UNICODE_STRING string2 = {0};
  string2.Buffer = (PWSTR)ExAllocatePool(PagedPool, BUFFER_SIZE);
  string2.MaximumLength = BUFFER_SIZE;
  status = RtlIntegerToUnicodeString(200, 10, &string2);
  if (!NT_SUCCESS(status))
  {
  KdPrint(("转换失败!\n"));
  }
  else
  {
  KdPrint(("%wZ\n", &string2));
  }
  RtlFreeUnicodeString(&string2);
  }
  8.ANSI_STRING 和 UNICODE_STRING字符串相互转换
  UNICODE_STRING转换为ANSI_STRING字符串 NTSTATUS 
  RtlUnicodeStringToAnsiString(
  IN OUT PANSI_STRING  DestinationString,
  IN PUNICODE_STRING  SourceString,
  IN BOOLEAN  AllocateDestinationString
  ); ANSI_STRING 转为 UNICODE_STRING 字符串 NTSTATUS 
  RtlAnsiStringToUnicodeString(
  IN OUT PUNICODE_STRING  DestinationString,
  IN PANSI_STRING  SourceString,
  IN BOOLEAN  AllocateDestinationString
  ); 示例代码:
  #pragma INITCODE
  VOID TestStringToString()
  {
  UNICODE_STRING unicodeString;
  RtlInitUnicodeString(&unicodeString, L"fuckyou!\n");
  ANSI_STRING ansiString;
  NTSTATUS status = RtlUnicodeStringToAnsiString(&ansiString, &unicodeString, TRUE); //为ansiString分配内存
  if(NT_SUCCESS(status))
  {
  KdPrint(("%Z",&ansiString));
  }
  //销毁ansiString
  RtlFreeAnsiString(&ansiString);
  }
  更多驱动编程文章 http://mzf2008.blog.163.com/blog/static/3559978620 101112115510592/
分享到:
评论

相关推荐

    精通Windows.API-函数、接口、编程实例.pdf

    15.2.5 字符串表 469 15.3 安装程序setup.exe的编号 469 15.4 使用msi文件进行安装 472 15.4.1 Windows Installer Service 472 15.4.2 msi文件的创建与修改工具orca.exe 474 15.4.3 准备工作 475 15.4.4...

    寒江独钓-Windows内核安全编程(高清完整版).part1

    2.2.3 字符串 23 2.3 重要的数据结构 23 2.3.1 驱动对象 23 2.3.2 设备对象 25 2.3.3 请求 26 2.4 函数调用 28 2.4.1 查阅帮助 28 2.4.2 帮助中有的几类函数 30 2.4.3 帮助中没有的函数 32 2.5 Windows的驱动开发...

    天书夜读:从汇编语言到Windows内核编程(完整版一)

     16.2 隐藏内核函数 244  16.3 混淆流程与数据操作 251  16.3.1 混淆函数出口 251  16.3.2 插入有意义的花指令 253  第17章 用VMProtect保护代码 258  17.1 安装VMProtect 259  17.2 使用VMProtect 261  ...

    天书夜读:从汇编语言到Windows内核编程(完整版 二)

     16.2 隐藏内核函数 244  16.3 混淆流程与数据操作 251  16.3.1 混淆函数出口 251  16.3.2 插入有意义的花指令 253  第17章 用VMProtect保护代码 258  17.1 安装VMProtect 259  17.2 使用VMProtect 261  ...

    寒江独钓-Windows内核安全编程(高清完整版).part4

    2.2.3 字符串 23 2.3 重要的数据结构 23 2.3.1 驱动对象 23 2.3.2 设备对象 25 2.3.3 请求 26 2.4 函数调用 28 2.4.1 查阅帮助 28 2.4.2 帮助中有的几类函数 30 2.4.3 帮助中没有的函数 32 2.5 Windows的驱动开发...

    精通WindowsAPI 函数 接口 编程实例

    15.2.5 字符串表 469 15.3 安装程序setup.exe的编号 469 15.4 使用msi文件进行安装 472 15.4.1 Windows Installer Service 472 15.4.2 msi文件的创建与修改工具orca.exe 474 15.4.3 准备工作 475 15.4.4...

    寒江独钓-Windows内核安全编程(高清完整版).part6

    2.2.3 字符串 23 2.3 重要的数据结构 23 2.3.1 驱动对象 23 2.3.2 设备对象 25 2.3.3 请求 26 2.4 函数调用 28 2.4.1 查阅帮助 28 2.4.2 帮助中有的几类函数 30 2.4.3 帮助中没有的函数 32 2.5 Windows的驱动开发...

    寒江独钓-Windows内核安全编程(高清完整版).part7

    2.2.3 字符串 23 2.3 重要的数据结构 23 2.3.1 驱动对象 23 2.3.2 设备对象 25 2.3.3 请求 26 2.4 函数调用 28 2.4.1 查阅帮助 28 2.4.2 帮助中有的几类函数 30 2.4.3 帮助中没有的函数 32 2.5 Windows的驱动开发...

    Windows内核安全与驱动开发光盘源码

    第1章 内核上机指导 2 1.1 下载和使用WDK 2 1.1.1 下载并安装WDK 2 1.1.2 编写第一个C文件 4 1.1.3 编译一个工程 5 1.2 安装与运行 6 1.2.1 下载一个安装工具 6 1.2.2 运行与查看输出信息 7 1.2.3 在虚拟机...

    寒江独钓-Windows内核安全编程(高清完整版).part5

    2.2.3 字符串 23 2.3 重要的数据结构 23 2.3.1 驱动对象 23 2.3.2 设备对象 25 2.3.3 请求 26 2.4 函数调用 28 2.4.1 查阅帮助 28 2.4.2 帮助中有的几类函数 30 2.4.3 帮助中没有的函数 32 2.5 Windows的驱动开发...

    从汇编语言到Windows内核编程

    第4章 内核字符串与内存 4.1 字符串的处理 4.1.1 使用字符串结构 4 1 2 字符串的初始化 4.1.3 字符串的拷贝 4.1.4 字符串的连接 4.1.5 字符串的打印 4 2 内存与链表 4 2.1 内存的分配与释放 4.2.2 使用LIST_ENTRY ...

    windows internals 7th-2; windows 内核数据结构;内核编程参考;英文PDF转word原版

    这本质上是一个以 null 结尾的 Unicode 字符数组,字符串长度(以字节为单位)存储在内存中字符数组开始之前的 4 个字节处。 * 性能监视器:运行对话框中键入 perfmon * 调试内核配置:srv*c:\symbols*...

    天书夜谈:从汇编语言到Windows内核编程

     16.2 隐藏内核函数 244  16.3 混淆流程与数据操作 251  16.3.1 混淆函数出口 251  16.3.2 插入有意义的花指令 253  第17章 用VMProtect保护代码 258  17.1 安装VMProtect 259  17.2 使用VMProtect 261  ...

    寒江独钓-Windows内核安全编程(高清完整版).part3

    2.2.3 字符串 23 2.3 重要的数据结构 23 2.3.1 驱动对象 23 2.3.2 设备对象 25 2.3.3 请求 26 2.4 函数调用 28 2.4.1 查阅帮助 28 2.4.2 帮助中有的几类函数 30 2.4.3 帮助中没有的函数 32 2.5 Windows的驱动开发...

    寒江独钓-Windows内核安全编程(高清完整版).part2

    2.2.3 字符串 23 2.3 重要的数据结构 23 2.3.1 驱动对象 23 2.3.2 设备对象 25 2.3.3 请求 26 2.4 函数调用 28 2.4.1 查阅帮助 28 2.4.2 帮助中有的几类函数 30 2.4.3 帮助中没有的函数 32 2.5 Windows的驱动开发...

    Windows内核安全驱动开发(随书光盘)

    第1章 内核上机指导 2 1.1 下载和使用WDK 2 1.1.1 下载并安装WDK 2 1.1.2 编写第一个C文件 4 1.1.3 编译一个工程 5 1.2 安装与运行 6 1.2.1 下载一个安装工具 6 1.2.2 运行与查看输出信息 7 1.2.3 在虚拟机...

    windows驱动开发技术详解-part2

     本章介绍了Windows内核模式下的一些常用内核函数,这些函数在驱动程序的开发中将会经常用到。  6.1 内核模式下的字符串操作  6.1.1 ASCII字符串和宽字符串  6.1.2 ANSI_STRING字符串与UNICODE_STRING字符串 ...

    Windows驱动编程基础教程-楚狂人.doc

    第一章 字符串 6 1.1 使用字符串结构 6 1.2 字符串的初始化 7 1.3 字符串的拷贝 8 1.4 字符串的连接 8 1.5 字符串的打印 9 第二章 内存与链表 11 2.1内存的分配与释放 11 2.2 使用LIST_ENTRY 12 2.3 使用长长整型...

    Windows驱动开发基础视频教程.txt

    第6章windows内核函数 第十七课 内核模式下的字符串操作1 第十八课 内核模式下的字符串操作 第十九课 内核模式下的字符串操作 第二十课 内核模式下的文件操作 第二十一课 内核模式下的文件操作 第二十二课 ...

Global site tag (gtag.js) - Google Analytics