summaryrefslogtreecommitdiff
path: root/src/format
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2010-03-11 22:40:17 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2010-03-11 22:40:17 (GMT)
commita6acb5629572e6da4d72f4419b01672c2ea5ddf2 (patch)
treebed9fa7dfa455de09fdc474ebbae7ce985bb5517 /src/format
parent1991abdadab865243168c4ff8f744e07110a01ad (diff)
Added first steps for a full PE support.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@143 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
Diffstat (limited to 'src/format')
-rw-r--r--src/format/Makefile.am5
-rw-r--r--src/format/elf/elf.c3
-rw-r--r--src/format/format.c2
-rw-r--r--src/format/format.h1
-rwxr-xr-xsrc/format/pe/Makefile.am7
-rw-r--r--src/format/pe/e_pe.c138
-rw-r--r--src/format/pe/pe-int.c359
-rw-r--r--src/format/pe/pe-int.h96
-rw-r--r--src/format/pe/pe.c386
-rw-r--r--src/format/pe/pe.h62
-rw-r--r--src/format/pe/pe_def.h343
-rw-r--r--src/format/pe/section.c59
-rw-r--r--src/format/pe/section.h (renamed from src/format/pe/e_pe.h)27
-rw-r--r--src/format/pe/symbols.c136
-rw-r--r--src/format/pe/symbols.h36
15 files changed, 1433 insertions, 227 deletions
diff --git a/src/format/Makefile.am b/src/format/Makefile.am
index 838cb99..82264bb 100644
--- a/src/format/Makefile.am
+++ b/src/format/Makefile.am
@@ -23,7 +23,8 @@ libformat_la_SOURCES = \
libformat_la_LIBADD = \
dwarf/libformatdwarf.la \
elf/libformatelf.la \
- mangling/libformatmangling.la
+ mangling/libformatmangling.la \
+ pe/libformatpe.la
# libformat_la_LIBADD = \
# dwarf/libformatdwarf.la \
@@ -41,5 +42,5 @@ AM_CPPFLAGS =
AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS)
-SUBDIRS = dwarf elf mangling
+SUBDIRS = dwarf elf mangling pe
#SUBDIRS = dwarf elf java mangling pe
diff --git a/src/format/elf/elf.c b/src/format/elf/elf.c
index b703dcf..e7bb48c 100644
--- a/src/format/elf/elf.c
+++ b/src/format/elf/elf.c
@@ -134,7 +134,7 @@ static void g_elf_format_class_init(GElfFormatClass *klass)
static void g_elf_format_init(GElfFormat *format)
{
- GExeFormat *exe_format;
+ GExeFormat *exe_format; /* Format parent à constituer */
exe_format = G_EXE_FORMAT(format);
@@ -436,7 +436,6 @@ static GBinPart **g_elf_format_get_parts(const GElfFormat *format, size_t *count
if (!find_elf_section_by_index(format, i, &section))
continue;
-
if (ELF_SHDR(format, section, sh_flags) & SHF_EXECINSTR)
{
part = g_binary_part_new();
diff --git a/src/format/format.c b/src/format/format.c
index 0ffbfe0..00c4538 100644
--- a/src/format/format.c
+++ b/src/format/format.c
@@ -30,6 +30,7 @@
#include "format-int.h"
#include "dwarf/dwarf.h"
#include "elf/elf.h"
+#include "pe/pe.h"
#include "../panels/log.h"
@@ -334,6 +335,7 @@ bool init_all_formats(void)
{
register_format(FID_ELF, _("ELF"), FMT_EXEC, elf_is_matching, g_elf_format_new);
register_format(FID_DWARF, _("Dwarf"), FMT_DEBUG, dwarf_is_matching, g_dwarf_format_new);
+ register_format(FID_PE, _("PE"), FMT_EXEC, pe_is_matching, g_pe_format_new);
return true;
diff --git a/src/format/format.h b/src/format/format.h
index a4de552..ccd3ee7 100644
--- a/src/format/format.h
+++ b/src/format/format.h
@@ -83,6 +83,7 @@ typedef enum _FormatIdentifier
{
FID_ELF, /* Format ELF */
FID_DWARF, /* Format Dwarf */
+ FID_PE, /* Format PE */
FID_COUNT
diff --git a/src/format/pe/Makefile.am b/src/format/pe/Makefile.am
index 45f2f6b..c977653 100755
--- a/src/format/pe/Makefile.am
+++ b/src/format/pe/Makefile.am
@@ -2,8 +2,11 @@
noinst_LTLIBRARIES = libformatpe.la
libformatpe_la_SOURCES = \
- e_pe.h e_pe.c \
- pe-int.h
+ pe-int.h pe-int.c \
+ pe.h pe.c \
+ pe_def.h \
+ section.h section.c \
+ symbols.h symbols.c
libformatpe_la_LDFLAGS =
diff --git a/src/format/pe/e_pe.c b/src/format/pe/e_pe.c
deleted file mode 100644
index a10f075..0000000
--- a/src/format/pe/e_pe.c
+++ /dev/null
@@ -1,138 +0,0 @@
-
-/* OpenIDA - Outil d'analyse de fichiers binaires
- * e_pe.c - support du format Portable Executable
- *
- * Copyright (C) 2008 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 "e_pe.h"
-
-
-#include <malloc.h>
-#include <string.h>
-
-
-#include "pe-int.h"
-
-
-
-/******************************************************************************
-* *
-* Paramètres : content = contenu binaire à parcourir. *
-* length = taille du contenu en question. *
-* *
-* Description : Indique si le format peut être pris en charge ici. *
-* *
-* Retour : true si la réponse est positive, false sinon. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-bool pe_is_matching(const uint8_t *content, off_t length)
-{
- bool result; /* Bilan à faire connaître */
- image_dos_header dos_header; /* En-tête DOS */
-
- result = false;
-
- if (length >= 2)
- {
- result = (strncmp((const char *)content, "\x4d\x5a" /* MZ */, 2) == 0);
- result &= length >= sizeof(image_dos_header);
- }
-
- if (result)
- {
- memcpy(&dos_header, content, sizeof(image_dos_header));
-
- result = length >= (dos_header.e_lfanew + 4);
-
- result &= (strncmp((const char *)&content[dos_header.e_lfanew],
- "\x50\x45\x00\x00" /* PE00 */, 4) == 0);
-
- }
-
- return result;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : content = contenu binaire à parcourir. *
-* length = taille du contenu en question. *
-* *
-* Description : Prend en charge une nouvelle classe PE. *
-* *
-* Retour : Adresse de la structure mise en place ou NULL en cas d'échec.*
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-exe_format *load_pe(const uint8_t *content, off_t length)
-{
- pe_format *result; /* Adresse à retourner */
- off_t pos; /* Point d'analyse */
-
- result = (pe_format *)calloc(1, sizeof(pe_format));
-
- EXE_FORMAT(result)->content = content;
- EXE_FORMAT(result)->length = length;
-
- pos = 0;
-
-
-
-
-
-
- return EXE_FORMAT(result);
-
- ldp_error:
-
- unload_pe(result);
-
- return NULL;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : format = description de l'exécutable à supprimer. *
-* *
-* Description : Efface la prise en charge une nouvelle classe PE. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-void unload_pe(pe_format *format)
-{
-
-
-
-
- free(format);
-
-}
diff --git a/src/format/pe/pe-int.c b/src/format/pe/pe-int.c
new file mode 100644
index 0000000..3db8318
--- /dev/null
+++ b/src/format/pe/pe-int.c
@@ -0,0 +1,359 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * pe-int.c - structures internes du format Portable Executable
+ *
+ * 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 "pe-int.h"
+
+
+#include <malloc.h>
+#include <string.h>
+
+
+#include "../../common/endianness.h"
+
+
+
+/******************************************************************************
+* *
+* Paramètres : format = informations chargées à consulter. *
+* pos = position de début de lecture. [OUT] *
+* header = structure lue à retourner. [OUT] *
+* *
+* Description : Procède à la lecture d'une en-tête de programme DOS. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool read_dos_image_header(const GPeFormat *format, off_t *pos, image_dos_header *header)
+{
+ bool result; /* Bilan à retourner */
+ const bin_t *content; /* Contenu binaire à lire */
+ off_t length; /* Taille totale du contenu */
+ size_t i; /* Boucle de parcours */
+
+ content = G_BIN_FORMAT(format)->content;
+ length = G_BIN_FORMAT(format)->length;
+
+ result = read_u16(&header->e_magic, content, pos, length, SRE_LITTLE);
+ result &= read_u16(&header->e_cblp, content, pos, length, SRE_LITTLE);
+ result &= read_u16(&header->e_cp, content, pos, length, SRE_LITTLE);
+ result &= read_u16(&header->e_crlc, content, pos, length, SRE_LITTLE);
+ result &= read_u16(&header->e_cparhdr, content, pos, length, SRE_LITTLE);
+ result &= read_u16(&header->e_minalloc, content, pos, length, SRE_LITTLE);
+ result &= read_u16(&header->e_maxalloc, content, pos, length, SRE_LITTLE);
+ result &= read_u16(&header->e_ss, content, pos, length, SRE_LITTLE);
+ result &= read_u16(&header->e_sp, content, pos, length, SRE_LITTLE);
+ result &= read_u16(&header->e_csum, content, pos, length, SRE_LITTLE);
+ result &= read_u16(&header->e_ip, content, pos, length, SRE_LITTLE);
+ result &= read_u16(&header->e_cs, content, pos, length, SRE_LITTLE);
+ result &= read_u16(&header->e_lfarlc, content, pos, length, SRE_LITTLE);
+ result &= read_u16(&header->e_ovno, content, pos, length, SRE_LITTLE);
+
+ for (i = 0; i < 4 && result; i++)
+ result = read_u16(&header->e_res[i], content, pos, length, SRE_LITTLE);
+
+ result &= read_u16(&header->e_oemid, content, pos, length, SRE_LITTLE);
+ result &= read_u16(&header->e_oeminfo, content, pos, length, SRE_LITTLE);
+
+ for (i = 0; i < 10 && result; i++)
+ result = read_u16(&header->e_res2[i], content, pos, length, SRE_LITTLE);
+
+ result &= read_u32(&header->e_lfanew, content, pos, length, SRE_LITTLE);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : format = informations chargées à consulter. *
+* pos = position de début de lecture. [OUT] *
+* header = structure lue à retourner. [OUT] *
+* *
+* Description : Procède à la lecture d'une en-tête de programme PE (1). *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool read_pe_file_header(const GPeFormat *format, off_t *pos, image_file_header *header)
+{
+ bool result; /* Bilan à retourner */
+ const bin_t *content; /* Contenu binaire à lire */
+ off_t length; /* Taille totale du contenu */
+
+ content = G_BIN_FORMAT(format)->content;
+ length = G_BIN_FORMAT(format)->length;
+
+ result = read_u16(&header->machine, content, pos, length, SRE_LITTLE);
+ result &= read_u16(&header->number_of_sections, content, pos, length, SRE_LITTLE);
+ result &= read_u32(&header->time_date_stamp, content, pos, length, SRE_LITTLE);
+ result &= read_u32(&header->pointer_to_symbol_table, content, pos, length, SRE_LITTLE);
+ result &= read_u32(&header->number_of_symbols, content, pos, length, SRE_LITTLE);
+ result &= read_u16(&header->size_of_optional_header, content, pos, length, SRE_LITTLE);
+ result &= read_u16(&header->characteristics, content, pos, length, SRE_LITTLE);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : format = informations chargées à consulter. *
+* pos = position de début de lecture. [OUT] *
+* header = structure lue à retourner. [OUT] *
+* *
+* Description : Procède à la lecture d'une en-tête de programme PE (2). *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool read_pe_optional_header(const GPeFormat *format, off_t *pos, image_optional_header *header)
+{
+ bool result; /* Bilan à retourner */
+ const bin_t *content; /* Contenu binaire à lire */
+ off_t length; /* Taille totale du contenu */
+ uint32_t i; /* Boucle de parcours */
+
+ content = G_BIN_FORMAT(format)->content;
+ length = G_BIN_FORMAT(format)->length;
+
+ result = read_u16(&header->magic, content, pos, length, SRE_LITTLE);
+ result &= read_u8(&header->major_linker_version, content, pos, length, SRE_LITTLE);
+ result &= read_u8(&header->minor_linker_version, content, pos, length, SRE_LITTLE);
+ result &= read_u32(&header->size_of_code, content, pos, length, SRE_LITTLE);
+ result &= read_u32(&header->size_of_initialized_data, content, pos, length, SRE_LITTLE);
+ result &= read_u32(&header->size_of_uninitialized_data, content, pos, length, SRE_LITTLE);
+ result &= read_u32(&header->address_of_entry_point, content, pos, length, SRE_LITTLE);
+ result &= read_u32(&header->base_of_code, content, pos, length, SRE_LITTLE);
+ result &= read_u32(&header->base_of_data, content, pos, length, SRE_LITTLE);
+ result &= read_u32(&header->image_base, content, pos, length, SRE_LITTLE);
+ result &= read_u32(&header->section_alignment, content, pos, length, SRE_LITTLE);
+ result &= read_u32(&header->file_alignment, content, pos, length, SRE_LITTLE);
+ result &= read_u16(&header->major_operating_system_version, content, pos, length, SRE_LITTLE);
+ result &= read_u16(&header->minor_operating_system_version, content, pos, length, SRE_LITTLE);
+ result &= read_u16(&header->major_image_version, content, pos, length, SRE_LITTLE);
+ result &= read_u16(&header->minor_image_version, content, pos, length, SRE_LITTLE);
+ result &= read_u16(&header->major_subsystem_version, content, pos, length, SRE_LITTLE);
+ result &= read_u16(&header->minor_subsystem_version, content, pos, length, SRE_LITTLE);
+ result &= read_u32(&header->win32_version_value, content, pos, length, SRE_LITTLE);
+ result &= read_u32(&header->size_of_image, content, pos, length, SRE_LITTLE);
+ result &= read_u32(&header->size_of_headers, content, pos, length, SRE_LITTLE);
+ result &= read_u32(&header->checksum, content, pos, length, SRE_LITTLE);
+ result &= read_u16(&header->subsystem, content, pos, length, SRE_LITTLE);
+ result &= read_u16(&header->dll_characteristics, content, pos, length, SRE_LITTLE);
+ result &= read_u32(&header->size_of_stack_reserve, content, pos, length, SRE_LITTLE);
+ result &= read_u32(&header->size_of_stack_commit, content, pos, length, SRE_LITTLE);
+ result &= read_u32(&header->size_of_heap_reserve, content, pos, length, SRE_LITTLE);
+ result &= read_u32(&header->size_of_heap_commit, content, pos, length, SRE_LITTLE);
+ result &= read_u32(&header->loader_flags, content, pos, length, SRE_LITTLE);
+ result &= read_u32(&header->number_of_rva_and_sizes, content, pos, length, SRE_LITTLE);
+
+ for (i = 0; i < header->number_of_rva_and_sizes && result; i++)
+ {
+ result = read_u32(&header->data_directory[i].virtual_address, content, pos, length, SRE_LITTLE);
+ result &= read_u32(&header->data_directory[i].size, content, pos, length, SRE_LITTLE);
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : format = informations chargées à consulter. *
+* pos = position de début de lecture. [OUT] *
+* header = structure lue à retourner. [OUT] *
+* *
+* Description : Procède à la lecture d'une en-tête de programme PE. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool read_pe_nt_header(const GPeFormat *format, off_t *pos, image_nt_headers *header)
+{
+ bool result; /* Bilan à retourner */
+ const bin_t *content; /* Contenu binaire à lire */
+ off_t length; /* Taille totale du contenu */
+
+ content = G_BIN_FORMAT(format)->content;
+ length = G_BIN_FORMAT(format)->length;
+
+ result = read_u32(&header->signature, content, pos, length, SRE_LITTLE);
+
+ result &= read_pe_file_header(format, pos, &header->file_header);
+ result &= read_pe_optional_header(format, pos, &header->optional_header);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : format = informations chargées à consulter. *
+* pos = position de début de lecture. [OUT] *
+* section = structure lue à retourner. [OUT] *
+* *
+* Description : Procède à la lecture d'une en-tête de section PE. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool read_pe_image_section_header(const GPeFormat *format, off_t *pos, image_section_header *section)
+{
+ bool result; /* Bilan à retourner */
+ const bin_t *content; /* Contenu binaire à lire */
+ off_t length; /* Taille totale du contenu */
+ size_t i; /* Boucle de parcours */
+
+ content = G_BIN_FORMAT(format)->content;
+ length = G_BIN_FORMAT(format)->length;
+
+ result = true;
+
+ for (i = 0; i < IMAGE_SIZEOF_SHORT_NAME && result; i++)
+ result = read_u8((uint8_t *)&section->name[i], content, pos, length, SRE_LITTLE);
+
+ result &= read_u32(&section->misc.physical_address, content, pos, length, SRE_LITTLE);
+
+ result &= read_u32(&section->virtual_address, content, pos, length, SRE_LITTLE);
+ result &= read_u32(&section->size_of_raw_data, content, pos, length, SRE_LITTLE);
+ result &= read_u32(&section->pointer_to_raw_data, content, pos, length, SRE_LITTLE);
+ result &= read_u32(&section->pointer_to_relocations, content, pos, length, SRE_LITTLE);
+ result &= read_u32(&section->pointer_to_line_numbers, content, pos, length, SRE_LITTLE);
+ result &= read_u16(&section->number_of_relocations, content, pos, length, SRE_LITTLE);
+ result &= read_u16(&section->number_of_line_numbers, content, pos, length, SRE_LITTLE);
+ result &= read_u32(&section->characteristics, content, pos, length, SRE_LITTLE);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : format = informations chargées à consulter. *
+* pos = position de début de lecture. [OUT] *
+* desc = structure lue à retourner. [OUT] *
+* *
+* Description : Procède à la lecture d'un répertoire de programme PE. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool read_pe_image_import_descriptor(const GPeFormat *format, off_t *pos, image_import_descriptor *desc)
+{
+ bool result; /* Bilan à retourner */
+ const bin_t *content; /* Contenu binaire à lire */
+ off_t length; /* Taille totale du contenu */
+
+ content = G_BIN_FORMAT(format)->content;
+ length = G_BIN_FORMAT(format)->length;
+
+ result = read_u32(&desc->original_first_thunk, content, pos, length, SRE_LITTLE);
+ result &= read_u32(&desc->time_date_stamp, content, pos, length, SRE_LITTLE);
+ result &= read_u32(&desc->forwarder_chain, content, pos, length, SRE_LITTLE);
+ result &= read_u32(&desc->module_name, content, pos, length, SRE_LITTLE);
+ result &= read_u32(&desc->first_thunk, content, pos, length, SRE_LITTLE);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : format = informations chargées à consulter. *
+* pos = position de début de lecture. [OUT] *
+* import = structure lue à retourner. [OUT] *
+* *
+* Description : Procède à la lecture d'une fonction importée par son nom. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool read_pe_image_import_by_name(const GPeFormat *format, off_t *pos, image_import_by_name *import)
+{
+ bool result; /* Bilan à retourner */
+ const bin_t *content; /* Contenu binaire à lire */
+ off_t length; /* Taille totale du contenu */
+ uint32_t link; /* Lien vers la prochaine zone */
+ off_t new_pos; /* Nouvelle tête de lecture */
+ size_t i; /* Boucle de parcours */
+
+ content = G_BIN_FORMAT(format)->content;
+ length = G_BIN_FORMAT(format)->length;
+
+ result = read_u32(&link, content, pos, length, SRE_LITTLE);
+
+ if (link == 0)
+ memset(import, 0, sizeof(image_import_by_name));
+
+ else if (link % 2 == 0)
+ {
+ new_pos = link;
+
+ result = read_u16(&import->hint, content, &new_pos, length, SRE_LITTLE);
+
+ import->name = (char *)calloc(1, sizeof(char));
+
+ for (i = 0; result; i++)
+ {
+ result = read_u8((uint8_t *)&import->name[i], content, &new_pos, length, SRE_LITTLE);
+
+ if (import->name[i] == '\0')
+ break;
+
+ import->name = (char *)realloc(import->name, (i + 2) * sizeof(char));
+
+ }
+
+ }
+ else /* TODO */;
+
+ return result;
+
+}
diff --git a/src/format/pe/pe-int.h b/src/format/pe/pe-int.h
index 8b18055..3322f62 100644
--- a/src/format/pe/pe-int.h
+++ b/src/format/pe/pe-int.h
@@ -25,7 +25,9 @@
#define _FORMAT_PE_E_PE_INT_H
-#include "../exe_format-int.h"
+#include "pe.h"
+#include "pe_def.h"
+#include "../executable-int.h"
@@ -33,85 +35,49 @@
+/* Format d'exécutable générique (instance) */
+struct _GPeFormat
+{
+ GExeFormat parent; /* A laisser en premier */
+ image_dos_header dos_header; /* En-tête DOS */
+ image_nt_headers nt_headers; /* En-tête Windows */
+ off_t section_offset; /* Début des sections */
+};
+/* Format d'exécutable générique (classe) */
+struct _GPeFormatClass
+{
+ GExeFormatClass parent; /* A laisser en premier */
+};
-/* ---------------------------- DESCRIPTION DU FORMAT PE ---------------------------- */
-/* En-tête DOS */
-typedef struct _image_dos_header
-{
- uint16_t e_magic; /* Numéro magique */
- uint16_t e_cblp; /* Octets de la dernière page */
- uint16_t e_cp; /* Pages dans le fichier */
- uint16_t e_crlc; /* Relocalisations */
- uint16_t e_cparhdr; /* Taille en paragraphes */
- uint16_t e_minalloc; /* Nb min de paragraphes requis*/
- uint16_t e_maxalloc; /* Nb max de paragraphes requis*/
- uint16_t e_ss; /* Valeur (relative) SS init. */
- uint16_t e_sp; /* Valeur SP initiale */
- uint16_t e_csum; /* Empreinte */
- uint16_t e_ip; /* Valeur IP initiale */
- uint16_t e_cs; /* Valeur (relative) CS init. */
- uint16_t e_lfarlc; /* Position de table de reloc. */
- uint16_t e_ovno; /* Nombre d'overlay */
- uint16_t e_res[4]; /* Mots réservés */
- uint16_t e_oemid; /* Identifiant OEM */
- uint16_t e_oeminfo; /* Infos OEM pour e_oemid */
- uint16_t e_res2[10]; /* Mots réservés */
- uint32_t e_lfanew; /* Décallage de bonne en-tête */
-
-} image_dos_header;
-
-/* Archtecture supportées */
-#define IMAGE_FILE_MACHINE_I386 0x014c /* x86 */
-#define IMAGE_FILE_MACHINE_IA64 0x0200 /* Intel IPF */
-#define IMAGE_FILE_MACHINE_AMD64 0x8664 /* x64 */
-
-/* Caractéristiques de l'image */
-#define IMAGE_FILE_RELOCS_STRIPPED 0x0001 /* Pas de relocalisation */
-#define IMAGE_FILE_EXECUTABLE_IMAGE 0x0002 /* Fichier exécutable */
-#define IMAGE_FILE_LINE_NUMS_STRIPPED 0x0004 /* Pas de ligne COFF */
-#define IMAGE_FILE_LOCAL_SYMS_STRIPPED 0x0008 /* Pas de table de symboles COFF */
-#define IMAGE_FILE_AGGRESIVE_WS_TRIM 0x0010 /* Aggressively trim the working set. This value is obsolete as of Windows 2000. */
-#define IMAGE_FILE_LARGE_ADDRESS_AWARE 0x0020 /* Adressage > 2 Go */
-#define IMAGE_FILE_BYTES_REVERSED_LO 0x0080 /* Octets inv. ; obsolète */
-#define IMAGE_FILE_32BIT_MACHINE 0x0100 /* Machine 32 bits */
-#define IMAGE_FILE_DEBUG_STRIPPED 0x0200 /* Pas d'infos de débogage */
-#define IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP 0x0400 /* ...support amovible */
-#define IMAGE_FILE_NET_RUN_FROM_SWAP 0x0800 /* Ficher issu du réseau */
-#define IMAGE_FILE_SYSTEM 0x1000 /* Fichier système */
-#define IMAGE_FILE_DLL 0x2000 /* Fichier DLL */
-#define IMAGE_FILE_UP_SYSTEM_ONLY 0x4000 /* Mono-proc. seulement */
-#define IMAGE_FILE_BYTES_REVERSED_HI 0x8000 /* Octets inv. ; obsolète */
-
-/* Première en-tête du "vrai" format */
-typedef struct _image_file_header
-{
- uint16_t machine; /* Type de machine visée */
- uint16_t number_of_sections; /* Nombre de sections */
- uint32_t time_date_stamp; /* Date de la liaison */
- uint32_t pointer_to_symbol_table; /* Position de ladite table */
- uint32_t number_of_symbols; /* Nombre de symboles */
- uint16_t size_of_optional_header; /* Taille de l'en-tête n°2 */
- uint16_t characteristics; /* Propriétés de l'image */
-} image_file_header;
+/* Procède à la lecture d'une en-tête de programme DOS. */
+bool read_dos_image_header(const GPeFormat *, off_t *, image_dos_header *);
+/* Procède à la lecture d'une en-tête de programme PE (1). */
+bool read_pe_file_header(const GPeFormat *, off_t *, image_file_header *);
-/* Description du format Portable Executable */
-struct _pe_format
-{
+/* Procède à la lecture d'une en-tête de programme PE (2). */
+bool read_pe_optional_header(const GPeFormat *, off_t *, image_optional_header *);
- int a;
+/* Procède à la lecture d'une en-tête de programme PE. */
+bool read_pe_nt_header(const GPeFormat *, off_t *, image_nt_headers *);
+/* Procède à la lecture d'une en-tête de section PE. */
+bool read_pe_image_section_header(const GPeFormat *, off_t *, image_section_header *);
-};
+/* Procède à la lecture d'un répertoire de programme PE. */
+bool read_pe_image_import_descriptor(const GPeFormat *, off_t *, image_import_descriptor *);
+
+/* Procède à la lecture d'une fonction importée par son nom. */
+bool read_pe_image_import_by_name(const GPeFormat *, off_t *, image_import_by_name *);
diff --git a/src/format/pe/pe.c b/src/format/pe/pe.c
new file mode 100644
index 0000000..1d4e6f4
--- /dev/null
+++ b/src/format/pe/pe.c
@@ -0,0 +1,386 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * pe.c - support du format Portable Executable
+ *
+ * Copyright (C) 2008 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 "pe.h"
+
+
+#include <string.h>
+
+
+#include "pe-int.h"
+#include "section.h"
+#include "symbols.h"
+
+
+
+/* Initialise la classe des formats d'exécutables PE. */
+static void g_pe_format_class_init(GPeFormatClass *);
+
+/* Initialise une instance de format d'exécutable PE. */
+static void g_pe_format_init(GPeFormat *);
+
+/* Indique le type d'architecture visée par le format. */
+static FormatTargetMachine g_pe_format_get_target_machine(const GPeFormat *);
+
+/* Fournit l'adresse mémoire du point d'entrée du programme. */
+static vmpa_t g_pe_format_get_entry_point(const GPeFormat *);
+
+/* Fournit les références aux zones binaires à analyser. */
+static GBinPart **g_pe_format_get_parts(const GPeFormat *, size_t *);
+
+/* Fournit la position correspondant à une adresse virtuelle. */
+static bool g_pe_format_translate_address_into_offset(const GPeFormat *, vmpa_t, off_t *);
+
+/* Fournit l'adresse virtuelle correspondant à une position. */
+static bool g_pe_format_translate_offset_into_address(const GPeFormat *, off_t, vmpa_t *);
+
+
+
+/******************************************************************************
+* *
+* Paramètres : type = type de format recherché. *
+* content = contenu binaire à parcourir. *
+* length = taille du contenu en question. *
+* *
+* Description : Indique si le format peut être pris en charge ici. *
+* *
+* Retour : true si la réponse est positive, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool pe_is_matching(FormatType type, const uint8_t *content, off_t length)
+{
+ bool result; /* Bilan à faire connaître */
+ image_dos_header dos_header; /* En-tête DOS */
+
+ result = false;
+
+ if (length >= 2)
+ {
+ result = (strncmp((const char *)content, "\x4d\x5a" /* MZ */, 2) == 0);
+ result &= length >= sizeof(image_dos_header);
+ }
+
+ if (result)
+ {
+ memcpy(&dos_header, content, sizeof(image_dos_header));
+
+ result = length >= (dos_header.e_lfanew + 4);
+
+ result &= (strncmp((const char *)&content[dos_header.e_lfanew],
+ "\x50\x45\x00\x00" /* PE00 */, 4) == 0);
+
+ }
+
+ return result;
+
+}
+
+
+/* Indique le type défini pour un format d'exécutable PE. */
+G_DEFINE_TYPE(GPeFormat, g_pe_format, G_TYPE_EXE_FORMAT);
+
+
+/******************************************************************************
+* *
+* Paramètres : klass = classe à initialiser. *
+* *
+* Description : Initialise la classe des formats d'exécutables PE. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_pe_format_class_init(GPeFormatClass *klass)
+{
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : format = instance à initialiser. *
+* *
+* Description : Initialise une instance de format d'exécutable PE. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_pe_format_init(GPeFormat *format)
+{
+ GExeFormat *exe_format; /* Format parent à constituer */
+
+ exe_format = G_EXE_FORMAT(format);
+
+ exe_format->get_machine = (get_target_machine_fc)g_pe_format_get_target_machine;
+ exe_format->get_entry_point = (get_entry_point_fc)g_pe_format_get_entry_point;
+ exe_format->get_parts = (get_parts_fc)g_pe_format_get_parts;
+
+ exe_format->translate_addr = (translate_addr_fc)g_pe_format_translate_address_into_offset;
+ exe_format->translate_off = (translate_off_fc)g_pe_format_translate_offset_into_address;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : content = contenu binaire à parcourir. *
+* length = taille du contenu en question. *
+* *
+* Description : Prend en charge un nouveau format PE. *
+* *
+* Retour : Adresse de la structure mise en place ou NULL en cas d'échec.*
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GBinFormat *g_pe_format_new(const bin_t *content, off_t length)
+{
+ GPeFormat *result; /* Structure à retourner */
+ off_t offset; /* Tête de lecture */
+
+
+ int i;
+
+
+ result = g_object_new(G_TYPE_PE_FORMAT, NULL);
+
+ g_binary_format_set_content(G_BIN_FORMAT(result), content, length);
+
+ offset = 0;
+
+ if (!read_dos_image_header(result, &offset, &result->dos_header))
+ {
+ /* TODO */
+ return NULL;
+ }
+
+ offset = result->dos_header.e_lfanew;
+
+ if (!read_pe_nt_header(result, &offset, &result->nt_headers))
+ {
+ /* TODO */
+ return NULL;
+ }
+
+ result->section_offset = offset;
+
+ printf("offset :: 0x%08x\n", offset);
+
+ printf("Format :: 0x%08x\n", result->nt_headers.signature);
+
+ printf("directories :: %d\n", result->nt_headers.optional_header.number_of_rva_and_sizes);
+
+ for (i = 0; i < result->nt_headers.optional_header.number_of_rva_and_sizes; i++)
+ printf(" [%d] addr=0x%08x size=%d\n", i,
+ result->nt_headers.optional_header.data_directory[i].virtual_address,
+ result->nt_headers.optional_header.data_directory[i].size);
+
+
+ load_pe_symbols(result);
+
+
+ return G_BIN_FORMAT(result);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : format = informations chargées à consulter. *
+* *
+* Description : Indique le type d'architecture visée par le format. *
+* *
+* Retour : Identifiant de l'architecture ciblée par le format. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static FormatTargetMachine g_pe_format_get_target_machine(const GPeFormat *format)
+{
+ FormatTargetMachine result; /* Identifiant à retourner */
+
+ result = FTM_386;
+
+ /*
+ switch (format->header.e_machine)
+ {
+ case EM_MIPS:
+ result = FTM_MIPS;
+ break;
+
+ case EM_386:
+ result = FTM_386;
+ break;
+
+ case EM_NONE:
+ default:
+ result = FTM_NONE;
+ break;
+
+ }
+ */
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : format = informations chargées à consulter. *
+* *
+* Description : Fournit l'adresse mémoire du point d'entrée du programme. *
+* *
+* Retour : Adresse de mémoire. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static vmpa_t g_pe_format_get_entry_point(const GPeFormat *format)
+{
+ return 0;//(format->is_32b ? format->header.e_entry.addr32 : format->header.e_entry.addr64);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : format = informations chargées à consulter. *
+* count = quantité de zones listées. [OUT] *
+* *
+* Description : Fournit les références aux zones binaires à analyser. *
+* *
+* Retour : Zones binaires à analyser. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static GBinPart **g_pe_format_get_parts(const GPeFormat *format, size_t *count)
+{
+ GBinPart **result; /* Tableau à retourner */
+ uint16_t i; /* Boucle de parcours */
+ image_section_header section; /* En-tête de section PE */
+ GBinPart *part; /* Partie à intégrer à la liste*/
+ char name[IMAGE_SIZEOF_SHORT_NAME + 1]; /* Nom de section utilisable */
+
+ result = NULL;
+ *count = 0;
+
+ for (i = 0; i < format->nt_headers.file_header.number_of_sections; i++)
+ {
+ if (!find_pe_section_by_index(format, i, &section))
+ continue;
+
+ if (section.characteristics & IMAGE_SCN_MEM_EXECUTE)
+ {
+ part = g_binary_part_new();
+
+ memset(name, 0, (IMAGE_SIZEOF_SHORT_NAME + 1) * sizeof(char));
+ memcpy(name, section.name, (IMAGE_SIZEOF_SHORT_NAME + 1) * sizeof(char));
+
+ g_binary_part_set_name(part, name);
+
+ printf("section '%s'\n", name);
+
+ g_binary_part_set_values(part,
+ section.pointer_to_raw_data,
+ section.size_of_raw_data,
+ section.virtual_address);
+
+ printf("section[%d] start=0x%08x size=%d addr=0x%08x\n", i,
+ section.pointer_to_raw_data,
+ section.size_of_raw_data,
+ section.virtual_address);
+
+ result = (GBinPart **)realloc(result, ++(*count) * sizeof(GBinPart *));
+ result[*count - 1] = part;
+
+ }
+
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* 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 : - *
+* *
+******************************************************************************/
+
+static bool g_pe_format_translate_address_into_offset(const GPeFormat *format, vmpa_t addr, off_t *pos)
+{
+ bool result; /* Bilan à retourner */
+
+ result = false;
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : format = description de l'exécutable à consulter. *
+* pos = position dans le flux binaire à retrouver. *
+* addr = adresse virtuelle correspondante. [OUT] *
+* *
+* Description : Fournit l'adresse virtuelle correspondant à une position. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool g_pe_format_translate_offset_into_address(const GPeFormat *format, off_t pos, vmpa_t *addr)
+{
+ bool result; /* Bilan à retourner */
+
+ result = false;
+
+ return result;
+
+}
diff --git a/src/format/pe/pe.h b/src/format/pe/pe.h
new file mode 100644
index 0000000..da1f44d
--- /dev/null
+++ b/src/format/pe/pe.h
@@ -0,0 +1,62 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * pe.h - prototypes pour le support du format Portable Executable
+ *
+ * Copyright (C) 2008 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_PE_E_PE_H
+#define _FORMAT_PE_E_PE_H
+
+
+#include <glib-object.h>
+#include <stdbool.h>
+#include <sys/types.h>
+
+
+#include "../format.h"
+
+
+
+#define G_TYPE_PE_FORMAT g_pe_format_get_type()
+#define G_PE_FORMAT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_pe_format_get_type(), GPeFormat))
+#define G_IS_PE_FORMAT(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_pe_format_get_type()))
+#define G_PE_FORMAT_GET_IFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE((inst), g_pe_format_get_type(), GPeFormatIface))
+#define G_PE_FORMAT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_PE_FORMAT, GPeFormatClass))
+
+
+/* Format d'exécutable PE (instance) */
+typedef struct _GPeFormat GPeFormat;
+
+/* Format d'exécutable PE (classe) */
+typedef struct _GPeFormatClass GPeFormatClass;
+
+
+/* Indique si le format peut être pris en charge ici. */
+bool pe_is_matching(FormatType, const bin_t *, off_t);
+
+/* Indique le type défini pour un format d'exécutable PE. */
+GType g_pe_format_get_type(void);
+
+/* Prend en charge un nouveau format PE. */
+GBinFormat *g_pe_format_new(const bin_t *, off_t);
+
+
+
+#endif /* _FORMAT_PE_E_PE_H */
diff --git a/src/format/pe/pe_def.h b/src/format/pe/pe_def.h
new file mode 100644
index 0000000..5440328
--- /dev/null
+++ b/src/format/pe/pe_def.h
@@ -0,0 +1,343 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * pe_def.h - liste des structures et constantes utilisées par le format PE
+ *
+ * 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_PE_PE_DEF_H
+#define _FORMAT_PE_PE_DEF_H
+
+
+#include <stdint.h>
+
+
+
+
+
+/* ---------------------------- DESCRIPTION DU FORMAT PE ---------------------------- */
+
+
+/* En-tête DOS */
+typedef struct _image_dos_header
+{
+ uint16_t e_magic; /* Numéro magique */
+ uint16_t e_cblp; /* Octets de la dernière page */
+ uint16_t e_cp; /* Pages dans le fichier */
+ uint16_t e_crlc; /* Relocalisations */
+ uint16_t e_cparhdr; /* Taille en paragraphes */
+ uint16_t e_minalloc; /* Nb min de paragraphes requis*/
+ uint16_t e_maxalloc; /* Nb max de paragraphes requis*/
+ uint16_t e_ss; /* Valeur (relative) SS init. */
+ uint16_t e_sp; /* Valeur SP initiale */
+ uint16_t e_csum; /* Empreinte */
+ uint16_t e_ip; /* Valeur IP initiale */
+ uint16_t e_cs; /* Valeur (relative) CS init. */
+ uint16_t e_lfarlc; /* Position de table de reloc. */
+ uint16_t e_ovno; /* Nombre d'overlay */
+ uint16_t e_res[4]; /* Mots réservés */
+ uint16_t e_oemid; /* Identifiant OEM */
+ uint16_t e_oeminfo; /* Infos OEM pour e_oemid */
+ uint16_t e_res2[10]; /* Mots réservés */
+ uint32_t e_lfanew; /* Décallage de bonne en-tête */
+
+} image_dos_header;
+
+/* Archtecture supportées */
+#define IMAGE_FILE_MACHINE_I386 0x014c /* x86 */
+#define IMAGE_FILE_MACHINE_IA64 0x0200 /* Intel IPF */
+#define IMAGE_FILE_MACHINE_AMD64 0x8664 /* x64 */
+
+/* Caractéristiques de l'image */
+#define IMAGE_FILE_RELOCS_STRIPPED 0x0001 /* Pas de relocalisation */
+#define IMAGE_FILE_EXECUTABLE_IMAGE 0x0002 /* Fichier exécutable */
+#define IMAGE_FILE_LINE_NUMS_STRIPPED 0x0004 /* Pas de ligne COFF */
+#define IMAGE_FILE_LOCAL_SYMS_STRIPPED 0x0008 /* Pas de table de symboles COFF */
+#define IMAGE_FILE_AGGRESIVE_WS_TRIM 0x0010 /* Aggressively trim the working set. This value is obsolete as of Windows 2000. */
+#define IMAGE_FILE_LARGE_ADDRESS_AWARE 0x0020 /* Adressage > 2 Go */
+#define IMAGE_FILE_BYTES_REVERSED_LO 0x0080 /* Octets inv. ; obsolète */
+#define IMAGE_FILE_32BIT_MACHINE 0x0100 /* Machine 32 bits */
+#define IMAGE_FILE_DEBUG_STRIPPED 0x0200 /* Pas d'infos de débogage */
+#define IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP 0x0400 /* ...support amovible */
+#define IMAGE_FILE_NET_RUN_FROM_SWAP 0x0800 /* Ficher issu du réseau */
+#define IMAGE_FILE_SYSTEM 0x1000 /* Fichier système */
+#define IMAGE_FILE_DLL 0x2000 /* Fichier DLL */
+#define IMAGE_FILE_UP_SYSTEM_ONLY 0x4000 /* Mono-proc. seulement */
+#define IMAGE_FILE_BYTES_REVERSED_HI 0x8000 /* Octets inv. ; obsolète */
+
+/* Première en-tête du "vrai" format */
+typedef struct _image_file_header
+{
+ uint16_t machine; /* Type de machine visée */
+ uint16_t number_of_sections; /* Nombre de sections */
+ uint32_t time_date_stamp; /* Date de la liaison */
+ uint32_t pointer_to_symbol_table; /* Position de ladite table */
+ uint32_t number_of_symbols; /* Nombre de symboles */
+ uint16_t size_of_optional_header; /* Taille de l'en-tête n°2 */
+ uint16_t characteristics; /* Propriétés de l'image */
+
+} image_file_header;
+
+
+
+
+
+
+
+
+
+
+/* -------------------------- EN-TETE EVOLUEE DU FORMAT PE -------------------------- */
+
+
+/**
+ * cf. http://msdn.microsoft.com/en-us/library/ms680305(VS.85).aspx
+ */
+
+/* Zone de données Windows */
+typedef struct _image_data_directory
+{
+ uint32_t virtual_address; /* Adresse de la table */
+ uint32_t size; /* Taille de la table */
+
+} image_data_directory;
+
+// Directory Entries
+#define IMAGE_DIRECTORY_ENTRY_EXPORT 0 // Export Directory
+#define IMAGE_DIRECTORY_ENTRY_IMPORT 1 // Import Directory
+#define IMAGE_DIRECTORY_ENTRY_RESOURCE 2 // Resource Directory
+#define IMAGE_DIRECTORY_ENTRY_EXCEPTION 3 // Exception Directory
+#define IMAGE_DIRECTORY_ENTRY_SECURITY 4 // Security Directory
+#define IMAGE_DIRECTORY_ENTRY_BASERELOC 5 // Base Relocation Table
+#define IMAGE_DIRECTORY_ENTRY_DEBUG 6 // Debug Directory
+// IMAGE_DIRECTORY_ENTRY_COPYRIGHT 7 // (X86 usage)
+#define IMAGE_DIRECTORY_ENTRY_ARCHITECTURE 7 // Architecture Specific Data
+#define IMAGE_DIRECTORY_ENTRY_GLOBALPTR 8 // RVA of GP
+#define IMAGE_DIRECTORY_ENTRY_TLS 9 // TLS Directory
+#define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG 10 // Load Configuration Directory
+#define IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT 11 // Bound Import Directory in headers
+#define IMAGE_DIRECTORY_ENTRY_IAT 12 // Import Address Table
+#define IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT 13 // Delay Load Import Descriptors
+#define IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR 14 // COM Runtime descriptor
+
+
+/**
+ * cf. http://msdn.microsoft.com/en-us/library/ms680339(VS.85).aspx
+ */
+
+#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16
+
+/* Seconde en-tête, optionnelle */
+typedef struct _image_optional_header
+{
+ uint16_t magic; /* Type de binaire manipulé */
+ uint8_t major_linker_version; /* Version majeure du linker */
+ uint8_t minor_linker_version; /* Version mineure du linker */
+ uint32_t size_of_code; /* Taille de tout le code */
+ uint32_t size_of_initialized_data; /* Taille des données init. */
+ uint32_t size_of_uninitialized_data; /* Taille des données non init.*/
+ uint32_t address_of_entry_point; /* Point d'entrée pour un exe. */
+ uint32_t base_of_code; /* Adresse relative du code */
+ uint32_t base_of_data; /* Adresse relative des données*/
+ uint32_t image_base; /* Adresse souhaitée en mémoire*/
+ uint32_t section_alignment; /* Alignement des sections */
+ uint32_t file_alignment; /* Alignement des données */
+ uint16_t major_operating_system_version;/* Numéro majeur d'OS requis */
+ uint16_t minor_operating_system_version;/* Numéro mineur d'OS requis */
+ uint16_t major_image_version; /* Numéro majeur du binaire */
+ uint16_t minor_image_version; /* Numéro mineur du binaire */
+ uint16_t major_subsystem_version; /* Numéro majeur du sous-sys. */
+ uint16_t minor_subsystem_version; /* Numéro mineur du sous-sys. */
+ uint32_t win32_version_value; /* Réservé (-> 0) */
+ uint32_t size_of_image; /* Taille de l'image */
+ uint32_t size_of_headers; /* Taille de l'en-tête */
+ uint32_t checksum; /* Somme de contrôle */
+ uint16_t subsystem; /* Sous-système visé */
+ uint16_t dll_characteristics; /* Propriétés de la DLL */
+ uint32_t size_of_stack_reserve; /* Taille de pile reservée */
+ uint32_t size_of_stack_commit; /* Taille de pile au démarrage */
+ uint32_t size_of_heap_reserve; /* Taille de tas reservée */
+ uint32_t size_of_heap_commit; /* Taille de tas au démarrage */
+ uint32_t loader_flags; /* Champ obslète */
+ uint32_t number_of_rva_and_sizes; /* Nombre d'entrées suivantes */
+ image_data_directory data_directory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
+
+} image_optional_header;
+
+/* Valeurs pour le champ 'magic' */
+#define IMAGE_NT_OPTIONAL_HDR32_MAGIC 0x10b /* Exécutable 32 bits */
+#define IMAGE_NT_OPTIONAL_HDR64_MAGIC 0x20b /* Exécutable 64 bits */
+#define IMAGE_ROM_OPTIONAL_HDR_MAGIC 0x107 /* Image ROM */
+
+/* Sous-système attendu (champ 'subsystem') */
+#define IMAGE_SUBSYSTEM_UNKNOWN 0 /* Inconnu */
+#define IMAGE_SUBSYSTEM_NATIVE 1 /* Rien de requis */
+#define IMAGE_SUBSYSTEM_WINDOWS_GUI 2 /* Windows GUI */
+#define IMAGE_SUBSYSTEM_WINDOWS_CUI 3 /* Windows CUI */
+#define IMAGE_SUBSYSTEM_OS2_CUI 5 /* OS/2 CUI */
+#define IMAGE_SUBSYSTEM_POSIX_CUI 7 /* Posix CUI */
+#define IMAGE_SUBSYSTEM_WINDOWS_CE_GUI 9 /* Windows CE */
+#define IMAGE_SUBSYSTEM_EFI_APPLICATION 10 /* Application EFI */
+#define IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER 11 /* Pilote EFI + boot */
+#define IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER 12 /* Pilote EFI + serv. */
+#define IMAGE_SUBSYSTEM_EFI_ROM 13 /* Image ROM EFI */
+#define IMAGE_SUBSYSTEM_XBOX 14 /* Xbox */
+#define IMAGE_SUBSYSTEM_WINDOWS_BOOT_APPLICATION 16 /* Application de boot */
+
+/* Détails pour le champ 'dll_characteristics' */
+#define IMAGE_DLLCHARACTERISTICS_UNKNOW_0 0x0001 /* Réservé */
+#define IMAGE_DLLCHARACTERISTICS_UNKNOW_1 0x0002 /* Réservé */
+#define IMAGE_DLLCHARACTERISTICS_UNKNOW_2 0x0004 /* Réservé */
+#define IMAGE_DLLCHARACTERISTICS_UNKNOW_3 0x0008 /* Réservé */
+#define IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE 0x0040/* Reloc. possible */
+#define IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY 0x0080 /* Vérif. forcées */
+#define IMAGE_DLLCHARACTERISTICS_NX_COMPAT 0x0100 /* Compatible DEP */
+#define IMAGE_DLLCHARACTERISTICS_NO_ISOLATION 0x0200/* Pas d'isolation */
+#define IMAGE_DLLCHARACTERISTICS_NO_SEH 0x0400 /* Pas de SEH */
+#define IMAGE_DLLCHARACTERISTICS_NO_BIND 0x0800 /* Ne pas lier */
+#define IMAGE_DLLCHARACTERISTICS_UNKNOW_4 0x1000 /* Réservé */
+#define IMAGE_DLLCHARACTERISTICS_WDM_DRIVER 0x2000 /* Pilote WDM */
+#define IMAGE_DLLCHARACTERISTICS_UNKNOW_5 0x4000 /* Réservé */
+#define IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE 0x8000 /* Support */
+
+
+/* Résumé global */
+typedef struct _image_nt_headers
+{
+ uint32_t signature; /* Numéro magique */
+ image_file_header file_header; /* En-tête n°1 */
+ image_optional_header optional_header; /* En-tête n°2 */
+
+} image_nt_headers;
+
+
+
+/* --------------------------- SECTIONS POUR LE FORMAT PE --------------------------- */
+
+/**
+ * cf. http://msdn.microsoft.com/en-us/library/ms680341(VS.85).aspx
+ */
+
+/* Taille maximale d'un nom, avec ou sans '\0' final */
+#define IMAGE_SIZEOF_SHORT_NAME 8
+
+/* Description d'une section */
+typedef struct _image_section_header
+{
+ char name[IMAGE_SIZEOF_SHORT_NAME]; /* Nom de la section */
+
+ union
+ {
+ uint32_t physical_address; /* Adresse physique */
+ uint32_t virtual_size; /* Taille en mémoire */
+ } misc;
+
+ uint32_t virtual_address; /* Adresse en mémoire */
+ uint32_t size_of_raw_data; /* Taille de données non init. */
+ uint32_t pointer_to_raw_data; /* Position de ces données */
+ uint32_t pointer_to_relocations; /* Position des relocalisations*/
+ uint32_t pointer_to_line_numbers; /* Position de numéros de ligne*/
+ uint16_t number_of_relocations; /* Quantité de relocalisations */
+ uint16_t number_of_line_numbers; /* Quantité de numéros de ligne*/
+ uint32_t characteristics; /* Caractéristiques */
+
+} image_section_header;
+
+/* Détails des caractéristiques d'une image (champ 'characteristics') */
+#define IMAGE_SCN_UNKNOWN_0 0x00000000 /* Réservé */
+#define IMAGE_SCN_UNKNOWN_1 0x00000001 /* Réservé */
+#define IMAGE_SCN_UNKNOWN_2 0x00000002 /* Réservé */
+#define IMAGE_SCN_UNKNOWN_3 0x00000004 /* Réservé */
+#define IMAGE_SCN_TYPE_NO_PAD 0x00000008 /* Pas de complément (obs) */
+#define IMAGE_SCN_UNKNOWN_4 0x00000010 /* Réservé */
+#define IMAGE_SCN_CNT_CODE 0x00000020 /* Code exécutable */
+#define IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040 /* Données intialisées */
+#define IMAGE_SCN_CNT_UNINITIALIZED_DATA 0x00000080 /* Données non init. */
+#define IMAGE_SCN_LNK_OTHER 0x00000100 /* Réservé */
+#define IMAGE_SCN_LNK_INFO 0x00000200 /* Commentaires ou autres */
+#define IMAGE_SCN_UNKNOWN_5 0x00000400 /* Réservé */
+#define IMAGE_SCN_LNK_REMOVE 0x00000800 /* A ne pas intégrer */
+#define IMAGE_SCN_LNK_COMDAT 0x00001000 /* Données COMDAT */
+#define IMAGE_SCN_UNKNOWN_6 0x00002000 /* Réservé */
+#define IMAGE_SCN_NO_DEFER_SPEC_EXC 0x00004000 /* Reset des exceptions */
+#define IMAGE_SCN_GPREL 0x00008000 /* Références globales */
+#define IMAGE_SCN_UNKNOWN_7 0x00010000 /* Réservé */
+#define IMAGE_SCN_MEM_PURGEABLE 0x00020000 /* Réservé */
+#define IMAGE_SCN_MEM_LOCKED 0x00040000 /* Réservé */
+#define IMAGE_SCN_MEM_PRELOAD 0x00080000 /* Réservé */
+#define IMAGE_SCN_ALIGN_1BYTES 0x00100000 /* Alignement sur 1 octet */
+#define IMAGE_SCN_ALIGN_2BYTES 0x00200000 /* Alignement sur 2 octets */
+#define IMAGE_SCN_ALIGN_4BYTES 0x00300000 /* Alignement sur 4 octets */
+#define IMAGE_SCN_ALIGN_8BYTES 0x00400000 /* Alignement sur 8 octets */
+#define IMAGE_SCN_ALIGN_16BYTES 0x00500000 /* Alignement de 16 octets */
+#define IMAGE_SCN_ALIGN_32BYTES 0x00600000 /* Alignement de 32 octets */
+#define IMAGE_SCN_ALIGN_64BYTES 0x00700000 /* Alignement de 64 octets */
+#define IMAGE_SCN_ALIGN_128BYTES 0x00800000 /* Alignement de 128 octets*/
+#define IMAGE_SCN_ALIGN_256BYTES 0x00900000 /* Alignement de 256 octets*/
+#define IMAGE_SCN_ALIGN_512BYTES 0x00a00000 /* Alignement de 512 octets*/
+#define IMAGE_SCN_ALIGN_1024BYTES 0x00b00000 /* Alignement sur 1 ko */
+#define IMAGE_SCN_ALIGN_2048BYTES 0x00c00000 /* Alignement sur 2 ko */
+#define IMAGE_SCN_ALIGN_4096BYTES 0x00d00000 /* Alignement sur 4 ko */
+#define IMAGE_SCN_ALIGN_8192BYTES 0x00e00000 /* Alignement sur 8 ko */
+#define IMAGE_SCN_LNK_NRELOC_OVFL 0x01000000 /* Trop de Relocalisations */
+#define IMAGE_SCN_MEM_DISCARDABLE 0x02000000 /* Section abandonnable */
+#define IMAGE_SCN_MEM_NOT_CACHED 0x04000000 /* Section non cachable */
+#define IMAGE_SCN_MEM_NOT_PAGED 0x08000000 /* Section non paginable */
+#define IMAGE_SCN_MEM_SHARED 0x10000000 /* Section partageable */
+#define IMAGE_SCN_MEM_EXECUTE 0x20000000 /* Section exécutable */
+#define IMAGE_SCN_MEM_READ 0x40000000 /* Section lisible */
+#define IMAGE_SCN_MEM_WRITE 0x80000000 /* Section modifiable */
+
+
+
+/* --------------------------- IDENTIFICATION DE SYMBOLES --------------------------- */
+
+/**
+ * cf. http://msdn.microsoft.com/en-us/library/ms809762.aspx
+ * http://sandsprite.com/CodeStuff/Understanding_imports.html
+ * http://olance.developpez.com/articles/windows/pe-iczelion/import-table/
+ */
+
+/* Point de départ de la chaîne des importations */
+typedef struct _image_import_descriptor
+{
+ uint32_t original_first_thunk;
+ uint32_t time_date_stamp;
+ uint32_t forwarder_chain;
+ uint32_t module_name;
+ uint32_t first_thunk;
+
+} image_import_descriptor;
+
+
+
+
+/* Désignation de fonction importée */
+typedef struct _image_import_by_name
+{
+ uint16_t hint;
+ char *name;
+
+} image_import_by_name;
+
+
+
+
+
+#endif /* _FORMAT_PE_PE_DEF_H */
diff --git a/src/format/pe/section.c b/src/format/pe/section.c
new file mode 100644
index 0000000..210ac37
--- /dev/null
+++ b/src/format/pe/section.c
@@ -0,0 +1,59 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * section.h - prototypes pour la gestion des sections d'un PE
+ *
+ * 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 "section.h"
+
+
+#include <malloc.h>
+#include <string.h>
+
+
+#include "pe-int.h"
+
+
+
+/******************************************************************************
+* *
+* Paramètres : format = description de l'exécutable à consulter. *
+* index = indice de la section recherchée. *
+* section = ensemble d'informations à faire remonter. [OUT] *
+* *
+* Description : Recherche une section donnée au sein de binaire par indice. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool find_pe_section_by_index(const GPeFormat *format, uint16_t index, image_section_header *section)
+{
+ off_t offset; /* Emplacement à venir lire */
+
+ if (index >= format->nt_headers.file_header.number_of_sections) return false;
+
+ offset = format->section_offset + sizeof(image_section_header) * index;
+
+ return read_pe_image_section_header(format, &offset, section);
+
+}
diff --git a/src/format/pe/e_pe.h b/src/format/pe/section.h
index 54820e2..cfc8471 100644
--- a/src/format/pe/e_pe.h
+++ b/src/format/pe/section.h
@@ -1,8 +1,8 @@
/* OpenIDA - Outil d'analyse de fichiers binaires
- * e_pe.h - prototypes pour le support du format Portable Executable
+ * section.h - prototypes pour la gestion des sections d'un PE
*
- * Copyright (C) 2008 Cyrille Bagard
+ * Copyright (C) 2010 Cyrille Bagard
*
* This file is part of OpenIDA.
*
@@ -21,27 +21,18 @@
*/
-#ifndef _FORMAT_PE_E_PE_H
-#define _FORMAT_PE_E_PE_H
+#ifndef _FORMAT_PE_SECTION_H
+#define _FORMAT_PE_SECTION_H
-#include "../exe_format.h"
+#include "pe.h"
+#include "pe_def.h"
-/* Description du format Pe */
-typedef struct _pe_format pe_format;
+/* Recherche une section donnée au sein de binaire par indice. */
+bool find_pe_section_by_index(const GPeFormat *, uint16_t, image_section_header *);
-/* Indique si le format peut être pris en charge ici. */
-bool pe_is_matching(const uint8_t *, off_t);
-/* Prend en charge une nouvelle classe PE. */
-exe_format *load_pe(const uint8_t *, off_t);
-
-/* Efface la prise en charge une nouvelle classe PE. */
-void unload_pe(pe_format *);
-
-
-
-#endif /* _FORMAT_PE_E_PE_H */
+#endif /* _FORMAT_PE_SECTION_H */
diff --git a/src/format/pe/symbols.c b/src/format/pe/symbols.c
new file mode 100644
index 0000000..8f75029
--- /dev/null
+++ b/src/format/pe/symbols.c
@@ -0,0 +1,136 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * symbols.c - gestion des symboles d'un PE
+ *
+ * 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 "symbols.h"
+
+
+#include "pe-int.h"
+
+
+
+
+
+
+
+
+/******************************************************************************
+* *
+* Paramètres : format = description de l'exécutable à compléter. *
+* *
+* Description : Charge en mémoire la liste humaine des symboles importés. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool load_pe_imported_symbols(GPeFormat *format)
+{
+ bool result; /* Bilan à retourner */
+ const image_data_directory *directory; /* Répertoire original */
+ image_import_descriptor dll; /* DLL importée */
+ off_t pos; /* Position de tête de lecture */
+ off_t i; /* Boucle de parcours */
+ image_import_by_name import; /* Fonction importée */
+
+ result = true;
+
+ directory = &format->nt_headers.optional_header.data_directory[IMAGE_DIRECTORY_ENTRY_IMPORT];
+
+ /* TODO : msg si size !% sizeof(...) */
+
+ for (pos = directory->virtual_address;
+ result && pos < (directory->virtual_address + directory->size); )
+ {
+ result = read_pe_image_import_descriptor(format, &pos, &dll);
+
+ printf("mod orig thunk :: 0x%08x\n", dll.original_first_thunk);
+ printf("mod name :: 0x%08x\n", dll.module_name);
+ printf("mod first thunk :: 0x%08x\n", dll.first_thunk);
+
+ i = dll.original_first_thunk;
+
+ /* TODO : i == 0 */
+ if (i == 0) continue;
+
+ while ((result = read_pe_image_import_by_name(format, &i, &import)))
+ {
+ if (import.hint == 0 && import.name == NULL)
+ break;
+
+
+
+ printf(" >> import '%s'\n", import.name);
+
+
+ }
+
+
+ }
+
+ lpis_exit:
+
+ return result;
+
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+/******************************************************************************
+* *
+* Paramètres : format = description de l'exécutable à compléter. *
+* *
+* Description : Charge en mémoire la liste humaine des symboles. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool load_pe_symbols(GPeFormat *format)
+{
+ bool result; /* Bilan à retourner */
+
+ /* Symboles externes */
+ result = load_pe_imported_symbols(format);
+
+ /* Symboles internes */
+
+ return result;
+
+}
diff --git a/src/format/pe/symbols.h b/src/format/pe/symbols.h
new file mode 100644
index 0000000..3d8fd8f
--- /dev/null
+++ b/src/format/pe/symbols.h
@@ -0,0 +1,36 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * symbols.h - prototypes pour la gestion des symboles d'un PE
+ *
+ * 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_PE_SYMBOLS_H
+#define _FORMAT_PE_SYMBOLS_H
+
+
+#include "pe.h"
+
+
+/* Charge en mémoire la liste humaine des symboles. */
+bool load_pe_symbols(GPeFormat *);
+
+
+
+#endif /* _FORMAT_PE_SYMBOLS_H */