Initial ic, ia refactor and make icc take lang as argument ##shell

This commit is contained in:
pancake 2023-11-24 19:27:17 +01:00 committed by GitHub
parent be612f7bfd
commit 50f13fc9b8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 1420 additions and 1299 deletions

View File

@ -1505,7 +1505,9 @@ R_API void r_bin_name_demangled(RBinName *bn, const char *dname) {
}
R_API char *r_bin_name_tostring(RBinName *bn) {
r_return_val_if_fail (bn, NULL);
if (!bn) {
return NULL;
}
if (bn->name) {
return bn->name;
}
@ -1517,7 +1519,9 @@ R_API char *r_bin_name_tostring(RBinName *bn) {
// prefered type
R_API char *r_bin_name_tostring2(RBinName *bn, int type) {
r_return_val_if_fail (bn, NULL);
if (!bn) {
return NULL;
}
if (type == 'd' && bn->name) {
return bn->name;
} else if (type == 'f' && bn->fname) {

View File

@ -3698,6 +3698,9 @@ static void classdump_java(RCore *r, RBinClass *c) {
*cn = 0;
cn++;
r_str_replace_char (pn, '/', '.');
} else {
char *dot = (char *)r_str_rchr (pn, NULL, '.');
cn = dot? dot + 1: pn;
}
r_cons_printf ("package %s;\n\n", pn);
r_cons_printf ("public class %s {\n", cn);
@ -3706,7 +3709,7 @@ static void classdump_java(RCore *r, RBinClass *c) {
if (f->name && f->kind == R_BIN_FIELD_KIND_VARIABLE) {
const char *fname = r_bin_name_tostring2 (f->name, pref);
const char *tp = r_bin_name_tostring2 (f->type, pref);
r_cons_printf (" public %s %s\n", tp? tp: "int", fname);
r_cons_printf (" public %s %s\n", R_STR_ISNOTEMPTY (tp)? tp: "Object", fname);
}
}
r_list_foreach (c->methods, iter, sym) {

View File

@ -19,7 +19,7 @@ static RCoreHelpMessage help_msg_i = {
"ic.", "", "show class and method name in current seek",
"ic-", "[klass.method]", "delete given klass or klass.name",
"ic+", "[klass.method]", "add new symbol in current seek for a given klass and method name",
"icc", "", "List classes, methods and fields in Header Format",
"icc", " [lang]", "List classes, methods and fields in Header Format (see bin.lang=swift,java,objc,cxx)",
"icg", " [str]", "List classes as agn/age commands to create class hierarchy graphs (matches str if provided)",
"icq", "", "List classes, in quiet mode (just the classname)",
"icqq", "", "List classes, in quieter mode (only show non-system classnames)",
@ -97,7 +97,6 @@ static void pair(const char *a, const char *b) {
r_cons_printf ("%s%s%s\n", a, ws, b);
}
static void classdump_keys(RCore *core, RBinObject *bo) {
const bool iova = r_config_get_b (core->config, "io.va");
RBinClass *k;
@ -442,7 +441,7 @@ static void cmd_info_bin(RCore *core, int va, PJ *pj, int mode) {
}
}
static void playMsg(RCore *core, const char *n, int len) {
static void tts_say(RCore *core, const char *n, int len) {
if (r_config_get_b (core->config, "scr.tts")) {
char *s = (*n && len > 0)
? r_str_newf ("%d %s", len, n)
@ -536,7 +535,7 @@ static bool isKnownPackage(const char *cn) {
static void cmd_ic_comma(RCore *core, const char *input) {
r_return_if_fail (core && input[0] == 'c' && input[1] == ',');
const char *q = input + 2;
RList *objs = r_core_bin_files (core);
RList *bfiles = r_core_bin_files (core);
RListIter *objs_iter;
RBinFile *bf;
RBinFile *cur = core->bin->cur;
@ -548,7 +547,7 @@ static void cmd_ic_comma(RCore *core, const char *input) {
r_table_add_column (t, typeString, "klass", 0);
r_table_add_column (t, typeString, "name", 0);
const bool iova = r_config_get_b (core->config, "io.va");
r_list_foreach (objs, objs_iter, bf) {
r_list_foreach (bfiles, objs_iter, bf) {
RBinObject *obj = bf->bo;
RBinClass *klass;
RListIter *iter, *iter2;
@ -572,7 +571,7 @@ static void cmd_ic_comma(RCore *core, const char *input) {
}
}
core->bin->cur = cur;
r_list_free (objs);
r_list_free (bfiles);
if (r_table_query (t, q)) {
char *s = r_table_tostring (t);
r_cons_printf ("%s\n", s);
@ -581,7 +580,7 @@ static void cmd_ic_comma(RCore *core, const char *input) {
r_table_free (t);
}
void cmd_ic_sub(RCore *core, const char *input) {
static void cmd_ic_sub(RCore *core, const char *input) {
RListIter *iter;
RBinClass *k;
RBinSymbol *m;
@ -670,13 +669,382 @@ void cmd_ic_add(RCore *core, const char *input) {
}
}
static void cmd_icg(RCore *core, RBinObject *obj, const char *arg) { // "icg"
const int pref = r_config_get_b (core->config, "asm.demangle")? 0: 'o';
RBinClass *cls;
RListIter *iter, *iter2;
if (!obj) {
return;
}
bool fullGraph = true;
const char *match = r_str_trim_head_ro (arg);
if (R_STR_ISNOTEMPTY (match)) {
r_list_foreach (obj->classes, iter, cls) {
if (!match || !strstr (cls->name, match)) {
continue;
}
r_cons_printf ("agn %s\n", cls->name);
if (cls->super) {
RBinName *bn;
r_list_foreach (cls->super, iter2, bn) {
const char *sk = r_bin_name_tostring2 (bn, pref);
if (match && strstr (sk, match)) {
r_cons_printf ("agn %s\n", sk);
r_cons_printf ("age %s %s\n", sk, cls->name);
}
}
}
}
} else if (fullGraph) {
r_list_foreach (obj->classes, iter, cls) {
RBinName *bn;
r_cons_printf ("agn %s\n", cls->name);
r_list_foreach (cls->super, iter2, bn) {
const char *sk = r_bin_name_tostring2 (bn, pref);
r_cons_printf ("agn %s\n", sk);
r_cons_printf ("age %s %s\n", sk, cls->name);
}
}
} else {
r_list_foreach (obj->classes, iter, cls) {
char *sk;
RListIter *iter;
r_list_foreach (cls->super, iter, sk) {
if (strstr (sk, "NSObject")) {
continue;
}
r_cons_printf ("agn %s\n", sk);
r_cons_printf ("agn %s\n", cls->name);
r_cons_printf ("age %s %s\n", sk, cls->name);
}
}
}
}
#define RBININFO(n,x,y,z)\
if (is_array) {\
pj_k (pj, n);\
}\
if (z) { tts_say (core, n, z);}\
r_core_bin_info (core, x, pj, mode, va, NULL, y);
static void cmd_ic(RCore *core, const char *input, PJ *pj, int is_array, bool va) {
int cmd = input[0];
int mode = 0;
const char *arg = input + 2;
const char *lastchar = strchr (input, ' ');
if (lastchar) {
arg = r_str_trim_head_ro (lastchar + 1);
lastchar = lastchar - 1;
} else {
arg = "";
lastchar = input + strlen (input) - 1;
}
switch (*lastchar) {
case 'j':
case 'k':
case '*':
case 'q': // quiet
case 'Q': // quieter
case ',':
mode = *lastchar;
if (cmd == *lastchar) {
cmd = 0;
}
break;
default:
mode = 0;
break;
}
if (mode == ',') {
cmd_ic_comma (core, input);
}
bool is_superquiet = strstr (input, "qq");
bool is_doublerad = strstr (input, "**");
///
switch (cmd) {
// help message
case '?': // "ic?"
r_core_cmd_help_contains (core, help_msg_i, "ic");
break;
case '-': // "ic-"
cmd_ic_sub (core, input);
break;
case '+': // "ic+"
cmd_ic_add (core, input + 2);
break;
// commands that iterate
case ' ': // "ic "
case 'k': // "ick"
case '.': // "ic."
case 's': // "ics"
case 'g': // "icg"
case 'j': // "icj"
case 'l': // "icl"
case 'c': // "icc"
case '*': // "ic*"
case 0: // "ic" "icq"
{
const bool iova = r_config_get_b (core->config, "io.va");
RListIter *objs_iter;
RBinFile *bf;
RBinFile *cur = core->bin->cur;
RList *objs = r_core_bin_files (core);
int count = 0;
bool filtered = false;
int idx = -1;
const char *cls_name = NULL;
if (r_num_is_valid_input (core->num, arg)) {
idx = r_num_math (core->num, arg);
} else {
const char *first_char = arg;
int not_space = strspn (first_char, " ");
if (first_char[not_space]) {
cls_name = first_char + not_space;
}
}
bool first = true;
r_list_foreach (objs, objs_iter, bf) {
RBinObject *obj = bf->bo;
if (!obj || !obj->classes || r_list_empty (obj->classes)) {
if (mode == 'j') {
r_cons_printf ("%s{}", first? "": ",");
}
first = false;
continue;
}
first = false;
if (filtered) {
break;
}
RBinClass *cls;
RBinSymbol *sym;
RListIter *iter, *iter2;
core->bin->cur = bf;
if (is_superquiet) {
r_list_foreach (obj->classes, iter, cls) {
if (!isKnownPackage (cls->name)) {
r_cons_printf ("%s\n", cls->name);
}
}
break;
}
tts_say (core, "classes", r_list_length (obj->classes));
switch (cmd) {
case 'g':
cmd_icg (core, obj, arg);
break;
case 's': // "ics"
r_list_foreach (obj->classes, iter, cls) {
r_list_foreach (cls->methods, iter2, sym) {
ut64 addr = iova? sym->vaddr: sym->paddr;
if (addr == 0 || addr == UT64_MAX) {
continue;
}
r_cons_printf ("0x%"PFMT64x" [%s] %s\n",
addr, cls->name, sym->name);
}
}
break;
case 'k': // "ick"
classdump_keys (core, obj);
return;
case 'l': // "icl"
r_list_foreach (obj->classes, iter, cls) {
r_list_foreach (cls->methods, iter2, sym) {
const char *comma = iter2->p? " ": "";
r_cons_printf ("%s0x%"PFMT64x, comma,
iova? sym->vaddr: sym->paddr);
}
if (!r_list_empty (cls->methods)) {
r_cons_newline ();
}
}
break;
case '.': // "ic."
{
ut64 addr = core->offset;
ut64 min = UT64_MAX;
const char *method = NULL;
ut64 max = 0LL;
r_list_foreach (obj->classes, iter, cls) {
method = NULL;
r_list_foreach (cls->methods, iter2, sym) {
ut64 at = iova? sym->vaddr: sym->paddr;
if (at < min) {
min = at;
}
if (at + sym->size > max) {
max = at + sym->size;
}
if (addr >= at && addr <= at + sym->size) {
method = sym->name;
}
}
if (addr >= min && addr < max) {
if (method) {
r_cons_printf ("%s::%s\n", cls->name, method);
} else {
r_cons_printf ("%s\n", cls->name);
}
}
min = UT64_MAX;
max = 0LL;
}
}
break;
case 'c': // "icc"
mode = R_MODE_CLASSDUMP;
eprintf ("icc\n");
if (mode == '*') {
mode |= R_MODE_RADARE;
} else if (mode == 'k') { // "icck"
classdump_keys (core, obj);
return;
}
const char *lang = strchr (input, ' ');
char *olang = NULL;
if (lang) {
olang = strdup (r_config_get (core->config, "bin.lang"));
r_config_set (core->config, "bin.lang", lang + 1);
}
RBININFO ("classes", R_CORE_BIN_ACC_CLASSES, NULL, r_list_length (obj->classes));
if (olang) {
r_config_set (core->config, "bin.lang", olang);
free (olang);
}
// input = " ";
break;
case 'q':
if (mode == 'j') {
mode = R_MODE_JSON;
}
RBININFO ("classes", R_CORE_BIN_ACC_CLASSES, NULL, r_list_length (obj->classes));
break;
case ' ': // "ic"
case 0: // "ic"
default:
{
r_list_foreach (obj->classes, iter, cls) {
if ((idx >= 0 && idx != count++) || (R_STR_ISNOTEMPTY (cls_name) && strcmp (cls_name, cls->name))) {
continue;
}
if (is_doublerad) {
r_cons_printf ("ac %s\n", cls->name);
r_list_foreach (cls->methods, iter2, sym) {
r_cons_printf ("ac %s %s 0x%08"PFMT64x"\n", cls->name,
sym->name, iova? sym->vaddr: sym->paddr);
}
eprintf ("doble rad quit\n");
continue;
}
bool listed_classes = false;
if (idx != -1 || R_STR_ISNOTEMPTY (cls_name)) {
filtered = true;
r_cons_printf ("class %s\n", cls->name);
r_list_foreach (cls->methods, iter2, sym) {
char *flags = r_core_bin_attr_tostring (sym->attr, true);
r_cons_printf ("0x%08"PFMT64x " method %s %-4s %s\n",
iova? sym->vaddr: sym->paddr,
cls->name, flags, sym->name);
free (flags);
}
continue;
}
switch (mode) {
case '*':
{
listed_classes = true;
int mode = R_MODE_RADARE;
RBININFO ("classes", R_CORE_BIN_ACC_CLASSES, NULL, r_list_length (obj->classes));
}
#if 0
r_list_foreach (cls->methods, iter2, sym) {
r_cons_printf ("f sym.%s @ 0x%"PFMT64x "\n",
sym->name, iova? sym->vaddr: sym->paddr);
}
#endif
break;
case 'l': // "icl"
r_list_foreach (cls->methods, iter2, sym) {
const char *comma = iter2->p? " ": "";
r_cons_printf ("%s0x%"PFMT64x, comma,
iova? sym->vaddr: sym->paddr);
}
r_cons_newline ();
input++;
break;
case 'j':
{
int mode = R_MODE_JSON; // (oldmode == 'q')? R_MODE_SIMPLE: 0;
int len = r_list_length (obj->classes);
listed_classes = true;
RBININFO ("classes", R_CORE_BIN_ACC_CLASSES, NULL, len);
}
#if 0
input++;
pj_ks (pj, "class", cls->name);
pj_ka (pj, "methods");
r_list_foreach (cls->methods, iter2, sym) {
pj_o (pj);
pj_ks (pj, "name", sym->name);
if (sym->attr) {
// TODO: must be an array of strings
char *flags = r_core_bin_attr_tostring (sym->attr, false);
pj_k (pj, "flags");
pj_j (pj, flags);
free (flags);
}
pj_kN (pj, "vaddr", sym->vaddr);
pj_kN (pj, "paddr", sym->paddr);
pj_end (pj);
}
pj_end (pj);
#endif
break;
case 0:
case 'q':
{
size_t len = r_list_length (obj->classes);
int oldmode = mode;
int mode = (oldmode == 'q')? R_MODE_SIMPLE: 0;
RBININFO ("classes", R_CORE_BIN_ACC_CLASSES, NULL, len);
listed_classes = true;
}
break;
default:
r_cons_printf ("class %s\n", cls->name);
r_list_foreach (cls->methods, iter2, sym) {
char *flags = r_core_bin_attr_tostring (sym->attr, true);
r_cons_printf ("0x%08"PFMT64x " method %s %-4s %s\n",
iova? sym->vaddr: sym->paddr,
cls->name, flags, sym->name);
free (flags);
}
break;
}
if (listed_classes) {
break;
}
}
}
break;
}
core->bin->cur = cur;
}
break;
}
}
}
static int cmd_info(void *data, const char *input) {
RCore *core = (RCore *) data;
int fd = r_io_fd_get_current (core->io);
RIODesc *desc = r_io_desc_get (core->io, fd);
int i;
const bool va = core->io->va || r_config_get_b (core->config, "cfg.debug");
int mode = 0;
bool rdump = false;
int is_array = 0;
bool is_izzzj = false;
@ -688,6 +1056,9 @@ static int cmd_info(void *data, const char *input) {
r_cons_printf ("GOD MODE ON\n");
return 0;
}
int mode = 0;
#if 1
// advance input until theres a space.. maybe not needed
for (i = 0; input[i] && input[i] != ' '; i++)
;
if (i > 0) {
@ -695,8 +1066,10 @@ static int cmd_info(void *data, const char *input) {
case '*': mode = R_MODE_RADARE; break;
case 'j': mode = R_MODE_JSON; break;
case 'q': mode = R_MODE_SIMPLE; break;
case 'k': mode = R_MODE_KV; break;
}
}
#endif
#define INIT_PJ()\
if (!pj) {\
pj = r_core_pj_new (core);\
@ -755,13 +1128,6 @@ static int cmd_info(void *data, const char *input) {
core->table_query = r_str_trim_dup (space + 1);
}
#define RBININFO(n,x,y,z)\
if (is_array) {\
pj_k (pj, n);\
}\
if (z) { playMsg (core, n, z);}\
r_core_bin_info (core, x, pj, mode, va, NULL, y);
switch (input[0]) {
case 'i': // "ii"
if (input[1] == 'c') { // "iic"
@ -783,21 +1149,21 @@ static int cmd_info(void *data, const char *input) {
goto done;
break;
case 'a': // "ia"
{
int arg = 0;
if (r_bin_cur_object (core->bin)) {
int narg = 0;
switch (mode) {
case R_MODE_RADARE: arg = '*'; break;
case R_MODE_SIMPLE: arg = 'q'; break;
case R_MODE_JSON:
case R_MODE_RADARE: narg = '*'; break;
case R_MODE_SIMPLE: narg = 'q'; break;
case R_MODE_JSON: // "iaj"
r_cons_printf ("{\"i\":");
arg = 'j';
narg = 'j';
break;
}
char cmd[8];
cmd[0] = arg;
cmd[0] = narg;
cmd[1] = 0;
cmd_info (core, cmd);
cmd[1] = arg;
cmd[1] = narg;
cmd[2] = 0;
const char *subcmds = "ieEcsSmz";
while (*subcmds) {
@ -811,9 +1177,31 @@ static int cmd_info(void *data, const char *input) {
if (mode == R_MODE_JSON) {
r_cons_println ("}");
}
} else {
r_cons_println ("{}");
}
goto done;
break;
case 'b': // "ib"
{
const char *arg = strchr (input, ' ');
if (arg) {
arg++;
}
ut64 baddr = arg? r_num_math (core->num, arg) : r_config_get_i (core->config, "bin.baddr");
// XXX: this will reload the bin using the buffer.
// An assumption is made that assumes there is an underlying
// plugin that will be used to load the bin (e.g. malloc://)
// TODO: Might be nice to reload a bin at a specified offset?
__r_core_bin_reload (core, NULL, baddr);
r_core_block_read (core);
}
goto done;
break;
case 'c': // "ic"
cmd_ic (core, input + 1, pj, is_array, va);
goto done;
break;
}
// TODO: slowly deprecate the loopy subcommands in here
while (*input) {
@ -822,16 +1210,6 @@ static int cmd_info(void *data, const char *input) {
break;
}
switch (*input) {
case 'b': // "ib"
{
ut64 baddr = (input[1] == ' ')? r_num_math (core->num, input + 1) : r_config_get_i (core->config, "bin.baddr");
// XXX: this will reload the bin using the buffer.
// An assumption is made that assumes there is an underlying
// plugin that will be used to load the bin (e.g. malloc://)
// TODO: Might be nice to reload a bin at a specified offset?
__r_core_bin_reload (core, NULL, baddr);
r_core_block_read (core);
}
break;
case 'k': // "ik"
{
@ -1051,13 +1429,13 @@ static int cmd_info(void *data, const char *input) {
break;
case 'H': // "iH"
if (input[1] == 'H') { // "iHH"
playMsg (core, "header", -1);
tts_say (core, "header", -1);
if (!r_core_bin_info (core, R_CORE_BIN_ACC_HEADER, pj, mode, va, NULL, NULL)) {
R_LOG_ERROR ("No header fields found");
}
break;
} else {
playMsg (core, "fields", -1);
tts_say (core, "fields", -1);
if (!r_core_bin_info (core, R_CORE_BIN_ACC_FIELDS, pj, mode, va, NULL, NULL)) {
R_LOG_ERROR ("No header fields found");
}
@ -1348,31 +1726,31 @@ static int cmd_info(void *data, const char *input) {
break;
case 'V': // "iV"
{
RList *objs = r_core_bin_files (core);
RList *bfiles= r_core_bin_files (core);
RListIter *iter;
RBinFile *bf;
RBinFile *cur = core->bin->cur;
r_list_foreach (objs, iter, bf) {
r_list_foreach (bfiles, iter, bf) {
core->bin->cur = bf;
RBININFO ("versioninfo", R_CORE_BIN_ACC_VERSIONINFO, NULL, 0);
}
core->bin->cur = cur;
r_list_free (objs);
r_list_free (bfiles);
}
break;
case 'T': // "iT"
case 'C': // "iC" // rabin2 -C create // should be deprecated and just use iT (or find a better name)
{
RList *objs = r_core_bin_files (core);
RList *bfiles = r_core_bin_files (core);
RListIter *iter;
RBinFile *bf;
RBinFile *cur = core->bin->cur;
r_list_foreach (objs, iter, bf) {
r_list_foreach (bfiles, iter, bf) {
core->bin->cur = bf;
RBININFO ("signature", R_CORE_BIN_ACC_SIGNATURE, NULL, 0);
}
core->bin->cur = cur;
r_list_free (objs);
r_list_free (bfiles);
}
break;
case 'z': // "iz"
@ -1455,288 +1833,23 @@ static int cmd_info(void *data, const char *input) {
break;
}
if (validcmd) {
RList *objs = r_core_bin_files (core);
RList *bfiles = r_core_bin_files (core);
RListIter *iter;
RBinFile *bf;
RBinFile *cur = core->bin->cur;
r_list_foreach (objs, iter, bf) {
r_list_foreach (bfiles, iter, bf) {
core->bin->cur = bf;
RBinObject *obj = r_bin_cur_object (core->bin);
RBININFO ("strings", R_CORE_BIN_ACC_STRINGS, NULL,
(obj && obj->strings)? r_list_length (obj->strings): 0);
}
core->bin->cur = cur;
r_list_free (objs);
r_list_free (bfiles);
} else {
//
}
}
break;
case 'c': // "ic"
// XXX this is dupe of cbin.c:bin_classes()
if (input[1] == '?') {
r_core_cmd_help_contains (core, help_msg_i, "ic");
} else if (input[1] == ',') { // "ic,"
cmd_ic_comma (core, input);
} else if (input[1] == '-') { // "ic-"
cmd_ic_sub (core, input + 2);
} else if (input[1] == '+') { // "ic+"
cmd_ic_add (core, input + 2);
} else if (input[1] == 'g') { // "icg"
const bool asm_demangle = r_config_get_b (core->config, "asm.demangle");
const int pref = asm_demangle? 0: 'o';
RBinClass *cls;
RListIter *iter, *iter2;
RBinObject *obj = r_bin_cur_object (core->bin);
if (!obj) {
break;
}
bool fullGraph = true;
const char *match = r_str_trim_head_ro (input + 2);
if (R_STR_ISNOTEMPTY (match)) {
r_list_foreach (obj->classes, iter, cls) {
if (!match || !strstr (cls->name, match)) {
continue;
}
r_cons_printf ("agn %s\n", cls->name);
if (cls->super) {
RBinName *bn;
r_list_foreach (cls->super, iter2, bn) {
const char *sk = r_bin_name_tostring2 (bn, pref);
if (match && strstr (sk, match)) {
r_cons_printf ("agn %s\n", sk);
r_cons_printf ("age %s %s\n", sk, cls->name);
}
}
}
}
} else if (fullGraph) {
r_list_foreach (obj->classes, iter, cls) {
RBinName *bn;
r_cons_printf ("agn %s\n", cls->name);
r_list_foreach (cls->super, iter2, bn) {
const char *sk = r_bin_name_tostring2 (bn, pref);
r_cons_printf ("agn %s\n", sk);
r_cons_printf ("age %s %s\n", sk, cls->name);
}
}
} else {
r_list_foreach (obj->classes, iter, cls) {
char *sk;
RListIter *iter;
r_list_foreach (cls->super, iter, sk) {
if (strstr (sk, "NSObject")) {
continue;
}
r_cons_printf ("agn %s\n", sk);
r_cons_printf ("agn %s\n", cls->name);
r_cons_printf ("age %s %s\n", sk, cls->name);
}
}
}
goto done;
} else if (input[1] == ' ' || input[1] == 'k' || input[1] == '.' || input[1] == 's' || input[1] == 'q' || input[1] == 'j' || input[1] == 'l' || input[1] == 'c' || input[1] == '*') {
const bool iova = r_config_get_b (core->config, "io.va");
RList *objs = r_core_bin_files (core);
RListIter *objs_iter;
RBinFile *bf;
RBinFile *cur = core->bin->cur;
r_list_foreach (objs, objs_iter, bf) {
RBinObject *obj = bf->bo;
RBinClass *cls;
RBinSymbol *sym;
RListIter *iter, *iter2;
core->bin->cur = bf;
//RBinObject *obj = r_bin_cur_object (core->bin);
if (!obj) {
break;
}
if (input[2] && input[2] != '*' && input[2] != 'j' && !strstr (input, "qq")) {
bool radare2 = strstr (input, "**");
int idx = -1;
const char * cls_name = NULL;
if (radare2) {
input ++;
}
if (r_num_is_valid_input (core->num, input + 2)) {
idx = r_num_math (core->num, input + 2);
} else {
const char * first_char = input + ((input[1] == ' ') ? 1 : 2);
int not_space = strspn (first_char, " ");
if (first_char[not_space]) {
cls_name = first_char + not_space;
}
}
if (radare2) {
input++;
}
int count = 0;
int mode = input[1];
r_list_foreach (obj->classes, iter, cls) {
if (radare2) {
r_cons_printf ("ac %s\n", cls->name);
r_list_foreach (cls->methods, iter2, sym) {
r_cons_printf ("ac %s %s 0x%08"PFMT64x"\n", cls->name,
sym->name, iova? sym->vaddr: sym->paddr);
}
continue;
}
if ((idx >= 0 && idx != count++) || (R_STR_ISNOTEMPTY (cls_name) && strcmp (cls_name, cls->name))) {
continue;
}
switch (mode) {
case '*':
r_list_foreach (cls->methods, iter2, sym) {
r_cons_printf ("f sym.%s @ 0x%"PFMT64x "\n",
sym->name, iova? sym->vaddr: sym->paddr);
}
input++;
break;
case 'l':
r_list_foreach (cls->methods, iter2, sym) {
const char *comma = iter2->p? " ": "";
r_cons_printf ("%s0x%"PFMT64x, comma,
iova? sym->vaddr: sym->paddr);
}
r_cons_newline ();
input++;
break;
case 'j':
input++;
pj_ks (pj, "class", cls->name);
pj_ka (pj, "methods");
r_list_foreach (cls->methods, iter2, sym) {
pj_o (pj);
pj_ks (pj, "name", sym->name);
if (sym->attr) {
// TODO: must be an array of strings
char *flags = r_core_bin_attr_tostring (sym->attr, false);
pj_k (pj, "flags");
pj_j (pj, flags);
free (flags);
}
pj_kN (pj, "vaddr", sym->vaddr);
pj_kN (pj, "paddr", sym->paddr);
pj_end (pj);
}
pj_end (pj);
break;
default:
r_cons_printf ("class %s\n", cls->name);
r_list_foreach (cls->methods, iter2, sym) {
char *flags = r_core_bin_attr_tostring (sym->attr, true);
r_cons_printf ("0x%08"PFMT64x " method %s %-4s %s\n",
iova? sym->vaddr: sym->paddr,
cls->name, flags, sym->name);
free (flags);
}
break;
}
goto done;
}
goto done;
} else if (obj->classes) {
const bool iova = r_config_get_b (core->config, "io.va");
playMsg (core, "classes", r_list_length (obj->classes));
if (strstr (input, "qq")) { // "icqq"
r_list_foreach (obj->classes, iter, cls) {
if (!isKnownPackage (cls->name)) {
r_cons_printf ("%s\n", cls->name);
}
}
} else if (input[1] == 's') { // "ics"
r_list_foreach (obj->classes, iter, cls) {
r_list_foreach (cls->methods, iter2, sym) {
ut64 addr = iova? sym->vaddr: sym->paddr;
if (addr == 0 || addr == UT64_MAX) {
continue;
}
r_cons_printf ("0x%"PFMT64x" [%s] %s\n",
addr, cls->name, sym->name);
}
}
} else if (input[1] == 'k') { // "ick"
classdump_keys (core, obj);
goto done;
} else if (input[1] == 'l') { // "icl"
r_list_foreach (obj->classes, iter, cls) {
r_list_foreach (cls->methods, iter2, sym) {
const char *comma = iter2->p? " ": "";
r_cons_printf ("%s0x%"PFMT64x, comma,
iova? sym->vaddr: sym->paddr);
}
if (!r_list_empty (cls->methods)) {
r_cons_newline ();
}
}
} else if (input[1] == '.') { // "ic."
ut64 addr = core->offset;
ut64 min = UT64_MAX;
const char *method = NULL;
ut64 max = 0LL;
r_list_foreach (obj->classes, iter, cls) {
method = NULL;
r_list_foreach (cls->methods, iter2, sym) {
ut64 at = iova? sym->vaddr: sym->paddr;
if (at < min) {
min = at;
}
if (at + sym->size > max) {
max = at + sym->size;
}
if (addr >= at && addr <= at + sym->size) {
method = sym->name;
}
}
if (addr >= min && addr < max) {
if (method) {
r_cons_printf ("%s::%s\n", cls->name, method);
} else {
r_cons_printf ("%s\n", cls->name);
}
}
min = UT64_MAX;
max = 0LL;
}
} else if (input[1] == 'c') { // "icc"
mode = R_MODE_CLASSDUMP;
if (input[2] == '*') {
mode |= R_MODE_RADARE;
} else if (input[2] == 'k') { // "icck"
classdump_keys (core, obj);
goto done;
}
RBININFO ("classes", R_CORE_BIN_ACC_CLASSES, NULL, r_list_length (obj->classes));
input = " ";
} else { // "icq"
if (input[2] == 'j') {
mode |= R_MODE_JSON; // default mode is R_MODE_SIMPLE
}
RBININFO ("classes", R_CORE_BIN_ACC_CLASSES, NULL, r_list_length (obj->classes));
}
goto done;
}
}
core->bin->cur = cur;
r_list_free (objs);
} else { // "ic"
// R2_600 - all commands have RCore.binFiles() loop . this is racy and dupe, maybe good to separate this logic into a function that takes another function as argument to generalize and simplify code
RList *objs = r_core_bin_files (core);
RListIter *iter;
RBinFile *bf;
RBinFile *cur = core->bin->cur;
r_list_foreach (objs, iter, bf) {
core->bin->cur = bf;
RBinObject *obj = bf->bo;
if (obj && obj->classes) {
int len = r_list_length (obj->classes);
RBININFO ("classes", R_CORE_BIN_ACC_CLASSES, NULL, len);
}
}
core->bin->cur = cur;
r_list_free (objs);
}
break;
case 'D': // "iD"
if (input[1] != ' ' || !demangle (core, input + 2)) {
r_core_cmd_help_match (core, help_msg_i, "iD");

View File

@ -95,12 +95,10 @@ static RCoreHelpMessage help_msg_ss = {
};
static void __init_seek_line(RCore *core) {
ut64 from, to;
r_config_bump (core->config, "lines.to");
from = r_config_get_i (core->config, "lines.from");
ut64 from = r_config_get_i (core->config, "lines.from");
const char *to_str = r_config_get (core->config, "lines.to");
to = r_num_math (core->num, (to_str && *to_str) ? to_str : "$s");
ut64 to = r_num_math (core->num, (to_str && *to_str) ? to_str : "$s");
if (r_core_lines_initcache (core, from, to) == -1) {
R_LOG_ERROR ("lines.from and lines.to are not defined");
}

View File

@ -28,8 +28,9 @@
#define R_MODE_JSON 0x008
#define R_MODE_ARRAY 0x010
#define R_MODE_SIMPLEST 0x020
#define R_MODE_CLASSDUMP 0x040
#define R_MODE_CLASSDUMP 0x040 /* deprecate maybe */
#define R_MODE_EQUAL 0x080
#define R_MODE_KV 0x100
#define R_IN /* do not use, implicit */
#define R_OUT /* parameter is written, not read */

File diff suppressed because it is too large Load Diff

980
test/db/cmd/cmd_ic Normal file
View File

@ -0,0 +1,980 @@
NAME=ic cpp classes
FILE=bins/elf/libmagic.so
CMDS=<<EOF
ic~_JNIEnv
ic~FindClass
EOF
EXPECT=<<EOF
0x00000000 [0x00006060 - 0x0000697c] 2332 jni class 0 _JNIEnv
0x000074f8 jni method 0 inject(_JNIEnv*, _jobject*, _jstring*, _jstring*)
0x0000699c jni method 1 findBaseDexClassloader(_JNIEnv*, _jobject*)
0x00006a2c jni method 2 getField(_JNIEnv*, _jobject*, _jobject*, _jstring*)
0x00006abc jni method 3 getPathList(_JNIEnv*, _jobject*)
0x00006af4 jni method 4 getDexElements(_JNIEnv*, _jobject*)
0x00006b1c jni method 5 setField(_JNIEnv*, _jobject*, _jobject*, _jstring*, _jobject*)
0x00006bb0 jni method 6 combineArray(_JNIEnv*, _jobject*, _jobject*)
0x00006d00 jni method 7 injectAboveEqualApiLevel14(_JNIEnv*, _jobject*, _jstring*, _jstring*)
0x00006e5c jni method 8 appendArray(_JNIEnv*, _jobject*, _jobject*)
0x00006f68 jni method 9 injectInAliyunOs(_JNIEnv*, _jobject*, _jstring*, _jstring*)
0x0000720c jni method 10 injectBelowApiLevel14(_JNIEnv*, _jobject*, _jstring*, _jstring*)
0x00006060 jni method 0 FindClass(char const*)
EOF
RUN
NAME=ic?
BROKEN=1
FILE=bins/elf/libmagic.so
CMDS=ic?~?Usage
EXPECT=<<EOF
1
EOF
RUN
NAME=icg
FILE=bins/elf/libmagic.so
CMDS=<<EOF
icg
?e
icg _JNIEnv
?e
icg System
EOF
EXPECT=<<EOF
agn _JNIEnv
agn SystemClassLoaderInjector
agn std
agn std::exception
agn std::bad_exception
agn __cxxabiv1::__forced_unwind
agn __cxxabiv1::__foreign_exception
agn __eh_globals_init
agn __cxxabiv1
agn __cxxabiv1::__fundamental_type_info
agn std::type_info
agn __cxxabiv1::__pointer_type_info
agn __cxxabiv1::__pbase_type_info
agn __cxxabiv1::__si_class_type_info
agn __cxxabiv1::__class_type_info
agn __gnu_cxx
agn __gnu_cxx::__concurrence_lock_error
agn __gnu_cxx::__concurrence_unlock_error
agn std::bad_cast
agn std::bad_typeid
agn _JNIEnv
agn SystemClassLoaderInjector
EOF
RUN
NAME=icl
FILE=bins/elf/libmagic.so
CMDS=icl
EXPECT=<<EOF
0x6060 0x606a 0x6074 0x608e 0x6098 0x60a4 0x60c0 0x60dc 0x60ea 0x695e 0x697c
0x74f8 0x699c 0x6a2c 0x6abc 0x6af4 0x6b1c 0x6bb0 0x6d00 0x6e5c 0x6f68 0x720c
0x9470 0x886c 0x9494 0x94ac 0x94c8
0x8884 0x88f4
0x889c 0x8904
0x88c4
0x88dc
0x8984
0x943c 0x9488
0x94e4
0x97bc 0x97d4 0x97dc 0x9854 0x97e4 0x9808
0x9528 0x9530 0x9574
0x9df0 0x9e34 0x9dd0
0x95f4 0x9638 0x969c 0x977c
0x98d8 0x991c 0x9948 0x9868 0x98c4 0x998c
0x9ec4 0x12780 0x127c8
0x126b0 0x126f8
0x126c0 0x126d0
0x12bd8 0x12bc8
0x12c2c 0x12c1c
EOF
RUN
NAME=icj
FILE=bins/elf/libmagic.so
CMDS=icj~{}
EXPECT=<<EOF
[
{
"classname": "_JNIEnv",
"addr": 0,
"lang": "jni",
"index": 0,
"methods": [
{
"name": "FindClass(char const*)",
"flag": "method._JNIEnv.FindClass_char_const_",
"realname": "_ZN7_JNIEnv9FindClassEPKc",
"addr": 24672
},
{
"name": "DeleteLocalRef(_jobject*)",
"flag": "method._JNIEnv.DeleteLocalRef__jobject_",
"realname": "_ZN7_JNIEnv14DeleteLocalRefEP8_jobject",
"addr": 24682
},
{
"name": "NewObject(_jclass*, _jmethodID*, ...)",
"flag": "method._JNIEnv.NewObject__jclass___jmethodID__..._",
"realname": "_ZN7_JNIEnv9NewObjectEP7_jclassP10_jmethodIDz",
"addr": 24692
},
{
"name": "GetObjectClass(_jobject*)",
"flag": "method._JNIEnv.GetObjectClass__jobject_",
"realname": "_ZN7_JNIEnv14GetObjectClassEP8_jobject",
"addr": 24718
},
{
"name": "GetMethodID(_jclass*, char const*, char const*)",
"flag": "method._JNIEnv.GetMethodID__jclass__char_const__char_const_",
"realname": "_ZN7_JNIEnv11GetMethodIDEP7_jclassPKcS3_",
"addr": 24728
},
{
"name": "CallObjectMethod(_jobject*, _jmethodID*, ...)",
"flag": "method._JNIEnv.CallObjectMethod__jobject___jmethodID__..._",
"realname": "_ZN7_JNIEnv16CallObjectMethodEP8_jobjectP10_jmethodIDz",
"addr": 24740
},
{
"name": "CallVoidMethod(_jobject*, _jmethodID*, ...)",
"flag": "method._JNIEnv.CallVoidMethod__jobject___jmethodID__..._",
"realname": "_ZN7_JNIEnv14CallVoidMethodEP8_jobjectP10_jmethodIDz",
"addr": 24768
},
{
"name": "GetStaticMethodID(_jclass*, char const*, char const*)",
"flag": "method._JNIEnv.GetStaticMethodID__jclass__char_const__char_const_",
"realname": "_ZN7_JNIEnv17GetStaticMethodIDEP7_jclassPKcS3_",
"addr": 24796
},
{
"name": "CallStaticObjectMethod(_jclass*, _jmethodID*, ...)",
"flag": "method._JNIEnv.CallStaticObjectMethod__jclass___jmethodID__..._",
"realname": "_ZN7_JNIEnv22CallStaticObjectMethodEP7_jclassP10_jmethodIDz",
"addr": 24810
},
{
"name": "CallStaticIntMethod(_jclass*, _jmethodID*, ...)",
"flag": "method._JNIEnv.CallStaticIntMethod__jclass___jmethodID__..._",
"realname": "_ZN7_JNIEnv19CallStaticIntMethodEP7_jclassP10_jmethodIDz",
"addr": 26974
},
{
"name": "CallStaticVoidMethod(_jclass*, _jmethodID*, ...)",
"flag": "method._JNIEnv.CallStaticVoidMethod__jclass___jmethodID__..._",
"realname": "_ZN7_JNIEnv20CallStaticVoidMethodEP7_jclassP10_jmethodIDz",
"addr": 27004
}
]
},
{
"classname": "SystemClassLoaderInjector",
"addr": 0,
"lang": "jni",
"index": 1,
"methods": [
{
"name": "inject(_JNIEnv*, _jobject*, _jstring*, _jstring*)",
"flag": "method.SystemClassLoaderInjector.inject__JNIEnv___jobject___jstring___jstring_",
"realname": "_ZN25SystemClassLoaderInjector6injectEP7_JNIEnvP8_jobjectP8_jstringS5_",
"addr": 29944
},
{
"name": "findBaseDexClassloader(_JNIEnv*, _jobject*)",
"flag": "method.SystemClassLoaderInjector.findBaseDexClassloader__JNIEnv___jobject_",
"realname": "_ZN25SystemClassLoaderInjector22findBaseDexClassloaderEP7_JNIEnvP8_jobject",
"addr": 27036
},
{
"name": "getField(_JNIEnv*, _jobject*, _jobject*, _jstring*)",
"flag": "method.SystemClassLoaderInjector.getField__JNIEnv___jobject___jobject___jstring_",
"realname": "_ZN25SystemClassLoaderInjector8getFieldEP7_JNIEnvP8_jobjectS3_P8_jstring",
"addr": 27180
},
{
"name": "getPathList(_JNIEnv*, _jobject*)",
"flag": "method.SystemClassLoaderInjector.getPathList__JNIEnv___jobject_",
"realname": "_ZN25SystemClassLoaderInjector11getPathListEP7_JNIEnvP8_jobject",
"addr": 27324
},
{
"name": "getDexElements(_JNIEnv*, _jobject*)",
"flag": "method.SystemClassLoaderInjector.getDexElements__JNIEnv___jobject_",
"realname": "_ZN25SystemClassLoaderInjector14getDexElementsEP7_JNIEnvP8_jobject",
"addr": 27380
},
{
"name": "setField(_JNIEnv*, _jobject*, _jobject*, _jstring*, _jobject*)",
"flag": "method.SystemClassLoaderInjector.setField__JNIEnv___jobject___jobject___jstring___jobject_",
"realname": "_ZN25SystemClassLoaderInjector8setFieldEP7_JNIEnvP8_jobjectS3_P8_jstringS3_",
"addr": 27420
},
{
"name": "combineArray(_JNIEnv*, _jobject*, _jobject*)",
"flag": "method.SystemClassLoaderInjector.combineArray__JNIEnv___jobject___jobject_",
"realname": "_ZN25SystemClassLoaderInjector12combineArrayEP7_JNIEnvP8_jobjectS3_",
"addr": 27568
},
{
"name": "injectAboveEqualApiLevel14(_JNIEnv*, _jobject*, _jstring*, _jstring*)",
"flag": "method.SystemClassLoaderInjector.injectAboveEqualApiLevel14__JNIEnv___jobject___jstring___jstring_",
"realname": "_ZN25SystemClassLoaderInjector26injectAboveEqualApiLevel14EP7_JNIEnvP8_jobjectP8_jstringS5_",
"addr": 27904
},
{
"name": "appendArray(_JNIEnv*, _jobject*, _jobject*)",
"flag": "method.SystemClassLoaderInjector.appendArray__JNIEnv___jobject___jobject_",
"realname": "_ZN25SystemClassLoaderInjector11appendArrayEP7_JNIEnvP8_jobjectS3_",
"addr": 28252
},
{
"name": "injectInAliyunOs(_JNIEnv*, _jobject*, _jstring*, _jstring*)",
"flag": "method.SystemClassLoaderInjector.injectInAliyunOs__JNIEnv___jobject___jstring___jstring_",
"realname": "_ZN25SystemClassLoaderInjector16injectInAliyunOsEP7_JNIEnvP8_jobjectP8_jstringS5_",
"addr": 28520
},
{
"name": "injectBelowApiLevel14(_JNIEnv*, _jobject*, _jstring*, _jstring*)",
"flag": "method.SystemClassLoaderInjector.injectBelowApiLevel14__JNIEnv___jobject___jstring___jstring_",
"realname": "_ZN25SystemClassLoaderInjector21injectBelowApiLevel14EP7_JNIEnvP8_jobjectP8_jstringS5_",
"addr": 29196
}
]
},
{
"classname": "std",
"addr": 0,
"lang": "c++",
"index": 2,
"methods": [
{
"name": "terminate()",
"flag": "method.std.terminate__",
"realname": "_ZSt9terminatev",
"addr": 38000
},
{
"name": "uncaught_exception()",
"flag": "method.std.uncaught_exception__",
"realname": "_ZSt18uncaught_exceptionv",
"addr": 34924
},
{
"name": "unexpected()",
"flag": "method.std.unexpected__",
"realname": "_ZSt10unexpectedv",
"addr": 38036
},
{
"name": "set_terminate(void (*)())",
"flag": "method.std.set_terminate_void______",
"realname": "_ZSt13set_terminatePFvvE",
"addr": 38060
},
{
"name": "set_unexpected(void (*)())",
"flag": "method.std.set_unexpected_void______",
"realname": "_ZSt14set_unexpectedPFvvE",
"addr": 38088
}
]
},
{
"classname": "std::exception",
"addr": 0,
"lang": "c++",
"index": 3,
"methods": [
{
"name": "~exception()",
"flag": "method.std::exception.exception__",
"realname": "_ZNSt9exceptionD2Ev",
"addr": 34948
},
{
"name": "what() const",
"flag": "method.std::exception.what___const",
"realname": "_ZNKSt9exception4whatEv",
"addr": 35060
}
]
},
{
"classname": "std::bad_exception",
"addr": 0,
"lang": "c++",
"index": 4,
"methods": [
{
"name": "~bad_exception()",
"flag": "method.std::bad_exception.bad_exception__",
"realname": "_ZNSt13bad_exceptionD2Ev",
"addr": 34972
},
{
"name": "what() const",
"flag": "method.std::bad_exception.what___const",
"realname": "_ZNKSt13bad_exception4whatEv",
"addr": 35076
}
]
},
{
"classname": "__cxxabiv1::__forced_unwind",
"addr": 0,
"lang": "c++",
"index": 5,
"methods": [
{
"name": "~__forced_unwind()",
"flag": "method.__cxxabiv1::__forced_unwind.__forced_unwind__",
"realname": "_ZN10__cxxabiv115__forced_unwindD2Ev",
"addr": 35012
}
]
},
{
"classname": "__cxxabiv1::__foreign_exception",
"addr": 0,
"lang": "c++",
"index": 6,
"methods": [
{
"name": "~__foreign_exception()",
"flag": "method.__cxxabiv1::__foreign_exception.__foreign_exception__",
"realname": "_ZN10__cxxabiv119__foreign_exceptionD2Ev",
"addr": 35036
}
]
},
{
"classname": "__eh_globals_init",
"addr": 0,
"lang": "c++",
"index": 7,
"methods": [
{
"name": "~__eh_globals_init()",
"flag": "method.__eh_globals_init.__eh_globals_init__",
"realname": "_ZN17__eh_globals_initD2Ev",
"addr": 35204
}
]
},
{
"classname": "__cxxabiv1",
"addr": 0,
"lang": "c++",
"index": 8,
"methods": [
{
"name": "__terminate(void (*)())",
"flag": "method.__cxxabiv1.__terminate_void______",
"realname": "_ZN10__cxxabiv111__terminateEPFvvE",
"addr": 37948
},
{
"name": "__unexpected(void (*)())",
"flag": "method.__cxxabiv1.__unexpected_void______",
"realname": "_ZN10__cxxabiv112__unexpectedEPFvvE",
"addr": 38024
}
]
},
{
"classname": "__cxxabiv1::__fundamental_type_info",
"addr": 0,
"lang": "c++",
"index": 9,
"methods": [
{
"name": "~__fundamental_type_info()",
"flag": "method.__cxxabiv1::__fundamental_type_info.__fundamental_type_info__",
"realname": "_ZN10__cxxabiv123__fundamental_type_infoD2Ev",
"addr": 38116
}
]
},
{
"classname": "std::type_info",
"addr": 0,
"lang": "c++",
"index": 10,
"methods": [
{
"name": "~type_info()",
"flag": "method.std::type_info.type_info__",
"realname": "_ZNSt9type_infoD2Ev",
"addr": 38844
},
{
"name": "__is_pointer_p() const",
"flag": "method.std::type_info.__is_pointer_p___const",
"realname": "_ZNKSt9type_info14__is_pointer_pEv",
"addr": 38868
},
{
"name": "__is_function_p() const",
"flag": "method.std::type_info.__is_function_p___const",
"realname": "_ZNKSt9type_info15__is_function_pEv",
"addr": 38876
},
{
"name": "__do_catch(std::type_info const*, void**, unsigned int) const",
"flag": "method.std::type_info.__do_catch_std::type_info_const__void__unsigned_int__const",
"realname": "_ZNKSt9type_info10__do_catchEPKS_PPvj",
"addr": 38996
},
{
"name": "__do_upcast(__cxxabiv1::__class_type_info const*, void**) const",
"flag": "method.std::type_info.__do_upcast___cxxabiv1::__class_type_info_const__void__const",
"realname": "_ZNKSt9type_info11__do_upcastEPKN10__cxxabiv117__class_type_infoEPPv",
"addr": 38884
},
{
"name": "operator==(std::type_info const&) const",
"flag": "method.std::type_info.operator_std::type_info_const__const",
"realname": "_ZNKSt9type_infoeqERKS_",
"addr": 38920
}
]
},
{
"classname": "__cxxabiv1::__pointer_type_info",
"addr": 0,
"lang": "c++",
"index": 11,
"methods": [
{
"name": "__is_pointer_p() const",
"flag": "method.__cxxabiv1::__pointer_type_info.__is_pointer_p___const",
"realname": "_ZNK10__cxxabiv119__pointer_type_info14__is_pointer_pEv",
"addr": 38184
},
{
"name": "~__pointer_type_info()",
"flag": "method.__cxxabiv1::__pointer_type_info.__pointer_type_info__",
"realname": "_ZN10__cxxabiv119__pointer_type_infoD2Ev",
"addr": 38192
},
{
"name": "__pointer_catch(__cxxabiv1::__pbase_type_info const*, void**, unsigned int) const",
"flag": "method.__cxxabiv1::__pointer_type_info.__pointer_catch___cxxabiv1::__pbase_type_info_const__void__unsigned_int__const",
"realname": "_ZNK10__cxxabiv119__pointer_type_info15__pointer_catchEPKNS_17__pbase_type_infoEPPvj",
"addr": 38260
}
]
},
{
"classname": "__cxxabiv1::__pbase_type_info",
"addr": 0,
"lang": "c++",
"index": 12,
"methods": [
{
"name": "~__pbase_type_info()",
"flag": "method.__cxxabiv1::__pbase_type_info.__pbase_type_info__",
"realname": "_ZN10__cxxabiv117__pbase_type_infoD2Ev",
"addr": 40432
},
{
"name": "__do_catch(std::type_info const*, void**, unsigned int) const",
"flag": "method.__cxxabiv1::__pbase_type_info.__do_catch_std::type_info_const__void__unsigned_int__const",
"realname": "_ZNK10__cxxabiv117__pbase_type_info10__do_catchEPKSt9type_infoPPvj",
"addr": 40500
},
{
"name": "__pointer_catch(__cxxabiv1::__pbase_type_info const*, void**, unsigned int) const",
"flag": "method.__cxxabiv1::__pbase_type_info.__pointer_catch___cxxabiv1::__pbase_type_info_const__void__unsigned_int__const",
"realname": "_ZNK10__cxxabiv117__pbase_type_info15__pointer_catchEPKS0_PPvj",
"addr": 40400
}
]
},
{
"classname": "__cxxabiv1::__si_class_type_info",
"addr": 0,
"lang": "c++",
"index": 13,
"methods": [
{
"name": "~__si_class_type_info()",
"flag": "method.__cxxabiv1::__si_class_type_info.__si_class_type_info__",
"realname": "_ZN10__cxxabiv120__si_class_type_infoD2Ev",
"addr": 38388
},
{
"name": "__do_find_public_src(int, void const*, __cxxabiv1::__class_type_info const*, void const*) const",
"flag": "method.__cxxabiv1::__si_class_type_info.__do_find_public_src_int__void_const____cxxabiv1::__class_type_info_const__void_const__const",
"realname": "_ZNK10__cxxabiv120__si_class_type_info20__do_find_public_srcEiPKvPKNS_17__class_type_infoES2_",
"addr": 38456
},
{
"name": "__do_dyncast(int, __cxxabiv1::__class_type_info::__sub_kind, __cxxabiv1::__class_type_info const*, void const*, __cxxabiv1::__class_type_info const*, void const*, __cxxabiv1::__class_type_info::__dyncast_result&) const",
"flag": "method.__cxxabiv1::__si_class_type_info.__do_dyncast_int____cxxabiv1::__class_type_info::__sub_kind____cxxabiv1::__class_type_info_const__void_const____cxxabiv1::__class_type_info_const__void_const____cxxabiv1::__class_type_info::__dyncast_result__co",
"realname": "_ZNK10__cxxabiv120__si_class_type_info12__do_dyncastEiNS_17__class_type_info10__sub_kindEPKS1_PKvS4_S6_RNS1_16__dyncast_resultE",
"addr": 38556
},
{
"name": "__do_upcast(__cxxabiv1::__class_type_info const*, void const*, __cxxabiv1::__class_type_info::__upcast_result&) const",
"flag": "method.__cxxabiv1::__si_class_type_info.__do_upcast___cxxabiv1::__class_type_info_const__void_const____cxxabiv1::__class_type_info::__upcast_result__const",
"realname": "_ZNK10__cxxabiv120__si_class_type_info11__do_upcastEPKNS_17__class_type_infoEPKvRNS1_15__upcast_resultE",
"addr": 38780
}
]
},
{
"classname": "__cxxabiv1::__class_type_info",
"addr": 0,
"lang": "c++",
"index": 14,
"methods": [
{
"name": "~__class_type_info()",
"flag": "method.__cxxabiv1::__class_type_info.__class_type_info__",
"realname": "_ZN10__cxxabiv117__class_type_infoD2Ev",
"addr": 39128
},
{
"name": "__do_upcast(__cxxabiv1::__class_type_info const*, void const*, __cxxabiv1::__class_type_info::__upcast_result&) const",
"flag": "method.__cxxabiv1::__class_type_info.__do_upcast___cxxabiv1::__class_type_info_const__void_const____cxxabiv1::__class_type_info::__upcast_result__const",
"realname": "_ZNK10__cxxabiv117__class_type_info11__do_upcastEPKS0_PKvRNS0_15__upcast_resultE",
"addr": 39196
},
{
"name": "__do_catch(std::type_info const*, void**, unsigned int) const",
"flag": "method.__cxxabiv1::__class_type_info.__do_catch_std::type_info_const__void__unsigned_int__const",
"realname": "_ZNK10__cxxabiv117__class_type_info10__do_catchEPKSt9type_infoPPvj",
"addr": 39240
},
{
"name": "__do_upcast(__cxxabiv1::__class_type_info const*, void**) const",
"flag": "method.__cxxabiv1::__class_type_info.__do_upcast___cxxabiv1::__class_type_info_const__void__const",
"realname": "_ZNK10__cxxabiv117__class_type_info11__do_upcastEPKS0_PPv",
"addr": 39016
},
{
"name": "__do_find_public_src(int, void const*, __cxxabiv1::__class_type_info const*, void const*) const",
"flag": "method.__cxxabiv1::__class_type_info.__do_find_public_src_int__void_const____cxxabiv1::__class_type_info_const__void_const__const",
"realname": "_ZNK10__cxxabiv117__class_type_info20__do_find_public_srcEiPKvPKS0_S2_",
"addr": 39108
},
{
"name": "__do_dyncast(int, __cxxabiv1::__class_type_info::__sub_kind, __cxxabiv1::__class_type_info const*, void const*, __cxxabiv1::__class_type_info const*, void const*, __cxxabiv1::__class_type_info::__dyncast_result&) const",
"flag": "method.__cxxabiv1::__class_type_info.__do_dyncast_int____cxxabiv1::__class_type_info::__sub_kind____cxxabiv1::__class_type_info_const__void_const____cxxabiv1::__class_type_info_const__void_const____cxxabiv1::__class_type_info::__dyncast_result__const",
"realname": "_ZNK10__cxxabiv117__class_type_info12__do_dyncastEiNS0_10__sub_kindEPKS0_PKvS3_S5_RNS0_16__dyncast_resultE",
"addr": 39308
}
]
},
{
"classname": "__gnu_cxx",
"addr": 0,
"lang": "c++",
"index": 15,
"methods": [
{
"name": "__verbose_terminate_handler()",
"flag": "method.__gnu_cxx.__verbose_terminate_handler__",
"realname": "_ZN9__gnu_cxx27__verbose_terminate_handlerEv",
"addr": 40644
},
{
"name": "__throw_concurrence_lock_error()",
"flag": "method.__gnu_cxx.__throw_concurrence_lock_error__",
"realname": "_ZN9__gnu_cxx30__throw_concurrence_lock_errorEv",
"addr": 75648
},
{
"name": "__throw_concurrence_unlock_error()",
"flag": "method.__gnu_cxx.__throw_concurrence_unlock_error__",
"realname": "_ZN9__gnu_cxx32__throw_concurrence_unlock_errorEv",
"addr": 75720
}
]
},
{
"classname": "__gnu_cxx::__concurrence_lock_error",
"addr": 0,
"lang": "c++",
"index": 16,
"methods": [
{
"name": "what() const",
"flag": "method.__gnu_cxx::__concurrence_lock_error.what___const",
"realname": "_ZNK9__gnu_cxx24__concurrence_lock_error4whatEv",
"addr": 75440
},
{
"name": "~__concurrence_lock_error()",
"flag": "method.__gnu_cxx::__concurrence_lock_error.__concurrence_lock_error__",
"realname": "_ZN9__gnu_cxx24__concurrence_lock_errorD2Ev",
"addr": 75512
}
]
},
{
"classname": "__gnu_cxx::__concurrence_unlock_error",
"addr": 0,
"lang": "c++",
"index": 17,
"methods": [
{
"name": "what() const",
"flag": "method.__gnu_cxx::__concurrence_unlock_error.what___const",
"realname": "_ZNK9__gnu_cxx26__concurrence_unlock_error4whatEv",
"addr": 75456
},
{
"name": "~__concurrence_unlock_error()",
"flag": "method.__gnu_cxx::__concurrence_unlock_error.__concurrence_unlock_error__",
"realname": "_ZN9__gnu_cxx26__concurrence_unlock_errorD2Ev",
"addr": 75472
}
]
},
{
"classname": "std::bad_cast",
"addr": 0,
"lang": "c++",
"index": 18,
"methods": [
{
"name": "~bad_cast()",
"flag": "method.std::bad_cast.bad_cast__",
"realname": "_ZNSt8bad_castD1Ev",
"addr": 76760
},
{
"name": "what() const",
"flag": "method.std::bad_cast.what___const",
"realname": "_ZNKSt8bad_cast4whatEv",
"addr": 76744
}
]
},
{
"classname": "std::bad_typeid",
"addr": 0,
"lang": "c++",
"index": 19,
"methods": [
{
"name": "~bad_typeid()",
"flag": "method.std::bad_typeid.bad_typeid__",
"realname": "_ZNSt10bad_typeidD1Ev",
"addr": 76844
},
{
"name": "what() const",
"flag": "method.std::bad_typeid.what___const",
"realname": "_ZNKSt10bad_typeid4whatEv",
"addr": 76828
}
]
}
]
EOF
RUN
NAME=ic*
FILE=bins/elf/libmagic.so
CMDS=ic*
EXPECT=<<EOF
fs classes
"f class._JNIEnv = 0x6060"
"f method._JNIEnv.FindClass(char_const*) = 0x6060"
"f method._JNIEnv.DeleteLocalRef(_jobject*) = 0x606a"
"f method._JNIEnv.NewObject(_jclass*,__jmethodID*,_...) = 0x6074"
"f method._JNIEnv.GetObjectClass(_jobject*) = 0x608e"
"f method._JNIEnv.GetMethodID(_jclass*,_char_const*,_char_const*) = 0x6098"
"f method._JNIEnv.CallObjectMethod(_jobject*,__jmethodID*,_...) = 0x60a4"
"f method._JNIEnv.CallVoidMethod(_jobject*,__jmethodID*,_...) = 0x60c0"
"f method._JNIEnv.GetStaticMethodID(_jclass*,_char_const*,_char_const*) = 0x60dc"
"f method._JNIEnv.CallStaticObjectMethod(_jclass*,__jmethodID*,_...) = 0x60ea"
"f method._JNIEnv.CallStaticIntMethod(_jclass*,__jmethodID*,_...) = 0x695e"
"f method._JNIEnv.CallStaticVoidMethod(_jclass*,__jmethodID*,_...) = 0x697c"
""td struct _JNIEnv { char empty[0];};
"f class.SystemClassLoaderInjector = 0x699c"
"f method.SystemClassLoaderInjector.inject(_JNIEnv*,__jobject*,__jstring*,__jstring*) = 0x74f8"
"f method.SystemClassLoaderInjector.findBaseDexClassloader(_JNIEnv*,__jobject*) = 0x699c"
"f method.SystemClassLoaderInjector.getField(_JNIEnv*,__jobject*,__jobject*,__jstring*) = 0x6a2c"
"f method.SystemClassLoaderInjector.getPathList(_JNIEnv*,__jobject*) = 0x6abc"
"f method.SystemClassLoaderInjector.getDexElements(_JNIEnv*,__jobject*) = 0x6af4"
"f method.SystemClassLoaderInjector.setField(_JNIEnv*,__jobject*,__jobject*,__jstring*,__jobject*) = 0x6b1c"
"f method.SystemClassLoaderInjector.combineArray(_JNIEnv*,__jobject*,__jobject*) = 0x6bb0"
"f method.SystemClassLoaderInjector.injectAboveEqualApiLevel14(_JNIEnv*,__jobject*,__jstring*,__jstring*) = 0x6d00"
"f method.SystemClassLoaderInjector.appendArray(_JNIEnv*,__jobject*,__jobject*) = 0x6e5c"
"f method.SystemClassLoaderInjector.injectInAliyunOs(_JNIEnv*,__jobject*,__jstring*,__jstring*) = 0x6f68"
"f method.SystemClassLoaderInjector.injectBelowApiLevel14(_JNIEnv*,__jobject*,__jstring*,__jstring*) = 0x720c"
""td struct SystemClassLoaderInjector { char empty[0];};
"f class.std = 0x886c"
"f method.std.terminate() = 0x9470"
"f method.std.uncaught_exception() = 0x886c"
"f method.std.unexpected() = 0x9494"
"f method.std.set_terminate(void_(*)()) = 0x94ac"
"f method.std.set_unexpected(void_(*)()) = 0x94c8"
""td struct std { char empty[0];};
"f class.std::exception = 0x8884"
"f method.std::exception.~exception() = 0x8884"
"f method.std::exception.what()_const = 0x88f4"
""td struct std::exception { char empty[0];};
"f class.std::bad_exception = 0x889c"
"f method.std::bad_exception.~bad_exception() = 0x889c"
"f method.std::bad_exception.what()_const = 0x8904"
""td struct std::bad_exception { char empty[0];};
"f class.__cxxabiv1::__forced_unwind = 0x88c4"
"f method.__cxxabiv1::__forced_unwind.~__forced_unwind() = 0x88c4"
""td struct __cxxabiv1::__forced_unwind { char empty[0];};
"f class.__cxxabiv1::__foreign_exception = 0x88dc"
"f method.__cxxabiv1::__foreign_exception.~__foreign_exception() = 0x88dc"
""td struct __cxxabiv1::__foreign_exception { char empty[0];};
"f class.__eh_globals_init = 0x8984"
"f method.__eh_globals_init.~__eh_globals_init() = 0x8984"
""td struct __eh_globals_init { char empty[0];};
"f class.__cxxabiv1 = 0x943c"
"f method.__cxxabiv1.__terminate(void_(*)()) = 0x943c"
"f method.__cxxabiv1.__unexpected(void_(*)()) = 0x9488"
""td struct __cxxabiv1 { char empty[0];};
"f class.__cxxabiv1::__fundamental_type_info = 0x94e4"
"f method.__cxxabiv1::__fundamental_type_info.~__fundamental_type_info() = 0x94e4"
""td struct __cxxabiv1::__fundamental_type_info { char empty[0];};
"f class.std::type_info = 0x97bc"
"f method.std::type_info.~type_info() = 0x97bc"
"f method.std::type_info.__is_pointer_p()_const = 0x97d4"
"f method.std::type_info.__is_function_p()_const = 0x97dc"
"f method.std::type_info.__do_catch(std::type_info_const*,_void**,_unsigned_int)_const = 0x9854"
"f method.std::type_info.__do_upcast(__cxxabiv1::__class_type_info_const*,_void**)_const = 0x97e4"
"f method.std::type_info.operator==(std::type_info_const&)_const = 0x9808"
""td struct std::type_info { char empty[0];};
"f class.__cxxabiv1::__pointer_type_info = 0x9528"
"f method.__cxxabiv1::__pointer_type_info.__is_pointer_p()_const = 0x9528"
"f method.__cxxabiv1::__pointer_type_info.~__pointer_type_info() = 0x9530"
"f method.__cxxabiv1::__pointer_type_info.__pointer_catch(__cxxabiv1::__pbase_type_info_const*,_void**,_unsigned_int)_const = 0x9574"
""td struct __cxxabiv1::__pointer_type_info { char empty[0];};
"f class.__cxxabiv1::__pbase_type_info = 0x9dd0"
"f method.__cxxabiv1::__pbase_type_info.~__pbase_type_info() = 0x9df0"
"f method.__cxxabiv1::__pbase_type_info.__do_catch(std::type_info_const*,_void**,_unsigned_int)_const = 0x9e34"
"f method.__cxxabiv1::__pbase_type_info.__pointer_catch(__cxxabiv1::__pbase_type_info_const*,_void**,_unsigned_int)_const = 0x9dd0"
""td struct __cxxabiv1::__pbase_type_info { char empty[0];};
"f class.__cxxabiv1::__si_class_type_info = 0x95f4"
"f method.__cxxabiv1::__si_class_type_info.~__si_class_type_info() = 0x95f4"
"f method.__cxxabiv1::__si_class_type_info.__do_find_public_src(int,_void_const*,___cxxabiv1::__class_type_info_const*,_void_const*)_const = 0x9638"
"f method.__cxxabiv1::__si_class_type_info.__do_dyncast(int,___cxxabiv1::__class_type_info::__sub_kind,___cxxabiv1::__class_type_info_const*,_void_const*,___cxxabiv1::__class_type_info_const*,_void_const*,___cxxabiv1::__class_type_info::__dyncast_result&)_const = 0x969c"
"f method.__cxxabiv1::__si_class_type_info.__do_upcast(__cxxabiv1::__class_type_info_const*,_void_const*,___cxxabiv1::__class_type_info::__upcast_result&)_const = 0x977c"
""td struct __cxxabiv1::__si_class_type_info { char empty[0];};
"f class.__cxxabiv1::__class_type_info = 0x9868"
"f method.__cxxabiv1::__class_type_info.~__class_type_info() = 0x98d8"
"f method.__cxxabiv1::__class_type_info.__do_upcast(__cxxabiv1::__class_type_info_const*,_void_const*,___cxxabiv1::__class_type_info::__upcast_result&)_const = 0x991c"
"f method.__cxxabiv1::__class_type_info.__do_catch(std::type_info_const*,_void**,_unsigned_int)_const = 0x9948"
"f method.__cxxabiv1::__class_type_info.__do_upcast(__cxxabiv1::__class_type_info_const*,_void**)_const = 0x9868"
"f method.__cxxabiv1::__class_type_info.__do_find_public_src(int,_void_const*,___cxxabiv1::__class_type_info_const*,_void_const*)_const = 0x98c4"
"f method.__cxxabiv1::__class_type_info.__do_dyncast(int,___cxxabiv1::__class_type_info::__sub_kind,___cxxabiv1::__class_type_info_const*,_void_const*,___cxxabiv1::__class_type_info_const*,_void_const*,___cxxabiv1::__class_type_info::__dyncast_result&)_const = 0x998c"
""td struct __cxxabiv1::__class_type_info { char empty[0];};
"f class.__gnu_cxx = 0x9ec4"
"f method.__gnu_cxx.__verbose_terminate_handler() = 0x9ec4"
"f method.__gnu_cxx.__throw_concurrence_lock_error() = 0x12780"
"f method.__gnu_cxx.__throw_concurrence_unlock_error() = 0x127c8"
""td struct __gnu_cxx { char empty[0];};
"f class.__gnu_cxx::__concurrence_lock_error = 0x126b0"
"f method.__gnu_cxx::__concurrence_lock_error.what()_const = 0x126b0"
"f method.__gnu_cxx::__concurrence_lock_error.~__concurrence_lock_error() = 0x126f8"
""td struct __gnu_cxx::__concurrence_lock_error { char empty[0];};
"f class.__gnu_cxx::__concurrence_unlock_error = 0x126c0"
"f method.__gnu_cxx::__concurrence_unlock_error.what()_const = 0x126c0"
"f method.__gnu_cxx::__concurrence_unlock_error.~__concurrence_unlock_error() = 0x126d0"
""td struct __gnu_cxx::__concurrence_unlock_error { char empty[0];};
"f class.std::bad_cast = 0x12bc8"
"f method.std::bad_cast.~bad_cast() = 0x12bd8"
"f method.std::bad_cast.what()_const = 0x12bc8"
""td struct std::bad_cast { char empty[0];};
"f class.std::bad_typeid = 0x12c1c"
"f method.std::bad_typeid.~bad_typeid() = 0x12c2c"
"f method.std::bad_typeid.what()_const = 0x12c1c"
""td struct std::bad_typeid { char empty[0];};
EOF
RUN
NAME=icc
FILE=bins/elf/libmagic.so
CMDS=icc
EXPECT=<<EOF
class _JNIEnv {
};
class SystemClassLoaderInjector {
};
class std {
};
class std::exception {
};
class std::bad_exception {
};
class __cxxabiv1::__forced_unwind {
};
class __cxxabiv1::__foreign_exception {
};
class __eh_globals_init {
};
class __cxxabiv1 {
};
class __cxxabiv1::__fundamental_type_info {
};
class std::type_info {
};
class __cxxabiv1::__pointer_type_info {
};
class __cxxabiv1::__pbase_type_info {
};
class __cxxabiv1::__si_class_type_info {
};
class __cxxabiv1::__class_type_info {
};
class __gnu_cxx {
};
class __gnu_cxx::__concurrence_lock_error {
};
class __gnu_cxx::__concurrence_unlock_error {
};
class std::bad_cast {
};
class std::bad_typeid {
};
EOF
RUN
NAME=ic?~ (match all)
FILE=malloc://512
CMDS=ic?~List
EXPECT=<<EOF
| ic List classes, methods and fields (icj for json)
| icc [lang] List classes, methods and fields in Header Format (see bin.lang=swift,java,objc,cxx)
| icg [str] List classes as agn/age commands to create class hierarchy graphs (matches str if provided)
| icq List classes, in quiet mode (just the classname)
| icqq List classes, in quieter mode (only show non-system classnames)
EOF
RUN
NAME=ic?~ (match one)
FILE=malloc://512
CMDS=ic?~Header
EXPECT=<<EOF
| icc [lang] List classes, methods and fields in Header Format (see bin.lang=swift,java,objc,cxx)
EOF
RUN
NAME=ic?~ (match none)
FILE=malloc://512
CMDS=ic?~Guess
EXPECT=<<EOF
EOF
RUN
NAME=ic (file Java)
FILE=bins/java/Hello.class
CMDS=ic
EXPECT=<<EOF
0x00000000 [0x0000022b - 0x000002aa] 127 java class 0 Hello :: java/lang/Object
0x0000022b java method 0 <init>
0x00000263 java method 1 say
0x000002aa java method 2 main
EOF
RUN
NAME=ic (file Java)
FILE=bins/java/Hello.class
CMDS=<<EOF
icg
icg Hello
icg no_match
EOF
EXPECT=<<EOF
agn Hello
agn java/lang/Object
age java/lang/Object Hello
agn Hello
EOF
RUN
NAME=icq (file Java)
FILE=bins/java/Hello.class
CMDS=icq
EXPECT=<<EOF
0x00000000 [0x0000022b - 0x000002aa] java Hello java/lang/Object
EOF
RUN
NAME=icqq (file Java)
FILE=bins/java/Hello.class
CMDS=icqq
EXPECT=<<EOF
Hello
EOF
RUN
NAME=icqq (file x86)
FILE=bins/elf/ls
CMDS=icqq
EXPECT=<<EOF
EOF
RUN
NAME=iqqc (file Java)
BROKEN=1
FILE=bins/java/Hello.class
CMDS=iqqc
EXPECT=<<EOF
Hello
EOF
RUN
NAME=iqqc (file x86)
BROKEN=1
FILE=bins/elf/ls
CMDS=iqqc
EXPECT=<<EOF
EOF
RUN
NAME=iqcq (file Java)
BROKEN=1
FILE=bins/java/Hello.class
CMDS=iqcq
EXPECT=<<EOF
Hello
EOF
RUN
NAME=iqcq (file x86)
BROKEN=1
FILE=bins/elf/ls
CMDS=iqcq
EXPECT=<<EOF
EOF
RUN