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是程序员自己申请内存,并初始化内存,当不用字符串时,需要回收字符串占用的内存。

示例代码:

#pragma INITCODE

VOID TestUnicodeString()

{

KdPrint(("1.利用DDK函数进行初始化UNICODE_STRING!\n"));

UNICODE_STRING ustrTest1;

WCHAR* wstring = L"Hello";

//用DDK宏进行初始化

RtlInitUnicodeString(&ustrTest1, wstring);

KdPrint(("%wZ", &ustrTest1));

KdPrint(("2.自己初始化UNICODE_STRING!\n"));

UNICODE_STRING ustring2 = {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);

}

windows内核函数1 - 字符串处理

时间: 2024-10-11 05:30:51

windows内核函数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 {  USH

Windows内核函数(3) - 内核模式下的注册表操作

Windows内核函数(3) - 内核模式下的注册表操作 2010-12-13 13:37:16|  分类: 驱动编程 |  标签:status  hkey  ulsize  注册  kdprint  |举报|字号 订阅 注册表里的几个概念: 1.       创建关闭注册表项 NTSTATUS   ZwCreateKey(    OUT PHANDLE  KeyHandle,    IN ACCESS_MASK  DesiredAccess, //访问权限,一般为KEY_ALL_ACCLESS

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

* Windows内核下操作字符串! */ #include <ntddk.h> #include <ntstrsafe.h> #define BUFFER_SIZE 1024 VOID DriverUnload(IN PDRIVER_OBJECT pDriverObject) { KdPrint(("DriverUnload Load...\n")); } //==================================================

Windows 驱动开发基础(九)内核函数

Windows 驱动开发基础系列,转载请标明出处:http://blog.csdn.net/ikerpeng/article/details/38849861 这里主要介绍3类Windows的内核函数:字符串处理函数,文件操作函数, 注册表读写函数.(这些函数都是运行时函数,所以都有Rtl字样) 1 字符串处理函数 首先驱动程序中,常用的字符串包括4种:CHAR (打印的时候注意小写%s), WCHAR(打印的时候注意大写%S), ANSI_STRING, UNICODE_STRING.后面两种

Windows内核分析——NtCreateDebugObject函数分析

第一篇分析Windows内核的文章,主要是加强学习记忆.以后会多写这种笔记,正如猪猪侠所说,所学的知识只有实践并且能够讲出来才能真正实现掌握. 程序来自ReactOS或WRK1.2 资料参考自<Windows内核情景分析>和<Windows 内核设计思想>以及网上文章和视频 NTSTATUS NtCreateDebugObject ( OUT PHANDLE DebugObjectHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_AT

C++windows内核编程笔记day07_day08,可视化建菜单、加速键使用、绘图等

可视化操作创建的菜单,加载到窗口. 方法1:注册时指定菜单 wce.lpszMenuName=MAKEINTRESOURCE(IDR_MENUMAIN);//数字形式的资源ID转换为字符串形式的资源 方法2: //创建窗口时加载菜单资源 HMENU menumain= LoadMenu(g_hinstance,MAKEINTRESOURCE(IDR_MENUMAIN)); menumain 传入 CreateWindowEx();//倒数第三个参数 窗口指定小图标: 1.注册时指定 wce.hI

C++windows内核编程笔记day09_day10,对话框和窗口基本控件等的使用

//设置字体颜色 SetTextColor(hdc,RGB(255,0,0)); //窗口背景 //wce.hbrBackground=(HBRUSH)(COLOR_WINDOW+1); //wce.hbrBackground=CreateSolidBrush(RGB(0,0,255)); //设置字体背景 SetBkColor(hdc,RGB(0,0,200)); //设置字体背景模式 SetBkMode(hdc,TRANSPARENT);//字体背景透明 //创建字体,成功返回字体,失败返回

Windows内核之内核对象

1内核对象定义: 1.1:每个内 核对象只是内核分配的一个内存块,并且只能由该内核访问. 1.2:该内存块是一种数据结构,它的成员负责维护该对象的各种信息. 有些数据成员(如安全性描述符.使用计数等)在所有对象类型中是相同的,但大多数数据成员属于特定的对象类型.例如,进程对象有一个进程ID .一个基 本优先级和一个退出代码,而文件对象则拥有一个字节位移.一个共享模式和一个打开模式. 2内核对象种类: 比如存取符号对象. 事件对象.文件对象.文件映射对象.I / O 完成端口对象.作业对象.信箱对

Windows内核安全与驱动开发

这篇是计算机中Windows Mobile/Symbian类的优质预售推荐<Windows内核安全与驱动开发>. 编辑推荐 本书适合计算机安全软件从业人员.计算机相关专业院校学生以及有一定C语言和操作系统基础知识的编程爱好者阅读. 内容简介 本书的前身是<天书夜读--从汇编语言到Windows内核编程>和<寒江独钓--Windows内核安全编程>.与Windows客户端安全软件开发相关的驱动程序开发是本书的主题.书中的程序使用环境从32位到64位,从Windows XP