From 063383ee06a472515ddd39a071c449a7e34f5c6b Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Fri, 7 Feb 2020 00:13:32 +0100 Subject: Improved the documentation for the Dex format Python bindings. --- plugins/dex/python/class.c | 137 +++++++++++++++++++++++++++-------------- plugins/dex/python/constants.c | 89 +++++++++++--------------- plugins/dex/python/constants.h | 4 +- plugins/dex/python/field.c | 28 ++++++--- plugins/dex/python/format.c | 20 ++++-- plugins/dex/python/method.c | 59 +++++++++++++----- plugins/dex/python/module.c | 10 ++- plugins/dex/python/routine.c | 24 ++++++-- 8 files changed, 234 insertions(+), 137 deletions(-) diff --git a/plugins/dex/python/class.c b/plugins/dex/python/class.c index 82c893e..e344124 100644 --- a/plugins/dex/python/class.c +++ b/plugins/dex/python/class.c @@ -37,6 +37,10 @@ +#define DEX_CLASS_DOC \ + "The DexClass object handles a class defined in a DEX file." + + /* Fournit la définition brute d'une classe. */ static PyObject *py_dex_class_get_definition(PyObject *, void *); @@ -44,13 +48,13 @@ static PyObject *py_dex_class_get_definition(PyObject *, void *); static PyObject *py_dex_class_get_data(PyObject *, void *); /* Indique le type Android d'une classe. */ -static PyObject *py_dex_class_get_class_type(PyObject *, void *); +static PyObject *py_dex_class_get_type(PyObject *, void *); /* Indique le type Android parent d'une classe. */ -static PyObject *py_dex_class_get_superclass_type(PyObject *, void *); +static PyObject *py_dex_class_get_super(PyObject *, void *); /* Indique le type Android des interfaces d'une classe. */ -static PyObject *py_dex_class_get_interface_types(PyObject *, void *); +static PyObject *py_dex_class_get_interfaces(PyObject *, void *); /* Fournit les champs chargés correspondant à une classe donnée. */ static PyObject *py_dex_class_get_fields(PyObject *, void *); @@ -82,6 +86,12 @@ static PyObject *py_dex_class_get_definition(PyObject *self, void *closure) GDexClass *class; /* Version native */ const class_def_item *item; /* Elément à traiter */ +#define DEX_CLASS_DEFINITION_ATTRIB PYTHON_GET_DEF_FULL \ +( \ + definition, py_dex_class, \ + "Native definition of the Dex class." \ +) + class = G_DEX_CLASS(pygobject_get(self)); item = g_dex_class_get_definition(class); @@ -112,6 +122,12 @@ static PyObject *py_dex_class_get_data(PyObject *self, void *closure) GDexClass *class; /* Version native */ const class_data_item *item; /* Elément à traiter */ +#define DEX_CLASS_DATA_ATTRIB PYTHON_GET_DEF_FULL \ +( \ + data, py_dex_class, \ + "Native data of the Dex class, if any." \ +) + class = G_DEX_CLASS(pygobject_get(self)); item = g_dex_class_get_data(class); @@ -143,12 +159,18 @@ static PyObject *py_dex_class_get_data(PyObject *self, void *closure) * * ******************************************************************************/ -static PyObject *py_dex_class_get_class_type(PyObject *self, void *closure) +static PyObject *py_dex_class_get_type(PyObject *self, void *closure) { PyObject *result; /* Valeur à retourner */ GDexClass *class; /* Version native */ GDataType *type; /* Type de classe */ +#define DEX_CLASS_TYPE_ATTRIB PYTHON_GET_DEF_FULL \ +( \ + type, py_dex_class, \ + "Android type of the Dex class, None on error." \ +) + class = G_DEX_CLASS(pygobject_get(self)); type = g_dex_class_get_class_type(class); @@ -185,12 +207,18 @@ static PyObject *py_dex_class_get_class_type(PyObject *self, void *closure) * * ******************************************************************************/ -static PyObject *py_dex_class_get_superclass_type(PyObject *self, void *closure) +static PyObject *py_dex_class_get_super(PyObject *self, void *closure) { PyObject *result; /* Valeur à retourner */ GDexClass *class; /* Version native */ GDataType *type; /* Type de classe */ +#define DEX_CLASS_SUPER_ATTRIB PYTHON_GET_DEF_FULL \ +( \ + super, py_dex_class, \ + "Android type of the parent Dex class, None on error." \ +) + class = G_DEX_CLASS(pygobject_get(self)); type = g_dex_class_get_superclass_type(class); @@ -227,7 +255,7 @@ static PyObject *py_dex_class_get_superclass_type(PyObject *self, void *closure) * * ******************************************************************************/ -static PyObject *py_dex_class_get_interface_types(PyObject *self, void *closure) +static PyObject *py_dex_class_get_interfaces(PyObject *self, void *closure) { PyObject *result; /* Valeur à retourner */ GDexClass *class; /* Version native */ @@ -236,6 +264,13 @@ static PyObject *py_dex_class_get_interface_types(PyObject *self, void *closure) size_t i; /* Boucle de parcours */ PyObject *type; /* Type à ajouter à la liste */ +#define DEX_CLASS_INTERFACES_ATTRIB PYTHON_GET_DEF_FULL \ +( \ + interfaces, py_dex_class, \ + "Interface Android types of the Dex class, None if none and" \ + " None on error." \ +) + class = G_DEX_CLASS(pygobject_get(self)); types = g_dex_class_get_interface_types(class, &count); @@ -300,6 +335,22 @@ static PyObject *py_dex_class_get_fields(PyObject *self, void *closure) GDexField *field; /* Champ à convertir */ PyObject *fld; /* Objet à ajouter à la liste */ +#define DEX_CLASS_STATIC_FIELDS_ATTRIB PYTHON_GETSET_DEF \ +( \ + "static_fields", py_dex_class_get_fields, NULL, \ + "List of static fields of the Dex class, None if none and" \ + " None on error.", \ + NULL \ +) + +#define DEX_CLASS_INSTANCE_FIELDS_ATTRIB PYTHON_GETSET_DEF \ +( \ + "static_fields", py_dex_class_get_fields, NULL, \ + "List of instance fields of the Dex class, None if none and" \ + " None on error.", \ + (void *)1 \ +) + class = G_DEX_CLASS(pygobject_get(self)); instance = (closure != NULL); @@ -365,6 +416,22 @@ static PyObject *py_dex_class_get_methods(PyObject *self, void *closure) GDexMethod *method; /* Méthode à convertir */ PyObject *meth; /* Objet à ajouter à la liste */ +#define DEX_CLASS_DIRECT_METHODS_ATTRIB PYTHON_GETSET_DEF \ +( \ + "direct_methods", py_dex_class_get_methods, NULL, \ + "List of direct methods of the Dex class, None if none and" \ + " None on error.", \ + (void *)1 \ +) + +#define DEX_CLASS_VIRTUAL_METHODS_ATTRIB PYTHON_GETSET_DEF \ +( \ + "virtual_methods", py_dex_class_get_methods, NULL, \ + "List of virtual methods of the Dex class, None if none and" \ + " None on error.", \ + NULL \ +) + class = G_DEX_CLASS(pygobject_get(self)); virtual = (closure == NULL); @@ -426,6 +493,12 @@ static PyObject *py_dex_class_get_source_file(PyObject *self, void *closure) GDexClass *class; /* Version native */ const char *file; /* Fichier à l'origine du code */ +#define DEX_CLASS_SOURCE_FILE_ATTRIB PYTHON_GET_DEF_FULL \ +( \ + source_file, py_dex_class, \ + "Source file of the Dex class, None on error." \ +) + class = G_DEX_CLASS(pygobject_get(self)); file = g_dex_class_get_source_file(class); @@ -463,46 +536,16 @@ PyTypeObject *get_python_dex_class_type(void) }; static PyGetSetDef py_dex_class_getseters[] = { - { - "definition", py_dex_class_get_definition, NULL, - "Native definition of the Dex class.", NULL - }, - { - "data", py_dex_class_get_data, NULL, - "Native data of the Dex class, if any.", NULL - }, - { - "type", py_dex_class_get_class_type, NULL, - "Android type of the Dex class, None on error.", NULL - }, - { - "super", py_dex_class_get_superclass_type, NULL, - "Android type of the parent Dex class, None on error.", NULL - }, - { - "interfaces", py_dex_class_get_interface_types, NULL, - "Interface Android types of the Dex class, None if none and None on error.", NULL - }, - { - "static_fields", py_dex_class_get_fields, NULL, - "List of static fields of the Dex class, None if none and None on error.", NULL - }, - { - "instance_fields", py_dex_class_get_fields, NULL, - "List of static fields of the Dex class, None if none and None on error.", py_dex_class_get_fields - }, - { - "direct_methods", py_dex_class_get_methods, NULL, - "List of direct methods of the Dex class, None if none and None on error.", py_dex_class_get_methods - }, - { - "virtual_methods", py_dex_class_get_methods, NULL, - "List of virtual methods of the Dex class, None if none and None on error.", NULL - }, - { - "source_file", py_dex_class_get_source_file, NULL, - "Source file of the Dex class, None on error.", NULL - }, + DEX_CLASS_DEFINITION_ATTRIB, + DEX_CLASS_DATA_ATTRIB, + DEX_CLASS_TYPE_ATTRIB, + DEX_CLASS_SUPER_ATTRIB, + DEX_CLASS_INTERFACES_ATTRIB, + DEX_CLASS_STATIC_FIELDS_ATTRIB, + DEX_CLASS_INSTANCE_FIELDS_ATTRIB, + DEX_CLASS_DIRECT_METHODS_ATTRIB, + DEX_CLASS_VIRTUAL_METHODS_ATTRIB, + DEX_CLASS_SOURCE_FILE_ATTRIB, { NULL } }; @@ -515,7 +558,7 @@ PyTypeObject *get_python_dex_class_type(void) .tp_flags = Py_TPFLAGS_DEFAULT, - .tp_doc = "PyChrysalide Dex class.", + .tp_doc = DEX_CLASS_DOC, .tp_methods = py_dex_class_methods, .tp_getset = py_dex_class_getseters diff --git a/plugins/dex/python/constants.c b/plugins/dex/python/constants.c index 3e77fd6..b43e3f1 100644 --- a/plugins/dex/python/constants.c +++ b/plugins/dex/python/constants.c @@ -32,13 +32,9 @@ -/* Définit les constantes communes pour le format Dex. */ -static bool define_python_dex_format_common_constants(PyTypeObject *); - - /****************************************************************************** * * -* Paramètres : obj_type = type dont le dictionnaire est à compléter. * +* Paramètres : type = type dont le dictionnaire est à compléter. * * * * Description : Définit les constantes communes pour le format Dex. * * * @@ -48,56 +44,43 @@ static bool define_python_dex_format_common_constants(PyTypeObject *); * * ******************************************************************************/ -static bool define_python_dex_format_common_constants(PyTypeObject *obj_type) -{ - bool result; /* Bilan à retourner */ - - result = true; - - /* Définition des drapeaux d'accès */ - - if (result) result = PyDict_AddULongMacro(obj_type, ACC_PUBLIC); - if (result) result = PyDict_AddULongMacro(obj_type, ACC_PRIVATE); - if (result) result = PyDict_AddULongMacro(obj_type, ACC_PROTECTED); - if (result) result = PyDict_AddULongMacro(obj_type, ACC_STATIC); - if (result) result = PyDict_AddULongMacro(obj_type, ACC_FINAL); - if (result) result = PyDict_AddULongMacro(obj_type, ACC_SYNCHRONIZED); - if (result) result = PyDict_AddULongMacro(obj_type, ACC_VOLATILE); - if (result) result = PyDict_AddULongMacro(obj_type, ACC_BRIDGE); - if (result) result = PyDict_AddULongMacro(obj_type, ACC_TRANSIENT); - if (result) result = PyDict_AddULongMacro(obj_type, ACC_VARARGS); - if (result) result = PyDict_AddULongMacro(obj_type, ACC_NATIVE); - if (result) result = PyDict_AddULongMacro(obj_type, ACC_INTERFACE); - if (result) result = PyDict_AddULongMacro(obj_type, ACC_ABSTRACT); - if (result) result = PyDict_AddULongMacro(obj_type, ACC_STRICT); - if (result) result = PyDict_AddULongMacro(obj_type, ACC_SYNTHETIC); - if (result) result = PyDict_AddULongMacro(obj_type, ACC_ANNOTATION); - if (result) result = PyDict_AddULongMacro(obj_type, ACC_ENUM); - if (result) result = PyDict_AddULongMacro(obj_type, ACC_CONSTRUCTOR); - if (result) result = PyDict_AddULongMacro(obj_type, ACC_DECLARED_SYNCHRONIZED); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : obj_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_python_dex_format_constants(PyTypeObject *obj_type) +bool define_python_dex_format_common_constants(PyTypeObject *type) { bool result; /* Bilan à retourner */ - - result = define_python_dex_format_common_constants(obj_type); + PyObject *values; /* Groupe de valeurs à établir */ + + values = PyDict_New(); + + result = add_const_to_group(values, "PUBLIC", ACC_PUBLIC); + if (result) result = add_const_to_group(values, "PRIVATE", ACC_PRIVATE); + if (result) result = add_const_to_group(values, "PROTECTED", ACC_PROTECTED); + if (result) result = add_const_to_group(values, "STATIC", ACC_STATIC); + if (result) result = add_const_to_group(values, "FINAL", ACC_FINAL); + if (result) result = add_const_to_group(values, "SYNCHRONIZED", ACC_SYNCHRONIZED); + if (result) result = add_const_to_group(values, "VOLATILE", ACC_VOLATILE); + if (result) result = add_const_to_group(values, "BRIDGE", ACC_BRIDGE); + if (result) result = add_const_to_group(values, "TRANSIENT", ACC_TRANSIENT); + if (result) result = add_const_to_group(values, "VARARGS", ACC_VARARGS); + if (result) result = add_const_to_group(values, "NATIVE", ACC_NATIVE); + if (result) result = add_const_to_group(values, "INTERFACE", ACC_INTERFACE); + if (result) result = add_const_to_group(values, "ABSTRACT", ACC_ABSTRACT); + if (result) result = add_const_to_group(values, "STRICT", ACC_STRICT); + if (result) result = add_const_to_group(values, "SYNTHETIC", ACC_SYNTHETIC); + if (result) result = add_const_to_group(values, "ANNOTATION", ACC_ANNOTATION); + if (result) result = add_const_to_group(values, "ENUM", ACC_ENUM); + if (result) result = add_const_to_group(values, "CONSTRUCTOR", ACC_CONSTRUCTOR); + if (result) result = add_const_to_group(values, "DECLARED_SYNCHRONIZED", ACC_DECLARED_SYNCHRONIZED); + + if (!result) + { + Py_DECREF(values); + goto exit; + } + + result = attach_constants_group_to_type(type, true, "AccessFlags", values, + "Accessibility and overall properties of classes and class members."); + + exit: return result; diff --git a/plugins/dex/python/constants.h b/plugins/dex/python/constants.h index 802bf2f..41618a4 100644 --- a/plugins/dex/python/constants.h +++ b/plugins/dex/python/constants.h @@ -31,8 +31,8 @@ -/* Définit les constantes pour le format Dex. */ -bool define_python_dex_format_constants(PyTypeObject *); +/* Définit les constantes communes pour le format Dex. */ +bool define_python_dex_format_common_constants(PyTypeObject *); diff --git a/plugins/dex/python/field.c b/plugins/dex/python/field.c index 69faccc..1381af6 100644 --- a/plugins/dex/python/field.c +++ b/plugins/dex/python/field.c @@ -36,6 +36,10 @@ +#define DEX_FIELD_DOC \ + "The DexField object handles a field linked to a DEX class." + + /* Fournit les indications Dex concernant le champ de classe. */ static PyObject *py_dex_field_get_encoded(PyObject *, void *); @@ -63,6 +67,12 @@ static PyObject *py_dex_field_get_encoded(PyObject *self, void *closure) GDexField *field; /* Version native */ const encoded_field *info; /* Elément à traiter */ +#define DEX_FIELD_ENCODED_ATTRIB PYTHON_GET_DEF_FULL \ +( \ + encoded, py_dex_field, \ + "Encoded information about the Dex field." \ +) + field = G_DEX_FIELD(pygobject_get(self)); info = g_dex_field_get_dex_info(field); @@ -93,6 +103,12 @@ static PyObject *py_dex_field_get_variable(PyObject *self, void *closure) GDexField *field; /* Version native */ GBinVariable *variable; /* Variable correspondante */ +#define DEX_FIELD_VARIABLE_ATTRIB PYTHON_GET_DEF_FULL \ +( \ + variable, py_dex_field, \ + "Chrysalide variable for the Dex field." \ +) + field = G_DEX_FIELD(pygobject_get(self)); variable = g_dex_field_get_variable(field); @@ -125,14 +141,8 @@ PyTypeObject *get_python_dex_field_type(void) }; static PyGetSetDef py_dex_field_getseters[] = { - { - "encoded", py_dex_field_get_encoded, NULL, - "Encoded information about the Dex field.", NULL - }, - { - "variable", py_dex_field_get_variable, NULL, - "Chrysalide variable for the Dex field.", NULL - }, + DEX_FIELD_ENCODED_ATTRIB, + DEX_FIELD_VARIABLE_ATTRIB, { NULL } }; @@ -145,7 +155,7 @@ PyTypeObject *get_python_dex_field_type(void) .tp_flags = Py_TPFLAGS_DEFAULT, - .tp_doc = "PyChrysalide Dex class field.", + .tp_doc = DEX_FIELD_DOC, .tp_methods = py_dex_field_methods, .tp_getset = py_dex_field_getseters diff --git a/plugins/dex/python/format.c b/plugins/dex/python/format.c index 6e3d7d7..c1e4c40 100644 --- a/plugins/dex/python/format.c +++ b/plugins/dex/python/format.c @@ -73,6 +73,15 @@ static PyObject *py_dex_format_new(PyTypeObject *type, PyObject *args, PyObject int ret; /* Bilan de lecture des args. */ GExeFormat *format; /* Création GLib à transmettre */ +#define DEX_FORMAT_DOC \ + "DexFormat deals with DEX format.\n" \ + "\n" \ + "Instances can be created using the following constructor:\n" \ + "\n" \ + " DexFormat(content)" \ + "\n" \ + "Where content is a pychrysalide.analysis.BinContent object." \ + ret = PyArg_ParseTuple(args, "O&", convert_to_binary_content, &content); if (!ret) return NULL; @@ -238,7 +247,7 @@ PyTypeObject *get_python_dex_format_type(void) .tp_flags = Py_TPFLAGS_DEFAULT, - .tp_doc = "PyChrysalide Dex format", + .tp_doc = DEX_FORMAT_DOC, .tp_methods = py_dex_format_methods, .tp_getset = py_dex_format_getseters, @@ -265,18 +274,17 @@ PyTypeObject *get_python_dex_format_type(void) bool register_python_dex_format(PyObject *module) { - PyTypeObject *py_dex_format_type; /* Type Python 'DexFormat' */ + PyTypeObject *type; /* Type Python 'DexFormat' */ PyObject *dict; /* Dictionnaire du module */ - py_dex_format_type = get_python_dex_format_type(); + type = get_python_dex_format_type(); dict = PyModule_GetDict(module); - if (!register_class_for_pygobject(dict, G_TYPE_DEX_FORMAT, - py_dex_format_type, get_python_executable_format_type())) + if (!register_class_for_pygobject(dict, G_TYPE_DEX_FORMAT, type, get_python_executable_format_type())) return false; - if (!define_python_dex_format_constants(py_dex_format_type)) + if (!define_python_dex_format_common_constants(type)) return false; return true; diff --git a/plugins/dex/python/method.c b/plugins/dex/python/method.c index 6cf9abd..fab8e2e 100644 --- a/plugins/dex/python/method.c +++ b/plugins/dex/python/method.c @@ -36,6 +36,11 @@ +#define DEX_METHOD_DOC \ + "The DexMethod handles a method defined in a DEX format." \ + + + /* Fournit les identifiants Dex concernant la méthode. */ static PyObject *py_dex_method_get_id_item(PyObject *, void *); @@ -77,7 +82,7 @@ static PyObject *py_dex_method_get_id_item(PyObject *self, void *closure) "All the fields are extracted from the Dex *method_id_item* structure:\n" \ "* class_idx: index into the *type_ids* list for the definer of the method ;\n" \ "* proto_idx: index into the *proto_ids* list for the prototype of the method ;\n" \ - "* name_idx: index into the *string_ids* list for the name of the method." \ + "* name_idx: index into the *string_ids* list for the name of the method." \ ) method = G_DEX_METHOD(pygobject_get(self)); @@ -110,6 +115,17 @@ static PyObject *py_dex_method_get_encoded(PyObject *self, void *closure) GDexMethod *method; /* Version native */ const encoded_method *info; /* Elément à traiter */ +#define DEX_METHOD_ENCODED_ATTRIB PYTHON_GET_DEF_FULL \ +( \ + encoded, py_dex_method, \ + "pychrysalide.PyStructObject instance for encoded information about the Dex method.\n" \ + "\n" \ + "All the fields are extracted from the Dex *encoded_method* structure:\n" \ + "* method_idx_diff: index into the *method_ids* list for the identity of the method ;\n" \ + "* access_flags: access flags for the method ;\n" \ + "* code_off: offset from the start of the file to the code structure for the method." \ +) + method = G_DEX_METHOD(pygobject_get(self)); info = g_dex_method_get_dex_info(method); @@ -140,6 +156,22 @@ static PyObject *py_dex_method_get_code_item(PyObject *self, void *closure) GDexMethod *method; /* Version native */ const code_item *body; /* Elément à traiter */ +#define DEX_METHOD_CODE_ITEM_ATTRIB PYTHON_GET_DEF_FULL \ +( \ + code_item, py_dex_method, \ + "pychrysalide.PyStructObject instance of code information about the Dex method," \ + " or None if none.\n" \ + "\n" \ + "All the fields are extracted from the Dex *code_item* structure:\n" \ + "* registers_size: the number of registers used by the code ;\n" \ + "* ins_size: number of words of incoming arguments to the method that the code is for ;\n" \ + "* outs_size: number of words of outgoing argument space required for invocation ;\n" \ + "* tries_size: number of *try_items* for the instance ;\n" \ + "* debug_info_off: offset from the start of the file to the debug info sequence" \ + " for this code, or 0 no such information ;\n" \ + "* insns_size: size of the instructions list, in 16-bit code units." \ +) + method = G_DEX_METHOD(pygobject_get(self)); body = g_dex_method_get_dex_body(method); @@ -177,6 +209,14 @@ static PyObject *py_dex_method_get_routine(PyObject *self, void *closure) GDexMethod *method; /* Version native */ GBinRoutine *routine; /* Routine correspondante */ +#define DEX_METHOD_ROUTINE_ATTRIB PYTHON_GET_DEF_FULL \ +( \ + routine, py_dex_method, \ + "DEX method as seen from Chrysalide.\n" \ + "\n" \ + "The result is a pychrysalide.analysis.BinRoutine instance or None." \ +) + method = G_DEX_METHOD(pygobject_get(self)); routine = g_dex_method_get_routine(method); @@ -210,18 +250,9 @@ PyTypeObject *get_python_dex_method_type(void) static PyGetSetDef py_dex_method_getseters[] = { DEX_METHOD_ID_ITEM_ATTRIB, - { - "encoded", py_dex_method_get_encoded, NULL, - "Encoded information about the Dex method.", NULL - }, - { - "code_item", py_dex_method_get_code_item, NULL, - "Code information about the Dex method, None if none.", NULL - }, - { - "routine", py_dex_method_get_routine, NULL, - "Chrysalide routine for the Dex method.", NULL - }, + DEX_METHOD_ENCODED_ATTRIB, + DEX_METHOD_CODE_ITEM_ATTRIB, + DEX_METHOD_ROUTINE_ATTRIB, { NULL } }; @@ -234,7 +265,7 @@ PyTypeObject *get_python_dex_method_type(void) .tp_flags = Py_TPFLAGS_DEFAULT, - .tp_doc = "PyChrysalide Dex method.", + .tp_doc = DEX_METHOD_DOC, .tp_methods = py_dex_method_methods, .tp_getset = py_dex_method_getseters diff --git a/plugins/dex/python/module.c b/plugins/dex/python/module.c index e375ad7..9fbc29c 100644 --- a/plugins/dex/python/module.c +++ b/plugins/dex/python/module.c @@ -59,12 +59,20 @@ bool add_format_dex_module_to_python_module(void) PyObject *super; /* Module à compléter */ PyObject *module; /* Sous-module mis en place */ +#define DEX_MODULE_DOC \ + "This module provides several features to deal with the Dalvik Executable" \ + " (DEX) format.\n" \ + "\n" \ + "The layout of such a format is described at:" \ + " https://source.android.com/devices/tech/dalvik/dex-format" + + static PyModuleDef py_chrysalide_dex_module = { .m_base = PyModuleDef_HEAD_INIT, .m_name = "pychrysalide.format.dex", - .m_doc = "Python module for Chrysalide.format.dex", + .m_doc = DEX_MODULE_DOC, .m_size = -1, diff --git a/plugins/dex/python/routine.c b/plugins/dex/python/routine.c index ef85cc7..31410c7 100644 --- a/plugins/dex/python/routine.c +++ b/plugins/dex/python/routine.c @@ -36,6 +36,15 @@ +#define DEX_ROUTINE_DOC \ + "The DexRoutine is a definition of binary routine for DEX methods." \ + "\n" \ + "The only reason for such an object to exist is to provide a link" \ + " to a pychrysalide.format.dex.DexMethod from a" \ + " pychrysalide.analysis.BinRoutine." + + + /* Fournit la méthode liée à une routine d'origine Dex. */ static PyObject *py_dex_routine_get_method(PyObject *, void *); @@ -61,6 +70,14 @@ static PyObject *py_dex_routine_get_method(PyObject *self, void *closure) GDexRoutine *routine; /* Version native */ GDexMethod *method; /* Méthode correspondante */ +#define DEX_ROUTINE_METHOD_ATTRIB PYTHON_GET_DEF_FULL \ +( \ + method, py_dex_routine, \ + "Dex method attached to the Dex routine." \ + "\n" \ + "The result is a pychrysalide.format.dex.DexMethod instance or None." \ +) + routine = G_DEX_ROUTINE(pygobject_get(self)); method = g_dex_routine_get_method(routine); @@ -102,10 +119,7 @@ PyTypeObject *get_python_dex_routine_type(void) }; static PyGetSetDef py_dex_routine_getseters[] = { - { - "method", py_dex_routine_get_method, NULL, - "Dex method attached to the Dex routine.", NULL - }, + DEX_ROUTINE_METHOD_ATTRIB, { NULL } }; @@ -118,7 +132,7 @@ PyTypeObject *get_python_dex_routine_type(void) .tp_flags = Py_TPFLAGS_DEFAULT, - .tp_doc = "PyChrysalide Dex routine.", + .tp_doc = DEX_ROUTINE_DOC, .tp_methods = py_dex_routine_methods, .tp_getset = py_dex_routine_getseters -- cgit v0.11.2-87-g4458