summaryrefslogtreecommitdiff
path: root/plugins/pe/python/translate.c
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2024-11-24 07:56:28 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2024-11-24 07:56:28 (GMT)
commit461f42dd8eb8b1932c11364d9d15367eeb294848 (patch)
treefd40ede6c00be9fe33feac4242fc4e5903296d62 /plugins/pe/python/translate.c
parent31c235f145189fe146f9374d6826927de5964a07 (diff)
Restore and improve the support for PE files.gtk4
Diffstat (limited to 'plugins/pe/python/translate.c')
-rw-r--r--plugins/pe/python/translate.c290
1 files changed, 287 insertions, 3 deletions
diff --git a/plugins/pe/python/translate.c b/plugins/pe/python/translate.c
index c01a337..1b4b3ce 100644
--- a/plugins/pe/python/translate.c
+++ b/plugins/pe/python/translate.c
@@ -45,7 +45,7 @@
* *
******************************************************************************/
-PyObject *translate_pe_dos_header_to_python(GPeFormat *format, const image_dos_header *header)
+PyObject *translate_pe_dos_header_to_python(GPeFormat *format, const image_dos_header_t *header)
{
PyObject *result; /* Construction à retourner */
PyTypeObject *base; /* Modèle d'objet à créer */
@@ -64,6 +64,7 @@ PyObject *translate_pe_dos_header_to_python(GPeFormat *format, const image_dos_h
{ \
attrib = PyLong_FromUnsignedLongLong(header->e_ ## _f); \
ret = PyDict_SetItemString(result, "e_" #_f, attrib); \
+ Py_DECREF(attrib); \
if (ret != 0) goto failed; \
} \
while (0);
@@ -79,8 +80,13 @@ PyObject *translate_pe_dos_header_to_python(GPeFormat *format, const image_dos_h
ret = PyTuple_SetItem(attrib, i, item); \
if (ret != 0) break; \
} \
- if (ret != 0) goto failed; \
+ if (i < _n) \
+ { \
+ Py_DECREF(attrib); \
+ goto failed; \
+ } \
ret = PyDict_SetItemString(result, "e_" #_f, attrib); \
+ Py_DECREF(attrib); \
if (ret != 0) goto failed; \
} \
while (0);
@@ -119,6 +125,215 @@ PyObject *translate_pe_dos_header_to_python(GPeFormat *format, const image_dos_h
/******************************************************************************
* *
* Paramètres : format = format PE chargé sur lequel s'appuyer. *
+* header = en-tête NT à décrire en Python. *
+* *
+* Description : Traduit un en-tête PE en Python. *
+* *
+* Retour : Structure mise en place ou NULL en cas d'erreur. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+PyObject *translate_pe_nt_headers_to_python(GPeFormat *format, const image_nt_headers_t *header)
+{
+ PyObject *result; /* Construction à retourner */
+ PyTypeObject *base; /* Modèle d'objet à créer */
+ PyObject *attrib; /* Attribut à constituer */
+ int ret; /* Bilan d'une mise en place */
+ PyObject *sub; /* Sous-construction #1 */
+ bool is_32b; /* Format en version 32 bits ? */
+ const image_data_directory_t *directories; /* Répertoires à charger */
+ uint32_t number_of_rva_and_sizes; /* Quantité de ces répertoires */
+ uint32_t i; /* Boucle de parcours */
+ PyObject *dirs; /* Répertoires de données */
+ PyObject *subsub; /* Sous-construction #2 */
+
+ base = get_python_py_struct_type();
+
+ result = PyObject_CallFunction((PyObject *)base, NULL);
+ assert(result != NULL);
+
+#define TRANSLATE_IMAGE_NT_HEADERS_FIELD(_f) \
+ do \
+ { \
+ attrib = PyLong_FromUnsignedLongLong(header->_f); \
+ ret = PyDict_SetItemString(result, #_f, attrib); \
+ Py_DECREF(attrib); \
+ if (ret != 0) goto failed; \
+ } \
+ while (0);
+
+ TRANSLATE_IMAGE_NT_HEADERS_FIELD(signature);
+
+ /* Partie file_header */
+
+ sub = PyObject_CallFunction((PyObject *)base, NULL);
+ assert(sub != NULL);
+
+#define TRANSLATE_IMAGE_FILE_HEADER_FIELD(_f) \
+ do \
+ { \
+ attrib = PyLong_FromUnsignedLongLong(header->file_header._f); \
+ ret = PyDict_SetItemString(sub, #_f, attrib); \
+ Py_DECREF(attrib); \
+ if (ret != 0) \
+ { \
+ Py_DECREF(sub); \
+ goto failed; \
+ } \
+ } \
+ while (0);
+
+ TRANSLATE_IMAGE_FILE_HEADER_FIELD(machine);
+ TRANSLATE_IMAGE_FILE_HEADER_FIELD(number_of_sections);
+ TRANSLATE_IMAGE_FILE_HEADER_FIELD(time_date_stamp);
+ TRANSLATE_IMAGE_FILE_HEADER_FIELD(pointer_to_symbol_table);
+ TRANSLATE_IMAGE_FILE_HEADER_FIELD(number_of_symbols);
+ TRANSLATE_IMAGE_FILE_HEADER_FIELD(size_of_optional_header);
+ TRANSLATE_IMAGE_FILE_HEADER_FIELD(characteristics);
+
+ ret = PyDict_SetItemString(result, "file_header", sub);
+ Py_DECREF(sub);
+ if (ret != 0) goto failed;
+
+ /* Partie optional_header */
+
+ sub = PyObject_CallFunction((PyObject *)base, NULL);
+ assert(sub != NULL);
+
+ is_32b = g_pe_format_get_is_32b(format);
+
+#define TRANSLATE_IMAGE_OPTIONAL_HEADER_FIELD(_f) \
+ do \
+ { \
+ if (is_32b) \
+ attrib = PyLong_FromUnsignedLongLong(header->optional_header.header_32._f); \
+ else \
+ attrib = PyLong_FromUnsignedLongLong(header->optional_header.header_64._f); \
+ ret = PyDict_SetItemString(sub, #_f, attrib); \
+ Py_DECREF(attrib); \
+ if (ret != 0) \
+ { \
+ Py_DECREF(sub); \
+ goto failed; \
+ } \
+ } \
+ while (0);
+
+#define TRANSLATE_IMAGE_OPTIONAL_HEADER_32B_FIELD(_f) \
+ do \
+ { \
+ attrib = PyLong_FromUnsignedLongLong(header->optional_header.header_32._f); \
+ ret = PyDict_SetItemString(sub, #_f, attrib); \
+ Py_DECREF(attrib); \
+ if (ret != 0) \
+ { \
+ Py_DECREF(sub); \
+ goto failed; \
+ } \
+ } \
+ while (0);
+
+ TRANSLATE_IMAGE_OPTIONAL_HEADER_FIELD(magic);
+ TRANSLATE_IMAGE_OPTIONAL_HEADER_FIELD(major_linker_version);
+ TRANSLATE_IMAGE_OPTIONAL_HEADER_FIELD(minor_linker_version);
+ TRANSLATE_IMAGE_OPTIONAL_HEADER_FIELD(size_of_code);
+ TRANSLATE_IMAGE_OPTIONAL_HEADER_FIELD(size_of_initialized_data);
+ TRANSLATE_IMAGE_OPTIONAL_HEADER_FIELD(size_of_uninitialized_data);
+ TRANSLATE_IMAGE_OPTIONAL_HEADER_FIELD(address_of_entry_point);
+ TRANSLATE_IMAGE_OPTIONAL_HEADER_FIELD(base_of_code);
+ if (is_32b) TRANSLATE_IMAGE_OPTIONAL_HEADER_32B_FIELD(base_of_data);
+ TRANSLATE_IMAGE_OPTIONAL_HEADER_FIELD(image_base);
+ TRANSLATE_IMAGE_OPTIONAL_HEADER_FIELD(section_alignment);
+ TRANSLATE_IMAGE_OPTIONAL_HEADER_FIELD(file_alignment);
+ TRANSLATE_IMAGE_OPTIONAL_HEADER_FIELD(major_operating_system_version);
+ TRANSLATE_IMAGE_OPTIONAL_HEADER_FIELD(minor_operating_system_version);
+ TRANSLATE_IMAGE_OPTIONAL_HEADER_FIELD(major_image_version);
+ TRANSLATE_IMAGE_OPTIONAL_HEADER_FIELD(minor_image_version);
+ TRANSLATE_IMAGE_OPTIONAL_HEADER_FIELD(major_subsystem_version);
+ TRANSLATE_IMAGE_OPTIONAL_HEADER_FIELD(minor_subsystem_version);
+ TRANSLATE_IMAGE_OPTIONAL_HEADER_FIELD(win32_version_value);
+ TRANSLATE_IMAGE_OPTIONAL_HEADER_FIELD(size_of_image);
+ TRANSLATE_IMAGE_OPTIONAL_HEADER_FIELD(size_of_headers);
+ TRANSLATE_IMAGE_OPTIONAL_HEADER_FIELD(checksum);
+ TRANSLATE_IMAGE_OPTIONAL_HEADER_FIELD(subsystem);
+ TRANSLATE_IMAGE_OPTIONAL_HEADER_FIELD(dll_characteristics);
+ TRANSLATE_IMAGE_OPTIONAL_HEADER_FIELD(size_of_stack_reserve);
+ TRANSLATE_IMAGE_OPTIONAL_HEADER_FIELD(size_of_stack_commit);
+ TRANSLATE_IMAGE_OPTIONAL_HEADER_FIELD(size_of_heap_reserve);
+ TRANSLATE_IMAGE_OPTIONAL_HEADER_FIELD(size_of_heap_commit);
+ TRANSLATE_IMAGE_OPTIONAL_HEADER_FIELD(loader_flags);
+ TRANSLATE_IMAGE_OPTIONAL_HEADER_FIELD(number_of_rva_and_sizes);
+
+ ret = PyDict_SetItemString(result, "optional_header", sub);
+ Py_DECREF(sub);
+ if (ret != 0) goto failed;
+
+ /* Répertoires de données */
+
+ if (is_32b)
+ {
+ directories = header->optional_header.header_32.data_directory;
+ number_of_rva_and_sizes = header->optional_header.header_32.number_of_rva_and_sizes;
+ }
+ else
+ {
+ directories = header->optional_header.header_64.data_directory;
+ number_of_rva_and_sizes = header->optional_header.header_64.number_of_rva_and_sizes;
+ }
+
+ dirs = PyTuple_New(number_of_rva_and_sizes);
+
+ for (i = 0; i < number_of_rva_and_sizes; i++)
+ {
+ subsub = translate_pe_image_data_directory_to_python(format, directories + i);
+ if (subsub == NULL) break;
+
+ ret = PyTuple_SetItem(dirs, i, subsub);
+ if (ret != 0) break;
+
+ }
+
+ if (i < number_of_rva_and_sizes)
+ goto failed_with_dirs;
+
+ /**
+ * La fonction PyTuple_SetItem() comporte le prologue suivant :
+ *
+ * if (!PyTuple_Check(op) || Py_REFCNT(op) != 1) {
+ * Py_XDECREF(newitem);
+ * PyErr_BadInternalCall();
+ * return -1;
+ * }
+ *
+ * Comme l'appel à PyDict_SetItemString() incrémente le compte de référence
+ * de dirs, il convient de le réaliser après la consitution de la liste.
+ */
+
+ ret = PyDict_SetItemString(sub, "directories", dirs);
+ if (ret != 0) goto failed_with_dirs;
+
+ Py_DECREF(dirs);
+
+ return result;
+
+ failed_with_dirs:
+
+ Py_DECREF(dirs);
+
+ failed:
+
+ Py_DECREF(result);
+
+ return NULL;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : format = format PE chargé sur lequel s'appuyer. *
* dir = répertoire PE à décrire en Python. *
* *
* Description : Traduit un répertoire PE en Python. *
@@ -129,7 +344,7 @@ PyObject *translate_pe_dos_header_to_python(GPeFormat *format, const image_dos_h
* *
******************************************************************************/
-PyObject *translate_pe_image_data_directory_to_python(GPeFormat *format, const image_data_directory *dir)
+PyObject *translate_pe_image_data_directory_to_python(GPeFormat *format, const image_data_directory_t *dir)
{
PyObject *result; /* Construction à retourner */
PyTypeObject *base; /* Modèle d'objet à créer */
@@ -146,6 +361,7 @@ PyObject *translate_pe_image_data_directory_to_python(GPeFormat *format, const i
{ \
attrib = PyLong_FromUnsignedLongLong(dir->_f); \
ret = PyDict_SetItemString(result, #_f, attrib); \
+ Py_DECREF(attrib); \
if (ret != 0) goto failed; \
} \
while (0);
@@ -167,6 +383,73 @@ PyObject *translate_pe_image_data_directory_to_python(GPeFormat *format, const i
/******************************************************************************
* *
* Paramètres : format = format PE chargé sur lequel s'appuyer. *
+* header = en-tête de section à décrire en Python. *
+* *
+* Description : Traduit une section PE en Python. *
+* *
+* Retour : Structure mise en place ou NULL en cas d'erreur. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+PyObject *translate_pe_section_header_to_python(GPeFormat *format, const image_section_header_t *header)
+{
+ PyObject *result; /* Construction à retourner */
+ PyTypeObject *base; /* Modèle d'objet à créer */
+ PyObject *attrib; /* Attribut à constituer */
+ int ret; /* Bilan d'une mise en place */
+
+ base = get_python_py_struct_type();
+
+ result = PyObject_CallFunction((PyObject *)base, NULL);
+ assert(result != NULL);
+
+ /* Nom de la section */
+
+ attrib = PyBytes_FromStringAndSize(header->name, IMAGE_SIZEOF_SHORT_NAME);
+
+ ret = PyDict_SetItemString(result, "name", attrib);
+ Py_DECREF(attrib);
+
+ if (ret != 0) goto failed;
+
+ /* Eléments classiques */
+
+#define TRANSLATE_IMAGE_SECTION_HEADER_FIELD(_f) \
+ do \
+ { \
+ attrib = PyLong_FromUnsignedLongLong(header->_f); \
+ ret = PyDict_SetItemString(result, #_f, attrib); \
+ Py_DECREF(attrib); \
+ if (ret != 0) goto failed; \
+ } \
+ while (0);
+
+ TRANSLATE_IMAGE_SECTION_HEADER_FIELD(virtual_size);
+ TRANSLATE_IMAGE_SECTION_HEADER_FIELD(virtual_address);
+ TRANSLATE_IMAGE_SECTION_HEADER_FIELD(size_of_raw_data);
+ TRANSLATE_IMAGE_SECTION_HEADER_FIELD(pointer_to_raw_data);
+ TRANSLATE_IMAGE_SECTION_HEADER_FIELD(pointer_to_relocations);
+ TRANSLATE_IMAGE_SECTION_HEADER_FIELD(pointer_to_line_numbers);
+ TRANSLATE_IMAGE_SECTION_HEADER_FIELD(number_of_relocations);
+ TRANSLATE_IMAGE_SECTION_HEADER_FIELD(number_of_line_numbers);
+ TRANSLATE_IMAGE_SECTION_HEADER_FIELD(characteristics);
+
+ return result;
+
+ failed:
+
+ Py_DECREF(result);
+
+ return NULL;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : format = format PE chargé sur lequel s'appuyer. *
* id = ensemble d'informations à décrire en Python. *
* *
* Description : Traduit une série d'informations enrichies en Python. *
@@ -194,6 +477,7 @@ PyObject *translate_pe_comp_id_to_python(GPeFormat *format, const comp_id_t *id)
{ \
attrib = PyLong_FromUnsignedLongLong(id->_f); \
ret = PyDict_SetItemString(result, #_f, attrib); \
+ Py_DECREF(attrib); \
if (ret != 0) goto failed; \
} \
while (0);