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:
parent
1ec978e844
commit
728dd81352
5 changed files with 71 additions and 13 deletions
34
doc/objc.pl
Executable file
34
doc/objc.pl
Executable 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";
|
||||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue