【问题标题】:Read struct from physical memory address in C从C中的物理内存地址读取结构
【发布时间】: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 寻址物理内存,你确定这是你想要的,而不是虚拟内存吗?
  • 你怎么知道它的物理地址?你在做驱动/内核工作吗?
  • 是的,目前我正在使用一个内核模块,该模块使用物理地址将某些数据结构和变量加载到内存中

标签: c linux memory


【解决方案1】:

我只回答这个问题:

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

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

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

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

【讨论】:

  • 谢谢拉尔斯曼。我认为我一直在以错误的方式进行此操作,现在我完全理解为什么我尝试访问物理地址不是正确的处理方式。我会尝试不同的方法!
猜你喜欢
  • 2014-09-06
  • 1970-01-01
  • 2020-10-06
  • 2021-10-28
  • 1970-01-01
  • 2017-04-26
  • 1970-01-01
  • 1970-01-01
  • 2012-04-17
相关资源
最近更新 更多