Refactoring java constant pool resolution

This commit is contained in:
Adam Pridgen 2014-02-18 22:21:07 -06:00
parent 12dc36ce23
commit 8f72843498
4 changed files with 258 additions and 211 deletions

View File

@ -16,6 +16,24 @@
#define IFDBG if(0)
#define IFINT if(0)
struct r_anal_java_access_t;
typedef struct r_anal_java_access_t {
char *method;
ut64 addr;
ut64 value;
ut64 op_type;
struct r_anal_java_access_t *next;
struct r_anal_java_access_t *previous;
} RAnalJavaAccess;
typedef struct r_anal_java_local_var_t {
char *name;
char *type;
RList *writes;
RList *reads;
RList *binops;
} RAnalJavaLocalVar;
typedef struct r_anal_ex_java_lin_sweep {
RList *cfg_node_addrs;

View File

@ -7330,6 +7330,31 @@ R_API RBinJavaCPTypeObj *r_bin_java_find_cp_name_and_type_info(ut16 name_idx, ut
return res;
}
R_API char * r_bin_java_resolve_cp_idx_type(RBinJavaObj *BIN_OBJ, int idx) {
RBinJavaCPTypeObj *item = NULL, *item2 = NULL;
char *cp_name = NULL,
*str = NULL;
int memory_alloc = 0;
if (BIN_OBJ && BIN_OBJ->cp_count < 1 ) {
//javasm_init(BIN_OBJ);
return NULL;
}
item = (RBinJavaCPTypeObj *) r_bin_java_get_item_from_bin_cp_list (BIN_OBJ, idx);
if (item) {
cp_name = ((RBinJavaCPTypeMetas *) item->metas->type_info)->name;
} else {
cp_name = "INVALID";
}
memory_alloc = strlen(cp_name)+1;
str = malloc (memory_alloc);
memcpy(str, cp_name, memory_alloc);
return str;
}
R_API RBinJavaCPTypeObj *r_bin_java_find_cp_ref_info_from_name_and_type (ut16 name_idx, ut16 descriptor_idx) {
RBinJavaCPTypeObj *res= NULL,
*obj = r_bin_java_find_cp_name_and_type_info (name_idx, descriptor_idx);
@ -7358,3 +7383,209 @@ R_API RBinJavaCPTypeObj *r_bin_java_find_cp_ref_info(ut16 name_and_type_idx) {
}
return res;
}
R_API char * r_bin_java_resolve_with_space(RBinJavaObj *obj, int idx) {
return r_bin_java_resolve(obj, idx, 1);
}
R_API char * r_bin_java_resolve_without_space(RBinJavaObj *obj, int idx) {
return r_bin_java_resolve(obj, idx, 0);
}
R_API char * r_bin_java_resolve(RBinJavaObj *BIN_OBJ, int idx, ut8 space_bn_name_type) {
// TODO XXX FIXME add a size parameter to the str when it is passed in
RBinJavaCPTypeObj *item = NULL, *item2 = NULL;
char *class_str = NULL,
*name_str = NULL,
*desc_str = NULL,
*string_str = NULL,
*empty = "",
*cp_name = NULL,
*cp_name2 = NULL,
*str = NULL;
int memory_alloc = 0;
if (BIN_OBJ && BIN_OBJ->cp_count < 1 ) {
//javasm_init(BIN_OBJ);
return NULL;
}
item = (RBinJavaCPTypeObj *) r_bin_java_get_item_from_bin_cp_list (BIN_OBJ, idx);
if (item) {
cp_name = ((RBinJavaCPTypeMetas *) item->metas->type_info)->name;
IFDBG eprintf("java_resolve Resolved: (%d) %s\n", idx, cp_name);
} else {
str = malloc (512);
if (str)
snprintf (str,512, "(%d) INVALID CP_OBJ", idx);
return str;
}
cp_name = ((RBinJavaCPTypeMetas *) item->metas->type_info)->name;
if ( strcmp (cp_name, "Class") == 0 ) {
item2 = (RBinJavaCPTypeObj *) r_bin_java_get_item_from_bin_cp_list (BIN_OBJ, idx);
//str = r_bin_java_get_name_from_bin_cp_list (BIN_OBJ, idx-1);
class_str = empty;
class_str = r_bin_java_get_item_name_from_bin_cp_list (BIN_OBJ, item);
if (!class_str)
class_str = empty;
name_str = r_bin_java_get_item_name_from_bin_cp_list (BIN_OBJ, item2);
if (!name_str)
name_str = empty;
desc_str = r_bin_java_get_item_desc_from_bin_cp_list (BIN_OBJ, item2);
if (!desc_str)
desc_str = empty;
memory_alloc = strlen (class_str) + strlen (name_str) + strlen (desc_str) + 3;
if (memory_alloc)
str = malloc (memory_alloc);
if (str && !space_bn_name_type)
snprintf (str, memory_alloc, "%s%s", name_str, desc_str);
else if (str && space_bn_name_type)
snprintf (str, memory_alloc, "%s %s", name_str, desc_str);
if (class_str != empty)
free (class_str);
if (name_str != empty)
free (name_str);
if (desc_str != empty)
free (desc_str);
}else if ( strcmp (cp_name, "MethodRef") == 0 ||
strcmp (cp_name, "FieldRef") == 0 ||
strcmp (cp_name, "InterfaceMethodRef") == 0) {
/*
* The MethodRef, FieldRef, and InterfaceMethodRef structures
*/
class_str = r_bin_java_get_name_from_bin_cp_list (BIN_OBJ, item->info.cp_method.class_idx);
if (!class_str)
class_str = empty;
name_str = r_bin_java_get_item_name_from_bin_cp_list (BIN_OBJ, item);
if (!name_str)
name_str = empty;
desc_str = r_bin_java_get_item_desc_from_bin_cp_list (BIN_OBJ, item);
if (!desc_str)
desc_str = empty;
memory_alloc = strlen (class_str) + strlen (name_str) + strlen (desc_str) + 3;
if (memory_alloc)
str = malloc (memory_alloc);
if (str && !space_bn_name_type)
snprintf (str, memory_alloc, "%s/%s%s", class_str, name_str, desc_str);
else if (str && space_bn_name_type)
snprintf (str, memory_alloc, "%s/%s %s", class_str, name_str, desc_str);
if (class_str != empty)
free (class_str);
if (name_str != empty)
free (name_str);
if (desc_str != empty)
free (desc_str);
} else if (strcmp (cp_name, "String") == 0) {
ut32 length = r_bin_java_get_utf8_len_from_bin_cp_list (BIN_OBJ, item->info.cp_string.string_idx);
string_str = r_bin_java_get_utf8_from_bin_cp_list (BIN_OBJ, item->info.cp_string.string_idx);
str = NULL;
IFDBG eprintf("java_resolve String got: (%d) %s\n", item->info.cp_string.string_idx, string_str);
if (!string_str) {
string_str = empty;
length = strlen (empty);
}
memory_alloc = length + 3;
if (memory_alloc)
str = malloc (memory_alloc);
if (str) {
//r_name_filter(string_str, length);
snprintf (str, memory_alloc, "\"%s\"", string_str);
}
IFDBG eprintf("java_resolve String return: %s\n", str);
if (string_str != empty)
free (string_str);
} else if (strcmp (cp_name, "Utf8") == 0) {
str = malloc (item->info.cp_utf8.length+3);
if (str) {
snprintf (str, item->info.cp_utf8.length+3, "\"%s\"", item->info.cp_utf8.bytes);
}
} else if (strcmp (cp_name, "Long") == 0) {
str = malloc (34);
if (str) {
snprintf (str, 34, "0x%llx", rbin_java_raw_to_long (item->info.cp_long.bytes.raw,0));
}
} else if (strcmp (cp_name, "Double") == 0) {
str = malloc (1000);
if (str) {
snprintf (str, 1000, "%f", rbin_java_raw_to_double (item->info.cp_double.bytes.raw,0));
}
} else if (strcmp (cp_name, "Integer") == 0) {
str = malloc (34);
if (str) {
snprintf (str, 34, "0x%08x", R_BIN_JAVA_UINT (item->info.cp_integer.bytes.raw,0));
}
} else if (strcmp (cp_name, "Float") == 0) {
str = malloc (34);
if (str) {
snprintf (str, 34, "%f", R_BIN_JAVA_FLOAT (item->info.cp_float.bytes.raw,0));
}
} else if (strcmp (cp_name, "NameAndType") == 0) {
str = malloc (64);
if (str) {
name_str = r_bin_java_get_item_name_from_bin_cp_list (BIN_OBJ, item);
if (!name_str)
name_str = empty;
desc_str = r_bin_java_get_item_desc_from_bin_cp_list (BIN_OBJ, item);
if (!desc_str)
desc_str = empty;
memory_alloc = strlen (name_str) + strlen (desc_str) + 3;
if (memory_alloc)
str = malloc (memory_alloc);
if (str && !space_bn_name_type)
snprintf (str, memory_alloc, "%s%s", name_str, desc_str);
else if (str && space_bn_name_type)
snprintf (str, memory_alloc, "%s %s", name_str, desc_str);
if (name_str != empty)
free (name_str);
if (desc_str != empty)
free (desc_str);
}
} else {
str = malloc (16);
if (str) {
snprintf (str, 16, "(null)");
}
}
return str;
}

View File

@ -1199,5 +1199,10 @@ R_API RList * r_bin_java_get_method_offsets(RBinJavaObj *bin);
R_API ut16 r_bin_java_calculate_method_access_value(const char * access_flags_str);
R_API ut16 r_bin_java_calculate_field_access_value(const char * access_flags_str);
R_API ut16 r_bin_java_calculate_class_access_value(const char * access_flags_str);
R_API char * r_bin_java_resolve(RBinJavaObj *obj, int idx, ut8 space_bn_name_type);
R_API char * r_bin_java_resolve_with_space(RBinJavaObj *obj, int idx);
R_API char * r_bin_java_resolve_without_space(RBinJavaObj *BIN_OBJ, int idx);
R_API char * r_bin_java_resolve_cp_idx_type(RBinJavaObj *BIN_OBJ, int idx);
#endif

View File

@ -16,10 +16,6 @@
#define IFDBG if(0)
static char * java_resolve_with_space(RBinJavaObj *obj, int idx);
static char * java_resolve_without_space(RBinJavaObj *obj, int idx);
static char * java_resolve(RBinJavaObj *obj, int idx, ut8 space_bn_name_type);
static void init_switch_op ();
static int enter_switch_op (ut64 addr, const ut8 * bytes, char *output, int outlen );
static int update_bytes_consumed (int sz);
@ -77,209 +73,6 @@ static int handle_switch_op (ut64 addr, const ut8 * bytes, char *output, int out
return update_bytes_consumed(sz);
}
static char * java_resolve_with_space(RBinJavaObj *obj, int idx) {
return java_resolve(obj, idx, 1);
}
static char * java_resolve_without_space(RBinJavaObj *obj, int idx) {
return java_resolve(obj, idx, 0);
}
static char * java_resolve(RBinJavaObj *BIN_OBJ, int idx, ut8 space_bn_name_type) {
// TODO XXX FIXME add a size parameter to the str when it is passed in
RBinJavaCPTypeObj *item = NULL, *item2 = NULL;
char *class_str = NULL,
*name_str = NULL,
*desc_str = NULL,
*string_str = NULL,
*empty = "",
*cp_name = NULL,
*cp_name2 = NULL,
*str = NULL;
int memory_alloc = 0;
if (BIN_OBJ && BIN_OBJ->cp_count < 1 ) {
//javasm_init(BIN_OBJ);
return NULL;
}
item = (RBinJavaCPTypeObj *) r_bin_java_get_item_from_bin_cp_list (BIN_OBJ, idx);
if (item) {
cp_name = ((RBinJavaCPTypeMetas *) item->metas->type_info)->name;
IFDBG eprintf("java_resolve Resolved: (%d) %s\n", idx, cp_name);
} else {
str = malloc (512);
if (str)
snprintf (str,512, "(%d) INVALID CP_OBJ", idx);
return str;
}
cp_name = ((RBinJavaCPTypeMetas *) item->metas->type_info)->name;
if ( strcmp (cp_name, "Class") == 0 ) {
item2 = (RBinJavaCPTypeObj *) r_bin_java_get_item_from_bin_cp_list (BIN_OBJ, idx);
//str = r_bin_java_get_name_from_bin_cp_list (BIN_OBJ, idx-1);
class_str = empty;
class_str = r_bin_java_get_item_name_from_bin_cp_list (BIN_OBJ, item);
if (!class_str)
class_str = empty;
name_str = r_bin_java_get_item_name_from_bin_cp_list (BIN_OBJ, item2);
if (!name_str)
name_str = empty;
desc_str = r_bin_java_get_item_desc_from_bin_cp_list (BIN_OBJ, item2);
if (!desc_str)
desc_str = empty;
memory_alloc = strlen (class_str) + strlen (name_str) + strlen (desc_str) + 3;
if (memory_alloc)
str = malloc (memory_alloc);
if (str && !space_bn_name_type)
snprintf (str, memory_alloc, "%s%s", name_str, desc_str);
else if (str && space_bn_name_type)
snprintf (str, memory_alloc, "%s %s", name_str, desc_str);
if (class_str != empty)
free (class_str);
if (name_str != empty)
free (name_str);
if (desc_str != empty)
free (desc_str);
}else if ( strcmp (cp_name, "MethodRef") == 0 ||
strcmp (cp_name, "FieldRef") == 0 ||
strcmp (cp_name, "InterfaceMethodRef") == 0) {
/*
* The MethodRef, FieldRef, and InterfaceMethodRef structures
*/
class_str = r_bin_java_get_name_from_bin_cp_list (BIN_OBJ, item->info.cp_method.class_idx);
if (!class_str)
class_str = empty;
name_str = r_bin_java_get_item_name_from_bin_cp_list (BIN_OBJ, item);
if (!name_str)
name_str = empty;
desc_str = r_bin_java_get_item_desc_from_bin_cp_list (BIN_OBJ, item);
if (!desc_str)
desc_str = empty;
memory_alloc = strlen (class_str) + strlen (name_str) + strlen (desc_str) + 3;
if (memory_alloc)
str = malloc (memory_alloc);
if (str && !space_bn_name_type)
snprintf (str, memory_alloc, "%s/%s%s", class_str, name_str, desc_str);
else if (str && space_bn_name_type)
snprintf (str, memory_alloc, "%s/%s %s", class_str, name_str, desc_str);
if (class_str != empty)
free (class_str);
if (name_str != empty)
free (name_str);
if (desc_str != empty)
free (desc_str);
} else if (strcmp (cp_name, "String") == 0) {
ut32 length = r_bin_java_get_utf8_len_from_bin_cp_list (BIN_OBJ, item->info.cp_string.string_idx);
string_str = r_bin_java_get_utf8_from_bin_cp_list (BIN_OBJ, item->info.cp_string.string_idx);
str = NULL;
IFDBG eprintf("java_resolve String got: (%d) %s\n", item->info.cp_string.string_idx, string_str);
if (!string_str) {
string_str = empty;
length = strlen (empty);
}
memory_alloc = length + 3;
if (memory_alloc)
str = malloc (memory_alloc);
if (str) {
//r_name_filter(string_str, length);
snprintf (str, memory_alloc, "\"%s\"", string_str);
}
IFDBG eprintf("java_resolve String return: %s\n", str);
if (string_str != empty)
free (string_str);
} else if (strcmp (cp_name, "Utf8") == 0) {
str = malloc (item->info.cp_utf8.length+3);
if (str) {
snprintf (str, item->info.cp_utf8.length+3, "\"%s\"", item->info.cp_utf8.bytes);
}
} else if (strcmp (cp_name, "Long") == 0) {
str = malloc (34);
if (str) {
snprintf (str, 34, "0x%llx", rbin_java_raw_to_long (item->info.cp_long.bytes.raw,0));
}
} else if (strcmp (cp_name, "Double") == 0) {
str = malloc (1000);
if (str) {
snprintf (str, 1000, "%f", rbin_java_raw_to_double (item->info.cp_double.bytes.raw,0));
}
} else if (strcmp (cp_name, "Integer") == 0) {
str = malloc (34);
if (str) {
snprintf (str, 34, "0x%08x", R_BIN_JAVA_UINT (item->info.cp_integer.bytes.raw,0));
}
} else if (strcmp (cp_name, "Float") == 0) {
str = malloc (34);
if (str) {
snprintf (str, 34, "%f", R_BIN_JAVA_FLOAT (item->info.cp_float.bytes.raw,0));
}
} else if (strcmp (cp_name, "NameAndType") == 0) {
str = malloc (64);
if (str) {
name_str = r_bin_java_get_item_name_from_bin_cp_list (BIN_OBJ, item);
if (!name_str)
name_str = empty;
desc_str = r_bin_java_get_item_desc_from_bin_cp_list (BIN_OBJ, item);
if (!desc_str)
desc_str = empty;
memory_alloc = strlen (name_str) + strlen (desc_str) + 3;
if (memory_alloc)
str = malloc (memory_alloc);
if (str && !space_bn_name_type)
snprintf (str, memory_alloc, "%s%s", name_str, desc_str);
else if (str && space_bn_name_type)
snprintf (str, memory_alloc, "%s %s", name_str, desc_str);
if (name_str != empty)
free (name_str);
if (desc_str != empty)
free (desc_str);
}
} else {
str = malloc (16);
if (str) {
snprintf (str, 16, "(null)");
}
}
return str;
}
int java_print_opcode(RBinJavaObj *obj, ut64 addr, int idx, const ut8 *bytes, char *output, int outlen) {
char *arg = NULL; //(char *) malloc (1024);
@ -324,7 +117,7 @@ int java_print_opcode(RBinJavaObj *obj, ut64 addr, int idx, const ut8 *bytes, ch
return update_bytes_consumed (JAVA_OPS[idx].size);
case 0x12: // ldc
arg = java_resolve_without_space (obj, (ut16)bytes[1]);
arg = r_bin_java_resolve_without_space (obj, (ut16)bytes[1]);
if (arg) {
snprintf (output, outlen, "%s %s", JAVA_OPS[idx].name, arg);
free (arg);
@ -335,7 +128,7 @@ int java_print_opcode(RBinJavaObj *obj, ut64 addr, int idx, const ut8 *bytes, ch
return update_bytes_consumed (JAVA_OPS[idx].size);
case 0x13:
case 0x14:
arg = java_resolve_without_space (obj, (int)USHORT (bytes, 1));
arg = r_bin_java_resolve_without_space (obj, (int)USHORT (bytes, 1));
if (arg) {
snprintf (output, outlen, "%s %s", JAVA_OPS[idx].name, arg);
free (arg);
@ -382,7 +175,7 @@ int java_print_opcode(RBinJavaObj *obj, ut64 addr, int idx, const ut8 *bytes, ch
case 0xb8: // invokestatic
case 0xb9: // invokeinterface
case 0xba: // invokedynamic
arg = java_resolve_without_space (obj, (int)USHORT (bytes, 1));
arg = r_bin_java_resolve_without_space (obj, (int)USHORT (bytes, 1));
if (arg) {
snprintf (output, outlen, "%s %s", JAVA_OPS[idx].name, arg);
free (arg);
@ -399,7 +192,7 @@ int java_print_opcode(RBinJavaObj *obj, ut64 addr, int idx, const ut8 *bytes, ch
case 0xbd: // anewarray
case 0xc0: // checkcast
case 0xc1: // instance of
arg = java_resolve_with_space (obj, (int)USHORT (bytes, 1));
arg = r_bin_java_resolve_with_space (obj, (int)USHORT (bytes, 1));
if (arg) {
snprintf (output, outlen, "%s %s", JAVA_OPS[idx].name, arg);
free (arg);