mirror of
https://github.com/radareorg/radare2.git
synced 2025-01-27 00:05:10 +00:00
Fixes for powerpc endian in mach0 and other issues
This commit is contained in:
parent
649748a8f2
commit
eb9feef231
@ -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;
|
||||
|
@ -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 = {
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user