summaryrefslogtreecommitdiff
path: root/plugins/pychrysalide/format
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2020-05-18 21:50:26 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2020-05-18 21:50:26 (GMT)
commit041056d04032d41a5c092c62cbfd67b199094991 (patch)
treea294afa55e307fe68617f80af3e9999ad7fa28b6 /plugins/pychrysalide/format
parent4f18f051936f633473c365d4c91ef7e77fa7feee (diff)
Updated the Python API for string symbols.
Diffstat (limited to 'plugins/pychrysalide/format')
-rw-r--r--plugins/pychrysalide/format/constants.c100
-rw-r--r--plugins/pychrysalide/format/constants.h6
-rw-r--r--plugins/pychrysalide/format/strsym.c274
-rw-r--r--plugins/pychrysalide/format/symbol.c2
4 files changed, 327 insertions, 55 deletions
diff --git a/plugins/pychrysalide/format/constants.c b/plugins/pychrysalide/format/constants.c
index 0df7bd4..9669b46 100644
--- a/plugins/pychrysalide/format/constants.c
+++ b/plugins/pychrysalide/format/constants.c
@@ -26,6 +26,7 @@
#include <format/format.h>
+#include <format/strsym.h>
#include <format/symbol.h>
@@ -159,3 +160,102 @@ bool define_binary_symbol_constants(PyTypeObject *type)
return result;
}
+
+
+/******************************************************************************
+* *
+* Paramètres : type = type dont le dictionnaire est à compléter. *
+* *
+* Description : Définit les constantes pour les symboles liés à des chaînes. *
+* *
+* Retour : true en cas de succès de l'opération, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool define_string_symbol_constants(PyTypeObject *type)
+{
+ bool result; /* Bilan à retourner */
+ PyObject *values; /* Groupe de valeurs à établir */
+
+ result = true;
+
+ values = PyDict_New();
+
+ if (result) result = add_const_to_group(values, "NONE", SET_NONE);
+ if (result) result = add_const_to_group(values, "ASCII", SET_ASCII);
+ if (result) result = add_const_to_group(values, "UTF_8", SET_UTF_8);
+ if (result) result = add_const_to_group(values, "MUTF_8", SET_MUTF_8);
+ if (result) result = add_const_to_group(values, "GUESS", SET_GUESS);
+
+ if (!result)
+ {
+ Py_DECREF(values);
+ goto exit;
+ }
+
+ result = attach_constants_group_to_type(type, false, "StringEncodingType", values,
+ "Kinds of encoding for strings.");
+
+ exit:
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : arg = argument quelconque à tenter de convertir. *
+* dst = destination des valeurs récupérées en cas de succès. *
+* *
+* Description : Tente de convertir en constante StringEncodingType. *
+* *
+* Retour : Bilan de l'opération, voire indications supplémentaires. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+int convert_to_string_encoding_type(PyObject *arg, void *dst)
+{
+ int result; /* Bilan à retourner */
+ unsigned long value; /* Valeur transcrite */
+
+ result = PyObject_IsInstance(arg, (PyObject *)&PyLong_Type);
+
+ switch (result)
+ {
+ case -1:
+ /* L'exception est déjà fixée par Python */
+ result = 0;
+ break;
+
+ case 0:
+ PyErr_SetString(PyExc_TypeError, "unable to convert the provided argument to StringEncodingType");
+ break;
+
+ case 1:
+ value = PyLong_AsUnsignedLong(arg);
+
+ if (value > SET_GUESS)
+ {
+ PyErr_SetString(PyExc_TypeError, "invalid value for StringEncodingType");
+ result = 0;
+ }
+
+ else
+ *((StringEncodingType *)dst) = value;
+
+ break;
+
+ default:
+ assert(false);
+ break;
+
+ }
+
+ return result;
+
+}
diff --git a/plugins/pychrysalide/format/constants.h b/plugins/pychrysalide/format/constants.h
index ad7b9a5..bbed6ae 100644
--- a/plugins/pychrysalide/format/constants.h
+++ b/plugins/pychrysalide/format/constants.h
@@ -37,6 +37,12 @@ bool define_binary_format_constants(PyTypeObject *);
/* Définit les constantes pour les symboles binaires. */
bool define_binary_symbol_constants(PyTypeObject *);
+/* Définit les constantes pour les symboles liés à des chaînes. */
+bool define_string_symbol_constants(PyTypeObject *);
+
+/* Tente de convertir en constante StringEncodingType. */
+int convert_to_string_encoding_type(PyObject *, void *);
+
#endif /* _PLUGINS_PYCHRYSALIDE_FORMAT_CONSTANTS_H */
diff --git a/plugins/pychrysalide/format/strsym.c b/plugins/pychrysalide/format/strsym.c
index e465002..2824677 100644
--- a/plugins/pychrysalide/format/strsym.c
+++ b/plugins/pychrysalide/format/strsym.c
@@ -33,15 +33,33 @@
#include <format/strsym.h>
+#include <plugins/dt.h>
+#include "constants.h"
+#include "format.h"
#include "symbol.h"
#include "../access.h"
#include "../helpers.h"
#include "../arch/feeder.h"
+#include "../arch/vmpa.h"
+/* ------------------------ GLUE POUR CREATION DEPUIS PYTHON ------------------------ */
+
+
+/* Accompagne la création d'une instance dérivée en Python. */
+static PyObject *py_string_symbol_new(PyTypeObject *, PyObject *, PyObject *);
+
+/* Initialise une instance sur la base du dérivé de GObject. */
+static int py_string_symbol_init(PyObject *, PyObject *, PyObject *);
+
+
+
+/* ----------------------- VITRINE POUR CHAINES DE CARACTERES ----------------------- */
+
+
/* Indique si une chaîne de caractères est liée au format. */
static PyObject *py_string_symbol_get_structural(PyObject *, void *);
@@ -57,10 +75,173 @@ static PyObject *py_string_symbol_get_raw(PyObject *, void *);
/* Fournit la chaîne de caractères du symbole. */
static PyObject *py_string_symbol_get_utf8(PyObject *, void *);
-/* Définit les constantes pour les chaînes de caractères. */
-static bool py_string_symbol_define_constants(PyTypeObject *);
+/* ---------------------------------------------------------------------------------- */
+/* GLUE POUR CREATION DEPUIS PYTHON */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+* *
+* Paramètres : type = type du nouvel objet à mettre en place. *
+* args = éventuelle liste d'arguments. *
+* kwds = éventuel dictionnaire de valeurs mises à disposition. *
+* *
+* Description : Accompagne la création d'une instance dérivée en Python. *
+* *
+* Retour : Nouvel objet Python mis en place ou NULL en cas d'échec. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_string_symbol_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ PyObject *result; /* Objet à retourner */
+ PyTypeObject *base; /* Type de base à dériver */
+ bool first_time; /* Evite les multiples passages*/
+ GType gtype; /* Nouveau type de processeur */
+ bool status; /* Bilan d'un enregistrement */
+
+ /* Validations diverses */
+
+ base = get_python_string_symbol_type();
+
+ if (type == base)
+ goto simple_way;
+
+ /* Mise en place d'un type dédié */
+
+ first_time = (g_type_from_name(type->tp_name) == 0);
+
+ gtype = build_dynamic_type(G_TYPE_STR_SYMBOL, type->tp_name, NULL, NULL, NULL);
+
+ if (first_time)
+ {
+ status = register_class_for_dynamic_pygobject(gtype, type, base);
+
+ if (!status)
+ {
+ result = NULL;
+ goto exit;
+ }
+
+ }
+
+ /* On crée, et on laisse ensuite la main à PyGObject_Type.tp_init() */
+
+ simple_way:
+
+ result = PyType_GenericNew(type, args, kwds);
+
+ exit:
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : self = objet à initialiser (théoriquement). *
+* args = arguments fournis à l'appel. *
+* kwds = arguments de type key=val fournis. *
+* *
+* Description : Initialise une instance sur la base du dérivé de GObject. *
+* *
+* Retour : 0. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static int py_string_symbol_init(PyObject *self, PyObject *args, PyObject *kwds)
+{
+ StringEncodingType encoding; /* Encodage spécifié */
+ GBinFormat *format; /* Format au contenu à relire */
+ mrange_t range; /* Version native d'un espace */
+ const char *string; /* Chaîne de caractères soumise*/
+ vmpa2t *addr; /* Emplacement de chaîne */
+ int ret; /* Bilan de lecture des args. */
+ GStrSymbol *symbol; /* Version GLib du symbole */
+
+ static char *kwlist[] = { "encoding", "format", "range", "string", "addr", NULL };
+
+#define STRING_SYMBOL_DOC \
+ "StrSymbol is a special symbol object dedicated to strings.\n" \
+ "\n" \
+ "Instances can be created using one of the following constructors:\n" \
+ "\n" \
+ " StrSymbol(encoding, format=pychrysalide.format.BinFormat," \
+ " range=pychrysalide.arch.mrange)" \
+ "\n" \
+ " StrSymbol(encoding, string=string, addr=pychrysalide.arch.vmpa)" \
+ "\n" \
+ "The first constructor is aimed to be used for read-only strings available" \
+ " from the raw data of the analyzed binary. The format provides the raw" \
+ " content, and the memory range specifies the location of the string.\n" \
+ "\n" \
+ "The second constructor is useful for strings which can not be extracted" \
+ " directly from the original content, such as obfuscted strings. A dynamic" \
+ " string is then provided here, and the start point of this string has to" \
+ " be provided.\n" \
+ "\n" \
+ "In both cases, the encoding remains the first argument, as a" \
+ " pychrysalide.format.StrSymbol.StringEncodingType value."
+
+ /* Récupération des paramètres */
+
+ format = NULL;
+ string = NULL;
+ addr = NULL;
+
+ ret = PyArg_ParseTupleAndKeywords(args, kwds, "O&|O&O&sO&", kwlist,
+ convert_to_string_encoding_type, &encoding,
+ convert_to_binary_format, &format,
+ convert_any_to_mrange, &range,
+ &string, convert_any_to_vmpa, &addr);
+ if (!ret) return -1;
+
+ /* Initialisation d'un objet GLib */
+
+ ret = forward_pygobjet_init(self);
+ if (ret == -1) return -1;
+
+ /* Eléments de base */
+
+ symbol = G_STR_SYMBOL(pygobject_get(self));
+
+ if (format != NULL)
+ g_string_symbol_init_read_only(symbol, encoding, format, &range);
+
+ else if (string != NULL && addr != NULL)
+ {
+ g_string_symbol_init_dynamic(symbol, encoding, string, addr);
+ clean_vmpa_arg(addr);
+ }
+
+ else
+ {
+ PyErr_SetString(PyExc_ValueError, _("Invalid argument combination."));
+
+ if (addr != NULL)
+ clean_vmpa_arg(addr);
+
+ return -1;
+
+ }
+
+ return 0;
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* VITRINE POUR CHAINES DE CARACTERES */
+/* ---------------------------------------------------------------------------------- */
+
/******************************************************************************
* *
@@ -149,10 +330,17 @@ static PyObject *py_string_symbol_get_encoding(PyObject *self, void *closure)
GStrSymbol *symbol; /* Elément à consulter */
StringEncodingType encoding; /* Encodage associé à la chaîne*/
+#define STRING_SYMBOL_ENCODING_ATTRIB PYTHON_GET_DEF_FULL \
+( \
+ encoding, py_string_symbol, \
+ "Encoding of the string, provided as a" \
+ " pychrysalide.format.StrSymbol.StringEncodingType value." \
+)
+
symbol = G_STR_SYMBOL(pygobject_get(self));
encoding = g_string_symbol_get_encoding(symbol);
- result = PyLong_FromLong(encoding);
+ result = cast_with_constants_group_from_type(get_python_string_symbol_type(), "StringEncodingType", encoding);
return result;
@@ -179,6 +367,12 @@ static PyObject *py_string_symbol_get_raw(PyObject *self, void *closure)
size_t len; /* Taille de la chaîne */
const char *data; /* Données à manipuler */
+#define STRING_SYMBOL_RAW_ATTRIB PYTHON_GET_DEF_FULL \
+( \
+ raw, py_string_symbol, \
+ "Raw data of the string, provided as bytes." \
+)
+
symbol = G_STR_SYMBOL(pygobject_get(self));
data = g_string_symbol_get_raw(symbol, &len);
@@ -209,6 +403,12 @@ static PyObject *py_string_symbol_get_utf8(PyObject *self, void *closure)
size_t len; /* Taille de la chaîne */
const char *data; /* Données à manipuler */
+#define STRING_SYMBOL_UTF8_ATTRIB PYTHON_GET_DEF_FULL \
+( \
+ utf8, py_string_symbol, \
+ "String content as UTF-8 data." \
+)
+
symbol = G_STR_SYMBOL(pygobject_get(self));
data = g_string_symbol_get_utf8(symbol, &len);
@@ -221,37 +421,6 @@ static PyObject *py_string_symbol_get_utf8(PyObject *self, void *closure)
/******************************************************************************
* *
-* Paramètres : obj_type = type dont le dictionnaire est à compléter. *
-* *
-* Description : Définit les constantes pour les chaînes de caractères. *
-* *
-* Retour : true en cas de succès de l'opération, false sinon. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static bool py_string_symbol_define_constants(PyTypeObject *obj_type)
-{
- bool result; /* Bilan à retourner */
-
- result = true;
-
- result &= PyDict_AddULongMacro(obj_type, SET_NONE);
-
- result &= PyDict_AddULongMacro(obj_type, SET_ASCII);
- result &= PyDict_AddULongMacro(obj_type, SET_UTF_8);
- result &= PyDict_AddULongMacro(obj_type, SET_MUTF_8);
-
- result &= PyDict_AddULongMacro(obj_type, SET_GUESS);
-
- return result;
-
-}
-
-
-/******************************************************************************
-* *
* Paramètres : - *
* *
* Description : Fournit un accès à une définition de type à diffuser. *
@@ -264,28 +433,19 @@ static bool py_string_symbol_define_constants(PyTypeObject *obj_type)
PyTypeObject *get_python_string_symbol_type(void)
{
- static PyMethodDef py_str_symbol_methods[] = {
+ static PyMethodDef py_string_symbol_methods[] = {
{ NULL }
};
- static PyGetSetDef py_str_symbol_getseters[] = {
+ static PyGetSetDef py_string_symbol_getseters[] = {
STRING_SYMBOL_STRUCTURAL_ATTRIB,
- {
- "encoding", py_string_symbol_get_encoding, NULL,
- "Encoding of the string.", NULL
- },
- {
- "raw", py_string_symbol_get_raw, NULL,
- "String content as raw data.", NULL
- },
- {
- "utf8", py_string_symbol_get_utf8, NULL,
- "String content as UTF-8 data.", NULL
- },
+ STRING_SYMBOL_ENCODING_ATTRIB,
+ STRING_SYMBOL_RAW_ATTRIB,
+ STRING_SYMBOL_UTF8_ATTRIB,
{ NULL }
};
- static PyTypeObject py_str_symbol_type = {
+ static PyTypeObject py_string_symbol_type = {
PyVarObject_HEAD_INIT(NULL, 0)
@@ -294,14 +454,17 @@ PyTypeObject *get_python_string_symbol_type(void)
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
- .tp_doc = "PyChrysalide string symbol",
+ .tp_doc = STRING_SYMBOL_DOC,
- .tp_methods = py_str_symbol_methods,
- .tp_getset = py_str_symbol_getseters
+ .tp_methods = py_string_symbol_methods,
+ .tp_getset = py_string_symbol_getseters,
+
+ .tp_init = py_string_symbol_init,
+ .tp_new = py_string_symbol_new
};
- return &py_str_symbol_type;
+ return &py_string_symbol_type;
}
@@ -335,10 +498,13 @@ bool ensure_python_string_symbol_is_registered(void)
if (!ensure_python_proxy_feeder_is_registered())
return false;
+ if (!ensure_python_binary_symbol_is_registered())
+ return false;
+
if (!register_class_for_pygobject(dict, G_TYPE_STR_SYMBOL, type, get_python_binary_symbol_type()))
return false;
- if (!py_string_symbol_define_constants(type))
+ if (!define_string_symbol_constants(type))
return false;
}
diff --git a/plugins/pychrysalide/format/symbol.c b/plugins/pychrysalide/format/symbol.c
index 7ecc576..d6d6402 100644
--- a/plugins/pychrysalide/format/symbol.c
+++ b/plugins/pychrysalide/format/symbol.c
@@ -270,7 +270,7 @@ static int py_binary_symbol_init(PyObject *self, PyObject *args, PyObject *kwds)
mrange_t range; /* Version native d'un espace */
unsigned long stype; /* Type prévu pour le symbole */
int ret; /* Bilan de lecture des args. */
- GBinSymbol *symbol; /* Version GLib du symble */
+ GBinSymbol *symbol; /* Version GLib du symbole */
#define BINARY_SYMBOL_DOC \
"BinSymbol represents all kinds of symbols, such as strings, routines or" \