设为首页 收藏本站
查看: 901|回复: 0

[经验分享] Windows内核函数(1) - 字符串处理函数

[复制链接]

尚未签到

发表于 2015-12-16 10:41:44 | 显示全部楼层 |阅读模式
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是程序员自己申请内存,并初始化内存,当不用字符串时,需要回收字符串占用的内存。
示例代码:
INITCODE
TestUnicodeString()
{
\n"));
         UNICODE_STRING ustrTest1;
         WCHAR* wstring = L"Hello";

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

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;

}
对于最后一步清理内存,DDK给出了简化函数,分别是RtlFreeAnsiStringRtlFreeUnicodeString,这两个函数内部调用了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);
}

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-151906-1-1.html 上篇帖子: Windows内核函数(2) - 内核模式下的文件操作 下篇帖子: Windows内核驱动中操作文件
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表