Home > Back-end >  how to get heap start address of a elf binary
how to get heap start address of a elf binary

Time:10-18

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.

CodePudding user response:

Question is how can i get heap & stack base address of a live process from within it

Note that neither heap, nor stack have anything to do with the ELF format, or libelf.

There is no such thing as "heap base address" -- most modern heap allocators will perform multiple mmap calls to obtain memory from the OS, then "dole" it out to various malloc requests.

i did also try at the very start in main call sbrk(0)

"Legacy" malloc used to obtain memory using sbrk(), but few modern ones do. If the malloc you are using does use sbrk, then calling sbrk(0) near the start of main is a usable approximation.

For the main thread stack, you would want to do the same. A good first approximation is taking &argc, and rounding it up to page boundary.

If you want to get better approximation, you could use the fact that on Linux (and possibly other ELF platforms) the kernel puts specific values on the stack before invoking the entry point. Iterating through the __environ values looking for the highest address will give a better approximation.

  • Related