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-08-25 00:47:54

Windows内核函数(1) - 字符串处理函数的相关文章

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

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

hive函数 -- split 字符串分割函数

hive字符串分割函数 split(str, regex) - Splits str around occurances that match regexTime taken: 0.769 seconds, Fetched: 1 row(s) 返回值为一个数组 a.基本用法: 例1: split('a,b,c,d',',') 得到的结果: ["a","b","c","d"] b.截取字符串中的某个值: 当然,我们也可以指定取结

oracle函数大全-字符串处理函数

字符函数——返回字符值 这些函数全都接收的是字符族类型的参数(CHR 除外)并且返回字符值.除了特别说明的之外,这些函数大部分返回VARCHAR2类型的数值.字符函数的返回类型所受的限制和基本数据库类型所受的限制是相同的,比如: VARCHAR2数值被限制为2000字符(ORACLE 8中为4000字符),而CHAR数值被限制为255字符(在ORACLE8中是2000).当在过程性语句中使用时,它们可以被赋值给VARCHAR2 或者CHAR类型的PL/SQL变量. CHR 语法: chr(x)

依据函数名字符串执行函数

这个问题虽然不是很严重,但却困扰本人许久.曾经多方询问朋友.查阅资料均无法达到效果. 今日偶然查到一些东西,经实测的却可行,也算了却了一桩心愿. 不再废话直接贴DEMO代码 1 unit Unit2; 2 3 interface 4 5 uses 6 Vcl.Dialogs, Vcl.Forms, System.Generics.Collections, System.Variants; 7 8 type 9 TMyIntf = class(TForm) 10 public 11 class f

C语言之字符串处理函数

C语言中字符串处理函数介绍 下面介绍8种基本的常用的字符串处理函数,在数值数组中也常常用到(部分函数).所有的C语言编译系统中一般都提供这些函数. 1.puts函数——输出字符串的函数 一般的形式为puts(字符串组) 作用:将一个字符串输出到终端.如,char一个string,并赋予初值.调用puts(string);进行字符串的输出. 2.gets函数——输入字符串的函数 一般的形式:gets(字符数组) 作用:从终端输入一个字符串到字符数组,并且得到一个函数值成为字符数组的起始地址. ge

ThinkPHP 3.2.2 视图模板中使用字符串截取函数

在项目的 Common/function.php 文件里( 项目结构如图 ) 添加函数: /*字符串截断函数+省略号*/ function subtext($text, $length) { if(mb_strlen($text, 'utf8') > $length) return mb_substr($text, 0, $length, 'utf8').'...'; return $text; } 然后在模板文件中这样写 ( 使用 TP 模板 ),例如在循环中: <volist name=&

Split字符串分割函数

非常非常常用的一个函数Split字符串分割函数. Dim myTest myTest = "aaa/bbb/ccc/ddd/eee/fff/ggg" Dim arrTest arrTest = Split(myTest , "/" , -1 , 1) Dim i For i = 0 to ubound(arrTest) print "arrTest(" & i & ") = " & arrTest(i)

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

IRQL和内核字符串处理函数

内核字符串处理函数和IRQL --by 张佩 系统中断级(IRQL) 借助于IRQL机制,系统实现了任务抢占功能.高中断级任务可以任意抢占低中断级任务的系统执行权,而低中断级任务必须等待所有高中断级任务都完成后,才能获取执行机会和相应系统资源.在单核系统中,系统中断级还被用做实现系统同步机制的手段,因为一颗核心的CPU在同一时刻,仅能运行一个线程,所以只要把当前正在使用Critical资源的线程IRQL提高到更高Level上,就可以避免其他线程和抢占自己的可能性. 系统功能被细分为许多系统模块,