Read struct from physical memory address in C
This is probably more of a problem with my lack of C knowledge, but I'm hoping someone might be able to offer a possible solution. In a nutshell, I'm trying to read a struct that is stored in memory, and I have it's physical memory address. Also this is being done on a 64-bit Linux system (Debian (Wheezy) Kernel 3.6.6), and I'd like to use C as the language.
For example the current address of the struct in question is at physical address: 0x3f5e16000
Now I did initially try to access this address by using using a pointer to /dev/mem. However, I've since learned that access to any address > 1024MB is not allowed, and I get a nice error message in var/log/messages telling me all about it. At present access is being attempted from a userspace app, but I'm more than happy to look into writing a kernel module, if that is what is required.
Interesting, I've also discovered something known as 'kprobe', which supposedly allows the > 1024MB /dev/mem restriction to be bypassed. However, I don't really want to introduce any potential security issues into my system, and I'm sure there must be an easier way to accomplish this. The info on kprobe can be found here: http://www.libcrack.so/2012/09/02/bypassing-devmem_is_allowed-with-kprobes/
I've done some reading and I've found references to using mmap to map the physical address into userspace so that it can be read, but I must confess that I don't understand the implementation of this in C.
If anyone could provide some information on accessing physical memory, or either mapping data from a physical address to a userspace virtual address, I would be extremely grateful.
You'll have to forgive me if I'm a little bit vague as to exactly what I'm doing, but it's part of a project and I don't want to give too much information away, so please bear with me :) I'm not being obtuse or anything.
The structure in memory is a block of four ints and ten longs that is loaded into memory by a running kernel module.
The address that I'm using is definitely a physical address and it's set to non-paged, the kernel module performs the translations to physical and I'm not using the address-of operator.
I'm wondering if I should just rephrase the question as how to read an int from a physical location, as that is the first element of the struct. I hope that helps to clarify things!
EDIT - After doing some more reading, it appears that one possible solution to this problem is to construct a kernel module, and then use the mmap
function to map the physical address to a virtual address the kernel module can then access. Can anyone offer any advice on achieving this using mmap?
I'm only going to answer this question:
I'm wondering if I should just rephrase the question as how to read an int from a physical location, as that is the first element of the struct.
No. The problem is not int
vs. struct
, the problem is that C in and of itself has no notion of physical memory. The OS in conjunction with the MMU makes sure that every process, including every running C program, runs in a virtual memory sandbox. The OS might offer an escape hatch into physical memory.
If you're writing a kernel module that manages some object at physical address 0x3f5e16000
, then you should offer some API to get to that memory, preferably one that uses a file descriptor or some other abstraction to hide the nitty-gritty of kernel memory management from the user program it communicates with.
If you're trying to communicate with a poorly designed kernel module that expects you to access a fixed physical memory address, then ugly hacks involving /dev/mem
are your share.
下一篇: 从C中的物理内存地址读取结构