From 2f0c162313fa7272bfec7eb674b71e5e15c4ec7c Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Mon, 2 Jan 2017 23:09:09 +0100 Subject: Unlinked instructions to save memory. --- ChangeLog | 13 +++ plugins/pychrysa/arch/instruction.c | 190 ------------------------------------ src/analysis/disass/area.c | 51 +++++----- src/arch/instruction-int.h | 10 -- src/arch/instruction.c | 139 -------------------------- src/arch/instruction.h | 21 ---- 6 files changed, 36 insertions(+), 388 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1c81be7..77106be 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +17-01-02 Cyrille Bagard + + * plugins/pychrysa/arch/instruction.c: + * src/analysis/disass/area.c: + Update code. + + * src/arch/instruction-int.h: + Unlink instructions to save memory. + + * src/arch/instruction.c: + * src/arch/instruction.h: + Update code. + 17-01-01 Cyrille Bagard * plugins/ropgadgets/finder.c: diff --git a/plugins/pychrysa/arch/instruction.c b/plugins/pychrysa/arch/instruction.c index 9e676d2..8ebdef0 100644 --- a/plugins/pychrysa/arch/instruction.c +++ b/plugins/pychrysa/arch/instruction.c @@ -403,32 +403,6 @@ bool register_python_arch_instruction(PyObject *module) -/* --------------------- ITERATEUR POUR BOUCLE SUR INSTRUCTIONS --------------------- */ - - -/* Itérateur pour les instructions */ -typedef struct _PyArchInstructionIter -{ - PyObject_HEAD /* A laisser en premier */ - - GArchInstruction *head; /* Ancrage supposé */ - PyObject *current; /* Départ, puis parcours... */ - bool started; /* Démarrage effectué ? */ - -} PyArchInstructionIter; - - -/* Prépare l'itérateur pour un parcours d'instructions. */ -static PyObject *py_arch_instruction_iterator_create(PyObject *); - -/* Libère la mémoire d'un itérateur de 'ArchInstruction'. */ -static void py_arch_instruction_iterator_dealloc(PyArchInstructionIter *); - -/* Fournit l'élément suivant dans un parcours d'instructions. */ -static PyObject *py_arch_instruction_iterator_next(PyArchInstructionIter *); - - - /* --------------------- INSTRUCTIONS D'ARCHITECTURES EN PYTHON --------------------- */ @@ -447,170 +421,6 @@ static PyObject *py_arch_instruction_get_keyword(PyObject *, void *); /* ---------------------------------------------------------------------------------- */ -/* ITERATEUR POUR BOUCLE SUR INSTRUCTIONS */ -/* ---------------------------------------------------------------------------------- */ - - -/****************************************************************************** -* * -* Paramètres : origin = élément à l'origine du parcours. * -* * -* Description : Prépare l'itérateur pour un parcours d'instructions. * -* * -* Retour : Instance d'itérateur prête à emploi. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static PyObject *py_arch_instruction_iterator_create(PyObject *origin) -{ - PyArchInstructionIter *result; /* Nouvelle instance à renvoyer*/ - PyObject *module; /* Module d'appartenance */ - PyTypeObject *type; /* Type d'objet à créer */ - - module = PyImport_ImportModule("pychrysalide.arch"); - type = (PyTypeObject *)PyObject_GetAttrString(module, "ArchInstructionIterator"); - Py_DECREF(module); - - result = (PyArchInstructionIter *)type->tp_alloc(type, 0); - Py_DECREF(type); - - if (result != NULL) - { - Py_INCREF(origin); - result->head = G_ARCH_INSTRUCTION(pygobject_get(origin)); - g_object_ref(G_OBJECT(result->head)); - - result->current = origin; - } - - return (PyObject *)result; - -} - - -/****************************************************************************** -* * -* Paramètres : self = instance d'objet à supprimer. * -* * -* Description : Libère la mémoire d'un itérateur de 'ArchInstruction'. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void py_arch_instruction_iterator_dealloc(PyArchInstructionIter *self) -{ - PyObject *first; /* Récupération de la première */ - - first = pygobject_new(G_OBJECT(self->head)); - - Py_DECREF(first); - g_object_unref(G_OBJECT(self->head)); - -#if PY_VERSION_HEX < 0x03000000 - self->ob_type->tp_free((PyObject *)self); -#else - Py_TYPE(self)->tp_free((PyObject *)self); -#endif - -} - - -/****************************************************************************** -* * -* Paramètres : self = instance manipulée à traiter. * -* * -* Description : Fournit l'élément suivant dans un parcours d'instructions. * -* * -* Retour : Point suivant du parcours ou NULL. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static PyObject *py_arch_instruction_iterator_next(PyArchInstructionIter *self) -{ - PyObject *result; /* Elément à retourner */ - GArchInstruction *next; /* Elément réel suivant */ - - if (!self->started) - { - self->started = true; - result = self->current; - Py_INCREF(result); - - } - else - { - next = G_ARCH_INSTRUCTION(pygobject_get(self->current)); - next = g_arch_instruction_get_next_iter(self->head, next, VMPA_MAX); - - if (next != NULL) - { - result = pygobject_new(G_OBJECT(next)); - self->current = result; - } - else result = NULL; - - } - - Py_XINCREF(result); - return (PyObject *)result; - -} - - -/****************************************************************************** -* * -* Paramètres : module = module dont la définition est à compléter. * -* * -* Description : Permet une itération de 'pychrysalide.arch.ArchInstruction'. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool register_python_arch_instruction_iterator(PyObject *module) -{ - int ret; /* Bilan d'un appel */ - - static PyTypeObject py_arch_instruction_iterator_type = { - - PyObject_HEAD_INIT(NULL) - - .tp_name = "pychrysalide.arch.ArchInstructionIterator", - .tp_basicsize = sizeof(PyArchInstructionIter), - - .tp_dealloc = (destructor)py_arch_instruction_iterator_dealloc, - - //.tp_flags = Py_TPFLAGS_HAVE_ITER | Py_TPFLAGS_HAVE_CLASS, - - .tp_doc = "PyChrysalide architecture instruction iterator", - - .tp_iter = PyObject_SelfIter, - .tp_iternext = (iternextfunc)py_arch_instruction_iterator_next - - }; - - if (PyType_Ready(&py_arch_instruction_iterator_type) < 0) - return false; - - Py_INCREF(&py_arch_instruction_iterator_type); - ret = PyModule_AddObject(module, "ArchInstructionIterator", (PyObject *)&py_arch_instruction_iterator_type); - - return (ret == 0); - -} - - - -/* ---------------------------------------------------------------------------------- */ /* INSTRUCTIONS D'ARCHITECTURES EN PYTHON */ /* ---------------------------------------------------------------------------------- */ diff --git a/src/analysis/disass/area.c b/src/analysis/disass/area.c index e57e2e0..a22f65a 100644 --- a/src/analysis/disass/area.c +++ b/src/analysis/disass/area.c @@ -861,8 +861,7 @@ mem_area *find_memory_area_by_addr(mem_area *list, size_t count, const vmpa2t *a void insert_extra_symbol_into_mem_areas(mem_area *areas, size_t count, const GBinSymbol *symbol) { SymbolType type; /* Type de symbole */ - GArchInstruction *list; /* Ensemble à insérer */ - GArchInstruction *iter; /* Boucle de parcours */ + GArchInstruction *instr; /* Instruction à insérer */ const mrange_t *range; /* Emplacement d'instruction */ const vmpa2t *addr; /* Départ de cet emplacement */ mem_area *area; /* Zone d'accueil désignée */ @@ -874,46 +873,42 @@ void insert_extra_symbol_into_mem_areas(mem_area *areas, size_t count, const GBi if (!HAS_DATA_INSTR(type)) return; - list = g_binary_symbol_get_instruction(symbol); + instr = g_binary_symbol_get_instruction(symbol); - for (iter = list; iter != NULL; iter = g_arch_instruction_get_next_iter(list, iter, ~0)) - { - range = g_arch_instruction_get_range(iter); - addr = get_mrange_addr(range); - - /* Une aire d'accueil existe-t-elle ? */ + range = g_arch_instruction_get_range(instr); + addr = get_mrange_addr(range); - area = find_memory_area_by_addr(areas, count, addr); + /* Une aire d'accueil existe-t-elle ? */ - if (area == NULL) - { - vmpa2_virt_to_string(addr, MDS_UNDEFINED, loc, NULL); + area = find_memory_area_by_addr(areas, count, addr); - log_variadic_message(LMT_WARNING, _("No place found for symbol located at %s."), loc); - continue; + if (area == NULL) + { + vmpa2_virt_to_string(addr, MDS_UNDEFINED, loc, NULL); - } + log_variadic_message(LMT_WARNING, _("No place found for symbol located at %s."), loc); + return; - /* L'instruction est-elle accueillie dans son intégralité ? */ + } - start = compute_vmpa_diff(get_mrange_addr(&area->range), addr); + /* L'instruction est-elle accueillie dans son intégralité ? */ - if (start + get_mrange_length(range) > get_mrange_length(&area->range)) - { - vmpa2_virt_to_string(addr, MDS_UNDEFINED, loc, NULL); + start = compute_vmpa_diff(get_mrange_addr(&area->range), addr); - log_variadic_message(LMT_WARNING, _("The symbol located at %s is too big for one place only."), loc); - continue; + if (start + get_mrange_length(range) > get_mrange_length(&area->range)) + { + vmpa2_virt_to_string(addr, MDS_UNDEFINED, loc, NULL); - } + log_variadic_message(LMT_WARNING, _("The symbol located at %s is too big for one place only."), loc); + return; - /* Inscription d'une instruction de symbole (sans retour arrière possible :/ ) */ + } - mark_range_in_mem_area_as_processed(area, iter, true); + /* Inscription d'une instruction de symbole (sans retour arrière possible :/ ) */ - g_object_ref(G_OBJECT(iter)); + mark_range_in_mem_area_as_processed(area, instr, true); - } + g_object_ref(G_OBJECT(instr)); } diff --git a/src/arch/instruction-int.h b/src/arch/instruction-int.h index 8679589..2d829c0 100644 --- a/src/arch/instruction-int.h +++ b/src/arch/instruction-int.h @@ -52,8 +52,6 @@ struct _GArchInstruction { GObject parent; /* A laisser en premier */ - DL_LIST_ITEM(flow); /* Maillon de liste chaînée */ - phys_t max_displayed_len; /* Quantité de code affichée */ const instr_hook_fc *hooks; /* Traitements complémentaires */ @@ -96,13 +94,5 @@ struct _GArchInstructionClass }; -#define ainstr_list_last(head) dl_list_last(head, GArchInstruction, flow) -#define ainstr_list_prev_iter(iter, head) dl_list_prev_iter(iter, head, GArchInstruction, flow) -#define ainstr_list_next_iter(iter, head) dl_list_next_iter(iter, head, GArchInstruction, flow) -#define ainstr_list_add_tail(new, head) dl_list_add_tail(new, head, GArchInstruction, flow) -#define ainstr_list_merge(head1, head2) dl_list_merge(head1, head2, GArchInstruction, flow) -#define ainstr_list_for_each(pos, head) dl_list_for_each(pos, head, GArchInstruction, flow) - - #endif /* _ARCH_INSTRUCTION_INT_H */ diff --git a/src/arch/instruction.c b/src/arch/instruction.c index 70b2819..db37bf7 100644 --- a/src/arch/instruction.c +++ b/src/arch/instruction.c @@ -122,8 +122,6 @@ static void g_arch_instruction_class_init(GArchInstructionClass *klass) static void g_arch_instruction_init(GArchInstruction *instr) { - DL_LIST_ITEM_INIT(&instr->flow); - instr->max_displayed_len = VMPA_NO_PHYSICAL; g_rw_lock_init(&instr->link_access); @@ -942,143 +940,6 @@ void g_arch_instruction_set_displayed_max_length(GArchInstruction *instr, phys_t /* ---------------------------------------------------------------------------------- */ -/* TRAITEMENT DES INSTRUCTIONS PAR ENSEMBLE */ -/* ---------------------------------------------------------------------------------- */ - - -/****************************************************************************** -* * -* Paramètres : list = liste d'instructions à compléter, ou NULL. * -* instr = nouvelle instruction à intégrer à l'ensemble. * -* * -* Description : Ajoute une instruction à un ensemble existant. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void g_arch_instruction_add_to_list(GArchInstruction **list, GArchInstruction *instr) -{ - ainstr_list_add_tail(instr, list); - -} - - -/****************************************************************************** -* * -* Paramètres : list1 = première liste à traiter. * -* list2 = seconde liste à traiter. * -* * -* Description : Fusionne deux listes d'instructions. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void g_arch_instruction_merge_lists(GArchInstruction **list1, GArchInstruction **list2) -{ - ainstr_list_merge(list1, list2); - -} - - -/****************************************************************************** -* * -* Paramètres : list = liste d'instructions à consulter. * -* : iter = position actuelle dans la liste. * -* * -* Description : Fournit l'élement suivant un autre pour un parcours. * -* * -* Retour : Elément suivant ou NULL si aucun. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GArchInstruction *g_arch_instruction_get_prev_iter(const GArchInstruction *list, const GArchInstruction *iter) -{ - GArchInstruction *result; /* Elément suivant à renvoyer */ - - result = ainstr_list_prev_iter(iter, list); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : list = liste d'instructions à consulter. * -* : iter = position actuelle dans la liste. * -* max = adresse marquant la limite (exclue) du parcours. * -* * -* Description : Fournit l'élement suivant un autre pour un parcours. * -* * -* Retour : Elément suivant ou NULL si aucun. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GArchInstruction *g_arch_instruction_get_next_iter(const GArchInstruction *list, const GArchInstruction *iter, vmpa_t max) -{ - GArchInstruction *result; /* Elément suivant à renvoyer */ - - result = ainstr_list_next_iter(iter, list); - - /* FIXME : utiliser les nouvelles adresses ! - - if (result != NULL && result->address >= max) - result = NULL; - - */ - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : list = liste de lignes à parcourir. * -* addr = position en mémoire ou physique à chercher. * -* strict = définit la considération à porter à l'adresse. * -* * -* Description : Recherche une instruction d'après son adresse. * -* * -* Retour : Instruction trouvée à l'adresse donnée, NULL si aucune. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GArchInstruction *g_arch_instruction_find_by_address(GArchInstruction *list, const vmpa2t *addr, bool strict) -{ - GArchInstruction *result; /* Trouvaille à retourner */ - bool found; /* Bilan de comparaisons */ - - ainstr_list_for_each(result, list) - { - if (strict) - found = (cmp_vmpa(get_mrange_addr(&result->range), addr) == 0); - else - found = mrange_contains_addr(&result->range, addr); - - if (found) break; - - } - - return result; - -} - - - -/* ---------------------------------------------------------------------------------- */ /* OFFRE DE CAPACITES DE GENERATION */ /* ---------------------------------------------------------------------------------- */ diff --git a/src/arch/instruction.h b/src/arch/instruction.h index 6c88e66..ffebaf3 100644 --- a/src/arch/instruction.h +++ b/src/arch/instruction.h @@ -223,25 +223,4 @@ void g_arch_instruction_set_displayed_max_length(GArchInstruction *, phys_t); -/* -------------------- TRAITEMENT DES INSTRUCTIONS PAR ENSEMBLE -------------------- */ - - -/* Ajoute une instruction à un ensemble existant. */ -void g_arch_instruction_add_to_list(GArchInstruction **, GArchInstruction *); - -/* Fusionne deux listes d'instructions. */ -void g_arch_instruction_merge_lists(GArchInstruction **, GArchInstruction **); - -/* Fournit l'élement suivant un autre pour un parcours. */ -GArchInstruction *g_arch_instruction_get_prev_iter(const GArchInstruction *, const GArchInstruction *); - -/* Fournit l'élement suivant un autre pour un parcours. */ -GArchInstruction *g_arch_instruction_get_next_iter(const GArchInstruction *, const GArchInstruction *, vmpa_t); - -/* Recherche une instruction d'après son adresse. */ -GArchInstruction *g_arch_instruction_find_by_address(GArchInstruction *, const vmpa2t *, bool) __attribute__ ((deprecated)); -/* -> g_arch_processor_find_instr_by_address */ - - - #endif /* _ARCH_INSTRUCTION_H */ -- cgit v0.11.2-87-g4458