从C中的物理内存地址读取struct

时间:2013-01-10 18:29:36

标签: c linux memory

这可能是我缺乏C知识的问题,但我希望有人能够提供可能的解决方案。简而言之,我正在尝试读取存储在内存中的结构,并且我拥有它的物理内存地址。这也是在64位Linux系统(Debian(Wheezy)内核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中的实现。 / p>

如果有人可以提供有关访问物理内存的信息,或者将数据从物理地址映射到用户空间虚拟地址,我将非常感激。

如果我对我正在做的事情有点模糊,你将不得不原谅我,但这是项目的一部分,我不想提供太多的信息,所以请忍受我:)我不是迟钝或什么的。

内存中的结构是一个由四个整数和十个长整数组成的块,由运行的内核模块加载到内存中。

我正在使用的地址绝对是一个物理地址,并且设置为非分页,内核模块执行到物理的转换,而我没有使用address-of运算符。

我想知道我是否应该将问题重新解释为如何从物理位置读取int,因为这是结构的第一个元素。我希望这有助于澄清事情!

编辑 - 在做了一些阅读之后,看来这个问题的一个可能的解决方案是构建一个内核模块,然后使用mmap函数将物理地址映射到然后内核模块可以访问的虚拟地址。任何人都可以使用mmap提供任何建议吗?

1 个答案:

答案 0 :(得分:4)

我只会回答这个问题:

  

我想知道我是否应该重新解释如何从物理位置读取int的问题,因为这是结构的第一个元素。

没有。问题不在于intstruct,问题在于C in和它本身没有物理内存的概念。操作系统与MMU一起确保每个进程(包括每个正在运行的C程序)都在虚拟内存沙箱中运行。操作系统可能为物理内存提供逃生舱。

如果您正在编写一个管理物理地址0x3f5e16000处某个对象的内核模块,那么您应该提供一些API来获取该内存,最好是使用文件描述符或其他抽象来隐藏来自与之通信的用户程序的内核内存管理的细节。

如果您正在尝试与设计不佳的内核模块进行通信,而该模块希望您访问固定的物理内存地址,那么涉及/dev/mem的丑陋黑客就是您的共享。