Windows System Software -- Consulting, Training, Development -- Unique Expertise, Guaranteed Results

Home NTDEV
Before Posting...
Please check out the Community Guidelines in the Announcements and Administration Category.

More Info on Driver Writing and Debugging


The free OSR Learning Library has more than 50 articles on a wide variety of topics about writing and debugging device drivers and Minifilters. From introductory level to advanced. All the articles have been recently reviewed and updated, and are written using the clear and definitive style you've come to expect from OSR over the years.


Check out The OSR Learning Library at: https://www.osr.com/osr-learning-library/


When and how KeExpandKernelStackAndCalloutEx is expected to be used?

0xrepnz0xrepnz Member Posts: 33
edited September 7 in NTDEV

I'm aware that the kernel stack is very limited - Are there any guidelines for when I should expand the stack? Can you give me some examples of real use cases?
I guess that in most cases it's pretty hard to know when you should expand the stack... well, I guess that the guideline is something like: In paths that you think the stack space can be large, call IoGetRemainingStackSize() to check the bytes left and call KeExpandKernelStackAndCalloutEx if necessary... The question is: In which cases do you think this check is necessary?
Also, when I do expand the stack, can I reference memory from the previous stack segment or is it not guaranteed to be valid?

Thanks!

- Ori Damari

Comments

  • Scott_Noone_(OSR)Scott_Noone_(OSR) Administrator Posts: 3,343

    We usually only use this if we are calling outside our own driver. That's really the only case where you have no idea or control over how much stack will be used. For example, in Windows the file systems use this API before calling down to the lower layers of the storage branch.

    The previous stack segment will remain valid for the duration of this call.

    -scott
    OSR

  • 0xrepnz0xrepnz Member Posts: 33
    Yeah but you tell me every time you call ZwOpenProcess you do it through KeExpandStackCallout? ZwOpenProcess invokes callbacks of other drivers that may use stack space..
    - Ori Damari
  • Scott_Noone_(OSR)Scott_Noone_(OSR) Administrator Posts: 3,343

    If you were in an IOCTL handler for a control device and called ZwOpenProcess I'd be surprised if it overflowed the stack. It could happen, but it's mitigated by a) the stack is fairly fresh when you're called and b) the fact that the Ps callbacks are call out and not call through. Compare this to the I/O subsystem and the number of stack frames you can end up with before getting to the end of the line. From the storage branch of a test VM right now:

    1: kd> kc
    # Call Site
    00 storport!RaUnitScsiIrp
    01 storport!RaDriverScsiIrp
    02 nt!IopfCallDriver
    03 nt!IovCallDriver
    04 nt!IofCallDriver
    05 CLASSPNP!SubmitTransferPacket
    06 CLASSPNP!ServiceTransferRequest
    07 CLASSPNP!ClassReadWrite
    08 CLASSPNP!ClassGlobalDispatch
    09 nt!IopfCallDriver
    0a nt!IovCallDriver
    0b nt!IofCallDriver
    0c partmgr!PmWrite
    0d partmgr!PmGlobalDispatch
    0e nt!IopfCallDriver
    0f nt!IovCallDriver
    10 nt!IofCallDriver
    11 partmgr!PartitionIo
    12 partmgr!PartitionWrite
    13 partmgr!PmGlobalDispatch
    14 nt!IopfCallDriver
    15 nt!IovCallDriver
    16 nt!IofCallDriver
    17 volmgr!VmReadWrite
    18 nt!IopfCallDriver
    19 nt!IovCallDriver
    1a nt!IofCallDriver
    1b volume!VolumePassThrough
    1c nt!IopfCallDriver
    1d nt!IovCallDriver
    1e nt!IofCallDriver
    1f volsnap!VolsnapWriteFilter
    20 volsnap!VolSnapWrite
    21 nt!IopfCallDriver
    22 nt!IovCallDriver
    23 nt!IofCallDriver
    24 nt!ViFilterDispatchGeneric
    25 nt!IopfCallDriver
    26 nt!IovCallDriver
    27 nt!IofCallDriver
    28 Wdf01000!FxIoTarget::Send
    29 Wdf01000!imp_WdfRequestSend
    2a OsrFlt!WdfRequestSend
    2b OsrFlt!OsrFltUtilSendAndForgetRequest
    2c OsrFlt!OsrFltVolumeEvtIoWrite
    2d Wdf01000!FxIoQueueIoRead::Invoke
    2e Wdf01000!FxIoQueue::DispatchRequestToDriver
    2f Wdf01000!FxIoQueue::DispatchEvents
    30 Wdf01000!FxIoQueue::QueueRequest
    31 Wdf01000!FxPkgIo::DispatchStep2
    32 Wdf01000!FxPkgIo::DispatchStep1
    33 Wdf01000!FxPkgIo::Dispatch
    34 Wdf01000!DispatchWorker
    35 Wdf01000!FxDevice::Dispatch
    36 Wdf01000!FxDevice::DispatchWithLock
    37 nt!IopfCallDriver
    38 nt!IovCallDriver
    39 nt!IofCallDriver
    3a nt!ViFilterDispatchGeneric
    3b nt!IopfCallDriver
    3c nt!IovCallDriver
    3d nt!IofCallDriver
    3e Ntfs!NtfsStorageDriverCallout
    3f nt!KxSwitchKernelStackCallout
    40 nt!KiSwitchKernelStackContinue
    41 nt!KiExpandKernelStackAndCalloutOnStackSegment
    42 nt!KiExpandKernelStackAndCalloutSwitchStack
    43 nt!KeExpandKernelStackAndCalloutInternal
    44 nt!KeExpandKernelStackAndCalloutEx
    45 Ntfs!NtfsMultipleAsync
    46 Ntfs!NtfsNonCachedIo
    47 Ntfs!NtfsCommonWrite
    48 Ntfs!NtfsFsdWrite
    49 nt!IopfCallDriver
    4a nt!IovCallDriver
    4b nt!IofCallDriver
    4c FLTMGR!FltpLegacyProcessingAfterPreCallbacksCompleted
    4d FLTMGR!FltpDispatch
    4e nt!IopfCallDriver
    4f nt!IovCallDriver
    50 nt!IofCallDriver
    51 nt!IopSynchronousServiceTail
    52 nt!NtWriteFile

    If you were going to call ZwOpenProcess from within a filter here you might need the expand call because you have no idea how much stack is left.

    Usually you find out where you need this API by getting a crash (hopefully in testing but maybe at a customer site). In recent memory we've needed it around FltCreateFile calls (they can cause I/O) and a USB filter that sometimes generated I/O as a result of I/O.

    -scott
    OSR

  • 0xrepnz0xrepnz Member Posts: 33

    I see, thanks for answering.

    - Ori Damari
Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Upcoming OSR Seminars
OSR has suspended in-person seminars due to the Covid-19 outbreak. But, don't miss your training! Attend via the internet instead!
Internals & Software Drivers 30 Nov 2020 LIVE ONLINE
Writing WDF Drivers 7 Dec 2020 LIVE ONLINE
Developing Minifilters Early 2021 LIVE ONLINE