Jump to content
Nytro

ELF: dynamic struggles

Recommended Posts

Posted

ELF: dynamic struggles

Mar 12, 2016

Intro

Every ELF64 binary starts with this header:

typedef struct elf64_hdr {
  unsigned char	e_ident[EI_NIDENT];
  Elf64_Half e_type;
  Elf64_Half e_machine;
  Elf64_Word e_version;
  Elf64_Addr e_entry;
  Elf64_Off e_phoff;
  Elf64_Off e_shoff;
  Elf64_Word e_flags;
  Elf64_Half e_ehsize;
  Elf64_Half e_phentsize;
  Elf64_Half e_phnum;
  Elf64_Half e_shentsize;
  Elf64_Half e_shnum;
  Elf64_Half e_shstrndx;
} Elf64_Ehdr;

We are only going to concern ourselves with dynamically linked Elf64_Ehdr.e_type =ET_EXEC (executable files) or ET_DYN (dynamic shared objects, basically shared libraries).

Note: If you don’t know what dynamic linking means, I suggest to read this article. I will not mention ELF sections on purpose. They are not relevant in executables and shared libraries. They don’t have to be there and should be treated like a nice bonus when they actually are. See sstrip. This “technique” is used by malware fairly often and you don’t need sstrip to do the job.

e_phoff specifies the start of a program header table (PHT) in the file. The PHT is made of Elf64_Phdr entries (segments):

typedef struct elf64_phdr {
  Elf64_Word p_type;
  Elf64_Word p_flags;
  Elf64_Off p_offset;		/* Segment file offset */
  Elf64_Addr p_vaddr;		/* Segment virtual address */
  Elf64_Addr p_paddr;		/* Segment physical address */
  Elf64_Xword p_filesz;		/* Segment size in file */
  Elf64_Xword p_memsz;		/* Segment size in memory */
  Elf64_Xword p_align;		/* Segment alignment, file & memory */
} Elf64_Phdr;

p_type can have values such as PT_LOAD, PT_DYNAMIC, PT_INTERP etc.

When loading an ELF binary, the linux kernel looks for PT_LOAD segments and maps them into memory (among other things). When doing so, it uses both p_offset(segment file offset) and p_vaddr (the address where to map the segment into memory). ELF segments can overlap in the file. Usually, there are 2 PT_LOADsegments - 1 for code (R-X) and 1 for data (RW-). There can also be just 1 or more than 2. Whenever a virtual address needs to be converted to a file offset, it can be done like this:

for(int i = 0; i < ehdr->e_phnum; i++) {
        if(seg.p_type != PT_LOAD)
                continue;

        if(va >= seg.p_vaddr && va < seg.p_vaddr + seg.p_memsz) {
                offset = seg.p_offset + (va - seg.p_vaddr);
        }
}

When you dynamically link an ELF, PT_DYNAMIC can be found in the program header table of the resulting binary. It usually belongs to the second PT_LOAD segment, therefore it is loaded into memory. PT_INTERP specifies the dynamic interpreter and the kernel is very sensitive about it.

PT_DYNAMIC is an array of dynamic entries:


typedef struct {
  Elf64_Sxword d_tag;		/* entry tag value */
  union {
    Elf64_Xword d_val;
    Elf64_Addr d_ptr;
  } d_un;
} Elf64_Dyn;

d_tag is the type of the dynamic entry. Dynamic entries contain vital information for the dynamic linker. Information such as symbol relocations to figure out what API are you trying to call (simplified) etc.

Case: executable binaries

Let’s compile a program and look at it with radare2 (always use the git version)! I am using radare on OS X:


$ r2 -v
radare2 0.10.2-git 10555 @ darwin-little-x86-64 git.0.10.1-99-g747699f
commit: 747699f712d7cc0402b20c9313a16634e68d7764 build: 2016-03-11

#include <fcntl.h>
#include <unistd.h>

int main()
{
        int fd = open("hello", O_CREAT | O_TRUNC | O_WRONLY);
        
        if(fd > 0) {
                write(fd, "world", 5);
                close(fd);
        }
        
        return 0;
}

I am using gcc (Debian 4.9.2-10) 4.9.2 ldd (Debian GLIBC 2.19-18+deb8u3) 2.19 onDebian 8.3 x64.

 

 

Articol complet: https://michalmalik.github.io/elf-dynamic-segment-struggles

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



×
×
  • Create New...