summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2020-01-30 23:23:16 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2020-01-30 23:23:16 (GMT)
commit62f178cc3dcc889d56ba6d94f6fc8bba7b503c1a (patch)
tree9d0a95ea433a42351ae7aa783356aa2e30a39f34
parentc1ca03be00a4e975f89d30edfb72b57fb5612282 (diff)
Compressed some architecture instruction properties.
-rw-r--r--plugins/arm/v7/instruction.c2
-rw-r--r--plugins/dalvik/pseudo/fill.c2
-rw-r--r--plugins/dalvik/pseudo/switch.c7
-rw-r--r--plugins/dalvik/v35/instruction.c8
-rw-r--r--plugins/pychrysalide/arch/instruction.c4
-rw-r--r--src/arch/instruction-int.h63
-rw-r--r--src/arch/instruction.c108
-rw-r--r--src/arch/instruction.h3
-rw-r--r--src/common/cpp.h7
-rw-r--r--src/glibext/Makefile.am1
-rw-r--r--src/glibext/objhole.h71
11 files changed, 253 insertions, 23 deletions
diff --git a/plugins/arm/v7/instruction.c b/plugins/arm/v7/instruction.c
index 97adddd..1c94887 100644
--- a/plugins/arm/v7/instruction.c
+++ b/plugins/arm/v7/instruction.c
@@ -210,7 +210,7 @@ GArchInstruction *g_armv7_instruction_new(itid_t uid, ARMv7Syntax sid)
result = g_object_new(G_TYPE_ARMV7_INSTRUCTION, NULL);
- G_ARCH_INSTRUCTION(result)->uid = uid;
+ g_arch_instruction_set_unique_id(G_ARCH_INSTRUCTION(result), uid);
result->sid = sid;
diff --git a/plugins/dalvik/pseudo/fill.c b/plugins/dalvik/pseudo/fill.c
index 12382f7..cc8a412 100644
--- a/plugins/dalvik/pseudo/fill.c
+++ b/plugins/dalvik/pseudo/fill.c
@@ -183,7 +183,7 @@ GArchInstruction *g_dalvik_fill_instr_new(uint16_t ident, GDalvikContext *ctx, c
result = g_object_new(G_TYPE_DALVIK_FILL_INSTR, NULL);
- G_ARCH_INSTRUCTION(result)->uid = DPO_FILL_ARRAY_DATA;
+ g_arch_instruction_set_unique_id(G_ARCH_INSTRUCTION(result), DPO_FILL_ARRAY_DATA);
if (!g_binary_content_read_u16(content, pos, SRE_LITTLE, &result->item_width))
goto gdfin_bad;
diff --git a/plugins/dalvik/pseudo/switch.c b/plugins/dalvik/pseudo/switch.c
index ea3aa90..f09fe59 100644
--- a/plugins/dalvik/pseudo/switch.c
+++ b/plugins/dalvik/pseudo/switch.c
@@ -193,7 +193,7 @@ GArchInstruction *g_dalvik_switch_instr_new(uint16_t ident, GDalvikContext *ctx,
result = g_object_new(G_TYPE_DALVIK_SWITCH_INSTR, NULL);
- G_ARCH_INSTRUCTION(result)->uid = ident;
+ g_arch_instruction_set_unique_id(G_ARCH_INSTRUCTION(result), ident);
if (!g_binary_content_read_u16(content, pos, SRE_LITTLE, &result->switch_size))
goto gdsin_bad;
@@ -237,6 +237,7 @@ GArchInstruction *g_dalvik_switch_instr_new(uint16_t ident, GDalvikContext *ctx,
static bool g_dalvik_switch_decode_data(GDalvikSwitchInstr *instr, const GBinContent *content, const vmpa2t *pos)
{
vmpa2t iter; /* Position modifiable */
+ itid_t uid; /* Identifiant unique */
int32_t first_key; /* Première clef */
uint16_t i; /* Boucle de parcours */
@@ -245,7 +246,9 @@ static bool g_dalvik_switch_decode_data(GDalvikSwitchInstr *instr, const GBinCon
copy_vmpa(&iter, pos);
- if (G_ARCH_INSTRUCTION(instr)->uid == DPO_PACKED_SWITCH)
+ uid = g_arch_instruction_get_unique_id(G_ARCH_INSTRUCTION(instr));
+
+ if (uid == DPO_PACKED_SWITCH)
{
if (!g_binary_content_read_s32(content, &iter, SRE_LITTLE, &first_key))
goto gdsdd_bad;
diff --git a/plugins/dalvik/v35/instruction.c b/plugins/dalvik/v35/instruction.c
index 28cb0dd..773ec7a 100644
--- a/plugins/dalvik/v35/instruction.c
+++ b/plugins/dalvik/v35/instruction.c
@@ -185,7 +185,7 @@ GArchInstruction *g_dalvik35_instruction_new(itid_t uid)
result = g_object_new(G_TYPE_DALVIK35_INSTRUCTION, NULL);
- G_ARCH_INSTRUCTION(result)->uid = uid;
+ g_arch_instruction_set_unique_id(G_ARCH_INSTRUCTION(result), uid);
return G_ARCH_INSTRUCTION(result);
@@ -232,7 +232,7 @@ static const char *g_dalvik35_instruction_get_keyword(const GDalvik35Instruction
const char *result; /* Désignation à retourner */
itid_t uid; /* Accès simplifié */
- uid = G_ARCH_INSTRUCTION(instr)->uid;
+ uid = g_arch_instruction_get_unique_id(G_ARCH_INSTRUCTION(instr));
assert(uid < DOP35_COUNT);
@@ -272,7 +272,7 @@ static void g_dalvik35_instruction_call_hook(GDalvik35Instruction *instr, InstrP
base = G_ARCH_INSTRUCTION(instr);
- uid = base->uid;
+ uid = g_arch_instruction_get_unique_id(base);
assert(uid < DOP35_COUNT);
@@ -301,7 +301,7 @@ static const char *g_dalvik35_instruction_get_description(const GDalvik35Instruc
const char *result; /* Description à retourner */
itid_t uid; /* Accès simplifié */
- uid = G_ARCH_INSTRUCTION(instr)->uid;
+ uid = g_arch_instruction_get_unique_id(G_ARCH_INSTRUCTION(instr));
assert(uid < DOP35_COUNT);
diff --git a/plugins/pychrysalide/arch/instruction.c b/plugins/pychrysalide/arch/instruction.c
index 1be3edb..757949a 100644
--- a/plugins/pychrysalide/arch/instruction.c
+++ b/plugins/pychrysalide/arch/instruction.c
@@ -407,7 +407,7 @@ static int py_arch_instruction_init(PyObject *self, PyObject *args, PyObject *kw
instr->cached_keyword = strdup(keyword);
- G_ARCH_INSTRUCTION(instr)->uid = uid;
+ g_arch_instruction_set_unique_id(G_ARCH_INSTRUCTION(instr), uid);
return 0;
@@ -723,7 +723,7 @@ static PyObject *py_arch_instruction_get_destinations(PyObject *self, void *unus
* *
* Description : Fournit l'identifiant unique pour un ensemble d'instructions.*
* *
-* Retour : Identifiant unique par type d'instruction et architecture. *
+* Retour : Identifiant unique par type d'instruction. *
* *
* Remarques : - *
* *
diff --git a/src/arch/instruction-int.h b/src/arch/instruction-int.h
index af897b0..fcb5453 100644
--- a/src/arch/instruction-int.h
+++ b/src/arch/instruction-int.h
@@ -27,6 +27,7 @@
#include "instruction.h"
#include "../common/array.h"
+#include "../glibext/objhole.h"
@@ -58,6 +59,38 @@ typedef GBufferLine * (* print_instruction_fc) (const GArchInstruction *, GBuffe
typedef void (* get_instruction_rw_regs_fc) (const GArchInstruction *, GArchRegister ***, size_t *, GArchRegister ***, size_t *);
+/* Informations glissées dans la structure GObject de GArchInstruction */
+typedef union _instr_obj_extra
+{
+ struct
+ {
+ itid_t uid; /* Identifiant unique du type */
+
+ ArchInstrFlag flags; /* Informations complémentaires*/
+
+ };
+
+ gint lock; /* Gestion d'accès aux fanions */
+
+} instr_obj_extra;
+
+/**
+ * Choix du bit de verrou pour le champ "lock".
+ */
+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+
+# define INSTR_EXTRA_LOCK_BIT 31
+
+#elif __BYTE_ORDER == __BIG_ENDIAN
+
+# define INSTR_EXTRA_LOCK_BIT 0
+
+#else
+
+# error "Unknown byte order"
+
+#endif
/* Définition générique d'une instruction d'architecture (instance) */
struct _GArchInstruction
@@ -93,12 +126,38 @@ struct _GArchInstruction
flat_array_t *from; /* Origines des références */
flat_array_t *to; /* Instructions visées */
- itid_t uid; /* Identifiant unique du type */
+#if __SIZEOF_INT__ == __SIZEOF_LONG__
- ArchInstrFlag flags; /* Informations complémentaires*/
+ /**
+ * L'inclusion des informations suivantes dépend de l'architecture.
+ *
+ * Si la structure GObject possède un trou, on remplit de préférence
+ * ce dernier.
+ */
+
+ instr_obj_extra extra; /* Externalisation embarquée */
+
+#endif
};
+/**
+ * Accès aux informations éventuellement déportées.
+ */
+
+#if __SIZEOF_INT__ == __SIZEOF_LONG__
+
+# define INIT_ARCH_INSTR_EXTRA(ins) ins->extra.lock = 0
+
+# define GET_ARCH_INSTR_EXTRA(ins) &ins->extra
+
+#else
+
+# define INIT_ARCH_INSTR_EXTRA(ins) INIT_GOBJECT_EXTRA(G_OBJECT(ins))
+
+# define GET_ARCH_INSTR_EXTRA(ins) GET_GOBJECT_EXTRA(G_OBJECT(ins), instr_obj_extra)
+
+#endif
/* Définition générique d'une instruction d'architecture (classe) */
struct _GArchInstructionClass
diff --git a/src/arch/instruction.c b/src/arch/instruction.c
index f571330..d3ac97e 100644
--- a/src/arch/instruction.c
+++ b/src/arch/instruction.c
@@ -139,6 +139,8 @@ static void g_arch_instruction_class_init(GArchInstructionClass *klass)
static void g_arch_instruction_init(GArchInstruction *instr)
{
+ INIT_ARCH_INSTR_EXTRA(instr);
+
instr->operands = NULL;
instr->from = NULL;
@@ -278,9 +280,20 @@ const char *g_arch_instruction_get_encoding(const GArchInstruction *instr)
bool g_arch_instruction_set_flag(GArchInstruction *instr, ArchInstrFlag flag)
{
- instr->flags |= flag;
+ bool result; /* Bilan à retourner */
+ instr_obj_extra *extra; /* Données insérées à modifier */
+
+ extra = GET_ARCH_INSTR_EXTRA(instr);
+
+ g_bit_lock(&extra->lock, INSTR_EXTRA_LOCK_BIT);
+
+ extra->flags |= flag;
+
+ result = true;
- return true;
+ g_bit_unlock(&extra->lock, INSTR_EXTRA_LOCK_BIT);
+
+ return result;
}
@@ -301,8 +314,15 @@ bool g_arch_instruction_set_flag(GArchInstruction *instr, ArchInstrFlag flag)
bool g_arch_instruction_has_flag(const GArchInstruction *instr, ArchInstrFlag flag)
{
bool result; /* Bilan à retourner */
+ instr_obj_extra *extra; /* Données insérées à consulter*/
+
+ extra = GET_ARCH_INSTR_EXTRA(instr);
+
+ g_bit_lock(&extra->lock, INSTR_EXTRA_LOCK_BIT);
- result = (instr->flags & flag);
+ result = (extra->flags & flag);
+
+ g_bit_unlock(&extra->lock, INSTR_EXTRA_LOCK_BIT);
return result;
@@ -323,7 +343,46 @@ bool g_arch_instruction_has_flag(const GArchInstruction *instr, ArchInstrFlag fl
ArchInstrFlag g_arch_instruction_get_flags(const GArchInstruction *instr)
{
- return instr->flags;
+ ArchInstrFlag result; /* Fanions à retourner */
+ instr_obj_extra *extra; /* Données insérées à consulter*/
+
+ extra = GET_ARCH_INSTR_EXTRA(instr);
+
+ g_bit_lock(&extra->lock, INSTR_EXTRA_LOCK_BIT);
+
+ result = extra->flags;
+
+ g_bit_unlock(&extra->lock, INSTR_EXTRA_LOCK_BIT);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : instr = instruction quelconque à consulter. *
+* uid = identifiant unique par type d'instruction. *
+* *
+* Description : Définit l'identifiant unique pour un ensemble d'instructions.*
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_arch_instruction_set_unique_id(GArchInstruction *instr, itid_t uid)
+{
+ instr_obj_extra *extra; /* Données insérées à modifier */
+
+ extra = GET_ARCH_INSTR_EXTRA(instr);
+
+ g_bit_lock(&extra->lock, INSTR_EXTRA_LOCK_BIT);
+
+ extra->uid = uid;
+
+ g_bit_unlock(&extra->lock, INSTR_EXTRA_LOCK_BIT);
}
@@ -343,8 +402,15 @@ ArchInstrFlag g_arch_instruction_get_flags(const GArchInstruction *instr)
itid_t g_arch_instruction_get_unique_id(const GArchInstruction *instr)
{
itid_t result; /* Numéro à retourner */
+ instr_obj_extra *extra; /* Données insérées à consulter*/
+
+ extra = GET_ARCH_INSTR_EXTRA(instr);
- result = instr->uid;
+ g_bit_lock(&extra->lock, INSTR_EXTRA_LOCK_BIT);
+
+ result = extra->uid;
+
+ g_bit_unlock(&extra->lock, INSTR_EXTRA_LOCK_BIT);
return result;
@@ -1409,6 +1475,7 @@ static bool g_arch_instruction_unserialize(GArchInstruction *instr, GAsmStorage
GArchOperand *op; /* Opérande à traiter */
instr_link_t link; /* Lien vers une instruction */
packed_buffer ins_pbuf; /* Tampon des données à écrire */
+ instr_obj_extra *extra; /* Données insérées à consulter*/
result = unpack_mrange(&instr->range, pbuf);
@@ -1489,10 +1556,19 @@ static bool g_arch_instruction_unserialize(GArchInstruction *instr, GAsmStorage
}
if (result)
- result = extract_packed_buffer(pbuf, &instr->uid, sizeof(itid_t), true);
+ {
+ extra = GET_ARCH_INSTR_EXTRA(instr);
- if (result)
- result = extract_packed_buffer(pbuf, &instr->flags, sizeof(ArchInstrFlag), true);
+ g_bit_lock(&extra->lock, INSTR_EXTRA_LOCK_BIT);
+
+ result = extract_packed_buffer(pbuf, &extra->uid, sizeof(itid_t), true);
+
+ if (result)
+ result = extract_packed_buffer(pbuf, &extra->flags, sizeof(ArchInstrFlag), true);
+
+ g_bit_unlock(&extra->lock, INSTR_EXTRA_LOCK_BIT);
+
+ }
return result;
@@ -1561,6 +1637,7 @@ static bool g_arch_instruction_serialize(GArchInstruction *instr, GAsmStorage *s
off64_t pos; /* Position dans le flux */
size_t kept; /* Nombre de liens conservés */
const instr_link_t *link; /* Lien vers une instruction */
+ instr_obj_extra *extra; /* Données insérées à consulter*/
result = pack_mrange(&instr->range, pbuf);
@@ -1661,10 +1738,19 @@ static bool g_arch_instruction_serialize(GArchInstruction *instr, GAsmStorage *s
}
if (result)
- result = extend_packed_buffer(pbuf, &instr->uid, sizeof(itid_t), true);
+ {
+ extra = GET_ARCH_INSTR_EXTRA(instr);
- if (result)
- result = extend_packed_buffer(pbuf, &instr->flags, sizeof(ArchInstrFlag), true);
+ g_bit_lock(&extra->lock, INSTR_EXTRA_LOCK_BIT);
+
+ result = extend_packed_buffer(pbuf, &extra->uid, sizeof(itid_t), true);
+
+ if (result)
+ result = extend_packed_buffer(pbuf, &extra->flags, sizeof(ArchInstrFlag), true);
+
+ g_bit_unlock(&extra->lock, INSTR_EXTRA_LOCK_BIT);
+
+ }
return result;
diff --git a/src/arch/instruction.h b/src/arch/instruction.h
index af6b03a..6c04acb 100644
--- a/src/arch/instruction.h
+++ b/src/arch/instruction.h
@@ -93,6 +93,9 @@ bool g_arch_instruction_has_flag(const GArchInstruction *, ArchInstrFlag);
/* Fournit les informations complémentaires d'une instruction. */
ArchInstrFlag g_arch_instruction_get_flags(const GArchInstruction *);
+/* Définit l'identifiant unique pour un ensemble d'instructions. */
+void g_arch_instruction_set_unique_id(GArchInstruction *, itid_t);
+
/* Fournit l'identifiant unique pour un ensemble d'instructions. */
itid_t g_arch_instruction_get_unique_id(const GArchInstruction *);
diff --git a/src/common/cpp.h b/src/common/cpp.h
index dc0c208..2305b29 100644
--- a/src/common/cpp.h
+++ b/src/common/cpp.h
@@ -47,5 +47,12 @@
#define SIZE_T_MAXLEN strlen(XSTR(LONG_MAX))
+/**
+ * Emprunt au noyau Linux (cf. include/linux/bug.h) pour les vérifications à la compilation.
+ */
+
+#define BUILD_BUG_ON(cond) (((void)sizeof(char[1 - 2 * !!(cond)])))
+
+
#endif /* _COMMON_CPP_H */
diff --git a/src/glibext/Makefile.am b/src/glibext/Makefile.am
index 127f60c..af4f876 100644
--- a/src/glibext/Makefile.am
+++ b/src/glibext/Makefile.am
@@ -25,6 +25,7 @@ libglibext_la_SOURCES = \
linegen-int.h \
linegen.h linegen.c \
linesegment.h linesegment.c \
+ objhole.h \
proto.h \
seq.h seq.c \
signal.h signal.c
diff --git a/src/glibext/objhole.h b/src/glibext/objhole.h
new file mode 100644
index 0000000..184e599
--- /dev/null
+++ b/src/glibext/objhole.h
@@ -0,0 +1,71 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * objhole.h - prototypes pour l'utilisation d'un espace inutilisé dans la structure GObject
+ *
+ * Copyright (C) 2019 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Chrysalide is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Chrysalide. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _GLIBEXT_OBJHOLE_H
+#define _GLIBEXT_OBJHOLE_H
+
+
+#include <glib-object.h>
+
+
+#include "../common/cpp.h"
+
+
+
+/**
+ * Une structure GObject a la définition suivante :
+ *
+ * struct _GObject
+ * {
+ * GTypeInstance g_type_instance;
+ * volatile guint ref_count;
+ * GData *qdata;
+ * };
+ *
+ * L'espace entre les deux derniers champs est exploité ici.
+ */
+
+
+#define INIT_GOBJECT_EXTRA(obj) \
+ do \
+ { \
+ guint *___space; \
+ ___space = (((guint *)&obj->ref_count) + 1); \
+ BUILD_BUG_ON((___space + 1) == (guint *)&obj->qdata); \
+ *___space = 0; \
+ } \
+ while (0)
+
+
+#define GET_GOBJECT_EXTRA(obj, tp) \
+ ({ \
+ BUILD_BUG_ON(sizeof(tp) > sizeof(guint)); \
+ tp *___result; \
+ ___result = (tp *)(((guint *)&obj->ref_count) + 1); \
+ BUILD_BUG_ON((___result + 1) == (tp *)&obj->qdata); \
+ ___result; \
+ })
+
+
+
+#endif /* _GLIBEXT_OBJHOLE_H */