diff options
Diffstat (limited to 'plugins/pychrysalide')
-rw-r--r-- | plugins/pychrysalide/format/constants.c | 100 | ||||
-rw-r--r-- | plugins/pychrysalide/format/constants.h | 6 | ||||
-rw-r--r-- | plugins/pychrysalide/format/strsym.c | 274 | ||||
-rw-r--r-- | plugins/pychrysalide/format/symbol.c | 2 |
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" \ |