简体   繁体   中英

c - segmentation fault when accessing virtual memory

I am trying to write a program that takes a command argument required_address prints the byte of memory located at this address if it exists.

This is my code thus far:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

/*
  - Takes a single arg: required_address
  - if the address is in virtual memory:
  -   print to stdout the value of the single byte of memory located at address
  -   return with exit code 1
  - else:
  -   print nothing
  -   return with exit code 0

  - 00405000-00426000 [heap]

 */

int main(int argc, char const *argv[]) {
    unsigned long ret_adr = strtoul(argv[1], NULL, 10);
    int pid = getpid();
    FILE *file;
    char c[1000];

    char file_addr[20];
    sprintf(file_addr, "/proc/%d/maps", pid);
    puts(file_addr);

    if ((file = fopen(file_addr,"r")) == NULL){
       printf("Error! opening file\n");

       // Program exits if the file pointer returns NULL.
       exit(1);
    }

    while (fgets(c, sizeof(c), file) != NULL) {
        printf("%s\n", c);
        sleep(1);
    }

    printf("pid: %d\n", pid);

    unsigned long* p = (unsigned long *)ret_adr;
    unsigned long first_byte = p[0];
    printf("%p\n", p);
    return 0;
}

This is my terminal:

[awhite4@fastx07 task1]$ gcc -ggdb -O0 -o task1 task1.c
[awhite4@fastx07 task1]$ setarch x86_64 -R ./task1 400000
/proc/32687/maps
00400000-00401000 r--p 00000000 00:37 3014860647                         /mnt/nfs/clasnetappvm/homedirs/awhite4/Downloads/task1/task1

00401000-00402000 r-xp 00001000 00:37 3014860647                         /mnt/nfs/clasnetappvm/homedirs/awhite4/Downloads/task1/task1

00402000-00403000 r--p 00002000 00:37 3014860647                         /mnt/nfs/clasnetappvm/homedirs/awhite4/Downloads/task1/task1

00403000-00404000 r--p 00002000 00:37 3014860647                         /mnt/nfs/clasnetappvm/homedirs/awhite4/Downloads/task1/task1

00404000-00405000 rw-p 00003000 00:37 3014860647                         /mnt/nfs/clasnetappvm/homedirs/awhite4/Downloads/task1/task1

00405000-00426000 rw-p 00000000 00:00 0                                  [heap]

7ffff7db7000-7ffff7dd9000 r--p 00000000 fd:00 5597327                    /usr/lib64/libc-2.29.so

7ffff7dd9000-7ffff7f26000 r-xp 00022000 fd:00 5597327                    /usr/lib64/libc-2.29.so

7ffff7f26000-7ffff7f72000 r--p 0016f000 fd:00 5597327                    /usr/lib64/libc-2.29.so

7ffff7f72000-7ffff7f73000 ---p 001bb000 fd:00 5597327                    /usr/lib64/libc-2.29.so

7ffff7f73000-7ffff7f77000 r--p 001bb000 fd:00 5597327                    /usr/lib64/libc-2.29.so

7ffff7f77000-7ffff7f79000 rw-p 001bf000 fd:00 5597327                    /usr/lib64/libc-2.29.so

7ffff7f79000-7ffff7f7f000 rw-p 00000000 00:00 0 

7ffff7fce000-7ffff7fd1000 r--p 00000000 00:00 0                          [vvar]

7ffff7fd1000-7ffff7fd2000 r-xp 00000000 00:00 0                          [vdso]

7ffff7fd2000-7ffff7fd3000 r--p 00000000 fd:00 5515071                    /usr/lib64/ld-2.29.so

7ffff7fd3000-7ffff7ff3000 r-xp 00001000 fd:00 5515071                    /usr/lib64/ld-2.29.so

7ffff7ff3000-7ffff7ffb000 r--p 00021000 fd:00 5515071                    /usr/lib64/ld-2.29.so

7ffff7ffc000-7ffff7ffd000 r--p 00029000 fd:00 5515071                    /usr/lib64/ld-2.29.so

7ffff7ffd000-7ffff7ffe000 rw-p 0002a000 fd:00 5515071                    /usr/lib64/ld-2.29.so

7ffff7ffe000-7ffff7fff000 rw-p 00000000 00:00 0 

7ffffffdd000-7ffffffff000 rw-p 00000000 00:00 0                          [stack]

ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]

pid: 32687
Segmentation fault (core dumped)

How do I use the 400000 address to access the value that is stored at this address? I tried to use a pointer and got an address but then when I try to get the value I get a Segmentation fault error.

How do I directly access the memory since I know it is valid (it is in the heap shown in /proc//maps)?

Am I just not understanding the correct way to access this memory?

The addresses shown in /proc/.../maps are shown in hexadecimal , ie base 16.

You are reading the 400000 address in base 10 ( 0x61a80 ), which means you are trying to access unmapped memory below 0x400000 which is the start of the first map.

Check your strtoul() parameters!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM