企业🤖AI智能体构建引擎,智能编排和调试,一键部署,支持知识库和私有化部署方案 广告
https://yq.aliyun.com/articles/592075 /dev/mem是物理内存的全映像,可以用来访问物理内存,用mmap来访问物理内存以及外设的IO资源,是实现用户空间驱动的一种方法 我们先用hexedit来看下/dev/mem,hexedit /dev/mem 可以物理内存的信息,当然肉眼是无法看的毕竟是16进制。 ``` 00000000 53 FF 00 F0 53 FF 00 F0 53 FF 00 F0 53 FF 00 F0 S...S...S...S... 00000010 53 FF 00 F0 53 FF 00 F0 CC E9 00 F0 53 FF 00 F0 S...S.......S... 00000020 A5 FE 00 F0 87 E9 00 F0 53 FF 00 F0 46 E7 00 F0 ........S...F... 00000030 46 E7 00 F0 46 E7 00 F0 57 EF 00 F0 53 FF 00 F0 F...F...W...S... 00000040 22 00 00 C0 4D F8 00 F0 41 F8 00 F0 FE E3 00 F0 "...M...A....... 00000050 39 E7 00 F0 59 F8 00 F0 2E E8 00 F0 D4 EF 00 F0 9...Y........... ``` 不过可以用mmap将/dev/mem 映射出来,然后可以对其读写可以实现用户空间的内核操作。先来说下mmap函数, ``` void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset); ``` 共6个参数含义分别如下: l addr如果为null,那么有内核选择一个映射的地址,如果不为null,那内核会把参数当做映射的提示(映射的地址就在所提示的附近,不会百分百确保的) l  length表示映射长度 l prot表示对映射的保护, 可以是可执行,可读,可写或不可访问,PROT_EXEC,PROT_READ,PROT_WRITE,PROT_NONE l flag表示是否对其他进程可见,MAP_SHARED表示其他进程可见。 l fd需要映射的文件描述符 l offset指向fd的编译 接下去我们用mmap来映射/dev/mem,编写代码如下: ``` #include<stdio.h> #include<unistd.h> #include<sys/mman.h> #include<sys/types.h> #include<sys/stat.h> #include<fcntl.h> int main () { unsigned char *map_base; FILE *f; int n, fd; fd = open ("/dev/mem", O_RDWR | O_SYNC); if (fd == -1) { printf ("open /dev/mem fail!\n"); return (-1); } map_base = mmap (NULL, 0xff, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0x20000); if (map_base == 0) { printf ("NULL pointer!\n"); } else { printf ("map Successfull!\n"); } unsigned long addr; unsigned char content; int i = 0; for (; i < 0xf; ++i) { addr = (unsigned long) (map_base + i); content = map_base[i]; printf ("address: 0x%lx value: 0x%x\t\t", addr,(unsigned int) content); map_base[i] = (unsigned char) i; content = map_base[i]; printf ("address: 0x%lx value: 0x%x\t\t", addr, (unsigned int) content); map_base[i] = (unsigned char) i; content = map_base[i]; printf ("address: 0x%lx new value: 0x%x\n", addr, (unsigned int) content); } close (fd); munmap (map_base, 0xff); return (1); } ```