我正在尝试使用内联汇编从cpu控制寄存器中读取数据。我最初的目标是x86-64。我不熟悉c或汇编,但我设法做了如下非常简单的尝试:
#include <stdio.h>
#include <stdint.h>
int main() {
uint64_t result;
asm ("movq %%cr4, %0;"
: "=r" (result) ::
);
printf("result: %d \n", result);
return 0;
}
这会编译但在gdb中抛出运行时错误:
Thread 1 received signal SIGILL, Illegal instruction.
main () at main.c:6
6 asm ("movq %%cr4, %0;"
我认为c /汇编是正确的,因为我能够从其他寄存器中提取值。我认为这个错误是因为我没有在内核模式下运行(基于我读过的内容),但是我不完全理解它的含义以及我对c的有限理解/ assembly我不确定我是否应该使用内核模式。
在内核模式之外还有其他方法吗?例如,通过暴露的dll调用可以获得此信息。
我欢迎任何关于在内核模式下运行应用程序的含义的评论。
答案 0 :(得分:4)
更新:根据this comment,此答案不适用于CR寄存器。
您正在寻找的是所谓的'WinRing0.sys'驱动程序,该驱动程序公开了一个API,允许您从用户模式中读取所有仅适用于内核(环0)代码的各种有趣的MSR。
这是一个开源组件,但最重要的是有人已付费签署驱动程序,因此可以在Windows中加载(作为个人,即使您愿意,也几乎不可能签署当前的Windows驱动程序支付)。您可以找到32位和64位(WinRing0x64.sys)二进制文件here。
this answer中提供了更多详细信息 - 关于编程性能计数器的问题,但所需的访问权限是相同的,WinRing0.sys将适用于两种用例。