* Added copypasta 'arm' code analysis for r_anal

This commit is contained in:
pancake 2010-03-08 10:53:15 +01:00
parent 1341620c73
commit 023bcce689
6 changed files with 202 additions and 20 deletions

View File

@ -8,6 +8,7 @@
#include "../config.h"
/* plugin pointers */
extern RAnalysisHandle r_anal_plugin_arm;
extern RAnalysisHandle r_anal_plugin_x86;
extern RAnalysisHandle r_anal_plugin_x86_bea;
extern RAnalysisHandle r_anal_plugin_ppc;

175
libr/anal/p/anal_arm.c Normal file
View File

@ -0,0 +1,175 @@
/* radare - LGPL - Copyright 2007-2010 */
/* pancake<nopcode.org> */
#include <string.h>
#include <r_types.h>
#include <r_lib.h>
#include <r_asm.h>
#include <r_anal.h>
/* DEPRECATE ?? */
#include "arm.h"
// XXX: must be configured somewhere with anal.bits
static int arm_mode = 32;
static unsigned int disarm_branch_offset ( unsigned int pc, unsigned int insoff ) {
unsigned int add = insoff << 2;
/* zero extend if higher is 1 (0x02000000) */
if ( (add & 0x02000000) == 0x02000000 )
add = add | 0xFC000000 ;
return add + pc + 8;
}
#define IS_BRANCH(x) \
((x&ARM_BRANCH_I_MASK) == ARM_BRANCH_I)
#define IS_BRANCHL(x) \
(IS_BRANCH(x) && (x&ARM_BRANCH_LINK) == ARM_BRANCH_LINK)
#define IS_RETURN(x) \
((x&(ARM_DTM_I_MASK|ARM_DTM_LOAD|(1<<15))) == (ARM_DTM_I|ARM_DTM_LOAD|(1<<15)))
//if ( (inst & ( ARM_DTX_I_MASK | ARM_DTX_LOAD | ( ARM_DTX_RD_MASK ) ) ) == ( ARM_DTX_LOAD | ARM_DTX_I | ( ARM_PC << 12 ) ) )
#define IS_UNKJMP(x) \
(( (( ARM_DTX_RD_MASK ) ) ) == ( ARM_DTX_LOAD | ARM_DTX_I | ( ARM_PC << 12 ) ))
#define IS_LOAD(x) \
((x&ARM_DTX_LOAD) == (ARM_DTX_LOAD))
#define IS_CONDAL(x) \
((x&ARM_COND_MASK)==ARM_COND_AL)
#define IS_EXITPOINT(x) \
(IS_BRANCH (x) || IS_RETURN (x) || IS_UNKJMP (x))
static int aop(RAnalysis *anal, RAnalysisAop *aop, ut64 addr, const ut8 *data, int len) {
unsigned int i = 0;
unsigned int* code = (unsigned int *)data;
unsigned int branch_dst_addr;
const ut8 *b = (ut8 *)data;
if (data == NULL)
return 0;
memset (aop, '\0', sizeof(RAnalysisAop));
aop->type = R_ANAL_OP_TYPE_UNK;
if (aop == NULL)
return (arm_mode==16)?2:4;
memset(aop, '\0', sizeof(struct r_anal_aop_t));
aop->type = R_ANAL_OP_TYPE_UNK;
#if 0
fprintf(stderr, "CODE %02x %02x %02x %02x\n",
codeA[0], codeA[1], codeA[2], codeA[3]);
#endif
//eprintf("0x%08x\n", code[i] & ARM_DTX_LOAD);
// 0x0001B4D8, 1eff2fe1 bx lr
if (b[3]==0xe2 && b[2]==0x8d && b[1]==0xd0) {
// ADD SP, SP, ...
aop->type = R_ANAL_OP_TYPE_ADD;
aop->stackop = R_ANAL_STACK_INCSTACK;
aop->value = -b[0];
}
if (b[3]==0xe2 && b[2]==0x4d && b[1]==0xd0) {
// SUB SP, SP, ..
aop->type = R_ANAL_OP_TYPE_SUB;
aop->stackop = R_ANAL_STACK_INCSTACK;
aop->value = b[0];
} else
if (b[3]==0xe2 && b[2]==0x4c && b[1]==0xb0) {
// SUB SP, FP, ..
aop->type = R_ANAL_OP_TYPE_SUB;
aop->stackop = R_ANAL_STACK_INCSTACK;
aop->value = -b[0];
} else
if (b[3]==0xe2 && b[2]==0x4b && b[1]==0xd0) {
// SUB SP, IP, ..
aop->type = R_ANAL_OP_TYPE_SUB;
aop->stackop = R_ANAL_STACK_INCSTACK;
aop->value = -b[0];
} else
if( (code[i] == 0x1eff2fe1) ||(code[i] == 0xe12fff1e)) { // bx lr
aop->type = R_ANAL_OP_TYPE_RET;
aop->eob = 1;
} else
if ((code[i] & ARM_DTX_LOAD)) { //IS_LOAD(code[i])) {
int ret = arm_mode/8;
ut32 ptr = 0;
aop->type = R_ANAL_OP_TYPE_MOV;
if (b[2]==0x1b) {
/* XXX pretty incomplete */
aop->stackop = R_ANAL_STACK_LOCAL_GET;
aop->ref = b[0];
//var_add_access(addr, -b[0], 1, 0); // TODO: set/get (the last 0)
} else {
//ut32 oaddr = addr+8+b[0];
//XXX TODO ret = radare_read_at(oaddr, (ut8*)&ptr, 4);
if (ret == 4) {
b = (ut8*)&ptr;
aop->ref = b[0] + (b[1]<<8) + (b[2]<<16) + (b[3]<<24);
//XXX data_xrefs_add(oaddr, aop->ref, 1);
//TODO change data type to pointer
} else {
aop->ref = 0;
}
}
} else
if (b[3]==0xe5) {
/* STORE */
aop->type = R_ANAL_OP_TYPE_STORE;
aop->stackop = R_ANAL_STACK_LOCAL_SET;
aop->ref = b[0];
}
if (IS_EXITPOINT (code[i])) {
branch_dst_addr = disarm_branch_offset (addr, code[i]&0x00FFFFFF);
aop->ref = 0;
if (IS_BRANCHL (code[i])) {
if (IS_BRANCH (code[i])) {
aop->type = R_ANAL_OP_TYPE_CALL;
aop->jump = branch_dst_addr;
aop->fail = addr + 4 ;
aop->eob = 1;
} else {
aop->type = R_ANAL_OP_TYPE_RET;
aop->eob = 1;
}
} else if (IS_BRANCH (code[i])) {
if (IS_CONDAL (code[i])) {
aop->type = R_ANAL_OP_TYPE_JMP;
aop->jump = branch_dst_addr;
aop->eob = 1;
} else {
aop->type = R_ANAL_OP_TYPE_CJMP;
aop->jump = branch_dst_addr;
aop->fail = addr + 4;
aop->eob = 1;
}
} else {
//unknown jump o return
aop->type = R_ANAL_OP_TYPE_UJMP;
aop->eob = 1;
}
}
return (arm_mode==16)?2:4;
}
struct r_anal_handle_t r_anal_plugin_arm = {
.name = "arm",
.desc = "ARM code analysis plugin",
.init = NULL,
.fini = NULL,
.aop = &aop
};
#ifndef CORELIB
struct r_lib_struct_t radare_plugin = {
.type = R_LIB_TYPE_ANAL,
.data = &r_anal_plugin_arm
};
#endif

