1

I'm trying my driver with Driver Verifier turned on in Windows 7 x64, and get IRQL_NOT_LESS_OR_EQUAL(0A) bugcheck. From analyze -v info, it seems that the memory page of RtlAnsiCharToUnicodeChar function gets paged out, so calling that function causes bugcheck 0A . RtlAnsiCharToUnicodeChar is an ntoskrnl.exe exported function. Can it really be paged out? If so, how can I prevent it?

On spot debug info screen shot below:

enter image description here

enter image description here

Jimm Chen
  • 3,411
  • 3
  • 35
  • 59
  • Would be so much more searchable for search engines if you pasted the contents of the WinDbg window instead of a screenshot. – 0xC0000022L Dec 01 '16 at 00:09

2 Answers2

4

yes. of course - very many ntoskrnl routines in PAGE* section. RtlAnsiCharToUnicodeChar also paged - read in documentation:

IRQL <= APC_LEVEL

also read about DbgPrintEx routine

DbgPrint and DbgPrintEx can be called at IRQL<=DIRQL. However, Unicode format codes (%wc and %ws) can be used only at IRQL = PASSIVE_LEVEL.

and

However, the Unicode format codes (%C, %S, %lc, %ls, %wc, %ws, and %wZ) can only be used with IRQL = PASSIVE_LEVEL.

so if you not use Unicode format you can use DbgPrint or KdPrint(this is macro) at any IRQL but if you use Unicode format - only on PASSIVE_LEVEL or APC_LEVEL (about APC_LEVEL i say by self)

RbMm
  • 31,280
  • 3
  • 35
  • 56
  • IIRC this wasn't always the case, but I may be wrong. IIRC earlier Windows versions had the whole kernel in NonPagedPool. Also, a routine requiring a particular IRQL has no bearing on where the function is located in the kernel image. The IRQL requirement is based, among other things, on the access to data structures. For example the Unicode upcase table is in paged pool, so there you have a reason for the requirements you cited. – 0xC0000022L Dec 01 '16 at 00:07
  • @0xC0000022L - how minimum from xp (almost sure that in win200 also but cannot check) - large amoutt of code in ntoskrnl.exe in `PAGE*` sections. and if function located in `PAGE*` section - it already can be called only IRQL <= APC_LEVEL . – RbMm Dec 01 '16 at 00:17
  • @RbMm ntoskrnl.exe also uses large pages, so it uses a whole page directory to refer to one page – Lewis Kelsey Mar 23 '21 at 17:13
  • specifically, on my Windows 7 right now there are there are 4 large pages that contain ntoskrnl.exe and hal.dll, starting at `FFFFF80003600000` to `FFFFF80003C00000` – Lewis Kelsey Mar 23 '21 at 20:39
  • @LewisKelsey - yes, sometime part of ntoskrnl.exe can use large pages. but how this related to question and answer ? – RbMm Mar 23 '21 at 20:43
  • @RbMm because I don't think that windows pages out large pages – Lewis Kelsey Mar 23 '21 at 20:46
  • @LewisKelsey - yes, windows never pages out large pages. but how i say, even if ntoskrnl.exe used large pages - this not mean that all image in this large pages. part of it anyway in paged memory. in concrete case clear visible crash reason. and this is documented (about dbgprint) – RbMm Mar 23 '21 at 20:48
  • @RbMm the entirety of ntoskrnl.exe is in large pages. There is a discussion about it here: https://community.osr.com/discussion/162293/safe-kernel-memory-access-am-i-crazy-or-is-windows but I don't quite understand the reason for mapping it with large pages, and this means that the fine grain protections on PAGE, PAGELK etc no longer apply. I'm trying to work it out – Lewis Kelsey Mar 23 '21 at 21:19
  • @LewisKelsey- this not true. not always large pages used at all. in concrete case clear visible that crash was on **execute** `RtlAnsiCharToUnicodeChar`. are you view screen from debugger and analyze it ? the `RtlAnsiCharToUnicodeChar` is paged out - how you can explain this ? – RbMm Mar 23 '21 at 21:29
  • well. I found it. It's because when you have driver verifier enabled, large pages are disabled. It's mentioned in the bible itself.. windows internals 6 part 2. Otherwise, large pages are used as a TLB space optimisation for those frequently accessed images – Lewis Kelsey Mar 23 '21 at 21:47
  • 1
    @LewisKelsey - not only in case when driver verifier active. i not view it in stack trace and think that it not active in concrete case. i think large pages not always used at all. can not say now when it used and when no. anyway - what you try prove ? – RbMm Mar 23 '21 at 21:53
1

You can try to use the MmLockPagableCodeSection on that specific routine to prevent it being paged out, however it's probably not advisable (and you don't know what dependencies it has, if they're located in pagable sections as well). In any case, make sure you read the documentation thoroughly.

A better approach is to run at Passive/APC level in the first place before invoking the printing function - e.g., by scheduling work item (you can also force lowering the IRQL with KeLowerIrql function but it's not advisable by MSFT).

SomeWittyUsername
  • 18,025
  • 3
  • 42
  • 85