Windows: avoid pushing full x86 context on stack

萝らか妹 提交于 2019-11-27 20:42:21

Basically you would need to re-implement many interrupt handlers, i.e. hook yourself into the Interrupt Descriptor Table (IDT). The problem is, that you would also need to re-implement a kernelmode -> usermode callback (for SEH this callback resides in ntdll.dll and is named KiuserExceptionDispatcher, this triggers all the SEH logic). The point is, that the rest of the system relies upon SEH working the way it does right now, and your solution would break things because you were doing it system wide. Maybe you could check in which process you are at the time of the interrupt. However, the overall concept is prone to errors and very badly affects system stability imho.
These are actually rootkit-like techniques.

Edit:
Some more details: the reason why you would need to re-implement interrupt handlers is, that exceptions (e.g. divide by zero) are essentially software interrupts and those always go through the IDT. When the exception has been thrown, the kernel collects the context and signals the exception back to usermode (through the aforementioned KiUserExceptionDispatcher in ntdll). You'd need to interfere at this point and therefore you would also need to provide a mechanism to get back to user mode. (There is a function in ntdll which is used as the entry point from kernel mode - I don't remember the name but its something with KiUserACP.....)

Seva Alekseyev

Consider decoupling the parameter/local stack from the real one. Use another register (e. g. EBP) as the effective stack pointer, leave the ESP-based stack the way Windows wants it.

You can't use PUSH/POP anymore. You'd have to use SUB/MOV/MOV/MOV combo instead of PUSH. But hey, beats patching the OS.

If Windows uses x86 hardware to implement their trap code, you need ring 0 access (via driver or API) to change which gate is used for traps.

The x86 concept of gate points one of:

  • an interrupt address (code segment + offset pointer) which is called while the whole register context, including return address, is pushed on current stack (=current esp), or
  • a task descriptor, which switches to another task (can be looked upon as hardware-supported thread). All relevant data is pushed to the stack (esp) of that task instead.

You ofcourse want the latter. I would have looked at how Wine implemented it, that might prove more effective than asking google.

My guess is that you unfortunately need to implement a driver to get it working on x86, and according to Wikipedia it is impossible for drivers to change it on IA64 plattform. The second best option might be to interleave space in your stacks, so that a context push from a trap always fits?

I ran out of space in the comment box...

Anyways I'm not sure where the vector points, I was basing the comment off of SDD's answer and mention of "KiUserExceptionDispatcher"... except upon further searching (http://www.nynaeve.net/?p=201) it looks like at this point it might be too late.

SIDT can be executed in ring 3... this will reveal the contents of the interrupt table, and you may be able to load the segment and at least read the contents of the table. With any luck you can then read the entry for (for example) vector 0/divide by zero, and read the contents of the handler.

At this point I'd try to match hex bytes to match the code with a system file, but there may be a better way to determine which file the code belongs to (it's not necessarily a DLL, it could be win32k.sys, or it could be dynamically generated, who knows). I don't know if there's a way dump the physical memory layout from user-mode.

If all else fails, you could either set up a kernel-mode debugger or emulate Windows (Bochs), where you can view the interrupt tables and memory layout directly. Then you could trace until the point the CONTEXT is pushed, and look for an opportunity to gain control before that happens.

Windows exception handling is called SEH. IIRC you can disable it, but the runtime of the language you are using might not like it.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!