diff options
Diffstat (limited to 'src/arch/link.c')
-rw-r--r-- | src/arch/link.c | 190 |
1 files changed, 190 insertions, 0 deletions
diff --git a/src/arch/link.c b/src/arch/link.c new file mode 100644 index 0000000..bc80e39 --- /dev/null +++ b/src/arch/link.c @@ -0,0 +1,190 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * link.c - édition des liens après la phase de désassemblage + * + * Copyright (C) 2014 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * OpenIDA is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * OpenIDA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +#include "link.h" + + +#include <assert.h> + + +#include "target.h" + + + +/****************************************************************************** +* * +* Paramètres : instr = instruction ARMv7 à traiter. * +* proc = représentation de l'architecture utilisée. * +* context = contexte associé à la phase de désassemblage. * +* format = acès aux données du binaire d'origine. * +* * +* Description : Etablit un lien de saut selon une instruction donnée. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void handle_jump_as_link(GArchInstruction *instr, GArchProcessor *proc, GProcContext *context, GBinFormat *format) +{ + GArchOperand *op; /* Opérande numérique en place */ + virt_t virt; /* Adresse virtuelle */ + vmpa2t addr; /* Adresse de destination */ + GArchInstruction *target; /* Ligne visée par la référence*/ + + assert(g_arch_instruction_count_operands(instr) > 0); + + op = g_arch_instruction_get_operand(instr, 0); + + if (!G_IS_IMM_OPERAND(op)) return; + + if (g_imm_operand_to_virt_t(G_IMM_OPERAND(op), &virt)) + { + init_vmpa(&addr, VMPA_NO_PHYSICAL, virt); + + target = g_arch_processor_find_instr_by_address(proc, &addr); + + if (target != NULL) + g_arch_instruction_link_with(instr, target, ILT_JUMP); + + } + +} + + +/****************************************************************************** +* * +* Paramètres : instr = instruction ARMv7 à traiter. * +* proc = représentation de l'architecture utilisée. * +* context = contexte associé à la phase de désassemblage. * +* format = acès aux données du binaire d'origine. * +* * +* Description : Etablit un lien d'appel selon une instruction donnée. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ +#include "instruction-int.h" +void handle_branch_if_true_as_link(GArchInstruction *instr, GArchProcessor *proc, GProcContext *context, GBinFormat *format) +{ + GArchOperand *op; /* Opérande numérique en place */ + virt_t virt; /* Adresse virtuelle */ + vmpa2t addr; /* Adresse de destination */ + GArchInstruction *target; /* Ligne visée par la référence*/ + GArchInstruction *list; /* Ensemble des instructions */ + + assert(g_arch_instruction_count_operands(instr) > 0); + + op = g_arch_instruction_get_operand(instr, 0); + + virt = VMPA_NO_VIRTUAL; + + if (G_IS_TARGET_OPERAND(op)) + virt = g_target_operand_get_addr(G_TARGET_OPERAND(op)); + + else if (G_IS_IMM_OPERAND(op)) + { + if (!g_imm_operand_to_virt_t(G_IMM_OPERAND(op), &virt)) + virt = VMPA_NO_VIRTUAL; + } + + if (virt != VMPA_NO_VIRTUAL) + { + /* TODO : utiliser format pour contruire une adresse avec une position physique, + * ce qui accélèrerait les recherches. + */ + init_vmpa(&addr, VMPA_NO_PHYSICAL, virt); + + target = g_arch_processor_find_instr_by_address(proc, &addr); + + printf(" @ 0x%08x BRANCH to 0x%08x -->> %p\n", + (unsigned int)instr->range.addr.virtual, (unsigned int)virt, target); + + if (target != NULL) + { + g_arch_instruction_link_with(instr, target, ILT_JUMP_IF_TRUE); + + list = g_arch_processor_get_disassembled_instructions(proc); + + target = g_arch_instruction_get_next_iter(list, instr, ~0); + + if (target != NULL) + g_arch_instruction_link_with(instr, target, ILT_JUMP_IF_FALSE); + + } + + } + + + else printf(" @ 0x%08x FAILED TO BRANCH\n", + (unsigned int)instr->range.addr.virtual); + + + + +} + + +/****************************************************************************** +* * +* Paramètres : instr = instruction ARMv7 à traiter. * +* proc = représentation de l'architecture utilisée. * +* context = contexte associé à la phase de désassemblage. * +* format = acès aux données du binaire d'origine. * +* * +* Description : Etablit un lien d'appel selon une instruction donnée. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void handle_call_as_link(GArchInstruction *instr, GArchProcessor *proc, GProcContext *context, GBinFormat *format) +{ + GArchOperand *op; /* Opérande numérique en place */ + virt_t virt; /* Adresse virtuelle */ + vmpa2t addr; /* Adresse de destination */ + GArchInstruction *target; /* Ligne visée par la référence*/ + + assert(g_arch_instruction_count_operands(instr) > 0); + + op = g_arch_instruction_get_operand(instr, 0); + + if (!G_IS_IMM_OPERAND(op)) return; + + if (g_imm_operand_to_virt_t(G_IMM_OPERAND(op), &virt)) + { + init_vmpa(&addr, VMPA_NO_PHYSICAL, virt); + + target = g_arch_processor_find_instr_by_address(proc, &addr); + + if (target != NULL) + g_arch_instruction_link_with(instr, target, ILT_CALL); + + } + +} |