Android Roaming note (2)---elf executable file format

Source: Internet
Author: User

Elf is a Unix-like system and of course includes executable file formats on Android (also including. So and. O class files). Can be understood as an EXE or DLL file format on an Android system. Understanding the Elf file specification is a prerequisite for understanding process loading and execution on an Android system. Let's take a closer look at what this elf is all about (the arm is the main form of elf format)! Of course, the introduction of the Elf on the internet has been very many, the best manual or directly look at the Official Elf Handbook, I just do a programmatic introduction to the Elf file, and then go straight to the topic, such as. GOT. A plt or r_arm_jump_slot,r_arm_relative thing.

Or take libc.so as an example to introduce, first look at the elf file generated by arm-linux-androideabi-readelf, very long, we first look at a fragment:


Let's pick a few interesting fields to illustrate.

First Elf header: As the name implies, this is the "head" of all elf files. Contains the elf file "programmatic" information, such as "machine" represents the current CPU architecture, the example is arm, "Start of Sections" for "Area (section) header" The number of offset bytes, and so on.

section headers lists all the sections that are contained in the file. such as. Data represents the data area,. text represents the code area, and so on. Here is an overview of the elf file format using a graph:


The left side is a static view, and the right side is the view when the link loads, both states of the same file.

/* Elf Header */typedef struct ELFHDR {unsigned chare_ident[ei_nident];/* Elf identification */elf32_halfe_type;/* Object File type */elf32_halfe_machine;/* machine */elf32_worde_version;/* object file version */elf32_addre_entry;/* virtual E Ntry point */elf32_offe_phoff;/* Program Header table offset */elf32_offe_shoff;/* section Header table offset */elf32_wor de_flags;/* processor-specific Flags */elf32_halfe_ehsize;/* ELF Header size */elf32_halfe_phentsize;/* program header Entry size */elf32_halfe_phnum;/* number of program header entries */elf32_halfe_shentsize;/* section header entry Size */ elf32_halfe_shnum;/* number of sections header Entries */elf32_halfe_shstrndx;/* section Header table ' s '    sections Header string Table "entry offset */} ELF32_EHDR;

The E_shoff is the "Start of section headers" We see above, and E_shstrndx refers to the starting index position of the sections string in the list (string table, also a section).

Let's look at the definition of the section header:

/* Section header */typedef struct {elf32_wordsh_name;/* name-index to section header   string table section */elf32 _wordsh_type;/* type */elf32_wordsh_flags;/* flags */elf32_addrsh_addr;/* address */elf32_offsh_offset;/* file offset * /elf32_wordsh_size;/* section size */elf32_wordsh_link;/* Sections Header table index link */elf32_wordsh_info;/* Extra in Formation */elf32_wordsh_addralign;/* Address alignment */elf32_wordsh_entsize;/* section entry size */} ELF32_SHDR;
We'll look at this in more detail, which can be used in the back:

Field:

Sh_name: As the name implies, section is named, type is Elf32_word, it is actually a pointer to the index value of the list

Sh_flags: Type Dynsym The type of DYNSYM indicates that the section contains the symbols to be dynamically linked, and so on

SH_ADDR: Address. The section area in memory, offset from the base address

Sh_offset: Offset. Represents the byte offset of the section to the head of the file.

Sh_size: section Area size

Sh_link: Represents a section index that has a link relationship to the current section, with different types of sections that have different interpretations. As in the above libc.so, its. Dynsym link is 2, and 2 is exactly the. Dynstr index, which is actually the index of the dynamic symbol string table

Sh_info: Some additional information

Sh_addralign: Address alignment for the section area

Sh_entsize: Size of section item (bytes)

There are so many messy looks, in fact, one thing to remember: All this information is the "reference table" that linker to use when loading Elf.

Old habits, we directly write an elf to read the applet, to verify our understanding.

