diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2024-11-24 07:56:28 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2024-11-24 07:56:28 (GMT) |
commit | 461f42dd8eb8b1932c11364d9d15367eeb294848 (patch) | |
tree | fd40ede6c00be9fe33feac4242fc4e5903296d62 /plugins/pe/python/translate.c | |
parent | 31c235f145189fe146f9374d6826927de5964a07 (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.c | 290 |
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); |