Search code examples
cobjcopy

C program to open binary elf files, read from them, and print them out (like objcopy)


I am trying to implement a functionality similar to objcopy where bytes of a binary file (specifically the .text section) will be printed out using open() and read(). How would I set the buffer sizes and iterate till the end of a .text section so that I don't read more bytes than I have to in order to avoid errors?


Solution

  • Here is how you read a file using open() and read().

    P.S I used fopen() and fread() instead of open() and read() because I am currently working with a Windows machine. However, the results will be the same for either.

    
    int main()
    {
        FILE *file = fopen("input.txt", "r");
        char buffer[2048];
    
        if (file)
        {
            /* Loop will continue until an end of file is reached i.e. fread returns 0 elements read */
            while (fread(buffer, 4, 1, file) == 1)
            {
                printf("%s", buffer);
            }
            fclose(file);
        }
    }
    
    

    Update: For interpreting ELF files specifically, I would recommend taking a look at the following resources:

    Check out the following code snippet. It shows how you can interpret an ELF file.

    #include <stdio.h>
    #include <libelf.h>
    #include <stdlib.h>
    #include <string.h>
    static void failure(void);
    void main(int argc, char **argv)
    {
        Elf32_Shdr *shdr;
        Elf32_Ehdr *ehdr;
        Elf *elf;
        Elf_Scn *scn;
        Elf_Data *data;
        int fd;
        unsigned int cnt;
    
        /* Open the input file */
        if ((fd = open(argv[1], O_RDONLY)) == -1)
            exit(1);
    
        /* Obtain the ELF descriptor */
        (void)elf_version(EV_CURRENT);
        if ((elf = elf_begin(fd, ELF_C_READ, NULL)) == NULL)
            failure();
    
        /* Obtain the .shstrtab data buffer */
        if (((ehdr = elf32_getehdr(elf)) == NULL) ||
            ((scn = elf_getscn(elf, ehdr->e_shstrndx)) == NULL) ||
            ((data = elf_getdata(scn, NULL)) == NULL))
            failure();
    
        /* Traverse input filename, printing each section */
        for (cnt = 1, scn = NULL; scn = elf_nextscn(elf, scn); cnt++)
        {
            if ((shdr = elf32_getshdr(scn)) == NULL)
                failure();
            (void)printf("[%d]    %s\n", cnt,
                         (char *)data->d_buf + shdr->sh_name);
        }
    } /* end main */
    
    static void
    failure()
    {
        (void)fprintf(stderr, "%s\n", elf_errmsg(elf_errno()));
        exit(1);
    }
    

    I would also recommend checking out the elfutils library, which can be found here.