summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2019-08-13 22:04:53 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2019-08-13 22:04:53 (GMT)
commit7cb4e815b691d05d8c0aea9decf56b9dbc41dfa6 (patch)
treeade598a747daa2e061f4903a81ac74e52e0c38b1
parentdd2853ea8cf97b773ba362da50d06d4abc608a09 (diff)
Used a Python enumeration for the binary symbol status.
-rw-r--r--plugins/pychrysalide/format/Makefile.am1
-rw-r--r--plugins/pychrysalide/format/constants.c71
-rw-r--r--plugins/pychrysalide/format/constants.h39
-rw-r--r--plugins/pychrysalide/format/symbol.c17
-rw-r--r--plugins/pychrysalide/helpers.c199
-rw-r--r--plugins/pychrysalide/helpers.h29
-rw-r--r--tests/format/symbol.py26
7 files changed, 377 insertions, 5 deletions
diff --git a/plugins/pychrysalide/format/Makefile.am b/plugins/pychrysalide/format/Makefile.am
index 6d50da7..24890ec 100644
--- a/plugins/pychrysalide/format/Makefile.am
+++ b/plugins/pychrysalide/format/Makefile.am
@@ -2,6 +2,7 @@
noinst_LTLIBRARIES = libpychrysaformat.la
libpychrysaformat_la_SOURCES = \
+ constants.h constants.c \
executable.h executable.c \
flat.h flat.c \
format.h format.c \
diff --git a/plugins/pychrysalide/format/constants.c b/plugins/pychrysalide/format/constants.c
new file mode 100644
index 0000000..9e63fdd
--- /dev/null
+++ b/plugins/pychrysalide/format/constants.c
@@ -0,0 +1,71 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * constants.c - équivalent Python partiel du fichier "plugins/dex/dex_def.h"
+ *
+ * Copyright (C) 2018 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+#include "constants.h"
+
+
+#include <format/symbol.h>
+
+
+#include "../helpers.h"
+
+
+
+/******************************************************************************
+* *
+* Paramètres : type = type dont le dictionnaire est à compléter. *
+* *
+* Description : Définit les constantes pour le format Dex. *
+* *
+* Retour : true en cas de succès de l'opération, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool define_binary_symbol_constants(PyTypeObject *type)
+{
+ bool result; /* Bilan à retourner */
+ PyObject *values; /* Groupe de valeurs à établir */
+
+ values = PyDict_New();
+
+ result = add_const_to_group(values, "INTERNAL", SSS_INTERNAL);
+ if (result) result = add_const_to_group(values, "EXPORTED", SSS_EXPORTED);
+ if (result) result = add_const_to_group(values, "IMPORTED", SSS_IMPORTED);
+ if (result) result = add_const_to_group(values, "DYNAMIC", SSS_DYNAMIC);
+
+ if (!result)
+ {
+ Py_DECREF(values);
+ goto exit;
+ }
+
+ result = attach_constants_group(type, false, "SymbolStatus", values, "Status of a symbol visibility.");
+
+ exit:
+
+ return result;
+
+}
diff --git a/plugins/pychrysalide/format/constants.h b/plugins/pychrysalide/format/constants.h
new file mode 100644
index 0000000..6515f35
--- /dev/null
+++ b/plugins/pychrysalide/format/constants.h
@@ -0,0 +1,39 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * constants.h - prototypes pour l'ajout des constantes liées aux formats
+ *
+ * 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+#ifndef _PLUGINS_PYCHRYSALIDE_FORMAT_CONSTANTS_H
+#define _PLUGINS_PYCHRYSALIDE_FORMAT_CONSTANTS_H
+
+
+#include <Python.h>
+#include <stdbool.h>
+
+
+
+/* Définit les constantes pour les symboles binaires. */
+bool define_binary_symbol_constants(PyTypeObject *);
+
+
+
+#endif /* _PLUGINS_PYCHRYSALIDE_FORMAT_CONSTANTS_H */
diff --git a/plugins/pychrysalide/format/symbol.c b/plugins/pychrysalide/format/symbol.c
index 3295e8c..af03473 100644
--- a/plugins/pychrysalide/format/symbol.c
+++ b/plugins/pychrysalide/format/symbol.c
@@ -36,6 +36,7 @@
#include <format/symbol.h>
+#include "constants.h"
#include "../access.h"
#include "../helpers.h"
#include "../analysis/routine.h"
@@ -349,10 +350,16 @@ static PyObject *py_binary_symbol_get_status(PyObject *self, void *closure)
GBinSymbol *symbol; /* Elément à consulter */
SymbolStatus status; /* Visibilité du symbole fourni*/
+#define BINARY_SYMBOL_STATUS_ATTRIB PYTHON_GET_DEF_FULL \
+( \
+ status, py_binary_symbol, \
+ "Status of the symbol's visibility." \
+)
+
symbol = G_BIN_SYMBOL(pygobject_get(self));
status = g_binary_symbol_get_status(symbol);
- result = PyLong_FromLong(status);
+ result = cast_with_constants_group(get_python_binary_symbol_type(), "SymbolStatus", status);
return result;
@@ -432,10 +439,7 @@ PyTypeObject *get_python_binary_symbol_type(void)
"range", py_binary_symbol_get_range, py_binary_symbol_set_range,
"Range covered by the symbol.", NULL
},
- {
- "status", py_binary_symbol_get_status, NULL,
- "Status of the symbol's visibility.", NULL
- },
+ BINARY_SYMBOL_STATUS_ATTRIB,
{ NULL }
};
@@ -498,6 +502,9 @@ bool ensure_python_binary_symbol_is_registered(void)
if (!py_binary_symbol_define_constants(type))
return false;
+ if (!define_binary_symbol_constants(type))
+ return false;
+
}
return true;
diff --git a/plugins/pychrysalide/helpers.c b/plugins/pychrysalide/helpers.c
index 6ffb4fe..6e13d3c 100644
--- a/plugins/pychrysalide/helpers.c
+++ b/plugins/pychrysalide/helpers.c
@@ -939,3 +939,202 @@ bool register_class_for_dynamic_pygobject(GType gtype, PyTypeObject *type, PyTyp
return result;
}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* TRANSFERT DES VALEURS CONSTANTES */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+* *
+* Paramètres : owner = type dont le dictionnaire est à compléter. *
+* flags = indique le type d'énumération ciblée. *
+* name = désignation humaine du groupe à constituer. *
+* values = noms et valeurs associées. *
+* doc = documentation à associer au groupe. *
+* *
+* Description : Officialise un groupe de constantes avec sémentique. *
+* *
+* Retour : true en cas de succès de l'opération, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool attach_constants_group(PyTypeObject *owner, bool flags, const char *name, PyObject *values, const char *doc)
+{
+ bool result; /* Bilan à retourner */
+ PyObject *enum_mod; /* Module Python enum */
+ PyObject *class; /* Classe "Enum*" */
+ PyObject *str_obj; /* Conversion en Python */
+ int ret; /* Bilan d'une insertion */
+ PyObject *args; /* Arguments de la construction*/
+ PyObject *kwargs; /* Mots clefs en complément */
+ PyObject *new; /* Nouvelle instance en place */
+ PyObject *features; /* Module à recompléter */
+ PyObject *features_dict; /* Dictionnaire à compléter */
+
+ result = false;
+
+ /* Recherche de la classe Python */
+
+ enum_mod = PyImport_ImportModule("enum");
+
+ if (enum_mod == NULL)
+ goto no_mod;
+
+ if (flags)
+ class = PyObject_GetAttrString(enum_mod, "IntFlag");
+ else
+ class = PyObject_GetAttrString(enum_mod, "IntEnum");
+
+ Py_DECREF(enum_mod);
+
+ if (class == NULL)
+ goto no_class;
+
+ /* Compléments des paramètres */
+
+ str_obj = PyUnicode_FromString(doc);
+ ret = PyDict_SetItemString(values, "__doc__", str_obj);
+ Py_DECREF(str_obj);
+
+ if (ret != 0)
+ goto doc_error;
+
+ args = PyTuple_New(2);
+
+ ret = PyTuple_SetItem(args, 0, PyUnicode_FromString(name));
+ if (ret != 0) goto args_error;
+
+ Py_INCREF(values);
+ ret = PyTuple_SetItem(args, 1, values);
+ if (ret != 0) goto args_error;
+
+ kwargs = PyDict_New();
+
+ str_obj = PyUnicode_FromString(owner->tp_name);
+ ret = PyDict_SetItemString(kwargs, "module", str_obj);
+ Py_DECREF(str_obj);
+
+ if (ret != 0) goto kwargs_error;
+
+ /* Constitution de l'énumération et enregistrement */
+
+ new = PyObject_Call(class, args, kwargs);
+ if (new == NULL) goto build_error;
+
+ ret = PyDict_SetItemString(owner->tp_dict, name, new);
+ if (ret != 0) goto register_0_error;
+
+ features = get_access_to_python_module("pychrysalide.features");
+
+ features_dict = PyModule_GetDict(features);
+
+ ret = PyDict_SetItemString(features_dict, name, new);
+ if (ret != 0) goto register_1_error;
+
+ result = true;
+
+ /* Sortie propre */
+
+ register_1_error:
+ register_0_error:
+
+ Py_DECREF(new);
+
+ build_error:
+ kwargs_error:
+
+ Py_DECREF(kwargs);
+
+ args_error:
+
+ Py_DECREF(args);
+
+ doc_error:
+
+ Py_DECREF(class);
+
+ no_class:
+ no_mod:
+
+ Py_DECREF(values);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : owner = propriétaire du groupe de constantes. *
+* name = désignation humaine du groupe à consulter. *
+* value = valeur à transmettre à Python. *
+* *
+* Description : Traduit une valeur constante C en équivalent Python. *
+* *
+* Retour : Objet Python résultant ou NULL en cas d'erreur. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+PyObject *cast_with_constants_group(const PyTypeObject *owner, const char *name, unsigned long value)
+{
+ PyObject *result; /* Objet Python à retourner */
+ char *dot; /* Position du dernier point */
+ char *modname; /* Chemin d'accès au module */
+ PyObject *module; /* Module à consulter */
+ PyObject *type; /* Classe propriétaire */
+ PyObject *class; /* Classe "Enum*" */
+ PyObject *args; /* Arguments de la construction*/
+
+ result = NULL;
+
+ /* Recherche de la classe Python */
+
+ dot = strrchr(owner->tp_name, '.');
+ assert(dot != NULL);
+
+ modname = strndup(owner->tp_name, dot - owner->tp_name);
+
+ module = get_access_to_python_module(modname);
+
+ if (module == NULL)
+ goto no_mod;
+
+ type = PyObject_GetAttrString(module, dot + 1);
+
+ if (type == NULL)
+ goto no_type;
+
+ class = PyObject_GetAttrString(type, name);
+
+ if (class == NULL)
+ goto no_class;
+
+ /* Construction */
+
+ args = Py_BuildValue("(k)", value);
+
+ result = PyObject_CallObject(class, args);
+
+ Py_DECREF(args);
+
+ Py_DECREF(class);
+
+ no_class:
+
+ Py_DECREF(type);
+
+ no_type:
+ no_mod:
+
+ free(modname);
+
+ return result;
+
+}
diff --git a/plugins/pychrysalide/helpers.h b/plugins/pychrysalide/helpers.h
index 4ffb447..e2ebfbc 100644
--- a/plugins/pychrysalide/helpers.h
+++ b/plugins/pychrysalide/helpers.h
@@ -156,4 +156,33 @@ bool register_class_for_dynamic_pygobject(GType, PyTypeObject *, PyTypeObject *)
+/* ----------------------- TRANSFERT DES VALEURS CONSTANTES ------------------------- */
+
+
+/* Officialise un groupe de constantes avec sémentique. */
+bool attach_constants_group(PyTypeObject *, bool, const char *, PyObject *, const char *);
+
+/* Simplification d'un ajout de constante pour l'appelant */
+#define add_const_to_group(d, n, v) \
+ ({ \
+ bool __result; \
+ PyObject *__val; \
+ int __ret; \
+ __val = PyLong_FromUnsignedLong(v); \
+ if (__val == NULL) \
+ __result = false; \
+ else \
+ { \
+ __ret = PyDict_SetItemString(d, n, __val); \
+ Py_DECREF(__val); \
+ __result = (__ret == 0); \
+ } \
+ __result; \
+ })
+
+/* Traduit une valeur constante C en équivalent Python. */
+PyObject *cast_with_constants_group(const PyTypeObject *, const char *, unsigned long);
+
+
+
#endif /* _PLUGINS_PYCHRYSALIDE_HELPERS_H */
diff --git a/tests/format/symbol.py b/tests/format/symbol.py
new file mode 100644
index 0000000..c720256
--- /dev/null
+++ b/tests/format/symbol.py
@@ -0,0 +1,26 @@
+#!/usr/bin/python3-dbg
+# -*- coding: utf-8 -*-
+
+
+# Tests pour valider la gestion des symboles
+
+
+from chrysacase import ChrysalideTestCase
+from pychrysalide.arch import vmpa, mrange
+from pychrysalide.format import BinSymbol
+
+
+class TestBinarySymbols(ChrysalideTestCase):
+ """TestCase for format.BinSymbol."""
+
+
+ def testSymbolDefaultStatus(self):
+ """Validate the default status for symbols."""
+
+ saddr = vmpa(0x10, vmpa.VMPA_NO_VIRTUAL)
+ srange = mrange(saddr, 0x3)
+ symbol = BinSymbol(BinSymbol.STP_ENTRY_POINT, srange)
+
+ self.assertEqual(symbol.status, BinSymbol.SymbolStatus.INTERNAL)
+
+ self.assertEqual(str(symbol.status), 'SymbolStatus.INTERNAL')