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:

typedefstruct_STRING{

USHORTLength;

USHORTMaximumLength;

PCHARBuffer;

}ANSI_STRING*PANSI_STRING;

UNICODE_STRING:

typedefstruct_UNICODE_STRING{

USHORTLength;

USHORTMaximumLength;

PWSTRBuffer;

}UNICODE_STRING*PUNICODE_STRING;

打印ANSI_STRING

ANSI_STRINGansiString;

//省略对ansiString的初始化

KdPrint(("%Z\n",&ansiString));//注意是大写的Z

打印UNICODE_STRING

UNICODE_STRINGunicodeString;

//省略对unicodeString的初始化

KdPrint(("%wZ",&unicodeString));//注意是小写的w和大写的Z

3.字符串的初始化与销毁

(1)方法一是使用DDK提供的相应的函数。

初始化ANSI_STRING字符串:VOID

RtlInitAnsiString(

INOUTPANSI_STRINGDestinationString,

INPCSZSourceString

);初始化UNICODE_STRING字符串VOID

RtlInitUnicodeString(

INOUTPUNICODE_STRINGDestinationString,

INPCWSTRSourceString

);使用方法(以ANSI_STRING为例):

ANSI_STRINGansiString;

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(

INOUTPSTRINGDestinationString,

INPSTRINGSourceStringOPTIONAL

);UNICODE_STRING字符串复制函数VOID

RtlCopyUnicodeString(

INOUTPUNICODE_STRINGDestinationString,

INPUNICODE_STRINGSourceString

);示例代码:

#pragmaINITCODE

voidTestCopy()

{

//初始化string1

UNICODE_STRINGstring1;

RtlInitUnicodeString(&string1,L"fuckzq");

//初始化string2

UNICODE_STRINGstring2;

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(

INPSTRINGString1,

INPSTRINGString2,

BOOLEANCaseInSensitive//是否对大小写敏感

);BOOLEAN

RtlEqualString(

INPSTRINGString1,

INPSTRINGString2,

INBOOLEANCaseInSensitive

);UNICODE_STRING比较函数LONG

RtlCompareUnicodeString(

INPUNICODE_STRINGString1,

INPUNICODE_STRINGString2,

INBOOLEANCaseInSensitive

);BOOLEAN

RtlEqualUnicodeString(

INCONSTUNICODE_STRING*String1,

INCONSTUNICODE_STRING*String2,

INBOOLEANCaseInSensitive

);示例代码:

#pragmaINITCODE

VOIDTestCmpSting()

{

UNICODE_STRINGstring1;

RtlInitUnicodeString(&string1,L"fuckyouzq");

UNICODE_STRINGstring2;

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(

INOUTPSTRINGDestinationString,

INPSTRINGSourceString

);UNICODE_STRING:NTSTATUS

RtlUpcaseUnicodeString(

INOUTPUNICODE_STRINGDestinationStringOPTIONAL,

INPCUNICODE_STRINGSourceString,

INBOOLEANAllocateDestinationString//是否为目的字符串分配内存

);注意:DDK虽然提供了转化成大写的函数,但是却没有提供转化为小写的函数。

示例代码:

#pragmaINITCODE

VOIDTestUpperString()

{

UNICODE_STRINGstring1;

RtlInitUnicodeString(&string1,L"HelloWorld");

KdPrint(("%wZ\n",&string1));

UNICODE_STRINGstring2;

//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(

INPUNICODE_STRINGString,//字符串

INULONGBaseOPTIONAL,//转换的数的进制

OUTPULONGValue//转换后的数字

);将整数转换成UNICODE_STRINGNTSTATUS

RtlIntegerToUnicodeString(

INULONGValue,

INULONGBaseOPTIONAL,

INOUTPUNICODE_STRINGString

);示例代码:

VOIDTestStringToInt()

{

UNICODE_STRINGstring1;

RtlInitUnicodeString(&string1,L"-100");

ULONGi;

NTSTATUSstatus=RtlUnicodeStringToInteger(&string1,10,&i);

if(!NT_SUCCESS(status))

{

KdPrint(("转换失败!\n"));

}

else

{

KdPrint(("%d",i));

}

UNICODE_STRINGstring2={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(

INOUTPANSI_STRINGDestinationString,

INPUNICODE_STRINGSourceString,

INBOOLEANAllocateDestinationString

);ANSI_STRING转为UNICODE_STRING字符串NTSTATUS

RtlAnsiStringToUnicodeString(

INOUTPUNICODE_STRINGDestinationString,

INPANSI_STRINGSourceString,

INBOOLEANAllocateDestinationString

);示例代码:

#pragmaINITCODE

VOIDTestStringToString()

{

UNICODE_STRINGunicodeString;

RtlInitUnicodeString(&unicodeString,L"fuckyou!\n");

ANSI_STRINGansiString;

NTSTATUSstatus=RtlUnicodeStringToAnsiString(&ansiString,&unicodeString,TRUE);//为ansiString分配内存

if(NT_SUCCESS(status))

{

KdPrint(("%Z",&ansiString));

}

//销毁ansiString

RtlFreeAnsiString(&ansiString);

}

更多驱动编程文章http://mzf2008.blog.163.com/blog/static/3559978620101112115510592/

相关推荐