/* * ELF32 Reader * Created on:2014-6 * author:chris.z * * #include <stdio.h> #include <stdlib.h> #include &l t;elf.h> #include <errno.h> #include <fcntl.h> #ifdef __x86_64 #define ELF_EHDR ELF64_EHDR #define Elf_s HDR ELF64_SHDR #define ELF_SYM elf64_sym #define ELF_REL elf64_rela #define ELF_R_SYM elf64_r_sym #define Rel_ DYN ". Rela.dyn" #define REL_PLT ". Rela.plt" #else #define ELF_EHDR elf32_ehdr #define ELF_SHDR ELF32_SHDR #defi NE elf_sym elf32_sym #define ELF_REL elf32_rel #define ELF_R_SYM elf32_r_sym #define REL_DYN ". Rel.dyn" #defin E rel_plt ". Rel.plt" #endif # define LOG (...) printf (__va_args__);/** * Lookup The start address of a specific module (libc.so ...) Within current process * Return 0 if FAILED */static uint32_t get_module_base (pid_t pid, const char *module_path) {FILE *f p = Null;char *pch = Null;char Filename[32];char line[512];uint32_t addr = 0; LOG ("[+] get libc base...\n"), if (PID < 0) snprintf (filename,sizeof (filename), "/proc/self/maps"), elsesnprintf (filename, sizeof (filename), "/proc/%d/maps", PID), if (fp = fopen ( FileName, "r")) = = NULL) {LOG ("[-]open%s failed!", filename); return 0;} while (fgets (line, sizeof, FP)) {if (Strstr (line, Module_path)) {pch = Strtok (line, "-"); addr = Strtoul (PCH, NULL, 1 6); break;}} Fclose (FP); LOG ("[+] libc base:0x%x...\n", addr); return addr;} /** * Read the elf header * return 0 if SUCCESS */static int read_header (int d, ELF_EHDR **header)//read elf header struct    ure{*header = (ELF_EHDR *) malloc (sizeof (ELF_EHDR));        if (Lseek (d, 0, Seek_set) < 0)//seek to the begin of file {free (*header);    return errno;        if (read (d, *header, sizeof (ELF_EHDR)) <= 0)//read from Begin,read sizof (elf_ehdr) bytes ==> Header {        Free (*header);    return errno = EINVAL; } return 0;} /** * Read the section header * Return 0 if SUCCESS */static int read_section_table (int d, Elf_ehdr const *header, elf_shd R **table)//read ELF Header,find section header base address{size_t size;    if (NULL = = header) return EINVAL;    size = header->e_shnum * sizeof (ELF_SHDR);//section numbers and total size *table = (ELF_SHDR *) malloc (size);        if (Lseek (d, Header->e_shoff, Seek_set) < 0)//point to sections Header,offset 0 {free (*table);    return errno;        } if (read (d, *table, size) <= 0)//read section header structure to **table {free (*table);    return errno = EINVAL; } return 0;} /** * Read the string section Table * Return 0 if SUCCESS */static int read_string_table (int d, Elf_shdr const *section, c    Har const **strings) {if (NULL = = section)//section = = >. dynstr section return EINVAL;    *strings = (char const *) malloc (section->sh_size);        if (Lseek (d, Section->sh_offset, Seek_set) < 0) {free (void *) *strings);    return errno; if (read (d, (char *) *strings, section->sh_size) <= 0)//strings include all Strings in. dynstr sections {free (void *) *strings);    return errno = EINVAL; } return 0;}    int main () {LOG ("[+]arm ELF32 reader...\n");    uint32_t lic_base = get_module_base ( -1, "/system/lib/libc.so"); int descriptor = open ("/system/lib/libc.so", o_rdonly);//open Libc.so,and return the handle elf_ehdr *header = null;//e    LF header Elf_shdr *section_header = null;//section header array ptr char const *strings = null;//string Table ptr    Read_header (Descriptor,&header);    LOG ("[+]libc.so elf header:\n");    LOG ("[+]e_ident[ei_nident]:%s\n", header->e_ident);    LOG ("[+]e_type:%d (Et_dyn:%d,dyn (Shared object file) \ n", Header->e_type,et_dyn);    LOG ("[+]e_machine:%d (em_arm:%d,advanced RISC machines) \ n", header->e_machine,em_arm);    LOG ("[+]e_shoff:%d bytes\n", Header->e_shoff);    LOG ("[+]libc.so section header:\n");    Read_section_table (Descriptor,header,§ion_header); Read_string_table (Descriptor,§ion_header[header->e_shstrndx], &strings);//header->e_shstrndx ==>the Index of string section header in section headers int i = 0; for (i = 0;i
Let's look at the results of the operation:



Look at the results of the readelf generation, Enjoy it!

Reprint Please indicate the source: Life Show

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.