您的位置:首页 > 其它

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

2014-03-05 10:22 417 查看
.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(&ustrTe
1bb8c
st1, 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);

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: