Windows内核--Rtl字符串API “不同IRQL“(3.2)

        本文将从最简单的rtl例程函数讲解不同IRQL的真正原因,其他IRQL类似。

        RtlCopyUnicodeString和RtlEqualUnicodeString看起来同属于rtl支持字符串例程,实际上它们可运行的IRQL还是不同的。这也许很不可思议,通过源代码解开其中的秘密。

二者IRQL不同

        RtlCopyUnicodeString

                

        RtlEqualUnicodeString 

                 

官方注解

        

NTSYSAPI VOID RtlCopyUnicodeString(
  [in, out]      PUNICODE_STRING  DestinationString,
  [in, optional] PCUNICODE_STRING SourceString
);

 

        >   1. Src是optional, 如果为NULL, 那么只需要把Dest的Length设置为0即可。

             2. 不管Src有多长,Dest的MaximumLength和Buffer都不会被改变。

             3. 和普通String或Memory copy类似,拷贝长度不会超过Src和Dest的MaximumLength.

             4. 最重要的一点,它指出,如果是DPC Level, Src和Dest都必须是非分页内存。当然,也 暗示了如果是DPC Level以下,Src和Dest可以是分页内存。

NTSYSAPI BOOLEAN RtlEqualUnicodeString(
  [in] PCUNICODE_STRING String1,
  [in] PCUNICODE_STRING String2,
  [in] BOOLEAN          CaseInSensitive
);

         

源代码解析

        

  • Src如果为空,直接设置Dest长度为0.

  • ASSERT_WELL_FORMED_UNICODE_STRING_IN检测字符长度是2的倍数。

  • 判断Src的长度如果大于Dest的最大长度,选择较小的那个。

  • RtlCopyMemory执行真正的拷贝动作。

  • 如果Dest的Length加上末尾的UNICODE_NULL不超过MaximumLength, 加上UNICODE_NULL.

  • 最后ASSERT_WELL_FORMED_UNICODE_STRING_OUT再次判断Dest的MaximumLength是2的倍数且Length不超过MaximumLength.

总结一下,源代码的实现和如上官方文档完全对上。因为函数会直接操作Src和Dest内存,和官方解释第四条对上: 把责任推给了调用者。

RtlEqualUnicodeString 调用RTL_PAGED_CODE(PAGED_CODE)

        此约束保证只能在PASSIVE_LEVEL执行。

         看起来功能就是普通比较字符串或内存是否相等,并不复杂的样子,为什么内核要约束它只能在PASSIVE_LEVEL执行呢?

       

        如果是大小写敏感,调用NLS_UPCASE.

                

                 Nls844UnicodeUpcaseTable变量被定义成分页内存的数据!! 这才是导致

                 RtlEqualUnicodeString为什么必须在PASSIVE_LEVEL的根本原因。

                         

内核为什么要用不同IRQL?

        对于ASCII码表,很小,几百字节,UNICODE表会大很多。内核不希望UNICODE表一直占用常驻内存,会降低可用内存,设计成可分页内存可节省内存开支。

        当然,对于String操作例程,还有很多,都可以通过源代码了解官网对应内核API的解释。

        

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值