diff options
-rw-r--r-- | ChangeLog | 5 | ||||
-rw-r--r-- | src/analysis/disass/area.c | 33 |
2 files changed, 34 insertions, 4 deletions
@@ -1,3 +1,8 @@ +17-08-05 Cyrille Bagard <nocbos@gmail.com> + + * src/analysis/disass/area.c: + Handle any partial replaced instruction when replacing instructions. + 17-07-28 Cyrille Bagard <nocbos@gmail.com> * src/gtkext/easygtk.c: diff --git a/src/analysis/disass/area.c b/src/analysis/disass/area.c index 06893ff..9a5387c 100644 --- a/src/analysis/disass/area.c +++ b/src/analysis/disass/area.c @@ -372,6 +372,8 @@ static bool mark_range_in_mem_area_as_processed(mem_area *area, GArchInstruction const vmpa2t *addr; /* Début de la zone à traiter */ phys_t len; /* Taille de l'aire visée */ phys_t offset; /* Décallage de départ */ + phys_t coverage_start; /* Début de zone à vider */ + phys_t coverage_len; /* Taille de cette même zone */ phys_t i; /* Boucle de parcours */ GArchInstruction *old; /* Instruction remplacée */ const mrange_t *old_range; /* Emplacement de l'instruction*/ @@ -445,19 +447,42 @@ static bool mark_range_in_mem_area_as_processed(mem_area *area, GArchInstruction * On réinitialise donc la zone couverte par la nouvelle instruction. */ - for (i = 0; i < len; i++) + coverage_start = offset; + coverage_len = len; + + /** + * Par ailleurs, il se peut que la nouvelle instruction ne couvre + * que partiellement une instruction existante. + * + * Il faut donc dans ce cas remonter la table des enregistrements + * pour retrouver l'instruction à l'origine de la couverture à remplacer. + */ + + while (area->instructions[coverage_start] == NULL) + { + if (coverage_start == 0) + break; + + coverage_start--; + coverage_len++; + + } + + assert(area->instructions[coverage_start] != NULL); + + for (i = 0; i < coverage_len; i++) { - old = area->instructions[offset + i]; + old = area->instructions[coverage_start + i]; if (old != NULL) { old_range = g_arch_instruction_get_range(old); old_len = get_mrange_length(old_range); - reset_in_bit_field(area->processed, offset + i, old_len); + reset_in_bit_field(area->processed, coverage_start + i, old_len); g_object_unref(G_OBJECT(old)); - area->instructions[offset + i] = NULL; + area->instructions[coverage_start + i] = NULL; g_atomic_pointer_add(&area->count, -1); |