diff options
Diffstat (limited to 'src/format')
| -rw-r--r-- | src/format/pe/Makefile.am | 21 | ||||
| -rw-r--r-- | src/format/pe/pe-int.c | 359 | ||||
| -rw-r--r-- | src/format/pe/pe-int.h | 84 | ||||
| -rw-r--r-- | src/format/pe/pe.c | 274 | ||||
| -rw-r--r-- | src/format/pe/pe.h | 63 | ||||
| -rw-r--r-- | src/format/pe/pe_def.h | 343 | ||||
| -rw-r--r-- | src/format/pe/section.c | 59 | ||||
| -rw-r--r-- | src/format/pe/section.h | 38 | ||||
| -rw-r--r-- | src/format/pe/symbols.c | 136 | ||||
| -rw-r--r-- | src/format/pe/symbols.h | 36 | 
10 files changed, 1413 insertions, 0 deletions
| diff --git a/src/format/pe/Makefile.am b/src/format/pe/Makefile.am new file mode 100644 index 0000000..00050a5 --- /dev/null +++ b/src/format/pe/Makefile.am @@ -0,0 +1,21 @@ + +noinst_LTLIBRARIES = libformatpe.la + +libformatpe_la_SOURCES =				\ +	pe-int.h pe-int.c					\ +	pe.h pe.c							\ +	pe_def.h							\ +	section.h section.c					\ +	symbols.h symbols.c + +libformatpe_la_LDFLAGS =  + + +devdir = $(includedir)/chrysalide/$(subdir:src/%=%) + +dev_HEADERS = $(libformatpe_la_SOURCES:%c=) + + +AM_CPPFLAGS = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) + +AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS) diff --git a/src/format/pe/pe-int.c b/src/format/pe/pe-int.c new file mode 100644 index 0000000..0ce1577 --- /dev/null +++ b/src/format/pe/pe-int.c @@ -0,0 +1,359 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * pe-int.c - structures internes du format Portable Executable + * + * Copyright (C) 2010-2017 Cyrille Bagard + * + *  This file is part of Chrysalide. + * + *  Chrysalide 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. + * + *  Chrysalide 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 Chrysalide.  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 = NULL; //G_BIN_FORMAT(format)->content; +    length = 0; //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 = NULL; //G_BIN_FORMAT(format)->content; +    length = 0; //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 = NULL; //G_BIN_FORMAT(format)->content; +    length = 0; //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); +    result &= read_u8(&header->minor_linker_version, content, pos, length); +    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 = NULL; //G_BIN_FORMAT(format)->content; +    length = 0; //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 = NULL; //G_BIN_FORMAT(format)->content; +    length = 0; //G_BIN_FORMAT(format)->length; + +    result = true; + +    for (i = 0; i < IMAGE_SIZEOF_SHORT_NAME && result; i++) +        result = read_u8((uint8_t *)§ion->name[i], content, pos, length); + +    result &= read_u32(§ion->misc.physical_address, content, pos, length, SRE_LITTLE); + +    result &= read_u32(§ion->virtual_address, content, pos, length, SRE_LITTLE); +    result &= read_u32(§ion->size_of_raw_data, content, pos, length, SRE_LITTLE); +    result &= read_u32(§ion->pointer_to_raw_data, content, pos, length, SRE_LITTLE); +    result &= read_u32(§ion->pointer_to_relocations, content, pos, length, SRE_LITTLE); +    result &= read_u32(§ion->pointer_to_line_numbers, content, pos, length, SRE_LITTLE); +    result &= read_u16(§ion->number_of_relocations, content, pos, length, SRE_LITTLE); +    result &= read_u16(§ion->number_of_line_numbers, content, pos, length, SRE_LITTLE); +    result &= read_u32(§ion->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 = NULL; //G_BIN_FORMAT(format)->content; +    length = 0; //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 = NULL; //G_BIN_FORMAT(format)->content; +    length = 0; //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); + +            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 new file mode 100644 index 0000000..14a6007 --- /dev/null +++ b/src/format/pe/pe-int.h @@ -0,0 +1,84 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * pe-int.h - prototypes pour les structures internes du format Portable Executable + * + * Copyright (C) 2009-2017 Cyrille Bagard + * + *  This file is part of Chrysalide. + * + *  Chrysalide 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. + * + *  Chrysalide 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 Chrysalide.  If not, see <http://www.gnu.org/licenses/>. + */ + + +#ifndef _FORMAT_PE_E_PE_INT_H +#define _FORMAT_PE_E_PE_INT_H + + +#include "pe.h" +#include "pe_def.h" +#include "../executable-int.h" + + + + + + + +/* Format d'exécutable PE (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 PE (classe) */ +struct _GPeFormatClass +{ +    GExeFormatClass parent;                 /* A laisser en premier        */ + +}; + + + + + +/* 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 *); + +/* 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 *); + +/* 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 *); + + + +#endif  /* _FORMAT_PE_E_PE_INT_H */ diff --git a/src/format/pe/pe.c b/src/format/pe/pe.c new file mode 100644 index 0000000..8533d25 --- /dev/null +++ b/src/format/pe/pe.c @@ -0,0 +1,274 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * pe.c - support du format Portable Executable + * + * Copyright (C) 2010-2017 Cyrille Bagard + * + *  This file is part of Chrysalide. + * + *  Chrysalide 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. + * + *  Chrysalide 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 Chrysalide.  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 const char *g_pe_format_get_target_machine(const GPeFormat *); + +/* Fournit les références aux zones binaires à analyser. */ +//static GBinPart **g_pe_format_get_parts(const GPeFormat *, size_t *); + + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : content = contenu binaire à parcourir.                       * +*                                                                             * +*  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(GBinContent *content) +{ +    bool result;                            /* Bilan à faire connaître     */ +    image_dos_header dos_header;            /* En-tête DOS                 */ + +    result = false; +#if 0 +    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); + +    } +#endif +    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) +{ + +} + + +/****************************************************************************** +*                                                                             * +*  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 const char *g_pe_format_get_target_machine(const GPeFormat *format) +{ +    return "i386"; + +} + + +/****************************************************************************** +*                                                                             * +*  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   : -                                                            * +*                                                                             * +******************************************************************************/ +#if 0 +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, §ion)) +            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; + +} +#endif diff --git a/src/format/pe/pe.h b/src/format/pe/pe.h new file mode 100644 index 0000000..f757d26 --- /dev/null +++ b/src/format/pe/pe.h @@ -0,0 +1,63 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * pe.h - prototypes pour le support du format Portable Executable + * + * Copyright (C) 2010-2017 Cyrille Bagard + * + *  This file is part of Chrysalide. + * + *  Chrysalide 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. + * + *  Chrysalide 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 Chrysalide.  If not, see <http://www.gnu.org/licenses/>. + */ + + +#ifndef _FORMAT_PE_PE_H +#define _FORMAT_PE_PE_H + + +#include <glib-object.h> +#include <stdbool.h> +#include <sys/types.h> + + +#include "../../core/formats.h" + + + +#define G_TYPE_PE_FORMAT            g_pe_format_get_type() +#define G_PE_FORMAT(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_PE_FORMAT, GPeFormat)) +#define G_IS_PE_FORMAT(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_PE_FORMAT)) +#define G_PE_FORMAT_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_PE_FORMAT, GPeFormatClass)) +#define G_IS_PE_FORMAT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_PE_FORMAT)) +#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(GBinContent *); + +/* 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_PE_H */ diff --git a/src/format/pe/pe_def.h b/src/format/pe/pe_def.h new file mode 100644 index 0000000..62d8afc --- /dev/null +++ b/src/format/pe/pe_def.h @@ -0,0 +1,343 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * pe_def.h - liste des structures et constantes utilisées par le format PE + * + * Copyright (C) 2010-2017 Cyrille Bagard + * + *  This file is part of Chrysalide. + * + *  Chrysalide 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. + * + *  Chrysalide 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 Chrysalide.  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écalage de bon 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..f4cdaf3 --- /dev/null +++ b/src/format/pe/section.c @@ -0,0 +1,59 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * section.h - prototypes pour la gestion des sections d'un PE + * + * Copyright (C) 2010-2017 Cyrille Bagard + * + *  This file is part of Chrysalide. + * + *  Chrysalide 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. + * + *  Chrysalide 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 Chrysalide.  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/section.h b/src/format/pe/section.h new file mode 100644 index 0000000..e7c399b --- /dev/null +++ b/src/format/pe/section.h @@ -0,0 +1,38 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * section.h - prototypes pour la gestion des sections d'un PE + * + * Copyright (C) 2010-2017 Cyrille Bagard + * + *  This file is part of Chrysalide. + * + *  Chrysalide 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. + * + *  Chrysalide 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 Chrysalide.  If not, see <http://www.gnu.org/licenses/>. + */ + + +#ifndef _FORMAT_PE_SECTION_H +#define _FORMAT_PE_SECTION_H + + +#include "pe.h" +#include "pe_def.h" + + + +/* Recherche une section donnée au sein de binaire par indice. */ +bool find_pe_section_by_index(const GPeFormat *, uint16_t, image_section_header *); + + + +#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..30e43b5 --- /dev/null +++ b/src/format/pe/symbols.c @@ -0,0 +1,136 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * symbols.c - gestion des symboles d'un PE + * + * Copyright (C) 2010-2017 Cyrille Bagard + * + *  This file is part of Chrysalide. + * + *  Chrysalide 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. + * + *  Chrysalide 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 Chrysalide.  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..7581152 --- /dev/null +++ b/src/format/pe/symbols.h @@ -0,0 +1,36 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * symbols.h - prototypes pour la gestion des symboles d'un PE + * + * Copyright (C) 2010-2017 Cyrille Bagard + * + *  This file is part of Chrysalide. + * + *  Chrysalide 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. + * + *  Chrysalide 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 Chrysalide.  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 */ | 
