summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2009-01-25 21:27:14 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2009-01-25 21:27:14 (GMT)
commit21493170bb188ad9548820c830c3e8d7055e3f46 (patch)
treefdc4d03b0aaa5e7ed8a0b8b151926f654cece321
parent8f1e49332cd81760c98166be9df79a7136f5ca57 (diff)
Supported the Java Class file format.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@46 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
-rw-r--r--ChangeLog38
-rw-r--r--configure.ac6
-rw-r--r--src/Makefile.am4
-rw-r--r--src/binary.c17
-rwxr-xr-xsrc/common/Makefile.am16
-rwxr-xr-xsrc/common/endianness.c166
-rwxr-xr-xsrc/common/endianness.h54
-rw-r--r--src/format/Makefile.am2
-rw-r--r--src/format/exe_format.c94
-rw-r--r--src/format/exe_format.h24
-rwxr-xr-xsrc/format/java/Makefile.am19
-rw-r--r--src/format/java/attribute.c712
-rw-r--r--src/format/java/attribute.h40
-rwxr-xr-xsrc/format/java/e_java.c173
-rwxr-xr-xsrc/format/java/e_java.h49
-rw-r--r--src/format/java/field.c158
-rw-r--r--src/format/java/field.h40
-rwxr-xr-xsrc/format/java/java-int.h415
-rw-r--r--src/format/java/method.c157
-rw-r--r--src/format/java/method.h40
-rwxr-xr-xsrc/format/java/pool.c354
-rwxr-xr-xsrc/format/java/pool.h42
22 files changed, 2614 insertions, 6 deletions
diff --git a/ChangeLog b/ChangeLog
index e2d0f8a..9c68616 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,41 @@
+2009-01-25 Cyrille Bagard <nocbos@gmail.com>
+
+ * configure.ac:
+ Add the new Makefiles from 'common' and 'src/format/java/' directories to AC_CONFIG_FILES.
+ The modification of WARNING_FLAGS and will be improved.
+
+ * src/binary.c:
+ Update code.
+
+ * src/common/endianness.c:
+ * src/common/endianness.h:
+ * src/common/Makefile.am:
+ New entries: read unsigned integers regardless of the host machine endianness.
+
+ * src/format/exe_format.c:
+ * src/format/exe_format.h:
+ Properly register new file formats.
+
+ * src/format/java/attribute.c:
+ * src/format/java/attribute.h:
+ * src/format/java/e_java.c:
+ * src/format/java/e_java.h:
+ * src/format/java/field.c:
+ * src/format/java/field.h:
+ * src/format/java/java-int.h:
+ * src/format/java/Makefile.am:
+ * src/format/java/method.c:
+ * src/format/java/method.h:
+ * src/format/java/pool.c:
+ * src/format/java/pool.h:
+ New entries: support the Java Class file format.
+
+ * src/format/Makefile.am:
+ Add java to SUBDIRS.
+
+ * src/Makefile.am:
+ Add common to SUBDIRS and update openida_LDADD.
+
2009-01-06 Cyrille Bagard <nocbos@gmail.com>
* src/easygtk.c:
diff --git a/configure.ac b/configure.ac
index 76c502f..44b68cb 100644
--- a/configure.ac
+++ b/configure.ac
@@ -139,7 +139,7 @@ AC_SUBST(DEBUG_CFLAGS)
#-Wall -Wimplicit -Wreturn-type -Wunused -Wswitch -Wcomment -Wuninitialized -Wparentheses -Wpointer-arith -Wmissing-prototypes
-WARNING_FLAGS="-Wall -Wimplicit -Wreturn-type -Wunused -Wswitch -Wcomment -Wuninitialized -Wparentheses -Wpointer-arith -Wmissing-prototypes"
+WARNING_FLAGS="-D_ISOC99_SOURCE -Wall -Wimplicit -Wreturn-type -Wunused -Wswitch -Wcomment -Wuninitialized -Wparentheses -Wpointer-arith -Wmissing-prototypes"
#-Wcast-qual -Wconversion -Wsign-compare -Wdisabled-optimization
@@ -183,9 +183,11 @@ AC_CONFIG_FILES([Makefile
src/Makefile
src/arch/Makefile
src/arch/x86/Makefile
+ src/common/Makefile
src/format/Makefile
src/format/dwarf/Makefile
- src/format/elf/Makefile])
+ src/format/elf/Makefile
+ src/format/java/Makefile])
AC_OUTPUT
diff --git a/src/Makefile.am b/src/Makefile.am
index 24c955a..5a0a565 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -25,7 +25,7 @@ AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS)
openida_LDFLAGS = $(LIBGTK_LIBS) -L/usr/X11R6/lib -ldl -lm $(LIBXML_LIBS) `pkg-config --libs gthread-2.0`
-openida_LDADD = $(LIBINTL) arch/libarch.a arch/x86/libarchx86.a format/libformat.a format/dwarf/libformatdwarf.a format/elf/libformatelf.a
+openida_LDADD = $(LIBINTL) arch/libarch.a arch/x86/libarchx86.a format/libformat.a format/dwarf/libformatdwarf.a format/elf/libformatelf.a format/java/libformatjava.a common/libcommon.a
-SUBDIRS = arch format
+SUBDIRS = arch common format
diff --git a/src/binary.c b/src/binary.c
index 4d31c40..6bfa551 100644
--- a/src/binary.c
+++ b/src/binary.c
@@ -43,6 +43,12 @@
#include "format/elf/e_elf.h"
#include "format/dwarf/d_dwarf.h"
+#include "format/java/e_java.h"
+
+
+#ifndef _
+# define _(str) str
+#endif
@@ -385,6 +391,8 @@ void fill_snippet(GtkSnippet *snippet, GtkWidget *panel, GtkWidget *panel2)
len = 0x28;
+ register_exe_format(_("Java"), java_is_matching, load_java);
+
bin_data = map_binary_file("/tmp/hello", &length);
@@ -395,6 +403,15 @@ void fill_snippet(GtkSnippet *snippet, GtkWidget *panel, GtkWidget *panel2)
+ format = load_new_exe_format(bin_data, length);
+
+ printf(" --> ok ? %p\n", format);
+
+ exit(0);
+
+ return;
+
+
format = load_elf(bin_data, length);
dformat = load_dwarf(bin_data, length, format);
diff --git a/src/common/Makefile.am b/src/common/Makefile.am
new file mode 100755
index 0000000..323ba17
--- /dev/null
+++ b/src/common/Makefile.am
@@ -0,0 +1,16 @@
+
+lib_LIBRARIES = libcommon.a
+
+libcommon_a_SOURCES = \
+ endianness.h endianness.c
+
+libcommon_a_CFLAGS = $(AM_CFLAGS)
+
+
+INCLUDES =
+
+AM_CPPFLAGS =
+
+AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS)
+
+SUBDIRS =
diff --git a/src/common/endianness.c b/src/common/endianness.c
new file mode 100755
index 0000000..202262a
--- /dev/null
+++ b/src/common/endianness.c
@@ -0,0 +1,166 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * endianness.c - manipulation abstraite des nombres
+ *
+ * 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 "endianness.h"
+
+
+
+
+
+
+
+/******************************************************************************
+* *
+* Paramètres : target = lieu d'enregistrement de la lecture. [OUT] *
+* data = flux de données à analyser. *
+* pos = position courante dans ce flux. [OUT] *
+* len = taille totale des données à analyser. *
+* endian = ordre des bits dans la source. *
+* *
+* Description : Lit un nombre non signé sur un octet. *
+* *
+* Retour : Bilan de l'opération : true en cas de succès, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool read_u8(uint8_t *target, const uint8_t *data, off_t *pos, off_t len, SourceEndian endian)
+{
+ if ((len - *pos) < 1) return false;
+
+ *target = data[*pos];
+
+ *pos += 1;
+
+ return true;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : target = lieu d'enregistrement de la lecture. [OUT] *
+* data = flux de données à analyser. *
+* pos = position courante dans ce flux. [OUT] *
+* len = taille totale des données à analyser. *
+* endian = ordre des bits dans la source. *
+* *
+* Description : Lit un nombre non signé sur deux octets. *
+* *
+* Retour : Bilan de l'opération : true en cas de succès, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool read_u16(uint16_t *target, const uint8_t *data, off_t *pos, off_t len, SourceEndian endian)
+{
+ if ((len - *pos) < 2) return false;
+
+ switch (endian)
+ {
+
+
+
+ case SRE_BIG:
+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+
+ *target = data[*pos + 1] | (uint16_t)data[*pos] << 8;
+
+#elif __BYTE_ORDER == __BIG_ENDIAN
+
+ *target = data[*pos] | (uint16_t)data[*pos + 1] << 8;
+
+#else
+
+# error "TODO : PDP !"
+
+#endif
+
+ break;
+
+
+ }
+
+ *pos += 2;
+
+ return true;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : target = lieu d'enregistrement de la lecture. [OUT] *
+* data = flux de données à analyser. *
+* pos = position courante dans ce flux. [OUT] *
+* len = taille totale des données à analyser. *
+* endian = ordre des bits dans la source. *
+* *
+* Description : Lit un nombre non signé sur quatre octets. *
+* *
+* Retour : Bilan de l'opération : true en cas de succès, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool read_u32(uint32_t *target, const uint8_t *data, off_t *pos, off_t len, SourceEndian endian)
+{
+ if ((len - *pos) < 4) return false;
+
+ switch (endian)
+ {
+
+
+
+ case SRE_BIG:
+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+
+ *target = data[*pos + 3] | (uint16_t)data[*pos + 2] << 8;
+ *target |= data[*pos + 1] << 16 | (uint16_t)data[*pos] << 24;
+
+#elif __BYTE_ORDER == __BIG_ENDIAN
+
+ *target = data[*pos] | (uint16_t)data[*pos + 1] << 8;
+ *target |= data[*pos + 2] << 16 | (uint16_t)data[*pos + 3] << 24;
+
+#else
+
+# error "TODO : PDP !"
+
+#endif
+
+ break;
+
+
+ }
+
+ *pos += 4;
+
+ return true;
+
+}
diff --git a/src/common/endianness.h b/src/common/endianness.h
new file mode 100755
index 0000000..7ae9575
--- /dev/null
+++ b/src/common/endianness.h
@@ -0,0 +1,54 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * endianness.h - prototypes pour la manipulation abstraite des nombres
+ *
+ * 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 _COMMON_ENDIANNESS_H
+#define _COMMON_ENDIANNESS_H
+
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <sys/types.h>
+
+
+/* Type de boutismes existants */
+typedef enum _SourceEndian
+{
+ SRE_LITTLE, /* Petits boutistes */
+ SRE_BIG, /* Gros boutistes */
+ SRE_MIDDLE /* Moyens boutistes */
+
+} SourceEndian;
+
+
+/* Lit un nombre non signé sur un octet. */
+bool read_u8(uint8_t *, const uint8_t *, off_t *, off_t, SourceEndian );
+
+/* Lit un nombre non signé sur deux octets. */
+bool read_u16(uint16_t *, const uint8_t *, off_t *, off_t, SourceEndian);
+
+/* Lit un nombre non signé sur quatre octets. */
+bool read_u32(uint32_t *, const uint8_t *, off_t *, off_t, SourceEndian);
+
+
+
+#endif /* _COMMON_ENDIANNESS_H */
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 */