10
libr/anal/p/arm.mk Normal file
View File

@ -0,0 +1,10 @@
OBJ_ARM=anal_arm.o
STATIC_OBJ+=${OBJ_ARM}
TARGET_ARM=anal_arm.${EXT_SO}
ALL_TARGETS+=${TARGET_ARM}
${TARGET_ARM}: ${OBJ_ARM}
${CC} ${CFLAGS} -o anal_arm.${EXT_SO} ${OBJ_ARM}
@#strip -s anal_x86.${EXT_SO}

View File

@ -1,4 +1,4 @@
/* radare - GPL3 - Copyright 2009 nibble<.ds@gmail.com> */
/* radare - GPL3 - Copyright 2009-2010 nibble<.ds@gmail.com> */
#include <stdio.h>
#include <stdarg.h>
@ -16,47 +16,42 @@ static unsigned long Offset = 0;
static char *buf_global = NULL;
static unsigned char bytes[4];
static int arm_buffer_read_memory (bfd_vma memaddr, bfd_byte *myaddr, unsigned int length, struct disassemble_info *info)
{
static int arm_buffer_read_memory (bfd_vma memaddr, bfd_byte *myaddr,
unsigned int length, struct disassemble_info *info) {
memcpy (myaddr, bytes, length);
return 0;
}
static int symbol_at_address(bfd_vma addr, struct disassemble_info * info)
{
static int symbol_at_address(bfd_vma addr, struct disassemble_info * info) {
return 0;
}
static void memory_error_func(int status, bfd_vma memaddr, struct disassemble_info *info)
{
static void memory_error_func(int status, bfd_vma memaddr, struct disassemble_info *info) {
//--
}
static void print_address(bfd_vma address, struct disassemble_info *info)
{
static void print_address(bfd_vma address, struct disassemble_info *info) {
char tmp[32];
if (buf_global == NULL)
return;
sprintf(tmp, "0x%08llx", (ut64)address);
strcat(buf_global, tmp);
sprintf (tmp, "0x%08llx", (ut64)address);
strcat (buf_global, tmp);
}
static int buf_fprintf(void *stream, const char *format, ...)
{
static int buf_fprintf(void *stream, const char *format, ...) {
va_list ap;
char *tmp;
if (buf_global == NULL)
return 0;
va_start(ap, format);
tmp = alloca(strlen(format)+strlen(buf_global)+2);
sprintf(tmp, "%s%s", buf_global, format);
vsprintf(buf_global, tmp, ap);
va_end(ap);
tmp = alloca (strlen (format)+strlen (buf_global)+2);
sprintf (tmp, "%s%s", buf_global, format);
vsprintf (buf_global, tmp, ap);
va_end (ap);
return 0;
}
static int disassemble(struct r_asm_t *a, struct r_asm_aop_t *aop, ut8 *buf, ut64 len)
{
static int disassemble(struct r_asm_t *a, struct r_asm_aop_t *aop, ut8 *buf, ut64 len) {
static struct disassemble_info disasm_obj;
buf_global = aop->buf_asm;
@ -78,7 +73,6 @@ static int disassemble(struct r_asm_t *a, struct r_asm_aop_t *aop, ut8 *buf, ut6
aop->buf_asm[0]='\0';
aop->inst_len = print_insn_arm((bfd_vma)Offset, &disasm_obj);
if (aop->inst_len == -1)
strncpy(aop->buf_asm, " (data)", R_ASM_BUFSIZE);

View File

@ -6,6 +6,7 @@ asm.x86
asm.x86_nasm
asm.x86_olly
anal.x86
anal.arm
anal.ppc
bin.dummy
bin.elf

View File

@ -1,2 +1,3 @@
* Add support for rasm2
* Add preprocessing support to compile 32/64 bit specific code.. or OS-dependent
* Rename to r_rcc