summaryrefslogtreecommitdiff
path: root/src/analysis/disass
diff options
context:
space:
mode:
Diffstat (limited to 'src/analysis/disass')
-rw-r--r--src/analysis/disass/area.c20
1 files changed, 14 insertions, 6 deletions
diff --git a/src/analysis/disass/area.c b/src/analysis/disass/area.c
index 84103e0..7eacc29 100644
--- a/src/analysis/disass/area.c
+++ b/src/analysis/disass/area.c
@@ -314,6 +314,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 i; /* Boucle de parcours */
+ GArchInstruction *old; /* Instruction remplacée */
start = get_mrange_addr(&area->range);
@@ -333,8 +335,6 @@ static bool mark_range_in_mem_area_as_processed(mem_area *area, GArchInstruction
{
assert(area->instructions[offset] == NULL || force);
-#ifndef NDEBUG
-
/**
* Un cas de remplacement forcé intervient en ARM, lorsque qu'une
* instruction utilise une valeur immédiate placée dans le code.
@@ -347,14 +347,22 @@ static bool mark_range_in_mem_area_as_processed(mem_area *area, GArchInstruction
* C'est par exemple le cas lors de l'utilisation d'appels système
* en assembleur, qui ne sont pas reconnus en tant qu'instructions
* cassant le flot d'exécution (typiquement : un exit()).
+ *
+ * On réinitialise donc la zone couverte par la nouvelle instruction.
*/
- if (area->instructions[offset] != NULL)
+ for (i = 0; force && i < len; i++)
{
- range = g_arch_instruction_get_range(area->instructions[offset]);
- assert(len == get_mrange_length(range));
+ old = area->instructions[offset + i];
+
+ if (old != NULL)
+ {
+ g_object_unref(G_OBJECT(old));
+ area->instructions[offset + 1] = NULL;
+ g_atomic_pointer_add(&area->count, -1);
+ }
+
}
-#endif
area->instructions[offset] = instr;
g_atomic_pointer_add(&area->count, 1);