顾锦歌——发现生活的美!

文章 分类 标签
23 11 0

公告

此处是站点公告

Windows驱动字符串相关操作---补发

顾锦歌 2022-05-09 455 0条评论 默认分类

首页 / 正文

字符串本质上就是一段内存,之所以和内存使用分开讲,是因为内核里的字符串太有花样了,细数下来竟然有 4 种字符串!这四种字符串,分别是:CHAR、WCHAR、ANSI_STRING、UNICODE_STRING。当然,内核里使用频率最多的是 UNICODE_STRING,其次是 WCHAR,再次是 CHAR,而 ANSI_STRING,则几乎没见过有什么内核函数使用。

但其实这四种字符串也不是完全独立的,ANSI_STRING 可以看成是CHAR的安全性扩展,UNICODE_STRING 可以看成是 WCHAR的安全性扩展。CHAR,可以理解成 CHAR 数组,本质上来说是一个地址,它的有效长度是多少?不知道。字符串有多长?不清楚,遇到0 就当成是字符串的结尾。综上所述,CHAR的安全性是非常糟糕的,如果内核使用 CHAR作为主要字符串,那么会非常不稳定。WCHAR和 CHAR类似,和 CHAR的唯一不同在于一个WCHAR 占 2 个字节,而一个 CHAR 只占 1 个字节。所以,WCHAR*的安全性也是非常糟糕的。微软为了安全性着想,推出了这两种字符串的扩展集,ANSI_STRING和UNICODE_STRING。ANSI_STRING 和 UNICODE_STRING 都是结构体。定义如下:

typedef struct _ANSI_STRING {
 USHORT Length;
 USHORT MaximumLength;
 PCHAR Buffer;
} ANSI_STRING, *PANSI_STRING;
typedef struct _UNICODE_STRING {
 USHORT Length;
 USHORT MaximumLength;
 PWCHAR Buffer;
} UNICODE_STRING, *PUNICODE_STRING;

可以看到,ANSI_STRING 和 UNICODE_STRING 的结构体大小是一样的,唯一不同在于第三个成员,他们分别对应 CHAR和 WCHAR。它们的第一和第二个成员分别代表字符串的长度和内存的有效长度。比如 BUFFER 的长度是 260 字节,而 BUFFER 只是一个单词”FUCK”,则 ANSI_STRING 的 Length=4 、 MaximumLength=260 ; UNICODE_STRING 的 Length=8 、MaximumLength=260。另外需要注意的是,CHAR和 WCHAR都是以 0 结尾的(CHAR以 1个0 结尾,WCHAR以 2 个0 结尾),但 ANSI_STRING 和 UNICODE_STRING 不一定以 0 结尾。因为有了长度的说明,就不需要用特殊标识符来表示结尾了。有些自以为是的人直接把ANSI_STRING 或 UNICODE_STRING 的 BUFFER 当作字符串用,是极端错误的。

下面是一些字符串常规操作
1.字符串初始化、2.字符串拷贝、3.字符串比较、4.字符串变大写、5.字符串与整型相
互转化、6. ANSI_STRING 字符串与 UNICODE_STRING 字符串相互转换。

//1.字符串初始化
VOID StringInitTest() 
{
//(1)用 RtlInitAnsiString 初始化字符串
ANSI_STRING AnsiString1;
CHAR * string1= "hello";
//初始化 ANSI_STRING 字符串
RtlInitAnsiString(&AnsiString1,string1);
KdPrint(("AnsiString1:%Z\n",&AnsiString1));//打印 hello
string1[0]='H';
string1[1]='E';
string1[2]='L';
string1[3]='L';
string1[4]='O';
//改变 string1,AnsiString1 同样会导致变化
KdPrint(("AnsiString1:%Z\n",&AnsiString1));//打印 HELLO
//(2)程序员自己初始化字符串
#define BUFFER_SIZE 1024
UNICODE_STRING UnicodeString1 = {0};
//设置缓冲区大小
UnicodeString1.MaximumLength = BUFFER_SIZE;
//分配内存
UnicodeString1.Buffer = (PWSTR)ExAllocatePool(PagedPool,BUFFER_SIZE);
WCHAR* wideString = L"hello";
//设置字符长度,因为是宽字符,所以是字符长度的 2 倍
UnicodeString1.Length = 2*wcslen(wideString);
//保证缓冲区足够大,否则程序终止
ASSERT(UnicodeString1.MaximumLength>=UnicodeString1.Length);
//内存拷贝,
RtlCopyMemory(UnicodeString1.Buffer,wideString,UnicodeString1.Length);
//设置字符长度
UnicodeString1.Length = 2*wcslen(wideString);
KdPrint(("UnicodeString:%wZ\n",&UnicodeString1));
//清理内存
ExFreePool(UnicodeString1.Buffer);
UnicodeString1.Buffer = NULL;
UnicodeString1.Length = UnicodeString1.MaximumLength = 0;
}

//2.字符串拷贝
VOID StringCopyTest() 
{
//初始化 UnicodeString1
UNICODE_STRING UnicodeString1;
RtlInitUnicodeString(&UnicodeString1,L"Hello World");
//初始化 UnicodeString2
UNICODE_STRING UnicodeString2={0};
UnicodeString2.Buffer = (PWSTR)ExAllocatePool(PagedPool,BUFFER_SIZE);
UnicodeString2.MaximumLength = BUFFER_SIZE;
//将初始化 UnicodeString2 拷贝到 UnicodeString1
RtlCopyUnicodeString(&UnicodeString2,&UnicodeString1);
//分别显示 UnicodeString1 和 UnicodeString2
KdPrint(("UnicodeString1:%wZ\n",&UnicodeString1));
KdPrint(("UnicodeString2:%wZ\n",&UnicodeString2));
//销毁 UnicodeString2
//注意!!UnicodeString1 不用销毁
RtlFreeUnicodeString(&UnicodeString2);
}

//3.字符串比较
VOID StringCompareTest() 
{
//初始化 UnicodeString1
UNICODE_STRING UnicodeString1;
RtlInitUnicodeString(&UnicodeString1,L"Hello World");
//初始化 UnicodeString2
UNICODE_STRING UnicodeString2;
RtlInitUnicodeString(&UnicodeString1,L"Hello");
if (RtlEqualUnicodeString(&UnicodeString1,&UnicodeString2,TRUE))
KdPrint(("UnicodeString1 and UnicodeString2 are equal\n"));
else
KdPrint(("UnicodeString1 and UnicodeString2 are NOT equal\n"));
}

//4.字符串变大写
VOID StringToUpperTest() 
{
//初始化 UnicodeString1
UNICODE_STRING UnicodeString1;
UNICODE_STRING UnicodeString2;
RtlInitUnicodeString(&UnicodeString1,L"Hello World");
//变化前
DbgPrint("UnicodeString1:%wZ\n",&UnicodeString1);
//变大写
RtlUpcaseUnicodeString(&UnicodeString2,&UnicodeString1,TRUE);
//变化后
DbgPrint("UnicodeString2:%wZ\n",&UnicodeString2);
//销毁 UnicodeString2(UnicodeString1 不用销毁)
RtlFreeUnicodeString(&UnicodeString2);
}

//5.字符串与整型相互转化
VOID StringToIntegerTest() 
{
//(1)字符串转换成数字
//初始化 UnicodeString1
UNICODE_STRING UnicodeString1;
RtlInitUnicodeString(&UnicodeString1,L"-100");
ULONG lNumber;
NTSTATUS nStatus = RtlUnicodeStringToInteger(&UnicodeString1,10,&lNumber);
if ( NT_SUCCESS(nStatus))
{
KdPrint(("Conver to integer succussfully!\n"));
KdPrint(("Result:%d\n",lNumber));
}
else
{
KdPrint(("Conver to integer unsuccessfully!\n"));
}
//(2)数字转换成字符串
//初始化 UnicodeString2
UNICODE_STRING UnicodeString2={0};
UnicodeString2.Buffer = (PWSTR)ExAllocatePool(PagedPool,BUFFER_SIZE);
UnicodeString2.MaximumLength = BUFFER_SIZE;
nStatus = RtlIntegerToUnicodeString(200,10,&UnicodeString2);
if ( NT_SUCCESS(nStatus))
{
KdPrint(("Conver to string succussfully!\n"));
KdPrint(("Result:%wZ\n",&UnicodeString2));
}
else
{
KdPrint(("Conver to string unsuccessfully!\n"));
}
//销毁 UnicodeString2
//注意!!UnicodeString1 不用销毁
RtlFreeUnicodeString(&UnicodeString2);
}


