Reputation: 139
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
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