diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2017-03-06 18:48:16 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2017-03-06 18:48:16 (GMT) |
commit | 12b8a066d1d8dd8cbef587dc6fafed870604f49f (patch) | |
tree | 3eb6cfbab886b430a8479fda9a721f75ae806a4d /src | |
parent | 0320d85e480882c58f254640a54c6c6e190dbf47 (diff) |
Locked access to instruction operands when needed.
Diffstat (limited to 'src')
-rw-r--r-- | src/analysis/db/items/switcher.c | 10 | ||||
-rw-r--r-- | src/analysis/db/items/switcher.h | 2 | ||||
-rw-r--r-- | src/analysis/disass/links.c | 23 | ||||
-rw-r--r-- | src/arch/arm/v7/fetch.c | 15 | ||||
-rw-r--r-- | src/arch/arm/v7/post.c | 13 | ||||
-rw-r--r-- | src/arch/dalvik/link.c | 8 | ||||
-rw-r--r-- | src/arch/instruction-int.h | 1 | ||||
-rw-r--r-- | src/arch/instruction.c | 147 | ||||
-rw-r--r-- | src/arch/instruction.h | 58 | ||||
-rw-r--r-- | src/arch/link.c | 24 | ||||
-rw-r--r-- | src/arch/post.c | 8 | ||||
-rw-r--r-- | src/arch/raw.c | 8 |
12 files changed, 239 insertions, 78 deletions
diff --git a/src/analysis/db/items/switcher.c b/src/analysis/db/items/switcher.c index 01c1910..9cd2a2e 100644 --- a/src/analysis/db/items/switcher.c +++ b/src/analysis/db/items/switcher.c @@ -264,7 +264,7 @@ static void g_db_switcher_finalize(GDbSwitcher *switcher) * * ******************************************************************************/ -GDbSwitcher *g_db_switcher_new(const GArchInstruction *instr, const GImmOperand *imm, ImmOperandDisplay display) +GDbSwitcher *g_db_switcher_new(GArchInstruction *instr, const GImmOperand *imm, ImmOperandDisplay display) { GDbSwitcher *result; /* Instance à retourner */ size_t count; /* Nombre d'opérandes à visiter*/ @@ -273,12 +273,16 @@ GDbSwitcher *g_db_switcher_new(const GArchInstruction *instr, const GImmOperand /* Recherche de la position de l'opérande */ - count = g_arch_instruction_count_operands(instr); + g_arch_instruction_lock_operands(instr); + + count = _g_arch_instruction_count_operands(instr); for (i = 0; i < count; i++) - if (G_ARCH_OPERAND(imm) == g_arch_instruction_get_operand(instr, i)) + if (G_ARCH_OPERAND(imm) == _g_arch_instruction_get_operand(instr, i)) break; + g_arch_instruction_unlock_operands(instr); + if (i == count) return NULL; diff --git a/src/analysis/db/items/switcher.h b/src/analysis/db/items/switcher.h index d155a13..7fda6d7 100644 --- a/src/analysis/db/items/switcher.h +++ b/src/analysis/db/items/switcher.h @@ -57,7 +57,7 @@ typedef struct _GDbSwitcherClass GDbSwitcherClass; GType g_db_switcher_get_type(void); /* Crée une définition d'un signet dans une zone de texte. */ -GDbSwitcher *g_db_switcher_new(const GArchInstruction *, const GImmOperand *, ImmOperandDisplay); +GDbSwitcher *g_db_switcher_new(GArchInstruction *, const GImmOperand *, ImmOperandDisplay); #if 0 /* Fournit l'adresse associée à un signet. */ diff --git a/src/analysis/disass/links.c b/src/analysis/disass/links.c index 0884dce..abe26d6 100644 --- a/src/analysis/disass/links.c +++ b/src/analysis/disass/links.c @@ -185,12 +185,15 @@ static void convert_immediate_into_target(GArchInstruction *instr, size_t index, vmpa2t target; /* Défination finale précise */ GArchOperand *new; /* Instruction de ciblage */ - op = g_arch_instruction_get_operand(instr, index); - if (!G_IS_IMM_OPERAND(op)) return; + op = _g_arch_instruction_get_operand(instr, index); + + if (!G_IS_IMM_OPERAND(op)) + goto ciit_done; imm = G_IMM_OPERAND(op); - if (g_imm_operand_get_display(imm) != IOD_HEX) return; + if (g_imm_operand_get_display(imm) != IOD_HEX) + goto ciit_done; if (g_imm_operand_to_virt_t(imm, &addr)) { @@ -203,12 +206,16 @@ static void convert_immediate_into_target(GArchInstruction *instr, size_t index, if (!g_target_operand_resolve(G_TARGET_OPERAND(new), format, false)) g_object_unref(G_OBJECT(new)); else - g_arch_instruction_replace_operand(instr, new, op); + _g_arch_instruction_replace_operand(instr, new, op); } } + ciit_done: + + ; + } @@ -240,14 +247,16 @@ void establish_links_for_instruction(GArchInstruction *instr, GBinFormat *format else skip = false; - count = g_arch_instruction_count_operands(instr); + g_arch_instruction_lock_operands(instr); + + count = _g_arch_instruction_count_operands(instr); for (i = 0; i < count; i++) { if (!skip) convert_immediate_into_target(instr, i, format); - op = g_arch_instruction_get_operand(instr, i); + op = _g_arch_instruction_get_operand(instr, i); if (!G_IS_TARGET_OPERAND(op)) continue; g_target_operand_get_addr(G_TARGET_OPERAND(op), &addr); @@ -262,4 +271,6 @@ void establish_links_for_instruction(GArchInstruction *instr, GBinFormat *format } + g_arch_instruction_unlock_operands(instr); + } diff --git a/src/arch/arm/v7/fetch.c b/src/arch/arm/v7/fetch.c index 15707e3..6675706 100644 --- a/src/arch/arm/v7/fetch.c +++ b/src/arch/arm/v7/fetch.c @@ -388,13 +388,16 @@ void help_fetching_with_instruction_ldr_literal_with_orig(GArchInstruction *inst break; } - op = g_arch_instruction_get_operand(instr, 1); + g_arch_instruction_lock_operands(instr); + + op = _g_arch_instruction_get_operand(instr, 1); assert(G_IS_IMM_OPERAND(op)); ret = g_imm_operand_get_value(G_IMM_OPERAND(op), MDS_32_BITS_UNSIGNED, &offset); if (!ret) { assert(0); + g_arch_instruction_unlock_operands(instr); return; } @@ -405,6 +408,7 @@ void help_fetching_with_instruction_ldr_literal_with_orig(GArchInstruction *inst if (!g_exe_format_translate_offset_into_vmpa(format, val_offset, &sym_addr)) { assert(0); + g_arch_instruction_unlock_operands(instr); return; } @@ -427,7 +431,11 @@ void help_fetching_with_instruction_ldr_literal_with_orig(GArchInstruction *inst ret = g_binary_content_read_u32(content, &pos, SRE_LITTLE /* FIXME */, &target); g_object_unref(G_OBJECT(content)); - if (!ret) return; + if (!ret) + { + g_arch_instruction_unlock_operands(instr); + return; + } /* Réalise l'intégration du symbole associé */ @@ -480,8 +488,9 @@ void help_fetching_with_instruction_ldr_literal_with_orig(GArchInstruction *inst new = g_imm_operand_new_from_value(MDS_32_BITS_UNSIGNED, target); - g_arch_instruction_replace_operand(instr, new, op); + _g_arch_instruction_replace_operand(instr, new, op); + g_arch_instruction_unlock_operands(instr); diff --git a/src/arch/arm/v7/post.c b/src/arch/arm/v7/post.c index 5ac3c62..6c63832 100644 --- a/src/arch/arm/v7/post.c +++ b/src/arch/arm/v7/post.c @@ -56,11 +56,12 @@ void post_process_ldr_instructions(GArchInstruction *instr, GArchProcessor *proc GBinRoutine *routine; /* Nouvelle routine trouvée */ GBinSymbol *symbol; /* Nouveau symbole construit */ - op = g_arch_instruction_get_operand(instr, 1); + g_arch_instruction_lock_operands(instr); + op = _g_arch_instruction_get_operand(instr, 1); - if (!G_IS_IMM_OPERAND(op)) return; - + if (!G_IS_IMM_OPERAND(op)) + goto ppli_release; if (g_imm_operand_get_value(G_IMM_OPERAND(op), MDS_32_BITS_UNSIGNED, &addr) && g_exe_format_translate_address_into_vmpa(format, addr, &target)) @@ -92,8 +93,12 @@ void post_process_ldr_instructions(GArchInstruction *instr, GArchProcessor *proc } - g_arch_instruction_replace_operand(instr, new, op); + _g_arch_instruction_replace_operand(instr, new, op); } + ppli_release: + + g_arch_instruction_unlock_operands(instr); + } diff --git a/src/arch/dalvik/link.c b/src/arch/dalvik/link.c index f92541b..d1404d0 100644 --- a/src/arch/dalvik/link.c +++ b/src/arch/dalvik/link.c @@ -101,9 +101,13 @@ void handle_dalvik_packed_switch_links(GArchInstruction *instr, GArchProcessor * char *int_val; /* Valeur en chaîne de carac. */ GDbComment *item; /* Indication sur la condition */ - assert(g_arch_instruction_count_operands(instr) == 2); + g_arch_instruction_lock_operands(instr); - op = g_arch_instruction_get_operand(instr, 1); + assert(_g_arch_instruction_count_operands(instr) == 2); + + op = _g_arch_instruction_get_operand(instr, 1); + + g_arch_instruction_unlock_operands(instr); defined = false; diff --git a/src/arch/instruction-int.h b/src/arch/instruction-int.h index 5f6758f..8dbdd18 100644 --- a/src/arch/instruction-int.h +++ b/src/arch/instruction-int.h @@ -56,6 +56,7 @@ struct _GArchInstruction GArchOperand **operands; /* Liste des opérandes */ size_t operands_count; /* Nbre. d'opérandes utilisées */ + gint operands_lock; /* Verrouillage des accès */ /** * Il existe le besoin indéniable d'un verrou pour les accès aux instructions diff --git a/src/arch/instruction.c b/src/arch/instruction.c index 7df72bf..339364f 100644 --- a/src/arch/instruction.c +++ b/src/arch/instruction.c @@ -145,6 +145,8 @@ static void g_arch_instruction_class_init(GArchInstructionClass *klass) static void g_arch_instruction_init(GArchInstruction *instr) { + instr->operands_lock = 0; + instr->from_count = 0; instr->to_count = 0; @@ -409,6 +411,91 @@ void g_arch_instruction_get_location(const GArchInstruction *instr, off_t *offse } + +/****************************************************************************** +* * +* Paramètres : instr = instruction à consulter. * +* rregs = liste des rgistres lus. [OUT] * +* rcount = nombre de registres lus. [OUT] * +* wregs = liste des rgistres écrits. [OUT] * +* wcount = nombre de registres écrits. [OUT] * +* * +* Description : Liste les registres lus et écrits par l'instruction. * +* * +* Retour : - * +* * +* Remarques : Les compteurs de références sont à décrémenter après usage ! * +* * +******************************************************************************/ + +void g_arch_instruction_get_rw_registers(const GArchInstruction *instr, GArchRegister ***rregs, size_t *rcount, GArchRegister ***wregs, size_t *wcount) +{ +#if 0 + + size_t i; /* Boucle de parcours */ + + *rregs = NULL; + *rcount = 0; + *wregs = NULL; + *wcount = 0; + + instr->get_rw_regs(instr, rregs, rcount, wregs, wcount); + + for (i = 0; i < *rcount; i++) + g_object_ref(G_OBJECT((*rregs)[i])); + + for (i = 0; i < *wcount; i++) + g_object_ref(G_OBJECT((*wregs)[i])); + +#endif + +} + + + +/* ---------------------------------------------------------------------------------- */ +/* MANIPULATION DES OPERANDES */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : instr = instruction à mettre à jour. * +* * +* Description : Verrouille les accès la liste des opérandes. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_arch_instruction_lock_operands(GArchInstruction *instr) +{ + g_bit_lock(&instr->operands_lock, 0); + +} + + +/****************************************************************************** +* * +* Paramètres : instr = instruction à mettre à jour. * +* * +* Description : Déverrouille les accès la liste des opérandes. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_arch_instruction_unlock_operands(GArchInstruction *instr) +{ + g_bit_unlock(&instr->operands_lock, 0); + +} + + /****************************************************************************** * * * Paramètres : instr = instance à mettre à jour. * @@ -424,11 +511,15 @@ void g_arch_instruction_get_location(const GArchInstruction *instr, off_t *offse void g_arch_instruction_attach_extra_operand(GArchInstruction *instr, GArchOperand *operand) { + g_arch_instruction_lock_operands(instr); + instr->operands_count++; instr->operands = (GArchOperand **)realloc(instr->operands, instr->operands_count * sizeof(GArchOperand *)); instr->operands[instr->operands_count - 1] = operand; + g_arch_instruction_unlock_operands(instr); + } @@ -444,8 +535,10 @@ void g_arch_instruction_attach_extra_operand(GArchInstruction *instr, GArchOpera * * ******************************************************************************/ -size_t g_arch_instruction_count_operands(const GArchInstruction *instr) +size_t _g_arch_instruction_count_operands(const GArchInstruction *instr) { + assert(instr->operands_lock != 0); + return instr->operands_count; } @@ -464,10 +557,12 @@ size_t g_arch_instruction_count_operands(const GArchInstruction *instr) * * ******************************************************************************/ -GArchOperand *g_arch_instruction_get_operand(const GArchInstruction *instr, size_t index) +GArchOperand *_g_arch_instruction_get_operand(const GArchInstruction *instr, size_t index) { GArchOperand *result; /* Opérande à retourner */ + assert(instr->operands_lock != 0); + if (index >= instr->operands_count) result = NULL; else result = instr->operands[index]; @@ -492,10 +587,12 @@ GArchOperand *g_arch_instruction_get_operand(const GArchInstruction *instr, size * * ******************************************************************************/ -void g_arch_instruction_replace_operand(GArchInstruction *instr, GArchOperand *new, const GArchOperand *old) +void _g_arch_instruction_replace_operand(GArchInstruction *instr, GArchOperand *new, const GArchOperand *old) { size_t i; /* Boucle de parcours */ + assert(instr->operands_lock != 0); + for (i = 0; i < instr->operands_count; i++) if (instr->operands[i] == old) break; @@ -522,10 +619,12 @@ void g_arch_instruction_replace_operand(GArchInstruction *instr, GArchOperand *n * * ******************************************************************************/ -void g_arch_instruction_detach_operand(GArchInstruction *instr, GArchOperand *operand) +void _g_arch_instruction_detach_operand(GArchInstruction *instr, GArchOperand *operand) { size_t i; /* Boucle de parcours */ + assert(instr->operands_lock != 0); + for (i = 0; i < instr->operands_count; i++) if (instr->operands[i] == operand) break; @@ -540,46 +639,6 @@ void g_arch_instruction_detach_operand(GArchInstruction *instr, GArchOperand *op } -/****************************************************************************** -* * -* Paramètres : instr = instruction à consulter. * -* rregs = liste des rgistres lus. [OUT] * -* rcount = nombre de registres lus. [OUT] * -* wregs = liste des rgistres écrits. [OUT] * -* wcount = nombre de registres écrits. [OUT] * -* * -* Description : Liste les registres lus et écrits par l'instruction. * -* * -* Retour : - * -* * -* Remarques : Les compteurs de références sont à décrémenter après usage ! * -* * -******************************************************************************/ - -void g_arch_instruction_get_rw_registers(const GArchInstruction *instr, GArchRegister ***rregs, size_t *rcount, GArchRegister ***wregs, size_t *wcount) -{ -#if 0 - - size_t i; /* Boucle de parcours */ - - *rregs = NULL; - *rcount = 0; - *wregs = NULL; - *wcount = 0; - - instr->get_rw_regs(instr, rregs, rcount, wregs, wcount); - - for (i = 0; i < *rcount; i++) - g_object_ref(G_OBJECT((*rregs)[i])); - - for (i = 0; i < *wcount; i++) - g_object_ref(G_OBJECT((*wregs)[i])); - -#endif - -} - - /* ---------------------------------------------------------------------------------- */ /* DEFINITION DES LIAISONS ENTRE INSTRUCTIONS */ diff --git a/src/arch/instruction.h b/src/arch/instruction.h index 6388f94..fad6c72 100644 --- a/src/arch/instruction.h +++ b/src/arch/instruction.h @@ -123,23 +123,67 @@ void g_arch_instruction_get_location(const GArchInstruction *, off_t *, off_t *, +/* Liste les registres lus et écrits par l'instruction. */ +void g_arch_instruction_get_rw_registers(const GArchInstruction *, GArchRegister ***, size_t *, GArchRegister ***, size_t *) __attribute__ ((deprecated)); + + + +/* --------------------------- MANIPULATION DES OPERANDES --------------------------- */ + + +/* Verrouille les accès la liste des opérandes. */ +void g_arch_instruction_lock_operands(GArchInstruction *); + +/* Déverrouille les accès la liste des opérandes. */ +void g_arch_instruction_unlock_operands(GArchInstruction *); + /* Attache un opérande supplémentaire à une instruction. */ void g_arch_instruction_attach_extra_operand(GArchInstruction *, GArchOperand *); /* Indique la quantité d'opérandes présents dans l'instruction. */ -size_t g_arch_instruction_count_operands(const GArchInstruction *); +size_t _g_arch_instruction_count_operands(const GArchInstruction *); /* Fournit un opérande donné d'une instruction. */ -GArchOperand *g_arch_instruction_get_operand(const GArchInstruction *, size_t); +GArchOperand *_g_arch_instruction_get_operand(const GArchInstruction *, size_t); /* Remplace un opérande d'une instruction par un autre. */ -void g_arch_instruction_replace_operand(GArchInstruction *, GArchOperand *, const GArchOperand *); +void _g_arch_instruction_replace_operand(GArchInstruction *, GArchOperand *, const GArchOperand *); /* Détache un opérande liée d'une instruction. */ -void g_arch_instruction_detach_operand(GArchInstruction *, GArchOperand *); - -/* Liste les registres lus et écrits par l'instruction. */ -void g_arch_instruction_get_rw_registers(const GArchInstruction *, GArchRegister ***, size_t *, GArchRegister ***, size_t *) __attribute__ ((deprecated)); +void _g_arch_instruction_detach_operand(GArchInstruction *, GArchOperand *); + + +#define g_arch_instruction_count_operands(ins) \ + ({ \ + size_t __result; \ + g_arch_instruction_lock_operands(ins); \ + __result = _g_arch_instruction_count_operands(ins); \ + g_arch_instruction_unlock_operands(ins); \ + __result; \ + }) + +#define g_arch_instruction_get_operand(ins, idx) \ + ({ \ + GArchOperand *__result; \ + g_arch_instruction_lock_operands(ins); \ + __result = _g_arch_instruction_get_operand(ins, idx); \ + g_arch_instruction_unlock_operands(ins); \ + __result; \ + }) + +#define g_arch_instruction_replace_operand(ins, n, o) \ + ({ \ + g_arch_instruction_lock_operands(ins); \ + _g_arch_instruction_replace_operand(ins, n, o); \ + g_arch_instruction_unlock_operands(ins); \ + }) + +#define g_arch_instruction_detach_operand(ins, o) \ + ({ \ + g_arch_instruction_lock_operands(ins); \ + _g_arch_instruction_detach_operand(ins, o); \ + g_arch_instruction_unlock_operands(ins); \ + }) diff --git a/src/arch/link.c b/src/arch/link.c index dfc2bd5..fbcd391 100644 --- a/src/arch/link.c +++ b/src/arch/link.c @@ -53,9 +53,13 @@ void handle_jump_as_link(GArchInstruction *instr, GArchProcessor *proc, GProcCon vmpa2t addr; /* Adresse de destination */ GArchInstruction *target; /* Ligne visée par la référence*/ - assert(g_arch_instruction_count_operands(instr) > 0); + g_arch_instruction_lock_operands(instr); - op = g_arch_instruction_get_operand(instr, 0); + assert(_g_arch_instruction_count_operands(instr) > 0); + + op = _g_arch_instruction_get_operand(instr, 0); + + g_arch_instruction_unlock_operands(instr); if (!G_IS_IMM_OPERAND(op)) return; @@ -102,9 +106,13 @@ void handle_branch_as_link(GArchInstruction *instr, GArchProcessor *proc, GProcC const mrange_t *range; /* Emplacement d'instruction */ vmpa2t next; /* Position suivante */ - assert(g_arch_instruction_count_operands(instr) > index); + g_arch_instruction_lock_operands(instr); + + assert(_g_arch_instruction_count_operands(instr) > index); - op = g_arch_instruction_get_operand(instr, index); + op = _g_arch_instruction_get_operand(instr, index); + + g_arch_instruction_unlock_operands(instr); defined = false; @@ -175,9 +183,13 @@ void handle_call_as_link(GArchInstruction *instr, GArchProcessor *proc, GProcCon vmpa2t addr; /* Adresse de destination */ GArchInstruction *target; /* Ligne visée par la référence*/ - assert(g_arch_instruction_count_operands(instr) > 0); + g_arch_instruction_lock_operands(instr); + + assert(_g_arch_instruction_count_operands(instr) > 0); + + op = _g_arch_instruction_get_operand(instr, 0); - op = g_arch_instruction_get_operand(instr, 0); + g_arch_instruction_unlock_operands(instr); if (!G_IS_IMM_OPERAND(op)) return; diff --git a/src/arch/post.c b/src/arch/post.c index 59ed40e..babe6a9 100644 --- a/src/arch/post.c +++ b/src/arch/post.c @@ -63,7 +63,9 @@ void post_process_target_resolution(GArchInstruction *instr, GArchProcessor *pro GBinRoutine *routine; /* Nouvelle routine trouvée */ GBinSymbol *symbol; /* Nouveau symbole construit */ - op = g_arch_instruction_get_operand(instr, index); + g_arch_instruction_lock_operands(instr); + + op = _g_arch_instruction_get_operand(instr, index); assert(G_IS_IMM_OPERAND(op)); if (g_imm_operand_to_virt_t(G_IMM_OPERAND(op), &addr) @@ -109,8 +111,10 @@ void post_process_target_resolution(GArchInstruction *instr, GArchProcessor *pro } - g_arch_instruction_replace_operand(instr, new, op); + _g_arch_instruction_replace_operand(instr, new, op); } + g_arch_instruction_unlock_operands(instr); + } diff --git a/src/arch/raw.c b/src/arch/raw.c index 63dadab..f22645f 100644 --- a/src/arch/raw.c +++ b/src/arch/raw.c @@ -512,6 +512,8 @@ static void g_raw_instruction_print(GRawInstruction *instr, GBufferLine *line, s first = true; + g_arch_instruction_lock_operands(base); + for (i = 0; i < base->operands_count; i++) { status = g_imm_operand_get_value(G_IMM_OPERAND(base->operands[i]), MDS_8_BITS, &byte); @@ -558,6 +560,8 @@ static void g_raw_instruction_print(GRawInstruction *instr, GBufferLine *line, s } + g_arch_instruction_unlock_operands(base); + /* Si une chaîne reste encore */ if (iter > 1) { @@ -581,6 +585,8 @@ static void g_raw_instruction_print(GRawInstruction *instr, GBufferLine *line, s else { + g_arch_instruction_lock_operands(base); + if (base->operands_count > 0) { g_arch_operand_print(base->operands[0], line, 0/*syntax*/); @@ -596,6 +602,8 @@ static void g_raw_instruction_print(GRawInstruction *instr, GBufferLine *line, s } + g_arch_instruction_unlock_operands(base); + } } |