diff options
| author | Cyrille Bagard <nocbos@gmail.com> | 2009-01-25 21:27:14 (GMT) | 
|---|---|---|
| committer | Cyrille Bagard <nocbos@gmail.com> | 2009-01-25 21:27:14 (GMT) | 
| commit | 21493170bb188ad9548820c830c3e8d7055e3f46 (patch) | |
| tree | fdc4d03b0aaa5e7ed8a0b8b151926f654cece321 /src/format | |
| parent | 8f1e49332cd81760c98166be9df79a7136f5ca57 (diff) | |
Supported the Java Class file format.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@46 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
Diffstat (limited to 'src/format')
| -rw-r--r-- | src/format/Makefile.am | 2 | ||||
| -rw-r--r-- | src/format/exe_format.c | 94 | ||||
| -rw-r--r-- | src/format/exe_format.h | 24 | ||||
| -rwxr-xr-x | src/format/java/Makefile.am | 19 | ||||
| -rw-r--r-- | src/format/java/attribute.c | 712 | ||||
| -rw-r--r-- | src/format/java/attribute.h | 40 | ||||
| -rwxr-xr-x | src/format/java/e_java.c | 173 | ||||
| -rwxr-xr-x | src/format/java/e_java.h | 49 | ||||
| -rw-r--r-- | src/format/java/field.c | 158 | ||||
| -rw-r--r-- | src/format/java/field.h | 40 | ||||
| -rwxr-xr-x | src/format/java/java-int.h | 415 | ||||
| -rw-r--r-- | src/format/java/method.c | 157 | ||||
| -rw-r--r-- | src/format/java/method.h | 40 | ||||
| -rwxr-xr-x | src/format/java/pool.c | 354 | ||||
| -rwxr-xr-x | src/format/java/pool.h | 42 | 
15 files changed, 2317 insertions, 2 deletions
| diff --git a/src/format/Makefile.am b/src/format/Makefile.am index acc849b..6f49822 100644 --- a/src/format/Makefile.am +++ b/src/format/Makefile.am @@ -16,4 +16,4 @@ AM_CPPFLAGS =  AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) -SUBDIRS = dwarf elf +SUBDIRS = dwarf elf java diff --git a/src/format/exe_format.c b/src/format/exe_format.c index 7fcbcfb..1077cfe 100644 --- a/src/format/exe_format.c +++ b/src/format/exe_format.c @@ -32,6 +32,29 @@ + + +/* ------------------------ DETECTION DE FORMATS EXECUTABLES ------------------------ */ + + +/* Format d'exécutables enregistré */ +typedef struct _registered_exe_format +{ +    const char *name;                       /* Désignation du format       */ + +    exe_match_fc match;                     /* Procédure de reconnaissance */ +    exe_load_fc load;                       /* Fonction de chargement      */ + +} registered_exe_format; + + +/* Liste des formats d'exécutables enregistrés */ +static registered_exe_format *exe_formats = NULL; +static size_t exe_formats_count = 0; + + + +  /* ---------------------------------------------------------------------------------- */  /*                          MANIPULATION DES PARTIES DE CODE                          */  /* ---------------------------------------------------------------------------------- */ @@ -162,10 +185,79 @@ void delete_bin_part(bin_part *part)  /* ---------------------------------------------------------------------------------- */ -/*                          MANIPULATION DES PARTIES DE CODE                          */ +/*                          DETECTION DE FORMATS EXECUTABLES                          */  /* ---------------------------------------------------------------------------------- */ +/****************************************************************************** +*                                                                             * +*  Paramètres  : name  = désignation humaine associée.                        * +*                match = procédure de reconnaissance fournie.                 * +*                load  = fonction de chargement fournie.                      * +*                                                                             * +*  Description : Enregistre la disponibilité d'un nouveau format exécutable.  * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void register_exe_format(const char *name, exe_match_fc match, exe_load_fc load) +{ +    exe_formats = (registered_exe_format *)realloc(exe_formats, +                                                   ++exe_formats_count * sizeof(registered_exe_format)); + +    exe_formats[exe_formats_count - 1].name = name; + +    exe_formats[exe_formats_count - 1].match = match; +    exe_formats[exe_formats_count - 1].load = load; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : content = contenu binaire à parcourir.                       * +*                length  = taille du contenu en question.                     * +*                                                                             * +*  Description : Charge si possible un nouvel exécutable binaire.             * +*                                                                             * +*  Retour      : Adresse du nouveau gestionnaire de format ou NULL si erreur. * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +exe_format *load_new_exe_format(const uint8_t *content, off_t length) +{ +    exe_format *result;                     /* Adresse à retourner         */ +    size_t i;                               /* Boucle de parcours          */ + +    result = NULL; + +    for (i = 0; i < exe_formats_count && result == NULL; i++) +        if (exe_formats[i].match(content, length)) +        { +            printf("<LOGINFO> %s is matching...\n", exe_formats[i].name); + +            result = exe_formats[i].load(content, length); + +        } + +    return result; + +} + + + + + + + +/* ---------------------------------------------------------------------------------- */ +/*                          MANIPULATION DES PARTIES DE CODE                          */ +/* ---------------------------------------------------------------------------------- */ diff --git a/src/format/exe_format.h b/src/format/exe_format.h index 8e4932f..4fedf13 100644 --- a/src/format/exe_format.h +++ b/src/format/exe_format.h @@ -56,10 +56,34 @@ void delete_bin_part(bin_part *); +/* FIXME !!!!!!!!!!!! */ +  /* Support générique d'un format d'exécutable */  typedef struct _exe_format exe_format; + +/* ------------------------ DETECTION DE FORMATS EXECUTABLES ------------------------ */ + + +/* Indication à propos du support d'un format */ +typedef bool (* exe_match_fc) (const uint8_t *, off_t); + +/* Méthode de chargement d'un format */ +typedef exe_format * (* exe_load_fc) (const uint8_t *, off_t); + + +/* Enregistre la disponibilité d'un nouveau format exécutable. */ +void register_exe_format(const char *, exe_match_fc, exe_load_fc); + +/* Charge si possible un nouvel exécutable binaire. */ +exe_format *load_new_exe_format(const uint8_t *, off_t); + + + + + +  /* Types de symbole */  typedef enum _SymbolType  { diff --git a/src/format/java/Makefile.am b/src/format/java/Makefile.am new file mode 100755 index 0000000..e3a88b2 --- /dev/null +++ b/src/format/java/Makefile.am @@ -0,0 +1,19 @@ + +lib_LIBRARIES = libformatjava.a + +libformatjava_a_SOURCES =				\ +	attribute.h attribute.c				\ +	e_java.h e_java.c					\ +	field.h field.c						\ +	java-int.h							\ +	method.h method.c					\ +	pool.h pool.c + +libformatjava_a_CFLAGS = $(AM_CFLAGS) + + +INCLUDES =  + +AM_CPPFLAGS =  + +AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) diff --git a/src/format/java/attribute.c b/src/format/java/attribute.c new file mode 100644 index 0000000..f5947dd --- /dev/null +++ b/src/format/java/attribute.c @@ -0,0 +1,712 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * attribute.c - manipulation des attributs Java + * + * 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 "attribute.h" + + +#include <malloc.h> +#include <string.h> + + +#include "java-int.h" +#include "pool.h" +#include "../../common/endianness.h" + + + +/* Charge les propriétés d'un attribut quelconque. */ +bool load_java_attribute(java_format *, java_attribute *, off_t *); + +/* Décharge les propriétés d'un attribut quelconque. */ +void unload_java_attribute(java_format *, java_attribute *); + +/* Charge les propriétés d'un attribut de valeur constante. */ +bool load_java_const_value_attribute(java_format *, const_value_attrib *, off_t *); + +/* Charge les propriétés d'un attribut de code. */ +bool load_java_code_attribute(java_format *, code_attrib *, off_t *); + +/* Décharge les propriétés d'un attribut de code. */ +void unload_java_code_attribute(java_format *, code_attrib *); + +/*Charge les propriétés d'un attribut d'exceptions lançables. */ +bool load_java_exceptions_attribute(java_format *, exceptions_attrib *, off_t *); + +/* Décharge les propriétés d'un attribut d'exceptions lançables. */ +void unload_java_exceptions_attribute(java_format *, exceptions_attrib *); + +/* Charge les propriétés d'un attribut de classes internes. */ +bool load_java_inner_classes_attribute(java_format *, inner_classes_attrib *, off_t *); + +/* Décharge les propriétés d'un attribut de classes internes. */ +void unload_java_inner_classes_attribute(java_format *, inner_classes_attrib *); + +/* Charge les propriétés d'un attribut de fichier source. */ +bool load_java_source_file_attribute(java_format *, source_file_attrib *, off_t *); + +/* Charge les propriétés d'un attribut de correspondance. */ +bool load_java_line_number_attribute(java_format *, line_number_attrib *, off_t *); + +/* Décharge les propriétés d'un attribut de correspondance. */ +void unload_java_line_number_attribute(java_format *, line_number_attrib *); + +/* Charge les propriétés d'un attribut de variables locales. */ +bool load_java_local_variables_attribute(java_format *, local_variables_attrib *, off_t *); + +/* Décharge les propriétés d'un attribut de variables locales. */ +void unload_java_local_variables_attribute(java_format *, local_variables_attrib *); + + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : format     = description de l'exécutable à compléter.        * +*                pos        = point de lecture à faire évoluer. [OUT]         * +*                attributes = tableau des attributs chargés. [OUT]            * +*                count      = nombre d'éléments à charger. [OUT]              * +*                                                                             * +*  Description : Charge les attribus d'un élément d'un binaire Java.          * +*                                                                             * +*  Retour      : true si l'opération s'est bien déroulée, false sinon.        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bool load_java_attributes(java_format *format, off_t *pos, java_attribute **attributes, uint16_t *count) +{ +    bool result;                            /* Bilan à remonter            */ +    uint16_t i;                             /* Boucle de parcours          */ + +    result = read_u16(count, EXE_FORMAT(format)->content, pos, +                      EXE_FORMAT(format)->length, SRE_BIG); + +    if (!result) return false; + +    if (*count > 0) +    { +        *attributes = (java_attribute *)calloc(*count, sizeof(java_attribute)); + +        for (i = 0; i < *count && result; i++) +            result = load_java_attribute(format, &(*attributes)[i], pos); + +        if (!result) +            unload_java_attributes(format, *attributes, *count); + +    } + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : format     = description de l'exécutable à libérer.          * +*                attributes = tableau des attributs à décharger.              * +*                count      = nombre d'éléments à décharger.                  * +*                                                                             * +*  Description : Décharge les attribus d'un élément d'un binaire Java.        * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void unload_java_attributes(java_format *format, java_attribute *attributes, uint16_t count) +{ +    uint16_t i;                             /* Boucle de parcours          */ + +    for (i = 0; i < count; i++) +        unload_java_attribute(format, &attributes[i]); + +    free(attributes); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : format = description de l'exécutable à compléter.            * +*                attrib = élément à spécifier. [OUT]                          * +*                pos    = point de lecture à faire évoluer. [OUT]             * +*                                                                             * +*  Description : Charge les propriétés d'un attribut quelconque.              * +*                                                                             * +*  Retour      : true si l'opération s'est bien déroulée, false sinon.        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bool load_java_attribute(java_format *format, java_attribute *attrib, off_t *pos) +{ +    bool result;                            /* Bilan à retourner           */ +    uint16_t index;                         /* Indice du nom assimilé      */ +    const char *name;                       /* Version humainement lisible */ +    uint32_t attrib_length;                 /* Taille de la charge utile   */ +    off_t saved_pos;                        /* Conservation de la position */ + +    result = read_u16(&index, EXE_FORMAT(format)->content, pos, +                      EXE_FORMAT(format)->length, SRE_BIG); + +    result &= get_java_pool_ut8_string(format, index, &name); + +    if (result) +    { +        result = read_u32(&attrib_length, EXE_FORMAT(format)->content, +                          pos, EXE_FORMAT(format)->length, SRE_BIG); + +        saved_pos = *pos; + +        if (result && strcmp("ConstantValue", name) == 0) +        { +            attrib->type = JAT_CONSTANT_VALUE; +            result = load_java_const_value_attribute(format, &attrib->info.const_value, pos); +        } + +        else if (result && strcmp("Code", name) == 0) +        { +            attrib->type = JAT_CODE; +            result = load_java_code_attribute(format, &attrib->info.code, pos); +        } + +        else if (result && strcmp("Exceptions", name) == 0) +        { +            attrib->type = JAT_EXCEPTIONS; +            result = load_java_exceptions_attribute(format, &attrib->info.exceptions, pos); +        } + +        else if (result && strcmp("InnerClasses", name) == 0) +        { +            attrib->type = JAT_INNER_CLASSES; +            result = load_java_inner_classes_attribute(format, &attrib->info.inner_classes, pos); +        } + +        else if (result && strcmp("Synthetic", name) == 0) +            attrib->type = JAT_SYNTHETIC; + +        else if (result && strcmp("SourceFile", name) == 0) +        { +            attrib->type = JAT_LINE_NUMBER; +            result = load_java_source_file_attribute(format, &attrib->info.source_file, pos); +        } + +        else if (result && strcmp("LineNumberTable", name) == 0) +        { +            attrib->type = JAT_SOURCE_FILE; +            result = load_java_line_number_attribute(format, &attrib->info.line_number, pos); +        } + +        else if (result && strcmp("LocalVariableTable", name) == 0) +        { +            attrib->type = JAT_LOCAL_VARIABLES; +            result = load_java_local_variables_attribute(format, &attrib->info.local_vars, pos); +        } + +        else if (result && strcmp("Deprecated", name) == 0) +            attrib->type = JAT_DEPRECATED; + +        else if (result) +        { +            result = false; +            printf("<OIDAIMPL> Nom d'attribut non supporté : '%s'\n", name); +        } + +        if (result && attrib_length != (*pos - saved_pos)) +            printf("<BADBIN> indication de la taille de l'attribut '%s' non vérifiée : %d vs %d\n", +                    name, attrib_length, *pos - saved_pos); + +    } + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : format = description de l'exécutable à compléter.            * +*                attrib = élément à libérer.                                  * +*                                                                             * +*  Description : Décharge les propriétés d'un attribut quelconque.            * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void unload_java_attribute(java_format *format, java_attribute *attrib) +{ +    switch (attrib->type) +    { +        case JAT_NONE: +            break; + +        case JAT_CONSTANT_VALUE: +            break; + +        case JAT_CODE: +            unload_java_code_attribute(format, &attrib->info.code); +            break; + +        case JAT_EXCEPTIONS: +            unload_java_exceptions_attribute(format, &attrib->info.exceptions); +            break; + +        case JAT_INNER_CLASSES: +            unload_java_inner_classes_attribute(format, &attrib->info.inner_classes); +            break; + +        case JAT_SYNTHETIC: +            break; + +        case JAT_SOURCE_FILE: +            break; + +        case JAT_LINE_NUMBER: +            unload_java_line_number_attribute(format, &attrib->info.line_number); +            break; + +        case JAT_LOCAL_VARIABLES: +            unload_java_local_variables_attribute(format, &attrib->info.local_vars); +            break; + +        case JAT_DEPRECATED: +            break; + +    } + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : format = description de l'exécutable à compléter.            * +*                attrib = élément à spécifier. [OUT]                          * +*                pos    = point de lecture à faire évoluer. [OUT]             * +*                                                                             * +*  Description : Charge les propriétés d'un attribut de valeur constante.     * +*                                                                             * +*  Retour      : true si l'opération s'est bien déroulée, false sinon.        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bool load_java_const_value_attribute(java_format *format, const_value_attrib *attrib, off_t *pos) +{ +    bool result;                            /* Bilan à retourner           */ + +    result = read_u16(&attrib->const_value_index, EXE_FORMAT(format)->content, +                      pos, EXE_FORMAT(format)->length, SRE_BIG); + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : format = description de l'exécutable à compléter.            * +*                attrib = élément à spécifier. [OUT]                          * +*                pos    = point de lecture à faire évoluer. [OUT]             * +*                                                                             * +*  Description : Charge les propriétés d'un attribut de code.                 * +*                                                                             * +*  Retour      : true si l'opération s'est bien déroulée, false sinon.        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bool load_java_code_attribute(java_format *format, code_attrib *attrib, off_t *pos) +{ +    bool result;                            /* Bilan à retourner           */ +    uint16_t i;                             /* Boucle de parcours          */ + +    result = read_u16(&attrib->max_stack, EXE_FORMAT(format)->content, +                      pos, EXE_FORMAT(format)->length, SRE_BIG); + +    result &= read_u16(&attrib->max_locals, EXE_FORMAT(format)->content, +                       pos, EXE_FORMAT(format)->length, SRE_BIG); + +    result &= read_u32(&attrib->code_length, EXE_FORMAT(format)->content, +                       pos, EXE_FORMAT(format)->length, SRE_BIG); + +    result &= ((*pos + attrib->code_length) <= EXE_FORMAT(format)->length); + +    if (result) +    { +        attrib->content = *pos; +        *pos += attrib->code_length; +    } + +    result &= read_u16(&attrib->exceptions_count, EXE_FORMAT(format)->content, +                       pos, EXE_FORMAT(format)->length, SRE_BIG); + +    if (result && attrib->exceptions_count > 0) +    { +        attrib->exceptions = (code_exception *)calloc(attrib->exceptions_count, sizeof(code_exception)); + +        for (i = 0; i < attrib->exceptions_count && result; i++) +        { +            result &= read_u16(&attrib->exceptions[i].start_pc, EXE_FORMAT(format)->content, +                               pos, EXE_FORMAT(format)->length, SRE_BIG); + +            result &= read_u16(&attrib->exceptions[i].end_pc, EXE_FORMAT(format)->content, +                               pos, EXE_FORMAT(format)->length, SRE_BIG); + +            result &= read_u16(&attrib->exceptions[i].handler_pc, EXE_FORMAT(format)->content, +                               pos, EXE_FORMAT(format)->length, SRE_BIG); + +            result &= read_u16(&attrib->exceptions[i].catch_type, EXE_FORMAT(format)->content, +                               pos, EXE_FORMAT(format)->length, SRE_BIG); + +        } + +    } + +    result &= load_java_attributes(format, pos, &attrib->attributes, &attrib->attributes_count); + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : format = description de l'exécutable à compléter.            * +*                attrib = élément à libérer de la mémoire.                    * +*                                                                             * +*  Description : Décharge les propriétés d'un attribut de code.               * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void unload_java_code_attribute(java_format *format, code_attrib *attrib) +{ +    if (attrib->exceptions != NULL) +        free(attrib->exceptions); + +    if (attrib->attributes != NULL) +        unload_java_attributes(format, attrib->attributes, attrib->attributes_count); + +} + + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : format = description de l'exécutable à compléter.            * +*                attrib = élément à spécifier. [OUT]                          * +*                pos    = point de lecture à faire évoluer. [OUT]             * +*                                                                             * +*  Description : Charge les propriétés d'un attribut d'exceptions lançables.  * +*                                                                             * +*  Retour      : true si l'opération s'est bien déroulée, false sinon.        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bool load_java_exceptions_attribute(java_format *format, exceptions_attrib *attrib, off_t *pos) +{ +    bool result;                            /* Bilan à retourner           */ +    uint16_t i;                             /* Boucle de parcours          */ + +    result = read_u16(&attrib->throw_count, EXE_FORMAT(format)->content, +                      pos, EXE_FORMAT(format)->length, SRE_BIG); + +    if (result && attrib->throw_count > 0) +    { +        attrib->throw = (uint16_t *)calloc(attrib->throw_count, sizeof(uint16_t)); + +        for (i = 0; i < attrib->throw_count && result; i++) +            result &= read_u16(&attrib->throw[i], EXE_FORMAT(format)->content, +                               pos, EXE_FORMAT(format)->length, SRE_BIG); + +    } + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : format = description de l'exécutable à compléter.            * +*                attrib = élément à libérer de la mémoire.                    * +*                                                                             * +*  Description : Décharge les propriétés d'un attribut d'exceptions lançables.* +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void unload_java_exceptions_attribute(java_format *format, exceptions_attrib *attrib) +{ +    if (attrib->throw != NULL) +        free(attrib->throw); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : format = description de l'exécutable à compléter.            * +*                attrib = élément à spécifier. [OUT]                          * +*                pos    = point de lecture à faire évoluer. [OUT]             * +*                                                                             * +*  Description : Charge les propriétés d'un attribut de classes internes.     * +*                                                                             * +*  Retour      : true si l'opération s'est bien déroulée, false sinon.        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bool load_java_inner_classes_attribute(java_format *format, inner_classes_attrib *attrib, off_t *pos) +{ +    bool result;                            /* Bilan à retourner           */ +    uint16_t i;                             /* Boucle de parcours          */ + +    result = read_u16(&attrib->classes_count, EXE_FORMAT(format)->content, +                      pos, EXE_FORMAT(format)->length, SRE_BIG); + +    if (result && attrib->classes_count > 0) +    { +        attrib->classes = (inner_class *)calloc(attrib->classes_count, sizeof(inner_class)); + +        for (i = 0; i < attrib->classes_count && result; i++) +        { +            result &= read_u16(&attrib->classes[i].inner_class_info_index, EXE_FORMAT(format)->content, +                               pos, EXE_FORMAT(format)->length, SRE_BIG); + +            result &= read_u16(&attrib->classes[i].outer_class_info_index, EXE_FORMAT(format)->content, +                               pos, EXE_FORMAT(format)->length, SRE_BIG); + +            result &= read_u16(&attrib->classes[i].inner_name_index, EXE_FORMAT(format)->content, +                               pos, EXE_FORMAT(format)->length, SRE_BIG); + +            result &= read_u16((uint16_t *)&attrib->classes[i].access, EXE_FORMAT(format)->content, +                               pos, EXE_FORMAT(format)->length, SRE_BIG); + +        } + +    } + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : format = description de l'exécutable à compléter.            * +*                attrib = élément à libérer de la mémoire.                    * +*                                                                             * +*  Description : Décharge les propriétés d'un attribut de classes internes.   * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void unload_java_inner_classes_attribute(java_format *format, inner_classes_attrib *attrib) +{ +    if (attrib->classes != NULL) +        free(attrib->classes); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : format = description de l'exécutable à compléter.            * +*                attrib = élément à spécifier. [OUT]                          * +*                pos    = point de lecture à faire évoluer. [OUT]             * +*                                                                             * +*  Description : Charge les propriétés d'un attribut de fichier source.       * +*                                                                             * +*  Retour      : true si l'opération s'est bien déroulée, false sinon.        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bool load_java_source_file_attribute(java_format *format, source_file_attrib *attrib, off_t *pos) +{ +    bool result;                            /* Bilan à retourner           */ + +    result = read_u16(&attrib->source_file_index, EXE_FORMAT(format)->content, +                      pos, EXE_FORMAT(format)->length, SRE_BIG); + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : format = description de l'exécutable à compléter.            * +*                attrib = élément à spécifier. [OUT]                          * +*                pos    = point de lecture à faire évoluer. [OUT]             * +*                                                                             * +*  Description : Charge les propriétés d'un attribut de correspondance.       * +*                                                                             * +*  Retour      : true si l'opération s'est bien déroulée, false sinon.        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bool load_java_line_number_attribute(java_format *format, line_number_attrib *attrib, off_t *pos) +{ +    bool result;                            /* Bilan à retourner           */ +    uint16_t i;                             /* Boucle de parcours          */ + +    result = read_u16(&attrib->lines_count, EXE_FORMAT(format)->content, +                      pos, EXE_FORMAT(format)->length, SRE_BIG); + +    if (result && attrib->lines_count > 0) +    { +        attrib->lines = (pc_and_line *)calloc(attrib->lines_count, sizeof(pc_and_line)); + +        for (i = 0; i < attrib->lines_count && result; i++) +        { +            result &= read_u16(&attrib->lines[i].start_pc, EXE_FORMAT(format)->content, +                               pos, EXE_FORMAT(format)->length, SRE_BIG); + +            result &= read_u16(&attrib->lines[i].number, EXE_FORMAT(format)->content, +                               pos, EXE_FORMAT(format)->length, SRE_BIG); + +        } + +    } + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : format = description de l'exécutable à compléter.            * +*                attrib = élément à libérer de la mémoire.                    * +*                                                                             * +*  Description : Décharge les propriétés d'un attribut de correspondance.     * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void unload_java_line_number_attribute(java_format *format, line_number_attrib *attrib) +{ +    if (attrib->lines != NULL) +        free(attrib->lines); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : format = description de l'exécutable à compléter.            * +*                attrib = élément à spécifier. [OUT]                          * +*                pos    = point de lecture à faire évoluer. [OUT]             * +*                                                                             * +*  Description : Charge les propriétés d'un attribut de variables locales.    * +*                                                                             * +*  Retour      : true si l'opération s'est bien déroulée, false sinon.        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bool load_java_local_variables_attribute(java_format *format, local_variables_attrib *attrib, off_t *pos) +{ +    bool result;                            /* Bilan à retourner           */ +    uint16_t i;                             /* Boucle de parcours          */ + +    result = read_u16(&attrib->vars_count, EXE_FORMAT(format)->content, +                      pos, EXE_FORMAT(format)->length, SRE_BIG); + +    if (result && attrib->vars_count > 0) +    { +        attrib->vars = (local_variable *)calloc(attrib->vars_count, sizeof(local_variable)); + +        for (i = 0; i < attrib->vars_count && result; i++) +        { +            result &= read_u16(&attrib->vars[i].start_pc, EXE_FORMAT(format)->content, +                               pos, EXE_FORMAT(format)->length, SRE_BIG); + +            result &= read_u16(&attrib->vars[i].length, EXE_FORMAT(format)->content, +                               pos, EXE_FORMAT(format)->length, SRE_BIG); + +            result &= read_u16(&attrib->vars[i].name_index, EXE_FORMAT(format)->content, +                               pos, EXE_FORMAT(format)->length, SRE_BIG); + +            result &= read_u16(&attrib->vars[i].descriptor_index, EXE_FORMAT(format)->content, +                               pos, EXE_FORMAT(format)->length, SRE_BIG); + +            result &= read_u16(&attrib->vars[i].index, EXE_FORMAT(format)->content, +                               pos, EXE_FORMAT(format)->length, SRE_BIG); + +        } + +    } + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : format = description de l'exécutable à compléter.            * +*                attrib = élément à libérer de la mémoire.                    * +*                                                                             * +*  Description : Décharge les propriétés d'un attribut de variables locales.  * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void unload_java_local_variables_attribute(java_format *format, local_variables_attrib *attrib) +{ +    if (attrib->vars != NULL) +        free(attrib->vars); + +} diff --git a/src/format/java/attribute.h b/src/format/java/attribute.h new file mode 100644 index 0000000..7d57383 --- /dev/null +++ b/src/format/java/attribute.h @@ -0,0 +1,40 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * attribute.h - prototypes pour la manipulation des attributs Java + * + * 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_JAVA_ATTRIBUTE_H +#define _FORMAT_JAVA_ATTRIBUTE_H + + +#include "e_java.h" + + + +/* Charge les attribus d'un élément d'un binaire Java. */ +bool load_java_attributes(java_format *, off_t *, java_attribute **, uint16_t *); + +/* Décharge les attribus d'un élément d'un binaire Java. */ +void unload_java_attributes(java_format *, java_attribute *, uint16_t); + + + +#endif  /* _FORMAT_JAVA_ATTRIBUTE_H */ diff --git a/src/format/java/e_java.c b/src/format/java/e_java.c new file mode 100755 index 0000000..e2f8fbf --- /dev/null +++ b/src/format/java/e_java.c @@ -0,0 +1,173 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * e_java.c - support du format Java + * + * 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_java.h" + + +#include <malloc.h> +#include <string.h> + + +#include "attribute.h" +#include "field.h" +#include "java-int.h" +#include "method.h" +#include "pool.h" +#include "../../common/endianness.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 java_is_matching(const uint8_t *content, off_t length) +{ +    bool result;                            /* Bilan à faire connaître     */ + +    result = false; + +    if (length >= 4) +        result = (strncmp((const char *)content, "\xca\xfe\xba\xbe", 4) == 0); + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : content = contenu binaire à parcourir.                       * +*                length  = taille du contenu en question.                     * +*                                                                             * +*  Description : Prend en charge une nouvelle classe Java.                    * +*                                                                             * +*  Retour      : Adresse de la structure mise en place ou NULL en cas d'échec.* +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +exe_format *load_java(const uint8_t *content, off_t length) +{ +    java_format *result;                    /* Adresse à retourner         */ +    off_t pos;                              /* Point d'analyse             */ +    uint32_t magic;                         /* Identifiant Java            */ +    uint16_t i;                             /* Boucle de parcours          */ + +    result = (java_format *)calloc(1, sizeof(java_format)); + +    EXE_FORMAT(result)->content = content; +    EXE_FORMAT(result)->length = length; + +    pos = 0; + +    if (!read_u32(&magic, content, &pos, length, SRE_BIG)) +        goto ldj_error; + +    if (!read_u16(&result->minor_version, content, &pos, length, SRE_BIG)) +        goto ldj_error; + +    if (!read_u16(&result->major_version, content, &pos, length, SRE_BIG)) +        goto ldj_error; + +    if (!load_java_pool(result, &pos)) +        goto ldj_error; + +    if (!read_u16((uint16_t *)&result->access, content, &pos, length, SRE_BIG)) +        goto ldj_error; + +    if (!read_u16(&result->this_class, content, &pos, length, SRE_BIG)) +        goto ldj_error; + +    if (!read_u16(&result->super_class, content, &pos, length, SRE_BIG)) +        goto ldj_error; + +    if (!read_u16(&result->interfaces_count, content, &pos, length, SRE_BIG)) +       goto ldj_error; + +    for (i = 0; i < result->interfaces_count; i++) +        if (!read_u16(&result->interfaces[i], content, &pos, length, SRE_BIG)) +            goto ldj_error; + +    if (!load_java_fields(result, &pos)) +        goto ldj_error; + +    if (!load_java_methods(result, &pos)) +        goto ldj_error; + +    if (!load_java_attributes(result, &pos, &result->attributes, &result->attributes_count)) +        goto ldj_error; + +    return EXE_FORMAT(result); + + ldj_error: + +    unload_java(result); + +    return NULL; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : format = description de l'exécutable à supprimer.            * +*                                                                             * +*  Description : Efface la prise en charge une nouvelle classe Java.          * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void unload_java(java_format *format) +{ +    if (format->pool_len > 0) +        unload_java_pool(format); + +    if (format->interfaces_count > 0) +        free(format->interfaces); + +    if (format->fields_count > 0) +        unload_java_fields(format); + +    if (format->methods_count > 0) +        unload_java_methods(format); + +    if (format->attributes_count > 0) +        unload_java_attributes(format, format->attributes, format->attributes_count); + +    free(format); + +} diff --git a/src/format/java/e_java.h b/src/format/java/e_java.h new file mode 100755 index 0000000..489404b --- /dev/null +++ b/src/format/java/e_java.h @@ -0,0 +1,49 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * e_java.h - prototypes pour le support du format Java + * + * 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_JAVA_E_JAVA_H +#define _FORMAT_JAVA_E_JAVA_H + + +#include "../exe_format.h" + + +/* Description des attributs Java */ +typedef struct _java_attribute java_attribute; + +/* Description du format Java */ +typedef struct _java_format java_format; + + +/* Indique si le format peut être pris en charge ici. */ +bool java_is_matching(const uint8_t *, off_t); + +/* Prend en charge une nouvelle classe Java. */ +exe_format *load_java(const uint8_t *, off_t); + +/* Efface la prise en charge une nouvelle classe Java. */ +void unload_java(java_format *); + + + +#endif  /* _FORMAT_JAVA_E_JAVA_H */ diff --git a/src/format/java/field.c b/src/format/java/field.c new file mode 100644 index 0000000..ede84f3 --- /dev/null +++ b/src/format/java/field.c @@ -0,0 +1,158 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * field.c - gestion des champs Java + * + * 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 "field.h" + + +#include <malloc.h> + + +#include "attribute.h" +#include "java-int.h" +#include "../../common/endianness.h" + + + +/* Charge les propriétés d'un champ de classe. */ +bool load_java_field(java_format *, java_field *, off_t *); + +/* Décharge les propriétés d'un champ de classe. */ +void unload_java_field(java_format *, java_field *); + + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : format = description de l'exécutable à compléter.            * +*                pos    = point de lecture à faire évoluer. [OUT]             * +*                                                                             * +*  Description : Charge les champs d'un binaire Java.                         * +*                                                                             * +*  Retour      : true si l'opération s'est bien déroulée, false sinon.        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bool load_java_fields(java_format *format, off_t *pos) +{ +    bool result;                            /* Bilan à remonter            */ +    uint16_t i;                             /* Boucle de parcours          */ + +    result = read_u16(&format->fields_count, EXE_FORMAT(format)->content, pos, +                      EXE_FORMAT(format)->length, SRE_BIG); + +    if (!result) return false; + +    if (format->fields_count > 0) +    { +        format->fields = (java_field *)calloc(format->fields_count, sizeof(java_field)); + +        for (i = 0; i < format->fields_count && result; i++) +            result = load_java_field(format, &format->fields[i], pos); + +    } + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : format = description de l'exécutable à vider.                * +*                                                                             * +*  Description : Décharge les champs d'un binaire Java.                       * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void unload_java_fields(java_format *format) +{ +    uint16_t i;                             /* Boucle de parcours          */ + +    for (i = 0; i < format->fields_count; i++) +        unload_java_field(format, &format->fields[i]); + +    free(format->fields); + + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : format = description de l'exécutable à compléter.            * +*                field  = élément à spécifier. [OUT]                          * +*                pos    = point de lecture à faire évoluer. [OUT]             * +*                                                                             * +*  Description : Charge les propriétés d'un champ de classe.                  * +*                                                                             * +*  Retour      : true si l'opération s'est bien déroulée, false sinon.        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bool load_java_field(java_format *format, java_field *field, off_t *pos) +{ +    bool result;                            /* Bilan à retourner           */ + +    result = read_u16((uint16_t *)&field->access, EXE_FORMAT(format)->content, +                      pos, EXE_FORMAT(format)->length, SRE_BIG); + +    result &= read_u16(&field->name_index, EXE_FORMAT(format)->content, +                       pos, EXE_FORMAT(format)->length, SRE_BIG); +    result &= read_u16(&field->descriptor_index, EXE_FORMAT(format)->content, +                       pos, EXE_FORMAT(format)->length, SRE_BIG); + +    result &= load_java_attributes(format, pos, +                                   &field->attributes, &field->attributes_count); + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : format = description de l'exécutable à compléter.            * +*                field  = élément à libérer.                                  * +*                                                                             * +*  Description : Décharge les propriétés d'un champ de classe.                * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void unload_java_field(java_format *format, java_field *field) +{ +    if (field->attributes_count > 0) +        unload_java_attributes(format, field->attributes, field->attributes_count); + +} diff --git a/src/format/java/field.h b/src/format/java/field.h new file mode 100644 index 0000000..94c1961 --- /dev/null +++ b/src/format/java/field.h @@ -0,0 +1,40 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * field.h - prototypes pour la gestion des champs Java + * + * 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_JAVA_FIELD_H +#define _FORMAT_JAVA_FIELD_H + + +#include "e_java.h" + + + +/* Charge les champs d'un binaire Java. */ +bool load_java_fields(java_format *, off_t *); + +/* Décharge les champs d'un binaire Java. */ +void unload_java_fields(java_format *); + + + +#endif  /* _FORMAT_JAVA_FIELD_H */ diff --git a/src/format/java/java-int.h b/src/format/java/java-int.h new file mode 100755 index 0000000..4fe9895 --- /dev/null +++ b/src/format/java/java-int.h @@ -0,0 +1,415 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * java-int.h - prototypes pour les structures internes du format Java + * + * 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_JAVA_E_JAVA_INT_H +#define _FORMAT_JAVA_E_JAVA_INT_H + + +#include "../exe_format-int.h" + + + +/* ----------------------- ELEMENTS DU RESERVOIR A CONSTANTES ----------------------- */ + + +/* Types de données dans le réservoir (§4.4) */ +typedef enum _ConstantPoolTag +{ +    CONSTANT_EMPTY                  =  0,   /* Non initialisé ou sur 2     */ + +    CONSTANT_CLASS                  =  7,   /* Classe ou interface         */ +    CONSTANT_FIELD_REF              =  9,   /* Champ ou méthode            */ +    CONSTANT_METHOD_REF             = 10,   /* Champ ou méthode            */ +    CONSTANT_INTERFACE_METHOD_REF   = 11,   /* Champ ou méthode            */ +    CONSTANT_STRING                 =  8,   /* Chaîne constante            */ +    CONSTANT_INTEGER                =  3,   /* Valeur entière              */ +    CONSTANT_FLOAT                  =  4,   /* Valeur flottante            */ +    CONSTANT_LONG                   =  5,   /* Valeur longue               */ +    CONSTANT_DOUBLE                 =  6,   /* Valeur double               */ +    CONSTANT_NAME_AND_TYPE          = 12,   /* Prototype complet           */ +    CONSTANT_UTF8                   =  1    /* Chaîne codée en UTF8        */ + +} ConstantPoolTag; + + +/* Représentation d'une classe ou d'une interface */ +typedef struct _class_info +{ +    uint16_t name_index;                    /* Indice pour le nom          */ + +} class_info; + +/* Représentation d'un champ ou d'une méthode */ +typedef struct _ref_info +{ +    uint16_t class_index;                   /* Indice de la classe         */ +    uint16_t name_and_type_index;           /* Prototype associé           */ + +} ref_info; + +/* Représentation d'une chaîne constante */ +typedef struct _string_info +{ +    uint16_t string_index;                  /* Indice de la valeur UTF8    */ + +} string_info; + +/* Représentation d'une valeur 'int' */ +typedef struct _integer_info +{ +    uint32_t val;                           /* Valeur au format 'int'      */ + +} integer_info; + +/* Représentation d'une valeur 'float' */ +typedef struct _float_info +{ +    float val;                              /* Valeur au format 'float'    */ + +} float_info; + +/* Représentation d'une valeur 'long' */ +typedef struct _long_info +{ +    long val;                               /* Valeur au format 'long'     */ + +} long_info; + +/* Représentation d'une valeur 'double' */ +typedef struct _double_info +{ +    double val;                             /* Valeur au format 'double'   */ + +} double_info; + +/* Représentation brève d'un champ ou d'une méthode */ +typedef struct _name_and_type_info +{ +    uint16_t name_index;                   /* Indice du nom correspondant */ +    uint16_t descriptor_index;             /* Prototype associé           */ + +} name_and_type_info; + +/* Représentation d'une chaîne codée en UTF8 */ +typedef struct _utf8_info +{ +    char *bytes;                            /* Valeur de la chaîne         */ + +} utf8_info; + + +/* Entrée du réservoir */ +typedef struct _constant_pool_entry +{ +    ConstantPoolTag tag;                    /* Type d'entrée présente      */ + +    union +    { +        class_info class; +        ref_info ref; +        string_info string; +        integer_info int_val; +        float_info float_val; +        long_info long_val; +        double_info double_val; +        name_and_type_info name_type; +        utf8_info utf8; + +    } info;                                 /* Infos portées par l'entrée  */ + +} constant_pool_entry; + + + +/* ------------------------ ATTRIBUTS POUR DES ELEMENTS JAVA ------------------------ */ + + +/* Types des attributs reconnus */ +typedef enum _JavaAttributeType +{ +    JAT_NONE                = 0,            /* Attribu non chargé          */ + +    JAT_CONSTANT_VALUE,                     /* Valeur constante            */ +    JAT_CODE,                               /* Code exécutable             */ +    JAT_EXCEPTIONS,                         /* Exceptions remontables      */ +    JAT_INNER_CLASSES,                      /* Classes internes            */ +    JAT_SYNTHETIC,                          /* Membre non présent          */ +    JAT_SOURCE_FILE,                        /* Fichier source du code      */ +    JAT_LINE_NUMBER,                        /* Correspondances de débogage */ +    JAT_LOCAL_VARIABLES,                    /* Variable(s) locale(s)       */ +    JAT_DEPRECATED                          /* Elément vieillot à oublier  */ + +} JavaAttributeType; + +/* Représentation d'un attribut à valeur constante (§4.7.2) */ +typedef struct _const_value_attrib +{ +    uint16_t const_value_index;             /* Indice dans le réservoir    */ + +} const_value_attrib; + +/* Représentation d'un attribut de code (§4.7.3) */ + +typedef struct _code_exception +{ +    uint16_t start_pc;                      /* Début de la zone couverte   */ +    uint16_t end_pc;                        /* Fin de la zone couverte     */ +    uint16_t handler_pc;                    /* Début du gestionnaire       */ +    uint16_t catch_type;                    /* Indice du type d'exception  */ + +} code_exception; + +typedef struct _code_attrib +{ +    uint16_t max_stack;                     /* Taille maximale de la pile  */ +    uint16_t max_locals;                    /* Nombre de variables (!)     */ +    uint32_t code_length;                   /* Taille du code référencé    */ + +    off_t content;                          /* Début du code exécutable    */ + +    code_exception *exceptions;             /* Exceptions gérées           */ +    uint16_t exceptions_count;              /* Nombre de ces exceptions    */ + +    java_attribute *attributes;             /* Attributs liés au code      */ +    uint16_t attributes_count;              /* Nombre de ces attributs     */ + +} code_attrib; + +/* Représentation d'un attribut fixant les exceptions remontables (§4.7.4) */ + +typedef struct _exceptions_attrib +{ +    uint16_t *throw;                        /* Exceptions remontées        */ +    uint16_t throw_count;                   /* Nombre de ces exceptions    */ + +} exceptions_attrib; + +/* Représentation d'un attribut présentant les classes internes (§4.7.5) */ + +typedef enum _InnerClassAccessFlags +{ +    ICA_PUBLIC      = 0x0001,               /* Elément public              */ +    ICA_PRIVATE     = 0x0002,               /* Elément privé               */ +    ICA_PROTECTED   = 0x0004,               /* Elément sous protection     */ +    ICA_STATIC      = 0x0008,               /* Elément statique            */ +    ICA_FINAL       = 0x0010,               /* Elément défini un seule fois*/ +    ICA_INTERFACE   = 0x0200,               /* Déclaration d'interface     */ +    ICA_ABSTRACT    = 0x0400                /* Déclaré comme abstrait      */ + +} InnerClassAccessFlags; + +typedef struct _inner_class +{ +    uint16_t inner_class_info_index;        /* Propriétés de la classe     */ +    uint16_t outer_class_info_index;        /* Propriétés de la parente    */ +    uint16_t inner_name_index;              /* Nom de la classe            */ +    InnerClassAccessFlags access;           /* Droits d'accès              */ + +} inner_class; + +typedef struct _inner_classes_attrib +{ +    inner_class *classes;                   /* Classes internes            */ +    uint16_t classes_count;                 /* Nombre de ces classe        */ + +} inner_classes_attrib; + +/* Représentation d'un fichier source (§4.7.7) */ +typedef struct _source_file_attrib +{ +    uint16_t source_file_index;             /* Indice dans le réservoir    */ + +} source_file_attrib; + +/* Représentation des correspondances entre lignes et code (§4.7.8) */ + +typedef struct _pc_and_line +{ +    uint16_t start_pc;                      /* Début de la zone visée      */ +    uint16_t number;                        /* Numéro de ligne du code     */ + +} pc_and_line; + +typedef struct _line_number_attrib +{ +    pc_and_line *lines;                     /* Correspondances code/source */ +    uint16_t lines_count;                   /* Nombre de correspondances   */ + +} line_number_attrib; + +/* Représentation des variables locales (§4.7.9) */ + +typedef struct _local_variable +{ +    uint16_t start_pc;                      /* Position dans le code       */ +    uint16_t length;                        /* Taille de la variable       */ +    uint16_t name_index;                    /* Indice nominal de réservoir */  +    uint16_t descriptor_index;              /* Type de la variable         */ +    uint16_t index;                         /* Place dans la liste complète*/ + +} local_variable; + +typedef struct _local_variables_attrib +{ +    local_variable *vars;                   /* Variables locales           */ +    uint16_t vars_count;                    /* Nombre de ces variables     */ + +} local_variables_attrib; + +/* Description des attributs Java */ +struct _java_attribute +{ +    JavaAttributeType type;                 /* Type d'attribut représenté  */ + +    union +    { +        const_value_attrib const_value; +        code_attrib code; +        exceptions_attrib exceptions; +        inner_classes_attrib inner_classes; +        source_file_attrib source_file; +        line_number_attrib line_number; +        local_variables_attrib local_vars; + +    } info;                                 /* Infos portées par l'attribut*/ + +}; + + + +/* ---------------------------- CHAMPS POUR CLASSES JAVA ---------------------------- */ + + +/* Types d'accès aux champs (§4.5) */ +typedef enum _FieldAccessFlags +{ +    FAC_PUBLIC      = 0x0001,               /* Elément public              */ +    FAC_PRIVATE     = 0x0002,               /* Elément privé               */ +    FAC_PROTECTED   = 0x0004,               /* Elément sous protection     */ +    FAC_STATIC      = 0x0008,               /* Elément statique            */ +    FAC_FINAL       = 0x0010,               /* Elément défini un seule fois*/ +    FAC_VOLATILE    = 0x0040,               /* Elément sans cache          */ +    FAC_TRANSIENT   = 0x0080                /* Elément ni lu ni écrit...   */ + +} FieldAccessFlags; + +/* Description d'un champ Java */ +typedef struct _java_field +{ +    FieldAccessFlags access;                /* Droits d'accès              */ + +    uint16_t name_index;                    /* Nom dans le réservoir       */ +    uint16_t descriptor_index;              /* Prototype au même endroit   */ + +    java_attribute *attributes;             /* Attributs liés au champ     */ +    uint16_t attributes_count;              /* Nombre de ces attributs     */ + +} java_field; + + + +/* --------------------------- METHODES POUR CLASSES JAVA --------------------------- */ + + +/* Types d'accès aux champs (§4.6) */ +typedef enum _MethodAccessFlags +{ +    MAC_PUBLIC          = 0x0001,           /* Elément public              */ +    MAC_PRIVATE         = 0x0002,           /* Elément privé               */ +    MAC_PROTECTED       = 0x0004,           /* Elément sous protection     */ +    MAC_STATIC          = 0x0008,           /* Elément statique            */ +    MAC_FINAL           = 0x0010,           /* Elément défini un seule fois*/ +    MAC_SYNCHRONIZED    = 0x0020,           /* Elément avec mutex natif    */ +    MAC_NATIVE          = 0x0100,           /* Elément conçu sans Java     */ +    MAC_ABSTRACT        = 0x0400,           /* Elément sans implantation   */ +    MAC_STRICT          = 0x0800            /* Elément déclaré stricte FP  */  + +} MethodAccessFlags; + +/* Description d'une méthode Java */ +typedef struct _java_method +{ +    MethodAccessFlags access;               /* Droits d'accès              */ + +    uint16_t name_index;                    /* Nom dans le réservoir       */ +    uint16_t descriptor_index;              /* Prototype au même endroit   */ + +    java_attribute *attributes;             /* Attributs liés à la méthode */ +    uint16_t attributes_count;              /* Nombre de ces attributs     */ + +} java_method; + + + +/* ---------------------------- LISTE DES DROITS D'ACCES ---------------------------- */ + + +/* Types d'accès (§4.1) */ +typedef enum _ClassAccessFlags +{ +    CAC_PUBLIC      = 0x0001,               /* Elément public              */ +    CAC_FINAL       = 0x0010,               /* Déclaré comme final         */ +    CAC_SUPER       = 0x0020,               /* Traitement spécial          */ +    CAC_INTERFACE   = 0x0200,               /* Déclaration d'interface     */ +    CAC_ABSTRACT    = 0x0400                /* Déclaré comme abstrait      */ + +} ClassAccessFlags; + + + +/* --------------------------- DESCRIPTION DU FORMAT JAVA --------------------------- */ + + +/* Description du format Java */ +struct _java_format +{ +    exe_format dummy;                       /* A laisser en premier        */ + +    uint16_t minor_version;                 /* Numéro de révision mineur   */ +    uint16_t major_version;                 /* Numéro de révision majeur   */ + +    constant_pool_entry *pool;              /* Réservoir de constantes     */ +    uint16_t pool_len;                      /* Quantité de ces éléments    */ + +    ClassAccessFlags access;                /* Type de classe/interface    */ + +    uint16_t this_class;                    /* Infos sur la classe         */ +    uint16_t super_class;                   /* Infos sur la classe parente */ + +    uint16_t *interfaces;                   /* Interfaces intégrées        */ +    uint16_t interfaces_count;              /* Nombre de ces interfaces    */ + +    java_field *fields;                     /* Champs de la classe         */ +    uint16_t fields_count;                  /* Nombre de champs présents   */ + +    java_method *methods;                   /* Méthodes de la classe       */ +    uint16_t methods_count;                 /* Nombre de méthodes listées  */ + +    java_attribute *attributes;             /* Attributs liés à la classe  */ +    uint16_t attributes_count;              /* Nombre de ces attributs     */ + +}; + + + +#endif  /* _FORMAT_JAVA_E_JAVA_INT_H */ diff --git a/src/format/java/method.c b/src/format/java/method.c new file mode 100644 index 0000000..bf927a1 --- /dev/null +++ b/src/format/java/method.c @@ -0,0 +1,157 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * method.c - gestion des méthodes Java + * + * 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 "method.h" + + +#include <malloc.h> + + +#include "attribute.h" +#include "java-int.h" +#include "../../common/endianness.h" + + + +/* Charge les propriétés d'une méthode de classe. */ +bool load_java_method(java_format *, java_method *, off_t *); + +/* Décharge les propriétés d'une méthode de classe. */ +void unload_java_method(java_format *, java_method *); + + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : format = description de l'exécutable à compléter.            * +*                pos    = point de lecture à faire évoluer. [OUT]             * +*                                                                             * +*  Description : Charge les méthodes d'un binaire Java.                       * +*                                                                             * +*  Retour      : true si l'opération s'est bien déroulée, false sinon.        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bool load_java_methods(java_format *format, off_t *pos) +{ +    bool result;                            /* Bilan à remonter            */ +    uint16_t i;                             /* Boucle de parcours          */ + +    result = read_u16(&format->methods_count, EXE_FORMAT(format)->content, pos, +                      EXE_FORMAT(format)->length, SRE_BIG); + +    if (!result) return false; + +    if (format->methods_count > 0) +    { +        format->methods = (java_method *)calloc(format->methods_count, sizeof(java_method)); + +        for (i = 0; i < format->methods_count && result; i++) +            result = load_java_method(format, &format->methods[i], pos); + +    } + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : format = description de l'exécutable à vider.                * +*                                                                             * +*  Description : Décharge les méthodes d'un binaire Java.                     * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void unload_java_methods(java_format *format) +{ +    uint16_t i;                             /* Boucle de parcours          */ + +    for (i = 0; i < format->methods_count; i++) +        unload_java_method(format, &format->methods[i]); + +    free(format->methods); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : format = description de l'exécutable à compléter.            * +*                method = élément à spécifier. [OUT]                          * +*                pos    = point de lecture à faire évoluer. [OUT]             * +*                                                                             * +*  Description : Charge les propriétés d'une méthode de classe.               * +*                                                                             * +*  Retour      : true si l'opération s'est bien déroulée, false sinon.        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bool load_java_method(java_format *format, java_method *method, off_t *pos) +{ +    bool result;                            /* Bilan à retourner           */ + +    result = read_u16((uint16_t *)&method->access, EXE_FORMAT(format)->content, +                      pos, EXE_FORMAT(format)->length, SRE_BIG); + +    result &= read_u16(&method->name_index, EXE_FORMAT(format)->content, +                       pos, EXE_FORMAT(format)->length, SRE_BIG); +    result &= read_u16(&method->descriptor_index, EXE_FORMAT(format)->content, +                       pos, EXE_FORMAT(format)->length, SRE_BIG); + +    result &= load_java_attributes(format, pos, +                                   &method->attributes, &method->attributes_count); + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : format = description de l'exécutable à compléter.            * +*                method = élément à libérer.                                  * +*                                                                             * +*  Description : Décharge les propriétés d'une méthode de classe.             * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void unload_java_method(java_format *format, java_method *method) +{ +    if (method->attributes_count > 0) +        unload_java_attributes(format, method->attributes, method->attributes_count); + +} diff --git a/src/format/java/method.h b/src/format/java/method.h new file mode 100644 index 0000000..01cef95 --- /dev/null +++ b/src/format/java/method.h @@ -0,0 +1,40 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * method.h - prototypes pour la gestion des méthodes Java + * + * 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_JAVA_METHOD_H +#define _FORMAT_JAVA_METHOD_H + + +#include "e_java.h" + + + +/* Charge les méthodes d'un binaire Java. */ +bool load_java_methods(java_format *, off_t *); + +/* Décharge les méthodes d'un binaire Java. */ +void unload_java_methods(java_format *); + + + +#endif  /* _FORMAT_JAVA_METHOD_H */ diff --git a/src/format/java/pool.c b/src/format/java/pool.c new file mode 100755 index 0000000..f735819 --- /dev/null +++ b/src/format/java/pool.c @@ -0,0 +1,354 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * pool.c - lecture du réservoir de constantes + * + * 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 "pool.h" + + +#include <malloc.h> +#include <math.h> +#include <string.h> + +#include "java-int.h" +#include "../../common/endianness.h" + + + +/* Charge les propriétés d'une constante du réservoir. */ +bool load_java_pool_entry(java_format *, constant_pool_entry *, off_t *); + + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : format = description de l'exécutable à compléter.            * +*                pos    = point de lecture à faire évoluer. [OUT]             * +*                                                                             * +*  Description : Charge le réservoir de constantes d'un binaire Java.         * +*                                                                             * +*  Retour      : true si l'opération s'est bien déroulée, false sinon.        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bool load_java_pool(java_format *format, off_t *pos) +{ +    bool result;                            /* Bilan à remonter            */ +    uint16_t count;                         /* Nombre d'éléments présents  */ +    uint16_t i;                             /* Boucle de parcours          */ + +    result = read_u16(&count, EXE_FORMAT(format)->content, pos, +                      EXE_FORMAT(format)->length, SRE_BIG); + +    format->pool_len = count - 1; +    format->pool = (constant_pool_entry *)calloc(count - 1, sizeof(constant_pool_entry)); + +    for (i = 1; i < count && result; i++) +    { +        result = load_java_pool_entry(format, &format->pool[i - 1], pos); + +        if (format->pool[i - 1].tag == CONSTANT_LONG +            || format->pool[i - 1].tag == CONSTANT_DOUBLE) +        { +            i++; + +            /* On n'est jamais trop prudent */ +            if (i < count) +                format->pool[i - 1].tag = CONSTANT_EMPTY; + +        } + +    } + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : format = description de l'exécutable à vider.                * +*                                                                             * +*  Description : Décharge le réservoir de constantes d'un binaire Java.       * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void unload_java_pool(java_format *format) +{ +    uint16_t i;                             /* Boucle de parcours          */ + +    for (i = 0; i < format->pool_len; i++) +        switch (format->pool[i].tag) +        { +            case CONSTANT_EMPTY: +            case CONSTANT_CLASS: +            case CONSTANT_FIELD_REF: +            case CONSTANT_METHOD_REF: +            case CONSTANT_INTERFACE_METHOD_REF: +            case CONSTANT_STRING: +            case CONSTANT_INTEGER: +            case CONSTANT_FLOAT: +            case CONSTANT_LONG: +            case CONSTANT_DOUBLE: +            case CONSTANT_NAME_AND_TYPE: +                break; + +            case CONSTANT_UTF8: +                free(format->pool[i].info.utf8.bytes); +                break; + +        } + +    free(format->pool); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : format = description de l'exécutable à compléter.            * +*                entry  = élément à spécifier. [OUT]                          * +*                pos    = point de lecture à faire évoluer. [OUT]             * +*                                                                             * +*  Description : Charge les propriétés d'une constante du réservoir.          * +*                                                                             * +*  Retour      : true si l'opération s'est bien déroulée, false sinon.        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bool load_java_pool_entry(java_format *format, constant_pool_entry *entry, off_t *pos) +{ +    bool result;                            /* Bilan à retourner           */ +    uint8_t tag;                            /* Type de l'élément           */ +    uint32_t low_bytes;                     /* Octets de poids faible      */ +    uint32_t high_bytes;                    /* Octets de poids fort        */ +    uint64_t bits;                          /* Nombre lu sur 64 bits       */ +    int sign;                               /* Signe du nombre lu          */ +	int exponent;                           /* Exposant du nombre lu       */ +	uint64_t mantissa32;                    /* Mantisse du nombre lu 32b   */ +	uint64_t mantissa64;                    /* Mantisse du nombre lu 64b   */ +    uint16_t length;                        /* Taille d'une chaîne         */ + +    result = read_u8(&tag, EXE_FORMAT(format)->content, pos, +                     EXE_FORMAT(format)->length, SRE_BIG); + +    entry->tag = tag; + +    switch (entry->tag) +    { +        case CONSTANT_CLASS: +            result = read_u16(&entry->info.class.name_index, EXE_FORMAT(format)->content, +                              pos, EXE_FORMAT(format)->length, SRE_BIG); +            break; + +        case CONSTANT_FIELD_REF: +        case CONSTANT_METHOD_REF: +        case CONSTANT_INTERFACE_METHOD_REF: + +            result = read_u16(&entry->info.ref.class_index, EXE_FORMAT(format)->content, +                              pos, EXE_FORMAT(format)->length, SRE_BIG); +            result &= read_u16(&entry->info.ref.name_and_type_index, EXE_FORMAT(format)->content, +                               pos, EXE_FORMAT(format)->length, SRE_BIG); + +            break; + +        case CONSTANT_STRING: +            result = read_u16(&entry->info.string.string_index, EXE_FORMAT(format)->content, +                              pos, EXE_FORMAT(format)->length, SRE_BIG); +            break; + +        case CONSTANT_INTEGER: +            result = read_u32(&entry->info.int_val.val, EXE_FORMAT(format)->content, +                              pos, EXE_FORMAT(format)->length, SRE_BIG); +            break; + +        case CONSTANT_FLOAT: + +            result = read_u32(&low_bytes, EXE_FORMAT(format)->content, +                              pos, EXE_FORMAT(format)->length, SRE_BIG); + +            if (result) +            { +                if (low_bytes == 0x7f800000) +                    entry->info.float_val.val = INFINITY; + +                else if (low_bytes == 0xff800000) +                    entry->info.float_val.val = /* -1* */INFINITY; + +                else if ((low_bytes >= 0x7f800001 && low_bytes <= 0x7fffffff) +                         || (low_bytes >= 0xff800001 && low_bytes <= 0xffffffff)) +                    entry->info.float_val.val = NAN; + +                else if (low_bytes == 0x00000000 || low_bytes == 0x80000000) +                    entry->info.float_val.val = 0; + +                else +                { +                    sign = (low_bytes & 0x80000000) ? -1 : 1; +                    exponent = (low_bytes >> 23) & 0xff; +                    mantissa32 = (exponent == 0 ? +                                  (low_bytes & 0x7fffff) << 1 : +                                  (low_bytes & 0x7fffff) | 0x800000); + +                    entry->info.float_val.val = pow(2, (exponent - 150)); +                    entry->info.float_val.val *= mantissa32; +                    entry->info.float_val.val *= sign; + +                } + +            } + +            break; + +        case CONSTANT_LONG: + +            result = read_u32(&high_bytes, EXE_FORMAT(format)->content, +                              pos, EXE_FORMAT(format)->length, SRE_BIG); +            result &= read_u32(&low_bytes, EXE_FORMAT(format)->content, +                               pos, EXE_FORMAT(format)->length, SRE_BIG); + +            if (result) +            { +                entry->info.double_val.val = (uint64_t)high_bytes << 32; +                entry->info.double_val.val += low_bytes; +            } + +            break; + +        case CONSTANT_DOUBLE: + +            result = read_u32(&high_bytes, EXE_FORMAT(format)->content, +                              pos, EXE_FORMAT(format)->length, SRE_BIG); +            result &= read_u32(&low_bytes, EXE_FORMAT(format)->content, +                               pos, EXE_FORMAT(format)->length, SRE_BIG); + +            if (result) +            { +                bits = (uint64_t)high_bytes << 32 | (uint64_t)low_bytes; + +                if (bits == 0x7ff0000000000000ll) +                    entry->info.double_val.val = INFINITY; + +                else if (bits == 0xfff0000000000000ll) +                    entry->info.double_val.val = /* -1* */INFINITY; + +                else if ((bits >= 0x7ff0000000000001ll && bits <= 0x7fffffffffffffffll) +                         || (bits >= 0xfff0000000000001ll && bits <= 0xffffffffffffffffll)) +                    entry->info.double_val.val = NAN; + +                else if (bits == 0x0000000000000000ll || bits == 0x8000000000000000ll) +                    entry->info.double_val.val = 0; + +                else +                { +                    sign = ((bits >> 63) == 0) ? 1 : -1; +                    exponent = (bits >> 52) & 0x7ffl; +                    mantissa64 = (exponent == 0 ? +                                  (bits & 0xfffffffffffffll) << 1 : +                                  (bits & 0xfffffffffffffll) | 0x10000000000000ll); + +                    entry->info.double_val.val = pow(2, (exponent - 1075)); +                    entry->info.double_val.val *= mantissa64; +                    entry->info.double_val.val *= sign; + +                } + +            } + +            break; + +        case CONSTANT_NAME_AND_TYPE: + +            result = read_u16(&entry->info.name_type.name_index, EXE_FORMAT(format)->content, +                              pos, EXE_FORMAT(format)->length, SRE_BIG); +            result &= read_u16(&entry->info.name_type.descriptor_index, EXE_FORMAT(format)->content, +                               pos, EXE_FORMAT(format)->length, SRE_BIG); + +            break; + +        case CONSTANT_UTF8: + +            result = read_u16(&length, EXE_FORMAT(format)->content, +                              pos, EXE_FORMAT(format)->length, SRE_BIG); + +            if (result) +            { +                entry->info.utf8.bytes = (char *)calloc(length + 1, sizeof(char)); +                memcpy(entry->info.utf8.bytes, &EXE_FORMAT(format)->content[*pos], length); +                *pos += length; +            } + +            break; + +        default: +            result = false; +            break; + +    } + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : format = description de l'exécutable à compléter.            * +*                index  = indice de l'élément dont la valeur est à recupérer. * +*                str    = adresse où placer la chaîne de caractères trouvée.  * +*                                                                             * +*  Description : Recherche une chaîne de caractères dans le réservoir.        * +*                                                                             * +*  Retour      : true si l'opération s'est bien déroulée, false sinon.        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bool get_java_pool_ut8_string(java_format *format, uint16_t index, const char **str) +{ +    bool result;                            /* Bilan à renvoyer            */ +    constant_pool_entry *entry;             /* Entrée du réservoir visée   */ + +    result = (index <= format->pool_len); + +    if (result) +    { +        entry = &format->pool[index - 1]; + +        result = (entry->tag == CONSTANT_UTF8); + +        if (result) +            (*str) = entry->info.utf8.bytes; + +    } + +    return result; + +} diff --git a/src/format/java/pool.h b/src/format/java/pool.h new file mode 100755 index 0000000..49d66a7 --- /dev/null +++ b/src/format/java/pool.h @@ -0,0 +1,42 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * pool.h - prototypes pour la lecture du réservoir de constantes + * + * 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_JAVA_POOL_H +#define _FORMAT_JAVA_POOL_H + + +#include "e_java.h" + + + +/* Charge le réservoir de constantes d'un binaire Java. xs*/ +bool load_java_pool(java_format *, off_t *); + +/* Décharge le réservoir de constantes d'un binaire Java. */ +void unload_java_pool(java_format *); + +/* Recherche une chaîne de caractères dans le réservoir. */ +bool get_java_pool_ut8_string(java_format *, uint16_t, const char **); + + +#endif  /* _FORMAT_JAVA_POOL_H */ | 
