【问题标题】:Accessing kernel memory from within the kernel given a pointer在给定指针的情况下从内核中访问内核内存
【发布时间】:2012-04-27 09:18:31
【问题描述】:

我正在尝试了解内核,并且一段时间以来一直在尝试打印构成内核环境的一些基本数据结构,但未成功。我的问题是,给定一个内存地址,我希望能够打印该地址的内容。

例如,我有一个确定 IDT 位置的函数。它按0xffff81b8c0000fff 的顺序返回(void *)。但是,每当我尝试printk 该地址的内容时,结果都是内核恐慌。我知道有一些保护措施可以防止从用户空间访问内核内存,但我试图从 start_kernel 中执行此操作,我认为它们是可读的。

代码是:

idt_ptr = sidt(); // returns (void *)
printk(KERN_INFO "680: IDT TABLE, FIRST ENTRY\n");
//entry is 64 bits
printk(KERN_INFO "680: %llx\n", *(unsigned long long *)idt_ptr);

这是在进行此尝试后发生的内核恐慌的结尾:

看来我需要一个信号量来进行读取访问,但这不只是一个任意地址吗?

【问题讨论】:

  • 根据我在操作系统开发方面的经验,您似乎正在触发页面错误。当您尝试访问不应该或不存在的分页内存时,就会发生这种情况。不幸的是,我不知道能说多少来帮助你。

标签: c linux memory kernel semaphore


【解决方案1】:

我建议让kdb 在内核内部四处探索。

尝试设置带有 kdb 补丁内核的 KVM 或 qemu VM。

【讨论】:

    【解决方案2】:

    例如,我有一个确定 IDT 位置的函数。它按 0xffff81b8c0000fff 的顺序返回 (void *)

    指向char* 以外的任何指针都不可能等于0x...ff——对于指向包含chars 以外的任何数据结构的指针,该地址未正确对齐。

    结论:您的sidt 函数已损坏并返回虚假地址。

    【讨论】:

    • 基于其他地址,我会说真实地址可能是0xffffffff81b8c000 - 0x0fff 很可能是 16 位 IDT 限制。 OP 应该注意sidt 操作码写入一个 10 字节的值,其中低两个字节是 16 位限制,高 8 个字节是地址。
    • 我担心可能是这种情况。我一直在尝试在用户空间中对其进行测试,但是因为无论如何我都无法访问内核内存,所以我无法判断我的地址是错误的还是无法访问其内容。 caf 说的很有道理,我会第一时间尝试并反馈。谢谢。
    猜你喜欢
    • 2014-07-21
    • 2011-12-15
    • 1970-01-01
    • 1970-01-01
    • 2013-10-02
    • 1970-01-01
    • 2016-06-03
    • 1970-01-01
    • 2018-06-30
    相关资源
    最近更新 更多