【发布时间】:2012-12-25 05:55:34
【问题描述】:
由于我缺乏 C 知识,这可能更多是一个问题,但我希望有人能够提供可能的解决方案。简而言之,我正在尝试读取存储在内存中的结构,并且我拥有它的物理内存地址。这也是在 64 位 Linux 系统(Debian (Wheezy) Kernel 3.6.6)上完成的,我想使用 C 作为语言。
例如,当前结构的地址是物理地址:0x3f5e16000
现在我最初确实尝试使用指向 /dev/mem 的指针来访问此地址。但是,从那以后,我了解到不允许访问任何大于 1024MB 的地址,并且我在 var/log/messages 中收到一条很好的错误消息,告诉我所有相关信息。目前正在尝试从用户空间应用程序进行访问,但如果需要的话,我很乐意研究编写内核模块。
有趣的是,我还发现了一个名为“kprobe”的东西,据说它允许绕过 > 1024MB /dev/mem 的限制。但是,我真的不想在我的系统中引入任何潜在的安全问题,而且我确信必须有一种更简单的方法来实现这一点。关于 kprobe 的信息可以在这里找到:http://www.libcrack.so/2012/09/02/bypassing-devmem_is_allowed-with-kprobes/
我已经阅读了一些内容,并且发现了使用 mmap 将物理地址映射到用户空间以便可以读取它的参考资料,但我必须承认我不了解 C 中的实现。
如果有人能提供一些关于访问物理内存的信息,或者将数据从物理地址映射到用户空间虚拟地址,我将非常感激。
如果我对自己在做什么有点含糊,请原谅我,但这是项目的一部分,我不想透露太多信息,所以请多多包涵我 :) 我不是迟钝之类的。
内存中的结构是一个由四个整数和十个长整数组成的块,由正在运行的内核模块加载到内存中。
我使用的地址肯定是物理地址,它被设置为非分页,内核模块执行物理转换,我没有使用地址操作符。
我想知道我是否应该将问题重新表述为如何从物理位置读取 int,因为这是结构的第一个元素。我希望这有助于澄清事情!
编辑 - 在做了更多阅读之后,似乎解决这个问题的一种可能方法是构造一个内核模块,然后使用mmap 函数将物理地址映射到虚拟地址然后内核模块可以访问该地址。任何人都可以就使用 mmap 实现这一点提供任何建议吗?
【问题讨论】:
-
您要究竟做什么?也就是说,您要访问什么设备的什么结构?
-
您从中获得的地址,例如address-of 运算符
&是不是物理地址,它们是虚拟地址并且仅对正在运行的进程有效。它们实际在实际物理内存中的位置与您在程序中的地址无关,如果它已被交换到磁盘,它甚至可能不在物理内存中。 -
/dev/mem寻址物理内存,你确定这是你想要的,而不是虚拟内存吗? -
你怎么知道它的物理地址?你在做驱动/内核工作吗?
-
是的,目前我正在使用一个内核模块,该模块使用物理地址将某些数据结构和变量加载到内存中