summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2010-04-05 19:11:16 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2010-04-05 19:11:16 (GMT)
commitc853ed6c88a82e2859033c4111b0edb0372bc570 (patch)
treefba98d186b6e80539c1e5aad9910316c0cb3725c
parentb6fd6dc823615aaee8661e8e2365181c1ea1775f (diff)
Reorganized the ELF header (32 or 64 bits).
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@148 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
-rw-r--r--ChangeLog20
-rw-r--r--src/format/elf/Makefile.am1
-rw-r--r--src/format/elf/elf-int.c102
-rw-r--r--src/format/elf/elf-int.h3
-rw-r--r--src/format/elf/elf.c168
-rw-r--r--src/format/elf/elf_def.h71
-rw-r--r--src/format/elf/helper_x86.c2
-rw-r--r--src/format/elf/program.c96
-rw-r--r--src/format/elf/program.h41
-rw-r--r--src/format/elf/section.c17
-rw-r--r--src/format/elf/strings.c4
11 files changed, 348 insertions, 177 deletions
diff --git a/ChangeLog b/ChangeLog
index 1297ed7..3a1a18b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,25 @@
10-04-05 Cyrille Bagard <nocbos@gmail.com>
+ * src/format/elf/elf.c:
+ * src/format/elf/elf_def.h:
+ * src/format/elf/elf-int.c:
+ * src/format/elf/elf-int.h:
+ * src/format/elf/helper_x86.c:
+ Reorganize the ELF header (32 or 64 bits).
+
+ * src/format/elf/Makefile.am:
+ Add the program.[ch] files to libformatelf_la_SOURCES.
+
+ * src/format/elf/program.c:
+ * src/format/elf/program.h:
+ New entries: provide program header relative functions.
+
+ * src/format/elf/section.c:
+ * src/format/elf/strings.c:
+ Reorganize the ELF header (32 or 64 bits).
+
+10-04-05 Cyrille Bagard <nocbos@gmail.com>
+
* src/arch/x86/instruction.c:
* src/arch/x86/instruction.h:
Support some extra opcodes : popa and arpl.
diff --git a/src/format/elf/Makefile.am b/src/format/elf/Makefile.am
index f524bdf..d91e2b0 100644
--- a/src/format/elf/Makefile.am
+++ b/src/format/elf/Makefile.am
@@ -6,6 +6,7 @@ libformatelf_la_SOURCES = \
elf.h elf.c \
elf_def.h \
helper_x86.h helper_x86.c \
+ program.h program.c \
section.h section.c \
strings.h strings.c \
symbols.h symbols.c
diff --git a/src/format/elf/elf-int.c b/src/format/elf/elf-int.c
index 69363d2..85bdfc0 100644
--- a/src/format/elf/elf-int.c
+++ b/src/format/elf/elf-int.c
@@ -24,6 +24,108 @@
#include "elf-int.h"
+#include <string.h>
+
+
+
+/******************************************************************************
+* *
+* Paramètres : content = contenu binaire à parcourir. *
+* length = taille du contenu en question. *
+* header = en-tête à déterminer. [OUT] *
+* is_32b = indique si le format est en 32 ou 64 bits. [OUT] *
+* endian = boutisme reconnu dans le format. [OUT] *
+* *
+* Description : Procède à la lecture de l'en-tête d'un contenu binaire ELF. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool read_elf_header(const bin_t *content, off_t length, elf_header *header, bool *is_32b, SourceEndian *endian)
+{
+ bool result; /* Bilan à retourner */
+ off_t pos; /* Position de lecture */
+
+ result = (length >= EI_NIDENT);
+
+ pos = 0;
+
+ if (result)
+ {
+ memcpy(header->hdr32.e_ident, content, EI_NIDENT);
+ pos += EI_NIDENT;
+ }
+
+ /* Détermination de l'espace d'adressage */
+ if (result)
+ switch (header->hdr32.e_ident[EI_CLASS])
+ {
+ case ELFCLASS32:
+ *is_32b = true;
+ break;
+ case ELFDATA2MSB:
+ *is_32b = false;
+ break;
+ default:
+ result = false;
+ break;
+ }
+
+ /* Détermination du boutisme */
+ if (result)
+ switch (header->hdr32.e_ident[EI_DATA])
+ {
+ case ELFDATA2LSB:
+ *endian = SRE_LITTLE;
+ break;
+ case ELFDATA2MSB:
+ *endian = SRE_BIG;
+ break;
+ default:
+ result = false;
+ break;
+ }
+
+ if (*is_32b)
+ {
+ result &= read_u16(&header->hdr32.e_type, content, &pos, length, *endian);
+ result &= read_u16(&header->hdr32.e_machine, content, &pos, length, *endian);
+ result &= read_u32(&header->hdr32.e_version, content, &pos, length, *endian);
+ result &= read_u32(&header->hdr32.e_entry, content, &pos, length, *endian);
+ result &= read_u32(&header->hdr32.e_phoff, content, &pos, length, *endian);
+ result &= read_u32(&header->hdr32.e_shoff, content, &pos, length, *endian);
+ result &= read_u32(&header->hdr32.e_flags, content, &pos, length, *endian);
+ result &= read_u16(&header->hdr32.e_ehsize, content, &pos, length, *endian);
+ result &= read_u16(&header->hdr32.e_phentsize, content, &pos, length, *endian);
+ result &= read_u16(&header->hdr32.e_phnum, content, &pos, length, *endian);
+ result &= read_u16(&header->hdr32.e_shentsize, content, &pos, length, *endian);
+ result &= read_u16(&header->hdr32.e_shnum, content, &pos, length, *endian);
+ result &= read_u16(&header->hdr32.e_shstrndx, content, &pos, length, *endian);
+ }
+ else
+ {
+ result &= read_u16(&header->hdr64.e_type, content, &pos, length, *endian);
+ result &= read_u16(&header->hdr64.e_machine, content, &pos, length, *endian);
+ result &= read_u32(&header->hdr64.e_version, content, &pos, length, *endian);
+ result &= read_u64(&header->hdr64.e_entry, content, &pos, length, *endian);
+ result &= read_u64(&header->hdr64.e_phoff, content, &pos, length, *endian);
+ result &= read_u64(&header->hdr64.e_shoff, content, &pos, length, *endian);
+ result &= read_u32(&header->hdr64.e_flags, content, &pos, length, *endian);
+ result &= read_u16(&header->hdr64.e_ehsize, content, &pos, length, *endian);
+ result &= read_u16(&header->hdr64.e_phentsize, content, &pos, length, *endian);
+ result &= read_u16(&header->hdr64.e_phnum, content, &pos, length, *endian);
+ result &= read_u16(&header->hdr64.e_shentsize, content, &pos, length, *endian);
+ result &= read_u16(&header->hdr64.e_shnum, content, &pos, length, *endian);
+ result &= read_u16(&header->hdr64.e_shstrndx, content, &pos, length, *endian);
+ }
+
+ return result;
+
+}
+
/******************************************************************************
* *
diff --git a/src/format/elf/elf-int.h b/src/format/elf/elf-int.h
index f7fd804..34570f9 100644
--- a/src/format/elf/elf-int.h
+++ b/src/format/elf/elf-int.h
@@ -52,6 +52,9 @@ struct _GElfFormatClass
+/* Procède à la lecture de l'en-tête d'un contenu binaire ELF. */
+bool read_elf_header(const bin_t *, off_t, elf_header *, bool *, SourceEndian *);
+
/* Procède à la lecture d'une en-tête de programme ELF. */
bool read_elf_program_header(const GElfFormat *, off_t *, elf_phdr *);
diff --git a/src/format/elf/elf.c b/src/format/elf/elf.c
index e7bb48c..ccd00ae 100644
--- a/src/format/elf/elf.c
+++ b/src/format/elf/elf.c
@@ -25,10 +25,12 @@
#include <malloc.h>
+#include <stddef.h>
#include <string.h>
#include "elf-int.h"
+#include "program.h"
#include "section.h"
#include "strings.h"
#include "symbols.h"
@@ -50,9 +52,6 @@ static void g_elf_format_class_init(GElfFormatClass *);
/* Initialise une instance de format d'exécutable ELF. */
static void g_elf_format_init(GElfFormat *);
-/* Procède à la lecture de l'en-tête d'un contenu binaire. */
-static bool read_elf_header(const bin_t *, off_t, elf_header *, bool *, SourceEndian *);
-
/* Indique le type d'architecture visée par le format. */
static FormatTargetMachine g_elf_format_get_target_machine(const GElfFormat *);
@@ -152,126 +151,6 @@ static void g_elf_format_init(GElfFormat *format)
* *
* Paramètres : content = contenu binaire à parcourir. *
* length = taille du contenu en question. *
-* header = en-tête à déterminer. [OUT] *
-* is_32b = indique si le format est en 32 ou 64 bits. [OUT] *
-* endian = boutisme reconnu dans le format. [OUT] *
-* *
-* Description : Procède à la lecture de l'en-tête d'un contenu binaire. *
-* *
-* Retour : Bilan de l'opération. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static bool read_elf_header(const bin_t *content, off_t length, elf_header *header, bool *is_32b, SourceEndian *endian)
-{
- bool result; /* Bilan à retourner */
- off_t pos; /* Position de lecture */
-
- result = (length >= EI_NIDENT);
-
- pos = 0;
-
- if (result)
- {
- memcpy(header->e_ident, content, EI_NIDENT);
- pos += EI_NIDENT;
- }
-
- /* Détermination de l'espace d'adressage */
- if (result)
- switch (header->e_ident[EI_CLASS])
- {
- case ELFCLASS32:
- *is_32b = true;
- break;
- case ELFDATA2MSB:
- *is_32b = false;
- break;
- default:
- result = false;
- break;
- }
-
- /* Détermination du boutisme */
- if (result)
- switch (header->e_ident[EI_DATA])
- {
- case ELFDATA2LSB:
- *endian = SRE_LITTLE;
- break;
- case ELFDATA2MSB:
- *endian = SRE_BIG;
- break;
- default:
- result = false;
- break;
- }
-
- if (result)
- result = read_u16(&header->e_type, content, &pos, length, *endian);
-
- if (result)
- result = read_u16(&header->e_machine, content, &pos, length, *endian);
-
- if (result)
- result = read_u32(&header->e_version, content, &pos, length, *endian);
-
- if (result)
- {
- if (*is_32b)
- result = read_u32(&header->e_entry.addr32, content, &pos, length, *endian);
- else
- result = read_u64(&header->e_entry.addr64, content, &pos, length, *endian);
- }
-
- if (result)
- {
- if (*is_32b)
- result = read_u32(&header->e_phoff.off32, content, &pos, length, *endian);
- else
- result = read_u64(&header->e_phoff.off64, content, &pos, length, *endian);
- }
-
- if (result)
- {
- if (*is_32b)
- result = read_u32(&header->e_shoff.off32, content, &pos, length, *endian);
- else
- result = read_u64(&header->e_shoff.off64, content, &pos, length, *endian);
- }
-
- if (result)
- result = read_u32(&header->e_flags, content, &pos, length, *endian);
-
- if (result)
- result = read_u16(&header->e_ehsize, content, &pos, length, *endian);
-
- if (result)
- result = read_u16(&header->e_phentsize, content, &pos, length, *endian);
-
- if (result)
- result = read_u16(&header->e_phnum, content, &pos, length, *endian);
-
- if (result)
- result = read_u16(&header->e_shentsize, content, &pos, length, *endian);
-
- if (result)
- result = read_u16(&header->e_shnum, content, &pos, length, *endian);
-
- if (result)
- result = read_u16(&header->e_shstrndx, content, &pos, length, *endian);
-
- return result;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : content = contenu binaire à parcourir. *
-* length = taille du contenu en question. *
* *
* Description : Prend en charge un nouveau format ELF. *
* *
@@ -298,25 +177,31 @@ GBinFormat *g_elf_format_new(const bin_t *content, off_t length)
/* Vérification des tailles d'entrée de table */
- if (result->header.e_phentsize != ELF_SIZEOF_PHDR(result))
+ if (ELF_HDR(result, result->header, e_phentsize) != ELF_SIZEOF_PHDR(result))
{
- log_variadic_message(LMT_BAD_BINARY, _("Corrupted program header size (%hu); fixed !"),
- result->header.e_phentsize);
- result->header.e_phentsize = ELF_SIZEOF_PHDR(result);
+ log_variadic_message(LMT_BAD_BINARY, _("Corrupted program header size (%hu); fixed ! -- replacing 0x%04hx by 0x%04hx at offset 0x%x"),
+ ELF_HDR(result, result->header, e_phentsize),
+ ELF_HDR(result, result->header, e_phentsize),
+ ELF_SIZEOF_PHDR(result), ELF_HDR_OFFSET_OF(result, e_phentsize));
+ ELF_HDR_SET(result, result->header, e_phentsize, ELF_SIZEOF_PHDR(result));
}
- if (result->header.e_shentsize != ELF_SIZEOF_SHDR(result))
+ if (ELF_HDR(result, result->header, e_shentsize) != ELF_SIZEOF_SHDR(result))
{
- log_variadic_message(LMT_BAD_BINARY, _("Corrupted section header size (%hu); fixed !"),
- result->header.e_shentsize);
- result->header.e_shentsize = ELF_SIZEOF_SHDR(result);
+ log_variadic_message(LMT_BAD_BINARY, _("Corrupted section header size (%hu); fixed ! -- replacing 0x%04hx by 0x%04hx at offset 0x%x"),
+ ELF_HDR(result, result->header, e_shentsize),
+ ELF_HDR(result, result->header, e_shentsize),
+ ELF_SIZEOF_SHDR(result), ELF_HDR_OFFSET_OF(result, e_shentsize));
+ ELF_HDR_SET(result, result->header, e_shentsize, ELF_SIZEOF_SHDR(result));
}
/* FIXME : à améliorer */
- if ((result->header.e_shnum * result->header.e_shentsize) >= length)
+ if ((ELF_HDR(result, result->header, e_shnum) * ELF_HDR(result, result->header, e_shentsize)) >= length)
{
- log_variadic_message(LMT_BAD_BINARY, ("Suspicious section table (bigger than the binary !) ; reset !"));
- result->header.e_shnum = 0;
+ log_variadic_message(LMT_BAD_BINARY, ("Suspicious section table (bigger than the binary !) ; reset ! -- replacing 0x%04hx by 0x%04hx at offset 0x%x"),
+ ELF_HDR(result, result->header, e_shnum),
+ 0, ELF_HDR_OFFSET_OF(result, e_shnum));
+ ELF_HDR_SET(result, result->header, e_shnum, 0);
}
@@ -358,7 +243,7 @@ static FormatTargetMachine g_elf_format_get_target_machine(const GElfFormat *for
{
FormatTargetMachine result; /* Identifiant à retourner */
- switch (format->header.e_machine)
+ switch (ELF_HDR(format, format->header, e_machine))
{
case EM_MIPS:
result = FTM_MIPS;
@@ -394,7 +279,7 @@ static FormatTargetMachine g_elf_format_get_target_machine(const GElfFormat *for
static vmpa_t g_elf_format_get_entry_point(const GElfFormat *format)
{
- return (format->is_32b ? format->header.e_entry.addr32 : format->header.e_entry.addr64);
+ return ELF_HDR(format, format->header, e_entry);
}
@@ -427,11 +312,11 @@ static GBinPart **g_elf_format_get_parts(const GElfFormat *format, size_t *count
result = NULL;
*count = 0;
- has_strings = find_elf_section_by_index(format, format->header.e_shstrndx, &strings);
+ has_strings = find_elf_section_by_index(format, ELF_HDR(format, format->header, e_shstrndx), &strings);
/* Première tentative : les sections */
- for (i = 0; i < format->header.e_shnum; i++)
+ for (i = 0; i < ELF_HDR(format, format->header, e_shnum); i++)
{
if (!find_elf_section_by_index(format, i, &section))
continue;
@@ -465,9 +350,10 @@ static GBinPart **g_elf_format_get_parts(const GElfFormat *format, size_t *count
/* En désespoir de cause, on se rabbat sur les parties de programme directement */
if (*count == 0)
- for (i = 0; i < format->header.e_phnum; i++)
+ for (i = 0; i < ELF_HDR(format, format->header, e_phnum); i++)
{
- offset = ELF_OFF(format, format->header.e_phoff) + format->header.e_phentsize * i;
+ offset = ELF_HDR(format, format->header, e_phoff)
+ + ELF_HDR(format, format->header, e_phentsize) * i;
if (!read_elf_program_header(format, &offset, &phdr))
continue;
@@ -517,7 +403,7 @@ static bool g_elf_format_translate_address_into_offset(const GElfFormat *format,
result = translate_address_into_offset_using_elf_sections(format, addr, pos);
if (!result)
- /* TODO : prgm... */;
+ result = translate_address_into_offset_using_elf_programs(format, addr, pos);
return result;
diff --git a/src/format/elf/elf_def.h b/src/format/elf/elf_def.h
index d063dcf..f125106 100644
--- a/src/format/elf/elf_def.h
+++ b/src/format/elf/elf_def.h
@@ -29,43 +29,42 @@
-/* Adresses virtuelles */
-typedef union _elf_addr
-{
- uint32_t addr32; /* Elf 32 bits */
- uint64_t addr64; /* Elf 64 bits */
-
-} elf_addr;
-
-/* Positions dans le fichier */
-typedef union _elf_off
-{
- uint32_t off32; /* Elf 32 bits */
- uint64_t off64; /* Elf 64 bits */
-
-} elf_off;
-
-
-#define ELF_OFF(fmt, off) (fmt->is_32b ? (off).off32 : (off).off64)
+/* ---------------------------- EN-TETE DES FICHIERS ELF ---------------------------- */
+#define EI_NIDENT 16
-/* ---------------------------- EN-TETE DES FICHIERS ELF ---------------------------- */
+/* En-tête de fichier ELF (32 et 64 bits) */
-#define EI_NIDENT 16
+typedef struct _elf32_header
+{
+ uint8_t e_ident[EI_NIDENT]; /* Magic number + informations */
+ uint16_t e_type; /* Type de fichier */
+ uint16_t e_machine; /* Architecture */
+ uint32_t e_version; /* Version du type de fichier */
+ uint32_t e_entry; /* Point d'entrée du programme */
+ uint32_t e_phoff; /* Début de la table 'Program' */
+ uint32_t e_shoff; /* Début de la table 'Section' */
+ uint32_t e_flags; /* Prop. spécifiques au proc. */
+ uint16_t e_ehsize; /* Taille de l'en-tête en oct. */
+ uint16_t e_phentsize; /* Taille d'une entrée Program */
+ uint16_t e_phnum; /* Nombre d'éléments 'Program' */
+ uint16_t e_shentsize; /* Taille d'une entrée Section */
+ uint16_t e_shnum; /* Nombre d'éléments 'Section' */
+ uint16_t e_shstrndx; /* Indice de la section chaînes*/
+} elf32_header;
-/* En-tête de fichier ELF */
-typedef struct _elf_header
+typedef struct _elf64_header
{
uint8_t e_ident[EI_NIDENT]; /* Magic number + informations */
uint16_t e_type; /* Type de fichier */
uint16_t e_machine; /* Architecture */
uint32_t e_version; /* Version du type de fichier */
- elf_addr e_entry; /* Point d'entrée du programme */
- elf_off e_phoff; /* Début de la table 'Program' */
- elf_off e_shoff; /* Début de la table 'Section' */
+ uint64_t e_entry; /* Point d'entrée du programme */
+ uint64_t e_phoff; /* Début de la table 'Program' */
+ uint64_t e_shoff; /* Début de la table 'Section' */
uint32_t e_flags; /* Prop. spécifiques au proc. */
uint16_t e_ehsize; /* Taille de l'en-tête en oct. */
uint16_t e_phentsize; /* Taille d'une entrée Program */
@@ -74,9 +73,31 @@ typedef struct _elf_header
uint16_t e_shnum; /* Nombre d'éléments 'Section' */
uint16_t e_shstrndx; /* Indice de la section chaînes*/
+} elf64_header;
+
+typedef union _elf_header
+{
+ elf32_header hdr32; /* Version 32 bits */
+ elf64_header hdr64; /* Version 64 bits */
+
} elf_header;
+#define ELF_HDR(fmt, hdr, fld) (fmt->is_32b ? (hdr).hdr32.fld : (hdr).hdr64.fld)
+
+#define ELF_HDR_SET(fmt, hdr, fld, val) \
+ do \
+ { \
+ if (fmt->is_32b) (hdr).hdr32.fld = val; \
+ else (hdr).hdr64.fld = val; \
+ } \
+ while (0)
+
+#define ELF_HDR_OFFSET_OF(fmt, fld) (fmt->is_32b ? offsetof(elf32_header, fld) : offsetof(elf64_header, fld))
+
+#define ELF_SIZEOF_HDR(fmt) (fmt->is_32b ? sizeof(elf32_header) : sizeof(elf64_header))
+
+
/* Composition du champ e_ident */
diff --git a/src/format/elf/helper_x86.c b/src/format/elf/helper_x86.c
index 02d4785..862b112 100644
--- a/src/format/elf/helper_x86.c
+++ b/src/format/elf/helper_x86.c
@@ -160,7 +160,7 @@ bool find_elf_x86_dynamic_symbols(GElfFormat *format, const elf_shdr *plt, const
instructions = decode_elf_relocations(format, plt, &count);
- switch (format->header.e_type)
+ switch (ELF_HDR(format, format->header, e_type))
{
case ET_EXEC:
translate_exe_elf_relocations(format, instructions, count);
diff --git a/src/format/elf/program.c b/src/format/elf/program.c
new file mode 100644
index 0000000..f55b7c7
--- /dev/null
+++ b/src/format/elf/program.c
@@ -0,0 +1,96 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * program.c - gestion des en-têtes de programme d'un ELF
+ *
+ * Copyright (C) 2010 Cyrille Bagard
+ *
+ * This file is part of OpenIDA.
+ *
+ * OpenIDA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * OpenIDA is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "program.h"
+
+
+#include "elf-int.h"
+
+
+
+/******************************************************************************
+* *
+* Paramètres : format = description de l'exécutable à consulter. *
+* index = indice de la section recherchée. *
+* program = ensemble d'informations à faire remonter. [OUT] *
+* *
+* Description : Recherche un programme donné au sein de binaire par indice. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool find_elf_program_by_index(const GElfFormat *format, uint16_t index, elf_phdr *program)
+{
+ off_t offset; /* Emplacement à venir lire */
+
+ if (index >= ELF_HDR(format, format->header, e_phnum)) return false;
+
+ offset = ELF_HDR(format, format->header, e_phoff)
+ + ELF_HDR(format, format->header, e_phentsize) * index;
+
+ return read_elf_program_header(format, &offset, program);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : format = description de l'exécutable à consulter. *
+* addr = adresse virtuelle à retrouver. *
+* pos = position correspondante. [OUT] *
+* *
+* Description : Fournit la position correspondant à une adresse virtuelle. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool translate_address_into_offset_using_elf_programs(const GElfFormat *format, vmpa_t addr, off_t *pos)
+{
+ bool result; /* Bilan à retourner */
+ uint16_t i; /* Boucle de parcours */
+ elf_phdr program; /* Programme à analyser */
+
+ result = false;
+
+ for (i = 0; i < ELF_HDR(format, format->header, e_phnum) && !result; i++)
+ {
+ find_elf_program_by_index(format, i, &program);
+
+ if (ELF_PHDR(format, program, p_vaddr) <= addr
+ && addr < (ELF_PHDR(format, program, p_vaddr) + ELF_PHDR(format, program, p_filesz)))
+ {
+ *pos = ELF_PHDR(format, program, p_offset) + addr - ELF_PHDR(format, program, p_vaddr);
+ result = true;
+ }
+
+ }
+
+ return result;
+
+}
diff --git a/src/format/elf/program.h b/src/format/elf/program.h
new file mode 100644
index 0000000..1718ca7
--- /dev/null
+++ b/src/format/elf/program.h
@@ -0,0 +1,41 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * program.h - prototypes pour la gestion des en-têtes de programme d'un ELF
+ *
+ * Copyright (C) 2010 Cyrille Bagard
+ *
+ * This file is part of OpenIDA.
+ *
+ * OpenIDA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * OpenIDA is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _FORMAT_ELF_PROGRAM_H
+#define _FORMAT_ELF_PROGRAM_H
+
+
+#include "elf.h"
+#include "elf_def.h"
+
+
+
+/* Recherche un programme donné au sein de binaire par indice. */
+bool find_elf_program_by_index(const GElfFormat *, uint16_t, elf_phdr *);
+
+/* Fournit la position correspondant à une adresse virtuelle. */
+bool translate_address_into_offset_using_elf_programs(const GElfFormat *, vmpa_t, off_t *);
+
+
+
+#endif /* _FORMAT_ELF_PROGRAM_H */
diff --git a/src/format/elf/section.c b/src/format/elf/section.c
index cb6a04a..b39ebee 100644
--- a/src/format/elf/section.c
+++ b/src/format/elf/section.c
@@ -50,9 +50,10 @@ bool find_elf_section_by_index(const GElfFormat *format, uint16_t index, elf_shd
{
off_t offset; /* Emplacement à venir lire */
- if (index >= format->header.e_shnum) return false;
+ if (index >= ELF_HDR(format, format->header, e_shnum)) return false;
- offset = ELF_OFF(format, format->header.e_shoff) + format->header.e_shentsize * index;
+ offset = ELF_HDR(format, format->header, e_shoff)
+ + ELF_HDR(format, format->header, e_shentsize) * index;
return read_elf_section_header(format, offset, section);
@@ -80,12 +81,12 @@ bool find_elf_section_by_name(const GElfFormat *format, const char *name, elf_sh
uint16_t i; /* Boucle de parcours */
const char *secname; /* Nom d'une section analysée */
- if (!find_elf_section_by_index(format, format->header.e_shstrndx, &strings))
+ if (!find_elf_section_by_index(format, ELF_HDR(format, format->header, e_shstrndx), &strings))
return false;
result = false;
- for (i = 0; i < format->header.e_shnum && !result; i++)
+ for (i = 0; i < ELF_HDR(format, format->header, e_shnum) && !result; i++)
{
find_elf_section_by_index(format, i, section);
@@ -124,7 +125,7 @@ bool find_elf_section_by_virtual_address(const GElfFormat *format, uint32_t addr
result = false;
- for (i = 0; i < format->header.e_shnum && !result; i++)
+ for (i = 0; i < ELF_HDR(format, format->header, e_shnum) && !result; i++)
{
find_elf_section_by_index(format, i, section);
@@ -160,7 +161,7 @@ bool find_elf_sections_by_type(const GElfFormat *format, uint32_t type, elf_shdr
*sections = NULL;
*count = 0;
- for (i = 0; i < format->header.e_shnum; i++)
+ for (i = 0; i < ELF_HDR(format, format->header, e_shnum); i++)
{
find_elf_section_by_index(format, i, &section);
@@ -299,7 +300,7 @@ bool translate_address_into_offset_using_elf_sections(const GElfFormat *format,
result = false;
- for (i = 0; i < format->header.e_shnum && !result; i++)
+ for (i = 0; i < ELF_HDR(format, format->header, e_shnum) && !result; i++)
{
find_elf_section_by_index(format, i, &section);
@@ -339,7 +340,7 @@ bool translate_offset_into_address_using_elf_sections(const GElfFormat *format,
result = false;
- for (i = 0; i < format->header.e_shnum && !result; i++)
+ for (i = 0; i < ELF_HDR(format, format->header, e_shnum) && !result; i++)
{
find_elf_section_by_index(format, i, &section);
diff --git a/src/format/elf/strings.c b/src/format/elf/strings.c
index 157d3b5..6fb61b5 100644
--- a/src/format/elf/strings.c
+++ b/src/format/elf/strings.c
@@ -109,9 +109,9 @@ bool find_all_elf_strings(GElfFormat *format)
if (!got_string)
{
length = G_BIN_FORMAT(format)->length;
- length = MIN(length, format->header.e_phnum * ELF_SIZEOF_PHDR(format));
+ length = MIN(length, ELF_HDR(format, format->header, e_phnum) * ELF_SIZEOF_PHDR(format));
- for (iter = ELF_OFF(format, format->header.e_phoff); iter < length; )
+ for (iter = ELF_HDR(format, format->header, e_phoff); iter < length; )
{
if (!read_elf_program_header(format, &iter, &phdr))
continue;