How can I start a user-mode stack trace when in kernel-mode? What I need is a single value of EIP. In fact, I need to know either a place where the user requested a kernel service or a place they will continue execution (if there is a case they differ).
My function will be an Irp-handler in a non-arbitrary thread context, so I know such information must be available.
Of course, documented approaches are preferable, but not the only ones I would be pleased with.
I know this question had been asked here back in 2004, but the questioner got no real answer apart from “do your homework” or “stop wasting your time on something you are not likely to got to work”.
Looking forward to helpful replies,
Michal Zientkiewicz
> the questioner got no real answer apart from “do your homework” or "stop wasting your time on
something you are not likely to got to work".
Actually, the questioner did get a right answer, i.e. the one that is mentioned above - you just cannot get to the user-mode stack from IRP handler. Period. By the time execution reaches your driver, all information about the user-mode stack is lost to everyone, apart from the system
(the system saves it in its internal structures so that it can restore the stack before the return to the user mode is made).
To summarize, just stop thinking about the whole thing - it is not going to lead you anywhere…
Anton Bassov
mike_phsx@wp.pl wrote:
I know this question had been asked here back in 2004, but the questioner got no real answer apart from “do your homework” or “stop wasting your time on something you are not likely to get to work”.
Well asking the more obvious question: What are you hoping to achieve in
a wider sense?
Clearly there is a problem X where you think the solution is to find the
user mode return address. What is X?
MH.
If you are using the return address on the stack as a form of security (e.g. a “trusted” caller based on who made the I/O call), this can be easily spoofed and circumvented and is no way to guarantee that the caller is trusted. See these links for more info
http://blogs.msdn.com/oldnewthing/archive/2004/01/01/47042.aspx
http://blogs.msdn.com/oldnewthing/archive/2006/08/17/704232.aspx
d
-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of mike_phsx@wp.pl
Sent: Tuesday, October 23, 2007 5:00 AM
To: Windows System Software Devs Interest List
Subject: [ntdev] User-mode stack trace from kernel
How can I start a user-mode stack trace when in kernel-mode? What I need is a single value of EIP. In fact, I need to know either a place where the user requested a kernel service or a place they will continue execution (if there is a case they differ).
My function will be an Irp-handler in a non-arbitrary thread context, so I know such information must be available.
Of course, documented approaches are preferable, but not the only ones I would be pleased with.
I know this question had been asked here back in 2004, but the questioner got no real answer apart from “do your homework” or “stop wasting your time on something you are not likely to got to work”.
Looking forward to helpful replies,
Michal Zientkiewicz
NTDEV is sponsored by OSR
For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars
To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer
So, to summarize:
- the return address to UserMode is heavily undocumented
- the only thing I could check about the user mode caller is the topmost function that issued the syscall/sysenter/int2e - the rest of the stack can be spoofed (at least to some level, while I can only go one level above the system libraries which deal nicely with EBP).
In fact, checking where the trap was would be nice, but there are very few viruses that do I/O this way (I only saw one and it was quite old).
Thanks for the answers anyway - I think they saved me some time.
> - the return address to UserMode is heavily undocumented
Correct. There are only 3 type of drivers (“unsupported”, of course) that get directly to the user stack:
-
The ones that hook interrupt/exception handlers. If we assume that it is user-mode and not kernel-mode code that gets interrupted, then user-mode EIP is on top of the stack and user-mode ESP is 12 bytes below it at the moment your function that hooks interrupt/exception handler enters execution
-
The ones that hook SSDT - they can arrive to the user-mode ESP( and, hence the return address) via EDX register, because, upon system calls, EDX points to location on the user-mode stack where function paramters are located
-
The ones that don’t mind dealing with internals kernel structures, i.e. ETHREAD and friends - as long as a call is made in context of the actual client thread (for example, IRP_MJ_CREATE), they can arrive to the user-mode stack by examining these structures.
This is how drivers can get to the user-mode stack. It is understandable that all “proper” drivers cannot do it, because they are not going to do any of the above mentioned tricks…
Anton Bassov
Well, going through ETHREAD would not be THAT bad after all - the only problem (and a big problem it is) would be inability to run the driver in untested environment. Since this is not going to be the most crucial functionality my driver provides, I could disable it when i don’t know the system OR when traversing the structures leads to exception OR when ProbeForRead fails on the returned stack pointer.