0

I'm trying to find the top (or base) of the stack in my callback function that is used in the Windows kernel. I thought to use IoGetInitialStack function for that, but unfortunately it's documentation states:

IRQL "<=APC_LEVEL"

I looked into it with a disassembler and all it seems to be doing in my copy of ntoskrnl is this:

enter image description here

Why are they limiting it to IRQL<=APC_LEVEL?

MikeF
  • 1,021
  • 9
  • 29
  • My guess is: Because the pointer to the stack is not guaranteed to be available on interrupts > APC_LEVEL. I.e. when a device interrupt kicks in, there might be no stack set up automatically. – Ctx Jul 18 '18 at 07:25
  • @Ctx: I might be going out on the limb here, but I don't think x86/64 CPU can get too far w/o a stack. – MikeF Jul 18 '18 at 07:30
  • @Ctx - current thread kernel stack always avaible of course - impossible run any code otherwise. and thread object itself always from notpaged pool - so formally we can call this api at any irql – RbMm Jul 18 '18 at 07:32
  • @RbMm: That's what I thought. Maybe a typo in the document. Btw, what's `gs:188h`? Is it `_ETHREAD` pointer? – MikeF Jul 18 '18 at 07:33
  • faster here can be mean that on dpc interrupt say thread can run on special dpc stack. different from it usual. as result return value of `IoGetInitialStack` lost sense. but formal we can call it – RbMm Jul 18 '18 at 07:34
  • @RbMm Who sets up the stack when the interrupt handler for an asynchronous device interrupt is called? – Ctx Jul 18 '18 at 07:34
  • @Ctx: For 64-bit long mode the new stack pointer `RSP` is taken from the `TSS` when an interrupt/exception is invoked. – MikeF Jul 18 '18 at 07:36
  • @Ctx - hardware interrupt of course begin on current kernel stack (where saved return address, flags) etc. then interrupt handler can switch stack for example. dpc (software interrupt) can switch (or not) to special stack. see also related - [`IoGetStackLimits`](https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/content/wdm/nf-wdm-iogetstacklimits) - *In Windows Server 2003 Service Pack 1 (SP1) and later versions of Windows, callers of IoGetStackLimits can be running at any IRQL. For earlier operating systems, the caller must be running at IRQL <= APC_LEVEL.* – RbMm Jul 18 '18 at 07:38
  • Yeah, `IoGetStackLimits` is OK to be called at any IRQL but the other one is not. Must be a typo. So @RbMm you're saying if the stack is switched by a DPC, then `IoGetInitialStack` will return the wrong result. If so, how would you recommend finding the current base of the stack in that case? – MikeF Jul 18 '18 at 07:42
  • the `IoGetInitialStack` will return correct result for current thread always. at this api can be called at any irql. but what you plan do next with return value ? say when DPC executed - system switch stack on special DPC stack - as result you can wrong interpret result of `IoGetStackLimits` – RbMm Jul 18 '18 at 07:45
  • http://www.osronline.com/article.cfm?article=529 or https://social.msdn.microsoft.com/Forums/en-US/ac41bbe8-39d4-4739-a009-7532d22b2cd4/dpc-stack-size-and-switch?forum=wdk – RbMm Jul 18 '18 at 07:48
  • @RbMm: I need to copy the "used" part of the stack "above" the `RSP` to be able to retrieve call stack functions later (from the passive level.) Or "walk the stack." But I need to know how much memory to copy from the stack. The idea was to `memcpy` it from `RSP` until the base address of the stack that I get from `IoGetInitialStack`. – MikeF Jul 18 '18 at 07:50

0 Answers0