获取一个进程的所有物理地址上的内存
Posted zengjianrong
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了获取一个进程的所有物理地址上的内存相关的知识,希望对你有一定的参考价值。
1. 获取进程的所有PTE表项,从而得到所有物理地址
参考:https://www.cnblogs.com/pengdonglin137/p/6802108.html
通过/proc/pid/pagemap
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <unistd.h> 4 #include <assert.h> 5 #include <errno.h> 6 #include <stdint.h> 7 #include <string.h> 8 9 #define PAGEMAP_ENTRY 8 10 #define GET_BIT(X,Y) (X & ((uint64_t)1<<Y)) >> Y 11 #define GET_PFN(X) X & 0x7FFFFFFFFFFFFF 12 13 const int __endian_bit = 1; 14 #define is_bigendian() ( (*(char*)&__endian_bit) == 0 ) 15 16 int i, c, pid, status; 17 unsigned long virt_addr; 18 uint64_t read_val, file_offset, page_size; 19 char path_buf [0x100] = ; 20 FILE * f; 21 char *end; 22 23 int read_pagemap(char * path_buf, unsigned long virt_addr); 24 25 int main(int argc, char ** argv) 26 if(argc!=3) 27 printf("Argument number is not correct!\\n pagemap PID VIRTUAL_ADDRESS\\n"); 28 return -1; 29 30 if(!memcmp(argv[1],"self",sizeof("self"))) 31 sprintf(path_buf, "/proc/self/pagemap"); 32 pid = -1; 33 34 else 35 pid = strtol(argv[1],&end, 10); 36 if (end == argv[1] || *end != ‘\\0‘ || pid<=0) 37 printf("PID must be a positive number or ‘self‘\\n"); 38 return -1; 39 40 41 virt_addr = strtoll(argv[2], NULL, 16); 42 if(pid!=-1) 43 sprintf(path_buf, "/proc/%u/pagemap", pid); 44 45 page_size = getpagesize(); 46 read_pagemap(path_buf, virt_addr); 47 return 0; 48 49 50 int read_pagemap(char * path_buf, unsigned long virt_addr) 51 printf("Big endian? %d\\n", is_bigendian()); 52 f = fopen(path_buf, "rb"); 53 if(!f) 54 printf("Error! Cannot open %s\\n", path_buf); 55 return -1; 56 57 58 //Shifting by virt-addr-offset number of bytes 59 //and multiplying by the size of an address (the size of an entry in pagemap file) 60 file_offset = virt_addr / page_size * PAGEMAP_ENTRY; 61 printf("Vaddr: 0x%lx, Page_size: %lld, Entry_size: %d\\n", virt_addr, page_size, PAGEMAP_ENTRY); 62 printf("Reading %s at 0x%llx\\n", path_buf, (unsigned long long) file_offset); 63 status = fseek(f, file_offset, SEEK_SET); 64 if(status) 65 perror("Failed to do fseek!"); 66 return -1; 67 68 errno = 0; 69 read_val = 0; 70 unsigned char c_buf[PAGEMAP_ENTRY]; 71 for(i=0; i < PAGEMAP_ENTRY; i++) 72 c = getc(f); 73 if(c==EOF) 74 printf("\\nReached end of the file\\n"); 75 return 0; 76 77 if(is_bigendian()) 78 c_buf[i] = c; 79 else 80 c_buf[PAGEMAP_ENTRY - i - 1] = c; 81 printf("[%d]0x%x ", i, c); 82 83 for(i=0; i < PAGEMAP_ENTRY; i++) 84 //printf("%d ",c_buf[i]); 85 read_val = (read_val << 8) + c_buf[i]; 86 87 printf("\\n"); 88 printf("Result: 0x%llx\\n", (unsigned long long) read_val); 89 if(GET_BIT(read_val, 63)) 90 uint64_t pfn = GET_PFN(read_val); 91 printf("PFN: 0x%llx (0x%llx)\\n", pfn, pfn * page_size + virt_addr % page_size); 92 else 93 printf("Page not present\\n"); 94 if(GET_BIT(read_val, 62)) 95 printf("Page swapped\\n"); 96 fclose(f); 97 return 0; 98
2. 通过mmap /dev/mem获取物理地址的存储内容
参考:https://blog.csdn.net/zhanglei4214/article/details/6653568
3. 获取之后:就有很多好玩的东东啦
a. 比如做crc校验,找出是否有人踩这个内存
b. 比如可以篡改内容,搞挂别人的程序
。。。
以上是关于获取一个进程的所有物理地址上的内存的主要内容,如果未能解决你的问题,请参考以下文章