I have written a sample program in C that uses libelf to dump the different sections. However i want to dump the heap & stack segment starting address which is only available when the process is "live" (running).
This is what i do for a binary i read from disk.
elf_fd = open(elf_fname, O_RDWR);
if(elf_fd < 0) {
fprintf(stderr, "Failed to open \"%s\" reason=%s\n", elf_fname, strerror(errno));
return -1;;
}
followed by
if(elf_version(EV_CURRENT) == EV_NONE) {
fprintf(stderr, "Failed to initialize libelf\n");
res = -1;
goto done;
}
elf->e = elf_begin(elf->fd, ELF_C_READ, NULL);
if(!elf->e) {
int err = elf_errno();
if (err != 0) {
fprintf(stderr, "Failed to open ELF file code=%d reason=%s\n", err,
elf_errmsg(err));
}
res = -1;
goto done;
}
This works fine when i read the binary image on disk
For run time what i tried is instead of doing this That is using the elf_fd returned by open
elf_fd = open(elf_fname, O_RDWR);
if(elf_fd < 0) {
fprintf(stderr, "Failed to open \"%s\" reason=%s\n", elf_fname, strerror(errno));
return -1;;
}
I instead do this
That is i get a handle from the pid of the current process
elf_fd = pidfd_open(getpid(), 0);
if (elf_fd == -1) {
perror("pidfd_open");
fprintf(stderr, "failed to open self %d\n", elf_fd);
exit(EXIT_FAILURE);
}
It returns me a valid descriptor but when i use this descriptor with
elf->e = elf_begin(elf->fd, ELF_C_READ, NULL);
if(!elf->e) {
int err = elf_errno();
if (err != 0) {
fprintf(stderr, "Failed to open ELF file code=%d reason=%s\n", err,
elf_errmsg(err));
}
}
It says "Invalid descriptor".
Question is how can i get heap & stack base address of a live process from within it
Also yes i did also try at the very start in main call sbrk(0) & that seems to print the heap start address but this may not always be reliable as there maybe no heap without a malloc call prior for now it does seem to print it.
pidfd_open
. It does not give you a file descriptor for a "live" ELF file. The addresses you are looking for can be found in/proc/[pid]/maps
. – mkayaalp