title: Parsing ELF sections
body: <p>Hi so I am trying to code a program which parses an ELF then creates a copy of it using the parsed info.
  I’ve been able to copy the elf header and program headers of elf files (readelf -l and -h are identical to orignal). But I’m struggling with sections</p>
  <pre><code>int parse64elfsec(t_elf_file ef)
  {
      Elf64_Shdr shdr;
      unsigned char *ptr = (unsigned char *)ef.file  + ef.elf64header.e_shoff;
      unsigned int i = 0;
  
      while (i &lt; ef.elf64header.e_shnum)
      {
          memcpy(&amp;shdr, ptr, sizeof(Elf64_Shdr));
          ptr += sizeof(Elf64_Shdr);
          if (shdr.sh_type != SHT_NOBITS)
          {
              write(ef.wfd, (unsigned char *)ef.file + shdr.sh_offset, shdr.sh_size);
          }
          i++;
      }
      return (0); 
  }
  </code></pre>
  <p>This is what I’m currently doing but I’m not getting all the sections it seems because the product binary is half the size of the original one and segfaults.</p>
  <p>Can anyone see what I’m missing out on here ?</p>
  <p>Edit :</p>
  <p>Here's my <a href="https://github.com/SaltyMilk/woody-woodpacker/tree/a9b8e0ea601ec21b7bdd19ccd314513504240418" rel="nofollow noreferrer">repo</a> if someone wishes to have the full context/try it.</p>
  <p>All macros and structs used here are defined by elf.h (man 5 elf).
  Except t_elf_file, this contains</p>
  <ul>
  <li>ef.file -&gt; original executable mapped in memory</li>
  <li>ef.wfd -&gt; file descriptor of the copy executable we're creating</li>
  <li>ef.elf64header -&gt; the Elf64_Ehdr (header) of the executable we're parsing</li>
  </ul>
  <p>edit 2:
  After some more research I printed the offsets at which each section starts and ends:</p>
  <pre><code>Finished to parse ph, they finish at : 2a8
  Starting to parse section start: 0 | end : 0
  Starting to parse section start: 2a8 | end : 2c4
  Starting to parse section start: 2c4 | end : 2e4
  Starting to parse section start: 2e4 | end : 308
  Starting to parse section start: 308 | end : 32c
  Starting to parse section start: 330 | end : 3d8
  Starting to parse section start: 3d8 | end : 45a
  Starting to parse section start: 45a | end : 468
  Starting to parse section start: 468 | end : 488
  Starting to parse section start: 488 | end : 548
  Starting to parse section start: 548 | end : 560
  Starting to parse section start: 1000 | end : 1017
  Starting to parse section start: 1020 | end : 1040
  Starting to parse section start: 1040 | end : 1048
  Starting to parse section start: 1050 | end : 11b1
  Starting to parse section start: 11b4 | end : 11bd
  Starting to parse section start: 2000 | end : 2010
  Starting to parse section start: 2010 | end : 204c
  Starting to parse section start: 2050 | end : 2158
  Starting to parse section start: 2de8 | end : 2df0
  Starting to parse section start: 2df0 | end : 2df8
  Starting to parse section start: 2df8 | end : 2fd8
  Starting to parse section start: 2fd8 | end : 3000
  Starting to parse section start: 3000 | end : 3020
  Starting to parse section start: 3020 | end : 3030
  Starting to parse section start: 3030 | end : 3038
  Starting to parse section start: 3030 | end : 304c
  Starting to parse section start: 3050 | end : 3650
  Starting to parse section start: 3650 | end : 3852
  Starting to parse section start: 3852 | end : 3959
  First section header at : 3960
  </code></pre>
  <p>We can see multiple odd things :</p>
  <p>1)</p>
  <pre><code>Starting to parse section start: 3030 | end : 3038
  Starting to parse section start: 3030 | end : 304c
  </code></pre>
  <p>-&gt;those two sections start at the same offset</p>
  <p>2)</p>
  <pre><code>Starting to parse section start: 308 | end : 32c
  Starting to parse section start: 330 | end : 3d8
  </code></pre>
  <p>-&gt;those two sections don't follow each other, therefore what are those bytes between those two sections ?</p>
  <p>To get that output I simply added this printf above the if in the given code</p>
  <pre><code>printf(&quot;Starting to parse section start: %lx | end : %lx\n&quot;,  shdr.sh_offset, shdr.sh_offset + shdr.sh_size);
  </code></pre>