diff --git a/libr/anal/p/anal_java.c b/libr/anal/p/anal_java.c index 2476b24db6..b560d2c21a 100644 --- a/libr/anal/p/anal_java.c +++ b/libr/anal/p/anal_java.c @@ -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; diff --git a/shlr/java/class.c b/shlr/java/class.c index c4b11d3ae0..074d6ffb2e 100644 --- a/shlr/java/class.c +++ b/shlr/java/class.c @@ -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; +} diff --git a/shlr/java/class.h b/shlr/java/class.h index ef16880498..c50134cd2c 100644 --- a/shlr/java/class.h +++ b/shlr/java/class.h @@ -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 diff --git a/shlr/java/code.c b/shlr/java/code.c index e2cf58e095..8f402d9f8a 100644 --- a/shlr/java/code.c +++ b/shlr/java/code.c @@ -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);