lex449
lex449

Reputation: 139

c - verify if memory address is allocated

I'm trying to complete a program with this goal:

Take a single argument that is a hexadecimal number that represents a memory address. If the address is in the virtual memory of the process print the value of the single byte of memory located at this address. If not, exit.

This is the code I have so far:

int main(int argc, char const *argv[]) {
    unsigned long ret_adr = strtoul(argv[1], NULL, 16);
    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("%lu\n", first_byte);
    return 0;
}

I can access the /proc/<pid>/maps but I do not know how to verify if ret_adr is in the maps or not.

At the bottom of the code, I tried to get a pointer of the address and then get the byte of that pointer. But I don't believe this is the correct answer because the address itself should be the "pointer" not the pointer of that variable.

This is my terminal for reference:

[task1]$ setarch x86_64 -R ./task1 400000
/proc/30879/maps
pid: 30879
282584257676671

Upvotes: 1

Views: 817

Answers (1)

Zan Lynx
Zan Lynx

Reputation: 54325

You can manually parse the maps file.

But there's another trick that has been around in Unix since forever: Attempt to call the write function using the pointer as the buffer, and a file descriptor opened to /dev/null. If the memory address is good it will succeed. If it isn't you get the error code EFAULT in errno.

Upvotes: 2

Related Questions