我的印象是 x86 上的“int”指令没有特权。所以,我认为我们应该能够从用户空间应用程序执行这条指令。但似乎并非如此。
我正在尝试从 Windows 上的用户应用程序执行 int 。我知道这样做可能不对。但我想找点乐子。但是 Windows 正在杀死我的应用程序。
我认为问题是由于条件 cpl <=iopl。有谁知道如何解决它?
通常,用于用户模式代码转换到内核模式以调用内核服务的旧调度程序机制是由int 2Eh
(现在替换为sysenter
)实现的。直到int 3
今天仍然保留断点。
基本上,内核为某些中断设置陷阱(不记得是否全部),并且根据陷阱代码,它们将为用户模式调用程序执行一些服务,或者如果这不可能,您的应用程序将被杀死,因为它尝试特权操作。
无论如何,细节将取决于您尝试调用的确切中断。例如,函数DbgBreakPoint
( ntdll.dll
) 和DebugBreak
( ) 除了调用(或实际上是特定的操作码)kernel32.dll
之外什么都不做。int 3
int3
编辑 1:在较新的 Windows 版本(XP SP2 和更新的 IIRC)上,正如我在回答中所写的那样sysenter
替换。int 2Eh
它被终止的一个可能原因——尽管你应该能够通过异常处理来捕捉它——是因为你没有传递它期望在堆栈上的参数。基本上,本机 API 的用户模式部分将您调用的系统服务的参数放入堆栈,然后将服务编号(系统服务调度程序表的索引 - SSDT,有时是 SDT)放入特定寄存器,然后调用在较新的系统sysenter
和较旧的系统上int 2Eh
。
给定中断向量的最小环级别(它决定给定的“int”是否具有特权)基于与中断描述符表中的向量关联的环级别描述符。
在 Windows 中,大多数中断都是特权指令。这可以防止用户模式仅仅调用双重故障处理程序来立即对操作系统进行错误检查。
Windows 中有一些非特权中断。具体来说:
所有其他中断都是特权的,调用它们会导致发出“无效指令”中断。
INT 是“特权控制”指令。内核必须以这种方式保护自己免受用户模式的影响。INT 经历与硬件中断和处理器异常经历完全相同的陷阱向量,因此如果用户模式可以任意触发这些异常,中断调度代码就会混淆。
如果要在 Windows 尚未设置的特定向量上触发中断,则必须使用调试器或内核驱动程序修改该中断向量的 IDT 条目。Patchguard 不允许您从 x64 版本的 Windows 上的驱动程序执行此操作。