Fixes for powerpc endian in mach0 and other issues

This commit is contained in:
pancake 2016-06-06 22:55:26 +02:00
parent 649748a8f2
commit eb9feef231
5 changed files with 54 additions and 38 deletions

View File

@ -1,4 +1,4 @@
/* radare2 - LGPL - Copyright 2013-2015 - pancake */
/* radare2 - LGPL - Copyright 2013-2016 - pancake */
#include <r_anal.h>
#include <r_lib.h>
@ -16,12 +16,14 @@ struct Getarg {
#define INSOP(n) insn->detail->ppc.operands[n]
static char *getarg2(struct Getarg *gop, int n, const char *setstr) {
csh handle = gop->handle;
cs_insn *insn = gop->insn;
cs_ppc_op op;
csh handle = gop->handle;
static char words[3][64];
if (n<0 || n>=3)
cs_ppc_op op;
if (n < 0 || n >= 3) {
return NULL;
}
op = INSOP (n);
switch (op.type) {
case PPC_OP_INVALID:
@ -47,6 +49,7 @@ static char *getarg2(struct Getarg *gop, int n, const char *setstr) {
}
return words[n];
}
#define ARG(n) getarg2(&gop, n, "")
#define ARG2(n,m) getarg2(&gop, n, m)
@ -137,7 +140,7 @@ static int analop(RAnal *a, RAnalOp *op, ut64 addr, const ut8 *buf, int len) {
// capstone-next
n = cs_disasm (handle, (const ut8*)buf, len, addr, 1, &insn);
if (n<1) {
if (n < 1) {
op->type = R_ANAL_OP_TYPE_ILL;
} else {
struct Getarg gop = {
@ -338,9 +341,12 @@ static int analop(RAnal *a, RAnalOp *op, ut64 addr, const ut8 *buf, int len) {
case PPC_INS_BLA:
op->type = R_ANAL_OP_TYPE_CALL;
op->jump = (ut64)insn->detail->ppc.operands[0].imm;
op->fail = addr+4;
op->fail = addr + 4;
esilprintf (op, "pc,lr,=,%s,pc,=", ARG(0));
break;
case PPC_INS_TRAP:
op->type = R_ANAL_OP_TYPE_TRAP;
break;
case PPC_INS_BLR:
case PPC_INS_BLRL:
op->type = R_ANAL_OP_TYPE_RET;

View File

@ -35,21 +35,17 @@ static int disassemble(RAsm *a, RAsmOp *op, const ut8 *buf, int len) {
}
cs_option (handle, CS_OPT_DETAIL, CS_OPT_OFF);
n = cs_disasm (handle, (const ut8*)buf, len, off, 1, &insn);
if (n>0) {
if (insn->size>0) {
op->size = insn->size;
snprintf (op->buf_asm, R_ASM_BUFSIZE, "%s%s%s",
insn->mnemonic, insn->op_str[0]?" ":"",
insn->op_str);
}
op->size = 4;
if (n > 0 && insn->size > 0) {
snprintf (op->buf_asm, R_ASM_BUFSIZE, "%s%s%s",
insn->mnemonic, insn->op_str[0]?" ":"",
insn->op_str);
cs_free (insn, n);
}
if (op->size == 4) {
op->size = 4;
return op->size;
}
op->size = 4;
return -1;
//op->size = -1;
cs_free (insn, n);
return 4;
}
RAsmPlugin r_asm_plugin_ppc_cs = {

View File

@ -16,7 +16,7 @@
#define IFDBG if(DO_THE_DBG)
#define IFINT if(0)
#define ELF_PAGE_MASK 0xFFFFFFFFFFFFF000
#define ELF_PAGE_MASK 0xFFFFFFFFFFFFF000LL
#define ELF_PAGE_SIZE 12
static RBinElfSection *g_sections = NULL;
@ -212,24 +212,31 @@ static int init_shdr(struct Elf_(r_bin_elf_obj_t) *bin) {
}
static int init_strtab(struct Elf_(r_bin_elf_obj_t) *bin) {
if (bin->strtab || !bin->shdr) return false;
if (bin->ehdr.e_shstrndx != SHN_UNDEF &&
(bin->ehdr.e_shstrndx >= bin->ehdr.e_shnum ||
(bin->ehdr.e_shstrndx >= SHN_LORESERVE && bin->ehdr.e_shstrndx <= SHN_HIRESERVE)))
return false;
if (bin->strtab || !bin->shdr) {
return false;
}
if (bin->ehdr.e_shstrndx != SHN_UNDEF &&
(bin->ehdr.e_shstrndx >= bin->ehdr.e_shnum ||
(bin->ehdr.e_shstrndx >= SHN_LORESERVE &&
bin->ehdr.e_shstrndx < SHN_HIRESERVE)))
return false;
/* sh_size must be lower than UT32_MAX and not equal to zero, to avoid bugs on malloc() */
if (bin->shdr[bin->ehdr.e_shstrndx].sh_size > UT32_MAX)
if (bin->shdr[bin->ehdr.e_shstrndx].sh_size > UT32_MAX) {
return false;
if (!bin->shdr[bin->ehdr.e_shstrndx].sh_size)
}
if (!bin->shdr[bin->ehdr.e_shstrndx].sh_size) {
return false;
bin->shstrtab_section =
}
bin->shstrtab_section = \
bin->strtab_section = &bin->shdr[bin->ehdr.e_shstrndx];
bin->shstrtab_size = bin->strtab_section->sh_size;
if (bin->shstrtab_size > bin->size) return false;
if (bin->shstrtab_size > bin->size) {
return false;
}
if ((bin->shstrtab = calloc (1, bin->shstrtab_size + 1)) == NULL) {
if (!(bin->shstrtab = calloc (1, bin->shstrtab_size + 1))) {
perror ("malloc");
bin->shstrtab = NULL;
return false;
@ -287,7 +294,9 @@ static int init_dynamic_section (struct Elf_(r_bin_elf_obj_t) *bin) {
tmp = dyn = (Elf_(Dyn)*)((ut8 *)bin->b->buf + bin->phdr[i].p_offset);
for (entries = 0; (ut8*)dyn < ((ut8*)tmp + dyn_size); dyn++) {
entries++;
if (dyn->d_tag == DT_NULL) break;
if (dyn->d_tag == DT_NULL) {
break;
}
if ((ut8*)(dyn+2) > ((ut8*)bin->b->buf + bin->size))
return false;
}
@ -295,10 +304,12 @@ static int init_dynamic_section (struct Elf_(r_bin_elf_obj_t) *bin) {
dyn = (Elf_(Dyn)*)calloc (entries, sizeof (Elf_(Dyn)));
if (!dyn) return false;
if (!UT32_MUL (&dyn_size, entries, sizeof (Elf_(Dyn))))
if (!UT32_MUL (&dyn_size, entries, sizeof (Elf_(Dyn)))) {
goto beach;
if (!dyn_size)
}
if (!dyn_size) {
goto beach;
}
offset = Elf_(r_bin_elf_v2p) (bin, bin->phdr[i].p_vaddr);
if (offset > bin->size || offset + dyn_size > bin->size)
goto beach;
@ -309,8 +320,9 @@ static int init_dynamic_section (struct Elf_(r_bin_elf_obj_t) *bin) {
r = r_buf_fread_at (bin->b, offset, (ut8 *)dyn,
bin->endian ? "2I":"2i", entries);
#endif
if (r < 1)
if (r < 1) {
goto beach;
}
for (i = 0; i < entries; i++) {
switch (dyn[i].d_tag) {
case DT_STRTAB: strtabaddr = Elf_(r_bin_elf_v2p) (bin, dyn[i].d_un.d_ptr); break;
@ -1620,6 +1632,9 @@ ut8 *Elf_(r_bin_elf_grab_regstate)(struct Elf_(r_bin_elf_obj_t) *bin, int *len)
}
int Elf_(r_bin_elf_is_big_endian)(struct Elf_(r_bin_elf_obj_t) *bin) {
if (bin->ehdr.e_machine == EM_PPC) {
return false;
}
return (bin->ehdr.e_ident[EI_DATA] == ELFDATA2MSB);
}

View File

@ -1679,7 +1679,9 @@ int MACH0_(get_bits)(struct MACH0_(obj_t)* bin) {
}
int MACH0_(is_big_endian)(struct MACH0_(obj_t)* bin) {
return bin && bin->big_endian;
bool is_ppc = bin && bin->hdr.cputype == CPU_TYPE_POWERPC64;
if (!is_ppc) is_ppc = bin && bin->hdr.cputype == CPU_TYPE_POWERPC;
return is_ppc;
}
const char* MACH0_(get_intrp)(struct MACH0_(obj_t)* bin) {

View File

@ -345,15 +345,13 @@ static RBinInfo* info(RBinFile *arch) {
ret->arch = MACH0_(get_cputype) (arch->o->bin_obj);
ret->machine = MACH0_(get_cpusubtype) (arch->o->bin_obj);
ret->type = MACH0_(get_filetype) (arch->o->bin_obj);
ret->big_endian = MACH0_(is_big_endian) (arch->o->bin_obj);
ret->bits = 32;
ret->big_endian = 0;
if (arch && arch->o && arch->o->bin_obj) {
ret->has_crypto = ((struct MACH0_(obj_t)*)
arch->o->bin_obj)->has_crypto;
ret->bits = MACH0_(get_bits) (arch->o->bin_obj);
ret->big_endian = MACH0_(is_big_endian) (arch->o->bin_obj);
}
ret->has_va = true;
ret->has_pi = MACH0_(is_pie) (arch->o->bin_obj);
return ret;
@ -364,7 +362,6 @@ static int check(RBinFile *arch) {
const ut8 *bytes = arch ? r_buf_buffer (arch->buf) : NULL;
ut64 sz = arch ? r_buf_size (arch->buf): 0;
return check_bytes (bytes, sz);
}
static int check_bytes(const ut8 *buf, ut64 length) {