From 21493170bb188ad9548820c830c3e8d7055e3f46 Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Sun, 25 Jan 2009 21:27:14 +0000
Subject: Supported the Java Class file format.

git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@46 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
---
 ChangeLog                   |  38 +++
 configure.ac                |   6 +-
 src/Makefile.am             |   4 +-
 src/binary.c                |  17 ++
 src/common/Makefile.am      |  16 +
 src/common/endianness.c     | 166 +++++++++++
 src/common/endianness.h     |  54 ++++
 src/format/Makefile.am      |   2 +-
 src/format/exe_format.c     |  94 +++++-
 src/format/exe_format.h     |  24 ++
 src/format/java/Makefile.am |  19 ++
 src/format/java/attribute.c | 712 ++++++++++++++++++++++++++++++++++++++++++++
 src/format/java/attribute.h |  40 +++
 src/format/java/e_java.c    | 173 +++++++++++
 src/format/java/e_java.h    |  49 +++
 src/format/java/field.c     | 158 ++++++++++
 src/format/java/field.h     |  40 +++
 src/format/java/java-int.h  | 415 ++++++++++++++++++++++++++
 src/format/java/method.c    | 157 ++++++++++
 src/format/java/method.h    |  40 +++
 src/format/java/pool.c      | 354 ++++++++++++++++++++++
 src/format/java/pool.h      |  42 +++
 22 files changed, 2614 insertions(+), 6 deletions(-)
 create mode 100755 src/common/Makefile.am
 create mode 100755 src/common/endianness.c
 create mode 100755 src/common/endianness.h
 create mode 100755 src/format/java/Makefile.am
 create mode 100644 src/format/java/attribute.c
 create mode 100644 src/format/java/attribute.h
 create mode 100755 src/format/java/e_java.c
 create mode 100755 src/format/java/e_java.h
 create mode 100644 src/format/java/field.c
 create mode 100644 src/format/java/field.h
 create mode 100755 src/format/java/java-int.h
 create mode 100644 src/format/java/method.c
 create mode 100644 src/format/java/method.h
 create mode 100755 src/format/java/pool.c
 create mode 100755 src/format/java/pool.h

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 */
-- 
cgit v0.11.2-87-g4458