Add objc.pl to import ObjC class info into r2, enhace arm.cs and more

- Fix @@ flagname*
- Fix precision bug in r_num_units()
- Better ARM Thumb code analysis (still pretty basic)
This commit is contained in:
pancake 2014-05-14 03:53:22 +02:00
parent 1ec978e844
commit 728dd81352
5 changed files with 71 additions and 13 deletions

34
doc/objc.pl Executable file
View file

@ -0,0 +1,34 @@
#!/usr/bin/perl
# Extract OBJC class information into a radare2 script
# author: pancake 2014
my $file = $ARGV[0] or die ("Usage: objc.pl [file]\n");
my $class = "";
my $bits = 32;
local $classdump = qx(class-dump -A "$file") or die ("Cannot open file\n");
foreach my $line (split /[\r\n]+/, $classdump) {
if ($line=~/Arch: /) {
if ($line=~/arm/) {
print "e asm.arch=arm.cs\n";
print "e anal.arch=arm.cs\n";
}
} elsif ($line=~/^\@interface ([^\ ]*)/) {
$class = $1;
} elsif ($line=~/IMP=0x(.*)$/) {
my $addr = hex ("0x".$1);
if ($line=~/\)([^:;]+)/) {
my $method = $1;
if ($addr & 1) {
$addr--;
$bits = 16; # enable thumb mode by default
#$method .= "_THUMB";
} else {
#$method .= "_ARM";
}
printf ("f objc.".$class."_".$method." = 0x%x\n",$addr);
}
}
}
print "e asm.bits=$bits\n";

View file

@ -14,7 +14,7 @@ static int analop(RAnal *a, RAnalOp *op, ut64 addr, const ut8 *buf, int len) {
cs_open (CS_ARCH_ARM, mode, &handle);
cs_option (handle, CS_OPT_DETAIL, CS_OPT_ON);
op->type = R_ANAL_OP_TYPE_NULL;
op->size = 0;
op->size = (a->bits==16)? 2: 4;
op->delay = 0;
if (ret == CS_ERR_OK) {
n = cs_disasm_ex (handle, (ut8*)buf, len, addr, 1, &insn);
@ -23,9 +23,29 @@ static int analop(RAnal *a, RAnalOp *op, ut64 addr, const ut8 *buf, int len) {
} else {
op->size = insn->size;
switch (insn->id) {
case ARM_INS_POP:
if (cs_reg_read (handle, insn, ARM_REG_PC)) {
op->type = R_ANAL_OP_TYPE_RET;
} else {
op->type = R_ANAL_OP_TYPE_POP;
}
break;
case ARM_INS_SUB:
op->type = R_ANAL_OP_TYPE_SUB;
break;
case ARM_INS_ADD:
op->type = R_ANAL_OP_TYPE_ADD;
break;
case ARM_INS_MOV:
case ARM_INS_MOVS:
case ARM_INS_MOVT:
case ARM_INS_MOVW:
case ARM_INS_VMOVL:
case ARM_INS_VMOVN:
case ARM_INS_VQMOVUN:
case ARM_INS_VQMOVN:
op->type = R_ANAL_OP_TYPE_MOV;
break;
case ARM_INS_TST:
op->type = R_ANAL_OP_TYPE_CMP;
break;
@ -36,8 +56,9 @@ static int analop(RAnal *a, RAnalOp *op, ut64 addr, const ut8 *buf, int len) {
break;
case ARM_INS_PUSH:
case ARM_INS_STR:
case ARM_INS_POP:
//case ARM_INS_POP:
case ARM_INS_LDR:
op->type = R_ANAL_OP_TYPE_LOAD;
break;
case ARM_INS_BL:
case ARM_INS_BLX:

View file

@ -348,8 +348,10 @@ R_API void r_cons_flush() {
r_cons_reset ();
} else if (I.buffer_len > CONS_MAX_USER) {
if (!r_cons_yesno ('n',"Do you want to print %d chars? (y/N)",
I.buffer_len)) {
char buf[64];
char *buflen = r_num_units (buf, I.buffer_len);
if (!r_cons_yesno ('n',"Do you want to print %s chars? (y/N)",
buflen)) {
r_cons_reset ();
return;
}

View file

@ -1355,7 +1355,7 @@ repeat_arroba:
goto next_arroba; //ignore; //return ret;
}
ignore:
for (ptr++;*ptr== ' ';ptr++); ptr--;
for (ptr++; *ptr== ' '; ptr++); ptr--;
cmd = r_str_clean (cmd);
if (ptr2) {
if (strlen (ptr+1)==13 && strlen (ptr2+1)==6 && \
@ -1385,7 +1385,7 @@ ignore:
}
next_arroba:
if (arroba) {
ptr = arroba; //-3;
ptr = arroba;
arroba = NULL;
goto repeat_arroba;
}
@ -1520,13 +1520,14 @@ R_API int r_core_cmd_foreach(RCore *core, const char *cmd, char *each) {
break;
str[i] = ch;
{
int flagspace = core->flags->space_idx;
/* for all flags in current flagspace */
// XXX: dont ask why, but this only works with _prev..
r_list_foreach_prev (core->flags->flags, iter, flag) {
if (r_cons_singleton()->breaked)
break;
/* filter per flag spaces */
if ((core->flags->space_idx != -1) && (flag->space != core->flags->space_idx))
if ((flagspace != -1) && (flag->space != flagspace))
continue;
if (r_str_glob (flag->name, word)) {
r_core_seek (core, flag->offset, 1);
@ -1537,7 +1538,7 @@ R_API int r_core_cmd_foreach(RCore *core, const char *cmd, char *each) {
}
}
r_cons_break (NULL, NULL);
core->flags->space_idx = flagspace;
core->rcmd->macro.counter++ ;
free (word);
word = NULL;

View file

@ -79,14 +79,14 @@ R_API void r_num_free(RNum *num) {
R_API char *r_num_units(char *buf, ut64 num) {
char unit;
double fnum;
double fnum = num;
if (!buf) buf = malloc (32);
//if (num>TB) { unit = 'T'; fnum = num/TB; } else
if (num>GB) { unit = 'G'; fnum = num/GB; } else
if (num>MB) { unit = 'M'; fnum = num/MB; } else
if (num>KB) { unit = 'K'; fnum = num/KB; } else
if (num>GB) { unit = 'G'; fnum = fnum/GB; } else
if (num>MB) { unit = 'M'; fnum = fnum/MB; } else
if (num>KB) { unit = 'K'; fnum = fnum/KB; } else
{ unit = 0; fnum = num; }
snprintf (buf, 32, "%.1f%c", fnum, unit);
snprintf (buf, 31, "%.1f%c", fnum, unit);
return buf;
}