summaryrefslogtreecommitdiff
path: root/src/format
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2015-10-01 10:04:22 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2015-10-01 10:04:22 (GMT)
commit9aa5b354e83825e2d9843aea742aa62221a2130b (patch)
treee4a352a51ea5dd60fb385cab961ca06606c9e743 /src/format
parent32f7a1126f8ac5a602f60a29de18eb7c5683dcc2 (diff)
Decoded mangled names in a way suitable for the DEX format.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@580 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
Diffstat (limited to 'src/format')
-rw-r--r--src/format/mangling/Makefile.am3
-rw-r--r--src/format/mangling/context-int.h8
-rw-r--r--src/format/mangling/context.c91
-rw-r--r--src/format/mangling/context.h9
-rw-r--r--src/format/mangling/demangler.c43
-rw-r--r--src/format/mangling/demangler.h15
-rw-r--r--src/format/mangling/dex/Makefile.am46
-rw-r--r--src/format/mangling/dex/context.c154
-rw-r--r--src/format/mangling/dex/context.h52
-rw-r--r--src/format/mangling/dex/shorty_gram.y138
-rw-r--r--src/format/mangling/dex/shorty_tok.l28
-rw-r--r--src/format/mangling/dex/type_gram.y149
-rw-r--r--src/format/mangling/dex/type_tok.l37
13 files changed, 719 insertions, 54 deletions
diff --git a/src/format/mangling/Makefile.am b/src/format/mangling/Makefile.am
index 0bb9444..e92deb2 100644
--- a/src/format/mangling/Makefile.am
+++ b/src/format/mangling/Makefile.am
@@ -14,6 +14,7 @@ libformatmangling_la_LDFLAGS =
libformatmangling_la_LIBADD = \
libjavamangling.la \
+ dex/libformatmanglingdex.la \
itanium/libformatmanglingitanium.la
@@ -39,4 +40,4 @@ AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS)
# Automake fait les choses à moitié
CLEANFILES = java_gram.h java_gram.c libjavamangling_la-java_tok.c
-SUBDIRS = itanium
+SUBDIRS = dex itanium
diff --git a/src/format/mangling/context-int.h b/src/format/mangling/context-int.h
index 851dd87..3e5e189 100644
--- a/src/format/mangling/context-int.h
+++ b/src/format/mangling/context-int.h
@@ -29,6 +29,10 @@
+/* Procède au décodage d'une chaîne de caractères. */
+typedef bool (* demangle_fc) (GDemanglingContext *, const char *);
+
+
/* Contexte de décodage (instance) */
struct _GDemanglingContext
{
@@ -36,6 +40,7 @@ struct _GDemanglingContext
union
{
+ GObject *gobj; /* Utile pour le nettoyage ! */
GBinRoutine *routine; /* Routine décodée */
GDataType *type; /* Type décodé */
};
@@ -47,6 +52,9 @@ struct _GDemanglingContextClass
{
GObjectClass parent; /* A laisser en premier */
+ demangle_fc demangle_type; /* Décodage de type */
+ demangle_fc demangle_routine; /* Décodage de routine */
+
};
diff --git a/src/format/mangling/context.c b/src/format/mangling/context.c
index d0235db..706af9f 100644
--- a/src/format/mangling/context.c
+++ b/src/format/mangling/context.c
@@ -34,6 +34,12 @@ static void g_demangling_context_class_init(GDemanglingContextClass *);
/* Initialise une instance de contexte pour décodage. */
static void g_demangling_context_init(GDemanglingContext *);
+/* Supprime toutes les références externes. */
+static void g_demangling_context_dispose(GDemanglingContext *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_demangling_context_finalize(GDemanglingContext *);
+
/* Indique le type défini pour un contexte de décodage. */
@@ -54,6 +60,12 @@ G_DEFINE_TYPE(GDemanglingContext, g_demangling_context, G_TYPE_OBJECT);
static void g_demangling_context_class_init(GDemanglingContextClass *klass)
{
+ GObjectClass *object; /* Autre version de la classe */
+
+ object = G_OBJECT_CLASS(klass);
+
+ object->dispose = (GObjectFinalizeFunc/* ! */)g_demangling_context_dispose;
+ object->finalize = (GObjectFinalizeFunc)g_demangling_context_finalize;
}
@@ -72,7 +84,47 @@ static void g_demangling_context_class_init(GDemanglingContextClass *klass)
static void g_demangling_context_init(GDemanglingContext *context)
{
- context->routine = g_binary_routine_new();
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : demangler = instance d'objet GLib à traiter. *
+* *
+* Description : Supprime toutes les références externes. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_demangling_context_dispose(GDemanglingContext *context)
+{
+ if (context->gobj != NULL)
+ g_object_unref(context->gobj);
+
+ G_OBJECT_CLASS(g_demangling_context_parent_class)->dispose(G_OBJECT(context));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : demangler = instance d'objet GLib à traiter. *
+* *
+* Description : Procède à la libération totale de la mémoire. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_demangling_context_finalize(GDemanglingContext *context)
+{
+ G_OBJECT_CLASS(g_demangling_context_parent_class)->finalize(G_OBJECT(context));
}
@@ -80,18 +132,32 @@ static void g_demangling_context_init(GDemanglingContext *context)
/******************************************************************************
* *
* Paramètres : context = instance à consulter. *
+* desc = chaîne de caractères à décoder. *
* *
-* Description : Fournit la routine créé à l'issue du codage. *
+* Description : Fournit la routine créée à l'issue du codage. *
* *
-* Retour : Instance en place ou NULL en cas d'erreur fatale. *
+* Retour : Bilan de l'opération. *
* *
* Remarques : - *
* *
******************************************************************************/
-GBinRoutine *g_demangling_context_get_decoded_routine(const GDemanglingContext *context)
+GBinRoutine *g_demangling_context_get_decoded_routine(GDemanglingContext *context, const char *desc)
{
- return context->routine;
+ GBinRoutine *result; /* Construction à remonter */
+
+ context->routine = g_binary_routine_new();
+
+ if (G_DEMANGLING_CONTEXT_GET_CLASS(context)->demangle_routine(context, desc))
+ {
+ g_object_ref(context->routine);
+ result = context->routine;
+ }
+
+ else
+ result = NULL;
+
+ return result;
}
@@ -108,8 +174,19 @@ GBinRoutine *g_demangling_context_get_decoded_routine(const GDemanglingContext *
* *
******************************************************************************/
-GDataType *g_demangling_context_get_decoded_type(const GDemanglingContext *context)
+GDataType *g_demangling_context_get_decoded_type(GDemanglingContext *context, const char *desc)
{
- return context->type;
+ GBinRoutine *result; /* Construction à remonter */
+
+ if (G_DEMANGLING_CONTEXT_GET_CLASS(context)->demangle_type(context, desc))
+ {
+ g_object_ref(context->type);
+ result = context->type;
+ }
+
+ else
+ result = NULL;
+
+ return result;
}
diff --git a/src/format/mangling/context.h b/src/format/mangling/context.h
index dcdaba1..e09e064 100644
--- a/src/format/mangling/context.h
+++ b/src/format/mangling/context.h
@@ -35,7 +35,8 @@
#define G_TYPE_DEMANGLING_CONTEXT g_demangling_context_get_type()
#define G_DEMANGLING_CONTEXT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_demangling_context_get_type(), GDemanglingContext))
#define G_IS_DEMANGLING_CONTEXT(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_demangling_context_get_type()))
-#define G_DEMANGLING_CONTEXT_GET_IFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE((inst), g_demangling_context_get_type(), GDemanglingContextIface))
+#define G_DEMANGLING_CONTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_DEMANGLING_CONTEXT, GDemanglingContextClass))
+#define G_IS_DEMANGLING_CONTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_DEMANGLING_CONTEXT))
#define G_DEMANGLING_CONTEXT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_DEMANGLING_CONTEXT, GDemanglingContextClass))
@@ -49,11 +50,11 @@ typedef struct _GDemanglingContextClass GDemanglingContextClass;
/* Indique le type défini pour un contexte de décodage. */
GType g_demangling_context_get_type(void);
-/* Fournit la routine créé à l'issue du codage. */
-GBinRoutine *g_demangling_context_get_decoded_routine(const GDemanglingContext *);
+/* Fournit la routine créée à l'issue du codage. */
+GBinRoutine *g_demangling_context_get_decoded_routine(GDemanglingContext *, const char *);
/* Fournit le type créé à l'issue du codage. */
-GDataType *g_demangling_context_get_decoded_type(const GDemanglingContext *);
+GDataType *g_demangling_context_get_decoded_type(GDemanglingContext *, const char *);
diff --git a/src/format/mangling/demangler.c b/src/format/mangling/demangler.c
index 715b4e8..d103550 100644
--- a/src/format/mangling/demangler.c
+++ b/src/format/mangling/demangler.c
@@ -58,7 +58,7 @@ typedef struct _demangling_properties
/* Liste des décodeurs */
-static demangling_properties demanglers[DGT_COUNT] = {
+static demangling_properties demanglers[/*DGT_COUNT*/] = {
/*
[DGT_ITANIUM] = {
@@ -68,13 +68,14 @@ static demangling_properties demanglers[DGT_COUNT] = {
.demangle_type = (demangle_fc)NULL
},
*/
+ /*
[DGT_JAVA] = {
.can_demangle = (can_be_demangled_fc)NULL,
.create_context = (create_context_fc)g_java_dcontext_new,
.demangle_routine = (demangle_fc)NULL,
.demangle_type = (demangle_fc)demangle_java_type
}
-
+ */
};
@@ -93,6 +94,7 @@ static demangling_properties demanglers[DGT_COUNT] = {
GBinRoutine *try_to_demangle_routine(const char *desc)
{
+#if 0
GBinRoutine *result; /* Construction à remonter */
DemanglerType i; /* Boucle de parcours */
@@ -147,6 +149,9 @@ GBinRoutine *try_to_demangle_routine(const char *desc)
}
return result;
+#endif
+
+ return NULL;
}
@@ -164,24 +169,14 @@ GBinRoutine *try_to_demangle_routine(const char *desc)
* *
******************************************************************************/
-GBinRoutine *demangle_routine(DemanglerType type, const char *desc)
+GBinRoutine *demangle_routine(GType type, const char *desc)
{
GBinRoutine *result; /* Construction à remonter */
GDemanglingContext *context; /* Contexte pour le décodage */
- result = NULL;
- /*
- if (demangler->can_be_demangled(demangler, name))
- result = demangler->demangle_routine(demangler, name);
- */
+ context = g_object_new(type, NULL);
- context = demanglers[type].create_context();
-
- if (demanglers[type].demangle_routine(context, desc))
- {
- result = g_demangling_context_get_decoded_routine(context);
- g_object_ref(result);
- }
+ result = g_demangling_context_get_decoded_routine(context, desc);
g_object_unref(context);
@@ -203,24 +198,14 @@ GBinRoutine *demangle_routine(DemanglerType type, const char *desc)
* *
******************************************************************************/
-GDataType *demangle_type(DemanglerType type, const char *desc)
+GDataType *demangle_type(GType type, const char *desc)
{
- GDataType *result; /* Construction à remonter */
+ GBinRoutine *result; /* Construction à remonter */
GDemanglingContext *context; /* Contexte pour le décodage */
- result = NULL;
- /*
- if (demangler->can_be_demangled(demangler, name))
- result = demangler->demangle_routine(demangler, name);
- */
-
- context = demanglers[type].create_context();
+ context = g_object_new(type, NULL);
- if (demanglers[type].demangle_type(context, desc))
- {
- result = g_demangling_context_get_decoded_type(context);
- g_object_ref(result);
- }
+ result = g_demangling_context_get_decoded_type(context, desc);
g_object_unref(context);
diff --git a/src/format/mangling/demangler.h b/src/format/mangling/demangler.h
index 5f5463f..65b77db 100644
--- a/src/format/mangling/demangler.h
+++ b/src/format/mangling/demangler.h
@@ -29,25 +29,14 @@
-/* Identifiant des décodeurs existants */
-typedef enum _DemanglerType
-{
- //DGT_ITANIUM, /* Gnu V3 */
- DGT_JAVA, /* Java / DEX */
-
- DGT_COUNT
-
-} DemanglerType;
-
-
/* Tente de décoder une chaîne de caractères donnée. */
GBinRoutine *try_to_demangle_routine(const char *);
/* Tente de décoder une chaîne de caractères donnée. */
-GBinRoutine *demangle_routine(DemanglerType, const char *);
+GBinRoutine *demangle_routine(GType, const char *);
/* Tente de décoder une chaîne de caractères donnée. */
-GDataType *demangle_type(DemanglerType, const char *);
+GDataType *demangle_type(GType, const char *);
diff --git a/src/format/mangling/dex/Makefile.am b/src/format/mangling/dex/Makefile.am
new file mode 100644
index 0000000..bdcbf8c
--- /dev/null
+++ b/src/format/mangling/dex/Makefile.am
@@ -0,0 +1,46 @@
+
+BUILT_SOURCES = libformatmanglingdexshorty_la-shorty_gram.h libformatmanglingdextype_la-type_gram.h
+
+AM_YFLAGS = -d
+
+noinst_LTLIBRARIES = libformatmanglingdex.la libformatmanglingdexshorty.la libformatmanglingdextype.la
+
+libformatmanglingdex_la_SOURCES = \
+ context.h context.c
+
+libformatmanglingdex_la_LDFLAGS =
+
+libformatmanglingdex_la_LIBADD = \
+ libformatmanglingdexshorty.la \
+ libformatmanglingdextype.la
+
+
+libformatmanglingdexshorty_la_SOURCES = \
+ shorty_gram.y \
+ shorty_tok.l
+
+libformatmanglingdexshorty_la_YFLAGS = -d -p shorty_ -o y.tab.c
+
+libformatmanglingdexshorty_la_LFLAGS = -P shorty_ -o lex.yy.c
+
+
+libformatmanglingdextype_la_SOURCES = \
+ type_gram.y \
+ type_tok.l
+
+libformatmanglingdextype_la_YFLAGS = -d -p type_ -o y.tab.c
+
+libformatmanglingdextype_la_LFLAGS = -P type_ -o lex.yy.c
+
+
+AM_CPPFLAGS = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS)
+
+AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS)
+
+
+# Automake fait les choses à moitié
+CLEANFILES = \
+ libformatmanglingdexshorty_la-shorty_gram.h libformatmanglingdexshorty_la-shorty_gram.c \
+ libformatmanglingdexshorty_la-shorty_tok.c \
+ libformatmanglingdextype_la-type_gram.h libformatmanglingdextype_la-type_gram.c \
+ libformatmanglingdextype_la-type_tok.c
diff --git a/src/format/mangling/dex/context.c b/src/format/mangling/dex/context.c
new file mode 100644
index 0000000..6fc12d4
--- /dev/null
+++ b/src/format/mangling/dex/context.c
@@ -0,0 +1,154 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * context.c - contextes de décodage DEX
+ *
+ * Copyright (C) 2015 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * 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 "context.h"
+
+
+#include "../context-int.h"
+
+
+
+/* Contexte de décodage DEX (instance) */
+struct _GDexDemangler
+{
+ GDemanglingContext parent; /* A laisser en premier */
+
+};
+
+/* Contexte de décodage DEX (classe) */
+struct _GDexDemanglerClass
+{
+ GDemanglingContextClass parent; /* A laisser en premier */
+
+};
+
+
+/* Initialise la classe des contextes de décodage DEX. */
+static void g_dex_demangler_class_init(GDexDemanglerClass *);
+
+/* Initialise une instance de contexte pour décodage DEX. */
+static void g_dex_demangler_init(GDexDemangler *);
+
+/* Supprime toutes les références externes. */
+static void g_dex_demangler_dispose(GDexDemangler *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_dex_demangler_finalize(GDexDemangler *);
+
+
+/* Procède au décodage d'une chaîne de caractères. */
+extern bool demangle_dex_routine(GDexDemangler *, const char *);
+
+/* Procède au décodage d'une chaîne de caractères. */
+extern bool demangle_dex_type(GDexDemangler *, const char *);
+
+
+
+/* Indique le type défini pour un contexte de décodage DEX. */
+G_DEFINE_TYPE(GDexDemangler, g_dex_demangler, G_TYPE_DEMANGLING_CONTEXT);
+
+
+/******************************************************************************
+* *
+* Paramètres : klass = classe à initialiser. *
+* *
+* Description : Initialise la classe des contextes de décodage DEX. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_dex_demangler_class_init(GDexDemanglerClass *klass)
+{
+ GObjectClass *object; /* Autre version de la classe */
+ GDemanglingContextClass *context; /* Version parente */
+
+ object = G_OBJECT_CLASS(klass);
+
+ object->dispose = (GObjectFinalizeFunc/* ! */)g_dex_demangler_dispose;
+ object->finalize = (GObjectFinalizeFunc)g_dex_demangler_finalize;
+
+ context = G_DEMANGLING_CONTEXT_CLASS(klass);
+
+ context->demangle_type = (demangle_fc)demangle_dex_type;
+ context->demangle_routine = (demangle_fc)demangle_dex_routine;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : demangler = instance à initialiser. *
+* *
+* Description : Initialise une instance de contexte pour décodage DEX. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_dex_demangler_init(GDexDemangler *demangler)
+{
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : demangler = instance d'objet GLib à traiter. *
+* *
+* Description : Supprime toutes les références externes. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_dex_demangler_dispose(GDexDemangler *demangler)
+{
+ G_OBJECT_CLASS(g_dex_demangler_parent_class)->dispose(G_OBJECT(demangler));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : demangler = instance d'objet GLib à traiter. *
+* *
+* Description : Procède à la libération totale de la mémoire. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_dex_demangler_finalize(GDexDemangler *demangler)
+{
+ G_OBJECT_CLASS(g_dex_demangler_parent_class)->finalize(G_OBJECT(demangler));
+
+}
diff --git a/src/format/mangling/dex/context.h b/src/format/mangling/dex/context.h
new file mode 100644
index 0000000..6242b61
--- /dev/null
+++ b/src/format/mangling/dex/context.h
@@ -0,0 +1,52 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * context.h - prototypes internes liés aux contextes de décodage DEX
+ *
+ * Copyright (C) 2015 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * 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_MANGLING_DEX_CONTEXT_H
+#define _FORMAT_MANGLING_DEX_CONTEXT_H
+
+
+#include <glib-object.h>
+
+
+
+#define G_TYPE_DEX_DEMANGLER g_dex_demangler_get_type()
+#define G_DEX_DEMANGLER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_dex_demangler_get_type(), GDexDemangler))
+#define G_IS_DEX_DEMANGLER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_dex_demangler_get_type()))
+#define G_DEX_DEMANGLER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_DEX_DEMANGLER, GDexDemanglerClass))
+#define G_IS_DEX_DEMANGLER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_DEX_DEMANGLER))
+#define G_DEX_DEMANGLER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_DEX_DEMANGLER, GDexDemanglerClass))
+
+
+/* Contexte de décodage DEX (instance) */
+typedef struct _GDexDemangler GDexDemangler;
+
+/* Contexte de décodage DEX (classe) */
+typedef struct _GDexDemanglerClass GDexDemanglerClass;
+
+
+/* Indique le type défini pour un contexte de décodage DEX. */
+GType g_dex_demangler_get_type(void);
+
+
+
+#endif /* _FORMAT_MANGLING_DEX_CONTEXT_H */
diff --git a/src/format/mangling/dex/shorty_gram.y b/src/format/mangling/dex/shorty_gram.y
new file mode 100644
index 0000000..55d849d
--- /dev/null
+++ b/src/format/mangling/dex/shorty_gram.y
@@ -0,0 +1,138 @@
+
+%{
+
+#include <stdbool.h>
+
+
+#include "context.h"
+#include "../context-int.h"
+
+
+
+/* Affiche un message d'erreur concernant l'analyse. */
+static int shorty_error(GDexDemangler *, char *);
+
+/* Procède au décodage d'une chaîne de caractères. */
+bool demangle_dex_routine(GDexDemangler *, const char *);
+
+
+%}
+
+
+%code requires {
+
+#include "../../../analysis/types/basic.h"
+#include "../../../analysis/types/cse.h"
+
+}
+
+%union {
+
+ GDataType *type; /* Type reconstruit */
+
+}
+
+
+%parse-param { GDexDemangler *demangler }
+
+%token V Z B S C I J F D L
+
+%type <type> shorty_return_type shorty_field_type
+
+
+%{
+
+/* Déclarations issues de l'analyseur syntaxique... */
+
+typedef struct yy_buffer_state *YY_BUFFER_STATE;
+
+extern YY_BUFFER_STATE shorty__scan_string(const char *);
+extern void shorty__delete_buffer(YY_BUFFER_STATE);
+extern int shorty_lex(void);
+
+%}
+
+
+%%
+
+
+shorty_descriptor:
+ shorty_return_type shorty_field_type_list {
+ GBinRoutine *routine;
+ routine = G_DEMANGLING_CONTEXT(demangler)->routine;
+ g_binary_routine_set_return_type(routine, $1);
+ }
+
+shorty_field_type_list:
+ /* empty */
+ | shorty_field_type shorty_field_type_list {
+ GBinRoutine *routine;
+ GBinVariable *var;
+ routine = G_DEMANGLING_CONTEXT(demangler)->routine;
+ var = g_binary_variable_new($1);
+ g_binary_routine_add_arg(routine, var);
+ }
+
+shorty_return_type:
+ V { $$ = g_basic_type_new(BTP_VOID); }
+ | shorty_field_type { $$ = $1; }
+
+shorty_field_type:
+ Z { $$ = g_basic_type_new(BTP_BOOL); }
+ | B { $$ = g_basic_type_new(BTP_UCHAR); }
+ | S { $$ = g_basic_type_new(BTP_SHORT); }
+ | C { $$ = g_basic_type_new(BTP_CHAR); }
+ | I { $$ = g_basic_type_new(BTP_INT); }
+ | J { $$ = g_basic_type_new(BTP_LONG); }
+ | F { $$ = g_basic_type_new(BTP_FLOAT); }
+ | D { $$ = g_basic_type_new(BTP_DOUBLE); }
+ | L { $$ = g_class_enum_type_new(CET_CLASS, ""); }
+
+
+%%
+
+
+/******************************************************************************
+* *
+* Paramètres : demangler = contexte associé à la procédure de décodage. *
+* msg = indications humaines sur l'événement. *
+* *
+* Description : Affiche un message d'erreur concernant l'analyse. *
+* *
+* Retour : Valeur historique, ignorée. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+static int shorty_error(GDexDemangler *demangler, char *msg)
+{
+ return -1;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : demangler = contexte de décodage à utiliser. *
+* desc = chaîne de caractères à décoder. *
+* *
+* Description : Procède au décodage d'une chaîne de caractères. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool demangle_dex_routine(GDexDemangler *demangler, const char *desc)
+{
+ YY_BUFFER_STATE buffer; /* Tampon pour bison */
+ int ret; /* Bilan de l'appel */
+
+ buffer = shorty__scan_string(desc);
+ ret = yyparse(demangler);
+ shorty__delete_buffer(buffer);
+
+ return (ret == 0);
+
+}
diff --git a/src/format/mangling/dex/shorty_tok.l b/src/format/mangling/dex/shorty_tok.l
new file mode 100644
index 0000000..92c264a
--- /dev/null
+++ b/src/format/mangling/dex/shorty_tok.l
@@ -0,0 +1,28 @@
+
+%{
+
+#include "context.h"
+#include "libformatmanglingdexshorty_la-shorty_gram.h"
+
+%}
+
+
+%option noyywrap
+%option yylineno
+%option nounput
+%option noinput
+
+%%
+
+"V" { return V; }
+"Z" { return Z; }
+"B" { return B; }
+"S" { return S; }
+"C" { return C; }
+"I" { return I; }
+"J" { return J; }
+"F" { return F; }
+"D" { return D; }
+"L" { return L; }
+
+%%
diff --git a/src/format/mangling/dex/type_gram.y b/src/format/mangling/dex/type_gram.y
new file mode 100644
index 0000000..1176bd2
--- /dev/null
+++ b/src/format/mangling/dex/type_gram.y
@@ -0,0 +1,149 @@
+
+%{
+
+#include <stdbool.h>
+
+
+#include "context.h"
+#include "../context-int.h"
+
+
+
+/* Affiche un message d'erreur concernant l'analyse. */
+static int type_error(GDexDemangler *, char *);
+
+/* Procède au décodage d'une chaîne de caractères. */
+bool demangle_dex_type(GDexDemangler *, const char *);
+
+
+%}
+
+
+%code requires {
+
+#include "../../../analysis/types/basic.h"
+#include "../../../analysis/types/cse.h"
+
+}
+
+%union {
+
+ GDataType *type; /* Type reconstruit */
+ size_t adeep; /* Dimension d'un tableau */
+ char *text; /* Chaîne de caractères */
+
+}
+
+
+%parse-param { GDexDemangler *demangler }
+
+%token V Z B S C I J F D
+%token ARRAY
+%token L SEMICOLON
+%token SLASH DOLLAR
+%token TEXT
+
+%type <type> type_descriptor field_type_descriptor non_array_field_type_descriptor full_class_name
+
+%type <text> TEXT
+
+
+%{
+
+/* Déclarations issues de l'analyseur syntaxique... */
+
+typedef struct yy_buffer_state *YY_BUFFER_STATE;
+
+extern YY_BUFFER_STATE type__scan_string(const char *);
+extern void type__delete_buffer(YY_BUFFER_STATE);
+extern int type_lex(void);
+
+%}
+
+
+%%
+
+
+input:
+ type_descriptor { G_DEMANGLING_CONTEXT(demangler)->type = $1; }
+
+type_descriptor:
+ V { $$ = g_basic_type_new(BTP_VOID); }
+ | field_type_descriptor { $$ = $1; }
+
+field_type_descriptor:
+ non_array_field_type_descriptor { $$ = $1; }
+ | ARRAY non_array_field_type_descriptor { $$ = $2; }
+
+non_array_field_type_descriptor:
+ Z { $$ = g_basic_type_new(BTP_BOOL); }
+ | B { $$ = g_basic_type_new(BTP_UCHAR); }
+ | S { $$ = g_basic_type_new(BTP_SHORT); }
+ | C { $$ = g_basic_type_new(BTP_CHAR); }
+ | I { $$ = g_basic_type_new(BTP_INT); }
+ | J { $$ = g_basic_type_new(BTP_LONG); }
+ | F { $$ = g_basic_type_new(BTP_FLOAT); }
+ | D { $$ = g_basic_type_new(BTP_DOUBLE); }
+ | L full_class_name SEMICOLON { $$ = $2; }
+
+full_class_name:
+ TEXT { $$ = g_class_enum_type_new(CET_CLASS, $1); }
+ | full_class_name SLASH TEXT {
+ $$ = g_class_enum_type_new(CET_CLASS, $3);
+ g_data_type_set_namespace($$, $1);
+ g_object_unref($1);
+ }
+ | full_class_name DOLLAR TEXT {
+ $$ = g_class_enum_type_new(CET_CLASS, $3);
+ g_data_type_set_namespace($$, $1);
+ g_object_unref($1);
+ }
+
+
+%%
+
+
+/******************************************************************************
+* *
+* Paramètres : demangler = contexte associé à la procédure de décodage. *
+* msg = indications humaines sur l'événement. *
+* *
+* Description : Affiche un message d'erreur concernant l'analyse. *
+* *
+* Retour : Valeur historique, ignorée. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+static int type_error(GDexDemangler *demangler, char *msg)
+{
+ return -1;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : demangler = contexte de décodage à utiliser. *
+* desc = chaîne de caractères à décoder. *
+* *
+* Description : Procède au décodage d'une chaîne de caractères. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool demangle_dex_type(GDexDemangler *demangler, const char *desc)
+{
+ YY_BUFFER_STATE buffer; /* Tampon pour bison */
+ int ret; /* Bilan de l'appel */
+
+ buffer = type__scan_string(desc);
+ ret = yyparse(demangler);
+ type__delete_buffer(buffer);
+
+ return (ret == 0);
+
+}
diff --git a/src/format/mangling/dex/type_tok.l b/src/format/mangling/dex/type_tok.l
new file mode 100644
index 0000000..7b8a8d3
--- /dev/null
+++ b/src/format/mangling/dex/type_tok.l
@@ -0,0 +1,37 @@
+
+%{
+
+#include "context.h"
+#include "libformatmanglingdextype_la-type_gram.h"
+
+%}
+
+
+%option noyywrap
+%option yylineno
+%option nounput
+%option noinput
+
+%x string
+
+%%
+
+"V" { return V; }
+"Z" { return Z; }
+"B" { return B; }
+"S" { return S; }
+"C" { return C; }
+"I" { return I; }
+"J" { return J; }
+"F" { return F; }
+"D" { return D; }
+"L" { BEGIN(string); return L; }
+"["* { type_lval.adeep = strlen(yytext); return ARRAY; }
+<string>"/" { return SLASH; }
+<string>"$" { return DOLLAR; }
+<string>";" { BEGIN(INITIAL); return SEMICOLON; }
+
+<string>[A-Za-z0-9_-]* { type_lval.text = yytext; return TEXT; }
+
+
+%%