cxcodememory-managementmemory-mapped-files

Unexpected output when displaying file content after using mmap()


I am parsing a .elf file to edit a few details in it. I am opening the file using open() and then creating a memory map for it using mmap() for easier editing.

The problem is that I am getting unexpected behaviour after I create the memory map.

In order to debug the issue and see if I am using the open() and mmap() functions correctly, I trimmed down the code to simply print the content of the .elf file. However, even when I did that, the printed content was not the same output as I get when I do a objdump -s myfile.elf

Please bare in mind, that this is not my full code, this is just a trimmed down version for the purpose of the question and it is still not working.

All what I am looking for now is to print the file content and have a same output as that of the objdump command

#include <sys/stat.h>
#include <stdio.h>
#include <fcntl.h>
#include <string.h>
#include   <sys/mman.h>

typedef struct iFi  {
  unsigned char               *pB;       // memory mapped file
  void           *hFmap;
  void           *hFile;
  int             handle_File;
  unsigned long            fSize;       // file size
  struct stat       sts;       /* File status */
  char        szFN[1024];       // file name
} XFILE;

int main (int argc, char **argv)  {
    if(argc != 2)    
        return 1;
    
    XFILE myfile;
    XFILE *pF = &myfile;
    memset (&pF->pB, 0, sizeof (pF->pB));
    memset (&pF->hFmap, 0, sizeof (pF->hFmap));
    memset (&pF->hFile, 0, sizeof (pF->hFile));
    memset (&pF->szFN, 0, sizeof (pF->szFN));

    strcpy (pF->szFN, argv[1]);
    mode_t perms = S_IRUSR | S_IWUSR;
    pF->handle_File = open(pF->szFN, O_RDWR, perms);
    if (pF->handle_File < 0)  {
        perror("open");
        return (1);
    }

    int n = stat (pF->szFN, &pF->sts);
    if (n != 0) return(1000);                     // failed
    pF->fSize = pF->sts.st_size;
    //pF->hFmap = CreateFileMapping (pF->hFile, NULL, PAGE_READWRITE /*PAGE_WRITECOPY*/, 0, 0, NULL);
    pF->pB = static_cast<unsigned char*>(mmap(NULL, pF->fSize, PROT_READ | PROT_WRITE, MAP_SHARED, pF->handle_File, 0));
    if (pF->pB == NULL) return 1000;             // can't map view of file
    printf("Contents of file = 0x%x\n", *pF->pB);

    return 0;

}

Here is my expected output (first 0xFF bytes)

0000 00000320 9d050000 c9050000 cd050000  ... ............
0010 c5050000 c5050000 c5050000 00000000  ................

and here is the actual output I get

Contents of file = 0x7f

As you can see, there is no 0x7f anywhere in my file and even if I print the whole content of pF->pB I get:

0x0000000100288000 "\U0000007fELF\U00000001\U00000001\U00000001"

Solution

  • However, even when I did that, the printed content was not the same output as I get when I do a objdump -s myfile.elf

    The printed content should match what you see when you do

    $ hd myfile.elf
    

    Memory mapping the file contents is not the same as the process done on loadint an .elf binary, as this requires dlopen(3) library call.

    Objdump reads and prints .elf specific info, like section contents and requires format to be ELF, while mmap(2) just maps the file contents (of any kind of file) in memory, so you can see the file contents as if it was memory.

    This means that, if you map with mmap(2), then you need to interpret the ELF header and search for the sections by mapping the addresses yourself.