在Linux下面/proc/pid/maps,这个文件里面保存了执行进程的所有内存映射情况以及内存属性,在程序里面可以通过读该文件进行判断内存是否可写。有些人会认为,有必要吗,调用者要确保传入的参数是正确的,听起来也有道理,但在某些场合,就是因为用户传入参数出错,或这个参数被踩了,导致这个函数写内存而崩溃,是不允许的。
下面这个函数可以检查输入地址和一个长度,检查这个范围中,是否都可以写。
#include <stdio.h> #include <unistd.h> int check_mem_wrtieable(unsigned long addr, int len) { pid_t pid ; char access, maps[32] , buff[1024]; unsigned long start_addr, end_addr, last_addr; FILE *fmap; pid = getpid(); sprintf(maps, "/proc/%d/maps", pid); fmap = fopen(maps, "rb"); if(!fmap){ printf("open %s file failed!/n", maps); return 0; } while(fgets(buff, sizeof(buff)-1, fmap) != NULL) { /* "%*c"表示忽略第一个字符 */ sscanf(buff, "%lx-%lx %*c%c", &start_addr, &end_addr, &access); if((addr >= start_addr) && (addr <= end_addr)){ if('w' != access){ fclose(fmap); return 0; } if((addr + len) < end_addr){ fclose(fmap); return 1; }else { last_addr = end_addr; len = len - (end_addr - addr); addr = last_addr; } } } fclose(fmap); return 0; }