//6. ANSI_STRING 字符串与 UNICODE_STRING 字符串相互转换
VOID StringConverTest() 
{
//(1)将 UNICODE_STRING 字符串转换成 ANSI_STRING 字符串
//初始化 UnicodeString1
UNICODE_STRING UnicodeString1;
RtlInitUnicodeString(&UnicodeString1,L"Hello World");
ANSI_STRING AnsiString1;
NTSTATUS nStatus = RtlUnicodeStringToAnsiString(&AnsiString1,&UnicodeString1,TRUE);
if ( NT_SUCCESS(nStatus))
{
KdPrint(("Conver succussfully!\n"));
KdPrint(("Result:%Z\n",&AnsiString1));
}
else
{
KdPrint(("Conver unsuccessfully!\n"));
}
//销毁 AnsiString1
RtlFreeAnsiString(&AnsiString1);
//(2)将 ANSI_STRING 字符串转换成 UNICODE_STRING 字符串
//初始化 AnsiString2
ANSI_STRING AnsiString2;
RtlInitString(&AnsiString2,"Hello World");
UNICODE_STRING UnicodeString2;
nStatus = RtlAnsiStringToUnicodeString(&UnicodeString2,&AnsiString2,TRUE);
if ( NT_SUCCESS(nStatus))
{
KdPrint(("Conver succussfully!\n"));
KdPrint(("Result:%wZ\n",&UnicodeString2));
}
else
{
KdPrint(("Conver unsuccessfully!\n"));
}
//销毁 UnicodeString2
RtlFreeUnicodeString(&UnicodeString2);
}

//UNICODE_STRINGz 转换为 CHAR*
//输入 UNICODE_STRING 的指针,输出窄字符串,BUFFER 需要已经分配好空间
VOID UnicodeToChar(PUNICODE_STRING dst, char *src)
{
ANSI_STRING string;
RtlUnicodeStringToAnsiString(&string,dst, TRUE);
strcpy(src,string.Buffer);
RtlFreeAnsiString(&string);
}


//WCHAR*转换为 CHAR*
//输入宽字符串首地址,输出窄字符串,BUFFER 需要已经分配好空间
VOID WcharToChar(PWCHAR src, PCHAR dst)
{
UNICODE_STRING uString;
ANSI_STRING aString;
RtlInitUnicodeString(&uString,src);
RtlUnicodeStringToAnsiString(&aString,&uString,TRUE);
strcpy(dst,aString.Buffer);
RtlFreeAnsiString(&aString);
}

//CHAR*转 WCHAR*
//输入窄字符串首地址,输出宽字符串,BUFFER 需要已经分配好空间
VOID CharToWchar(PCHAR src, PWCHAR dst)
{
UNICODE_STRING uString;
ANSI_STRING aString;
RtlInitAnsiString(&aString,src);
RtlAnsiStringToUnicodeString(&uString,&aString,TRUE);
wcscpy(dst,uString.Buffer);
RtlFreeUnicodeString(&uString);
}

评论(0)

当前没有评论,还不快来留下第一个脚印吧

热门文章

最新评论

  • Jacob Hankinson

    Your go-to source for leads. We can provide business to business and business to consumer leads, custom-tailored to your needs. CustomDatabases.org

  • Otilia Drechsler

    Hi, It is with sad regret to inform you TopDataList.com is shutting down. We are ceasing operations on TopDataList.com and have made our leads available at a $149 once off fee. Visit us on TopDataList.com Regards, Otilia

  • Ervin Quinn

    Hello, from CustomData.click we are a provider of unique databases that could help your business. Please visit us at CustomData.click to see if we can help you. Regards, Ervin

  • Keri Cardus

    Hello. It is with sad regret to inform you TopDataList.com is shutting down. We have made all our databases available for you for a once off fee. Visit us on TopDataList.com

  • Beth Steele

    ZippyLeads.org is running an easter special till the 18th of April. Get all the leads you need for your company with our easter special.

  • Johan Fourie

    Hello. My name is Johan Fourie and I am looking to sell DataList.biz. We are a data company that has been in the industry for 12 years. We do around $170k/year in revenue. 1) I am looking to sell 50% of the business for $5k. 2) It would be helpful if you are knowledgeable about the Data Business. 3) I am looking for someone that is willing to take over administration, support, client relations. 4) I will continue to do the marketing for new products. 5) You will accept all future income and pay me from it. Please contact me on WhatsApp +27 72 280 1952 or my personal email: johanfourieinc@gmail.com if you are interested in this and we can have a call. Regards, Johan Fourie

  • Pam Using

    Hi, I am interested in some of your products. Please give me a call on +1 304-873-4360

  • Typecho

    欢迎加入 Typecho 大家族

日历

2025年01月

   1234
567891011
12131415161718
19202122232425
262728293031 

标签云

文章目录

推荐关键字:

上一张 下一张