summaryrefslogtreecommitdiff
path: root/src/arch/arm/v7/link.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/arch/arm/v7/link.c')
-rw-r--r--src/arch/arm/v7/link.c242
1 files changed, 240 insertions, 2 deletions
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 <assert.h>
+#include <operands/offset.h>
@@ -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);
}