• 获取一个进程的所有物理地址上的内存


    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!
     pagemap PID VIRTUAL_ADDRESS
    ");
    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 != '' || pid<=0){ 
    37             printf("PID must be a positive number or 'self'
    ");
    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
    ", is_bigendian());
    52     f = fopen(path_buf, "rb");
    53     if(!f){
    54         printf("Error! Cannot open %s
    ", 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
    ", virt_addr, page_size, PAGEMAP_ENTRY);
    62     printf("Reading %s at 0x%llx
    ", 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("
    Reached end of the file
    ");
    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("
    ");
    88     printf("Result: 0x%llx
    ", (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)
    ", pfn, pfn * page_size + virt_addr % page_size);
    92     } else
    93         printf("Page not present
    ");
    94     if(GET_BIT(read_val, 62))
    95         printf("Page swapped
    ");
    96     fclose(f);
    97     return 0;
    98 }
    View Code

    2. 通过mmap /dev/mem获取物理地址的存储内容

      参考:https://blog.csdn.net/zhanglei4214/article/details/6653568

    3. 获取之后:就有很多好玩的东东啦

      a. 比如做crc校验,找出是否有人踩这个内存

      b. 比如可以篡改内容,搞挂别人的程序

      。。。

  • 相关阅读:
    LeetCode:Remove Nth Node From End of List
    链表排序(冒泡、选择、插入、快排、归并、希尔、堆排序)
    快速排序partition过程常见的两种写法+快速排序非递归实现
    LeetCode:Permutations, Permutations II(求全排列)
    LeetCode:3Sum, 3Sum Closest, 4Sum
    LeetCode:Two Sum
    判断一个图是否有环
    c++设计一个无法被继承的类
    设计模式--单例模式
    windows多线程同步互斥--总结
  • 原文地址:https://www.cnblogs.com/zengjianrong/p/11169094.html
Copyright © 2020-2023  润新知