The/dev/mem driver provided in the Linux kernel provides a channel for us to read and write memory physical addresses. Here are 2 ways to read and write physical addresses using MEM device files, one for device-driven and the other for system calls. First we look at the mem this device file,/dev/mem is a character device under Linux, the source file is ~/DRIVERS/CHAR/MEM.C, this device file is specifically used to read and write physical address. The contents are the address of all physical memory and the content information. Typically, only the root user has read and write access to it. 1. Device-driven approach The following is the file_operations structure defined in the Mem.c file, providing Llseek,read,write,mmap and open methods. static struct File_operations Mem_fops = { . Llseek = Memory_lseek, . Read = Read_mem, . write = Write_mem, . mmap = Mmap_mem, . open = Open_mem, }; So we can use the general drive to treat the memory as a device completely. The application is as follows: #include <stdio.h> #include <fcntl.h> int main (void) { int FD; Char *rdbuf; char *wrbuf = "Butterfly"; int i; FD = open ("/dev/mem", O_RDWR); if (FD < 0) { printf ("Open/dev/mem failed."); } Read (fd,rdbuf,10); for (i = 0;i < 10;i++) { printf ("Old mem[%d]:%c\n", i,* (Rdbuf + i)); } Lseek (fd,5,0); Write (fd,wrbuf,10); Lseek (fd,0,0);//move F_ops to the front Read (fd,rdbuf,10); for (i = 0;i < 10;i++) { printf ("New mem[%d]:%c\n", i,* (Rdbuf + i)); } return 0; The results are as follows: Replace the content with the first 10 bytes of memory. [Root@voip-ipcam app]#./memtest Old Mem[0]:b Old Mem[1]:u Old Mem[2]:t Old Mem[3]:t Old Mem[4]:e Old Mem[5]:r Old Mem[6]:f Old Mem[7]:l Old Mem[8]:y Old mem[9]:! New MEM[0]:B New Mem[1]:u New Mem[2]:t New Mem[3]:t New Mem[4]:e New MEM[5]:B New Mem[6]:u New Mem[7]:t New Mem[8]:t New Mem[9]:e 2. Method of System call Careful you may find that, since you said in front of this file is the memory of the address and content information, then I can see directly, the answer is: yes. Linux kernel developers provide us with a command HexEdit, through which you can display/dev/mem content (if you use Cat/dev/mem will see garbled), the implementation of HEXEDIT/DEV/MEM results are as follows: 00000000 62 The butterfly! of the 6C-A- 00000010 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20-20 00000020 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20-20 00000030 6F EF F0 6F ef F0 EF F0 6F ef F0 o...o ... W...O ... 00000040 C0 4D F8 F0 F8 (F0) F0 .... M... A... 4.. 00000050 E7 F0 F8 F0 2E E8 F0-D2 EF F0 9...Y ... and so on. 00000060 A4 E7 F0 F2 E6 F0 6E FE F0 (FF) F0 ...... S... 00000070 FF F0 A4 F0 F0 C7 EF F0 1C C0 S ..... ...... B. As seen from the above, the leftmost display is the address, and the next 24 columns display the ASCII information of each memory byte cell, and the rightmost display is the corresponding character information. It is gratifying that this file can be directly modified, press the TAB key into the modified mode, modify the contents of the changes will be shown in bold, press F2 after saving bold disappeared. The above butterfly is modified in this way. Since the address of the memory and the content information are all stored in the MEM this device file, then we can think of another way to achieve the physical address of reading and writing. It is the use of MEM device files and mmap system calls to map the physical memory address in the file to the address space of the process, thereby enabling reading and writing to the physical address of the memory. Let's talk a little bit about mmap system calls. The function prototype for mmap is: void *mmap (void *start,size_t length,int prot,int flags,int offset), which is defined in fd,off_t In Mman.h, when used, include: #include <sys/mman.h>,mmap () is used to map the contents of a file to the address space of the process, and access to that space is read and write to the contents of the file. The parameter description is as follows: Start: The starting address of the address space to map to, usually set to null or 0. Indicates that the system melts the address automatically, and the address returns when the mapping succeeds. Length: Represents the size, in bytes, of the content of the mapped file. Prot: Represents the protected mode of a mapped area, with four combinations: The--prot_exec mapping area can be executed, The--prot_read map area is readable, The--prot_write mapping area is writable, --prot_none map area cannot be accessed Flags: Some of the features of the mapped area include: --map_fixed Error returns if the mapping is unsuccessful, --map_shared write data to the mapped area will be written back to the original file --map_private write data to the mapped region will not be written back to the original file --map_anonymous --map_denywrite only allow writes to the mapped region, and other actions to write directly to the file will be rejected --map_locked Locked Map Area When calling Mmap (), you must specify Map_shared or Map_private. The file descriptor returned by Fd:open (). Offset: The number of offsets to the mapped file, which indicates where to start mapping from the file, typically set to 0, which indicates that the mapping starts at the beginning of the file. Offset must be an integer multiple of the paging size (4096 bytes). The application is as follows: #include <stdio.h> #include <fcntl.h> #include <sys/mman.h>//mmap head file int main (void) { int i; int FD; Char *start; Char *buf = "butterfly!"; Open/dev/mem with Read and write mode FD = open ("/dev/mem", O_RDWR); if (FD < 0) { printf ("Cannot open/dev/mem."); return-1; } Map Physical Memory 0-10 bytes Start = (char *) mmap (0, Prot_read | Prot_write, map_shared, FD, 0); if (Start < 0) { printf ("Mmap failed."); return-1; } Read old value for (i = 0; i < i++) { printf ("Old mem[%d]:%c\n", I, * (start + i)); } Write memory memcpy (Start, buf, 10); Read New Value for (i = 0;i < 10;i++) { printf ("New mem[%d]:%c\n", i,* (start + i)); } Munmap (start, 10); Destroy map memory Close (FD); Close File return 0; The results of the program execution are as follows: [Root@voip-ipcam app]#./rwphy Old Mem[0]:b Old Mem[1]:u Old Mem[2]:t Old Mem[3]:t Old Mem[4]:e Old Mem[5]:b Old Mem[6]:u Old Mem[7]:t Old Mem[8]:t Old Mem[9]:e New MEM[0]:B New Mem[1]:u New Mem[2]:t New Mem[3]:t New Mem[4]:e New Mem[5]:r New Mem[6]:f New Mem[7]:l New Mem[8]:y New mem[9]:! "/dev/mem is a fun thing and you can actually access physical memory directly." This in Linux is simply too magical, this feeling like a thief is going to steal a bank, but this bank is heavily guarded, just when the thief is suffering no countermeasures, suddenly found in a humble place has a backdoor, this backdoor can directly to the bank's vault. "Original: http://hi.baidu.com/liuming910/blog/item/b2b19f59ff296888800a18b7.html |