什么是特权指令?

问题描述 投票:0回答:10

我添加了一些可以干净编译的代码,并且刚刚收到此 Windows 错误:

---------------------------
(MonTel Administrator) 2.12.7: MtAdmin.exe - Application Error
---------------------------
The exception Privileged instruction.

 (0xc0000096) occurred in the application at location 0x00486752.

我即将开始寻找错误,我预计我所做的事情会很愚蠢,而恰好会产生此消息。该代码编译干净,没有错误或警告。 EXE 文件的大小已增长到 1,454,132 字节,并包含指向

ODCS.lib
的链接,但它是 Win32 API 的纯 C 语言,并且启用了 DEBUG(在 Windows 2000 的 P4 上运行)。

c winapi debugging odbc
10个回答
40
投票

为了回答这个问题,特权指令是只能在“管理程序”(或 Ring-0)模式下执行的处理器操作码(汇编指令)。 这些类型的指令往往用于从 Windows 内核访问 I/O 设备和受保护的数据结构。

常规程序在“用户模式”(Ring-3)下执行,不允许直接访问 I/O 设备等...

正如其他人提到的,原因可能是堆栈损坏或函数指针调用混乱。


7
投票

这种情况通常发生在使用指向无效数据的函数指针时。 如果您的代码破坏了返回堆栈,也可能会发生这种情况。有时追踪此类错误可能非常棘手,因为它们通常很难重现。


7
投票

特权指令是IA-32指令,只允许在Ring-0(即内核模式)下执行。如果您在用户空间中遇到此问题,那么您要么得到了一个非常旧的 EXE,要么得到了损坏的二进制文件。


7
投票

正如我所怀疑的那样,我做了一些愚蠢的事情。我想我解决这个问题的速度是原来的两倍,因为上面消息中评论中的一些线索。感谢那些人,特别是那些指出应用程序早期覆盖堆栈的内容的人。实际上,我在这里发现了几个答案,比我标记为回答问题的帖子更有用,因为他们为我提供了线索并让我排队去哪里查看,尽管我认为它最好地总结了答案。

事实证明,我刚刚添加了一个按钮,该按钮超出了保存一些工具栏按钮信息(位于堆栈上)的数组的最大大小。我都忘记了

#定义 MAX_NUM_TOOBAR_BUTTONS (24)

甚至存在!


4
投票

我能想到的第一个可能性是,您可能正在使用本地数组,并且它位于函数声明的顶部附近。你的边界检查变得疯狂并覆盖返回地址,它指向一些只允许内核执行的指令。


2
投票

错误位置 0x00486752 对我来说似乎非常小,在可执行代码通常所在的位置之前。我同意丹尼尔的观点,这对我来说看起来像是一个狂野的指针。


2
投票

我在 2000 年用 Visual c++ 6.0 看到了这个。

调试 C++ 库在异常处理程序中调用了物理 I/O 指令。 如果我没记错的话,它会将状态转储到曾经用于 DMA 基址寄存器的 I/O 端口,我假设 Microsoft 的某个人将其用于调试器卡。

查找某些可能潜在导致诊断代码运行的错误情况。

我正在调试、回溯并阅读反汇编。处理时出现异常

std::string
,可能是索引超出了末尾。


2
投票

过去15年制造的大多数处理器的CPU都有一些非常强大的特殊指令。这些特权指令是为操作系统内核应用程序保留的,不能被用户编写的程序使用。

这限制了用户编写的程序对系统造成的损害,并减少了系统实际崩溃的次数。


2
投票

在内核模式下执行时,操作系统可以不受限制地访问内核和用户程序的内存。

基址和限制寄存器的加载指令是特权指令。


0
投票

我也有同样的问题。我正在将代码从 XE3 移植到 10.2

它适用于同一台机器上的 XE 版本。

© www.soinside.com 2019 - 2024. All rights reserved.