From 141d2f0fbb2ce3b4ddf85383c55b891fd59dc598 Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Sat, 24 Jan 2015 11:19:32 +0000 Subject: Introduced conditional calls in instruction definition rules. git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@459 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a --- ChangeLog | 82 +++ src/analysis/disass/area.c | 116 +++- src/analysis/disass/fetch.c | 17 + src/arch/arm/v456/instruction.c | 2 +- src/arch/arm/v7/context.c | 48 +- src/arch/arm/v7/context.h | 15 + src/arch/arm/v7/link.c | 242 ++++++- src/arch/arm/v7/link.h | 33 + src/arch/arm/v7/opdefs/Makefile.am | 1 + src/arch/arm/v7/opdefs/b_A8818.d | 45 ++ src/arch/arm/v7/opdefs/bl_A8825.d | 32 +- src/arch/arm/v7/opdefs/blx_A8826.d | 2 + src/arch/arm/v7/opdefs/bx_A8827.d | 12 + src/arch/arm/v7/opdefs/cbnz_A8829.d | 14 + src/arch/arm/v7/opdefs/ldr_A8862.d | 3 + src/arch/arm/v7/opdefs/ldr_A8863.d | 2 + src/arch/arm/v7/opdefs/ldr_A8864.d | 32 +- src/arch/arm/v7/opdefs/ldr_A8865.d | 1 + src/arch/arm/v7/opdefs/ldrb_A8867.d | 3 + src/arch/arm/v7/post.c | 189 ++++++ src/arch/arm/v7/post.h | 9 + src/arch/arm/v7/processor.c | 7 +- src/arch/artificial.c | 23 - src/arch/dalvik/instruction.c | 2 +- src/arch/instruction-int.h | 9 +- src/arch/instruction.c | 26 +- src/arch/instruction.h | 3 + src/arch/x86/instruction.c | 2 +- tools/d2c/Makefile.am | 2 + tools/d2c/args.c | 1161 ++++++++++++++++++++++++++++++++ tools/d2c/args.h | 131 ++++ tools/d2c/conv.c | 1251 ++--------------------------------- tools/d2c/conv.h | 98 +-- tools/d2c/d2c_gram.y | 69 +- tools/d2c/d2c_tok.l | 51 +- tools/d2c/qckcall.c | 110 +++ tools/d2c/qckcall.h | 44 ++ tools/d2c/rules.c | 96 ++- tools/d2c/rules.h | 32 +- tools/d2c/spec.c | 13 +- 40 files changed, 2619 insertions(+), 1411 deletions(-) create mode 100644 tools/d2c/args.c create mode 100644 tools/d2c/args.h create mode 100644 tools/d2c/qckcall.c create mode 100644 tools/d2c/qckcall.h diff --git a/ChangeLog b/ChangeLog index f730ae1..68a0145 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,85 @@ +15-01-24 Cyrille Bagard + + * src/analysis/disass/area.c: + Try to better follow the execution flow. + + * src/analysis/disass/fetch.c: + Add some extra entry points. They are fixed, so this needs to be improved. + + * src/arch/arm/v456/instruction.c: + Disable some old code. + + * src/arch/arm/v7/context.c: + * src/arch/arm/v7/context.h: + Provide a way to create new drop points and memorize their encodings. + + * src/arch/arm/v7/link.c: + * src/arch/arm/v7/link.h: + Handle more instructions: b, cb[n]z and ldr. + + * src/arch/arm/v7/opdefs/b_A8818.d: + * src/arch/arm/v7/opdefs/bl_A8825.d: + * src/arch/arm/v7/opdefs/blx_A8826.d: + * src/arch/arm/v7/opdefs/bx_A8827.d: + * src/arch/arm/v7/opdefs/cbnz_A8829.d: + * src/arch/arm/v7/opdefs/ldr_A8862.d: + * src/arch/arm/v7/opdefs/ldr_A8863.d: + * src/arch/arm/v7/opdefs/ldr_A8864.d: + * src/arch/arm/v7/opdefs/ldr_A8865.d: + * src/arch/arm/v7/opdefs/ldrb_A8867.d: + Update hooks and rules. + + * src/arch/arm/v7/opdefs/Makefile.am: + Register the 'DefineAsReturn' macro in D2C_MACROS. + + * src/arch/arm/v7/post.c: + * src/arch/arm/v7/post.h: + Handle more instructions: b, cb[n]z and ldr. + + * src/arch/arm/v7/processor.c: + Do not create a dummy instruction when decoding failed anymore. + + * src/arch/artificial.c: + Remove the old 'g_db_instruction_is_return()' function. + + * src/arch/dalvik/instruction.c: + Disable some old code. + + * src/arch/instruction.c: + * src/arch/instruction.h: + * src/arch/instruction-int.h: + Change the way an instruction gives information about its 'return'-like + behavior property. + + * src/arch/x86/instruction.c: + Disable some old code. + + * tools/d2c/args.c: + * tools/d2c/args.h: + New entries: handle expressions used as call arguments. + + * tools/d2c/conv.c: + * tools/d2c/conv.h: + Update code by using new arguments. + + * tools/d2c/d2c_gram.y: + * tools/d2c/d2c_tok.l: + Introduce conditional calls in instruction definition rules. + + * tools/d2c/Makefile.am: + Add the new 'args.[ch]' and 'qckcall.[ch]' files into d2c_SOURCES. + + * tools/d2c/qckcall.c: + * tools/d2c/qckcall.h: + New entries: provide a way to call functions and manage associated casts. + + * tools/d2c/rules.c: + * tools/d2c/rules.h: + Introduce conditional calls in instruction definition rules. + + * tools/d2c/spec.c: + Update code. + 15-01-18 Cyrille Bagard * src/arch/arm/v7/opdefs/Makefile.am: diff --git a/src/analysis/disass/area.c b/src/analysis/disass/area.c index 8c46eb0..7e3a9a8 100644 --- a/src/analysis/disass/area.c +++ b/src/analysis/disass/area.c @@ -28,8 +28,6 @@ - - /* Zone mémoire bien bornée */ typedef struct _mem_area { @@ -49,10 +47,6 @@ typedef struct _mem_area } mem_area; - - - - /* Initialise une aire de données à partir d'une adresse donnée. */ static void init_mem_area_from_addr(mem_area *, const vmpa2t *, phys_t); @@ -381,6 +375,14 @@ void load_code_from_mem_area(mem_area *area, mem_area *list, size_t count, const //printf(" [%p] CODE start @ %u (len=%u)\n", area, (unsigned int)diff, (unsigned int)alen); + + + printf(" START @ 0x%08x\n", (unsigned int)get_virt_addr(&pos)); + + + bin_length = (get_phy_addr(get_mrange_addr(&area->range)) + alen); + + for (i = diff; i < alen; i += diff) { //il y a eu un point d'entrée... -> STOP @@ -418,6 +420,26 @@ void load_code_from_mem_area(mem_area *area, mem_area *list, size_t count, const assert(!is_range_blank_in_mem_areas(list, count, &range)); + + + + printf(" --disass-- '%s' @ 0x%08x (break=%d)\n", + g_arch_instruction_get_keyword(instr, 0), + (unsigned int)get_virt_addr(&prev), + g_arch_instruction_is_return(instr)); + + + + + if (g_arch_instruction_is_return(instr)) + printf("BREAK @ 0x%08x\n", (unsigned int)get_virt_addr(&prev)); + + //continue; + + /* Rupture du flot d'exécution ? */ + if (g_arch_instruction_is_return(instr)) + break; + } @@ -485,8 +507,9 @@ static void load_data_from_mem_area(mem_area *area, mem_area *list, size_t count advance_vmpa(&pos, diff); /* - printf(" [%p] DATA start @ 0x%08x -> %u (len=%u)\n", - area, (unsigned int)get_phy_addr(&pos), (unsigned int)diff, (unsigned int)alen); + printf(" [%p] DATA start @ 0x%08x -> %u (len=%u) => 0x%08x <-> 0x%08x\n", + area, (unsigned int)get_phy_addr(&pos), (unsigned int)diff, (unsigned int)alen, + (unsigned int)get_virt_addr(&pos), (unsigned int)(get_virt_addr(&pos) + alen)); */ for (i = diff; i < alen; i += diff) @@ -496,7 +519,7 @@ static void load_data_from_mem_area(mem_area *area, mem_area *list, size_t count copy_vmpa(&prev, &pos); instr = NULL; - + /* if (instr == NULL && (i + 4) <= alen) { init_mrange(&range, &pos, 4); @@ -505,7 +528,7 @@ static void load_data_from_mem_area(mem_area *area, mem_area *list, size_t count instr = g_raw_instruction_new_array(bin_data, MDS_32_BITS, 1, &pos, bin_length, endianness); } - + */ if (instr == NULL && (i + 2) <= alen) { copy_vmpa(&pos, &prev); @@ -525,10 +548,29 @@ static void load_data_from_mem_area(mem_area *area, mem_area *list, size_t count instr = g_raw_instruction_new_array(bin_data, MDS_8_BITS, 1, &pos, bin_length, endianness); else { - printf(" break !! 0x%08x\n", - (unsigned int)get_phy_addr(&pos)); - assert(0); - break; + /** + * On rencontre ici un morceau déjà traité. + * On recherche donc la fin de cette partie à sauter, si elle existe. + */ + + ////////////// + return; + + + + for (i++; i < alen; i++) + { + advance_vmpa(&pos, 1); + init_mrange(&range, &pos, 1); + + if (is_range_blank_in_mem_areas(list, count, &range)) + break; + + } + + diff = 0; + continue; + } } @@ -551,6 +593,12 @@ static void load_data_from_mem_area(mem_area *area, mem_area *list, size_t count assert(!is_range_blank_in_mem_areas(list, count, &range)); + + + if (area->exec) break; + + + } } @@ -579,11 +627,14 @@ static void fill_mem_area(mem_area *area, mem_area *list, size_t count, const GL phys_t i; /* Boucle de parcours */ vmpa2t start; /* Adresse de départ de combles*/ - /* - printf(" === FILLING | 0x%08x (%u)...\n", + bool on = true; + + + printf(" === FILLING | 0x%08x // 0x%08x <-> 0x%08x...\n", (unsigned int)get_phy_addr(get_mrange_addr(&area->range)), - (unsigned int)get_phy_addr(get_mrange_addr(&area->range))); - */ + (unsigned int)get_virt_addr(get_mrange_addr(&area->range)), + (unsigned int)(get_virt_addr(get_mrange_addr(&area->range)) + get_mrange_length(&area->range))); + /* Les symboles se doivent d'être indépendants ! */ if (area->has_sym) return; @@ -597,14 +648,29 @@ static void fill_mem_area(mem_area *area, mem_area *list, size_t count, const GL copy_vmpa(&start, get_mrange_addr(&area->range)); advance_vmpa(&start, i); - if (area->exec) + if (area->exec && get_virt_addr(&start) % 4 == 0) + { load_code_from_mem_area(area, list, count, binary, ctx, &start, info); + if (!is_range_blank_in_mem_area(area, i, 1, NULL)) + { + printf(" --filled-- @ 0x%08x\n", (unsigned int)get_virt_addr(&start)); + on = false; + } + else + printf(" --fill failed-- @ 0x%08x\n", (unsigned int)get_virt_addr(&start)); + + + } + if (is_range_blank_in_mem_area(area, i, 1, NULL)) load_data_from_mem_area(area, list, count, binary, ctx, &start, info); } + + else on = true; + if (is_range_blank_in_mem_area(area, i, 1, NULL)) printf(" [%p] error with %u\n", area, (unsigned int)i); @@ -1134,6 +1200,18 @@ static bool handle_bytes_map_in_mem_area(mem_area *list, size_t count, const mra else { + + printf("BUG_ON | off=%u remaining=%u length=%u\n", + (unsigned int)offset, + (unsigned int)remaining, + (unsigned int)get_mrange_length(&area->range)); + + printf("BUG_ON @ 0x%08x + %d\n", + (unsigned int)get_virt_addr(get_mrange_addr(range)), + (int)get_mrange_length(range) + ); + + assert(0); /* Traitement de la fin de la première aire */ diff --git a/src/analysis/disass/fetch.c b/src/analysis/disass/fetch.c index 2e9eb81..ffc653a 100644 --- a/src/analysis/disass/fetch.c +++ b/src/analysis/disass/fetch.c @@ -58,6 +58,8 @@ static void follow_execution_flow(const GLoadedBinary *binary, GProcContext *ctx vmpa2t addr; /* Conversion en pleine adresse*/ mem_area *area; /* Zone de désassemblage */ + printf("-- follow 0x%08x\n", (unsigned int)virt); + g_proc_context_push_drop_point(ctx, virt); while (g_proc_context_has_drop_points(ctx)) @@ -65,10 +67,20 @@ static void follow_execution_flow(const GLoadedBinary *binary, GProcContext *ctx virt = g_proc_context_pop_drop_point(ctx); init_vmpa(&addr, VMPA_NO_PHYSICAL, virt); + + + printf(" ++ point 0x%08x\n", (unsigned int)virt); + + area = find_memory_area_by_addr(areas, count, &addr); load_code_from_mem_area(area, areas, count, binary, ctx, &addr, info); + + + printf(" ++\n"); + + } } @@ -128,6 +140,9 @@ GArchInstruction *disassemble_binary_content(const GLoadedBinary *binary, GtkExt virt = g_binary_format_get_entry_point(format); + follow_execution_flow(binary, ctx, areas, count, info, 0x84c5); + follow_execution_flow(binary, ctx, areas, count, info, 0x8a65); + follow_execution_flow(binary, ctx, areas, count, info, virt); /* Symboles exécutables présents et passés à travers les mailles */ @@ -147,6 +162,8 @@ GArchInstruction *disassemble_binary_content(const GLoadedBinary *binary, GtkExt } + printf(" ------------------------------------------- follow done\n"); + done = get_current_progessive_status(info); fini_progessive_status(info); diff --git a/src/arch/arm/v456/instruction.c b/src/arch/arm/v456/instruction.c index b5df0f8..4fc78a2 100644 --- a/src/arch/arm/v456/instruction.c +++ b/src/arch/arm/v456/instruction.c @@ -399,7 +399,7 @@ static void g_dalvik_instruction_init(GDalvikInstruction *instr) parent->get_rw_regs = (get_instruction_rw_regs_fc)g_dalvik_instruction_get_rw_registers; parent->get_text = (get_instruction_text_fc)dalvik_get_instruction_text; parent->get_link = (get_instruction_link_fc)dalvik_get_instruction_link; - parent->is_return = (is_instruction_return_fc)dalvik_instruction_is_return; + //parent->is_return = (is_instruction_return_fc)dalvik_instruction_is_return; parent->decomp = (decomp_instr_fc)dalvik_instruction_decompile; } diff --git a/src/arch/arm/v7/context.c b/src/arch/arm/v7/context.c index 41ffd29..c29794d 100644 --- a/src/arch/arm/v7/context.c +++ b/src/arch/arm/v7/context.c @@ -24,6 +24,9 @@ #include "context.h" +#include + + #include "../context-int.h" @@ -208,7 +211,7 @@ static void g_armv7_context_push_drop_point(GArmV7Context *ctx, virt_t addr) { - printf("PUSH v7 !!\n"); + printf("PUSH v7 !! 0x%08x\n", addr); @@ -224,6 +227,47 @@ static void g_armv7_context_push_drop_point(GArmV7Context *ctx, virt_t addr) } +/****************************************************************************** +* * +* Paramètres : ctx = contexte de désassemblage à compléter. * +* addr = adresse d'un nouveau point de départ à traiter. * +* * +* Description : Ajoute une adresse virtuelle comme point de départ de code. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_armv7_context_push_drop_point_ext(GArmV7Context *ctx, virt_t addr, ArmV7InstrSet marker) +{ + + + printf("PUSH v7 !! 0x%08x\n", (unsigned int)addr); + + + + if (addr & 0x1) + { + addr -= 0x1; + assert(marker == AV7IS_THUMB); + } + + + g_armv7_context_define_encoding(ctx, addr, marker); + + G_PROC_CONTEXT_CLASS(g_armv7_context_parent_class)->push_point(G_PROC_CONTEXT(ctx), addr); + +} + + + + + + + + /****************************************************************************** @@ -242,6 +286,8 @@ static void g_armv7_context_push_drop_point(GArmV7Context *ctx, virt_t addr) void g_armv7_context_define_encoding(GArmV7Context *ctx, virt_t addr, ArmV7InstrSet marker) { + printf(" --encoding-- @ 0x%08llx -> %d\n", (unsigned long long)addr, (int)marker); + _g_arm_context_define_encoding(G_ARM_CONTEXT(ctx), addr, marker); } diff --git a/src/arch/arm/v7/context.h b/src/arch/arm/v7/context.h index 65b5302..a4d99d6 100644 --- a/src/arch/arm/v7/context.h +++ b/src/arch/arm/v7/context.h @@ -79,4 +79,19 @@ ArmV7InstrSet g_armv7_context_find_encoding(GArmV7Context *, virt_t); + + + + + + + + +void g_armv7_context_push_drop_point_ext(GArmV7Context *ctx, virt_t addr, ArmV7InstrSet marker); + + + + + + #endif /* _ARCH_ARM_V7_CONTEXT_H */ diff --git a/src/arch/arm/v7/link.c b/src/arch/arm/v7/link.c index fff0944..c1f83ac 100644 --- a/src/arch/arm/v7/link.c +++ b/src/arch/arm/v7/link.c @@ -25,6 +25,7 @@ #include +#include @@ -43,6 +44,54 @@ * * ******************************************************************************/ +void handle_links_with_instruction_b_with_orig(GArchInstruction *instr, GArmV7Context *context, GBinFormat *format, ArmV7InstrSet iset) +{ + const mrange_t *range; /* Emplacementt d'instruction */ + virt_t pc; /* Position dans l'exécution */ + GArchOperand *op; /* Opérande numérique en place */ + int32_t offset; /* Décallage encodé en dur */ + virt_t target; /* Adresse virtuelle visée */ + + range = g_arch_instruction_get_range(instr); + + pc = get_virt_addr(get_mrange_addr(range)); + + pc += get_mrange_length(range); + + op = g_arch_instruction_get_operand(instr, 0); + + if (g_imm_operand_get_value(G_IMM_OPERAND(op), MDS_32_BITS_SIGNED, &offset)) + g_imm_operand_set_value(G_IMM_OPERAND(op), MDS_32_BITS_UNSIGNED, pc + offset); + + else assert(0); + + printf("1... 0x%x (0x%x) + 0x%x\n", + (unsigned int)get_virt_addr(get_mrange_addr(range)), + (unsigned int)pc, (unsigned int)offset); + + target = pc + offset; + + //g_armv7_context_define_encoding(context, target, iset); + g_armv7_context_push_drop_point_ext(context, target, iset); + +} + + +/****************************************************************************** +* * +* Paramètres : instr = instruction ARMv7 à traiter. * +* context = contexte associé à la phase de désassemblage. * +* format = acès aux données du binaire d'origine. * +* iset = type de jeu d'instructions courant à faire suivre. * +* * +* Description : Complète un désassemblage accompli pour une instruction. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + void handle_links_with_instruction_bl_with_orig(GArchInstruction *instr, GArmV7Context *context, GBinFormat *format, ArmV7InstrSet iset) { const mrange_t *range; /* Emplacementt d'instruction */ @@ -69,9 +118,18 @@ void handle_links_with_instruction_bl_with_orig(GArchInstruction *instr, GArmV7C if (g_imm_operand_get_value(G_IMM_OPERAND(op), MDS_32_BITS_SIGNED, &offset)) g_imm_operand_set_value(G_IMM_OPERAND(op), MDS_32_BITS_UNSIGNED, pc + offset); + else assert(0); + + printf("2... 0x%x (0x%x) + 0x%x\n", + (unsigned int)get_virt_addr(get_mrange_addr(range)), + (unsigned int)pc, (unsigned int)offset); + + + target = pc + offset; - g_armv7_context_define_encoding(context, target, iset); + //g_armv7_context_define_encoding(context, target, iset); + g_armv7_context_push_drop_point_ext(context, target, iset); } @@ -118,8 +176,188 @@ void handle_links_with_instruction_blx_with_dest(GArchInstruction *instr, GArmV7 if (g_imm_operand_get_value(G_IMM_OPERAND(op), MDS_32_BITS_SIGNED, &offset)) g_imm_operand_set_value(G_IMM_OPERAND(op), MDS_32_BITS_UNSIGNED, pc + offset); + else assert(0); + + printf("3... 0x%x (0x%x) + 0x%x\n", + (unsigned int)get_virt_addr(get_mrange_addr(range)), + (unsigned int)pc, (unsigned int)offset); + + + target = pc + offset; - g_armv7_context_define_encoding(context, target, iset); + //g_armv7_context_define_encoding(context, target, iset); + g_armv7_context_push_drop_point_ext(context, target, iset); + +} + + +/****************************************************************************** +* * +* Paramètres : instr = instruction ARMv7 à traiter. * +* context = contexte associé à la phase de désassemblage. * +* format = acès aux données du binaire d'origine. * +* * +* Description : Complète un désassemblage accompli pour une instruction. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void handle_links_with_instruction_cb_n_z(GArchInstruction *instr, GArmV7Context *context, GBinFormat *format) +{ + const mrange_t *range; /* Emplacementt d'instruction */ + virt_t pc; /* Position dans l'exécution */ + GArchOperand *op; /* Opérande numérique en place */ + uint32_t offset; /* Décallage encodé en dur */ + virt_t target; /* Adresse virtuelle visée */ + + range = g_arch_instruction_get_range(instr); + + pc = get_virt_addr(get_mrange_addr(range)); + + + printf("PC :: 0x%08x\n", (unsigned int)pc); + + + /** + * En mode Thumb, pc a pour valeur l'adresse courante plus 4. + */ + + pc += 4; + + op = g_arch_instruction_get_operand(instr, 1); + + if (g_imm_operand_get_value(G_IMM_OPERAND(op), MDS_32_BITS_UNSIGNED, &offset)) + g_imm_operand_set_value(G_IMM_OPERAND(op), MDS_32_BITS_UNSIGNED, pc + offset); + + else assert(0); + + target = pc + offset; + + //g_armv7_context_define_encoding(context, target, AV7IS_THUMB); + g_armv7_context_push_drop_point_ext(context, target, AV7IS_THUMB); + +} + + +/****************************************************************************** +* * +* Paramètres : instr = instruction ARMv7 à traiter. * +* context = contexte associé à la phase de désassemblage. * +* format = acès aux données du binaire d'origine. * +* iset = type de jeu d'instructions courant à inverser. * +* * +* Description : Complète un désassemblage accompli pour une instruction. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void handle_links_with_instruction_ldr_literal_with_orig(GArchInstruction *instr, GArmV7Context *context, GBinFormat *format, ArmV7InstrSet iset) +{ + const mrange_t *range; /* Emplacementt d'instruction */ + phys_t phys_pc; /* Position dans l'exécution */ + GArchOperand *op; /* Opérande de surcouche */ + GArchOperand *sub_op; /* Opérande numérique en place */ + + + uint32_t offset; /* Décallage encodé en dur */ + bool ret; /* Bilan d'une récupération */ + + + off_t val_offset; /* Position de valeur à lire */ + + + + off_t length; /* Taille des données à lire */ + const bin_t *data; /* Données binaires à lire */ + + + uint32_t target; /* Adresse virtuelle visée */ + GArchOperand *new; /* Instruction de ciblage */ + + /* Récupération de l'adresse visée par le chargement */ + + range = g_arch_instruction_get_range(instr); + + phys_pc = get_phy_addr(get_mrange_addr(range)); + + phys_pc &= ~3; + //phys_pc = (phys_pc + 3) & ~3; + + printf(">>>>>>> @pc @ 0x%08x\n", (unsigned int)phys_pc); + + + switch (iset) + { + case AV7IS_ARM: + phys_pc += 8; + break; + case AV7IS_THUMB: + phys_pc += 4; + break; + default: + assert(0); + break; + } + + op = g_arch_instruction_get_operand(instr, 1); + assert(G_IS_ARMV7_OFFSET_OPERAND(op)); + + sub_op = g_armv7_offset_operand_get_value(G_ARMV7_OFFSET_OPERAND(op)); + + ret = g_imm_operand_get_value(G_IMM_OPERAND(sub_op), MDS_32_BITS_UNSIGNED, &offset); + if (!ret) + { + assert(0); + return; + } + + /* Lecture de la valeur vers laquelle renvoyer */ + + if (g_armv7_offset_operand_is_positive(G_ARMV7_OFFSET_OPERAND(op))) + val_offset = phys_pc + offset; + else + val_offset = phys_pc - offset; + + + data = g_binary_format_get_content(format, &length); + + + printf(">>>>>>> @reading @ 0x%08x (0x%x)\n", (unsigned int)val_offset, offset); + + + ret = read_u32(&target, data, &val_offset, length, SRE_LITTLE /* FIXME */); + if (!ret) return; + + + printf(">>>>>>> @got target :: 0x%08x\n", (unsigned int)target); + + + //g_imm_operand_set_value(G_IMM_OPERAND(sub_op), MDS_32_BITS_UNSIGNED, target); + + + new = g_imm_operand_new_from_value(MDS_32_BITS_UNSIGNED, target); + g_arch_instruction_replace_operand(instr, new, op); + + + + + //exit(0); + + + + //target = pc + offset; + + //g_armv7_context_define_encoding(context, target, AV7IS_THUMB); + g_armv7_context_push_drop_point_ext(context, target, AV7IS_THUMB); + + + //exit(0); } diff --git a/src/arch/arm/v7/link.h b/src/arch/arm/v7/link.h index ef71bd6..87bef54 100644 --- a/src/arch/arm/v7/link.h +++ b/src/arch/arm/v7/link.h @@ -32,6 +32,21 @@ /* Complète un désassemblage accompli pour une instruction. */ +void handle_links_with_instruction_b_with_orig(GArchInstruction *, GArmV7Context *, GBinFormat *, ArmV7InstrSet); + + +static inline void handle_links_with_instruction_b_from_arm(GArchInstruction *ins, GArmV7Context *ctx, GBinFormat *fmt) +{ + handle_links_with_instruction_b_with_orig(ins, ctx, fmt, AV7IS_THUMB); +} + +static inline void handle_links_with_instruction_b_from_thumb(GArchInstruction *ins, GArmV7Context *ctx, GBinFormat *fmt) +{ + handle_links_with_instruction_b_with_orig(ins, ctx, fmt, AV7IS_ARM); +} + + +/* Complète un désassemblage accompli pour une instruction. */ void handle_links_with_instruction_bl_with_orig(GArchInstruction *, GArmV7Context *, GBinFormat *, ArmV7InstrSet); @@ -61,5 +76,23 @@ static inline void handle_links_with_instruction_blx_from_thumb(GArchInstruction } +/* Complète un désassemblage accompli pour une instruction. */ +void handle_links_with_instruction_cb_n_z(GArchInstruction *, GArmV7Context *, GBinFormat *); + +/* Complète un désassemblage accompli pour une instruction. */ +void handle_links_with_instruction_ldr_literal_with_orig(GArchInstruction *, GArmV7Context *, GBinFormat *, ArmV7InstrSet); + + +static inline void handle_links_with_instruction_ldr_literal_from_arm(GArchInstruction *ins, GArmV7Context *ctx, GBinFormat *fmt) +{ + handle_links_with_instruction_ldr_literal_with_orig(ins, ctx, fmt, AV7IS_ARM); +} + +static inline void handle_links_with_instruction_ldr_literal_from_thumb(GArchInstruction *ins, GArmV7Context *ctx, GBinFormat *fmt) +{ + handle_links_with_instruction_ldr_literal_with_orig(ins, ctx, fmt, AV7IS_THUMB); +} + + #endif /* _ARCH_ARM_V7_LINK_H */ diff --git a/src/arch/arm/v7/opdefs/Makefile.am b/src/arch/arm/v7/opdefs/Makefile.am index 0966e2e..fa42230 100644 --- a/src/arch/arm/v7/opdefs/Makefile.am +++ b/src/arch/arm/v7/opdefs/Makefile.am @@ -16,6 +16,7 @@ D2C_ENCODINGS = \ -e T=thumb_32_ D2C_MACROS = \ + -M DefineAsReturn=g_arch_instruction_define_as_return \ -M SetFlags=g_armv7_instruction_define_setflags \ -M Condition=g_arm_instruction_set_cond \ -M Register=translate_armv7_register \ diff --git a/src/arch/arm/v7/opdefs/b_A8818.d b/src/arch/arm/v7/opdefs/b_A8818.d index 50600d4..5d696a3 100644 --- a/src/arch/arm/v7/opdefs/b_A8818.d +++ b/src/arch/arm/v7/opdefs/b_A8818.d @@ -36,10 +36,18 @@ } + @hooks { + + link = handle_links_with_instruction_b_from_thumb + post = post_process_branch_instructions + + } + @rules { //if cond == '1110' then UNDEFINED; //if cond == '1111' then SEE SVC; + call DefineAsReturn(1) } @@ -57,9 +65,17 @@ } + @hooks { + + link = handle_links_with_instruction_b_from_thumb + post = post_process_branch_instructions + + } + @rules { //if InITBlock() && !LastInITBlock() then UNPREDICTABLE; + call DefineAsReturn(1) } @@ -78,10 +94,18 @@ } + @hooks { + + link = handle_links_with_instruction_b_from_thumb + post = post_process_branch_instructions + + } + @rules { //if cond<3:1> == '111' then SEE "Related encodings"; //if InITBlock() then UNPREDICTABLE; + call DefineAsReturn(1) } @@ -101,9 +125,17 @@ } + @hooks { + + link = handle_links_with_instruction_b_from_thumb + post = post_process_branch_instructions + + } + @rules { //if InITBlock() && !LastInITBlock() then UNPREDICTABLE; + call DefineAsReturn(1) } @@ -122,4 +154,17 @@ } + @hooks { + + link = handle_links_with_instruction_b_from_arm + post = post_process_branch_instructions + + } + + @rules { + + call DefineAsReturn(1) + + } + } diff --git a/src/arch/arm/v7/opdefs/bl_A8825.d b/src/arch/arm/v7/opdefs/bl_A8825.d index 96c782f..c5de31e 100644 --- a/src/arch/arm/v7/opdefs/bl_A8825.d +++ b/src/arch/arm/v7/opdefs/bl_A8825.d @@ -40,7 +40,13 @@ @hooks { link = handle_links_with_instruction_bl_from_thumb - post = post_process_branch_instructions + post = post_process_branch_and_link_instructions + + } + + @rules { + + //call DefineAsReturn(1) } @@ -63,7 +69,13 @@ @hooks { link = handle_links_with_instruction_blx_from_thumb - post = post_process_branch_instructions + post = post_process_branch_and_link_instructions + + } + + @rules { + + //call DefineAsReturn(1) } @@ -84,7 +96,13 @@ @hooks { link = handle_links_with_instruction_bl_from_arm - post = post_process_branch_instructions + post = post_process_branch_and_link_instructions + + } + + @rules { + + //call DefineAsReturn(1) } @@ -105,7 +123,13 @@ @hooks { link = handle_links_with_instruction_blx_from_arm - post = post_process_branch_instructions + post = post_process_branch_and_link_instructions + + } + + @rules { + + //call DefineAsReturn(1) } diff --git a/src/arch/arm/v7/opdefs/blx_A8826.d b/src/arch/arm/v7/opdefs/blx_A8826.d index 178515a..12c55ad 100644 --- a/src/arch/arm/v7/opdefs/blx_A8826.d +++ b/src/arch/arm/v7/opdefs/blx_A8826.d @@ -39,6 +39,7 @@ //if m == 15 then UNPREDICTABLE; //if InITBlock() && !LastInITBlock() then UNPREDICTABLE; + //call DefineAsReturn(1) } @@ -60,6 +61,7 @@ @rules { //if m == 15 then UNPREDICTABLE; + //call DefineAsReturn(1) } diff --git a/src/arch/arm/v7/opdefs/bx_A8827.d b/src/arch/arm/v7/opdefs/bx_A8827.d index 45ccfd5..b8ab6f8 100644 --- a/src/arch/arm/v7/opdefs/bx_A8827.d +++ b/src/arch/arm/v7/opdefs/bx_A8827.d @@ -36,6 +36,12 @@ } + @rules { + + call DefineAsReturn(1) + + } + } @encoding(A1) { @@ -51,4 +57,10 @@ } + @rules { + + call DefineAsReturn(1) + + } + } diff --git a/src/arch/arm/v7/opdefs/cbnz_A8829.d b/src/arch/arm/v7/opdefs/cbnz_A8829.d index 9ecf141..93a8d1f 100644 --- a/src/arch/arm/v7/opdefs/cbnz_A8829.d +++ b/src/arch/arm/v7/opdefs/cbnz_A8829.d @@ -36,6 +36,13 @@ } + @hooks { + + link = handle_links_with_instruction_cb_n_z + post = post_process_comp_and_branch_instructions + + } + } @encoding(t12) { @@ -51,4 +58,11 @@ } + @hooks { + + link = handle_links_with_instruction_cb_n_z + post = post_process_comp_and_branch_instructions + + } + } diff --git a/src/arch/arm/v7/opdefs/ldr_A8862.d b/src/arch/arm/v7/opdefs/ldr_A8862.d index 7799fce..ecb530b 100644 --- a/src/arch/arm/v7/opdefs/ldr_A8862.d +++ b/src/arch/arm/v7/opdefs/ldr_A8862.d @@ -76,6 +76,7 @@ //if Rn == '1111' then SEE LDR (literal); //if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE; + if (Rt == '1111'); call DefineAsReturn(1) } @@ -103,6 +104,7 @@ //if Rn == '1101' && P == '0' && U == '1' && W == '1' && imm8 == '00000100' then SEE POP; //if P == '0' && W == '0' then UNDEFINED; //if (wback && n == t) || (t == 15 && InITBlock() && !LastInITBlock()) then UNPREDICTABLE; + if (Rt == '1111'); call DefineAsReturn(1) } @@ -131,6 +133,7 @@ //if Rn == '1101' && P == '0' && U == '1' && W == '1' && imm8 == '00000100' then SEE POP; //if P == '0' && W == '0' then UNDEFINED; //if (wback && n == t) || (t == 15 && InITBlock() && !LastInITBlock()) then UNPREDICTABLE; + if (Rt == '1111'); call DefineAsReturn(1) } diff --git a/src/arch/arm/v7/opdefs/ldr_A8863.d b/src/arch/arm/v7/opdefs/ldr_A8863.d index 2526671..0158c3d 100644 --- a/src/arch/arm/v7/opdefs/ldr_A8863.d +++ b/src/arch/arm/v7/opdefs/ldr_A8863.d @@ -46,6 +46,7 @@ //t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); //index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); //if wback && n == t then UNPREDICTABLE; + if (Rt == '1111'); call DefineAsReturn(1) } @@ -75,6 +76,7 @@ //t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); //index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); //if wback && n == t then UNPREDICTABLE; + if (Rt == '1111'); call DefineAsReturn(1) } diff --git a/src/arch/arm/v7/opdefs/ldr_A8864.d b/src/arch/arm/v7/opdefs/ldr_A8864.d index acb6f94..3fbc0e3 100644 --- a/src/arch/arm/v7/opdefs/ldr_A8864.d +++ b/src/arch/arm/v7/opdefs/ldr_A8864.d @@ -37,6 +37,13 @@ } + @hooks { + + link = handle_links_with_instruction_ldr_literal_from_thumb + post = post_process_ldr_instructions + + } + } @encoding(T2) { @@ -53,9 +60,17 @@ } + @hooks { + + link = handle_links_with_instruction_ldr_literal_from_thumb + post = post_process_ldr_instructions + + } + @rules { //if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE; + if (Rt == '1111'); call DefineAsReturn(1) } @@ -65,14 +80,29 @@ @word cond(4) 0 1 0 1 U(1) 0 0 1 1 1 1 1 Rt(4) imm12(12) - @syntax