1 /* Apache 2.0 - Copyright 2007-2018 - pancake and dso
2 class.c rewrite: Adam Pridgen <dso@rice.edu || adam.pridgen@thecoverofnight.com>
3 */
4 #include <stdio.h>
5 #include <string.h>
6 #include <stdlib.h>
7 #include <stdarg.h>
8 #include <r_types.h>
9 #include <r_util.h>
10 #include <r_bin.h>
11 #include <math.h>
12 #include <sdb.h>
13 #include "class.h"
14 #include "dsojson.h"
15
16 static PrintfCallback Eprintf =(PrintfCallback) printf;
17 #ifdef IFDBG
18 #undef IFDBG
19 #endif
20 #define DO_THE_DBG 0
21 #define IFDBG if (DO_THE_DBG)
22 #define IFINT if (0)
23
24 #define MAX_CPITEMS 8192
25
26 R_API char *U(r_bin_java_unmangle_method)(const char *flags, const char *name, const char *params, const char *r_value);
27 R_API int r_bin_java_is_fm_type_private(RBinJavaField *fm_type);
28 R_API int r_bin_java_is_fm_type_protected(RBinJavaField *fm_type);
29 R_API ut32 U(r_bin_java_swap_uint)(ut32 x);
30
31 // R_API const char * r_bin_java_get_this_class_name(RBinJavaObj *bin);
32 R_API void U(add_cp_objs_to_sdb)(RBinJavaObj * bin);
33 R_API void U(add_field_infos_to_sdb)(RBinJavaObj * bin);
34 R_API void U(add_method_infos_to_sdb)(RBinJavaObj * bin);
35 R_API RList *retrieve_all_access_string_and_value(RBinJavaAccessFlags *access_flags);
36 R_API char *retrieve_access_string(ut16 flags, RBinJavaAccessFlags *access_flags);
37 R_API ut16 calculate_access_value(const char *access_flags_str, RBinJavaAccessFlags *access_flags);
38 R_API int r_bin_java_new_bin(RBinJavaObj *bin, ut64 loadaddr, Sdb *kv, const ut8 *buf, ut64 len);
39 R_API int extract_type_value(const char *arg_str, char **output);
40 R_API int r_bin_java_check_reset_cp_obj(RBinJavaCPTypeObj *cp_obj, ut8 tag);
41 R_API ut8 *r_bin_java_cp_get_4bytes(ut8 tag, ut32 *out_sz, const ut8 *buf, const ut64 len);
42 R_API ut8 *r_bin_java_cp_get_8bytes(ut8 tag, ut32 *out_sz, const ut8 *buf, const ut64 len);
43 R_API ut8 *r_bin_java_cp_get_utf8(ut8 tag, ut32 *out_sz, const ut8 *buf, const ut64 len);
44
45 R_API RBinJavaCPTypeObj *r_bin_java_get_item_from_bin_cp_list(RBinJavaObj *bin, ut64 idx);
46 R_API RBinJavaCPTypeObj *r_bin_java_get_item_from_cp_item_list(RList *cp_list, ut64 idx);
47 // Allocs for objects
48 R_API RBinJavaCPTypeObj *r_bin_java_class_cp_new(RBinJavaObj *bin, ut8 *buffer, ut64 offset);
49 R_API RBinJavaCPTypeObj *r_bin_java_fieldref_cp_new(RBinJavaObj *bin, ut8 *buffer, ut64 offset);
50 R_API RBinJavaCPTypeObj *r_bin_java_methodref_cp_new(RBinJavaObj *bin, ut8 *buffer, ut64 offset);
51 R_API RBinJavaCPTypeObj *r_bin_java_interfacemethodref_cp_new(RBinJavaObj *bin, ut8 *buffer, ut64 offset);
52 R_API RBinJavaCPTypeObj *r_bin_java_name_and_type_cp_new(RBinJavaObj *bin, ut8 *buffer, ut64 offset);
53 R_API RBinJavaCPTypeObj *r_bin_java_string_cp_new(RBinJavaObj *bin, ut8 *buffer, ut64 offset);
54 R_API RBinJavaCPTypeObj *r_bin_java_integer_cp_new(RBinJavaObj *bin, ut8 *buffer, ut64 offset);
55 R_API RBinJavaCPTypeObj *r_bin_java_float_cp_new(RBinJavaObj *bin, ut8 *buffer, ut64 offset);
56 R_API RBinJavaCPTypeObj *r_bin_java_long_cp_new(RBinJavaObj *bin, ut8 *buffer, ut64 offset);
57 R_API RBinJavaCPTypeObj *r_bin_java_double_cp_new(RBinJavaObj *bin, ut8 *buffer, ut64 offset);
58 R_API RBinJavaCPTypeObj *r_bin_java_utf8_cp_new(RBinJavaObj *bin, ut8 *buffer, ut64 offset);
59 R_API RBinJavaCPTypeObj *r_bin_java_do_nothing_new(RBinJavaObj *bin, ut8 *buffer, ut64 sz);
60 R_API RBinJavaCPTypeObj *r_bin_java_clone_cp_item(RBinJavaCPTypeObj *obj);
61 R_API RBinJavaCPTypeObj *r_bin_java_clone_cp_idx(RBinJavaObj *bin, ut32 idx);
62 R_API RBinJavaCPTypeObj *r_bin_java_methodhandle_cp_new(RBinJavaObj *bin, ut8 *buffer, ut64 sz);
63 R_API RBinJavaCPTypeObj *r_bin_java_methodtype_cp_new(RBinJavaObj *bin, ut8 *buffer, ut64 sz);
64 R_API RBinJavaCPTypeObj *r_bin_java_invokedynamic_cp_new(RBinJavaObj *bin, ut8 *buffer, ut64 sz);
65 // Deallocs for type objects
66 R_API void r_bin_java_default_free(void /*RBinJavaCPTypeObj*/ *obj);
67 R_API void r_bin_java_obj_free(void /*RBinJavaCPTypeObj*/ *obj);
68 R_API void r_bin_java_utf8_info_free(void /*RBinJavaCPTypeObj*/ *obj);
69 R_API void r_bin_java_do_nothing_free(void /*RBinJavaCPTypeObj*/ *obj);
70 R_API void r_bin_java_fmtype_free(void /*RBinJavaField*/ *fm_type);
71 // handle freeing the lists
72 // handle the reading of the various field
73 R_API RBinJavaAttrInfo *r_bin_java_read_next_attr(RBinJavaObj *bin, const ut64 offset, const ut8 *buf, const ut64 len);
74 R_API RBinJavaCPTypeObj *r_bin_java_read_next_constant_pool_item(RBinJavaObj *bin, const ut64 offset, const ut8 *buf, ut64 len);
75 R_API RBinJavaAttrMetas *r_bin_java_get_attr_type_by_name(const char *name);
76 R_API RBinJavaCPTypeObj *r_bin_java_get_java_null_cp(void);
77 R_API ut64 r_bin_java_read_class_file2(RBinJavaObj *bin, const ut64 offset, const ut8 *buf, ut64 len);
78 R_API RBinJavaAttrInfo *r_bin_java_get_attr_from_field(RBinJavaField *field, R_BIN_JAVA_ATTR_TYPE attr_type, ut32 pos);
79 R_API RBinJavaField *r_bin_java_read_next_field(RBinJavaObj *bin, const ut64 offset, const ut8 *buffer, const ut64 len);
80 R_API RBinJavaField *r_bin_java_read_next_method(RBinJavaObj *bin, const ut64 offset, const ut8 *buffer, const ut64 len);
81 R_API void r_bin_java_print_utf8_cp_summary(RBinJavaCPTypeObj *obj);
82 R_API void r_bin_java_print_name_and_type_cp_summary(RBinJavaCPTypeObj *obj);
83 R_API void r_bin_java_print_double_cp_summary(RBinJavaCPTypeObj *obj);
84 R_API void r_bin_java_print_long_cp_summary(RBinJavaCPTypeObj *obj);
85 R_API void r_bin_java_print_float_cp_summary(RBinJavaCPTypeObj *obj);
86 R_API void r_bin_java_print_integer_cp_summary(RBinJavaCPTypeObj *obj);
87 R_API void r_bin_java_print_string_cp_summary(RBinJavaCPTypeObj *obj);
88 R_API void r_bin_java_print_classref_cp_summary(RBinJavaCPTypeObj *obj);
89 R_API void r_bin_java_print_fieldref_cp_summary(RBinJavaCPTypeObj *obj);
90 R_API void r_bin_java_print_methodref_cp_summary(RBinJavaCPTypeObj *obj);
91 R_API void r_bin_java_print_interfacemethodref_cp_summary(RBinJavaCPTypeObj *obj);
92 R_API void r_bin_java_print_unknown_cp_summary(RBinJavaCPTypeObj *obj);
93 R_API void r_bin_java_print_null_cp_summary(RBinJavaCPTypeObj *obj);
94 R_API void r_bin_java_print_unknown_attr_summary(RBinJavaAttrInfo *attr);
95 R_API void r_bin_java_print_methodhandle_cp_summary(RBinJavaCPTypeObj *obj);
96 R_API void r_bin_java_print_methodtype_cp_summary(RBinJavaCPTypeObj *obj);
97 R_API void r_bin_java_print_invokedynamic_cp_summary(RBinJavaCPTypeObj *obj);
98 R_API RBinJavaCPTypeObj *r_bin_java_unknown_cp_new(RBinJavaObj *bin, ut8 *buffer, ut64 sz);
99 R_API RBinJavaInterfaceInfo *r_bin_java_interface_new(RBinJavaObj *bin, const ut8 *buf, ut64 sz);
100 R_API RBinJavaInterfaceInfo *r_bin_java_read_next_interface_item(RBinJavaObj *bin, const ut64 offset, const ut8 *buf, ut64 len);
101 R_API void r_bin_java_interface_free(void /*RBinJavaInterfaceInfo*/ *obj);
102 R_API void r_bin_java_stack_frame_free(void /*RBinJavaStackMapFrame*/ *obj);
103 R_API void r_bin_java_stack_map_table_attr_free(void /*RBinJavaAttrInfo*/ *attr);
104 R_API void r_bin_java_verification_info_free(void /*RBinJavaVerificationObj*/ *obj);
105 R_API void r_bin_java_print_stack_map_table_attr_summary(RBinJavaAttrInfo *obj);
106 R_API void r_bin_java_print_stack_map_frame_summary(RBinJavaStackMapFrame *obj);
107 R_API void r_bin_java_print_verification_info_summary(RBinJavaVerificationObj *obj);
108 R_API RBinJavaStackMapFrame *r_bin_java_build_stack_frame_from_local_variable_table(RBinJavaObj *bin, RBinJavaAttrInfo *attr);
109 R_API void U(r_bin_java_print_stack_map_append_frame_summary)(RBinJavaStackMapFrame * obj);
110 R_API void U(r_bin_java_stack_frame_default_free)(void /*RBinJavaStackMapFrame*/ *stack_frame);
111 R_API void U(r_bin_java_stack_frame_do_nothing_free)(void /*RBinJavaStackMapFrame*/ *stack_frame);
112 R_API void U(r_bin_java_stack_frame_do_nothing_new)(RBinJavaObj * bin, RBinJavaStackMapFrame * stack_frame, ut64 offset);
113 R_API RBinJavaStackMapFrame *r_bin_java_stack_map_frame_new(ut8 *buffer, ut64 sz, RBinJavaStackMapFrame *p_frame, ut64 buf_offset);
114 // R_API RBinJavaStackMapFrame* r_bin_java_stack_map_frame_new (ut8* buffer, ut64 sz, ut64 buf_offset);
115 R_API RBinJavaElementValue *r_bin_java_element_value_new(ut8 *buffer, ut64 sz, ut64 buf_offset);
116 // R_API RBinJavaVerificationObj* r_bin_java_read_next_verification_info_new(ut8* buffer, ut64 sz, ut64 buf_offset);
117 R_API RBinJavaAnnotation *r_bin_java_annotation_new(ut8 *buffer, ut64 sz, ut64 buf_offset);
118 R_API RBinJavaElementValuePair *r_bin_java_element_pair_new(ut8 *buffer, ut64 sz, ut64 buf_offset);
119 R_API RBinJavaElementValue *r_bin_java_element_value_new(ut8 *buffer, ut64 sz, ut64 buf_offset);
120 // R_API RBinJavaBootStrapArgument* r_bin_java_bootstrap_method_argument_new(ut8* buffer, ut64 sz, ut64 buf_offset);
121 R_API RBinJavaBootStrapMethod *r_bin_java_bootstrap_method_new(ut8 *buffer, ut64 sz, ut64 buf_offset);
122 R_API RBinJavaAnnotationsArray *r_bin_java_annotation_array_new(ut8 *buffer, ut64 sz, ut64 buf_offset);
123 R_API RBinJavaElementValueMetas *r_bin_java_get_ev_meta_from_tag(ut8 tag);
124 R_API RBinJavaCPTypeMetas *U(r_bin_java_get_cp_meta_from_tag)(ut8 tag);
125 R_API void r_bin_java_inner_classes_attr_entry_free(void /*RBinJavaClassesAttribute*/ *attr);
126 R_API void r_bin_java_annotation_default_attr_free(void /*RBinJavaAttrInfo*/ *attr);
127 R_API void r_bin_java_enclosing_methods_attr_free(void /*RBinJavaAttrInfo*/ *attr);
128 R_API void r_bin_java_local_variable_type_table_attr_entry_free(void /*RBinJavaLocalVariableTypeAttribute*/ *lvattr);
129 R_API void r_bin_java_local_variable_type_table_attr_free(void /*RBinJavaAttrInfo*/ *attr);
130 R_API void r_bin_java_signature_attr_free(void /*RBinJavaAttrInfo*/ *attr);
131 R_API void r_bin_java_source_debug_attr_free(void /*RBinJavaAttrInfo*/ *attr);
132 R_API void r_bin_java_element_value_free(void /*RBinJavaElementValue*/ *element_value);
133 R_API void r_bin_java_element_pair_free(void /*RBinJavaElementValuePair*/ *evp);
134 R_API void r_bin_java_annotation_free(void /*RBinJavaAnnotation*/ *annotation);
135 R_API void r_bin_java_rtv_annotations_attr_free(void /*RBinJavaAttrInfo*/ *attr);
136 R_API void r_bin_java_rti_annotations_attr_free(void /*RBinJavaAttrInfo*/ *attr);
137 R_API void r_bin_java_annotation_array_free(void /*RBinJavaAnnotationsArray*/ *annotation_array);
138 R_API void r_bin_java_bootstrap_methods_attr_free(void /*RBinJavaAttrInfo*/ *attr);
139 R_API void r_bin_java_bootstrap_method_free(void /*RBinJavaBootStrapMethod*/ *bsm);
140 R_API void r_bin_java_bootstrap_method_argument_free(void /*RBinJavaBootStrapArgument*/ *bsm_arg);
141 R_API void r_bin_java_rtvp_annotations_attr_free(void /*RBinJavaAttrInfo*/ *attr);
142 R_API void r_bin_java_rtip_annotations_attr_free(void /*RBinJavaAttrInfo*/ *attr);
143 R_API void r_bin_java_unknown_attr_free(void /*RBinJavaAttrInfo*/ *attr);
144 R_API void r_bin_java_code_attr_free(void /*RBinJavaAttrInfo*/ *attr);
145 R_API void r_bin_java_constant_value_attr_free(void /*RBinJavaAttrInfo*/ *attr);
146 R_API void r_bin_java_deprecated_attr_free(void /*RBinJavaAttrInfo*/ *attr);
147 R_API void r_bin_java_exceptions_attr_free(void /*RBinJavaAttrInfo*/ *attr);
148 R_API void r_bin_java_inner_classes_attr_free(void /*RBinJavaAttrInfo*/ *attr);
149 R_API void r_bin_java_line_number_table_attr_free(void /*RBinJavaAttrInfo*/ *attr);
150 R_API void r_bin_java_local_variable_table_attr_free(void /*RBinJavaAttrInfo*/ *attr);
151 R_API void r_bin_java_source_code_file_attr_free(void /*RBinJavaAttrInfo*/ *attr);
152 R_API void r_bin_java_synthetic_attr_free(void /*RBinJavaAttrInfo*/ *attr);
153
154 R_API void r_bin_java_print_annotation_default_attr_summary(RBinJavaAttrInfo *attr);
155 R_API void r_bin_java_print_enclosing_methods_attr_summary(RBinJavaAttrInfo *attr);
156 R_API void r_bin_java_print_local_variable_type_attr_summary(RBinJavaLocalVariableTypeAttribute *lvattr);
157 R_API void r_bin_java_print_local_variable_type_table_attr_summary(RBinJavaAttrInfo *attr);
158 R_API void r_bin_java_print_signature_attr_summary(RBinJavaAttrInfo *attr);
159 R_API void r_bin_java_print_source_debug_attr_summary(RBinJavaAttrInfo *attr);
160 R_API void r_bin_java_print_element_value_summary(RBinJavaElementValue *element_value);
161 R_API void r_bin_java_print_annotation_summary(RBinJavaAnnotation *annotation);
162 R_API void r_bin_java_print_element_pair_summary(RBinJavaElementValuePair *evp);
163 R_API void r_bin_java_print_bootstrap_methods_attr_summary(RBinJavaAttrInfo *attr);
164 // R_API void r_bin_java_bootstrap_method_summary(RBinJavaBootStrapMethod *bsm);
165 // R_API void r_bin_java_bootstrap_method_argument_summary(RBinJavaBootStrapArgument *bsm_arg);
166 R_API void r_bin_java_print_rtv_annotations_attr_summary(RBinJavaAttrInfo *attr);
167 R_API void r_bin_java_print_rti_annotations_attr_summary(RBinJavaAttrInfo *attr);
168 R_API void r_bin_java_print_annotation_array_summary(RBinJavaAnnotationsArray *annotation_array);
169 R_API void r_bin_java_print_rtvp_annotations_attr_summary(RBinJavaAttrInfo *attr);
170 R_API void r_bin_java_print_rtip_annotations_attr_summary(RBinJavaAttrInfo *attr);
171 R_API void r_bin_java_attribute_free(void /*RBinJavaAttrInfo*/ *attr);
172 R_API void r_bin_java_constant_pool(void /*RBinJavaCPTypeObj*/ *obj);
173 R_API void r_bin_java_print_field_summary(RBinJavaField *field);
174 // R_API void r_bin_java_print_interface_summary(RBinJavaField *field);
175 R_API void r_bin_java_print_method_summary(RBinJavaField *field);
176 R_API void r_bin_java_print_code_exceptions_attr_summary(RBinJavaExceptionEntry *exc_entry);
177 R_API void r_bin_java_print_code_attr_summary(RBinJavaAttrInfo *attr);
178 R_API void r_bin_java_print_constant_value_attr_summary(RBinJavaAttrInfo *attr);
179 R_API void r_bin_java_print_deprecated_attr_summary(RBinJavaAttrInfo *attr);
180 R_API void r_bin_java_print_exceptions_attr_summary(RBinJavaAttrInfo *attr);
181 R_API void r_bin_java_print_classes_attr_summary(RBinJavaClassesAttribute *icattr);
182 R_API void r_bin_java_print_inner_classes_attr_summary(RBinJavaAttrInfo *attr);
183 R_API void r_bin_java_print_line_number_table_attr_summary(RBinJavaAttrInfo *attr);
184 R_API void r_bin_java_print_local_variable_attr_summary(RBinJavaLocalVariableAttribute *lvattr);
185 R_API void r_bin_java_print_local_variable_table_attr_summary(RBinJavaAttrInfo *attr);
186 R_API void r_bin_java_print_source_code_file_attr_summary(RBinJavaAttrInfo *attr);
187 R_API void r_bin_java_print_synthetic_attr_summary(RBinJavaAttrInfo *attr);
188 R_API void r_bin_java_print_attr_summary(RBinJavaAttrInfo *attr);
189 R_API RBinJavaAttrInfo *r_bin_java_read_next_attr_from_buffer(RBinJavaObj *bin, ut8 *buffer, st64 sz, st64 buf_offset);
190 R_API RBinJavaAttrInfo *r_bin_java_unknown_attr_new(RBinJavaObj *bin, ut8 *buf, ut64 sz, ut64 buf_offset);
191 R_API RBinJavaAttrInfo *r_bin_java_annotation_default_attr_new(RBinJavaObj *bin, ut8 *buf, ut64 sz, ut64 buf_offset);
192 R_API RBinJavaAttrInfo *r_bin_java_enclosing_methods_attr_new(RBinJavaObj *bin, ut8 *buf, ut64 sz, ut64 buf_offset);
193 R_API RBinJavaAttrInfo *r_bin_java_local_variable_type_table_attr_new(RBinJavaObj *bin, ut8 *buf, ut64 sz, ut64 buf_offset);
194 R_API RBinJavaAttrInfo *r_bin_java_signature_attr_new(RBinJavaObj *bin, ut8 *buf, ut64 sz, ut64 buf_offset);
195 R_API RBinJavaAttrInfo *r_bin_java_source_debug_attr_new(RBinJavaObj *bin, ut8 *buf, ut64 sz, ut64 buf_offset);
196 R_API RBinJavaAttrInfo *r_bin_java_bootstrap_methods_attr_new(RBinJavaObj *bin, ut8 *buf, ut64 sz, ut64 buf_offset);
197 R_API RBinJavaAttrInfo *r_bin_java_rtv_annotations_attr_new(RBinJavaObj *bin, ut8 *buf, ut64 sz, ut64 buf_offset);
198 R_API RBinJavaAttrInfo *r_bin_java_rti_annotations_attr_new(RBinJavaObj *bin, ut8 *buf, ut64 sz, ut64 buf_offset);
199 R_API RBinJavaAttrInfo *r_bin_java_rtvp_annotations_attr_new(RBinJavaObj *bin, ut8 *buf, ut64 sz, ut64 buf_offset);
200 R_API RBinJavaAttrInfo *r_bin_java_rtip_annotations_attr_new(RBinJavaObj *bin, ut8 *buf, ut64 sz, ut64 buf_offset);
201 R_API RBinJavaAttrInfo *r_bin_java_code_attr_new(RBinJavaObj *bin, ut8 *buf, ut64 sz, ut64 buf_offset);
202 R_API RBinJavaAttrInfo *r_bin_java_constant_value_attr_new(RBinJavaObj *bin, ut8 *buf, ut64 sz, ut64 buf_offset);
203 R_API RBinJavaAttrInfo *r_bin_java_deprecated_attr_new(RBinJavaObj *bin, ut8 *buf, ut64 sz, ut64 buf_offset);
204 R_API RBinJavaAttrInfo *r_bin_java_exceptions_attr_new(RBinJavaObj *bin, ut8 *buf, ut64 sz, ut64 buf_offset);
205 R_API RBinJavaAttrInfo *r_bin_java_inner_classes_attr_new(RBinJavaObj *bin, ut8 *buf, ut64 sz, ut64 buf_offset);
206 R_API RBinJavaAttrInfo *r_bin_java_line_number_table_attr_new(RBinJavaObj *bin, ut8 *buf, ut64 sz, ut64 buf_offset);
207 R_API RBinJavaAttrInfo *r_bin_java_local_variable_table_attr_new(RBinJavaObj *bin, ut8 *buf, ut64 sz, ut64 buf_offset);
208 R_API RBinJavaAttrInfo *r_bin_java_source_code_file_attr_new(RBinJavaObj *bin, ut8 *buf, ut64 sz, ut64 buf_offset);
209 R_API RBinJavaAttrInfo *r_bin_java_stack_map_table_attr_new(RBinJavaObj *bin, ut8 *buf, ut64 sz, ut64 buf_offset);
210 R_API RBinJavaAttrInfo *r_bin_java_synthetic_attr_new(RBinJavaObj *bin, ut8 *buf, ut64 sz, ut64 buf_offset);
211 R_API ut64 r_bin_java_unknown_attr_calc_size(RBinJavaAttrInfo *attr);
212 R_API ut64 r_bin_java_annotation_default_attr_calc_size(RBinJavaAttrInfo *attr);
213 R_API ut64 r_bin_java_enclosing_methods_attr_calc_size(RBinJavaAttrInfo *attr);
214 R_API ut64 r_bin_java_local_variable_type_table_attr_calc_size(RBinJavaAttrInfo *attr);
215 R_API ut64 r_bin_java_signature_attr_calc_size(RBinJavaAttrInfo *attr);
216 R_API ut64 r_bin_java_source_debug_attr_calc_size(RBinJavaAttrInfo *attr);
217 R_API ut64 r_bin_java_bootstrap_methods_attr_calc_size(RBinJavaAttrInfo *attr);
218 R_API ut64 r_bin_java_rtv_annotations_attr_calc_size(RBinJavaAttrInfo *attr);
219 R_API ut64 r_bin_java_rti_annotations_attr_calc_size(RBinJavaAttrInfo *attr);
220 R_API ut64 r_bin_java_rtvp_annotations_attr_calc_size(RBinJavaAttrInfo *attr);
221 R_API ut64 r_bin_java_rtip_annotations_attr_calc_size(RBinJavaAttrInfo *attr);
222 R_API ut64 r_bin_java_code_attr_calc_size(RBinJavaAttrInfo *attr);
223 R_API ut64 r_bin_java_constant_value_attr_calc_size(RBinJavaAttrInfo *attr);
224 R_API ut64 r_bin_java_deprecated_attr_calc_size(RBinJavaAttrInfo *attr);
225 R_API ut64 r_bin_java_exceptions_attr_calc_size(RBinJavaAttrInfo *attr);
226 R_API ut64 r_bin_java_inner_classes_attr_calc_size(RBinJavaAttrInfo *attr);
227 R_API ut64 r_bin_java_line_number_table_attr_calc_size(RBinJavaAttrInfo *attr);
228 R_API ut64 r_bin_java_local_variable_table_attr_calc_size(RBinJavaAttrInfo *attr);
229 R_API ut64 r_bin_java_source_code_file_attr_calc_size(RBinJavaAttrInfo *attr);
230 R_API ut64 r_bin_java_stack_map_table_attr_calc_size(RBinJavaAttrInfo *attr);
231 R_API ut64 r_bin_java_synthetic_attr_calc_size(RBinJavaAttrInfo *attr);
232 R_API ut64 r_bin_java_bootstrap_method_calc_size(RBinJavaBootStrapMethod *bsm);
233 R_API ut64 r_bin_java_element_pair_calc_size(RBinJavaElementValuePair *evp);
234 R_API ut64 r_bin_java_element_value_calc_size(RBinJavaElementValue *element_value);
235
236 R_API ut64 r_bin_java_unknown_cp_calc_size(RBinJavaCPTypeObj *obj);
237 R_API ut64 r_bin_java_class_cp_calc_size(RBinJavaCPTypeObj *obj);
238 R_API ut64 r_bin_java_fieldref_cp_calc_size(RBinJavaCPTypeObj *obj);
239 R_API ut64 r_bin_java_methodref_cp_calc_size(RBinJavaCPTypeObj *obj);
240 R_API ut64 r_bin_java_interfacemethodref_cp_calc_size(RBinJavaCPTypeObj *obj);
241 R_API ut64 r_bin_java_name_and_type_cp_calc_size(RBinJavaCPTypeObj *obj);
242 R_API ut64 r_bin_java_string_cp_calc_size(RBinJavaCPTypeObj *obj);
243 R_API ut64 r_bin_java_integer_cp_calc_size(RBinJavaCPTypeObj *obj);
244 R_API ut64 r_bin_java_float_cp_calc_size(RBinJavaCPTypeObj *obj);
245 R_API ut64 r_bin_java_long_cp_calc_size(RBinJavaCPTypeObj *obj);
246 R_API ut64 r_bin_java_double_cp_calc_size(RBinJavaCPTypeObj *obj);
247 R_API ut64 r_bin_java_utf8_cp_calc_size(RBinJavaCPTypeObj *obj);
248 R_API ut64 r_bin_java_do_nothing_calc_size(RBinJavaCPTypeObj *obj);
249 R_API ut64 r_bin_java_methodhandle_cp_calc_size(RBinJavaCPTypeObj *obj);
250 R_API ut64 r_bin_java_methodtype_cp_calc_size(RBinJavaCPTypeObj *obj);
251 R_API ut64 r_bin_java_invokedynamic_cp_calc_size(RBinJavaCPTypeObj *obj);
252 R_API RBinJavaStackMapFrame *r_bin_java_default_stack_frame(void);
253
254 R_API RList *r_bin_java_find_cp_const_by_val_float(RBinJavaObj *bin_obj, const ut8 *bytes, ut32 len);
255 R_API RList *r_bin_java_find_cp_const_by_val_double(RBinJavaObj *bin_obj, const ut8 *bytes, ut32 len);
256 R_API RList *r_bin_java_find_cp_const_by_val_int(RBinJavaObj *bin_obj, const ut8 *bytes, ut32 len);
257 R_API RList *r_bin_java_find_cp_const_by_val_long(RBinJavaObj *bin_obj, const ut8 *bytes, ut32 len);
258 R_API RList *r_bin_java_find_cp_const_by_val_utf8(RBinJavaObj *bin_obj, const ut8 *bytes, ut32 len);
259 R_API ut8 *r_bin_java_cp_append_classref_and_name(RBinJavaObj *bin, ut32 *out_sz, const char *classname, const ut32 classname_len);
260 R_API ut8 *U(r_bin_java_cp_append_ref_cname_fname_ftype)(RBinJavaObj * bin, ut32 * out_sz, ut8 tag, const char *cname, const ut32 c_len, const char *fname, const ut32 f_len, const char *tname, const ut32 t_len);
261 R_API ut8 *r_bin_java_cp_get_classref(RBinJavaObj *bin, ut32 *out_sz, const char *classname, const ut32 classname_len, const ut16 name_idx);
262 R_API ut8 *U(r_bin_java_cp_get_method_ref)(RBinJavaObj * bin, ut32 * out_sz, ut16 class_idx, ut16 name_and_type_idx);
263 R_API ut8 *U(r_bin_java_cp_get_field_ref)(RBinJavaObj * bin, ut32 * out_sz, ut16 class_idx, ut16 name_and_type_idx);
264 R_API ut8 *r_bin_java_cp_get_fm_ref(RBinJavaObj *bin, ut32 *out_sz, ut8 tag, ut16 class_idx, ut16 name_and_type_idx);
265 R_API ut8 *r_bin_java_cp_get_2_ut16(RBinJavaObj *bin, ut32 *out_sz, ut8 tag, ut16 ut16_one, ut16 ut16_two);
266 R_API ut8 *r_bin_java_cp_get_name_type(RBinJavaObj *bin, ut32 *out_sz, ut16 name_idx, ut16 type_idx);
267
convert_string(const char * bytes,ut32 len)268 static char *convert_string(const char *bytes, ut32 len) {
269 ut32 idx = 0, pos = 0;
270 ut32 str_sz = 32 * len + 1;
271 char *cpy_buffer = len > 0 ? malloc (str_sz) : NULL;
272 if (!cpy_buffer) {
273 return cpy_buffer;
274 }
275 // 4x is the increase from byte to \xHH where HH represents hexed byte
276 memset (cpy_buffer, 0, str_sz);
277 while (idx < len && pos < len) {
278 if (dso_json_char_needs_hexing (bytes[idx])) {
279 if (pos + 2 < len) {
280 free (cpy_buffer);
281 return NULL;
282 }
283 sprintf (cpy_buffer + pos, "\\x%02x", bytes[idx]);
284 pos += 4;
285 } else {
286 cpy_buffer[pos] = bytes[idx];
287 pos++;
288 }
289 idx++;
290 }
291 return cpy_buffer;
292 }
293
294 // taken from LLVM Code Byte Swap
295 // TODO: move into r_util
U(r_bin_java_swap_uint)296 R_API ut32 U(r_bin_java_swap_uint)(ut32 x) {
297 const ut32 Byte0 = x & 0x000000FF;
298 const ut32 Byte1 = x & 0x0000FF00;
299 const ut32 Byte2 = x & 0x00FF0000;
300 const ut32 Byte3 = x & 0xFF000000;
301 return (Byte0 << 24) | (Byte1 << 8) | (Byte2 >> 8) | (Byte3 >> 24);
302 }
303
304 static bool R_BIN_JAVA_NULL_TYPE_INITTED = false;
305 // XXX - this is a global variable used while parsing the class file
306 // this variable should DIE.
307 static RBinJavaObj *R_BIN_JAVA_GLOBAL_BIN = NULL;
308 static RBinJavaAccessFlags FIELD_ACCESS_FLAGS[] = {
309 { "public", R_BIN_JAVA_FIELD_ACC_PUBLIC, 6 },
310 { "private", R_BIN_JAVA_FIELD_ACC_PRIVATE, 7 },
311 { "protected", R_BIN_JAVA_FIELD_ACC_PROTECTED, 9 },
312 { "static", R_BIN_JAVA_FIELD_ACC_STATIC, 6 },
313 { "final", R_BIN_JAVA_FIELD_ACC_FINAL, 5 },
314 { "undefined.0x0020", 0x0020, 16 },
315 { "volatile", R_BIN_JAVA_FIELD_ACC_VOLATILE, 8 },
316 { "transient", R_BIN_JAVA_FIELD_ACC_TRANSIENT, 9 },
317 { "undefined.0x0100", 0x0100, 16 },
318 { "undefined.0x0200", 0x0200, 16 },
319 { "undefined.0x0400", 0x0400, 16 },
320 { "undefined.0x0800", 0x0800, 16 },
321 { "synthetic", R_BIN_JAVA_FIELD_ACC_SYNTHETIC, 9 },
322 { "undefined.0x2000", 0x2000, 16 },
323 { "enum", R_BIN_JAVA_FIELD_ACC_ENUM, 16 },
324 { "undefined.0x8000", 0x8000, 16 },
325 { NULL, 0, 0 }
326 };
327 static RBinJavaAccessFlags METHOD_ACCESS_FLAGS[] = {
328 { "public", R_BIN_JAVA_METHOD_ACC_PUBLIC, 6 },
329 { "private", R_BIN_JAVA_METHOD_ACC_PRIVATE, 7 },
330 { "protected", R_BIN_JAVA_METHOD_ACC_PROTECTED, 9 },
331 { "static", R_BIN_JAVA_METHOD_ACC_STATIC, 6 },
332 { "final", R_BIN_JAVA_METHOD_ACC_FINAL, 5 },
333 { "synchronized", R_BIN_JAVA_METHOD_ACC_SYNCHRONIZED, 12 },
334 { "bridge", R_BIN_JAVA_METHOD_ACC_BRIDGE, 6 },
335 { "varargs", R_BIN_JAVA_METHOD_ACC_VARARGS, 7 },
336 { "native", R_BIN_JAVA_METHOD_ACC_NATIVE, 6 },
337 { "interface", R_BIN_JAVA_METHOD_ACC_INTERFACE, 9 },
338 { "abstract", R_BIN_JAVA_METHOD_ACC_ABSTRACT, 8 },
339 { "strict", R_BIN_JAVA_METHOD_ACC_STRICT, 6 },
340 { "synthetic", R_BIN_JAVA_METHOD_ACC_SYNTHETIC, 9 },
341 { "annotation", R_BIN_JAVA_METHOD_ACC_ANNOTATION, 10 },
342 { "enum", R_BIN_JAVA_METHOD_ACC_ENUM, 4 },
343 { "undefined.0x8000", 0x8000, 16 },
344 { NULL, 0, 0 }
345 };
346 // XXX - Fix these there are some incorrect ongs
347 static RBinJavaAccessFlags CLASS_ACCESS_FLAGS[] = {
348 { "public", R_BIN_JAVA_CLASS_ACC_PUBLIC, 6 },
349 { "undefined.0x0002", 0x0002, 16 },
350 { "undefined.0x0004", 0x0004, 16 },
351 { "undefined.0x0008", 0x0008, 16 },
352 { "final", R_BIN_JAVA_CLASS_ACC_FINAL, 5 },
353 { "super", R_BIN_JAVA_CLASS_ACC_SUPER, 5 },
354 { "undefined.0x0040", 0x0040, 16 },
355 { "undefined.0x0080", 0x0080, 16 },
356 { "undefined.0x0100", 0x0100, 16 },
357 { "interface", R_BIN_JAVA_CLASS_ACC_INTERFACE, 9 },
358 { "abstract", R_BIN_JAVA_CLASS_ACC_ABSTRACT, 8 },
359 { "undefined.0x0800", 0x0800, 16 },
360 { "synthetic", R_BIN_JAVA_CLASS_ACC_SYNTHETIC, 9 },
361 { "annotation", R_BIN_JAVA_CLASS_ACC_ANNOTATION, 10 },
362 { "enum", R_BIN_JAVA_CLASS_ACC_ENUM, 4 },
363 { "undefined.0x8000", 0x8000, 16 },
364 { NULL, 0, 0 }
365 };
366 static RBinJavaRefMetas R_BIN_JAVA_REF_METAS[] = {
367 { "Unknown", R_BIN_JAVA_REF_UNKNOWN },
368 { "GetField", R_BIN_JAVA_REF_GETFIELD },
369 { "GetStatic", R_BIN_JAVA_REF_GETSTATIC },
370 { "PutField", R_BIN_JAVA_REF_PUTFIELD },
371 { "PutStatic", R_BIN_JAVA_REF_PUTSTATIC },
372 { "InvokeVirtual", R_BIN_JAVA_REF_INVOKEVIRTUAL },
373 { "InvokeStatic", R_BIN_JAVA_REF_INVOKESTATIC },
374 { "InvokeSpecial", R_BIN_JAVA_REF_INVOKESPECIAL },
375 { "NewInvokeSpecial", R_BIN_JAVA_REF_NEWINVOKESPECIAL },
376 { "InvokeInterface", R_BIN_JAVA_REF_INVOKEINTERFACE }
377 };
378 static ut16 R_BIN_JAVA_ELEMENT_VALUE_METAS_SZ = 14;
379 static RBinJavaElementValueMetas R_BIN_JAVA_ELEMENT_VALUE_METAS[] = {
380 { "Byte", R_BIN_JAVA_EV_TAG_BYTE, NULL },
381 { "Char", R_BIN_JAVA_EV_TAG_CHAR, NULL },
382 { "Double", R_BIN_JAVA_EV_TAG_DOUBLE, NULL },
383 { "Float", R_BIN_JAVA_EV_TAG_FLOAT, NULL },
384 { "Integer", R_BIN_JAVA_EV_TAG_INT, NULL },
385 { "Long", R_BIN_JAVA_EV_TAG_LONG, NULL },
386 { "Short", R_BIN_JAVA_EV_TAG_SHORT, NULL },
387 { "Boolean", R_BIN_JAVA_EV_TAG_BOOLEAN, NULL },
388 { "Array of ", R_BIN_JAVA_EV_TAG_ARRAY, NULL },
389 { "String", R_BIN_JAVA_EV_TAG_STRING, NULL },
390 { "Enum", R_BIN_JAVA_EV_TAG_ENUM, NULL },
391 { "Class", R_BIN_JAVA_EV_TAG_CLASS, NULL },
392 { "Annotation", R_BIN_JAVA_EV_TAG_ANNOTATION, NULL },
393 { "Unknown", R_BIN_JAVA_EV_TAG_UNKNOWN, NULL },
394 };
395 static RBinJavaVerificationMetas R_BIN_JAVA_VERIFICATION_METAS[] = {
396 { "Top", R_BIN_JAVA_STACKMAP_TOP },
397 { "Integer", R_BIN_JAVA_STACKMAP_INTEGER },
398 { "Float", R_BIN_JAVA_STACKMAP_FLOAT },
399 { "Double", R_BIN_JAVA_STACKMAP_DOUBLE },
400 { "Long", R_BIN_JAVA_STACKMAP_LONG },
401 { "NULL", R_BIN_JAVA_STACKMAP_NULL },
402 { "This", R_BIN_JAVA_STACKMAP_THIS },
403 { "Object", R_BIN_JAVA_STACKMAP_OBJECT },
404 { "Uninitialized", R_BIN_JAVA_STACKMAP_UNINIT },
405 { "Unknown", R_BIN_JAVA_STACKMAP_UNKNOWN }
406 };
407 static RBinJavaStackMapFrameMetas R_BIN_JAVA_STACK_MAP_FRAME_METAS[] = {
408 { "ImplicitStackFrame", R_BIN_JAVA_STACK_FRAME_IMPLICIT, NULL },
409 { "Same", R_BIN_JAVA_STACK_FRAME_SAME, NULL },
410 { "SameLocals1StackItem", R_BIN_JAVA_STACK_FRAME_SAME_LOCALS_1, NULL },
411 { "Chop", R_BIN_JAVA_STACK_FRAME_CHOP, NULL },
412 { "SameFrameExtended", R_BIN_JAVA_STACK_FRAME_SAME_FRAME_EXTENDED, NULL },
413 { "Append", R_BIN_JAVA_STACK_FRAME_APPEND, NULL },
414 { "FullFrame", R_BIN_JAVA_STACK_FRAME_FULL_FRAME, NULL },
415 { "Reserved", R_BIN_JAVA_STACK_FRAME_RESERVED, NULL }
416 };
417
418 static RBinJavaCPTypeObjectAllocs R_BIN_ALLOCS_CONSTANTS[] = {
419 { r_bin_java_do_nothing_new, r_bin_java_do_nothing_free, r_bin_java_print_null_cp_summary, r_bin_java_do_nothing_calc_size, r_bin_java_print_null_cp_stringify },
420 { r_bin_java_utf8_cp_new, r_bin_java_utf8_info_free, r_bin_java_print_utf8_cp_summary, r_bin_java_utf8_cp_calc_size, r_bin_java_print_utf8_cp_stringify },
421 { r_bin_java_unknown_cp_new, r_bin_java_default_free, r_bin_java_print_unknown_cp_summary, r_bin_java_unknown_cp_calc_size, r_bin_java_print_unknown_cp_stringify },
422 { r_bin_java_integer_cp_new, r_bin_java_default_free, r_bin_java_print_integer_cp_summary, r_bin_java_integer_cp_calc_size, r_bin_java_print_integer_cp_stringify },
423 { r_bin_java_float_cp_new, r_bin_java_default_free, r_bin_java_print_float_cp_summary, r_bin_java_float_cp_calc_size, r_bin_java_print_float_cp_stringify },
424 { r_bin_java_long_cp_new, r_bin_java_default_free, r_bin_java_print_long_cp_summary, r_bin_java_long_cp_calc_size, r_bin_java_print_long_cp_stringify },
425 { r_bin_java_double_cp_new, r_bin_java_default_free, r_bin_java_print_double_cp_summary, r_bin_java_double_cp_calc_size, r_bin_java_print_double_cp_stringify },
426 { r_bin_java_class_cp_new, r_bin_java_default_free, r_bin_java_print_classref_cp_summary, r_bin_java_class_cp_calc_size, r_bin_java_print_classref_cp_stringify },
427 { r_bin_java_string_cp_new, r_bin_java_default_free, r_bin_java_print_string_cp_summary, r_bin_java_string_cp_calc_size, r_bin_java_print_string_cp_stringify },
428 { r_bin_java_fieldref_cp_new, r_bin_java_default_free, r_bin_java_print_fieldref_cp_summary, r_bin_java_fieldref_cp_calc_size, r_bin_java_print_fieldref_cp_stringify },
429 { r_bin_java_methodref_cp_new, r_bin_java_default_free, r_bin_java_print_methodref_cp_summary, r_bin_java_methodref_cp_calc_size, r_bin_java_print_methodref_cp_stringify },
430 { r_bin_java_interfacemethodref_cp_new, r_bin_java_default_free, r_bin_java_print_interfacemethodref_cp_summary, r_bin_java_interfacemethodref_cp_calc_size, r_bin_java_print_interfacemethodref_cp_stringify },
431 { r_bin_java_name_and_type_cp_new, r_bin_java_default_free, r_bin_java_print_name_and_type_cp_summary, r_bin_java_name_and_type_cp_calc_size, r_bin_java_print_name_and_type_cp_stringify },
432 { NULL, NULL, NULL, NULL, NULL },
433 { NULL, NULL, NULL, NULL, NULL },
434 { r_bin_java_methodhandle_cp_new, r_bin_java_default_free, r_bin_java_print_methodhandle_cp_summary, r_bin_java_methodhandle_cp_calc_size, r_bin_java_print_methodhandle_cp_stringify },
435 { r_bin_java_methodtype_cp_new, r_bin_java_default_free, r_bin_java_print_methodtype_cp_summary, r_bin_java_methodtype_cp_calc_size, r_bin_java_print_methodtype_cp_stringify },
436 { NULL, NULL, NULL, NULL, NULL },
437 { r_bin_java_invokedynamic_cp_new, r_bin_java_default_free, r_bin_java_print_invokedynamic_cp_summary, r_bin_java_invokedynamic_cp_calc_size, r_bin_java_print_invokedynamic_cp_stringify },
438 };
439 static RBinJavaCPTypeObj R_BIN_JAVA_NULL_TYPE;
440 static ut8 R_BIN_JAVA_CP_METAS_SZ = 12;
441 static RBinJavaCPTypeMetas R_BIN_JAVA_CP_METAS[] = {
442 // Each field has a name pointer and a tag field
443 { "NULL", R_BIN_JAVA_CP_NULL, 0, &R_BIN_ALLOCS_CONSTANTS[0] },
444 { "Utf8", R_BIN_JAVA_CP_UTF8, 3, &R_BIN_ALLOCS_CONSTANTS[1] }, // 2 bytes = length, N bytes string (containts a pointer in the field)
445 { "Unknown", R_BIN_JAVA_CP_UNKNOWN, 0, &R_BIN_ALLOCS_CONSTANTS[2] },
446 { "Integer", R_BIN_JAVA_CP_INTEGER, 5, &R_BIN_ALLOCS_CONSTANTS[3] }, // 4 bytes
447 { "Float", R_BIN_JAVA_CP_FLOAT, 5, &R_BIN_ALLOCS_CONSTANTS[4] }, // 4 bytes
448 { "Long", R_BIN_JAVA_CP_LONG, 9, &R_BIN_ALLOCS_CONSTANTS[5] }, // 4 high 4 low
449 { "Double", R_BIN_JAVA_CP_DOUBLE, 9, &R_BIN_ALLOCS_CONSTANTS[6] }, // 4 high 4 low
450 { "Class", R_BIN_JAVA_CP_CLASS, 3, &R_BIN_ALLOCS_CONSTANTS[7] }, // 2 name_idx
451 { "String", R_BIN_JAVA_CP_STRING, 3, &R_BIN_ALLOCS_CONSTANTS[8] }, // 2 string_idx
452 { "FieldRef", R_BIN_JAVA_CP_FIELDREF, 5, &R_BIN_ALLOCS_CONSTANTS[9] }, // 2 class idx, 2 name/type_idx
453 { "MethodRef", R_BIN_JAVA_CP_METHODREF, 5, &R_BIN_ALLOCS_CONSTANTS[10] }, // 2 class idx, 2 name/type_idx
454 { "InterfaceMethodRef", R_BIN_JAVA_CP_INTERFACEMETHOD_REF, 5, &R_BIN_ALLOCS_CONSTANTS[11] }, // 2 class idx, 2 name/type_idx
455 { "NameAndType", R_BIN_JAVA_CP_NAMEANDTYPE, 5, &R_BIN_ALLOCS_CONSTANTS[12] }, // 4 high 4 low
456 { "Unknown", R_BIN_JAVA_CP_UNKNOWN, 0, &R_BIN_ALLOCS_CONSTANTS[2] },
457 { "Unknown", R_BIN_JAVA_CP_UNKNOWN, 0, &R_BIN_ALLOCS_CONSTANTS[2] },
458 { "MethodHandle", R_BIN_JAVA_CP_METHODHANDLE, 4, &R_BIN_ALLOCS_CONSTANTS[15] }, // 4 high 4 low
459 { "MethodType", R_BIN_JAVA_CP_METHODTYPE, 3, &R_BIN_ALLOCS_CONSTANTS[16] }, // 4 high 4 low
460 { "Unknown", R_BIN_JAVA_CP_UNKNOWN, 0, &R_BIN_ALLOCS_CONSTANTS[2] },
461 { "InvokeDynamic", R_BIN_JAVA_CP_INVOKEDYNAMIC, 5, &R_BIN_ALLOCS_CONSTANTS[18] }, // 4 high 4 low
462 };
463 static RBinJavaAttrInfoObjectAllocs RBIN_JAVA_ATTRS_ALLOCS[] = {
464 { r_bin_java_annotation_default_attr_new, r_bin_java_annotation_default_attr_free, r_bin_java_print_annotation_default_attr_summary, r_bin_java_annotation_default_attr_calc_size },
465 { r_bin_java_bootstrap_methods_attr_new, r_bin_java_bootstrap_methods_attr_free, r_bin_java_print_bootstrap_methods_attr_summary, r_bin_java_bootstrap_methods_attr_calc_size },
466 { r_bin_java_code_attr_new, r_bin_java_code_attr_free, r_bin_java_print_code_attr_summary, r_bin_java_code_attr_calc_size },
467 { r_bin_java_constant_value_attr_new, r_bin_java_constant_value_attr_free, r_bin_java_print_constant_value_attr_summary, r_bin_java_constant_value_attr_calc_size },
468 { r_bin_java_deprecated_attr_new, r_bin_java_deprecated_attr_free, r_bin_java_print_deprecated_attr_summary, r_bin_java_deprecated_attr_calc_size },
469 { r_bin_java_enclosing_methods_attr_new, r_bin_java_enclosing_methods_attr_free, r_bin_java_print_enclosing_methods_attr_summary, r_bin_java_enclosing_methods_attr_calc_size },
470 { r_bin_java_exceptions_attr_new, r_bin_java_exceptions_attr_free, r_bin_java_print_exceptions_attr_summary, r_bin_java_exceptions_attr_calc_size },
471 { r_bin_java_inner_classes_attr_new, r_bin_java_inner_classes_attr_free, r_bin_java_print_inner_classes_attr_summary, r_bin_java_inner_classes_attr_calc_size },
472 { r_bin_java_line_number_table_attr_new, r_bin_java_line_number_table_attr_free, r_bin_java_print_line_number_table_attr_summary, r_bin_java_line_number_table_attr_calc_size },
473 { r_bin_java_local_variable_table_attr_new, r_bin_java_local_variable_table_attr_free, r_bin_java_print_local_variable_table_attr_summary, r_bin_java_local_variable_table_attr_calc_size },
474 { r_bin_java_local_variable_type_table_attr_new, r_bin_java_local_variable_type_table_attr_free, r_bin_java_print_local_variable_type_table_attr_summary, r_bin_java_local_variable_type_table_attr_calc_size },
475 { r_bin_java_rti_annotations_attr_new, r_bin_java_rti_annotations_attr_free, r_bin_java_print_rti_annotations_attr_summary, r_bin_java_rti_annotations_attr_calc_size },
476 { r_bin_java_rtip_annotations_attr_new, r_bin_java_rtip_annotations_attr_free, r_bin_java_print_rtip_annotations_attr_summary, r_bin_java_rtip_annotations_attr_calc_size },
477 { r_bin_java_rtv_annotations_attr_new, r_bin_java_rtv_annotations_attr_free, r_bin_java_print_rtv_annotations_attr_summary, r_bin_java_rtv_annotations_attr_calc_size },
478 { r_bin_java_rtvp_annotations_attr_new, r_bin_java_rtvp_annotations_attr_free, r_bin_java_print_rtvp_annotations_attr_summary, r_bin_java_rtvp_annotations_attr_calc_size },
479 { r_bin_java_signature_attr_new, r_bin_java_signature_attr_free, r_bin_java_print_signature_attr_summary, r_bin_java_signature_attr_calc_size },
480 { r_bin_java_source_debug_attr_new, r_bin_java_source_debug_attr_free, r_bin_java_print_source_debug_attr_summary, r_bin_java_source_debug_attr_calc_size },
481 { r_bin_java_source_code_file_attr_new, r_bin_java_source_code_file_attr_free, r_bin_java_print_source_code_file_attr_summary, r_bin_java_source_code_file_attr_calc_size },
482 { r_bin_java_stack_map_table_attr_new, r_bin_java_stack_map_table_attr_free, r_bin_java_print_stack_map_table_attr_summary, r_bin_java_stack_map_table_attr_calc_size },
483 { r_bin_java_synthetic_attr_new, r_bin_java_synthetic_attr_free, r_bin_java_print_synthetic_attr_summary, r_bin_java_synthetic_attr_calc_size },
484 { r_bin_java_unknown_attr_new, r_bin_java_unknown_attr_free, r_bin_java_print_unknown_attr_summary, r_bin_java_unknown_attr_calc_size }
485 };
486 // R_API ut32 RBIN_JAVA_ATTRS_METAS_SZ = 21;
487 static ut32 RBIN_JAVA_ATTRS_METAS_SZ = 20;
488 static RBinJavaAttrMetas RBIN_JAVA_ATTRS_METAS[] = {
489 { "AnnotationDefault", R_BIN_JAVA_ATTR_TYPE_ANNOTATION_DEFAULT_ATTR, &RBIN_JAVA_ATTRS_ALLOCS[0] },
490 { "BootstrapMethods", R_BIN_JAVA_ATTR_TYPE_BOOTSTRAP_METHODS_ATTR, &RBIN_JAVA_ATTRS_ALLOCS[1] },
491 { "Code", R_BIN_JAVA_ATTR_TYPE_CODE_ATTR, &RBIN_JAVA_ATTRS_ALLOCS[2] },
492 { "ConstantValue", R_BIN_JAVA_ATTR_TYPE_CONST_VALUE_ATTR, &RBIN_JAVA_ATTRS_ALLOCS[3] },
493 { "Deperecated", R_BIN_JAVA_ATTR_TYPE_DEPRECATED_ATTR, &RBIN_JAVA_ATTRS_ALLOCS[4] },
494 { "EnclosingMethod", R_BIN_JAVA_ATTR_TYPE_ENCLOSING_METHOD_ATTR, &RBIN_JAVA_ATTRS_ALLOCS[5] },
495 { "Exceptions", R_BIN_JAVA_ATTR_TYPE_EXCEPTIONS_ATTR, &RBIN_JAVA_ATTRS_ALLOCS[6] },
496 { "InnerClasses", R_BIN_JAVA_ATTR_TYPE_INNER_CLASSES_ATTR, &RBIN_JAVA_ATTRS_ALLOCS[7] },
497 { "LineNumberTable", R_BIN_JAVA_ATTR_TYPE_LINE_NUMBER_TABLE_ATTR, &RBIN_JAVA_ATTRS_ALLOCS[8] },
498 { "LocalVariableTable", R_BIN_JAVA_ATTR_TYPE_LOCAL_VARIABLE_TABLE_ATTR, &RBIN_JAVA_ATTRS_ALLOCS[9] },
499 { "LocalVariableTypeTable", R_BIN_JAVA_ATTR_TYPE_LOCAL_VARIABLE_TYPE_TABLE_ATTR, &RBIN_JAVA_ATTRS_ALLOCS[10] },
500 { "RuntimeInvisibleAnnotations", R_BIN_JAVA_ATTR_TYPE_RUNTIME_INVISIBLE_ANNOTATION_ATTR, &RBIN_JAVA_ATTRS_ALLOCS[11] },
501 { "RuntimeInvisibleParameterAnnotations", R_BIN_JAVA_ATTR_TYPE_RUNTIME_INVISIBLE_PARAMETER_ANNOTATION_ATTR, &RBIN_JAVA_ATTRS_ALLOCS[12] },
502 { "RuntimeVisibleAnnotations", R_BIN_JAVA_ATTR_TYPE_RUNTIME_VISIBLE_ANNOTATION_ATTR, &RBIN_JAVA_ATTRS_ALLOCS[13] },
503 { "RuntimeVisibleParameterAnnotations", R_BIN_JAVA_ATTR_TYPE_RUNTIME_VISIBLE_PARAMETER_ANNOTATION_ATTR, &RBIN_JAVA_ATTRS_ALLOCS[14] },
504 { "Signature", R_BIN_JAVA_ATTR_TYPE_SIGNATURE_ATTR, &RBIN_JAVA_ATTRS_ALLOCS[15] },
505 { "SourceDebugExtension", R_BIN_JAVA_ATTR_TYPE_SOURCE_DEBUG_EXTENTSION_ATTR, &RBIN_JAVA_ATTRS_ALLOCS[16] },
506 { "SourceFile", R_BIN_JAVA_ATTR_TYPE_SOURCE_FILE_ATTR, &RBIN_JAVA_ATTRS_ALLOCS[17] },
507 { "StackMapTable", R_BIN_JAVA_ATTR_TYPE_STACK_MAP_TABLE_ATTR, &RBIN_JAVA_ATTRS_ALLOCS[18] },
508 // { "StackMap", R_BIN_JAVA_ATTR_TYPE_STACK_MAP_TABLE_ATTR, &RBIN_JAVA_ATTRS_ALLOCS[18]},
509 { "Synthetic", R_BIN_JAVA_ATTR_TYPE_SYNTHETIC_ATTR, &RBIN_JAVA_ATTRS_ALLOCS[19] },
510 { "Unknown", R_BIN_JAVA_ATTR_TYPE_UNKNOWN_ATTR, &RBIN_JAVA_ATTRS_ALLOCS[20] }
511 };
512
r_bin_java_is_old_format(RBinJavaObj * bin)513 R_API bool r_bin_java_is_old_format(RBinJavaObj *bin) {
514 return bin->cf.major[1] == 45 && bin->cf.minor[1] <= 2;
515 }
516
r_bin_java_reset_bin_info(RBinJavaObj * bin)517 R_API void r_bin_java_reset_bin_info(RBinJavaObj *bin) {
518 free (bin->cf2.flags_str);
519 free (bin->cf2.this_class_name);
520 r_list_free (bin->imports_list);
521 r_list_free (bin->methods_list);
522 r_list_free (bin->fields_list);
523 r_list_free (bin->attrs_list);
524 r_list_free (bin->cp_list);
525 r_list_free (bin->interfaces_list);
526 r_str_constpool_fini (&bin->constpool);
527 memset (bin, 0, sizeof (RBinJavaObj));
528 r_str_constpool_init (&bin->constpool);
529 bin->cf2.flags_str = strdup ("unknown");
530 bin->cf2.this_class_name = strdup ("unknown");
531 bin->imports_list = r_list_newf (free);
532 bin->methods_list = r_list_newf (r_bin_java_fmtype_free);
533 bin->fields_list = r_list_newf (r_bin_java_fmtype_free);
534 bin->attrs_list = r_list_newf (r_bin_java_attribute_free);
535 bin->cp_list = r_list_newf (r_bin_java_constant_pool);
536 bin->interfaces_list = r_list_newf (r_bin_java_interface_free);
537 }
538
r_bin_java_unmangle_method(const char * flags,const char * name,const char * params,const char * r_value)539 R_API char *r_bin_java_unmangle_method(const char *flags, const char *name, const char *params, const char *r_value) {
540 RList *the_list = params ? r_bin_java_extract_type_values (params) : r_list_new ();
541 RListIter *iter = NULL;
542 // second case removes leading space if no flags are given
543 const char *fmt = flags ? "%s %s %s (%s)" : "%s%s %s (%s)";
544 char *str = NULL, *f_val_str = NULL, *r_val_str = NULL, *prototype = NULL, *p_val_str = NULL;
545 ut32 params_idx = 0, params_len = 0, prototype_len = 0;
546 if (!extract_type_value (r_value, &r_val_str)) {
547 r_list_free (the_list);
548 return NULL;
549 }
550 if (!r_val_str) {
551 r_val_str = strdup ("UNKNOWN");
552 }
553 f_val_str = strdup (r_str_get (flags));
554 r_list_foreach (the_list, iter, str) {
555 params_len += strlen (str);
556 if (params_idx > 0) {
557 params_len += 2;
558 }
559 params_idx++;
560 }
561 if (params_len > 0) {
562 ut32 offset = 0;
563 params_len += 1;
564 p_val_str = malloc (params_len);
565 r_list_foreach (the_list, iter, str) {
566 if (offset != 0) {
567 offset += snprintf (p_val_str + offset, params_len - offset, ", %s", str);
568 } else {
569 offset += snprintf (p_val_str + offset, params_len - offset, "%s", str);
570 }
571 }
572 } else {
573 p_val_str = strdup ("");
574 }
575
576 prototype_len += (flags ? strlen (flags) + 1 : 0); // space vs no space
577 prototype_len += strlen (name) + 1; // name + space
578 prototype_len += strlen (r_val_str) + 1; // r_value + space
579 prototype_len += strlen (p_val_str) + 3; // space + l_paren + params + r_paren
580 prototype_len += 1; // null
581 prototype = malloc (prototype_len);
582 /// TODO enable this function and start using it to demangle strings
583 snprintf (prototype, prototype_len, fmt, f_val_str, r_val_str, name, p_val_str);
584 free (f_val_str);
585 free (r_val_str);
586 free (p_val_str);
587 r_list_free (the_list);
588 return prototype;
589 }
590
r_bin_java_unmangle(const char * flags,const char * name,const char * descriptor)591 R_API char *r_bin_java_unmangle(const char *flags, const char *name, const char *descriptor) {
592 ut32 l_paren_pos = -1, r_paren_pos = -1;
593 char *result = NULL;
594 ut32 desc_len = descriptor && *descriptor ? strlen (descriptor) : 0,
595 name_len = name && *name ? strlen (name) : 0,
596 flags_len = flags && *flags ? strlen (flags) : 0,
597 i = 0;
598 if (desc_len == 0 || name == 0) {
599 return NULL;
600 }
601 for (i = 0; i < desc_len; i++) {
602 if (descriptor[i] == '(') {
603 l_paren_pos = i;
604 } else if (l_paren_pos != (ut32) - 1 && descriptor[i] == ')') {
605 r_paren_pos = i;
606 break;
607 }
608 }
609 // handle field case;
610 if (l_paren_pos == (ut32) - 1 && r_paren_pos == (ut32) - 1) {
611 char *unmangle_field_desc = NULL;
612 ut32 len = extract_type_value (descriptor, &unmangle_field_desc);
613 if (len == 0) {
614 eprintf ("Warning: attempting to unmangle invalid type descriptor.\n");
615 free (unmangle_field_desc);
616 return result;
617 }
618 if (flags_len > 0) {
619 len += (flags_len + name_len + 5); // space and null
620 result = malloc (len);
621 snprintf (result, len, "%s %s %s", flags, unmangle_field_desc, name);
622 } else {
623 len += (name_len + 5); // space and null
624 result = malloc (len);
625 snprintf (result, len, "%s %s", unmangle_field_desc, name);
626 }
627 free (unmangle_field_desc);
628 } else if (l_paren_pos != (ut32) - 1 &&
629 r_paren_pos != (ut32) - 1 &&
630 l_paren_pos < r_paren_pos) {
631 // params_len account for l_paren + 1 and null
632 ut32 params_len = r_paren_pos - (l_paren_pos + 1) != 0 ? r_paren_pos - (l_paren_pos + 1) + 1 : 0;
633 char *params = params_len ? malloc (params_len) : NULL;
634 const char *rvalue = descriptor + r_paren_pos + 1;
635 if (params) {
636 snprintf (params, params_len, "%s", descriptor + l_paren_pos + 1);
637 }
638 result = r_bin_java_unmangle_method (flags, name, params, rvalue);
639 free (params);
640 }
641 return result;
642 }
643
r_bin_java_get_bin_obj_json(RBinJavaObj * bin)644 R_API DsoJsonObj *r_bin_java_get_bin_obj_json(RBinJavaObj *bin) {
645 DsoJsonObj *imports_list = r_bin_java_get_import_json_definitions (bin);
646 DsoJsonObj *fields_list = r_bin_java_get_field_json_definitions (bin);
647 DsoJsonObj *methods_list = r_bin_java_get_method_json_definitions (bin);
648 // interfaces_list = r_bin_java_get_interface_json_definitions (bin);
649 DsoJsonObj *class_dict = r_bin_java_get_class_info_json (bin);
650 char *res = dso_json_obj_to_str (methods_list);
651 // eprintf ("Resulting methods json: \n%s\n", res);
652 free (res);
653 if (dso_json_dict_insert_str_key_obj (class_dict, "methods", methods_list)) {
654 // dso_json_list_free (methods_list);
655 dso_json_obj_del (methods_list);
656 }
657
658 res = dso_json_obj_to_str (fields_list);
659 // eprintf ("Resulting fields json: \n%s\n", res);
660 free (res);
661 if (dso_json_dict_insert_str_key_obj (class_dict, "fields", fields_list)) {
662 // dso_json_list_free (fields_list);
663 dso_json_obj_del (fields_list);
664 }
665
666 res = dso_json_obj_to_str (imports_list);
667 // eprintf ("Resulting imports json: \n%s\n", res);
668 free (res);
669 if (dso_json_dict_insert_str_key_obj (class_dict, "imports", imports_list)) {
670 // dso_json_list_free (imports_list);
671 dso_json_obj_del (imports_list);
672 }
673
674 // res = dso_json_obj_to_str (interfaces_list);
675 // eprintf ("Resulting interfaces json: \n%s\n", res);
676 // free (res);
677 // dso_json_dict_insert_str_key_obj (class_dict, "interfaces", interfaces_list);
678
679 res = dso_json_obj_to_str (class_dict);
680 // eprintf ("Resulting class info json: \n%s\n", res);
681 free (res);
682 // dso_json_obj_del (class_dict);
683 return class_dict;
684 }
685
r_bin_java_get_import_json_definitions(RBinJavaObj * bin)686 R_API DsoJsonObj *r_bin_java_get_import_json_definitions(RBinJavaObj *bin) {
687 RList *the_list;
688 DsoJsonObj *json_list = dso_json_list_new ();
689 RListIter *iter = NULL;
690 char *new_str;
691
692 if (!bin || !(the_list = r_bin_java_get_lib_names (bin))) {
693 return json_list;
694 }
695
696 r_list_foreach (the_list, iter, new_str) {
697 char *tmp = new_str;
698 // eprintf ("Processing string: %s\n", new_str);
699 while (*tmp) {
700 if (*tmp == '/') {
701 *tmp = '.';
702 }
703 tmp++;
704 }
705 // eprintf ("adding string: %s\n", new_str);
706 dso_json_list_append_str (json_list, new_str);
707 }
708 r_list_free (the_list);
709 return json_list;
710 }
711
r_bin_java_get_class_info_json(RBinJavaObj * bin)712 R_API DsoJsonObj *r_bin_java_get_class_info_json(RBinJavaObj *bin) {
713 RList *classes = r_bin_java_get_classes (bin);
714 DsoJsonObj *interfaces_list = dso_json_list_new ();
715 DsoJsonObj *class_info_dict = dso_json_dict_new ();
716 RBinClass *class_ = r_list_get_n (classes, 0);
717
718 if (class_) {
719 int dummy = 0;
720 RListIter *iter;
721 RBinClass *class_v = NULL;
722 // add access flags like in methods
723 bool is_public = ((class_->visibility & R_BIN_JAVA_CLASS_ACC_PUBLIC) != 0);
724 bool is_final = ((class_->visibility & R_BIN_JAVA_CLASS_ACC_FINAL) != 0);
725 bool is_super = ((class_->visibility & R_BIN_JAVA_CLASS_ACC_SUPER) != 0);
726 bool is_interface = ((class_->visibility & R_BIN_JAVA_CLASS_ACC_INTERFACE) != 0);
727 bool is_abstract = ((class_->visibility & R_BIN_JAVA_CLASS_ACC_ABSTRACT) != 0);
728 bool is_synthetic = ((class_->visibility & R_BIN_JAVA_CLASS_ACC_SYNTHETIC) != 0);
729 bool is_annotation = ((class_->visibility & R_BIN_JAVA_CLASS_ACC_ANNOTATION) != 0);
730 bool is_enum = ((class_->visibility & R_BIN_JAVA_CLASS_ACC_ENUM) != 0);
731
732 dso_json_dict_insert_str_key_num (class_info_dict, "access_flags", class_->visibility);
733 dso_json_dict_insert_str_key_num (class_info_dict, "is_public", is_public);
734 dso_json_dict_insert_str_key_num (class_info_dict, "is_final", is_final);
735 dso_json_dict_insert_str_key_num (class_info_dict, "is_super", is_super);
736 dso_json_dict_insert_str_key_num (class_info_dict, "is_interface", is_interface);
737 dso_json_dict_insert_str_key_num (class_info_dict, "is_abstract", is_abstract);
738 dso_json_dict_insert_str_key_num (class_info_dict, "is_synthetic", is_synthetic);
739 dso_json_dict_insert_str_key_num (class_info_dict, "is_annotation", is_annotation);
740 dso_json_dict_insert_str_key_num (class_info_dict, "is_enum", is_enum);
741 dso_json_dict_insert_str_key_str (class_info_dict, "name", class_->name);
742
743 if (!class_->super) {
744 DsoJsonObj *str = dso_json_str_new ();
745 if (dso_json_dict_insert_str_key_obj (class_info_dict, "super", str)) {
746 dso_json_str_free (str);
747 }
748 } else {
749 dso_json_dict_insert_str_key_str (class_info_dict, "super", class_->super);
750 }
751
752 r_list_foreach (classes, iter, class_v) {
753 if (!dummy) {
754 dummy++;
755 continue;
756 }
757 // enumerate all interface classes and append them to the interfaces
758 if ((class_v->visibility & R_BIN_JAVA_CLASS_ACC_INTERFACE) != 0) {
759 dso_json_list_append_str (interfaces_list, class_v->name);
760 }
761 }
762 }
763 if (dso_json_dict_insert_str_key_obj (class_info_dict, "interfaces", interfaces_list)) {
764 // dso_json_list_free (interfaces_list);
765 dso_json_obj_del (interfaces_list);
766 }
767 r_list_free (classes);
768 return class_info_dict;
769 }
770
r_bin_java_get_interface_json_definitions(RBinJavaObj * bin)771 R_API DsoJsonObj *r_bin_java_get_interface_json_definitions(RBinJavaObj *bin) {
772 RList *the_list;
773 DsoJsonObj *json_list = dso_json_list_new ();
774 RListIter *iter = NULL;
775 char *new_str;
776
777 if (!bin || !(the_list = r_bin_java_get_interface_names (bin))) {
778 return json_list;
779 }
780
781 r_list_foreach (the_list, iter, new_str) {
782 char *tmp = new_str;
783 // eprintf ("Processing string: %s\n", new_str);
784 while (*tmp) {
785 if (*tmp == '/') {
786 *tmp = '.';
787 }
788 tmp++;
789 }
790 // eprintf ("adding string: %s\n", new_str);
791 dso_json_list_append_str (json_list, new_str);
792 }
793 r_list_free (the_list);
794 return json_list;
795 }
796
r_bin_java_get_method_json_definitions(RBinJavaObj * bin)797 R_API DsoJsonObj *r_bin_java_get_method_json_definitions(RBinJavaObj *bin) {
798 RBinJavaField *fm_type = NULL;
799 RListIter *iter = NULL;
800 DsoJsonObj *json_list = dso_json_list_new ();
801 if (!bin) {
802 return json_list;
803 }
804 r_list_foreach (bin->methods_list, iter, fm_type) {
805 DsoJsonObj *method_proto = r_bin_java_get_method_json_definition (bin, fm_type);
806 // eprintf ("Method json: %s\n", method_proto);
807 dso_json_list_append (json_list, method_proto);
808 }
809 return json_list;
810 }
811
r_bin_java_get_field_json_definitions(RBinJavaObj * bin)812 R_API DsoJsonObj *r_bin_java_get_field_json_definitions(RBinJavaObj *bin) {
813 RBinJavaField *fm_type = NULL;
814 RListIter *iter = NULL;
815 DsoJsonObj *json_list = dso_json_list_new ();
816 if (!bin) {
817 return json_list;
818 }
819 r_list_foreach (bin->fields_list, iter, fm_type) {
820 DsoJsonObj *field_proto = r_bin_java_get_field_json_definition (bin, fm_type);
821 // eprintf ("Field json: %s\n", field_proto);
822 dso_json_list_append (json_list, field_proto);
823 }
824 return json_list;
825 }
826
r_bin_java_create_method_fq_str(const char * klass,const char * name,const char * signature)827 R_API char *r_bin_java_create_method_fq_str(const char *klass, const char *name, const char *signature) {
828 if (!klass) {
829 klass = "null_class";
830 }
831 if (!name) {
832 name = "null_name";
833 }
834 if (!signature) {
835 signature = "null_signature";
836 }
837 return r_str_newf ("%s.%s.%s", klass, name, signature);
838 }
839
r_bin_java_create_field_fq_str(const char * klass,const char * name,const char * signature)840 R_API char *r_bin_java_create_field_fq_str(const char *klass, const char *name, const char *signature) {
841 if (!klass) {
842 klass = "null_class";
843 }
844 if (!name) {
845 name = "null_name";
846 }
847 if (!signature) {
848 signature = "null_signature";
849 }
850 return r_str_newf ("%s %s.%s", signature, klass, name);
851 }
852
r_bin_java_get_fm_type_definition_json(RBinJavaObj * bin,RBinJavaField * fm_type,int is_method)853 R_API DsoJsonObj *r_bin_java_get_fm_type_definition_json(RBinJavaObj *bin, RBinJavaField *fm_type, int is_method) {
854 ut64 addr = UT64_MAX;
855 char *prototype = NULL, *fq_name = NULL;
856 bool is_native = ((fm_type->flags & R_BIN_JAVA_METHOD_ACC_NATIVE) != 0);
857 bool is_static = ((fm_type->flags & R_BIN_JAVA_METHOD_ACC_STATIC) != 0);
858 bool is_synthetic = ((fm_type->flags & R_BIN_JAVA_METHOD_ACC_SYNTHETIC) != 0);
859 bool is_private = ((fm_type->flags & R_BIN_JAVA_METHOD_ACC_PRIVATE) != 0);
860 bool is_public = ((fm_type->flags & R_BIN_JAVA_METHOD_ACC_PUBLIC) != 0);
861 bool is_protected = ((fm_type->flags & R_BIN_JAVA_METHOD_ACC_PROTECTED) != 0);
862 bool is_super = ((fm_type->flags & R_BIN_JAVA_CLASS_ACC_SUPER) != 0);
863
864 DsoJsonObj *fm_type_dict = dso_json_dict_new ();
865 dso_json_dict_insert_str_key_num (fm_type_dict, "access_flags", fm_type->flags);
866 dso_json_dict_insert_str_key_num (fm_type_dict, "is_method", is_method);
867 dso_json_dict_insert_str_key_num (fm_type_dict, "is_native", is_native);
868 dso_json_dict_insert_str_key_num (fm_type_dict, "is_synthetic", is_synthetic);
869 dso_json_dict_insert_str_key_num (fm_type_dict, "is_private", is_private);
870 dso_json_dict_insert_str_key_num (fm_type_dict, "is_public", is_public);
871 dso_json_dict_insert_str_key_num (fm_type_dict, "is_static", is_static);
872 dso_json_dict_insert_str_key_num (fm_type_dict, "is_protected", is_protected);
873 dso_json_dict_insert_str_key_num (fm_type_dict, "is_super", is_super);
874
875 addr = r_bin_java_get_method_code_offset (fm_type);
876 if (addr == 0) {
877 addr = fm_type->file_offset;
878 }
879 addr += bin->loadaddr;
880
881 dso_json_dict_insert_str_key_num (fm_type_dict, "addr", addr);
882 dso_json_dict_insert_str_key_num (fm_type_dict, "offset", fm_type->file_offset + bin->loadaddr);
883 dso_json_dict_insert_str_key_str (fm_type_dict, "class_name", fm_type->class_name);
884 dso_json_dict_insert_str_key_str (fm_type_dict, "signature", fm_type->descriptor);
885 dso_json_dict_insert_str_key_str (fm_type_dict, "name", fm_type->name);
886
887 if (is_method) {
888 fq_name = r_bin_java_create_method_fq_str (fm_type->class_name, fm_type->name, fm_type->descriptor);
889 } else {
890 fq_name = r_bin_java_create_field_fq_str (fm_type->class_name, fm_type->name, fm_type->descriptor);
891 }
892 dso_json_dict_insert_str_key_str (fm_type_dict, "fq_name", fq_name);
893
894 prototype = r_bin_java_unmangle (fm_type->flags_str, fm_type->name, fm_type->descriptor);
895 dso_json_dict_insert_str_key_str (fm_type_dict, "prototype", prototype);
896 free (prototype);
897 free (fq_name);
898 return fm_type_dict;
899 }
900
r_bin_java_get_method_definition(RBinJavaField * fm_type)901 R_API char *r_bin_java_get_method_definition(RBinJavaField *fm_type) {
902 return r_bin_java_unmangle (fm_type->flags_str, fm_type->name, fm_type->descriptor);
903 }
904
r_bin_java_get_field_definition(RBinJavaField * fm_type)905 R_API char *r_bin_java_get_field_definition(RBinJavaField *fm_type) {
906 return r_bin_java_unmangle (fm_type->flags_str, fm_type->name, fm_type->descriptor);
907 }
908
r_bin_java_get_method_json_definition(RBinJavaObj * bin,RBinJavaField * fm_type)909 R_API DsoJsonObj *r_bin_java_get_method_json_definition(RBinJavaObj *bin, RBinJavaField *fm_type) {
910 return r_bin_java_get_fm_type_definition_json (bin, fm_type, 1);
911 }
912
r_bin_java_get_field_json_definition(RBinJavaObj * bin,RBinJavaField * fm_type)913 R_API DsoJsonObj *r_bin_java_get_field_json_definition(RBinJavaObj *bin, RBinJavaField *fm_type) {
914 return r_bin_java_get_fm_type_definition_json (bin, fm_type, 0);
915 }
916
r_bin_java_extract_reference_name(const char * input_str,char ** ref_str,ut8 array_cnt)917 R_API int r_bin_java_extract_reference_name(const char *input_str, char **ref_str, ut8 array_cnt) {
918 char *new_str = NULL;
919 ut32 str_len = array_cnt ? (array_cnt + 1) * 2 : 0;
920 const char *str_pos = input_str;
921 int consumed = 0, len = 0;
922 if (!str_pos || *str_pos != 'L' || !*str_pos) {
923 return -1;
924 }
925 consumed++;
926 str_pos++;
927 while (*str_pos && *str_pos != ';') {
928 str_pos++;
929 len++;
930 consumed++;
931 }
932 str_pos = input_str + 1;
933 free (*ref_str);
934 str_len += len;
935 *ref_str = malloc (str_len + 1);
936 new_str = *ref_str;
937 memcpy (new_str, str_pos, str_len);
938 new_str[str_len] = 0;
939 while (*new_str) {
940 if (*new_str == '/') {
941 *new_str = '.';
942 }
943 new_str++;
944 }
945 return len + 2;
946 }
947
UNUSED_FUNCTION(r_bin_java_print_prototypes)948 R_API void UNUSED_FUNCTION(r_bin_java_print_prototypes)(RBinJavaObj * bin) {
949 RList *the_list = r_bin_java_get_method_definitions (bin);
950 RListIter *iter;
951 char *str;
952 r_list_foreach (the_list, iter, str) {
953 eprintf ("%s;\n", str);
954 }
955 r_list_free (the_list);
956 }
957
get_type_value_str(const char * arg_str,ut8 array_cnt)958 R_API char *get_type_value_str(const char *arg_str, ut8 array_cnt) {
959 ut32 str_len = array_cnt ? (array_cnt + 1) * 2 + strlen (arg_str) : strlen (arg_str);
960 char *str = malloc (str_len + 1);
961 ut32 bytes_written = snprintf (str, str_len + 1, "%s", arg_str);
962 while (array_cnt > 0) {
963 strcpy (str + bytes_written, "[]");
964 bytes_written += 2;
965 array_cnt--;
966 }
967 return str;
968 }
969
extract_type_value(const char * arg_str,char ** output)970 R_API int extract_type_value(const char *arg_str, char **output) {
971 ut8 found_one = 0, array_cnt = 0;
972 ut32 len = 0, consumed = 0;
973 char *str = NULL;
974 if (!arg_str || !output) {
975 return 0;
976 }
977 if (output && *output && *output != NULL) {
978 R_FREE (*output);
979 }
980 while (arg_str && *arg_str && !found_one) {
981 len = 1;
982 // handle the end of an object
983 switch (*arg_str) {
984 case 'V':
985 str = get_type_value_str ("void", array_cnt);
986 break;
987 case 'J':
988 str = get_type_value_str ("long", array_cnt);
989 array_cnt = 0;
990 break;
991 case 'I':
992 str = get_type_value_str ("int", array_cnt);
993 array_cnt = 0;
994 break;
995 case 'D':
996 str = get_type_value_str ("double", array_cnt);
997 array_cnt = 0;
998 break;
999 case 'F':
1000 str = get_type_value_str ("float", array_cnt);
1001 array_cnt = 0;
1002 break;
1003 case 'B':
1004 str = get_type_value_str ("byte", array_cnt);
1005 array_cnt = 0;
1006 break;
1007 case 'C':
1008 str = get_type_value_str ("char", array_cnt);
1009 array_cnt = 0;
1010 break;
1011 case 'Z':
1012 str = get_type_value_str ("boolean", array_cnt);
1013 array_cnt = 0;
1014 break;
1015 case 'S':
1016 str = get_type_value_str ("short", array_cnt);
1017 array_cnt = 0;
1018 break;
1019 case '[':
1020 array_cnt++;
1021 break;
1022 case 'L':
1023 len = r_bin_java_extract_reference_name (arg_str, &str, array_cnt);
1024 array_cnt = 0;
1025 break;
1026 case '(':
1027 str = strdup ("(");
1028 break;
1029 case ')':
1030 str = strdup (")");
1031 break;
1032 default:
1033 return 0;
1034 }
1035 if (len < 1) {
1036 break;
1037 }
1038 consumed += len;
1039 arg_str += len;
1040 if (str) {
1041 *output = str;
1042 break;
1043 }
1044 }
1045 return consumed;
1046 }
1047
r_bin_java_extract_type_values(const char * arg_str)1048 R_API RList *r_bin_java_extract_type_values(const char *arg_str) {
1049 RList *list_args = r_list_new ();
1050 if (!list_args) {
1051 return NULL;
1052 }
1053 char *str = NULL;
1054 const char *str_cur_pos = NULL;
1055 ut32 len = 0;
1056 if (!arg_str) {
1057 return list_args;
1058 }
1059 str_cur_pos = arg_str;
1060 list_args->free = free;
1061 while (str_cur_pos && *str_cur_pos) {
1062 // handle the end of an object
1063 len = extract_type_value (str_cur_pos, &str);
1064 if (len < 1) {
1065 r_list_free (list_args);
1066 return NULL;
1067 }
1068 str_cur_pos += len;
1069 r_list_append (list_args, str);
1070 str = NULL;
1071 }
1072 return list_args;
1073 }
1074
r_bin_java_is_fm_type_private(RBinJavaField * fm_type)1075 R_API int r_bin_java_is_fm_type_private(RBinJavaField *fm_type) {
1076 if (fm_type && fm_type->type == R_BIN_JAVA_FIELD_TYPE_METHOD) {
1077 return fm_type->flags & R_BIN_JAVA_METHOD_ACC_PRIVATE;
1078 }
1079 if (fm_type && fm_type->type == R_BIN_JAVA_FIELD_TYPE_FIELD) {
1080 return fm_type->flags & R_BIN_JAVA_FIELD_ACC_PRIVATE;
1081 }
1082 return 0;
1083 }
1084
r_bin_java_is_fm_type_protected(RBinJavaField * fm_type)1085 R_API int r_bin_java_is_fm_type_protected(RBinJavaField *fm_type) {
1086 if (fm_type && fm_type->type == R_BIN_JAVA_FIELD_TYPE_METHOD) {
1087 return fm_type->flags & R_BIN_JAVA_METHOD_ACC_PROTECTED;
1088 }
1089 if (fm_type && fm_type->type == R_BIN_JAVA_FIELD_TYPE_FIELD) {
1090 return fm_type->flags & R_BIN_JAVA_FIELD_ACC_PROTECTED;
1091 }
1092 return 0;
1093 }
1094
r_bin_java_get_args(RBinJavaField * fm_type)1095 R_API RList *r_bin_java_get_args(RBinJavaField *fm_type) {
1096 RList *the_list = r_bin_java_extract_type_values (fm_type->descriptor);
1097 RList *arg_list = r_list_new ();
1098 ut8 in_args = 0;
1099 RListIter *desc_iter;
1100 char *str;
1101 r_list_foreach (the_list, desc_iter, str) {
1102 if (str && *str == '(') {
1103 in_args = 1;
1104 continue;
1105 }
1106 if (str && *str == ')') {
1107 break;
1108 }
1109 if (in_args && str) {
1110 r_list_append (arg_list, strdup (str));
1111 }
1112 }
1113 r_list_free (the_list);
1114 return arg_list;
1115 }
1116
r_bin_java_get_ret(RBinJavaField * fm_type)1117 R_API RList *r_bin_java_get_ret(RBinJavaField *fm_type) {
1118 RList *the_list = r_bin_java_extract_type_values (fm_type->descriptor);
1119 RList *ret_list = r_list_new ();
1120 ut8 in_ret = 0;
1121 RListIter *desc_iter;
1122 char *str;
1123 r_list_foreach (the_list, desc_iter, str) {
1124 if (str && *str != ')') {
1125 in_ret = 0;
1126 }
1127 if (in_ret) {
1128 r_list_append (ret_list, strdup (str));
1129 }
1130 }
1131 r_list_free (the_list);
1132 return ret_list;
1133 }
1134
r_bin_java_get_this_class_name(RBinJavaObj * bin)1135 R_API char *r_bin_java_get_this_class_name(RBinJavaObj *bin) {
1136 return (bin->cf2.this_class_name ? strdup (bin->cf2.this_class_name) : strdup ("unknown"));
1137 }
1138
calculate_access_value(const char * access_flags_str,RBinJavaAccessFlags * access_flags)1139 R_API ut16 calculate_access_value(const char *access_flags_str, RBinJavaAccessFlags *access_flags) {
1140 ut16 result = 0;
1141 ut16 size = strlen (access_flags_str) + 1;
1142 char *p_flags, *my_flags = malloc (size);
1143 RBinJavaAccessFlags *iter = NULL;
1144 if (size < 5 || !my_flags) {
1145 free (my_flags);
1146 return result;
1147 }
1148 memcpy (my_flags, access_flags_str, size);
1149 p_flags = strtok (my_flags, " ");
1150 while (p_flags && access_flags) {
1151 int idx = 0;
1152 do {
1153 iter = &access_flags[idx];
1154 if (!iter || !iter->str) {
1155 continue;
1156 }
1157 if (iter->len > 0 && iter->len != 16) {
1158 if (!strncmp (iter->str, p_flags, iter->len)) {
1159 result |= iter->value;
1160 }
1161 }
1162 idx++;
1163 } while (access_flags[idx].str != NULL);
1164 p_flags = strtok (NULL, " ");
1165 }
1166 free (my_flags);
1167 return result;
1168 }
1169
retrieve_all_access_string_and_value(RBinJavaAccessFlags * access_flags)1170 R_API RList *retrieve_all_access_string_and_value(RBinJavaAccessFlags *access_flags) {
1171 const char *fmt = "%s = 0x%04x";
1172 RList *result = r_list_new ();
1173 if (!result) {
1174 return NULL;
1175 }
1176 result->free = free;
1177 int i = 0;
1178 for (i = 0; access_flags[i].str != NULL; i++) {
1179 char *str = malloc (50);
1180 if (!str) {
1181 r_list_free (result);
1182 return NULL;
1183 }
1184 snprintf (str, 49, fmt, access_flags[i].str, access_flags[i].value);
1185 r_list_append (result, str);
1186 }
1187 return result;
1188 }
1189
retrieve_access_string(ut16 flags,RBinJavaAccessFlags * access_flags)1190 R_API char *retrieve_access_string(ut16 flags, RBinJavaAccessFlags *access_flags) {
1191 char *outbuffer = NULL, *cur_pos = NULL;
1192 ut16 i;
1193 ut16 max_str_len = 0;
1194 for (i = 0; access_flags[i].str != NULL; i++) {
1195 if (flags & access_flags[i].value) {
1196 max_str_len += (strlen (access_flags[i].str) + 1);
1197 if (max_str_len < strlen (access_flags[i].str)) {
1198 return NULL;
1199 }
1200 }
1201 }
1202 max_str_len++;
1203 outbuffer = (char *) malloc (max_str_len);
1204 if (outbuffer) {
1205 memset (outbuffer, 0, max_str_len);
1206 cur_pos = outbuffer;
1207 for (i = 0; access_flags[i].str != NULL; i++) {
1208 if (flags & access_flags[i].value) {
1209 ut8 len = strlen (access_flags[i].str);
1210 const char *the_string = access_flags[i].str;
1211 memcpy (cur_pos, the_string, len);
1212 memcpy (cur_pos + len, " ", 1);
1213 cur_pos += len + 1;
1214 }
1215 }
1216 if (cur_pos != outbuffer) {
1217 *(cur_pos - 1) = 0;
1218 }
1219 }
1220 return outbuffer;
1221 }
1222
retrieve_method_access_string(ut16 flags)1223 R_API char *retrieve_method_access_string(ut16 flags) {
1224 return retrieve_access_string (flags, METHOD_ACCESS_FLAGS);
1225 }
1226
retrieve_field_access_string(ut16 flags)1227 R_API char *retrieve_field_access_string(ut16 flags) {
1228 return retrieve_access_string (flags, FIELD_ACCESS_FLAGS);
1229 }
1230
retrieve_class_method_access_string(ut16 flags)1231 R_API char *retrieve_class_method_access_string(ut16 flags) {
1232 return retrieve_access_string (flags, CLASS_ACCESS_FLAGS);
1233 }
1234
r_bin_java_build_obj_key(RBinJavaObj * bin)1235 R_API char *r_bin_java_build_obj_key(RBinJavaObj *bin) {
1236 char *jvcname = NULL;
1237 char *cname = r_bin_java_get_this_class_name (bin);
1238 ut32 class_name_len = cname ? strlen (cname) : strlen ("_unknown_");
1239 jvcname = malloc (class_name_len + 8 + 30);
1240 if (cname) {
1241 snprintf (jvcname, class_name_len + 30, "%d.%s.class", bin->id, cname);
1242 free (cname);
1243 } else {
1244 snprintf (jvcname, class_name_len + 30, "%d._unknown_.class", bin->id);
1245 }
1246 return jvcname;
1247 }
1248
sdb_iterate_build_list(void * user,const char * k,const char * v)1249 R_API bool sdb_iterate_build_list(void *user, const char *k, const char *v) {
1250 RList *bin_objs_list = (RList *) user;
1251 size_t value = (size_t) sdb_atoi (v);
1252 RBinJavaObj *bin_obj = NULL;
1253 IFDBG eprintf("Found %s == %"PFMT64x " bin_objs db\n", k, (ut64) value);
1254 if (value != 0 && value != (size_t) -1) {
1255 bin_obj = (RBinJavaObj *) value;
1256 r_list_append (bin_objs_list, bin_obj);
1257 }
1258 return true;
1259 }
1260
r_bin_java_get_java_null_cp(void)1261 R_API RBinJavaCPTypeObj *r_bin_java_get_java_null_cp(void) {
1262 if (R_BIN_JAVA_NULL_TYPE_INITTED) {
1263 return &R_BIN_JAVA_NULL_TYPE;
1264 }
1265 memset (&R_BIN_JAVA_NULL_TYPE, 0, sizeof (R_BIN_JAVA_NULL_TYPE));
1266 R_BIN_JAVA_NULL_TYPE.metas = R_NEW0 (RBinJavaMetaInfo);
1267 if (!R_BIN_JAVA_NULL_TYPE.metas) {
1268 return NULL;
1269 }
1270 memset (R_BIN_JAVA_NULL_TYPE.metas, 0, sizeof (RBinJavaMetaInfo));
1271 R_BIN_JAVA_NULL_TYPE.metas->type_info = &R_BIN_JAVA_CP_METAS[0];
1272 R_BIN_JAVA_NULL_TYPE.metas->ord = 0;
1273 R_BIN_JAVA_NULL_TYPE.file_offset = 0;
1274 R_BIN_JAVA_NULL_TYPE_INITTED = true;
1275 return &R_BIN_JAVA_NULL_TYPE;
1276 }
1277
r_bin_java_get_ev_meta_from_tag(ut8 tag)1278 R_API RBinJavaElementValueMetas *r_bin_java_get_ev_meta_from_tag(ut8 tag) {
1279 ut16 i = 0;
1280 RBinJavaElementValueMetas *res = &R_BIN_JAVA_ELEMENT_VALUE_METAS[13];
1281 for (i = 0; i < R_BIN_JAVA_ELEMENT_VALUE_METAS_SZ; i++) {
1282 if (tag == R_BIN_JAVA_ELEMENT_VALUE_METAS[i].tag) {
1283 res = &R_BIN_JAVA_ELEMENT_VALUE_METAS[i];
1284 break;
1285 }
1286 }
1287 return res;
1288 }
1289
r_bin_java_quick_check(ut8 expected_tag,ut8 actual_tag,ut32 actual_len,const char * name)1290 R_API ut8 r_bin_java_quick_check(ut8 expected_tag, ut8 actual_tag, ut32 actual_len, const char *name) {
1291 ut8 res = 0;
1292 if (expected_tag > R_BIN_JAVA_CP_METAS_SZ) {
1293 eprintf ("Invalid tag '%d' expected 0x%02x for %s.\n", actual_tag, expected_tag, name);
1294 res = 1;
1295 } else if (expected_tag != actual_tag) {
1296 eprintf ("Invalid tag '%d' expected 0x%02x for %s.\n", actual_tag, expected_tag, name);
1297 res = 1;
1298 } else if (actual_len < R_BIN_JAVA_CP_METAS[expected_tag].len) {
1299 eprintf ("Unable to parse '%d' expected sz=0x%02x got 0x%02x for %s.\n",
1300 actual_tag, R_BIN_JAVA_CP_METAS[expected_tag].len, actual_len, name);
1301 res = 2;
1302 }
1303 return res;
1304 }
1305
r_bin_java_raw_to_long(const ut8 * raw,ut64 offset)1306 R_API ut64 r_bin_java_raw_to_long(const ut8 *raw, ut64 offset) {
1307 return R_BIN_JAVA_LONG (raw, offset);
1308 }
1309 // yanked from careercup, because i am lazy:
1310 // 1) dont want to figure out how make radare use math library
1311 // 2) dont feel like figuring it out when google does it in O(1).
my_pow(ut64 base,int exp)1312 R_API double my_pow(ut64 base, int exp) {
1313 ut8 flag = 0;
1314 ut64 res = 1;
1315 if (exp < 0) {
1316 flag = 1;
1317 exp *= -1;
1318 }
1319 while (exp) {
1320 if (exp & 1) {
1321 res *= base;
1322 }
1323 exp >>= 1;
1324 base *= base;
1325 IFDBG eprintf("Result: %"PFMT64d ", base: %"PFMT64d ", exp: %d\n", res, base, exp);
1326 }
1327 if (flag == 0) {
1328 return 1.0 * res;
1329 }
1330 return (1.0 / res);
1331 }
1332
r_bin_java_raw_to_double(const ut8 * raw,ut64 offset)1333 R_API double r_bin_java_raw_to_double(const ut8 *raw, ut64 offset) {
1334 ut64 bits = R_BIN_JAVA_LONG (raw, offset);
1335 int s = ((bits >> 63) == 0) ? 1 : -1;
1336 int e = (int) ((bits >> 52) & 0x7ffL);
1337 long m = (e == 0) ?
1338 (bits & 0xfffffffffffffLL) << 1 :
1339 (bits & 0xfffffffffffffLL) | 0x10000000000000LL;
1340 double res = 0.0;
1341 IFDBG eprintf("Convert Long to Double: %08"PFMT64x "\n", bits);
1342 if (bits == 0x7ff0000000000000LL) {
1343 return INFINITY;
1344 }
1345 if (bits == 0xfff0000000000000LL) {
1346 return -INFINITY;
1347 }
1348 if (0x7ff0000000000001LL <= bits && bits <= 0x7fffffffffffffffLL) {
1349 return NAN;
1350 }
1351 if (0xfff0000000000001LL <= bits && bits <= 0xffffffffffffffffLL) {
1352 return NAN;
1353 }
1354 res = s * m * my_pow (2, e - 1075);// XXXX TODO Get double to work correctly here
1355 IFDBG eprintf(" High-bytes = %02x %02x %02x %02x\n", raw[0], raw[1], raw[2], raw[3]);
1356 IFDBG eprintf(" Low-bytes = %02x %02x %02x %02x\n", raw[4], raw[5], raw[6], raw[7]);
1357 IFDBG eprintf("Convert Long to Double s: %d, m: 0x%08lx, e: 0x%08x, res: %f\n", s, m, e, res);
1358 return res;
1359 }
1360
r_bin_java_read_next_method(RBinJavaObj * bin,const ut64 offset,const ut8 * buf,const ut64 len)1361 R_API RBinJavaField *r_bin_java_read_next_method(RBinJavaObj *bin, const ut64 offset, const ut8 *buf, const ut64 len) {
1362 ut32 i, idx;
1363 const ut8 *f_buf = buf + offset;
1364 ut64 adv = 0;
1365 RBinJavaCPTypeObj *item = NULL;
1366 if (!bin || offset + 8 >= len) {
1367 return NULL;
1368 }
1369 RBinJavaField *method = (RBinJavaField *) R_NEW0 (RBinJavaField);
1370 if (!method) {
1371 eprintf ("Unable to allocate memory for method information\n");
1372 return NULL;
1373 }
1374 method->metas = (RBinJavaMetaInfo *) R_NEW0 (RBinJavaMetaInfo);
1375 if (!method->metas) {
1376 eprintf ("Unable to allocate memory for meta information\n");
1377 free (method);
1378 return NULL;
1379 }
1380 method->file_offset = offset;
1381 method->flags = R_BIN_JAVA_USHORT (f_buf, 0);
1382 method->flags_str = retrieve_method_access_string (method->flags);
1383 // need to subtract 1 for the idx
1384 method->name_idx = R_BIN_JAVA_USHORT (f_buf, 2);
1385 method->descriptor_idx = R_BIN_JAVA_USHORT (f_buf, 4);
1386 method->attr_count = R_BIN_JAVA_USHORT (f_buf, 6);
1387 method->attributes = r_list_newf (r_bin_java_attribute_free);
1388 method->type = R_BIN_JAVA_FIELD_TYPE_METHOD;
1389 method->metas->ord = bin->method_idx;
1390 adv += 8;
1391 idx = method->name_idx;
1392 item = r_bin_java_get_item_from_bin_cp_list (bin, idx);
1393 method->name = r_bin_java_get_utf8_from_bin_cp_list (bin, (ut32) (method->name_idx));
1394 IFDBG eprintf("Method name_idx: %d, which is: ord: %d, name: %s, value: %s\n", idx, item->metas->ord, ((RBinJavaCPTypeMetas *)item->metas->type_info)->name, method->name);
1395 if (!method->name) {
1396 method->name = (char *) malloc (21);
1397 snprintf ((char *) method->name, 20, "sym.method_%08x", method->metas->ord);
1398 IFDBG eprintf("r_bin_java_read_next_method: Unable to find the name for 0x%02x index.\n", method->name_idx);
1399 }
1400 idx = method->descriptor_idx;
1401 item = r_bin_java_get_item_from_bin_cp_list (bin, idx);
1402 method->descriptor = r_bin_java_get_utf8_from_bin_cp_list (bin, (ut32) method->descriptor_idx);
1403 IFDBG eprintf("Method descriptor_idx: %d, which is: ord: %d, name: %s, value: %s\n", idx, item->metas->ord, ((RBinJavaCPTypeMetas *)item->metas->type_info)->name, method->descriptor);
1404 if (!method->descriptor) {
1405 method->descriptor = r_str_dup (NULL, "NULL");
1406 IFDBG eprintf("r_bin_java_read_next_method: Unable to find the descriptor for 0x%02x index.\n", method->descriptor_idx);
1407 }
1408 IFDBG eprintf("Looking for a NameAndType CP with name_idx: %d descriptor_idx: %d\n", method->name_idx, method->descriptor_idx);
1409 method->field_ref_cp_obj = r_bin_java_find_cp_ref_info_from_name_and_type (bin, method->name_idx, method->descriptor_idx);
1410 if (method->field_ref_cp_obj) {
1411 IFDBG eprintf("Found the obj.\n");
1412 item = r_bin_java_get_item_from_bin_cp_list (bin, method->field_ref_cp_obj->info.cp_method.class_idx);
1413 IFDBG eprintf("Method class reference value: %d, which is: ord: %d, name: %s\n", method->field_ref_cp_obj->info.cp_method.class_idx, item->metas->ord, ((RBinJavaCPTypeMetas *)item->metas->type_info)->name);
1414 method->class_name = r_bin_java_get_item_name_from_bin_cp_list (bin, item);
1415 IFDBG eprintf("Method requesting ref_cp_obj the following which is: ord: %d, name: %s\n", method->field_ref_cp_obj->metas->ord, ((RBinJavaCPTypeMetas *)method->field_ref_cp_obj->metas->type_info)->name);
1416 IFDBG eprintf("MethodRef class name resolves to: %s\n", method->class_name);
1417 if (!method->class_name) {
1418 method->class_name = r_str_dup (NULL, "NULL");
1419 }
1420 } else {
1421 // XXX - default to this class?
1422 method->field_ref_cp_obj = r_bin_java_get_item_from_bin_cp_list (bin, bin->cf2.this_class);
1423 method->class_name = r_bin_java_get_item_name_from_bin_cp_list (bin, method->field_ref_cp_obj);
1424 }
1425 IFDBG eprintf("Parsing %s(%s)\n", method->name, method->descriptor);
1426 if (method->attr_count > 0) {
1427 method->attr_offset = adv + offset;
1428 RBinJavaAttrInfo *attr = NULL;
1429 for (i = 0; i < method->attr_count; i++) {
1430 attr = r_bin_java_read_next_attr (bin, adv + offset, buf, len);
1431 if (!attr) {
1432 eprintf ("[X] r_bin_java: Error unable to parse remainder of classfile after Method Attribute: %d.\n", i);
1433 break;
1434 }
1435 if ((r_bin_java_get_attr_type_by_name (attr->name))->type == R_BIN_JAVA_ATTR_TYPE_CODE_ATTR) {
1436 // This is necessary for determing the appropriate number of bytes when readin
1437 // uoffset, ustack, ulocalvar values
1438 bin->cur_method_code_length = attr->info.code_attr.code_length;
1439 bin->offset_sz = 2;// (attr->info.code_attr.code_length > 65535) ? 4 : 2;
1440 bin->ustack_sz = 2;// (attr->info.code_attr.max_stack > 65535) ? 4 : 2;
1441 bin->ulocalvar_sz = 2;// (attr->info.code_attr.max_locals > 65535) ? 4 : 2;
1442 }
1443 IFDBG eprintf("Parsing @ 0x%"PFMT64x " (%s) = 0x%"PFMT64x " bytes\n", attr->file_offset, attr->name, attr->size);
1444 r_list_append (method->attributes, attr);
1445 adv += attr->size;
1446 if (adv + offset >= len) {
1447 eprintf ("[X] r_bin_java: Error unable to parse remainder of classfile after Method Attribute: %d.\n", i);
1448 break;
1449 }
1450 }
1451 }
1452 method->size = adv;
1453 // reset after parsing the method attributes
1454 IFDBG eprintf("Parsing @ 0x%"PFMT64x " %s(%s) = 0x%"PFMT64x " bytes\n", method->file_offset, method->name, method->descriptor, method->size);
1455 return method;
1456 }
1457
r_bin_java_read_next_field(RBinJavaObj * bin,const ut64 offset,const ut8 * buffer,const ut64 len)1458 R_API RBinJavaField *r_bin_java_read_next_field(RBinJavaObj *bin, const ut64 offset, const ut8 *buffer, const ut64 len) {
1459 RBinJavaAttrInfo *attr;
1460 ut32 i, idx;
1461 ut8 buf[8];
1462 RBinJavaCPTypeObj *item = NULL;
1463 const ut8 *f_buf = buffer + offset;
1464 ut64 adv = 0;
1465 if (!bin || offset + 8 >= len) {
1466 return NULL;
1467 }
1468 RBinJavaField *field = (RBinJavaField *) R_NEW0 (RBinJavaField);
1469 if (!field) {
1470 eprintf ("Unable to allocate memory for field information\n");
1471 return NULL;
1472 }
1473 field->metas = (RBinJavaMetaInfo *) R_NEW0 (RBinJavaMetaInfo);
1474 if (!field->metas) {
1475 eprintf ("Unable to allocate memory for meta information\n");
1476 free (field);
1477 return NULL;
1478 }
1479 memcpy (buf, f_buf, 8);
1480 field->file_offset = offset;
1481 field->flags = R_BIN_JAVA_USHORT (buf, 0);
1482 field->flags_str = retrieve_field_access_string (field->flags);
1483 field->name_idx = R_BIN_JAVA_USHORT (buf, 2);
1484 field->descriptor_idx = R_BIN_JAVA_USHORT (buf, 4);
1485 field->attr_count = R_BIN_JAVA_USHORT (buf, 6);
1486 field->attributes = r_list_newf (r_bin_java_attribute_free);
1487 field->type = R_BIN_JAVA_FIELD_TYPE_FIELD;
1488 adv += 8;
1489 field->metas->ord = bin->field_idx;
1490
1491 idx = field->name_idx;
1492 item = r_bin_java_get_item_from_bin_cp_list (bin, idx);
1493 field->name = r_bin_java_get_utf8_from_bin_cp_list (bin, (ut32) (field->name_idx));
1494 IFDBG eprintf("Field name_idx: %d, which is: ord: %d, name: %s, value: %s\n", idx, item->metas->ord, ((RBinJavaCPTypeMetas *)item->metas->type_info)->name, field->name);
1495 if (!field->name) {
1496 field->name = (char *) malloc (21);
1497 snprintf ((char *) field->name, 20, "sym.field_%08x", field->metas->ord);
1498 IFDBG eprintf("r_bin_java_read_next_field: Unable to find the name for 0x%02x index.\n", field->name_idx);
1499 }
1500 idx = field->descriptor_idx;
1501 item = r_bin_java_get_item_from_bin_cp_list (bin, idx);
1502 field->descriptor = r_bin_java_get_utf8_from_bin_cp_list (bin, (ut32) field->descriptor_idx);
1503 IFDBG eprintf("Field descriptor_idx: %d, which is: ord: %d, name: %s, value: %s\n", idx, item->metas->ord, ((RBinJavaCPTypeMetas *)item->metas->type_info)->name, field->descriptor);
1504 if (!field->descriptor) {
1505 field->descriptor = r_str_dup (NULL, "NULL");
1506 IFDBG eprintf("r_bin_java_read_next_field: Unable to find the descriptor for 0x%02x index.\n", field->descriptor_idx);
1507 }
1508 IFDBG eprintf("Looking for a NameAndType CP with name_idx: %d descriptor_idx: %d\n", field->name_idx, field->descriptor_idx);
1509 field->field_ref_cp_obj = r_bin_java_find_cp_ref_info_from_name_and_type (bin, field->name_idx, field->descriptor_idx);
1510 if (field->field_ref_cp_obj) {
1511 IFDBG eprintf("Found the obj.\n");
1512 item = r_bin_java_get_item_from_bin_cp_list (bin, field->field_ref_cp_obj->info.cp_field.class_idx);
1513 IFDBG eprintf("Field class reference value: %d, which is: ord: %d, name: %s\n", field->field_ref_cp_obj->info.cp_field.class_idx, item->metas->ord, ((RBinJavaCPTypeMetas *)item->metas->type_info)->name);
1514 field->class_name = r_bin_java_get_item_name_from_bin_cp_list (bin, item);
1515 IFDBG eprintf("Field requesting ref_cp_obj the following which is: ord: %d, name: %s\n", field->field_ref_cp_obj->metas->ord, ((RBinJavaCPTypeMetas *)field->field_ref_cp_obj->metas->type_info)->name);
1516 IFDBG eprintf("FieldRef class name resolves to: %s\n", field->class_name);
1517 if (!field->class_name) {
1518 field->class_name = r_str_dup (NULL, "NULL");
1519 }
1520 } else {
1521 // XXX - default to this class?
1522 field->field_ref_cp_obj = r_bin_java_get_item_from_bin_cp_list (bin, bin->cf2.this_class);
1523 field->class_name = r_bin_java_get_item_name_from_bin_cp_list (bin, field->field_ref_cp_obj);
1524 }
1525 IFDBG eprintf("Parsing %s(%s)", field->name, field->descriptor);
1526 if (field->attr_count > 0) {
1527 field->attr_offset = adv + offset;
1528 for (i = 0; i < field->attr_count && offset + adv < len; i++) {
1529 attr = r_bin_java_read_next_attr (bin, offset + adv, buffer, len);
1530 if (!attr) {
1531 eprintf ("[X] r_bin_java: Error unable to parse remainder of classfile after Field Attribute: %d.\n", i);
1532 free (field->metas);
1533 free (field);
1534 return NULL;
1535 }
1536 if ((r_bin_java_get_attr_type_by_name (attr->name))->type == R_BIN_JAVA_ATTR_TYPE_CODE_ATTR) {
1537 // This is necessary for determing the appropriate number of bytes when readin
1538 // uoffset, ustack, ulocalvar values
1539 bin->cur_method_code_length = attr->info.code_attr.code_length;
1540 bin->offset_sz = 2;// (attr->info.code_attr.code_length > 65535) ? 4 : 2;
1541 bin->ustack_sz = 2;// (attr->info.code_attr.max_stack > 65535) ? 4 : 2;
1542 bin->ulocalvar_sz = 2;// (attr->info.code_attr.max_locals > 65535) ? 4 : 2;
1543 }
1544 r_list_append (field->attributes, attr);
1545 adv += attr->size;
1546 if (adv + offset >= len) {
1547 eprintf ("[X] r_bin_java: Error unable to parse remainder of classfile after Field Attribute: %d.\n", i);
1548 r_bin_java_fmtype_free (field);
1549 return NULL;
1550 }
1551 }
1552 }
1553 field->size = adv;
1554 return field;
1555 }
1556
r_bin_java_clone_cp_idx(RBinJavaObj * bin,ut32 idx)1557 R_API RBinJavaCPTypeObj *r_bin_java_clone_cp_idx(RBinJavaObj *bin, ut32 idx) {
1558 RBinJavaCPTypeObj *obj = NULL;
1559 if (bin) {
1560 obj = r_bin_java_get_item_from_bin_cp_list (bin, idx);
1561 }
1562 return r_bin_java_clone_cp_item (obj);
1563 }
1564
r_bin_java_clone_cp_item(RBinJavaCPTypeObj * obj)1565 R_API RBinJavaCPTypeObj *r_bin_java_clone_cp_item(RBinJavaCPTypeObj *obj) {
1566 RBinJavaCPTypeObj *clone_obj = NULL;
1567 if (obj == NULL) {
1568 return clone_obj;
1569 }
1570 clone_obj = R_NEW0 (RBinJavaCPTypeObj);
1571 if (clone_obj) {
1572 memcpy (clone_obj, obj, sizeof (RBinJavaCPTypeObj));
1573 clone_obj->metas = (RBinJavaMetaInfo *) R_NEW0 (RBinJavaMetaInfo);
1574 clone_obj->metas->type_info = (void *) &R_BIN_JAVA_CP_METAS[clone_obj->tag];
1575 clone_obj->name = strdup (obj->name? obj->name: "unk");
1576 if (obj->tag == R_BIN_JAVA_CP_UTF8) {
1577 clone_obj->info.cp_utf8.bytes = (ut8 *) malloc (obj->info.cp_utf8.length + 1);
1578 if (clone_obj->info.cp_utf8.bytes) {
1579 memcpy (clone_obj->info.cp_utf8.bytes, obj->info.cp_utf8.bytes, clone_obj->info.cp_utf8.length);
1580 } else {
1581 // TODO: eprintf allocation error
1582 }
1583 }
1584 }
1585 return clone_obj;
1586 }
1587
r_bin_java_read_next_constant_pool_item(RBinJavaObj * bin,const ut64 offset,const ut8 * buf,ut64 len)1588 R_API RBinJavaCPTypeObj *r_bin_java_read_next_constant_pool_item(RBinJavaObj *bin, const ut64 offset, const ut8 *buf, ut64 len) {
1589 RBinJavaCPTypeMetas *java_constant_info = NULL;
1590 ut8 tag = 0;
1591 ut64 buf_sz = 0;
1592 ut8 *cp_buf = NULL;
1593 ut32 str_len = 0;
1594 RBinJavaCPTypeObj *java_obj = NULL;
1595 tag = buf[offset];
1596 if (tag > R_BIN_JAVA_CP_METAS_SZ) {
1597 eprintf ("Invalid tag '%d' at offset 0x%08"PFMT64x "\n", tag, (ut64) offset);
1598 return NULL;
1599 #if 0
1600 java_obj = r_bin_java_unknown_cp_new (bin, &tag, 1);
1601 if (java_obj != NULL && java_obj->metas != NULL) {
1602 java_obj->file_offset = offset;
1603 java_obj->loadaddr = bin->loadaddr;
1604 }
1605 return NULL; // early error to avoid future overflows
1606 // return java_obj;
1607 #endif
1608 }
1609 java_constant_info = &R_BIN_JAVA_CP_METAS[tag];
1610 if (java_constant_info->tag == 0 || java_constant_info->tag == 2) {
1611 return java_obj;
1612 }
1613 buf_sz += java_constant_info->len;
1614 if (java_constant_info->tag == 1) {
1615 if (offset + 32 < len) {
1616 str_len = R_BIN_JAVA_USHORT (buf, offset + 1);
1617 buf_sz += str_len;
1618 } else {
1619 return NULL;
1620 }
1621 }
1622 cp_buf = calloc (buf_sz, 1);
1623 if (!cp_buf) {
1624 return java_obj;
1625 }
1626 if (offset + buf_sz < len) {
1627 memcpy (cp_buf, (ut8 *) buf + offset, buf_sz);
1628 IFDBG eprintf("Parsed the tag '%d':%s and create object from offset 0x%08"PFMT64x ".\n", tag, R_BIN_JAVA_CP_METAS[tag].name, offset);
1629 java_obj = (*java_constant_info->allocs->new_obj)(bin, cp_buf, buf_sz);
1630 if (java_obj != NULL && java_obj->metas != NULL) {
1631 java_obj->file_offset = offset;
1632 // IFDBG eprintf ("java_obj->file_offset = 0x%08"PFMT64x".\n",java_obj->file_offset);
1633 } else if (!java_obj) {
1634 eprintf ("Unable to parse the tag '%d' and create valid object.\n", tag);
1635 } else if (!java_obj->metas) {
1636 eprintf ("Unable to parse the tag '%d' and create valid object.\n", tag);
1637 } else {
1638 eprintf ("Failed to set the java_obj->metas-file_offset for '%d' offset is(0x%08"PFMT64x ").\n", tag, offset);
1639 }
1640 }
1641 free (cp_buf);
1642 return java_obj;
1643 }
1644
r_bin_java_read_next_interface_item(RBinJavaObj * bin,const ut64 offset,const ut8 * buf,const ut64 len)1645 R_API RBinJavaInterfaceInfo *r_bin_java_read_next_interface_item(RBinJavaObj *bin, const ut64 offset, const ut8 *buf, const ut64 len) {
1646 ut8 idx[2] = {
1647 0
1648 };
1649 RBinJavaInterfaceInfo *ifobj;
1650 const ut8 *if_buf = buf + offset;
1651 if (offset + 2 >= len) {
1652 return NULL;
1653 }
1654 memcpy (&idx, if_buf, 2);
1655 ifobj = r_bin_java_interface_new (bin, if_buf, len - offset);
1656 if (ifobj) {
1657 ifobj->file_offset = offset;
1658 }
1659 return ifobj;
1660 }
1661 // R_API void addrow (RBinJavaObj *bin, int addr, int line) {
1662 // int n = bin->lines.count++;
1663 //// XXX. possible memleak
1664 // bin->lines.addr = realloc (bin->lines.addr, sizeof (int)*n+1);
1665 // bin->lines.addr[n] = addr;
1666 // bin->lines.line = realloc (bin->lines.line, sizeof (int)*n+1);
1667 // bin->lines.line[n] = line;
1668 // }
1669 // R_API struct r_bin_java_cp_item_t* r_bin_java_get_item_from_cp_CP(RBinJavaObj *bin, int i) {
1670 // return (i<0||i>bin->cf.cp_count)? &cp_null_item: &bin->cp_items[i];
1671 // }
1672
r_bin_java_get_utf8_from_bin_cp_list(RBinJavaObj * bin,ut64 idx)1673 R_API char *r_bin_java_get_utf8_from_bin_cp_list(RBinJavaObj *bin, ut64 idx) {
1674 /*
1675 Search through the Constant Pool list for the given CP Index.
1676 If the idx not found by directly going to the list index,
1677 the list will be walked and then the IDX will be checked.
1678 rvalue: new char* for caller to free.
1679 */
1680 if (bin == NULL) {
1681 return NULL;
1682 }
1683 return r_bin_java_get_utf8_from_cp_item_list (bin->cp_list, idx);
1684 }
1685
r_bin_java_get_utf8_len_from_bin_cp_list(RBinJavaObj * bin,ut64 idx)1686 R_API ut32 r_bin_java_get_utf8_len_from_bin_cp_list(RBinJavaObj *bin, ut64 idx) {
1687 /*
1688 Search through the Constant Pool list for the given CP Index.
1689 If the idx not found by directly going to the list index,
1690 the list will be walked and then the IDX will be checked.
1691 rvalue: new char* for caller to free.
1692 */
1693 if (bin == NULL) {
1694 return 0;
1695 }
1696 return r_bin_java_get_utf8_len_from_cp_item_list (bin->cp_list, idx);
1697 }
1698
r_bin_java_get_name_from_bin_cp_list(RBinJavaObj * bin,ut64 idx)1699 R_API char *r_bin_java_get_name_from_bin_cp_list(RBinJavaObj *bin, ut64 idx) {
1700 /*
1701 Search through the Constant Pool list for the given CP Index.
1702 If the idx not found by directly going to the list index,
1703 the list will be walked and then the IDX will be checked.
1704 rvalue: new char* for caller to free.
1705 */
1706 if (bin == NULL) {
1707 return NULL;
1708 }
1709 return r_bin_java_get_name_from_cp_item_list (bin->cp_list, idx);
1710 }
1711
r_bin_java_get_desc_from_bin_cp_list(RBinJavaObj * bin,ut64 idx)1712 R_API char *r_bin_java_get_desc_from_bin_cp_list(RBinJavaObj *bin, ut64 idx) {
1713 /*
1714 Search through the Constant Pool list for the given CP Index.
1715 If the idx not found by directly going to the list index,
1716 the list will be walked and then the IDX will be checked.
1717 rvalue: new char* for caller to free.
1718 */
1719 if (bin == NULL) {
1720 return NULL;
1721 }
1722 return r_bin_java_get_desc_from_cp_item_list (bin->cp_list, idx);
1723 }
1724
r_bin_java_get_item_from_bin_cp_list(RBinJavaObj * bin,ut64 idx)1725 R_API RBinJavaCPTypeObj *r_bin_java_get_item_from_bin_cp_list(RBinJavaObj *bin, ut64 idx) {
1726 /*
1727 Search through the Constant Pool list for the given CP Index.
1728 If the idx not found by directly going to the list index,
1729 the list will be walked and then the IDX will be checked.
1730 rvalue: RBinJavaObj* (user does NOT free).
1731 */
1732 if (bin == NULL) {
1733 return NULL;
1734 }
1735 if (idx > bin->cp_count || idx == 0) {
1736 return r_bin_java_get_java_null_cp ();
1737 }
1738 return r_bin_java_get_item_from_cp_item_list (bin->cp_list, idx);
1739 }
1740
r_bin_java_get_item_name_from_bin_cp_list(RBinJavaObj * bin,RBinJavaCPTypeObj * obj)1741 R_API char *r_bin_java_get_item_name_from_bin_cp_list(RBinJavaObj *bin, RBinJavaCPTypeObj *obj) {
1742 char *res = NULL;
1743 /*
1744 Given a constant poool object Class, FieldRef, MethodRef, or InterfaceMethodRef
1745 return the actual descriptor string.
1746 @param cp_list: RList of RBinJavaCPTypeObj *
1747 @param obj object to look up the name for
1748 @rvalue char* (user frees) or NULL
1749 */
1750 if (bin && obj) {
1751 res = r_bin_java_get_item_name_from_cp_item_list (
1752 bin->cp_list, obj, MAX_CPITEMS);
1753 }
1754 return res;
1755 }
1756
r_bin_java_get_item_desc_from_bin_cp_list(RBinJavaObj * bin,RBinJavaCPTypeObj * obj)1757 R_API char *r_bin_java_get_item_desc_from_bin_cp_list(RBinJavaObj *bin, RBinJavaCPTypeObj *obj) {
1758 /*
1759 Given a constant poool object Class, FieldRef, MethodRef, or InterfaceMethodRef
1760 return the actual descriptor string.
1761 @param cp_list: RList of RBinJavaCPTypeObj *
1762 @param obj object to look up the name for
1763 @rvalue char* (user frees) or NULL
1764 */
1765 return bin? r_bin_java_get_item_desc_from_cp_item_list (bin->cp_list, obj, MAX_CPITEMS): NULL;
1766 }
1767
r_bin_java_get_utf8_from_cp_item_list(RList * cp_list,ut64 idx)1768 R_API char *r_bin_java_get_utf8_from_cp_item_list(RList *cp_list, ut64 idx) {
1769 /*
1770 Search through the Constant Pool list for the given CP Index.
1771 If the idx not found by directly going to the list index,
1772 the list will be walked and then the IDX will be checked.
1773 rvalue: new char* for caller to free.
1774 */
1775 char *value = NULL;
1776 RListIter *iter;
1777 if (!cp_list) {
1778 return NULL;
1779 }
1780 RBinJavaCPTypeObj *item = (RBinJavaCPTypeObj *) r_list_get_n (cp_list, idx);
1781 if (item && item->tag == R_BIN_JAVA_CP_UTF8 && item->metas->ord == idx) {
1782 value = convert_string ((const char *) item->info.cp_utf8.bytes, item->info.cp_utf8.length);
1783 }
1784 if (!value) {
1785 r_list_foreach (cp_list, iter, item) {
1786 if (item && (item->tag == R_BIN_JAVA_CP_UTF8) && item->metas->ord == idx) {
1787 value = convert_string ((const char *) item->info.cp_utf8.bytes, item->info.cp_utf8.length);
1788 break;
1789 }
1790 }
1791 }
1792 return value;
1793 }
1794
r_bin_java_get_utf8_len_from_cp_item_list(RList * cp_list,ut64 idx)1795 R_API ut32 r_bin_java_get_utf8_len_from_cp_item_list(RList *cp_list, ut64 idx) {
1796 /*
1797 Search through the Constant Pool list for the given CP Index.
1798 If the idx not found by directly going to the list index,
1799 the list will be walked and then the IDX will be checked.
1800 rvalue: new ut32 .
1801 */
1802 ut32 value = -1;
1803 RListIter *iter;
1804 if (!cp_list) {
1805 return 0;
1806 }
1807 RBinJavaCPTypeObj *item = (RBinJavaCPTypeObj *) r_list_get_n (cp_list, idx);
1808 if (item && (item->tag == R_BIN_JAVA_CP_UTF8) && item->metas->ord == idx) {
1809 value = item->info.cp_utf8.length;
1810 }
1811 if (value == -1) {
1812 r_list_foreach (cp_list, iter, item) {
1813 if (item && (item->tag == R_BIN_JAVA_CP_UTF8) && item->metas->ord == idx) {
1814 value = item->info.cp_utf8.length;
1815 break;
1816 }
1817 }
1818 }
1819 return value;
1820 }
1821
r_bin_java_get_item_from_cp_item_list(RList * cp_list,ut64 idx)1822 R_API RBinJavaCPTypeObj *r_bin_java_get_item_from_cp_item_list(RList *cp_list, ut64 idx) {
1823 /*
1824 Search through the Constant Pool list for the given CP Index.
1825 rvalue: RBinJavaObj *
1826 */
1827 RBinJavaCPTypeObj *item = NULL;
1828 if (cp_list == NULL) {
1829 return NULL;
1830 }
1831 item = (RBinJavaCPTypeObj *) r_list_get_n (cp_list, idx);
1832 return item;
1833 }
1834
r_bin_java_get_item_name_from_cp_item_list(RList * cp_list,RBinJavaCPTypeObj * obj,int depth)1835 R_API char *r_bin_java_get_item_name_from_cp_item_list(RList *cp_list, RBinJavaCPTypeObj *obj, int depth) {
1836 /*
1837 Given a constant poool object Class, FieldRef, MethodRef, or InterfaceMethodRef
1838 return the actual descriptor string.
1839 @param cp_list: RList of RBinJavaCPTypeObj *
1840 @param obj object to look up the name for
1841 @rvalue ut8* (user frees) or NULL
1842 */
1843 if (obj == NULL || cp_list == NULL || depth < 0) {
1844 return NULL;
1845 }
1846 switch (obj->tag) {
1847 case R_BIN_JAVA_CP_NAMEANDTYPE:
1848 return r_bin_java_get_utf8_from_cp_item_list (
1849 cp_list, obj->info.cp_name_and_type.name_idx);
1850 case R_BIN_JAVA_CP_CLASS:
1851 return r_bin_java_get_utf8_from_cp_item_list (
1852 cp_list, obj->info.cp_class.name_idx);
1853 // XXX - Probably not good form, but they are the same memory structure
1854 case R_BIN_JAVA_CP_FIELDREF:
1855 case R_BIN_JAVA_CP_INTERFACEMETHOD_REF:
1856 case R_BIN_JAVA_CP_METHODREF:
1857 obj = r_bin_java_get_item_from_cp_item_list (
1858 cp_list, obj->info.cp_method.name_and_type_idx);
1859 return r_bin_java_get_item_name_from_cp_item_list (
1860 cp_list, obj, depth - 1);
1861 default:
1862 return NULL;
1863 case 0:
1864 IFDBG eprintf("Invalid 0 tag in the constant pool\n");
1865 return NULL;
1866 }
1867 return NULL;
1868 }
1869
r_bin_java_get_name_from_cp_item_list(RList * cp_list,ut64 idx)1870 R_API char *r_bin_java_get_name_from_cp_item_list(RList *cp_list, ut64 idx) {
1871 /*
1872 Given a constant poool object Class, FieldRef, MethodRef, or InterfaceMethodRef
1873 return the actual descriptor string.
1874 @param cp_list: RList of RBinJavaCPTypeObj *
1875 @param obj object to look up the name for
1876 @rvalue ut8* (user frees) or NULL
1877 */
1878 RBinJavaCPTypeObj *obj = r_bin_java_get_item_from_cp_item_list (
1879 cp_list, idx);
1880 if (obj && cp_list) {
1881 return r_bin_java_get_item_name_from_cp_item_list (
1882 cp_list, obj, MAX_CPITEMS);
1883 }
1884 return NULL;
1885 }
1886
r_bin_java_get_item_desc_from_cp_item_list(RList * cp_list,RBinJavaCPTypeObj * obj,int depth)1887 R_API char *r_bin_java_get_item_desc_from_cp_item_list(RList *cp_list, RBinJavaCPTypeObj *obj, int depth) {
1888 /*
1889 Given a constant poool object FieldRef, MethodRef, or InterfaceMethodRef
1890 return the actual descriptor string.
1891 @rvalue ut8* (user frees) or NULL
1892 */
1893 if (!obj || !cp_list || depth < 0) {
1894 return NULL;
1895 }
1896 switch (obj->tag) {
1897 case R_BIN_JAVA_CP_NAMEANDTYPE:
1898 return r_bin_java_get_utf8_from_cp_item_list (cp_list,
1899 obj->info.cp_name_and_type.descriptor_idx);
1900 // XXX - Probably not good form, but they are the same memory structure
1901 case R_BIN_JAVA_CP_FIELDREF:
1902 case R_BIN_JAVA_CP_INTERFACEMETHOD_REF:
1903 case R_BIN_JAVA_CP_METHODREF:
1904 obj = r_bin_java_get_item_from_cp_item_list (cp_list,
1905 obj->info.cp_method.name_and_type_idx);
1906 return r_bin_java_get_item_desc_from_cp_item_list (
1907 cp_list, obj, depth - 1);
1908 default:
1909 return NULL;
1910 }
1911 return NULL;
1912 }
1913
r_bin_java_get_desc_from_cp_item_list(RList * cp_list,ut64 idx)1914 R_API char *r_bin_java_get_desc_from_cp_item_list(RList *cp_list, ut64 idx) {
1915 /*
1916 Given a constant poool object FieldRef, MethodRef, or InterfaceMethodRef
1917 return the actual descriptor string.
1918 @rvalue ut8* (user frees) or NULL
1919 */
1920 RBinJavaCPTypeObj *obj = r_bin_java_get_item_from_cp_item_list (cp_list, idx);
1921 if (cp_list == NULL) {
1922 return NULL;
1923 }
1924 return r_bin_java_get_item_desc_from_cp_item_list (cp_list, obj, MAX_CPITEMS);
1925 }
1926
r_bin_java_get_method_code_attribute(const RBinJavaField * method)1927 R_API RBinJavaAttrInfo *r_bin_java_get_method_code_attribute(const RBinJavaField *method) {
1928 /*
1929 Search through a methods attributes and return the code attr.
1930 rvalue: RBinJavaAttrInfo* if found otherwise NULL.
1931 */
1932 RBinJavaAttrInfo *res = NULL, *attr = NULL;
1933 RListIter *iter;
1934 if (method) {
1935 r_list_foreach (method->attributes, iter, attr) {
1936 if (attr && (attr->type == R_BIN_JAVA_ATTR_TYPE_CODE_ATTR)) {
1937 res = attr;
1938 break;
1939 }
1940 }
1941 }
1942 return res;
1943 }
1944
r_bin_java_get_attr_from_field(RBinJavaField * field,R_BIN_JAVA_ATTR_TYPE attr_type,ut32 pos)1945 R_API RBinJavaAttrInfo *r_bin_java_get_attr_from_field(RBinJavaField *field, R_BIN_JAVA_ATTR_TYPE attr_type, ut32 pos) {
1946 /*
1947 Search through the Attribute list for the given type starting at position pos.
1948 rvalue: NULL or the first occurrence of attr_type after pos
1949 */
1950 RBinJavaAttrInfo *attr = NULL, *item;
1951 RListIter *iter;
1952 ut32 i = 0;
1953 if (field) {
1954 r_list_foreach (field->attributes, iter, item) {
1955 // Note the increment happens after the comparison
1956 if ((i++) >= pos) {
1957 if (item && (item->type == attr_type)) {
1958 attr = item;
1959 break;
1960 }
1961 }
1962 }
1963 }
1964 return attr;
1965 }
1966
r_bin_java_get_attr_buf(RBinJavaObj * bin,ut64 sz,const ut64 offset,const ut8 * buf,const ut64 len)1967 R_API ut8 *r_bin_java_get_attr_buf(RBinJavaObj *bin, ut64 sz, const ut64 offset, const ut8 *buf, const ut64 len) {
1968 ut8 *attr_buf = NULL;
1969 int pending = len - offset;
1970 const ut8 *a_buf = offset + buf;
1971 attr_buf = (ut8 *) calloc (pending + 1, 1);
1972 if (attr_buf == NULL) {
1973 eprintf ("Unable to allocate enough bytes (0x%04"PFMT64x
1974 ") to read in the attribute.\n", sz);
1975 return attr_buf;
1976 }
1977 memcpy (attr_buf, a_buf, pending); // sz+1);
1978 return attr_buf;
1979 }
1980
r_bin_java_default_attr_new(RBinJavaObj * bin,ut8 * buffer,ut64 sz,ut64 buf_offset)1981 R_API RBinJavaAttrInfo *r_bin_java_default_attr_new(RBinJavaObj *bin, ut8 *buffer, ut64 sz, ut64 buf_offset) {
1982 // NOTE: this function receives the buffer offset in the original buffer,
1983 // but the buffer is already point to that particular offset.
1984 // XXX - all the code that relies on this function should probably be modified
1985 // so that the original buffer pointer is passed in and then the buffer+buf_offset
1986 // points to the correct location.
1987 RBinJavaAttrInfo *attr = R_NEW0 (RBinJavaAttrInfo);
1988 if (!attr) {
1989 return NULL;
1990 }
1991 RBinJavaAttrMetas *type_info = NULL;
1992 attr->metas = R_NEW0 (RBinJavaMetaInfo);
1993 if (attr->metas == NULL) {
1994 free (attr);
1995 return NULL;
1996 }
1997 attr->is_attr_in_old_format = r_bin_java_is_old_format(bin);
1998 attr->file_offset = buf_offset;
1999 attr->name_idx = R_BIN_JAVA_USHORT (buffer, 0);
2000 attr->length = R_BIN_JAVA_UINT (buffer, 2);
2001 attr->size = R_BIN_JAVA_UINT (buffer, 2) + 6;
2002 attr->name = r_bin_java_get_utf8_from_bin_cp_list (R_BIN_JAVA_GLOBAL_BIN, attr->name_idx);
2003 if (attr->name == NULL) {
2004 // Something bad has happened
2005 attr->name = r_str_dup (NULL, "NULL");
2006 eprintf ("r_bin_java_default_attr_new: Unable to find the name for %d index.\n", attr->name_idx);
2007 }
2008 type_info = r_bin_java_get_attr_type_by_name (attr->name);
2009 attr->metas->ord = (R_BIN_JAVA_GLOBAL_BIN->attr_idx++);
2010 attr->metas->type_info = (void *) type_info;
2011 // IFDBG eprintf (" Addrs for type_info [tag=%d]: 0x%08"PFMT64x"\n", type_val, &attr->metas->type_info);
2012 return attr;
2013 }
2014
r_bin_java_get_attr_type_by_name(const char * name)2015 R_API RBinJavaAttrMetas *r_bin_java_get_attr_type_by_name(const char *name) {
2016 // TODO: use sdb/hashtable here
2017 int i;
2018 for (i = 0; i < RBIN_JAVA_ATTRS_METAS_SZ; i++) {
2019 if (!strcmp ((const char *) name, RBIN_JAVA_ATTRS_METAS[i].name)) {
2020 return &RBIN_JAVA_ATTRS_METAS[i];
2021 }
2022 }
2023 return &RBIN_JAVA_ATTRS_METAS[R_BIN_JAVA_ATTR_TYPE_UNKNOWN_ATTR];
2024 }
2025
r_bin_java_read_next_attr(RBinJavaObj * bin,const ut64 offset,const ut8 * buf,const ut64 buf_len)2026 R_API RBinJavaAttrInfo *r_bin_java_read_next_attr(RBinJavaObj *bin, const ut64 offset, const ut8 *buf, const ut64 buf_len) {
2027 RBinJavaAttrInfo *attr = NULL;
2028 ut32 sz = 0;
2029 ut8 *buffer = NULL;
2030 const ut8 *a_buf = offset + buf;
2031 ut8 attr_idx_len = 6;
2032 if (offset + 6 > buf_len) {
2033 eprintf ("[X] r_bin_java: Error unable to parse remainder of classfile in Attribute offset "
2034 "(0x%"PFMT64x ") > len of remaining bytes (0x%"PFMT64x ").\n", offset, buf_len);
2035 return NULL;
2036 }
2037 // ut16 attr_idx, ut32 length of attr.
2038 sz = R_BIN_JAVA_UINT (a_buf, 2) + attr_idx_len; // r_bin_java_read_int (bin, buf_offset+2) + attr_idx_len;
2039 if (sz + offset > buf_len) {
2040 eprintf ("[X] r_bin_java: Error unable to parse remainder of classfile in Attribute len "
2041 "(0x%x) + offset (0x%"PFMT64x ") exceeds length of buffer (0x%"PFMT64x ").\n",
2042 sz, offset, buf_len);
2043 return NULL;
2044 }
2045 // when reading the attr bytes, need to also
2046 // include the initial 6 bytes, which
2047 // are not included in the attribute length
2048 // ,
2049 // sz, buf_offset, buf_offset+sz);
2050 buffer = r_bin_java_get_attr_buf (bin, sz, offset, buf, buf_len);
2051 // printf ("%d %d %d\n", sz, buf_len, offset);
2052 if (offset < buf_len) {
2053 attr = r_bin_java_read_next_attr_from_buffer (bin, buffer, buf_len - offset, offset);
2054 free (buffer);
2055
2056 if (!attr) {
2057 return NULL;
2058 }
2059 attr->size = sz;
2060 } else {
2061 free (buffer);
2062 eprintf ("IS OOB\n");
2063 }
2064 return attr;
2065 }
2066
r_bin_java_read_next_attr_from_buffer(RBinJavaObj * bin,ut8 * buffer,st64 sz,st64 buf_offset)2067 R_API RBinJavaAttrInfo *r_bin_java_read_next_attr_from_buffer(RBinJavaObj *bin, ut8 *buffer, st64 sz, st64 buf_offset) {
2068 RBinJavaAttrInfo *attr = NULL;
2069 ut64 offset = 0;
2070 ut16 name_idx;
2071 st64 nsz;
2072
2073 if (!buffer || ((int) sz) < 4 || buf_offset < 0) {
2074 eprintf ("r_bin_Java_read_next_attr_from_buffer: invalid buffer size %d\n", (int) sz);
2075 return NULL;
2076 }
2077 name_idx = R_BIN_JAVA_USHORT (buffer, offset);
2078 offset += 2;
2079 nsz = R_BIN_JAVA_UINT (buffer, offset);
2080 // DEAD INCREMENT offset += 4;
2081
2082 char *name = r_bin_java_get_utf8_from_bin_cp_list (R_BIN_JAVA_GLOBAL_BIN, name_idx);
2083 if (!name) {
2084 name = strdup ("unknown");
2085 }
2086 IFDBG eprintf("r_bin_java_read_next_attr: name_idx = %d is %s\n", name_idx, name);
2087 RBinJavaAttrMetas *type_info = r_bin_java_get_attr_type_by_name (name);
2088 if (type_info) {
2089 IFDBG eprintf("Typeinfo: %s, was %s\n", type_info->name, name);
2090 // printf ("SZ %d %d %d\n", nsz, sz, buf_offset);
2091 if (nsz > sz) {
2092 free (name);
2093 return NULL;
2094 }
2095 if ((attr = type_info->allocs->new_obj (bin, buffer, nsz, buf_offset))) {
2096 attr->metas->ord = (R_BIN_JAVA_GLOBAL_BIN->attr_idx++);
2097 }
2098 } else {
2099 eprintf ("r_bin_java_read_next_attr_from_buffer: Cannot find type_info for %s\n", name);
2100 }
2101 free (name);
2102 return attr;
2103 }
2104
r_bin_java_read_class_file2(RBinJavaObj * bin,const ut64 offset,const ut8 * obuf,ut64 len)2105 R_API ut64 r_bin_java_read_class_file2(RBinJavaObj *bin, const ut64 offset, const ut8 *obuf, ut64 len) {
2106 const ut8 *cf2_buf = obuf + offset;
2107 RBinJavaCPTypeObj *this_class_cp_obj = NULL;
2108 IFDBG eprintf("\n0x%"PFMT64x " Offset before reading the cf2 structure\n", offset);
2109 /*
2110 Reading the following fields:
2111 ut16 access_flags;
2112 ut16 this_class;
2113 ut16 super_class;
2114 */
2115 if (cf2_buf + 6 > obuf + len) {
2116 return 0;
2117 }
2118 bin->cf2.cf2_size = 6;
2119 bin->cf2.access_flags = R_BIN_JAVA_USHORT (cf2_buf, 0);
2120 bin->cf2.this_class = R_BIN_JAVA_USHORT (cf2_buf, 2);
2121 bin->cf2.super_class = R_BIN_JAVA_USHORT (cf2_buf, 4);
2122 free (bin->cf2.flags_str);
2123 free (bin->cf2.this_class_name);
2124 bin->cf2.flags_str = retrieve_class_method_access_string (bin->cf2.access_flags);
2125 this_class_cp_obj = r_bin_java_get_item_from_bin_cp_list (bin, bin->cf2.this_class);
2126 bin->cf2.this_class_name = r_bin_java_get_item_name_from_bin_cp_list (bin, this_class_cp_obj);
2127 IFDBG eprintf("This class flags are: %s\n", bin->cf2.flags_str);
2128 return bin->cf2.cf2_size;
2129 }
2130
r_bin_java_parse_cp_pool(RBinJavaObj * bin,const ut64 offset,const ut8 * buf,const ut64 len)2131 R_API ut64 r_bin_java_parse_cp_pool(RBinJavaObj *bin, const ut64 offset, const ut8 *buf, const ut64 len) {
2132 int ord = 0;
2133 ut64 adv = 0;
2134 RBinJavaCPTypeObj *obj = NULL;
2135 const ut8 *cp_buf = buf + offset;
2136 r_list_free (bin->cp_list);
2137 bin->cp_list = r_list_newf (r_bin_java_constant_pool);
2138 bin->cp_offset = offset;
2139 memcpy ((char *) &bin->cp_count, cp_buf, 2);
2140 bin->cp_count = R_BIN_JAVA_USHORT (cp_buf, 0) - 1;
2141 adv += 2;
2142 IFDBG eprintf("ConstantPoolCount %d\n", bin->cp_count);
2143 r_list_append (bin->cp_list, r_bin_java_get_java_null_cp ());
2144 for (ord = 1, bin->cp_idx = 0; bin->cp_idx < bin->cp_count && adv < len; ord++, bin->cp_idx++) {
2145 obj = r_bin_java_read_next_constant_pool_item (bin, offset + adv, buf, len);
2146 if (obj) {
2147 // IFDBG eprintf ("SUCCESS Read ConstantPoolItem %d\n", i);
2148 obj->metas->ord = ord;
2149 obj->idx = ord;
2150 r_list_append (bin->cp_list, obj);
2151 if (obj->tag == R_BIN_JAVA_CP_LONG || obj->tag == R_BIN_JAVA_CP_DOUBLE) {
2152 // i++;
2153 ord++;
2154 bin->cp_idx++;
2155 r_list_append (bin->cp_list, &R_BIN_JAVA_NULL_TYPE);
2156 }
2157
2158 IFDBG ((RBinJavaCPTypeMetas *) obj->metas->type_info)->allocs->print_summary (obj);
2159 adv += ((RBinJavaCPTypeMetas *) obj->metas->type_info)->allocs->calc_size (obj);
2160 if (offset + adv > len) {
2161 eprintf ("[X] r_bin_java: Error unable to parse remainder of classfile after Constant Pool Object: %d.\n", ord);
2162 break;
2163 }
2164 } else {
2165 IFDBG eprintf("Failed to read ConstantPoolItem %d\n", bin->cp_idx);
2166 break;
2167 }
2168 }
2169 // Update the imports
2170 r_bin_java_set_imports (bin);
2171 bin->cp_size = adv;
2172 return bin->cp_size;
2173 }
2174
r_bin_java_parse_interfaces(RBinJavaObj * bin,const ut64 offset,const ut8 * buf,const ut64 len)2175 R_API ut64 r_bin_java_parse_interfaces(RBinJavaObj *bin, const ut64 offset, const ut8 *buf, const ut64 len) {
2176 int i = 0;
2177 ut64 adv = 0;
2178 RBinJavaInterfaceInfo *interfaces_obj;
2179 const ut8 *if_buf = buf + offset;
2180 bin->cp_offset = offset;
2181 bin->interfaces_offset = offset;
2182 r_list_free (bin->interfaces_list);
2183 bin->interfaces_list = r_list_newf (r_bin_java_interface_free);
2184 if (offset + 2 > len) {
2185 bin->interfaces_size = 0;
2186 return 0;
2187 }
2188 bin->interfaces_count = R_BIN_JAVA_USHORT (if_buf, 0);
2189 adv += 2;
2190 IFDBG eprintf("Interfaces count: %d\n", bin->interfaces_count);
2191 if (bin->interfaces_count > 0) {
2192 for (i = 0; i < bin->interfaces_count; i++) {
2193 interfaces_obj = r_bin_java_read_next_interface_item (bin, offset + adv, buf, len);
2194 if (interfaces_obj) {
2195 r_list_append (bin->interfaces_list, interfaces_obj);
2196 adv += interfaces_obj->size;
2197 if (offset + adv > len) {
2198 eprintf ("[X] r_bin_java: Error unable to parse remainder of classfile after Interface: %d.\n", i);
2199 break;
2200 }
2201 } else {
2202 break;
2203 }
2204 }
2205 }
2206 bin->interfaces_size = adv;
2207 return adv;
2208 }
2209
r_bin_java_parse_fields(RBinJavaObj * bin,const ut64 offset,const ut8 * buf,const ut64 len)2210 R_API ut64 r_bin_java_parse_fields(RBinJavaObj *bin, const ut64 offset, const ut8 *buf, const ut64 len) {
2211 int i = 0;
2212 ut64 adv = 0;
2213 RBinJavaField *field;
2214 const ut8 *fm_buf = buf + offset;
2215 r_list_free (bin->fields_list);
2216 bin->fields_list = r_list_newf (r_bin_java_fmtype_free);
2217 bin->fields_offset = offset;
2218 if (offset + 2 >= len) {
2219 return UT64_MAX;
2220 }
2221 bin->fields_count = R_BIN_JAVA_USHORT (fm_buf, 0);
2222 adv += 2;
2223 IFDBG eprintf("Fields count: %d 0x%"PFMT64x "\n", bin->fields_count, bin->fields_offset);
2224 if (bin->fields_count > 0) {
2225 for (i = 0; i < bin->fields_count; i++, bin->field_idx++) {
2226 field = r_bin_java_read_next_field (bin, offset + adv, buf, len);
2227 if (field) {
2228 adv += field->size;
2229 r_list_append (bin->fields_list, field);
2230 IFDBG r_bin_java_print_field_summary(field);
2231 if (adv + offset > len) {
2232 eprintf ("[X] r_bin_java: Error unable to parse remainder of classfile after Field: %d.\n", i);
2233 break;
2234 }
2235 } else {
2236 IFDBG eprintf("Failed to read Field %d\n", i);
2237 break;
2238 }
2239 }
2240 }
2241 bin->fields_size = adv;
2242 return adv;
2243 }
2244
r_bin_java_parse_attrs(RBinJavaObj * bin,const ut64 offset,const ut8 * buf,const ut64 len)2245 R_API ut64 r_bin_java_parse_attrs(RBinJavaObj *bin, const ut64 offset, const ut8 *buf, const ut64 len) {
2246 int i = 0;
2247 ut64 adv = 0;
2248 const ut8 *a_buf = buf + offset;
2249 if (offset + 2 >= len) {
2250 // Check if we can read that USHORT
2251 return UT64_MAX;
2252 }
2253 r_list_free (bin->attrs_list);
2254 bin->attrs_list = r_list_newf (r_bin_java_attribute_free);
2255 bin->attrs_offset = offset;
2256 bin->attrs_count = R_BIN_JAVA_USHORT (a_buf, adv);
2257 adv += 2;
2258 if (bin->attrs_count > 0) {
2259 for (i = 0; i < bin->attrs_count; i++, bin->attr_idx++) {
2260 RBinJavaAttrInfo *attr = r_bin_java_read_next_attr (bin, offset + adv, buf, len);
2261 if (!attr) {
2262 // eprintf ("[X] r_bin_java: Error unable to parse remainder of classfile after Attribute: %d.\n", i);
2263 break;
2264 }
2265 r_list_append (bin->attrs_list, attr);
2266 adv += attr->size;
2267 if (adv + offset >= len) {
2268 // eprintf ("[X] r_bin_java: Error unable to parse remainder of classfile after Attribute: %d.\n", i);
2269 break;
2270 }
2271 }
2272 }
2273 bin->attrs_size = adv;
2274 return adv;
2275 }
2276
r_bin_java_parse_methods(RBinJavaObj * bin,const ut64 offset,const ut8 * buf,const ut64 len)2277 R_API ut64 r_bin_java_parse_methods(RBinJavaObj *bin, const ut64 offset, const ut8 *buf, const ut64 len) {
2278 int i = 0;
2279 ut64 adv = 0;
2280 RBinJavaField *method;
2281 const ut8 *fm_buf = buf + offset;
2282 r_list_free (bin->methods_list);
2283 bin->methods_list = r_list_newf (r_bin_java_fmtype_free);
2284
2285 if (offset + 2 >= len) {
2286 return 0LL;
2287 }
2288 bin->methods_offset = offset;
2289 bin->methods_count = R_BIN_JAVA_USHORT (fm_buf, 0);
2290 adv += 2;
2291 IFDBG eprintf("Methods count: %d 0x%"PFMT64x "\n", bin->methods_count, bin->methods_offset);
2292 bin->main = NULL;
2293 bin->entrypoint = NULL;
2294 bin->main_code_attr = NULL;
2295 bin->entrypoint_code_attr = NULL;
2296 for (i = 0; i < bin->methods_count; i++, bin->method_idx++) {
2297 method = r_bin_java_read_next_method (bin, offset + adv, buf, len);
2298 if (method) {
2299 adv += method->size;
2300 r_list_append (bin->methods_list, method);
2301 }
2302 // Update Main, Init, or Class Init
2303 if (method && !strcmp ((const char *) method->name, "main")) {
2304 bin->main = method;
2305 // get main code attr
2306 bin->main_code_attr = r_bin_java_get_attr_from_field (method, R_BIN_JAVA_ATTR_TYPE_CODE_ATTR, 0);
2307 } else if (method && (!strcmp ((const char *) method->name, "<init>") || !strcmp ((const char *) method->name, "init"))) {
2308 IFDBG eprintf("Found an init function.\n");
2309 bin->entrypoint = method;
2310 bin->entrypoint_code_attr = r_bin_java_get_attr_from_field (method, R_BIN_JAVA_ATTR_TYPE_CODE_ATTR, 0);
2311 } else if (method && (!strcmp ((const char *) method->name, "<cinit>") || !strcmp ((const char *) method->name, "cinit"))) {
2312 bin->cf2.this_class_entrypoint = method;
2313 bin->cf2.this_class_entrypoint_code_attr = r_bin_java_get_attr_from_field (method, R_BIN_JAVA_ATTR_TYPE_CODE_ATTR, 0);
2314 }
2315 if (adv + offset > len) {
2316 eprintf ("[X] r_bin_java: Error unable to parse remainder of classfile after Method: %d.\n", i);
2317 break;
2318 }
2319 IFDBG r_bin_java_print_field_summary(method);
2320 }
2321 bin->methods_size = adv;
2322 return adv;
2323 }
2324
r_bin_java_new_bin(RBinJavaObj * bin,ut64 loadaddr,Sdb * kv,const ut8 * buf,ut64 len)2325 R_API int r_bin_java_new_bin(RBinJavaObj *bin, ut64 loadaddr, Sdb *kv, const ut8 *buf, ut64 len) {
2326 R_BIN_JAVA_GLOBAL_BIN = bin;
2327 if (!r_str_constpool_init (&bin->constpool)) {
2328 return false;
2329 }
2330 bin->lines.count = 0;
2331 bin->loadaddr = loadaddr;
2332 r_bin_java_get_java_null_cp ();
2333 bin->id = r_num_rand (UT32_MAX);
2334 bin->kv = kv ? kv : sdb_new (NULL, NULL, 0);
2335 bin->AllJavaBinObjs = NULL;
2336 return r_bin_java_load_bin (bin, buf, len);
2337 }
2338
r_bin_java_load_bin(RBinJavaObj * bin,const ut8 * buf,ut64 buf_sz)2339 R_API int r_bin_java_load_bin(RBinJavaObj *bin, const ut8 *buf, ut64 buf_sz) {
2340 ut64 adv = 0;
2341 R_BIN_JAVA_GLOBAL_BIN = bin;
2342 if (!bin) {
2343 return false;
2344 }
2345 r_bin_java_reset_bin_info (bin);
2346 memcpy ((ut8 *) &bin->cf, buf, 10);
2347 if (memcmp (bin->cf.cafebabe, "\xCA\xFE\xBA\xBE", 4)) {
2348 eprintf ("r_bin_java_new_bin: Invalid header (%02x %02x %02x %02x)\n",
2349 bin->cf.cafebabe[0], bin->cf.cafebabe[1],
2350 bin->cf.cafebabe[2], bin->cf.cafebabe[3]);
2351 return false;
2352 }
2353 if (bin->cf.major[0] == bin->cf.major[1] && bin->cf.major[0] == 0) {
2354 eprintf ("Java CLASS with MACH0 header?\n");
2355 return false;
2356 }
2357 adv += 8;
2358 // -2 so that the cp_count will be parsed
2359 adv += r_bin_java_parse_cp_pool (bin, adv, buf, buf_sz);
2360 if (adv > buf_sz) {
2361 eprintf ("[X] r_bin_java: Error unable to parse remainder of classfile after Constant Pool.\n");
2362 return true;
2363 }
2364 adv += r_bin_java_read_class_file2 (bin, adv, buf, buf_sz);
2365 if (adv > buf_sz) {
2366 eprintf ("[X] r_bin_java: Error unable to parse remainder of classfile after class file info.\n");
2367 return true;
2368 }
2369 IFDBG eprintf("This class: %d %s\n", bin->cf2.this_class, bin->cf2.this_class_name);
2370 IFDBG eprintf("0x%"PFMT64x " Access flags: 0x%04x\n", adv, bin->cf2.access_flags);
2371 adv += r_bin_java_parse_interfaces (bin, adv, buf, buf_sz);
2372 if (adv > buf_sz) {
2373 eprintf ("[X] r_bin_java: Error unable to parse remainder of classfile after Interfaces.\n");
2374 return true;
2375 }
2376 adv += r_bin_java_parse_fields (bin, adv, buf, buf_sz);
2377 if (adv > buf_sz) {
2378 eprintf ("[X] r_bin_java: Error unable to parse remainder of classfile after Fields.\n");
2379 return true;
2380 }
2381 adv += r_bin_java_parse_methods (bin, adv, buf, buf_sz);
2382 if (adv > buf_sz) {
2383 eprintf ("[X] r_bin_java: Error unable to parse remainder of classfile after Methods.\n");
2384 return true;
2385 }
2386 adv += r_bin_java_parse_attrs (bin, adv, buf, buf_sz);
2387 bin->calc_size = adv;
2388 // if (adv > buf_sz) {
2389 // eprintf ("[X] r_bin_java: Error unable to parse remainder of classfile after Attributes.\n");
2390 // return true;
2391 // }
2392
2393 // add_cp_objs_to_sdb(bin);
2394 // add_method_infos_to_sdb(bin);
2395 // add_field_infos_to_sdb(bin);
2396 return true;
2397 }
2398
r_bin_java_get_version(RBinJavaObj * bin)2399 R_API char *r_bin_java_get_version(RBinJavaObj *bin) {
2400 return r_str_newf ("0x%02x%02x 0x%02x%02x",
2401 bin->cf.major[1], bin->cf.major[0],
2402 bin->cf.minor[1], bin->cf.minor[0]);
2403 }
2404
r_bin_java_get_entrypoints(RBinJavaObj * bin)2405 R_API RList *r_bin_java_get_entrypoints(RBinJavaObj *bin) {
2406 RListIter *iter = NULL, *iter_tmp = NULL;
2407 RBinJavaField *fm_type;
2408 RList *ret = r_list_newf (free);
2409 if (!ret) {
2410 return NULL;
2411 }
2412 r_list_foreach_safe (bin->methods_list, iter, iter_tmp, fm_type) {
2413 if (!strcmp (fm_type->name, "main")
2414 || !strcmp (fm_type->name, "<init>")
2415 || !strcmp (fm_type->name, "<clinit>")
2416 || strstr (fm_type->flags_str, "static")) {
2417 RBinAddr *addr = R_NEW0 (RBinAddr);
2418 if (addr) {
2419 addr->vaddr = addr->paddr = \
2420 r_bin_java_get_method_code_offset (fm_type) + bin->loadaddr;
2421 addr->hpaddr = fm_type->file_offset;
2422 r_list_append (ret, addr);
2423 }
2424 }
2425 }
2426 return ret;
2427 }
2428
r_bin_java_get_method_code_attribute_with_addr(RBinJavaObj * bin,ut64 addr)2429 R_API RBinJavaField *r_bin_java_get_method_code_attribute_with_addr(RBinJavaObj *bin, ut64 addr) {
2430 RListIter *iter = NULL, *iter_tmp = NULL;
2431 RBinJavaField *fm_type, *res = NULL;
2432 if (bin == NULL && R_BIN_JAVA_GLOBAL_BIN) {
2433 bin = R_BIN_JAVA_GLOBAL_BIN;
2434 } else if (bin == NULL) {
2435 eprintf ("Attempting to analyse function when the R_BIN_JAVA_GLOBAL_BIN has not been set.\n");
2436 return NULL;
2437 }
2438 r_list_foreach_safe (bin->methods_list, iter, iter_tmp, fm_type) {
2439 ut64 offset = r_bin_java_get_method_code_offset (fm_type) + bin->loadaddr,
2440 size = r_bin_java_get_method_code_size (fm_type);
2441 if (addr >= offset && addr <= size + offset) {
2442 res = fm_type;
2443 }
2444 }
2445 return res;
2446 }
2447
r_bin_java_get_entrypoint(RBinJavaObj * bin,int sym)2448 R_API RBinAddr *r_bin_java_get_entrypoint(RBinJavaObj *bin, int sym) {
2449 RBinAddr *ret = NULL;
2450 ret = R_NEW0 (RBinAddr);
2451 if (!ret) {
2452 return NULL;
2453 }
2454 ret->paddr = UT64_MAX;
2455 switch (sym) {
2456 case R_BIN_SYM_ENTRY:
2457 case R_BIN_SYM_INIT:
2458 ret->paddr = r_bin_java_find_method_offset (bin, "<init>");
2459 if (ret->paddr == UT64_MAX) {
2460 ret->paddr = r_bin_java_find_method_offset (bin, "<cinit>");
2461 }
2462 break;
2463 case R_BIN_SYM_FINI:
2464 ret->paddr = UT64_MAX;
2465 break;
2466 case R_BIN_SYM_MAIN:
2467 ret->paddr = r_bin_java_find_method_offset (bin, "main");
2468 break;
2469 default:
2470 ret->paddr = -1;
2471 }
2472 if (ret->paddr != -1) {
2473 ret->paddr += bin->loadaddr;
2474 }
2475 return ret;
2476 }
2477
r_bin_java_get_method_code_size(RBinJavaField * fm_type)2478 R_API ut64 r_bin_java_get_method_code_size(RBinJavaField *fm_type) {
2479 RListIter *attr_iter = NULL, *attr_iter_tmp = NULL;
2480 RBinJavaAttrInfo *attr = NULL;
2481 ut64 sz = 0;
2482 r_list_foreach_safe (fm_type->attributes, attr_iter, attr_iter_tmp, attr) {
2483 if (attr->type == R_BIN_JAVA_ATTR_TYPE_CODE_ATTR) {
2484 sz = attr->info.code_attr.code_length;
2485 break;
2486 }
2487 }
2488 return sz;
2489 }
2490
r_bin_java_find_method_offset(RBinJavaObj * bin,const char * method_name)2491 R_API ut64 r_bin_java_find_method_offset(RBinJavaObj *bin, const char *method_name) {
2492 RListIter *attr_iter = NULL, *attr_iter_tmp = NULL;
2493 RBinJavaField *method = NULL;
2494 ut64 offset = -1;
2495 r_list_foreach_safe (bin->methods_list, attr_iter, attr_iter_tmp, method) {
2496 if (method && !strcmp ((const char *) method->name, method_name)) {
2497 offset = r_bin_java_get_method_code_offset (method) + bin->loadaddr;
2498 break;
2499 }
2500 }
2501 return offset;
2502 }
2503
r_bin_java_get_method_code_offset(RBinJavaField * fm_type)2504 R_API ut64 r_bin_java_get_method_code_offset(RBinJavaField *fm_type) {
2505 RListIter *attr_iter = NULL, *attr_iter_tmp = NULL;
2506 RBinJavaAttrInfo *attr = NULL;
2507 ut64 offset = 0;
2508 r_list_foreach_safe (fm_type->attributes, attr_iter, attr_iter_tmp, attr) {
2509 if (attr->type == R_BIN_JAVA_ATTR_TYPE_CODE_ATTR) {
2510 offset = attr->info.code_attr.code_offset;
2511 break;
2512 }
2513 }
2514 return offset;
2515 }
2516
r_bin_java_allocate_rbinfield(void)2517 R_API RBinField *r_bin_java_allocate_rbinfield(void) {
2518 RBinField *t = (RBinField *) malloc (sizeof (RBinField));
2519 if (t) {
2520 memset (t, 0, sizeof (RBinField));
2521 }
2522 return t;
2523 }
2524
r_bin_java_create_new_rbinfield_from_field(RBinJavaField * fm_type,ut64 baddr)2525 R_API RBinField *r_bin_java_create_new_rbinfield_from_field(RBinJavaField *fm_type, ut64 baddr) {
2526 RBinField *field = r_bin_java_allocate_rbinfield ();
2527 if (field) {
2528 field->name = strdup (fm_type->name);
2529 field->paddr = fm_type->file_offset + baddr;
2530 field->visibility = fm_type->flags;
2531 }
2532 return field;
2533 }
2534
r_bin_java_create_new_symbol_from_field(RBinJavaField * fm_type,ut64 baddr)2535 R_API RBinSymbol *r_bin_java_create_new_symbol_from_field(RBinJavaField *fm_type, ut64 baddr) {
2536 RBinSymbol *sym = R_NEW0 (RBinSymbol);
2537 if (fm_type == NULL || fm_type->field_ref_cp_obj == NULL || fm_type->field_ref_cp_obj == &R_BIN_JAVA_NULL_TYPE) {
2538 R_FREE (sym);
2539 }
2540 if (sym) {
2541 sym->name = strdup (fm_type->name);
2542 // strncpy (sym->type, fm_type->descriptor, R_BIN_SIZEOF_STRINGS);
2543 if (fm_type->type == R_BIN_JAVA_FIELD_TYPE_METHOD) {
2544 sym->type = R_BIN_TYPE_FUNC_STR;
2545 sym->paddr = r_bin_java_get_method_code_offset (fm_type);
2546 sym->vaddr = r_bin_java_get_method_code_offset (fm_type) + baddr;
2547 sym->size = r_bin_java_get_method_code_size (fm_type);
2548 } else {
2549 sym->type = "FIELD";
2550 sym->paddr = fm_type->file_offset;// r_bin_java_get_method_code_offset (fm_type);
2551 sym->vaddr = fm_type->file_offset + baddr;
2552 sym->size = fm_type->size;
2553 }
2554 if (r_bin_java_is_fm_type_protected (fm_type)) {
2555 sym->bind = R_BIN_BIND_LOCAL_STR;
2556 } else if (r_bin_java_is_fm_type_private (fm_type)) {
2557 sym->bind = R_BIN_BIND_LOCAL_STR;
2558 } else if (r_bin_java_is_fm_type_protected (fm_type)) {
2559 sym->bind = R_BIN_BIND_GLOBAL_STR;
2560 }
2561 sym->forwarder = "NONE";
2562 if (fm_type->class_name) {
2563 sym->classname = strdup (fm_type->class_name);
2564 } else {
2565 sym->classname = strdup ("UNKNOWN"); // dupped names?
2566 }
2567 sym->ordinal = fm_type->metas->ord;
2568 sym->visibility = fm_type->flags;
2569 if (fm_type->flags_str) {
2570 sym->visibility_str = strdup (fm_type->flags_str);
2571 }
2572 }
2573 return sym;
2574 }
2575
r_bin_java_create_new_symbol_from_fm_type_meta(RBinJavaField * fm_type,ut64 baddr)2576 R_API RBinSymbol *r_bin_java_create_new_symbol_from_fm_type_meta(RBinJavaField *fm_type, ut64 baddr) {
2577 RBinSymbol *sym = R_NEW0 (RBinSymbol);
2578 if (!sym || !fm_type || !fm_type->field_ref_cp_obj || fm_type->field_ref_cp_obj == &R_BIN_JAVA_NULL_TYPE) {
2579 free (sym);
2580 return NULL;
2581 }
2582 // ut32 new_name_len = strlen (fm_type->name) + strlen ("_meta") + 1;
2583 // char *new_name = malloc (new_name_len);
2584 sym->name = r_str_newf ("meta_%s", fm_type->name);
2585 if (fm_type->type == R_BIN_JAVA_FIELD_TYPE_METHOD) {
2586 sym->type = "FUNC_META";
2587 } else {
2588 sym->type = "FIELD_META";
2589 }
2590 if (r_bin_java_is_fm_type_protected (fm_type)) {
2591 sym->bind = R_BIN_BIND_LOCAL_STR;
2592 } else if (r_bin_java_is_fm_type_private (fm_type)) {
2593 sym->bind = R_BIN_BIND_LOCAL_STR;
2594 } else if (r_bin_java_is_fm_type_protected (fm_type)) {
2595 sym->bind = R_BIN_BIND_GLOBAL_STR;
2596 }
2597 sym->forwarder = "NONE";
2598 if (fm_type->class_name) {
2599 sym->classname = strdup (fm_type->class_name);
2600 } else {
2601 sym->classname = strdup ("UNKNOWN");
2602 }
2603 sym->paddr = fm_type->file_offset;// r_bin_java_get_method_code_offset (fm_type);
2604 sym->vaddr = fm_type->file_offset + baddr;
2605 sym->ordinal = fm_type->metas->ord;
2606 sym->size = fm_type->size;
2607 sym->visibility = fm_type->flags;
2608 if (fm_type->flags_str) {
2609 sym->visibility_str = strdup (fm_type->flags_str);
2610 }
2611 return sym;
2612 }
2613
r_bin_java_create_new_symbol_from_ref(RBinJavaObj * bin,RBinJavaCPTypeObj * obj,ut64 baddr)2614 R_API RBinSymbol *r_bin_java_create_new_symbol_from_ref(RBinJavaObj *bin, RBinJavaCPTypeObj *obj, ut64 baddr) {
2615 RBinSymbol *sym = R_NEW0 (RBinSymbol);
2616 if (!sym) {
2617 return NULL;
2618 }
2619 char *class_name, *name, *type_name;
2620 if (obj == NULL || (obj->tag != R_BIN_JAVA_CP_METHODREF &&
2621 obj->tag != R_BIN_JAVA_CP_INTERFACEMETHOD_REF &&
2622 obj->tag != R_BIN_JAVA_CP_FIELDREF)) {
2623 R_FREE (sym);
2624 return sym;
2625 }
2626 if (sym) {
2627 class_name = r_bin_java_get_name_from_bin_cp_list (bin,
2628 obj->info.cp_method.class_idx);
2629 name = r_bin_java_get_name_from_bin_cp_list (bin,
2630 obj->info.cp_method.name_and_type_idx);
2631 type_name = r_bin_java_get_name_from_bin_cp_list (bin,
2632 obj->info.cp_method.name_and_type_idx);
2633 if (name) {
2634 sym->name = name;
2635 name = NULL;
2636 }
2637 if (type_name) {
2638 sym->type = r_str_constpool_get (&bin->constpool, type_name);
2639 R_FREE (type_name);
2640 }
2641 if (class_name) {
2642 sym->classname = strdup (class_name);
2643 }
2644 sym->paddr = obj->file_offset + baddr;
2645 sym->vaddr = obj->file_offset + baddr;
2646 sym->ordinal = obj->metas->ord;
2647 sym->size = 0;
2648 }
2649 return sym;
2650 }
2651
2652 // TODO: vaddr+vsize break things if set
r_bin_java_get_sections(RBinJavaObj * bin)2653 R_API RList *r_bin_java_get_sections(RBinJavaObj *bin) {
2654 RBinSection *section = NULL;
2655 RList *sections = r_list_newf (free);
2656 ut64 baddr = bin->loadaddr;
2657 RBinJavaField *fm_type;
2658 RListIter *iter = NULL;
2659 if (bin->cp_count > 0) {
2660 section = R_NEW0 (RBinSection);
2661 if (section) {
2662 section->name = strdup ("constant_pool");
2663 section->paddr = bin->cp_offset + baddr;
2664 section->size = bin->cp_size;
2665 #if 0
2666 section->vsize = section->size;
2667 section->vaddr = 0x10; // XXX // bin->cp_offset; // + baddr;
2668 #endif
2669 section->vaddr = baddr;
2670 // section->vaddr = section->paddr;
2671 // section->vsize = section->size;
2672 section->perm = R_PERM_R;
2673 section->add = true;
2674 r_list_append (sections, section);
2675 }
2676 section = NULL;
2677 }
2678 if (bin->fields_count > 0) {
2679 section = R_NEW0 (RBinSection);
2680 if (section) {
2681 section->name = strdup ("fields");
2682 section->size = bin->fields_size;
2683 section->paddr = bin->fields_offset + baddr;
2684 #if 0
2685 section->vsize = section->size;
2686 section->vaddr = section->paddr;
2687 #endif
2688 section->perm = R_PERM_R;
2689 section->add = true;
2690 r_list_append (sections, section);
2691 section = NULL;
2692 r_list_foreach (bin->fields_list, iter, fm_type) {
2693 if (fm_type->attr_offset == 0) {
2694 continue;
2695 }
2696 section = R_NEW0 (RBinSection);
2697 if (section) {
2698 section->name = r_str_newf ("attrs.%s", fm_type->name);
2699 section->size = fm_type->size - (fm_type->file_offset - fm_type->attr_offset);
2700 #if 0
2701 section->vsize = section->size;
2702 section->vaddr = section->paddr;
2703 #endif
2704 section->paddr = fm_type->attr_offset + baddr;
2705 section->perm = R_PERM_R;
2706 section->add = true;
2707 r_list_append (sections, section);
2708 }
2709 }
2710 }
2711 }
2712 if (bin->methods_count > 0) {
2713 section = R_NEW0 (RBinSection);
2714 if (section) {
2715 section->name = strdup ("methods");
2716 section->paddr = bin->methods_offset + baddr;
2717 section->size = bin->methods_size;
2718 // section->vaddr = section->paddr;
2719 // section->vsize = section->size;
2720 section->perm = R_PERM_RX;
2721 section->add = true;
2722 r_list_append (sections, section);
2723 section = NULL;
2724 r_list_foreach (bin->methods_list, iter, fm_type) {
2725 if (fm_type->attr_offset == 0) {
2726 continue;
2727 }
2728 section = R_NEW0 (RBinSection);
2729 if (section) {
2730 section->name = r_str_newf ("attrs.%s", fm_type->name);
2731 section->size = fm_type->size - (fm_type->file_offset - fm_type->attr_offset);
2732 // section->vsize = section->size;
2733 // section->vaddr = section->paddr;
2734 section->paddr = fm_type->attr_offset + baddr;
2735 section->perm = R_PERM_R | R_PERM_X;
2736 section->add = true;
2737 r_list_append (sections, section);
2738 }
2739 }
2740 }
2741 }
2742 if (bin->interfaces_count > 0) {
2743 section = R_NEW0 (RBinSection);
2744 if (section) {
2745 section->name = strdup ("interfaces");
2746 section->paddr = bin->interfaces_offset + baddr;
2747 section->size = bin->interfaces_size;
2748 // section->vaddr = section->paddr;
2749 // section->vsize = section->size;
2750 section->perm = R_PERM_R;
2751 section->add = true;
2752 r_list_append (sections, section);
2753 }
2754 section = NULL;
2755 }
2756 if (bin->attrs_count > 0) {
2757 section = R_NEW0 (RBinSection);
2758 if (section) {
2759 section->name = strdup ("attributes");
2760 section->paddr = bin->attrs_offset + baddr;
2761 section->size = bin->attrs_size;
2762 // section->vaddr = section->paddr;
2763 // section->vsize = section->size;
2764 section->perm = R_PERM_R;
2765 section->perm = R_PERM_R;
2766 section->add = true;
2767 r_list_append (sections, section);
2768 }
2769 section = NULL;
2770 }
2771 return sections;
2772 }
2773
r_bin_java_enum_class_methods(RBinJavaObj * bin,ut16 class_idx)2774 R_API RList *r_bin_java_enum_class_methods(RBinJavaObj *bin, ut16 class_idx) {
2775 RList *methods = r_list_newf (free);
2776 RListIter *iter;
2777 RBinJavaField *field;
2778 r_list_foreach (bin->methods_list, iter, field) {
2779 if (field->field_ref_cp_obj && 0) {
2780 if ((field && field->field_ref_cp_obj->metas->ord == class_idx)) {
2781 RBinSymbol *sym = r_bin_java_create_new_symbol_from_ref (
2782 bin, field->field_ref_cp_obj, bin->loadaddr);
2783 if (sym) {
2784 r_list_append (methods, sym);
2785 }
2786 }
2787 } else {
2788 RBinSymbol *sym = R_NEW0 (RBinSymbol);
2789 sym->name = strdup (field->name);
2790 // func defintion
2791 // sym->paddr = field->file_offset + bin->loadaddr;
2792 // code implementation
2793 sym->paddr = r_bin_java_get_method_code_offset (field);
2794 sym->vaddr = sym->paddr; // + bin->loadaddr;
2795 r_list_append (methods, sym);
2796 }
2797 }
2798 return methods;
2799 }
2800
r_bin_java_enum_class_fields(RBinJavaObj * bin,ut16 class_idx)2801 R_API RList *r_bin_java_enum_class_fields(RBinJavaObj *bin, ut16 class_idx) {
2802 RList *fields = r_list_newf (free);
2803 RListIter *iter;
2804 RBinJavaField *fm_type;
2805 RBinField *field = NULL;
2806 r_list_foreach (bin->fields_list, iter, fm_type) {
2807 if (fm_type) {
2808 if (fm_type && fm_type->field_ref_cp_obj
2809 && fm_type->field_ref_cp_obj->metas->ord == class_idx) {
2810 field = r_bin_java_create_new_rbinfield_from_field (fm_type, bin->loadaddr);
2811 if (field) {
2812 r_list_append (fields, field);
2813 }
2814 }
2815 }
2816 }
2817 return fields;
2818 }
2819
is_class_interface(RBinJavaObj * bin,RBinJavaCPTypeObj * cp_obj)2820 R_API int is_class_interface(RBinJavaObj *bin, RBinJavaCPTypeObj *cp_obj) {
2821 RBinJavaInterfaceInfo *ifobj;
2822 RListIter *iter;
2823 int res = false;
2824 r_list_foreach (bin->interfaces_list, iter, ifobj) {
2825 if (ifobj) {
2826 res = cp_obj == ifobj->cp_class;
2827 if (res) {
2828 break;
2829 }
2830 }
2831 }
2832 return res;
2833 }
2834 /*
2835 R_API RList * r_bin_java_get_interface_classes(RBinJavaObj * bin) {
2836 RList *interfaces_names = r_list_new ();
2837 RListIter *iter;
2838 RBinJavaInterfaceInfo *ifobj;
2839 r_list_foreach(bin->interfaces_list, iter, iinfo) {
2840 RBinClass *class_ = R_NEW0 (RBinClass);
2841 RBinJavaCPTypeObj *cp_obj = ;
2842 if (ifobj && ifobj->name) {
2843 ut8 * name = strdup(ifobj->name);
2844 r_list_append(interfaces_names, name);
2845 }
2846 }
2847 return interfaces_names;
2848 }
2849 */
2850
r_bin_java_get_lib_names(RBinJavaObj * bin)2851 R_API RList *r_bin_java_get_lib_names(RBinJavaObj *bin) {
2852 RList *lib_names = r_list_newf (free);
2853 RListIter *iter;
2854 RBinJavaCPTypeObj *cp_obj = NULL;
2855 if (!bin) {
2856 return lib_names;
2857 }
2858 r_list_foreach (bin->cp_list, iter, cp_obj) {
2859 if (cp_obj && cp_obj->tag == R_BIN_JAVA_CP_CLASS &&
2860 (bin->cf2.this_class != cp_obj->info.cp_class.name_idx || !is_class_interface (bin, cp_obj))) {
2861 char *name = r_bin_java_get_item_name_from_bin_cp_list (bin, cp_obj);
2862 if (name) {
2863 r_list_append (lib_names, name);
2864 }
2865 }
2866 }
2867 return lib_names;
2868 }
2869
r_bin_java_classes_free(void * k)2870 R_API void r_bin_java_classes_free(void /*RBinClass*/ *k) {
2871 RBinClass *klass = k;
2872 if (klass) {
2873 r_list_free (klass->methods);
2874 r_list_free (klass->fields);
2875 free (klass->name);
2876 free (klass->super);
2877 free (klass->visibility_str);
2878 free (klass);
2879 }
2880 }
2881
r_bin_java_get_classes(RBinJavaObj * bin)2882 R_API RList *r_bin_java_get_classes(RBinJavaObj *bin) {
2883 RList *classes = r_list_newf (r_bin_java_classes_free);
2884 RListIter *iter;
2885 RBinJavaCPTypeObj *cp_obj = NULL;
2886 RBinJavaCPTypeObj *this_class_cp_obj = r_bin_java_get_item_from_bin_cp_list (bin, bin->cf2.this_class);
2887 ut32 idx = 0;
2888 RBinClass *k = R_NEW0 (RBinClass);
2889 if (!k) {
2890 r_list_free (classes);
2891 return NULL;
2892 }
2893 k->visibility = bin->cf2.access_flags;
2894 if (bin->cf2.flags_str) {
2895 k->visibility_str = strdup (bin->cf2.flags_str);
2896 }
2897 k->methods = r_bin_java_enum_class_methods (bin, bin->cf2.this_class);
2898 k->fields = r_bin_java_enum_class_fields (bin, bin->cf2.this_class);
2899 k->name = r_bin_java_get_this_class_name (bin);
2900 k->super = r_bin_java_get_name_from_bin_cp_list (bin, bin->cf2.super_class);
2901 k->index = (idx++);
2902 r_list_append (classes, k);
2903 r_list_foreach (bin->cp_list, iter, cp_obj) {
2904 if (cp_obj && cp_obj->tag == R_BIN_JAVA_CP_CLASS
2905 && (this_class_cp_obj != cp_obj && is_class_interface (bin, cp_obj))) {
2906 k = R_NEW0 (RBinClass);
2907 if (!k) {
2908 break;
2909 }
2910 k->methods = r_bin_java_enum_class_methods (bin, cp_obj->info.cp_class.name_idx);
2911 k->fields = r_bin_java_enum_class_fields (bin, cp_obj->info.cp_class.name_idx);
2912 k->index = idx;
2913 k->name = r_bin_java_get_item_name_from_bin_cp_list (bin, cp_obj);
2914 r_list_append (classes, k);
2915 idx++;
2916 }
2917 }
2918 return classes;
2919 }
2920
r_bin_java_create_new_symbol_from_invoke_dynamic(RBinJavaCPTypeObj * obj,ut64 baddr)2921 R_API RBinSymbol *r_bin_java_create_new_symbol_from_invoke_dynamic(RBinJavaCPTypeObj *obj, ut64 baddr) {
2922 if (!obj || (obj->tag != R_BIN_JAVA_CP_INVOKEDYNAMIC)) {
2923 return NULL;
2924 }
2925 return r_bin_java_create_new_symbol_from_cp_idx (obj->info.cp_invoke_dynamic.name_and_type_index, baddr);
2926 }
2927
r_bin_java_create_new_symbol_from_cp_idx(ut32 cp_idx,ut64 baddr)2928 R_API RBinSymbol *r_bin_java_create_new_symbol_from_cp_idx(ut32 cp_idx, ut64 baddr) {
2929 RBinSymbol *sym = NULL;
2930 RBinJavaCPTypeObj *obj = r_bin_java_get_item_from_bin_cp_list (
2931 R_BIN_JAVA_GLOBAL_BIN, cp_idx);
2932 if (obj) {
2933 switch (obj->tag) {
2934 case R_BIN_JAVA_CP_METHODREF:
2935 case R_BIN_JAVA_CP_FIELDREF:
2936 case R_BIN_JAVA_CP_INTERFACEMETHOD_REF:
2937 sym = r_bin_java_create_new_symbol_from_ref (R_BIN_JAVA_GLOBAL_BIN, obj, baddr);
2938 break;
2939 case R_BIN_JAVA_CP_INVOKEDYNAMIC:
2940 sym = r_bin_java_create_new_symbol_from_invoke_dynamic (obj, baddr);
2941 break;
2942 default:
2943 break;
2944 }
2945 }
2946 return sym;
2947 }
2948
U(r_bin_java_get_fields)2949 R_API RList *U(r_bin_java_get_fields)(RBinJavaObj * bin) {
2950 RListIter *iter = NULL, *iter_tmp = NULL;
2951 RList *fields = r_list_new ();
2952 RBinJavaField *fm_type;
2953 RBinField *field;
2954 r_list_foreach_safe (bin->fields_list, iter, iter_tmp, fm_type) {
2955 field = r_bin_java_create_new_rbinfield_from_field (fm_type, bin->loadaddr);
2956 if (field) {
2957 r_list_append (fields, field);
2958 }
2959 }
2960 return fields;
2961 }
2962
r_bin_add_import(RBinJavaObj * bin,RBinJavaCPTypeObj * obj,const char * type)2963 R_API void r_bin_add_import(RBinJavaObj *bin, RBinJavaCPTypeObj *obj, const char *type) {
2964 RBinImport *imp = R_NEW0 (RBinImport);
2965 char *class_name = r_bin_java_get_name_from_bin_cp_list (bin, obj->info.cp_method.class_idx);
2966 char *name = r_bin_java_get_name_from_bin_cp_list (bin, obj->info.cp_method.name_and_type_idx);
2967 char *descriptor = r_bin_java_get_desc_from_bin_cp_list (bin, obj->info.cp_method.name_and_type_idx);
2968 class_name = class_name ? class_name : strdup ("INVALID CLASS NAME INDEX");
2969 name = name ? name : strdup ("InvalidNameIndex");
2970 descriptor = descriptor ? descriptor : strdup ("INVALID DESCRIPTOR INDEX");
2971 imp->classname = class_name;
2972 imp->name = name;
2973 imp->bind = "NONE";
2974 imp->type = r_str_constpool_get (&bin->constpool, type);
2975 imp->descriptor = descriptor;
2976 imp->ordinal = obj->idx;
2977 r_list_append (bin->imports_list, imp);
2978 }
2979
r_bin_java_set_imports(RBinJavaObj * bin)2980 R_API void r_bin_java_set_imports(RBinJavaObj *bin) {
2981 RListIter *iter = NULL;
2982 RBinJavaCPTypeObj *obj = NULL;
2983 r_list_free (bin->imports_list);
2984 bin->imports_list = r_list_newf (free);
2985 r_list_foreach (bin->cp_list, iter, obj) {
2986 const char *type = NULL;
2987 switch (obj->tag) {
2988 case R_BIN_JAVA_CP_METHODREF: type = "METHOD"; break;
2989 case R_BIN_JAVA_CP_INTERFACEMETHOD_REF: type = "FIELD"; break;
2990 case R_BIN_JAVA_CP_FIELDREF: type = "INTERFACE_METHOD"; break;
2991 default: type = NULL; break;
2992 }
2993 if (type) {
2994 r_bin_add_import (bin, obj, type);
2995 }
2996 }
2997 }
2998
r_bin_java_get_imports(RBinJavaObj * bin)2999 R_API RList *r_bin_java_get_imports(RBinJavaObj *bin) {
3000 RList *ret = r_list_newf (free);
3001 RBinImport *import = NULL;
3002 RListIter *iter;
3003 r_list_foreach (bin->imports_list, iter, import) {
3004 RBinImport *n_import = R_NEW0 (RBinImport);
3005 if (!n_import) {
3006 r_list_free (ret);
3007 return NULL;
3008 }
3009 memcpy (n_import, import, sizeof (RBinImport));
3010 r_list_append (ret, n_import);
3011 }
3012 return ret;
3013 }
3014
r_bin_java_get_symbols(RBinJavaObj * bin)3015 R_API RList *r_bin_java_get_symbols(RBinJavaObj *bin) {
3016 RListIter *iter = NULL, *iter_tmp = NULL;
3017 RList *imports, *symbols = r_list_newf (free);
3018 RBinSymbol *sym = NULL;
3019 RBinImport *imp;
3020 RBinJavaField *fm_type;
3021 r_list_foreach_safe (bin->methods_list, iter, iter_tmp, fm_type) {
3022 sym = r_bin_java_create_new_symbol_from_field (fm_type, bin->loadaddr);
3023 if (sym) {
3024 r_list_append (symbols, (void *) sym);
3025 }
3026 sym = r_bin_java_create_new_symbol_from_fm_type_meta (fm_type, bin->loadaddr);
3027 if (sym) {
3028 r_list_append (symbols, (void *) sym);
3029 }
3030 }
3031 r_list_foreach_safe (bin->fields_list, iter, iter_tmp, fm_type) {
3032 sym = r_bin_java_create_new_symbol_from_field (fm_type, bin->loadaddr);
3033 if (sym) {
3034 r_list_append (symbols, (void *) sym);
3035 }
3036 sym = r_bin_java_create_new_symbol_from_fm_type_meta (fm_type, bin->loadaddr);
3037 if (sym) {
3038 r_list_append (symbols, (void *) sym);
3039 }
3040 }
3041 bin->lang = "java";
3042 if (bin->cf.major[1] >= 46) {
3043 switch (bin->cf.major[1]) {
3044 static char lang[32];
3045 int langid;
3046 case 46:
3047 case 47:
3048 case 48:
3049 langid = 2 + (bin->cf.major[1] - 46);
3050 snprintf (lang, sizeof (lang) - 1, "java 1.%d", langid);
3051 bin->lang = lang;
3052 break;
3053 default:
3054 langid = 5 + (bin->cf.major[1] - 49);
3055 snprintf (lang, sizeof (lang) - 1, "java %d", langid);
3056 bin->lang = lang;
3057 }
3058 }
3059 imports = r_bin_java_get_imports (bin);
3060 r_list_foreach (imports, iter, imp) {
3061 sym = R_NEW0 (RBinSymbol);
3062 if (!sym) {
3063 break;
3064 }
3065 if (imp->classname && !strncmp (imp->classname, "kotlin/jvm", 10)) {
3066 bin->lang = "kotlin";
3067 }
3068 sym->name = strdup (imp->name);
3069 sym->is_imported = true;
3070 if (!sym->name) {
3071 free (sym);
3072 break;
3073 }
3074 sym->type = "import";
3075 if (!sym->type) {
3076 free (sym);
3077 break;
3078 }
3079 sym->vaddr = sym->paddr = imp->ordinal;
3080 sym->ordinal = imp->ordinal;
3081 r_list_append (symbols, (void *) sym);
3082 }
3083 r_list_free (imports);
3084 return symbols;
3085 }
3086
r_bin_java_get_strings(RBinJavaObj * bin)3087 R_API RList *r_bin_java_get_strings(RBinJavaObj *bin) {
3088 RList *strings = r_list_newf (free);
3089 RBinString *str = NULL;
3090 RListIter *iter = NULL, *iter_tmp = NULL;
3091 RBinJavaCPTypeObj *cp_obj = NULL;
3092 r_list_foreach_safe (bin->cp_list, iter, iter_tmp, cp_obj) {
3093 if (cp_obj && cp_obj->tag == R_BIN_JAVA_CP_UTF8) {
3094 str = (RBinString *) R_NEW0 (RBinString);
3095 if (str) {
3096 str->paddr = cp_obj->file_offset + bin->loadaddr;
3097 str->ordinal = cp_obj->metas->ord;
3098 str->size = cp_obj->info.cp_utf8.length + 3;
3099 str->length = cp_obj->info.cp_utf8.length;
3100 if (str->size > 0) {
3101 str->string = r_str_ndup ((const char *)
3102 cp_obj->info.cp_utf8.bytes,
3103 R_BIN_JAVA_MAXSTR);
3104 }
3105 r_list_append (strings, (void *) str);
3106 }
3107 }
3108 }
3109 return strings;
3110 }
3111
r_bin_java_free(RBinJavaObj * bin)3112 R_API void *r_bin_java_free(RBinJavaObj *bin) {
3113 char *bin_obj_key = NULL;
3114 if (!bin) {
3115 return NULL;
3116 }
3117 // Delete the bin object from the data base.
3118 bin_obj_key = r_bin_java_build_obj_key (bin);
3119 // if (bin->AllJavaBinObjs && sdb_exists (bin->AllJavaBinObjs, bin_obj_key)) {
3120 // sdb_unset (bin->AllJavaBinObjs, bin_obj_key, 0);
3121 // }
3122 free (bin_obj_key);
3123 r_list_free (bin->imports_list);
3124 // XXX - Need to remove all keys belonging to this class from
3125 // the share meta information sdb.
3126 // TODO e.g. iterate over bin->kv and delete all obj, func, etc. keys
3127 // sdb_free (bin->kv);
3128 // free up the constant pool list
3129 r_list_free (bin->cp_list);
3130 // free up the fields list
3131 r_list_free (bin->fields_list);
3132 // free up methods list
3133 r_list_free (bin->methods_list);
3134 // free up interfaces list
3135 r_list_free (bin->interfaces_list);
3136 r_list_free (bin->attrs_list);
3137 // TODO: XXX if a class list of all inner classes
3138 // are formed then this will need to be updated
3139 free (bin->cf2.flags_str);
3140 free (bin->cf2.this_class_name);
3141 if (bin == R_BIN_JAVA_GLOBAL_BIN) {
3142 R_BIN_JAVA_GLOBAL_BIN = NULL;
3143 }
3144 free (bin->file);
3145 r_str_constpool_fini (&bin->constpool);
3146 free (bin);
3147 return NULL;
3148 }
3149
r_bin_java_new_buf(RBuffer * buf,ut64 loadaddr,Sdb * kv)3150 R_API RBinJavaObj *r_bin_java_new_buf(RBuffer *buf, ut64 loadaddr, Sdb *kv) {
3151 RBinJavaObj *bin = R_NEW0 (RBinJavaObj);
3152 if (!bin) {
3153 return NULL;
3154 }
3155 ut64 tmpsz;
3156 const ut8 *tmp = r_buf_data (buf, &tmpsz);
3157 if (!r_bin_java_new_bin (bin, loadaddr, kv, tmp, tmpsz)) {
3158 return r_bin_java_free (bin);
3159 }
3160 return bin;
3161 }
3162
r_bin_java_attribute_free(void * a)3163 R_API void r_bin_java_attribute_free(void /*RBinJavaAttrInfo*/ *a) {
3164 RBinJavaAttrInfo *attr = a;
3165 if (attr) {
3166 IFDBG eprintf("Deleting attr %s, %p\n", attr->name, attr);
3167 if (attr && attr->metas && attr->metas->type_info) {
3168 RBinJavaAttrMetas *a = attr->metas->type_info;
3169 if (a && a->allocs && a->allocs->delete_obj) {
3170 a->allocs->delete_obj (attr);
3171 }
3172 }
3173 // free (attr->metas);
3174 // free (attr);
3175 }
3176 }
3177
r_bin_java_constant_pool(void * o)3178 R_API void r_bin_java_constant_pool(void /*RBinJavaCPTypeObj*/ *o) {
3179 RBinJavaCPTypeObj *obj = o;
3180 if (obj != &R_BIN_JAVA_NULL_TYPE) {
3181 ((RBinJavaCPTypeMetas *) obj->metas->type_info)->allocs->delete_obj (obj);
3182 }
3183 }
3184
r_bin_java_fmtype_free(void * f)3185 R_API void r_bin_java_fmtype_free(void /*RBinJavaField*/ *f) {
3186 RBinJavaField *fm_type = f;
3187 if (!fm_type) {
3188 return;
3189 }
3190 free (fm_type->descriptor);
3191 free (fm_type->name);
3192 free (fm_type->flags_str);
3193 free (fm_type->class_name);
3194 free (fm_type->metas);
3195 r_list_free (fm_type->attributes);
3196 free (fm_type);
3197 }
3198 // Start Free the various attribute types
r_bin_java_unknown_attr_free(void * a)3199 R_API void r_bin_java_unknown_attr_free(void /*RBinJavaAttrInfo*/ *a) {
3200 RBinJavaAttrInfo *attr = a;
3201 if (attr) {
3202 free (attr->name);
3203 free (attr->metas);
3204 free (attr);
3205 }
3206 }
3207
r_bin_java_local_variable_table_attr_entry_free(void * a)3208 R_API void r_bin_java_local_variable_table_attr_entry_free(void /*RBinJavaLocalVariableAttribute*/ *a) {
3209 RBinJavaLocalVariableAttribute *lvattr = a;
3210 if (lvattr) {
3211 free (lvattr->descriptor);
3212 free (lvattr->name);
3213 free (lvattr);
3214 }
3215 }
3216
r_bin_java_local_variable_table_attr_free(void * a)3217 R_API void r_bin_java_local_variable_table_attr_free(void /*RBinJavaAttrInfo*/ *a) {
3218 RBinJavaAttrInfo *attr = a;
3219 if (attr) {
3220 free (attr->name);
3221 free (attr->metas);
3222 r_list_free (attr->info.local_variable_table_attr.local_variable_table);
3223 free (attr);
3224 }
3225 }
3226
r_bin_java_local_variable_type_table_attr_entry_free(void * a)3227 R_API void r_bin_java_local_variable_type_table_attr_entry_free(void /*RBinJavaLocalVariableTypeAttribute*/ *a) {
3228 RBinJavaLocalVariableTypeAttribute *attr = a;
3229 if (attr) {
3230 free (attr->name);
3231 free (attr->signature);
3232 free (attr);
3233 }
3234 }
3235
r_bin_java_local_variable_type_table_attr_free(void * a)3236 R_API void r_bin_java_local_variable_type_table_attr_free(void /*RBinJavaAttrInfo*/ *a) {
3237 RBinJavaAttrInfo *attr = a;
3238 if (attr) {
3239 free (attr->name);
3240 free (attr->metas);
3241 r_list_free (attr->info.local_variable_type_table_attr.local_variable_table);
3242 free (attr);
3243 }
3244 }
3245
r_bin_java_deprecated_attr_free(void * a)3246 R_API void r_bin_java_deprecated_attr_free(void /*RBinJavaAttrInfo*/ *a) {
3247 RBinJavaAttrInfo *attr = a;
3248 if (attr) {
3249 free (attr->name);
3250 free (attr->metas);
3251 free (attr);
3252 }
3253 }
3254
r_bin_java_enclosing_methods_attr_free(void * a)3255 R_API void r_bin_java_enclosing_methods_attr_free(void /*RBinJavaAttrInfo*/ *a) {
3256 RBinJavaAttrInfo *attr = a;
3257 if (attr) {
3258 free (attr->name);
3259 free (attr->metas);
3260 free (attr->info.enclosing_method_attr.class_name);
3261 free (attr->info.enclosing_method_attr.method_name);
3262 free (attr->info.enclosing_method_attr.method_descriptor);
3263 free (attr);
3264 }
3265 }
3266
r_bin_java_synthetic_attr_free(void * a)3267 R_API void r_bin_java_synthetic_attr_free(void /*RBinJavaAttrInfo*/ *a) {
3268 RBinJavaAttrInfo *attr = a;
3269 if (attr) {
3270 free (attr->name);
3271 free (attr->metas);
3272 free (attr);
3273 }
3274 }
3275
r_bin_java_constant_value_attr_free(void * a)3276 R_API void r_bin_java_constant_value_attr_free(void /*RBinJavaAttrInfo*/ *a) {
3277 RBinJavaAttrInfo *attr = a;
3278 if (attr) {
3279 free (attr->name);
3280 free (attr->metas);
3281 free (attr);
3282 }
3283 }
3284
r_bin_java_line_number_table_attr_free(void * a)3285 R_API void r_bin_java_line_number_table_attr_free(void /*RBinJavaAttrInfo*/ *a) {
3286 RBinJavaAttrInfo *attr = a;
3287 if (attr) {
3288 free (attr->name);
3289 free (attr->metas);
3290 r_list_free (attr->info.line_number_table_attr.line_number_table);
3291 free (attr);
3292 }
3293 }
3294
r_bin_java_code_attr_free(void * a)3295 R_API void r_bin_java_code_attr_free(void /*RBinJavaAttrInfo*/ *a) {
3296 RBinJavaAttrInfo *attr = a;
3297 if (attr) {
3298 // XXX - Intentional memory leak here. When one of the
3299 // Code attributes is parsed, the code (the r_bin_java)
3300 // is not properly parsing the class file
3301 r_bin_java_stack_frame_free (attr->info.code_attr.implicit_frame);
3302 r_list_free (attr->info.code_attr.attributes);
3303 free (attr->info.code_attr.code);
3304 r_list_free (attr->info.code_attr.exception_table);
3305 free (attr->name);
3306 free (attr->metas);
3307 free (attr);
3308 }
3309 }
3310
r_bin_java_exceptions_attr_free(void * a)3311 R_API void r_bin_java_exceptions_attr_free(void /*RBinJavaAttrInfo*/ *a) {
3312 RBinJavaAttrInfo *attr = a;
3313 if (attr) {
3314 free (attr->name);
3315 free (attr->metas);
3316 free (attr->info.exceptions_attr.exception_idx_table);
3317 free (attr);
3318 }
3319 }
3320
r_bin_java_inner_classes_attr_entry_free(void * a)3321 R_API void r_bin_java_inner_classes_attr_entry_free(void /*RBinJavaClassesAttribute*/ *a) {
3322 RBinJavaClassesAttribute *attr = a;
3323 if (attr) {
3324 free (attr->name);
3325 free (attr->flags_str);
3326 free (attr);
3327 }
3328 }
3329
r_bin_java_inner_classes_attr_free(void * a)3330 R_API void r_bin_java_inner_classes_attr_free(void /*RBinJavaAttrInfo*/ *a) {
3331 RBinJavaAttrInfo *attr = a;
3332 if (attr) {
3333 free (attr->name);
3334 free (attr->metas);
3335 r_list_free (attr->info.inner_classes_attr.classes);
3336 free (attr);
3337 }
3338 }
3339
r_bin_java_signature_attr_free(void * a)3340 R_API void r_bin_java_signature_attr_free(void /*RBinJavaAttrInfo*/ *a) {
3341 RBinJavaAttrInfo *attr = a;
3342 if (attr) {
3343 free (attr->name);
3344 free (attr->metas);
3345 free (attr->info.signature_attr.signature);
3346 free (attr);
3347 }
3348 }
3349
r_bin_java_source_debug_attr_free(void * a)3350 R_API void r_bin_java_source_debug_attr_free(void /*RBinJavaAttrInfo*/ *a) {
3351 RBinJavaAttrInfo *attr = a;
3352 if (attr) {
3353 free (attr->name);
3354 free (attr->metas);
3355 free (attr->info.debug_extensions.debug_extension);
3356 free (attr);
3357 }
3358 }
3359
r_bin_java_source_code_file_attr_free(void * a)3360 R_API void r_bin_java_source_code_file_attr_free(void /*RBinJavaAttrInfo*/ *a) {
3361 RBinJavaAttrInfo *attr = a;
3362 if (attr) {
3363 free (attr->name);
3364 free (attr->metas);
3365 free (attr);
3366 }
3367 }
3368
r_bin_java_stack_map_table_attr_free(void * a)3369 R_API void r_bin_java_stack_map_table_attr_free(void /*RBinJavaAttrInfo*/ *a) {
3370 RBinJavaAttrInfo *attr = a;
3371 if (attr) {
3372 free (attr->name);
3373 free (attr->metas);
3374 r_list_free (attr->info.stack_map_table_attr.stack_map_frame_entries);
3375 free (attr);
3376 }
3377 }
3378
r_bin_java_stack_frame_free(void * o)3379 R_API void r_bin_java_stack_frame_free(void /*RBinJavaStackMapFrame*/ *o) {
3380 RBinJavaStackMapFrame *obj = o;
3381 if (obj) {
3382 r_list_free (obj->local_items);
3383 r_list_free (obj->stack_items);
3384 free (obj->metas);
3385 free (obj);
3386 }
3387 }
3388
r_bin_java_verification_info_free(void * o)3389 R_API void r_bin_java_verification_info_free(void /*RBinJavaVerificationObj*/ *o) {
3390 RBinJavaVerificationObj *obj = o;
3391 // eprintf ("Freeing verification object\n");
3392 if (obj) {
3393 free (obj->name);
3394 free (obj);
3395 }
3396 }
3397
r_bin_java_interface_free(void * o)3398 R_API void r_bin_java_interface_free(void /*RBinJavaInterfaceInfo*/ *o) {
3399 RBinJavaInterfaceInfo *obj = o;
3400 if (obj) {
3401 free (obj->name);
3402 free (obj);
3403 }
3404 }
3405 // End Free the various attribute types
3406 // Start the various attibute types new
r_bin_java_attr_calc_size(RBinJavaAttrInfo * attr)3407 R_API ut64 r_bin_java_attr_calc_size(RBinJavaAttrInfo *attr) {
3408 return attr ? ((RBinJavaAttrMetas *) attr->metas->type_info)->allocs->calc_size (attr) : 0;
3409 }
3410
r_bin_java_unknown_attr_calc_size(RBinJavaAttrInfo * attr)3411 R_API ut64 r_bin_java_unknown_attr_calc_size(RBinJavaAttrInfo *attr) {
3412 return attr ? 6 : 0;
3413 }
3414
r_bin_java_unknown_attr_new(RBinJavaObj * bin,ut8 * buffer,ut64 sz,ut64 buf_offset)3415 R_API RBinJavaAttrInfo *r_bin_java_unknown_attr_new(RBinJavaObj *bin, ut8 *buffer, ut64 sz, ut64 buf_offset) {
3416 return r_bin_java_default_attr_new (bin, buffer, sz, buf_offset);
3417 }
3418
r_bin_java_code_attr_calc_size(RBinJavaAttrInfo * attr)3419 R_API ut64 r_bin_java_code_attr_calc_size(RBinJavaAttrInfo *attr) {
3420 RListIter *iter;
3421 // RListIter *iter_tmp;
3422 ut64 size = 0;
3423 bool is_attr_in_old_format = attr->is_attr_in_old_format;
3424 if (attr) {
3425 // attr = r_bin_java_default_attr_new (buffer, sz, buf_offset);
3426 size += is_attr_in_old_format ? 4 : 6;
3427 // attr->info.code_attr.max_stack = R_BIN_JAVA_USHORT (buffer, 0);
3428 size += is_attr_in_old_format ? 1 : 2;
3429 // attr->info.code_attr.max_locals = R_BIN_JAVA_USHORT (buffer, 2);
3430 size += is_attr_in_old_format ? 1 : 2;
3431 // attr->info.code_attr.code_length = R_BIN_JAVA_UINT (buffer, 4);
3432 size += is_attr_in_old_format ? 2 : 4;
3433 if (attr->info.code_attr.code) {
3434 size += attr->info.code_attr.code_length;
3435 }
3436 // attr->info.code_attr.exception_table_length = R_BIN_JAVA_USHORT (buffer, offset);
3437 size += 2;
3438 // RBinJavaExceptionEntry *exc_entry;
3439 // r_list_foreach_safe (attr->info.code_attr.exception_table, iter, iter_tmp, exc_entry) {
3440 r_list_foreach_iter (attr->info.code_attr.exception_table, iter) {
3441 // exc_entry->start_pc = R_BIN_JAVA_USHORT (buffer,offset);
3442 size += 2;
3443 // exc_entry->end_pc = R_BIN_JAVA_USHORT (buffer,offset);
3444 size += 2;
3445 // exc_entry->handler_pc = R_BIN_JAVA_USHORT (buffer,offset);
3446 size += 2;
3447 // exc_entry->catch_type = R_BIN_JAVA_USHORT (buffer, offset);
3448 size += 2;
3449 }
3450 // attr->info.code_attr.attributes_count = R_BIN_JAVA_USHORT (buffer, offset);
3451 size += 2;
3452 // RBinJavaAttrInfo *_attr;
3453 if (attr->info.code_attr.attributes_count > 0) {
3454 // r_list_foreach_safe (attr->info.code_attr.attributes, iter, iter_tmp, _attr) {
3455 r_list_foreach_iter (attr->info.code_attr.attributes, iter) {
3456 size += r_bin_java_attr_calc_size (attr);
3457 }
3458 }
3459 }
3460 return size;
3461 }
3462
r_bin_java_code_attr_new(RBinJavaObj * bin,ut8 * buffer,ut64 sz,ut64 buf_offset)3463 R_API RBinJavaAttrInfo *r_bin_java_code_attr_new(RBinJavaObj *bin, ut8 *buffer, ut64 sz, ut64 buf_offset) {
3464 RBinJavaAttrInfo *attr = NULL, *_attr = NULL;
3465 ut32 k = 0, curpos;
3466 ut64 offset = 0;
3467 attr = r_bin_java_default_attr_new (bin, buffer, sz, buf_offset);
3468 if (!attr) {
3469 return NULL;
3470 }
3471 if (sz < 16 || sz > buf_offset) {// sz > buf_offset) {
3472 free (attr);
3473 return NULL;
3474 }
3475 offset += 6;
3476 attr->type = R_BIN_JAVA_ATTR_TYPE_CODE_ATTR;
3477 attr->info.code_attr.max_stack = attr->is_attr_in_old_format ? buffer[offset] : R_BIN_JAVA_USHORT (buffer, offset);
3478 offset += attr->is_attr_in_old_format ? 1 : 2;
3479 attr->info.code_attr.max_locals = attr->is_attr_in_old_format ? buffer[offset] : R_BIN_JAVA_USHORT (buffer, offset);
3480 offset += attr->is_attr_in_old_format ? 1 : 2;
3481 attr->info.code_attr.code_length = attr->is_attr_in_old_format ? R_BIN_JAVA_USHORT(buffer, offset) : R_BIN_JAVA_UINT (buffer, offset);
3482 offset += attr->is_attr_in_old_format ? 2 : 4;
3483 // BUG: possible unsigned integer overflow here
3484 attr->info.code_attr.code_offset = buf_offset + offset;
3485 attr->info.code_attr.code = (ut8 *) malloc (attr->info.code_attr.code_length);
3486 if (!attr->info.code_attr.code) {
3487 eprintf ("Handling Code Attributes: Unable to allocate memory "
3488 "(%u bytes) for a code.\n", attr->info.code_attr.code_length);
3489 return attr;
3490 }
3491 R_BIN_JAVA_GLOBAL_BIN->current_code_attr = attr;
3492 {
3493 int len = attr->info.code_attr.code_length;
3494 memset (attr->info.code_attr.code, 0, len);
3495 if (offset + len >= sz) {
3496 return attr;
3497 }
3498 memcpy (attr->info.code_attr.code, buffer + offset, len);
3499 offset += len;
3500 }
3501 attr->info.code_attr.exception_table_length = R_BIN_JAVA_USHORT (buffer, offset);
3502 offset += 2;
3503 attr->info.code_attr.exception_table = r_list_newf (free);
3504 for (k = 0; k < attr->info.code_attr.exception_table_length; k++) {
3505 curpos = buf_offset + offset;
3506 if (curpos + 8 > sz) {
3507 return attr;
3508 }
3509 RBinJavaExceptionEntry *e = R_NEW0 (RBinJavaExceptionEntry);
3510 if (!e) {
3511 free (attr);
3512 return NULL;
3513 }
3514 e->file_offset = curpos;
3515 e->start_pc = R_BIN_JAVA_USHORT (buffer, offset);
3516 offset += 2;
3517 e->end_pc = R_BIN_JAVA_USHORT (buffer, offset);
3518 offset += 2;
3519 e->handler_pc = R_BIN_JAVA_USHORT (buffer, offset);
3520 offset += 2;
3521 e->catch_type = R_BIN_JAVA_USHORT (buffer, offset);
3522 offset += 2;
3523 r_list_append (attr->info.code_attr.exception_table, e);
3524 e->size = 8;
3525 }
3526 attr->info.code_attr.attributes_count = R_BIN_JAVA_USHORT (buffer, offset);
3527 offset += 2;
3528 // IFDBG eprintf (" code Attributes_count: %d\n", attr->info.code_attr.attributes_count);
3529 // XXX - attr->info.code_attr.attributes is not freed because one of the code attributes is improperly parsed.
3530 attr->info.code_attr.attributes = r_list_newf (r_bin_java_attribute_free);
3531 if (attr->info.code_attr.attributes_count > 0) {
3532 for (k = 0; k < attr->info.code_attr.attributes_count; k++) {
3533 int size = (offset < sz) ? sz - offset : 0;
3534 if (size > sz || size <= 0) {
3535 break;
3536 }
3537 _attr = r_bin_java_read_next_attr_from_buffer (bin, buffer + offset, size, buf_offset + offset);
3538 if (!_attr) {
3539 eprintf ("[X] r_bin_java_code_attr_new: Error unable to parse remainder of classfile after Method's Code Attribute: %d.\n", k);
3540 break;
3541 }
3542 IFDBG eprintf("Parsing @ 0x%"PFMT64x " (%s) = 0x%"PFMT64x " bytes, %p\n", _attr->file_offset, _attr->name, _attr->size, _attr);
3543 offset += _attr->size;
3544 r_list_append (attr->info.code_attr.attributes, _attr);
3545 if (_attr->type == R_BIN_JAVA_ATTR_TYPE_LOCAL_VARIABLE_TABLE_ATTR) {
3546 IFDBG eprintf("Parsed the LocalVariableTable, preparing the implicit mthod frame.\n");
3547 // r_bin_java_print_attr_summary(_attr);
3548 attr->info.code_attr.implicit_frame = r_bin_java_build_stack_frame_from_local_variable_table (R_BIN_JAVA_GLOBAL_BIN, _attr);
3549 attr->info.code_attr.implicit_frame->file_offset = buf_offset;
3550 IFDBG r_bin_java_print_stack_map_frame_summary(attr->info.code_attr.implicit_frame);
3551 // r_list_append (attr->info.code_attr.attributes, attr->info.code_attr.implicit_frame);
3552 }
3553 // if (offset > sz) {
3554 // eprintf ("[X] r_bin_java: Error unable to parse remainder of classfile after Attribute: %d.\n", k);
3555 // break;
3556 // }
3557
3558 }
3559 }
3560 if (attr->info.code_attr.implicit_frame == NULL) {
3561 // build a default implicit_frame
3562 attr->info.code_attr.implicit_frame = r_bin_java_default_stack_frame ();
3563 // r_list_append (attr->info.code_attr.attributes, attr->info.code_attr.implicit_frame);
3564 }
3565 attr->size = offset;
3566 return attr;
3567 }
3568
r_bin_java_constant_value_attr_new(RBinJavaObj * bin,ut8 * buffer,ut64 sz,ut64 buf_offset)3569 R_API RBinJavaAttrInfo *r_bin_java_constant_value_attr_new(RBinJavaObj *bin, ut8 *buffer, ut64 sz, ut64 buf_offset) {
3570 ut64 offset = 6;
3571 RBinJavaAttrInfo *attr = r_bin_java_default_attr_new (bin, buffer, sz, buf_offset);
3572 if (attr) {
3573 attr->type = R_BIN_JAVA_ATTR_TYPE_CONST_VALUE_ATTR;
3574 attr->info.constant_value_attr.constantvalue_idx = R_BIN_JAVA_USHORT (buffer, offset);
3575 offset += 2;
3576 attr->size = offset;
3577 }
3578 // IFDBG r_bin_java_print_constant_value_attr_summary(attr);
3579 return attr;
3580 }
3581
r_bin_java_constant_value_attr_calc_size(RBinJavaAttrInfo * attr)3582 R_API ut64 r_bin_java_constant_value_attr_calc_size(RBinJavaAttrInfo *attr) {
3583 return attr ? 8 : 0;
3584 }
3585
r_bin_java_deprecated_attr_new(RBinJavaObj * bin,ut8 * buffer,ut64 sz,ut64 buf_offset)3586 R_API RBinJavaAttrInfo *r_bin_java_deprecated_attr_new(RBinJavaObj *bin, ut8 *buffer, ut64 sz, ut64 buf_offset) {
3587 RBinJavaAttrInfo *attr = NULL;
3588 ut64 offset = 0;
3589 attr = r_bin_java_default_attr_new (bin, buffer, sz, buf_offset);
3590 offset += 6;
3591 if (attr) {
3592 attr->type = R_BIN_JAVA_ATTR_TYPE_DEPRECATED_ATTR;
3593 attr->size = offset;
3594 }
3595 // IFDBG r_bin_java_print_deprecated_attr_summary(attr);
3596 return attr;
3597 }
3598
r_bin_java_deprecated_attr_calc_size(RBinJavaAttrInfo * attr)3599 R_API ut64 r_bin_java_deprecated_attr_calc_size(RBinJavaAttrInfo *attr) {
3600 return attr ? 6 : 0;
3601 }
3602
r_bin_java_signature_attr_new(RBinJavaObj * bin,ut8 * buffer,ut64 sz,ut64 buf_offset)3603 R_API RBinJavaAttrInfo *r_bin_java_signature_attr_new(RBinJavaObj *bin, ut8 *buffer, ut64 sz, ut64 buf_offset) {
3604 ut64 offset = 6;
3605 RBinJavaAttrInfo *attr = r_bin_java_default_attr_new (bin, buffer, sz, buf_offset);
3606 if (!attr) {
3607 return NULL;
3608 }
3609 attr->type = R_BIN_JAVA_ATTR_TYPE_SIGNATURE_ATTR;
3610 // attr->info.source_file_attr.sourcefile_idx = R_BIN_JAVA_USHORT (buffer, offset);
3611 // offset += 2;
3612 attr->info.signature_attr.signature_idx = R_BIN_JAVA_USHORT (buffer, offset);
3613 offset += 2;
3614 attr->info.signature_attr.signature = r_bin_java_get_utf8_from_bin_cp_list (
3615 R_BIN_JAVA_GLOBAL_BIN, attr->info.signature_attr.signature_idx);
3616 if (!attr->info.signature_attr.signature) {
3617 eprintf ("r_bin_java_signature_attr_new: Unable to resolve the "
3618 "Signature UTF8 String Index: 0x%02x\n", attr->info.signature_attr.signature_idx);
3619 }
3620 attr->size = offset;
3621 // IFDBG r_bin_java_print_source_code_file_attr_summary(attr);
3622 return attr;
3623 }
3624
r_bin_java_signature_attr_calc_size(RBinJavaAttrInfo * attr)3625 R_API ut64 r_bin_java_signature_attr_calc_size(RBinJavaAttrInfo *attr) {
3626 ut64 size = 0;
3627 if (attr == NULL) {
3628 // TODO eprintf allocation fail
3629 return size;
3630 }
3631 size += 6;
3632 // attr->info.source_file_attr.sourcefile_idx = R_BIN_JAVA_USHORT (buffer, offset);
3633 size += 2;
3634 // attr->info.signature_attr.signature_idx = R_BIN_JAVA_USHORT (buffer, offset);
3635 size += 2;
3636 return size;
3637 }
3638
r_bin_java_enclosing_methods_attr_new(RBinJavaObj * bin,ut8 * buffer,ut64 sz,ut64 buf_offset)3639 R_API RBinJavaAttrInfo *r_bin_java_enclosing_methods_attr_new(RBinJavaObj *bin, ut8 *buffer, ut64 sz, ut64 buf_offset) {
3640 ut64 offset = 6;
3641 RBinJavaAttrInfo *attr = r_bin_java_default_attr_new (bin, buffer, sz, buf_offset);
3642 if (!attr || sz < 10) {
3643 free (attr);
3644 return NULL;
3645 }
3646 attr->type = R_BIN_JAVA_ATTR_TYPE_ENCLOSING_METHOD_ATTR;
3647 attr->info.enclosing_method_attr.class_idx = R_BIN_JAVA_USHORT (buffer, offset);
3648 offset += 2;
3649 attr->info.enclosing_method_attr.method_idx = R_BIN_JAVA_USHORT (buffer, offset);
3650 offset += 2;
3651 attr->info.enclosing_method_attr.class_name = r_bin_java_get_name_from_bin_cp_list (R_BIN_JAVA_GLOBAL_BIN, attr->info.enclosing_method_attr.class_idx);
3652 if (attr->info.enclosing_method_attr.class_name == NULL) {
3653 eprintf ("Could not resolve enclosing class name for the enclosed method.\n");
3654 }
3655 attr->info.enclosing_method_attr.method_name = r_bin_java_get_name_from_bin_cp_list (R_BIN_JAVA_GLOBAL_BIN, attr->info.enclosing_method_attr.method_idx);
3656 if (attr->info.enclosing_method_attr.class_name == NULL) {
3657 eprintf ("Could not resolve method descriptor for the enclosed method.\n");
3658 }
3659 attr->info.enclosing_method_attr.method_descriptor = r_bin_java_get_desc_from_bin_cp_list (R_BIN_JAVA_GLOBAL_BIN, attr->info.enclosing_method_attr.method_idx);
3660 if (attr->info.enclosing_method_attr.method_name == NULL) {
3661 eprintf ("Could not resolve method name for the enclosed method.\n");
3662 }
3663 attr->size = offset;
3664 return attr;
3665 }
3666
r_bin_java_enclosing_methods_attr_calc_size(RBinJavaAttrInfo * attr)3667 R_API ut64 r_bin_java_enclosing_methods_attr_calc_size(RBinJavaAttrInfo *attr) {
3668 ut64 size = 0;
3669 if (attr) {
3670 size += 6;
3671 // attr->info.enclosing_method_attr.class_idx = R_BIN_JAVA_USHORT (buffer, offset);
3672 size += 2;
3673 // attr->info.enclosing_method_attr.method_idx = R_BIN_JAVA_USHORT (buffer, offset);
3674 size += 2;
3675 }
3676 return size;
3677 }
3678
r_bin_java_exceptions_attr_new(RBinJavaObj * bin,ut8 * buffer,ut64 sz,ut64 buf_offset)3679 R_API RBinJavaAttrInfo *r_bin_java_exceptions_attr_new(RBinJavaObj *bin, ut8 *buffer, ut64 sz, ut64 buf_offset) {
3680 ut32 i = 0, offset = 0;
3681 ut64 size;
3682 RBinJavaAttrInfo *attr = NULL;
3683 if (sz < 8) {
3684 return NULL;
3685 }
3686 attr = r_bin_java_default_attr_new (bin, buffer, sz, buf_offset);
3687 offset += 6;
3688 if (!attr) {
3689 return attr;
3690 }
3691 attr->type = R_BIN_JAVA_ATTR_TYPE_LINE_NUMBER_TABLE_ATTR;
3692 attr->info.exceptions_attr.number_of_exceptions = R_BIN_JAVA_USHORT (buffer, offset);
3693 offset += 2;
3694 size = sizeof (ut16) * attr->info.exceptions_attr.number_of_exceptions;
3695 if (size < attr->info.exceptions_attr.number_of_exceptions) {
3696 free (attr);
3697 return NULL;
3698 }
3699 attr->info.exceptions_attr.exception_idx_table = (ut16 *) malloc (size);
3700 if (!attr->info.exceptions_attr.exception_idx_table) {
3701 free (attr);
3702 return NULL;
3703 }
3704 for (i = 0; i < attr->info.exceptions_attr.number_of_exceptions; i++) {
3705 if (offset + 2 > sz) {
3706 break;
3707 }
3708 attr->info.exceptions_attr.exception_idx_table[i] = R_BIN_JAVA_USHORT (buffer, offset);
3709 offset += 2;
3710 }
3711 attr->size = offset;
3712 // IFDBG r_bin_java_print_exceptions_attr_summary(attr);
3713 return attr;
3714 }
3715
r_bin_java_exceptions_attr_calc_size(RBinJavaAttrInfo * attr)3716 R_API ut64 r_bin_java_exceptions_attr_calc_size(RBinJavaAttrInfo *attr) {
3717 ut64 size = 0, i = 0;
3718 if (attr) {
3719 size += 6;
3720 for (i = 0; i < attr->info.exceptions_attr.number_of_exceptions; i++) {
3721 // attr->info.exceptions_attr.exception_idx_table[i] = R_BIN_JAVA_USHORT (buffer, offset);
3722 size += 2;
3723 }
3724 }
3725 return size;
3726 }
3727
r_bin_java_inner_classes_attr_new(RBinJavaObj * bin,ut8 * buffer,ut64 sz,ut64 buf_offset)3728 R_API RBinJavaAttrInfo *r_bin_java_inner_classes_attr_new(RBinJavaObj *bin, ut8 *buffer, ut64 sz, ut64 buf_offset) {
3729 RBinJavaClassesAttribute *icattr;
3730 RBinJavaAttrInfo *attr = NULL;
3731 RBinJavaCPTypeObj *obj;
3732 ut32 i = 0;
3733 ut64 offset = 0, curpos;
3734 attr = r_bin_java_default_attr_new (bin, buffer, sz, buf_offset);
3735 offset += 6;
3736 if (attr == NULL) {
3737 // TODO eprintf
3738 return attr;
3739 }
3740 attr->type = R_BIN_JAVA_ATTR_TYPE_INNER_CLASSES_ATTR;
3741 attr->info.inner_classes_attr.number_of_classes = R_BIN_JAVA_USHORT (buffer, offset);
3742 offset += 2;
3743 attr->info.inner_classes_attr.classes = r_list_newf (r_bin_java_inner_classes_attr_entry_free);
3744 for (i = 0; i < attr->info.inner_classes_attr.number_of_classes; i++) {
3745 curpos = buf_offset + offset;
3746 if (offset + 8 > sz) {
3747 eprintf ("Invalid amount of inner classes\n");
3748 break;
3749 }
3750 icattr = R_NEW0 (RBinJavaClassesAttribute);
3751 if (!icattr) {
3752 break;
3753 }
3754 icattr->inner_class_info_idx = R_BIN_JAVA_USHORT (buffer, offset);
3755 offset += 2;
3756 icattr->outer_class_info_idx = R_BIN_JAVA_USHORT (buffer, offset);
3757 offset += 2;
3758 icattr->inner_name_idx = R_BIN_JAVA_USHORT (buffer, offset);
3759 offset += 2;
3760 icattr->inner_class_access_flags = R_BIN_JAVA_USHORT (buffer, offset);
3761 offset += 2;
3762 icattr->flags_str = retrieve_class_method_access_string (icattr->inner_class_access_flags);
3763 icattr->file_offset = curpos;
3764 icattr->size = 8;
3765
3766 obj = r_bin_java_get_item_from_bin_cp_list (R_BIN_JAVA_GLOBAL_BIN, icattr->inner_name_idx);
3767 if (obj == NULL) {
3768 eprintf ("BINCPLIS IS HULL %d\n", icattr->inner_name_idx);
3769 }
3770 icattr->name = r_bin_java_get_item_name_from_bin_cp_list (R_BIN_JAVA_GLOBAL_BIN, obj);
3771 if (!icattr->name) {
3772 obj = r_bin_java_get_item_from_bin_cp_list (R_BIN_JAVA_GLOBAL_BIN, icattr->inner_class_info_idx);
3773 if (!obj) {
3774 eprintf ("BINCPLIST IS NULL %d\n", icattr->inner_class_info_idx);
3775 }
3776 icattr->name = r_bin_java_get_item_name_from_bin_cp_list (R_BIN_JAVA_GLOBAL_BIN, obj);
3777 if (!icattr->name) {
3778 icattr->name = r_str_dup (NULL, "NULL");
3779 eprintf ("r_bin_java_inner_classes_attr: Unable to find the name for %d index.\n", icattr->inner_name_idx);
3780 free (icattr);
3781 break;
3782 }
3783 }
3784
3785 IFDBG eprintf("r_bin_java_inner_classes_attr: Inner class name %d is %s.\n", icattr->inner_name_idx, icattr->name);
3786 r_list_append (attr->info.inner_classes_attr.classes, (void *) icattr);
3787 }
3788 attr->size = offset;
3789 // IFDBG r_bin_java_print_inner_classes_attr_summary(attr);
3790 return attr;
3791 }
3792
r_bin_java_inner_class_attr_calc_size(RBinJavaClassesAttribute * icattr)3793 R_API ut64 r_bin_java_inner_class_attr_calc_size(RBinJavaClassesAttribute *icattr) {
3794 ut64 size = 0;
3795 if (icattr) {
3796 // icattr->inner_class_info_idx = R_BIN_JAVA_USHORT (buffer, offset);
3797 size += 2;
3798 // icattr->outer_class_info_idx = R_BIN_JAVA_USHORT (buffer, offset);
3799 size += 2;
3800 // icattr->inner_name_idx = R_BIN_JAVA_USHORT (buffer, offset);
3801 size += 2;
3802 // icattr->inner_class_access_flags = R_BIN_JAVA_USHORT (buffer, offset);
3803 size += 2;
3804 }
3805 return size;
3806 }
3807
r_bin_java_inner_classes_attr_calc_size(RBinJavaAttrInfo * attr)3808 R_API ut64 r_bin_java_inner_classes_attr_calc_size(RBinJavaAttrInfo *attr) {
3809 RBinJavaClassesAttribute *icattr = NULL;
3810 RListIter *iter;
3811 ut64 size = 6;
3812 if (!attr) {
3813 return 0;
3814 }
3815 r_list_foreach (attr->info.inner_classes_attr.classes, iter, icattr) {
3816 size += r_bin_java_inner_class_attr_calc_size (icattr);
3817 }
3818 return size;
3819 }
3820
r_bin_java_line_number_table_attr_new(RBinJavaObj * bin,ut8 * buffer,ut64 sz,ut64 buf_offset)3821 R_API RBinJavaAttrInfo *r_bin_java_line_number_table_attr_new(RBinJavaObj *bin, ut8 *buffer, ut64 sz, ut64 buf_offset) {
3822 ut32 i = 0;
3823 ut64 curpos, offset = 0;
3824 RBinJavaLineNumberAttribute *lnattr;
3825 if (sz < 6) {
3826 return NULL;
3827 }
3828 RBinJavaAttrInfo *attr = r_bin_java_default_attr_new (bin, buffer, sz, buf_offset);
3829 if (!attr) {
3830 return NULL;
3831 }
3832 offset += 6;
3833 attr->type = R_BIN_JAVA_ATTR_TYPE_LINE_NUMBER_TABLE_ATTR;
3834 attr->info.line_number_table_attr.line_number_table_length = R_BIN_JAVA_USHORT (buffer, offset);
3835 offset += 2;
3836 attr->info.line_number_table_attr.line_number_table = r_list_newf (free);
3837
3838 ut32 linenum_len = attr->info.line_number_table_attr.line_number_table_length;
3839 RList *linenum_list = attr->info.line_number_table_attr.line_number_table;
3840 for (i = 0; i < linenum_len; i++) {
3841 curpos = buf_offset + offset;
3842 // printf ("%llx %llx \n", curpos, sz);
3843 // XXX if (curpos + 8 >= sz) break;
3844 lnattr = R_NEW0 (RBinJavaLineNumberAttribute);
3845 if (!lnattr) {
3846 break;
3847 }
3848 // wtf it works
3849 if (offset - 2 > sz) {
3850 R_FREE (lnattr);
3851 break;
3852 }
3853 lnattr->start_pc = R_BIN_JAVA_USHORT (buffer, offset);
3854 offset += 2;
3855 lnattr->line_number = R_BIN_JAVA_USHORT (buffer, offset);
3856 offset += 2;
3857 lnattr->file_offset = curpos;
3858 lnattr->size = 4;
3859 r_list_append (linenum_list, lnattr);
3860 }
3861 attr->size = offset;
3862 return attr;
3863 }
3864
r_bin_java_line_number_table_attr_calc_size(RBinJavaAttrInfo * attr)3865 R_API ut64 r_bin_java_line_number_table_attr_calc_size(RBinJavaAttrInfo *attr) {
3866 ut64 size = 6;
3867 // RBinJavaLineNumberAttribute *lnattr;
3868 RListIter *iter;
3869 // RListIter *iter_tmp;
3870 if (!attr) {
3871 return 0LL;
3872 }
3873 // r_list_foreach_safe (attr->info.line_number_table_attr.line_number_table, iter, iter_tmp, lnattr) {
3874 r_list_foreach_iter (attr->info.line_number_table_attr.line_number_table, iter) {
3875 // lnattr->start_pc = R_BIN_JAVA_USHORT (buffer, offset);
3876 size += 2;
3877 // lnattr->line_number = R_BIN_JAVA_USHORT (buffer, offset);
3878 size += 2;
3879 }
3880 return size;
3881 }
3882
r_bin_java_source_debug_attr_new(RBinJavaObj * bin,ut8 * buffer,ut64 sz,ut64 buf_offset)3883 R_API RBinJavaAttrInfo *r_bin_java_source_debug_attr_new(RBinJavaObj *bin, ut8 *buffer, ut64 sz, ut64 buf_offset) {
3884 ut64 offset = 6;
3885 RBinJavaAttrInfo *attr = r_bin_java_default_attr_new (bin, buffer, sz, buf_offset);
3886 if (!attr) {
3887 return NULL;
3888 }
3889 attr->type = R_BIN_JAVA_ATTR_TYPE_SOURCE_DEBUG_EXTENTSION_ATTR;
3890 if (attr->length == 0) {
3891 eprintf ("r_bin_java_source_debug_attr_new: Attempting to allocate 0 bytes for debug_extension.\n");
3892 attr->info.debug_extensions.debug_extension = NULL;
3893 return attr;
3894 } else if ((attr->length + offset) > sz) {
3895 eprintf ("r_bin_java_source_debug_attr_new: Expected %d byte(s) got %"
3896 PFMT64d " bytes for debug_extension.\n", attr->length, (offset + sz));
3897 }
3898 attr->info.debug_extensions.debug_extension = (ut8 *) malloc (attr->length);
3899 if (attr->info.debug_extensions.debug_extension && (attr->length > (sz - offset))) {
3900 memcpy (attr->info.debug_extensions.debug_extension, buffer + offset, sz - offset);
3901 } else if (attr->info.debug_extensions.debug_extension) {
3902 memcpy (attr->info.debug_extensions.debug_extension, buffer + offset, attr->length);
3903 } else {
3904 eprintf ("r_bin_java_source_debug_attr_new: Unable to allocate the data for the debug_extension.\n");
3905 }
3906 offset += attr->length;
3907 attr->size = offset;
3908 return attr;
3909 }
3910
r_bin_java_source_debug_attr_calc_size(RBinJavaAttrInfo * attr)3911 R_API ut64 r_bin_java_source_debug_attr_calc_size(RBinJavaAttrInfo *attr) {
3912 ut64 size = 6;
3913 if (!attr) {
3914 return 0LL;
3915 }
3916 if (attr->info.debug_extensions.debug_extension) {
3917 size += attr->length;
3918 }
3919 return size;
3920 }
3921
r_bin_java_local_variable_table_attr_calc_size(RBinJavaAttrInfo * attr)3922 R_API ut64 r_bin_java_local_variable_table_attr_calc_size(RBinJavaAttrInfo *attr) {
3923 ut64 size = 0;
3924 // ut64 offset = 0;
3925 RListIter *iter;
3926 // RBinJavaLocalVariableAttribute *lvattr;
3927 if (!attr) {
3928 return 0LL;
3929 }
3930 size += 6;
3931 // attr->info.local_variable_table_attr.table_length = R_BIN_JAVA_USHORT (buffer, offset);
3932 size += 2;
3933 // r_list_foreach (attr->info.local_variable_table_attr.local_variable_table, iter, lvattr) {
3934 r_list_foreach_iter (attr->info.local_variable_table_attr.local_variable_table, iter) {
3935 // lvattr->start_pc = R_BIN_JAVA_USHORT (buffer, offset);
3936 size += 2;
3937 // lvattr->length = R_BIN_JAVA_USHORT (buffer, offset);
3938 size += 2;
3939 // lvattr->name_idx = R_BIN_JAVA_USHORT (buffer, offset);
3940 size += 2;
3941 // lvattr->descriptor_idx = R_BIN_JAVA_USHORT (buffer, offset);
3942 size += 2;
3943 // lvattr->index = R_BIN_JAVA_USHORT (buffer, offset);
3944 size += 2;
3945 }
3946 return size;
3947 }
3948
r_bin_java_local_variable_table_attr_new(RBinJavaObj * bin,ut8 * buffer,ut64 sz,ut64 buf_offset)3949 R_API RBinJavaAttrInfo *r_bin_java_local_variable_table_attr_new(RBinJavaObj *bin, ut8 *buffer, ut64 sz, ut64 buf_offset) {
3950 RBinJavaLocalVariableAttribute *lvattr;
3951 ut64 curpos = 0, offset = 6;
3952 RBinJavaAttrInfo *attr;
3953 ut32 i = 0;
3954 if (!buffer || sz < 1) {
3955 return NULL;
3956 }
3957 attr = r_bin_java_default_attr_new (bin, buffer, sz, buf_offset);
3958 if (!attr) {
3959 return NULL;
3960 }
3961 attr->type = R_BIN_JAVA_ATTR_TYPE_LOCAL_VARIABLE_TABLE_ATTR;
3962 attr->info.local_variable_table_attr.table_length = R_BIN_JAVA_USHORT (buffer, offset);
3963 offset += 2;
3964 attr->info.local_variable_table_attr.local_variable_table =\
3965 r_list_newf (r_bin_java_local_variable_table_attr_entry_free);
3966 for (i = 0; i < attr->info.local_variable_table_attr.table_length; i++) {
3967 if (offset + 10 > sz) {
3968 break;
3969 }
3970 curpos = buf_offset + offset;
3971 lvattr = R_NEW0 (RBinJavaLocalVariableAttribute);
3972 lvattr->start_pc = R_BIN_JAVA_USHORT (buffer, offset);
3973 offset += 2;
3974 lvattr->length = R_BIN_JAVA_USHORT (buffer, offset);
3975 offset += 2;
3976 lvattr->name_idx = R_BIN_JAVA_USHORT (buffer, offset);
3977 offset += 2;
3978 lvattr->descriptor_idx = R_BIN_JAVA_USHORT (buffer, offset);
3979 offset += 2;
3980 lvattr->index = R_BIN_JAVA_USHORT (buffer, offset);
3981 offset += 2;
3982 lvattr->file_offset = curpos;
3983 lvattr->name = r_bin_java_get_utf8_from_bin_cp_list (R_BIN_JAVA_GLOBAL_BIN, lvattr->name_idx);
3984 lvattr->size = 10;
3985 if (!lvattr->name) {
3986 lvattr->name = strdup ("NULL");
3987 eprintf ("r_bin_java_local_variable_table_attr_new: Unable to find the name for %d index.\n", lvattr->name_idx);
3988 }
3989 lvattr->descriptor = r_bin_java_get_utf8_from_bin_cp_list (R_BIN_JAVA_GLOBAL_BIN, lvattr->descriptor_idx);
3990 if (!lvattr->descriptor) {
3991 lvattr->descriptor = strdup ("NULL");
3992 eprintf ("r_bin_java_local_variable_table_attr_new: Unable to find the descriptor for %d index.\n", lvattr->descriptor_idx);
3993 }
3994 r_list_append (attr->info.local_variable_table_attr.local_variable_table, lvattr);
3995 }
3996 attr->size = offset;
3997 // IFDBG r_bin_java_print_local_variable_table_attr_summary(attr);
3998 return attr;
3999 }
4000
r_bin_java_local_variable_type_table_attr_calc_size(RBinJavaAttrInfo * attr)4001 R_API ut64 r_bin_java_local_variable_type_table_attr_calc_size(RBinJavaAttrInfo *attr) {
4002 // RBinJavaLocalVariableTypeAttribute *lvattr;
4003 RListIter *iter;
4004 ut64 size = 0;
4005 if (attr) {
4006 RList *list = attr->info.local_variable_type_table_attr.local_variable_table;
4007 size += 6;
4008 // attr->info.local_variable_type_table_attr.table_length = R_BIN_JAVA_USHORT (buffer, offset);
4009 size += 2;
4010 // r_list_foreach (list, iter, lvattr) {
4011 r_list_foreach_iter (list, iter) {
4012 // lvattr->start_pc = R_BIN_JAVA_USHORT (buffer, offset);
4013 size += 2;
4014 // lvattr->length = R_BIN_JAVA_USHORT (buffer, offset);
4015 size += 2;
4016 // lvattr->name_idx = R_BIN_JAVA_USHORT (buffer, offset);
4017 size += 2;
4018 // lvattr->signature_idx = R_BIN_JAVA_USHORT (buffer, offset);
4019 size += 2;
4020 // lvattr->index = R_BIN_JAVA_USHORT (buffer, offset);
4021 size += 2;
4022 }
4023 }
4024 return size;
4025 }
4026
r_bin_java_local_variable_type_table_attr_new(RBinJavaObj * bin,ut8 * buffer,ut64 sz,ut64 buf_offset)4027 R_API RBinJavaAttrInfo *r_bin_java_local_variable_type_table_attr_new(RBinJavaObj *bin, ut8 *buffer, ut64 sz, ut64 buf_offset) {
4028 RBinJavaLocalVariableTypeAttribute *lvattr;
4029 ut64 offset = 6;
4030 ut32 i = 0;
4031 RBinJavaAttrInfo *attr = r_bin_java_default_attr_new (bin, buffer, sz, 0);
4032 if (!attr) {
4033 return NULL;
4034 }
4035 attr->type = R_BIN_JAVA_ATTR_TYPE_LOCAL_VARIABLE_TYPE_TABLE_ATTR;
4036 attr->info.local_variable_type_table_attr.table_length = R_BIN_JAVA_USHORT (buffer, offset);
4037 offset += 2;
4038 attr->info.local_variable_type_table_attr.local_variable_table = r_list_newf (r_bin_java_local_variable_type_table_attr_entry_free);
4039 for (i = 0; i < attr->info.local_variable_type_table_attr.table_length; i++) {
4040 ut64 curpos = buf_offset + offset;
4041 lvattr = R_NEW0 (RBinJavaLocalVariableTypeAttribute);
4042 if (!lvattr) {
4043 perror ("calloc");
4044 break;
4045 }
4046 if (offset + 10 > sz) {
4047 eprintf ("oob");
4048 free (lvattr);
4049 break;
4050 }
4051 lvattr->start_pc = R_BIN_JAVA_USHORT (buffer, offset);
4052 offset += 2;
4053 lvattr->length = R_BIN_JAVA_USHORT (buffer, offset);
4054 offset += 2;
4055 lvattr->name_idx = R_BIN_JAVA_USHORT (buffer, offset);
4056 offset += 2;
4057 lvattr->signature_idx = R_BIN_JAVA_USHORT (buffer, offset);
4058 offset += 2;
4059 lvattr->index = R_BIN_JAVA_USHORT (buffer, offset);
4060 offset += 2;
4061 lvattr->file_offset = curpos;
4062 lvattr->name = r_bin_java_get_utf8_from_bin_cp_list (R_BIN_JAVA_GLOBAL_BIN, lvattr->name_idx);
4063 lvattr->size = 10;
4064 if (!lvattr->name) {
4065 lvattr->name = strdup ("NULL");
4066 eprintf ("r_bin_java_local_variable_type_table_attr_new: Unable to find the name for %d index.\n", lvattr->name_idx);
4067 }
4068 lvattr->signature = r_bin_java_get_utf8_from_bin_cp_list (R_BIN_JAVA_GLOBAL_BIN, lvattr->signature_idx);
4069 if (!lvattr->signature) {
4070 lvattr->signature = strdup ("NULL");
4071 eprintf ("r_bin_java_local_variable_type_table_attr_new: Unable to find the descriptor for %d index.\n", lvattr->signature_idx);
4072 }
4073 r_list_append (attr->info.local_variable_type_table_attr.local_variable_table, lvattr);
4074 }
4075 // IFDBG r_bin_java_print_local_variable_type_table_attr_summary(attr);
4076 attr->size = offset;
4077 return attr;
4078 }
4079
r_bin_java_source_code_file_attr_new(RBinJavaObj * bin,ut8 * buffer,ut64 sz,ut64 buf_offset)4080 R_API RBinJavaAttrInfo *r_bin_java_source_code_file_attr_new(RBinJavaObj *bin, ut8 *buffer, ut64 sz, ut64 buf_offset) {
4081 if (!sz) {
4082 return NULL;
4083 }
4084 ut64 offset = 0;
4085 RBinJavaAttrInfo *attr = r_bin_java_default_attr_new (bin, buffer, sz, buf_offset);
4086 offset += 6;
4087 if (!attr) {
4088 return NULL;
4089 }
4090 attr->type = R_BIN_JAVA_ATTR_TYPE_SOURCE_FILE_ATTR;
4091 // if (buffer + offset > buffer + sz) return NULL;
4092 attr->info.source_file_attr.sourcefile_idx = R_BIN_JAVA_USHORT (buffer, offset);
4093 offset += 2;
4094 attr->size = offset;
4095 // IFDBG r_bin_java_print_source_code_file_attr_summary(attr);
4096 return attr;
4097 }
4098
r_bin_java_source_code_file_attr_calc_size(RBinJavaAttrInfo * attr)4099 R_API ut64 r_bin_java_source_code_file_attr_calc_size(RBinJavaAttrInfo *attr) {
4100 return attr ? 8 : 0;
4101 }
4102
r_bin_java_synthetic_attr_new(RBinJavaObj * bin,ut8 * buffer,ut64 sz,ut64 buf_offset)4103 R_API RBinJavaAttrInfo *r_bin_java_synthetic_attr_new(RBinJavaObj *bin, ut8 *buffer, ut64 sz, ut64 buf_offset) {
4104 ut64 offset = 0;
4105 RBinJavaAttrInfo *attr = r_bin_java_default_attr_new (bin, buffer, sz, buf_offset);
4106 if (!attr) {
4107 return NULL;
4108 }
4109 offset += 6;
4110 attr->type = R_BIN_JAVA_ATTR_TYPE_SYNTHETIC_ATTR;
4111 attr->size = offset;
4112 return attr;
4113 }
4114
r_bin_java_synthetic_attr_calc_size(RBinJavaAttrInfo * attr)4115 R_API ut64 r_bin_java_synthetic_attr_calc_size(RBinJavaAttrInfo *attr) {
4116 return attr ? 12 : 6;
4117 }
4118
r_bin_java_interface_new(RBinJavaObj * bin,const ut8 * buffer,ut64 sz)4119 R_API RBinJavaInterfaceInfo *r_bin_java_interface_new(RBinJavaObj *bin, const ut8 *buffer, ut64 sz) {
4120 RBinJavaInterfaceInfo *ifobj = NULL;
4121 ifobj = R_NEW0 (RBinJavaInterfaceInfo);
4122 IFDBG eprintf("Parsing RBinJavaInterfaceInfo\n");
4123 if (ifobj) {
4124 if (buffer) {
4125 ifobj->class_info_idx = R_BIN_JAVA_USHORT (buffer, 0);
4126 ifobj->cp_class = r_bin_java_get_item_from_bin_cp_list (bin, ifobj->class_info_idx);
4127 if (ifobj->cp_class) {
4128 ifobj->name = r_bin_java_get_item_name_from_bin_cp_list (bin, ifobj->cp_class);
4129 } else {
4130 ifobj->name = r_str_dup (NULL, "NULL");
4131 }
4132 ifobj->size = 2;
4133 } else {
4134 ifobj->class_info_idx = 0;
4135 ifobj->name = r_str_dup (NULL, "NULL");
4136 }
4137 }
4138 return ifobj;
4139 }
4140
r_bin_java_verification_info_from_type(RBinJavaObj * bin,R_BIN_JAVA_STACKMAP_TYPE type,ut32 value)4141 R_API RBinJavaVerificationObj *r_bin_java_verification_info_from_type(RBinJavaObj *bin, R_BIN_JAVA_STACKMAP_TYPE type, ut32 value) {
4142 RBinJavaVerificationObj *se = R_NEW0 (RBinJavaVerificationObj);
4143 if (!se) {
4144 return NULL;
4145 }
4146 se->tag = type;
4147 if (se->tag == R_BIN_JAVA_STACKMAP_OBJECT) {
4148 se->info.obj_val_cp_idx = (ut16) value;
4149 } else if (se->tag == R_BIN_JAVA_STACKMAP_UNINIT) {
4150 /*if (bin->offset_sz == 4) {
4151 se->info.uninit_offset = value;
4152 } else {
4153 se->info.uninit_offset = (ut16) value;
4154 }*/
4155 se->info.uninit_offset = (ut16) value;
4156 }
4157 return se;
4158 }
4159
r_bin_java_read_from_buffer_verification_info_new(ut8 * buffer,ut64 sz,ut64 buf_offset)4160 R_API RBinJavaVerificationObj *r_bin_java_read_from_buffer_verification_info_new(ut8 *buffer, ut64 sz, ut64 buf_offset) {
4161 ut64 offset = 0;
4162 RBinJavaVerificationObj *se = R_NEW0 (RBinJavaVerificationObj);
4163 if (!se) {
4164 return NULL;
4165 }
4166 se->file_offset = buf_offset;
4167 se->tag = buffer[offset];
4168 offset += 1;
4169 if (se->tag == R_BIN_JAVA_STACKMAP_OBJECT) {
4170 se->info.obj_val_cp_idx = R_BIN_JAVA_USHORT (buffer, offset);
4171 offset += 2;
4172 } else if (se->tag == R_BIN_JAVA_STACKMAP_UNINIT) {
4173 se->info.uninit_offset = R_BIN_JAVA_USHORT (buffer, offset);
4174 offset += 2;
4175 }
4176 if (R_BIN_JAVA_STACKMAP_UNINIT < se->tag) {
4177 r_bin_java_verification_info_free (se);
4178 return NULL;
4179 }
4180 se->size = offset;
4181 return se;
4182 }
4183
rbin_java_verification_info_calc_size(RBinJavaVerificationObj * se)4184 R_API ut64 rbin_java_verification_info_calc_size(RBinJavaVerificationObj *se) {
4185 ut64 sz = 1;
4186 if (!se) {
4187 return 0;
4188 }
4189 // r_buf_read_at (bin->b, offset, (ut8*)(&se->tag), 1)
4190 switch (se->tag) {
4191 case R_BIN_JAVA_STACKMAP_OBJECT:
4192 // r_buf_read_at (bin->b, offset+1, (ut8*)buf, 2)
4193 sz += 2;
4194 break;
4195 case R_BIN_JAVA_STACKMAP_UNINIT:
4196 // r_buf_read_at (bin->b, offset+1, (ut8*)buf, 2)
4197 sz += 2;
4198 break;
4199 }
4200 return sz;
4201 }
4202
r_bin_java_determine_stack_frame_type(ut8 tag)4203 R_API RBinJavaStackMapFrameMetas *r_bin_java_determine_stack_frame_type(ut8 tag) {
4204 ut8 type_value = 0;
4205 if (tag < 64) {
4206 type_value = R_BIN_JAVA_STACK_FRAME_SAME;
4207 } else if (tag < 128) {
4208 type_value = R_BIN_JAVA_STACK_FRAME_SAME_LOCALS_1;
4209 } else if (247 < tag && tag < 251) {
4210 type_value = R_BIN_JAVA_STACK_FRAME_CHOP;
4211 } else if (tag == 251) {
4212 type_value = R_BIN_JAVA_STACK_FRAME_SAME_FRAME_EXTENDED;
4213 } else if (251 < tag && tag < 255) {
4214 type_value = R_BIN_JAVA_STACK_FRAME_APPEND;
4215 } else if (tag == 255) {
4216 type_value = R_BIN_JAVA_STACK_FRAME_FULL_FRAME;
4217 } else {
4218 type_value = R_BIN_JAVA_STACK_FRAME_RESERVED;
4219 }
4220 return &R_BIN_JAVA_STACK_MAP_FRAME_METAS[type_value];
4221 }
4222
r_bin_java_stack_map_frame_calc_size(RBinJavaStackMapFrame * sf)4223 R_API ut64 r_bin_java_stack_map_frame_calc_size(RBinJavaStackMapFrame *sf) {
4224 ut64 size = 0;
4225 RListIter *iter, *iter_tmp;
4226 RBinJavaVerificationObj *se;
4227 if (sf) {
4228 // sf->tag = buffer[offset];
4229 size += 1;
4230 switch (sf->type) {
4231 case R_BIN_JAVA_STACK_FRAME_SAME:
4232 // Nothing to read
4233 break;
4234 case R_BIN_JAVA_STACK_FRAME_SAME_LOCALS_1:
4235 r_list_foreach_safe (sf->stack_items, iter, iter_tmp, se) {
4236 size += rbin_java_verification_info_calc_size (se);
4237 }
4238 break;
4239 case R_BIN_JAVA_STACK_FRAME_CHOP:
4240 // sf->offset_delta = R_BIN_JAVA_USHORT (buffer, offset);
4241 size += 2;
4242 break;
4243 case R_BIN_JAVA_STACK_FRAME_SAME_FRAME_EXTENDED:
4244 // sf->offset_delta = R_BIN_JAVA_USHORT (buffer, offset);
4245 size += 2;
4246 r_list_foreach_safe (sf->stack_items, iter, iter_tmp, se) {
4247 size += rbin_java_verification_info_calc_size (se);
4248 }
4249 break;
4250 case R_BIN_JAVA_STACK_FRAME_APPEND:
4251 // sf->offset_delta = R_BIN_JAVA_USHORT (buffer, offset);
4252 size += 2;
4253 r_list_foreach_safe (sf->stack_items, iter, iter_tmp, se) {
4254 size += rbin_java_verification_info_calc_size (se);
4255 }
4256 break;
4257 case R_BIN_JAVA_STACK_FRAME_FULL_FRAME:
4258 // sf->offset_delta = R_BIN_JAVA_USHORT (buffer, offset);
4259 size += 2;
4260 // sf->number_of_locals = R_BIN_JAVA_USHORT (buffer, offset);
4261 size += 2;
4262 r_list_foreach_safe (sf->local_items, iter, iter_tmp, se) {
4263 size += rbin_java_verification_info_calc_size (se);
4264 }
4265 // sf->number_of_stack_items = R_BIN_JAVA_USHORT (buffer, offset);
4266 size += 2;
4267 r_list_foreach_safe (sf->stack_items, iter, iter_tmp, se) {
4268 size += rbin_java_verification_info_calc_size (se);
4269 }
4270 break;
4271 default:
4272 eprintf ("Unknown type\n");
4273 break;
4274 }
4275 }
4276 return size;
4277 }
4278
r_bin_java_stack_map_frame_new(ut8 * buffer,ut64 sz,RBinJavaStackMapFrame * p_frame,ut64 buf_offset)4279 R_API RBinJavaStackMapFrame *r_bin_java_stack_map_frame_new(ut8 *buffer, ut64 sz, RBinJavaStackMapFrame *p_frame, ut64 buf_offset) {
4280 RBinJavaStackMapFrame *stack_frame = r_bin_java_default_stack_frame ();
4281 RBinJavaVerificationObj *se = NULL;
4282 ut64 offset = 0;
4283 if (!stack_frame) {
4284 return NULL;
4285 }
4286 stack_frame->tag = buffer[offset];
4287 offset += 1;
4288 stack_frame->metas->type_info = (void *) r_bin_java_determine_stack_frame_type (stack_frame->tag);
4289 stack_frame->type = ((RBinJavaStackMapFrameMetas *) stack_frame->metas->type_info)->type;
4290 stack_frame->file_offset = buf_offset;
4291 stack_frame->p_stack_frame = p_frame;
4292 switch (stack_frame->type) {
4293 case R_BIN_JAVA_STACK_FRAME_SAME:
4294 // Maybe? 1. Copy the previous frames locals and set the locals count.
4295 // copy_type_info_to_stack_frame_list_up_to_idx (p_frame->local_items, stack_frame->local_items, idx);
4296 if (p_frame) {
4297 stack_frame->number_of_locals = p_frame->number_of_locals;
4298 } else {
4299 IFINT eprintf("><?><\n");
4300 IFDBG eprintf("Unable to set previous stackframe with the number of locals (current info.code_attr.implicit_frame was probably not set :/)");
4301 }
4302 IFDBG eprintf("r_bin_java_stack_map_frame_new: TODO Stack Frame Same Locals Condition is untested, so there may be issues.\n");
4303 break;
4304 case R_BIN_JAVA_STACK_FRAME_SAME_LOCALS_1:
4305 // 1. Read the stack type
4306 stack_frame->number_of_stack_items = 1;
4307 if (offset > sz) {
4308 r_bin_java_stack_frame_free (stack_frame);
4309 return NULL;
4310 }
4311 se = r_bin_java_read_from_buffer_verification_info_new (buffer + offset, sz - offset, buf_offset + offset);
4312 IFDBG eprintf("r_bin_java_stack_map_frame_new: Parsed R_BIN_JAVA_STACK_FRAME_SAME_LOCALS_1.\n");
4313 if (se) {
4314 offset += se->size;
4315 } else {
4316 eprintf ("r_bin_java_stack_map_frame_new: Unable to parse the Stack Items for the stack frame.\n");
4317 r_bin_java_stack_frame_free (stack_frame);
4318 return NULL;
4319 }
4320 r_list_append (stack_frame->stack_items, (void *) se);
4321 // Maybe? 3. Copy the previous frames locals and set the locals count.
4322 // copy_type_info_to_stack_frame_list_up_to_idx (p_frame->local_items, stack_frame->local_items, idx);
4323 if (p_frame) {
4324 stack_frame->number_of_locals = p_frame->number_of_locals;
4325 } else {
4326 IFDBG eprintf("Unable to set previous stackframe with the number of locals (current info.code_attr.implicit_frame was probably not set :/)");
4327 }
4328 IFDBG eprintf("r_bin_java_stack_map_frame_new: TODO Stack Frame Same Locals 1 Stack Element Condition is untested, so there may be issues.\n");
4329 break;
4330 case R_BIN_JAVA_STACK_FRAME_CHOP:
4331 // 1. Calculate the max index we want to copy from the list of the
4332 // previous frames locals
4333 IFDBG eprintf("r_bin_java_stack_map_frame_new: Parsing R_BIN_JAVA_STACK_FRAME_CHOP.\n");
4334 // ut16 k = 251 - stack_frame->tag;
4335 /*,
4336 idx = p_frame->number_of_locals - k;
4337 */
4338 // 2. read the uoffset value
4339 stack_frame->offset_delta = R_BIN_JAVA_USHORT (buffer, offset);
4340 offset += 2;
4341 // Maybe? 3. Copy the previous frames locals and set the locals count.
4342 // copy_type_info_to_stack_frame_list_up_to_idx (p_frame->local_items, stack_frame->local_items, idx);
4343 if (p_frame) {
4344 stack_frame->number_of_locals = p_frame->number_of_locals;
4345 } else {
4346 IFINT eprintf("><?><\n");
4347 IFDBG eprintf("Unable to set previous stackframe with the number of locals (current info.code_attr.implicit_frame was probably not set :/)");
4348 }
4349 IFDBG eprintf("r_bin_java_stack_map_frame_new: TODO Stack Frame Chop Condition is untested, so there may be issues.\n");
4350 break;
4351 case R_BIN_JAVA_STACK_FRAME_SAME_FRAME_EXTENDED:
4352 IFDBG eprintf("r_bin_java_stack_map_frame_new: Parsing R_BIN_JAVA_STACK_FRAME_SAME_FRAME_EXTENDED.\n");
4353 // 1. Read the uoffset
4354 stack_frame->offset_delta = R_BIN_JAVA_USHORT (buffer, offset);
4355 offset += 2;
4356 // 2. Read the stack element type
4357 stack_frame->number_of_stack_items = 1;
4358 se = r_bin_java_read_from_buffer_verification_info_new (buffer + offset, sz - offset, buf_offset + offset);
4359 if (se) {
4360 offset += se->size;
4361 } else {
4362 eprintf ("r_bin_java_stack_map_frame_new: Unable to parse the Stack Items for the stack frame.\n");
4363 r_bin_java_stack_frame_free (stack_frame);
4364 return NULL;
4365 }
4366 r_list_append (stack_frame->stack_items, (void *) se);
4367 // Maybe? 3. Copy the previous frames locals to the current locals
4368 // copy_type_info_to_stack_frame_list_up_to_idx (p_frame->local_items, stack_frame->local_items, idx);
4369 if (p_frame) {
4370 stack_frame->number_of_locals = p_frame->number_of_locals;
4371 } else {
4372 IFINT eprintf("><?><\n");
4373 IFDBG eprintf("Unable to set previous stackframe with the number of locals (current info.code_attr.implicit_frame was probably not set :/)");
4374 }
4375 IFDBG eprintf("r_bin_java_stack_map_frame_new: TODO Stack Frame Same Locals Frame Stack 1 Extended Condition is untested, so there may be issues.\n");
4376 break;
4377 case R_BIN_JAVA_STACK_FRAME_APPEND:
4378 IFDBG eprintf("r_bin_java_stack_map_frame_new: Parsing R_BIN_JAVA_STACK_FRAME_APPEND.\n");
4379 // 1. Calculate the max index we want to copy from the list of the
4380 // previous frames locals
4381 ut16 k = stack_frame->tag - 251;
4382 ut32 i = 0;
4383 // 2. Read the uoffset
4384 stack_frame->offset_delta = R_BIN_JAVA_USHORT (buffer, offset);
4385 offset += 2;
4386 // Maybe? 3. Copy the previous frames locals to the current locals
4387 // copy_type_info_to_stack_frame_list_up_to_idx (p_frame->local_items, stack_frame->local_items, idx);
4388 // 4. Read off the rest of the appended locals types
4389 for (i = 0; i < k; i++) {
4390 if (offset >= sz) {
4391 break;
4392 }
4393 IFDBG eprintf("r_bin_java_stack_map_frame_new: Parsing verifying the k'th frame: %d of %d.\n", i, k);
4394 se = r_bin_java_read_from_buffer_verification_info_new (buffer + offset, sz - offset, buf_offset + offset);
4395 IFDBG eprintf("r_bin_java_stack_map_frame_new: Completed Parsing\n");
4396 if (se) {
4397 offset += se->size;
4398 } else {
4399 eprintf ("r_bin_java_stack_map_frame_new: Unable to parse the locals for the stack frame.\n");
4400 r_bin_java_stack_frame_free (stack_frame);
4401 return NULL;
4402 }
4403 r_list_append (stack_frame->local_items, (void *) se);
4404 }
4405 IFDBG eprintf("r_bin_java_stack_map_frame_new: Breaking out of loop");
4406 IFDBG eprintf("p_frame: %p\n", p_frame);
4407 if (p_frame) {
4408 stack_frame->number_of_locals = p_frame->number_of_locals + k;
4409 } else {
4410 IFINT eprintf("><?><\n");
4411 IFDBG eprintf("Unable to set previous stackframe with the number of locals (current info.code_attr.implicit_frame was probably not set :/)");
4412 }
4413 IFDBG eprintf("r_bin_java_stack_map_frame_new: TODO Stack Frame Same Locals Frame Stack 1 Extended Condition is untested, so there may be issues.\n");
4414 break;
4415 case R_BIN_JAVA_STACK_FRAME_FULL_FRAME:
4416 IFDBG eprintf("r_bin_java_stack_map_frame_new: Parsing R_BIN_JAVA_STACK_FRAME_FULL_FRAME.\n");
4417 stack_frame->offset_delta = R_BIN_JAVA_USHORT (buffer, offset);
4418 offset += 2;
4419 // IFDBG eprintf ("r_bin_java_stack_map_frame_new: Code Size > 65535, read(%d byte(s)), offset = 0x%08x.\n", var_sz, stack_frame->offset_delta);
4420 // Read the number of variables based on the max # local variable
4421 stack_frame->number_of_locals = R_BIN_JAVA_USHORT (buffer, offset);
4422 offset += 2;
4423 // IFDBG eprintf ("r_bin_java_stack_map_frame_new: Max ulocalvar > 65535, read(%d byte(s)), number_of_locals = 0x%08x.\n", var_sz, stack_frame->number_of_locals);
4424 IFDBG r_bin_java_print_stack_map_frame_summary(stack_frame);
4425 // read the number of locals off the stack
4426 for (i = 0; i < stack_frame->number_of_locals; i++) {
4427 if (offset >= sz) {
4428 break;
4429 }
4430 se = r_bin_java_read_from_buffer_verification_info_new (buffer + offset, sz - offset, buf_offset + offset);
4431 if (se) {
4432 offset += se->size;
4433 // r_list_append (stack_frame->local_items, (void *) se);
4434 } else {
4435 eprintf ("r_bin_java_stack_map_frame_new: Unable to parse the locals for the stack frame.\n");
4436 r_bin_java_stack_frame_free (stack_frame);
4437 return NULL;
4438 }
4439 r_list_append (stack_frame->local_items, (void *) se);
4440 }
4441 // Read the number of stack items based on the max size of stack
4442 stack_frame->number_of_stack_items = R_BIN_JAVA_USHORT (buffer, offset);
4443 offset += 2;
4444 // IFDBG eprintf ("r_bin_java_stack_map_frame_new: Max ustack items > 65535, read(%d byte(s)), number_of_locals = 0x%08x.\n", var_sz, stack_frame->number_of_stack_items);
4445 // read the stack items
4446 for (i = 0; i < stack_frame->number_of_stack_items; i++) {
4447 if (offset >= sz) {
4448 break;
4449 }
4450 se = r_bin_java_read_from_buffer_verification_info_new (buffer + offset, sz - offset, buf_offset + offset);
4451 if (se) {
4452 offset += se->size;
4453 // r_list_append (stack_frame->stack_items, (void *) se);
4454 } else {
4455 eprintf ("r_bin_java_stack_map_frame_new: Unable to parse the stack items for the stack frame.\n");
4456 r_bin_java_stack_frame_free (stack_frame);
4457 return NULL;
4458 }
4459 r_list_append (stack_frame->local_items, (void *) se);
4460 }
4461 break;
4462 default:
4463 eprintf ("java: Unknown type\n");
4464 break;
4465 }
4466 // IFDBG eprintf ("Created a stack frame at offset(0x%08"PFMT64x") of size: %d\n", buf_offset, stack_frame->size);//r_bin_java_print_stack_map_frame_summary(stack_frame);
4467 stack_frame->size = offset;
4468 // IFDBG r_bin_java_print_stack_map_frame_summary(stack_frame);
4469 return stack_frame;
4470 }
4471
r_bin_java_find_cp_class_ref_from_name_idx(RBinJavaObj * bin,ut16 name_idx)4472 R_API ut16 r_bin_java_find_cp_class_ref_from_name_idx(RBinJavaObj *bin, ut16 name_idx) {
4473 ut16 pos, len = (ut16) r_list_length (bin->cp_list);
4474 RBinJavaCPTypeObj *item;
4475 for (pos = 0; pos < len; pos++) {
4476 item = (RBinJavaCPTypeObj *) r_list_get_n (bin->cp_list, pos);
4477 if (item && item->tag == R_BIN_JAVA_CP_CLASS && item->info.cp_class.name_idx == name_idx) {
4478 break;
4479 }
4480 }
4481 return (pos != len) ? pos : 0;
4482 }
4483
r_bin_java_default_stack_frame(void)4484 R_API RBinJavaStackMapFrame *r_bin_java_default_stack_frame(void) {
4485 RBinJavaStackMapFrame *sf = R_NEW0 (RBinJavaStackMapFrame);
4486 if (!sf) {
4487 return NULL;
4488 }
4489 sf->metas = R_NEW0 (RBinJavaMetaInfo);
4490 if (!sf->metas) {
4491 free (sf);
4492 return NULL;
4493 }
4494 sf->metas->type_info = (void *) &R_BIN_JAVA_STACK_MAP_FRAME_METAS[R_BIN_JAVA_STACK_FRAME_IMPLICIT];
4495 sf->type = ((RBinJavaStackMapFrameMetas *) sf->metas->type_info)->type;
4496 sf->local_items = r_list_newf (r_bin_java_verification_info_free);
4497 sf->stack_items = r_list_newf (r_bin_java_verification_info_free);
4498 sf->number_of_stack_items = 0;
4499 sf->number_of_locals = 0;
4500 return sf;
4501 }
4502
r_bin_java_build_stack_frame_from_local_variable_table(RBinJavaObj * bin,RBinJavaAttrInfo * attr)4503 R_API RBinJavaStackMapFrame *r_bin_java_build_stack_frame_from_local_variable_table(RBinJavaObj *bin, RBinJavaAttrInfo *attr) {
4504 RBinJavaStackMapFrame *sf = r_bin_java_default_stack_frame ();
4505 RBinJavaLocalVariableAttribute *lvattr = NULL;
4506 RBinJavaVerificationObj *type_item;
4507 RListIter *iter = NULL;
4508 ut32 value_cnt = 0;
4509 ut8 value;
4510 if (!sf || !bin || !attr || attr->type != R_BIN_JAVA_ATTR_TYPE_LOCAL_VARIABLE_TABLE_ATTR) {
4511 eprintf ("Attempting to create a stack_map frame from a bad attribute.\n");
4512 return sf;
4513 }
4514 sf->number_of_locals = attr->info.local_variable_table_attr.table_length;
4515 r_list_foreach (attr->info.local_variable_table_attr.local_variable_table, iter, lvattr) {
4516 ut32 pos = 0;
4517 // knock the array Types
4518 while (lvattr->descriptor[pos] == '[') {
4519 pos++;
4520 }
4521 value = lvattr->descriptor[pos];
4522 // IFDBG eprintf ("Found the following type value: %c at pos %d in %s\n", value, pos, lvattr->descriptor);
4523 switch (value) {
4524 case 'I':
4525 case 'Z':
4526 case 'S':
4527 case 'B':
4528 case 'C':
4529 type_item = r_bin_java_verification_info_from_type (bin, R_BIN_JAVA_STACKMAP_INTEGER, 0);
4530 break;
4531 case 'F':
4532 type_item = r_bin_java_verification_info_from_type (bin, R_BIN_JAVA_STACKMAP_FLOAT, 0);
4533 break;
4534 case 'D':
4535 type_item = r_bin_java_verification_info_from_type (bin, R_BIN_JAVA_STACKMAP_DOUBLE, 0);
4536 break;
4537 case 'J':
4538 type_item = r_bin_java_verification_info_from_type (bin, R_BIN_JAVA_STACKMAP_LONG, 0);
4539 break;
4540 case 'L':
4541 // TODO: FIXME write something that will iterate over the CP Pool and find the
4542 // CONSTANT_Class_info referencing this
4543 {
4544 ut16 idx = r_bin_java_find_cp_class_ref_from_name_idx (bin, lvattr->name_idx);
4545 type_item = r_bin_java_verification_info_from_type (bin, R_BIN_JAVA_STACKMAP_OBJECT, idx);
4546 }
4547 break;
4548 default:
4549 eprintf ("r_bin_java_build_stack_frame_from_local_variable_table: "
4550 "not sure how to handle: name: %s, type: %s\n", lvattr->name, lvattr->descriptor);
4551 type_item = r_bin_java_verification_info_from_type (bin, R_BIN_JAVA_STACKMAP_NULL, 0);
4552 }
4553 if (type_item) {
4554 r_list_append (sf->local_items, (void *) type_item);
4555 }
4556 value_cnt++;
4557 }
4558 if (value_cnt != attr->info.local_variable_table_attr.table_length) {
4559 IFDBG eprintf("r_bin_java_build_stack_frame_from_local_variable_table: "
4560 "Number of locals not accurate. Expected %d but got %d",
4561 attr->info.local_variable_table_attr.table_length, value_cnt);
4562 }
4563 return sf;
4564 }
4565
r_bin_java_stack_map_table_attr_calc_size(RBinJavaAttrInfo * attr)4566 R_API ut64 r_bin_java_stack_map_table_attr_calc_size(RBinJavaAttrInfo *attr) {
4567 ut64 size = 0;
4568 RListIter *iter, *iter_tmp;
4569 RBinJavaStackMapFrame *sf;
4570 if (attr) {
4571 // attr = r_bin_java_default_attr_new (buffer, sz, buf_offset);
4572 size += 6;
4573 // IFDBG r_bin_java_print_source_code_file_attr_summary(attr);
4574 // Current spec does not call for variable sizes.
4575 // attr->info.stack_map_table_attr.number_of_entries = R_BIN_JAVA_USHORT (buffer, offset);
4576 size += 2;
4577 r_list_foreach_safe (attr->info.stack_map_table_attr.stack_map_frame_entries, iter, iter_tmp, sf) {
4578 size += r_bin_java_stack_map_frame_calc_size (sf);
4579 }
4580 }
4581 return size;
4582 }
4583
r_bin_java_stack_map_table_attr_new(RBinJavaObj * bin,ut8 * buffer,ut64 sz,ut64 buf_offset)4584 R_API RBinJavaAttrInfo *r_bin_java_stack_map_table_attr_new(RBinJavaObj *bin, ut8 *buffer, ut64 sz, ut64 buf_offset) {
4585 ut32 i = 0;
4586 ut64 offset = 0;
4587 RBinJavaStackMapFrame *stack_frame = NULL, *new_stack_frame = NULL;
4588 if (sz < 10) {
4589 return NULL;
4590 }
4591 RBinJavaAttrInfo *attr = r_bin_java_default_attr_new (bin, buffer, sz, buf_offset);
4592 offset += 6;
4593 IFDBG eprintf("r_bin_java_stack_map_table_attr_new: New stack map allocated.\n");
4594 if (!attr) {
4595 return NULL;
4596 }
4597 attr->info.stack_map_table_attr.stack_map_frame_entries = r_list_newf (r_bin_java_stack_frame_free);
4598 // IFDBG r_bin_java_print_source_code_file_attr_summary(attr);
4599 // Current spec does not call for variable sizes.
4600 attr->info.stack_map_table_attr.number_of_entries = R_BIN_JAVA_USHORT (buffer, offset);
4601 offset += 2;
4602 IFDBG eprintf("r_bin_java_stack_map_table_attr_new: Processing stack map, summary is:\n");
4603 IFDBG r_bin_java_print_stack_map_table_attr_summary(attr);
4604 for (i = 0; i < attr->info.stack_map_table_attr.number_of_entries; i++) {
4605 // read next stack frame
4606 IFDBG eprintf("Reading StackMap Entry #%d @ 0x%08"PFMT64x "\n", i, buf_offset + offset);
4607 if (stack_frame == NULL && R_BIN_JAVA_GLOBAL_BIN && R_BIN_JAVA_GLOBAL_BIN->current_code_attr) {
4608 IFDBG eprintf("Setting an implicit frame at #%d @ 0x%08"PFMT64x "\n", i, buf_offset + offset);
4609 stack_frame = R_BIN_JAVA_GLOBAL_BIN->current_code_attr->info.code_attr.implicit_frame;
4610 }
4611 IFDBG eprintf("Reading StackMap Entry #%d @ 0x%08"PFMT64x ", current stack_frame: %p\n", i, buf_offset + offset, stack_frame);
4612 if (offset >= sz) {
4613 r_bin_java_stack_map_table_attr_free (attr);
4614 return NULL;
4615 }
4616 new_stack_frame = r_bin_java_stack_map_frame_new (buffer + offset, sz - offset, stack_frame, buf_offset + offset);
4617 if (new_stack_frame) {
4618 offset += new_stack_frame->size;
4619 // append stack frame to the list
4620 r_list_append (attr->info.stack_map_table_attr.stack_map_frame_entries, (void *) new_stack_frame);
4621 stack_frame = new_stack_frame;
4622 } else {
4623 eprintf ("r_bin_java_stack_map_table_attr_new: Unable to parse the stack frame for the stack map table.\n");
4624 r_bin_java_stack_map_table_attr_free (attr);
4625 attr = NULL;
4626 break;
4627 }
4628 }
4629 if (attr) {
4630 attr->size = offset;
4631 }
4632 return attr;
4633 }
4634 // End attribute types new
4635 // Start new Constant Pool Types
r_bin_java_do_nothing_new(RBinJavaObj * bin,ut8 * buffer,ut64 sz)4636 R_API RBinJavaCPTypeObj *r_bin_java_do_nothing_new(RBinJavaObj *bin, ut8 *buffer, ut64 sz) {
4637 return (RBinJavaCPTypeObj *) NULL;
4638 }
4639
r_bin_java_do_nothing_calc_size(RBinJavaCPTypeObj * obj)4640 R_API ut64 r_bin_java_do_nothing_calc_size(RBinJavaCPTypeObj *obj) {
4641 return 0;
4642 }
4643
r_bin_java_do_nothing_free(void * obj)4644 R_API void r_bin_java_do_nothing_free(void /*RBinJavaCPTypeObj*/ *obj) {
4645 return;
4646 }
4647
r_bin_java_unknown_cp_new(RBinJavaObj * bin,ut8 * buffer,ut64 sz)4648 R_API RBinJavaCPTypeObj *r_bin_java_unknown_cp_new(RBinJavaObj *bin, ut8 *buffer, ut64 sz) {
4649 ut8 tag = buffer[0];
4650 RBinJavaCPTypeObj *obj = NULL;
4651 obj = (RBinJavaCPTypeObj *) malloc (sizeof (RBinJavaCPTypeObj));
4652 if (obj) {
4653 memset (obj, 0, sizeof (RBinJavaCPTypeObj));
4654 obj->tag = tag;
4655 obj->metas = R_NEW0 (RBinJavaMetaInfo);
4656 obj->metas->type_info = (void *) &R_BIN_JAVA_CP_METAS[R_BIN_JAVA_CP_UNKNOWN];
4657 }
4658 return obj;
4659 }
4660
r_bin_java_unknown_cp_calc_size(RBinJavaCPTypeObj * obj)4661 R_API ut64 r_bin_java_unknown_cp_calc_size(RBinJavaCPTypeObj *obj) {
4662 return 1LL;
4663 }
4664
r_bin_java_class_cp_new(RBinJavaObj * bin,ut8 * buffer,ut64 sz)4665 R_API RBinJavaCPTypeObj *r_bin_java_class_cp_new(RBinJavaObj *bin, ut8 *buffer, ut64 sz) {
4666 ut8 tag = buffer[0];
4667 int quick_check = r_bin_java_quick_check (R_BIN_JAVA_CP_CLASS, tag, sz, "Class");
4668 if (quick_check > 0) {
4669 return NULL;
4670 }
4671 RBinJavaCPTypeObj *obj = R_NEW0 (RBinJavaCPTypeObj);
4672 if (obj) {
4673 obj->tag = tag;
4674 obj->metas = R_NEW0 (RBinJavaMetaInfo);
4675 obj->metas->type_info = (void *) &R_BIN_JAVA_CP_METAS[tag];
4676 obj->info.cp_class.name_idx = R_BIN_JAVA_USHORT (buffer, 1);
4677 }
4678 return obj;
4679 }
4680
r_bin_java_class_cp_calc_size(RBinJavaCPTypeObj * obj)4681 R_API ut64 r_bin_java_class_cp_calc_size(RBinJavaCPTypeObj *obj) {
4682 ut64 size = 0;
4683 // ut8 tag = buffer[0];
4684 size += 1;
4685 // obj->info.cp_class.name_idx = R_BIN_JAVA_USHORT (buffer, 1);
4686 size += 2;
4687 return size;
4688 }
4689
r_bin_java_fieldref_cp_new(RBinJavaObj * bin,ut8 * buffer,ut64 sz)4690 R_API RBinJavaCPTypeObj *r_bin_java_fieldref_cp_new(RBinJavaObj *bin, ut8 *buffer, ut64 sz) {
4691 ut8 tag = buffer[0];
4692 RBinJavaCPTypeObj *obj = NULL;
4693 int quick_check = 0;
4694 quick_check = r_bin_java_quick_check (R_BIN_JAVA_CP_FIELDREF, tag, sz, "FieldRef");
4695 if (quick_check > 0) {
4696 return obj;
4697 }
4698 obj = (RBinJavaCPTypeObj *) malloc (sizeof (RBinJavaCPTypeObj));
4699 if (obj) {
4700 memset (obj, 0, sizeof (RBinJavaCPTypeObj));
4701 obj->tag = tag;
4702 obj->metas = R_NEW0 (RBinJavaMetaInfo);
4703 obj->metas->type_info = (void *) &R_BIN_JAVA_CP_METAS[tag];
4704 obj->info.cp_field.class_idx = R_BIN_JAVA_USHORT (buffer, 1);
4705 obj->info.cp_field.name_and_type_idx = R_BIN_JAVA_USHORT (buffer, 3);
4706
4707 }
4708 return (RBinJavaCPTypeObj *) obj;
4709 }
4710
r_bin_java_fieldref_cp_calc_size(RBinJavaCPTypeObj * obj)4711 R_API ut64 r_bin_java_fieldref_cp_calc_size(RBinJavaCPTypeObj *obj) {
4712 ut64 size = 0;
4713 // tag
4714 size += 1;
4715 // obj->info.cp_field.class_idx = R_BIN_JAVA_USHORT (buffer, 1);
4716 size += 2;
4717 // obj->info.cp_field.name_and_type_idx = R_BIN_JAVA_USHORT (buffer, 3);
4718 size += 2;
4719 return size;
4720 }
4721
r_bin_java_methodref_cp_new(RBinJavaObj * bin,ut8 * buffer,ut64 sz)4722 R_API RBinJavaCPTypeObj *r_bin_java_methodref_cp_new(RBinJavaObj *bin, ut8 *buffer, ut64 sz) {
4723 ut8 tag = buffer[0];
4724 RBinJavaCPTypeObj *obj = NULL;
4725 int quick_check = 0;
4726 quick_check = r_bin_java_quick_check (R_BIN_JAVA_CP_METHODREF, tag, sz, "MethodRef");
4727 if (quick_check > 0) {
4728 return obj;
4729 }
4730 obj = (RBinJavaCPTypeObj *) malloc (sizeof (RBinJavaCPTypeObj));
4731 if (obj) {
4732 memset (obj, 0, sizeof (RBinJavaCPTypeObj));
4733 obj->tag = tag;
4734 obj->metas = R_NEW0 (RBinJavaMetaInfo);
4735 obj->metas->type_info = (void *) &R_BIN_JAVA_CP_METAS[tag];
4736 obj->info.cp_method.class_idx = R_BIN_JAVA_USHORT (buffer, 1);
4737 obj->info.cp_method.name_and_type_idx = R_BIN_JAVA_USHORT (buffer, 3);
4738 }
4739 return obj;
4740 }
4741
r_bin_java_methodref_cp_calc_size(RBinJavaCPTypeObj * obj)4742 R_API ut64 r_bin_java_methodref_cp_calc_size(RBinJavaCPTypeObj *obj) {
4743 ut64 size = 0;
4744 // tag
4745 size += 1;
4746 // obj->info.cp_method.class_idx = R_BIN_JAVA_USHORT (buffer, 1);
4747 size += 2;
4748 // obj->info.cp_method.name_and_type_idx = R_BIN_JAVA_USHORT (buffer, 3);
4749 size += 2;
4750 return size;
4751 }
4752
r_bin_java_interfacemethodref_cp_new(RBinJavaObj * bin,ut8 * buffer,ut64 sz)4753 R_API RBinJavaCPTypeObj *r_bin_java_interfacemethodref_cp_new(RBinJavaObj *bin, ut8 *buffer, ut64 sz) {
4754 ut8 tag = buffer[0];
4755 int quick_check = r_bin_java_quick_check (R_BIN_JAVA_CP_INTERFACEMETHOD_REF, tag, sz, "InterfaceMethodRef");
4756 if (quick_check > 0) {
4757 return NULL;
4758 }
4759 RBinJavaCPTypeObj *obj = R_NEW0 (RBinJavaCPTypeObj);
4760 if (obj) {
4761 obj->tag = tag;
4762 obj->metas = R_NEW0 (RBinJavaMetaInfo);
4763 obj->metas->type_info = (void *) &R_BIN_JAVA_CP_METAS[tag];
4764 obj->name = r_str_dup (NULL, (const char *) R_BIN_JAVA_CP_METAS[tag].name);
4765 obj->info.cp_interface.class_idx = R_BIN_JAVA_USHORT (buffer, 1);
4766 obj->info.cp_interface.name_and_type_idx = R_BIN_JAVA_USHORT (buffer, 3);
4767
4768 }
4769 return obj;
4770 }
4771
r_bin_java_interfacemethodref_cp_calc_size(RBinJavaCPTypeObj * obj)4772 R_API ut64 r_bin_java_interfacemethodref_cp_calc_size(RBinJavaCPTypeObj *obj) {
4773 ut64 size = 0;
4774 // tag
4775 size += 1;
4776 // obj->info.cp_interface.class_idx = R_BIN_JAVA_USHORT (buffer, 1);
4777 size += 2;
4778 // obj->info.cp_interface.name_and_type_idx = R_BIN_JAVA_USHORT (buffer, 3);
4779 size += 2;
4780 return size;
4781 }
4782
r_bin_java_string_cp_new(RBinJavaObj * bin,ut8 * buffer,ut64 sz)4783 R_API RBinJavaCPTypeObj *r_bin_java_string_cp_new(RBinJavaObj *bin, ut8 *buffer, ut64 sz) {
4784 ut8 tag = buffer[0];
4785 int quick_check = r_bin_java_quick_check (R_BIN_JAVA_CP_STRING, tag, sz, "String");
4786 if (quick_check > 0) {
4787 return NULL;
4788 }
4789 RBinJavaCPTypeObj *obj = R_NEW0 (RBinJavaCPTypeObj);
4790 if (obj) {
4791 obj->tag = tag;
4792 obj->metas = R_NEW0 (RBinJavaMetaInfo);
4793 obj->metas->type_info = (void *) &R_BIN_JAVA_CP_METAS[tag];
4794 obj->name = r_str_dup (NULL, (const char *) R_BIN_JAVA_CP_METAS[tag].name);
4795 obj->info.cp_string.string_idx = R_BIN_JAVA_USHORT (buffer, 1);
4796 }
4797 return obj;
4798 }
4799
r_bin_java_string_cp_calc_size(RBinJavaCPTypeObj * obj)4800 R_API ut64 r_bin_java_string_cp_calc_size(RBinJavaCPTypeObj *obj) {
4801 ut64 size = 0;
4802 // tag
4803 size += 1;
4804 // obj->info.cp_string.string_idx = R_BIN_JAVA_USHORT (buffer, 1);
4805 size += 2;
4806 return size;
4807 }
4808
r_bin_java_integer_cp_new(RBinJavaObj * bin,ut8 * buffer,ut64 sz)4809 R_API RBinJavaCPTypeObj *r_bin_java_integer_cp_new(RBinJavaObj *bin, ut8 *buffer, ut64 sz) {
4810 ut8 tag = buffer[0];
4811 RBinJavaCPTypeObj *obj = NULL;
4812 int quick_check = 0;
4813 quick_check = r_bin_java_quick_check (R_BIN_JAVA_CP_INTEGER, tag, sz, "Integer");
4814 if (quick_check > 0) {
4815 return obj;
4816 }
4817 obj = (RBinJavaCPTypeObj *) R_NEW0 (RBinJavaCPTypeObj);
4818 if (obj) {
4819 obj->tag = tag;
4820 obj->metas = R_NEW0 (RBinJavaMetaInfo);
4821 obj->metas->type_info = (void *) &R_BIN_JAVA_CP_METAS[tag];
4822 obj->name = r_str_dup (NULL, (const char *) R_BIN_JAVA_CP_METAS[tag].name);
4823 memset (&obj->info.cp_integer.bytes, 0, sizeof (obj->info.cp_integer.bytes));
4824 memcpy (&obj->info.cp_integer.bytes.raw, buffer + 1, 4);
4825
4826 }
4827 return obj;
4828 }
4829
r_bin_java_integer_cp_calc_size(RBinJavaCPTypeObj * obj)4830 R_API ut64 r_bin_java_integer_cp_calc_size(RBinJavaCPTypeObj *obj) {
4831 ut64 size = 0;
4832 // tag
4833 size += 1;
4834 // obj->info.cp_string.string_idx = R_BIN_JAVA_USHORT (buffer, 1);
4835 size += 4;
4836 return size;
4837 }
4838
r_bin_java_float_cp_new(RBinJavaObj * bin,ut8 * buffer,ut64 sz)4839 R_API RBinJavaCPTypeObj *r_bin_java_float_cp_new(RBinJavaObj *bin, ut8 *buffer, ut64 sz) {
4840 ut8 tag = buffer[0];
4841 RBinJavaCPTypeObj *obj = NULL;
4842 int quick_check = 0;
4843 quick_check = r_bin_java_quick_check (R_BIN_JAVA_CP_FLOAT, tag, sz, "Float");
4844 if (quick_check > 0) {
4845 return obj;
4846 }
4847 obj = (RBinJavaCPTypeObj *) calloc (1, sizeof (RBinJavaCPTypeObj));
4848 if (obj) {
4849 obj->tag = tag;
4850 obj->metas = R_NEW0 (RBinJavaMetaInfo);
4851 obj->metas->type_info = (void *) &R_BIN_JAVA_CP_METAS[tag];
4852 obj->name = r_str_dup (NULL, (const char *) R_BIN_JAVA_CP_METAS[tag].name);
4853 memset (&obj->info.cp_float.bytes, 0, sizeof (obj->info.cp_float.bytes));
4854 memcpy (&obj->info.cp_float.bytes.raw, buffer, 4);
4855 }
4856 return (RBinJavaCPTypeObj *) obj;
4857 }
4858
r_bin_java_float_cp_calc_size(RBinJavaCPTypeObj * obj)4859 R_API ut64 r_bin_java_float_cp_calc_size(RBinJavaCPTypeObj *obj) {
4860 ut64 size = 0;
4861 // tag
4862 size += 1;
4863 // obj->info.cp_string.string_idx = R_BIN_JAVA_USHORT (buffer, 1);
4864 size += 4;
4865 return size;
4866 }
4867
r_bin_java_long_cp_new(RBinJavaObj * bin,ut8 * buffer,ut64 sz)4868 R_API RBinJavaCPTypeObj *r_bin_java_long_cp_new(RBinJavaObj *bin, ut8 *buffer, ut64 sz) {
4869 ut8 tag = buffer[0];
4870 RBinJavaCPTypeObj *obj = NULL;
4871 int quick_check = 0;
4872 quick_check = r_bin_java_quick_check (R_BIN_JAVA_CP_LONG, tag, sz, "Long");
4873 if (quick_check > 0) {
4874 return obj;
4875 }
4876 obj = (RBinJavaCPTypeObj *) malloc (sizeof (RBinJavaCPTypeObj));
4877 if (obj) {
4878 memset (obj, 0, sizeof (RBinJavaCPTypeObj));
4879 obj->tag = tag;
4880 obj->metas = R_NEW0 (RBinJavaMetaInfo);
4881 obj->metas->type_info = (void *) &R_BIN_JAVA_CP_METAS[tag];
4882 obj->name = r_str_dup (NULL, (const char *) R_BIN_JAVA_CP_METAS[tag].name);
4883 memset (&obj->info.cp_long.bytes, 0, sizeof (obj->info.cp_long.bytes));
4884 memcpy (&(obj->info.cp_long.bytes), buffer + 1, 8);
4885
4886 }
4887 return obj;
4888 }
4889
r_bin_java_long_cp_calc_size(RBinJavaCPTypeObj * obj)4890 R_API ut64 r_bin_java_long_cp_calc_size(RBinJavaCPTypeObj *obj) {
4891 ut64 size = 0;
4892 // tag
4893 size += 1;
4894 // obj->info.cp_string.string_idx = R_BIN_JAVA_USHORT (buffer, 1);
4895 size += 8;
4896 return size;
4897 }
4898
r_bin_java_double_cp_new(RBinJavaObj * bin,ut8 * buffer,ut64 sz)4899 R_API RBinJavaCPTypeObj *r_bin_java_double_cp_new(RBinJavaObj *bin, ut8 *buffer, ut64 sz) {
4900 ut8 tag = buffer[0];
4901 RBinJavaCPTypeObj *obj = NULL;
4902 int quick_check = 0;
4903 quick_check = r_bin_java_quick_check (R_BIN_JAVA_CP_DOUBLE, tag, sz, "Double");
4904 if (quick_check > 0) {
4905 return (RBinJavaCPTypeObj *) obj;
4906 }
4907 obj = (RBinJavaCPTypeObj *) malloc (sizeof (RBinJavaCPTypeObj));
4908 if (obj) {
4909 memset (obj, 0, sizeof (RBinJavaCPTypeObj));
4910 obj->tag = tag;
4911 obj->metas = R_NEW0 (RBinJavaMetaInfo);
4912 obj->metas->type_info = (void *) &R_BIN_JAVA_CP_METAS[tag];
4913 obj->name = r_str_dup (NULL, (const char *) R_BIN_JAVA_CP_METAS[tag].name);
4914 memset (&obj->info.cp_double.bytes, 0, sizeof (obj->info.cp_double.bytes));
4915 memcpy (&obj->info.cp_double.bytes, buffer + 1, 8);
4916 }
4917 return obj;
4918 }
4919
r_bin_java_double_cp_calc_size(RBinJavaCPTypeObj * obj)4920 R_API ut64 r_bin_java_double_cp_calc_size(RBinJavaCPTypeObj *obj) {
4921 ut64 size = 0;
4922 // tag
4923 size += 1;
4924 // obj->info.cp_string.string_idx = R_BIN_JAVA_USHORT (buffer, 1);
4925 size += 8;
4926 return size;
4927 }
4928
r_bin_java_utf8_cp_new(RBinJavaObj * bin,ut8 * buffer,ut64 sz)4929 R_API RBinJavaCPTypeObj *r_bin_java_utf8_cp_new(RBinJavaObj *bin, ut8 *buffer, ut64 sz) {
4930 ut8 tag = buffer[0];
4931 RBinJavaCPTypeObj *obj;
4932 int quick_check = r_bin_java_quick_check (R_BIN_JAVA_CP_UTF8, tag, sz, "Utf8");
4933 if (quick_check > 0) {
4934 return NULL;
4935 }
4936 if ((obj = R_NEW0 (RBinJavaCPTypeObj))) {
4937 obj->tag = tag;
4938 obj->metas = R_NEW0 (RBinJavaMetaInfo);
4939 obj->metas->type_info = (void *) &R_BIN_JAVA_CP_METAS[tag];
4940 obj->name = r_str_dup (NULL, (const char *) R_BIN_JAVA_CP_METAS[tag].name);
4941 obj->info.cp_utf8.length = R_BIN_JAVA_USHORT (buffer, 1);
4942 obj->info.cp_utf8.bytes = (ut8 *) malloc (obj->info.cp_utf8.length + 1);
4943 if (obj->info.cp_utf8.bytes) {
4944 memset (obj->info.cp_utf8.bytes, 0, obj->info.cp_utf8.length + 1);
4945 if (obj->info.cp_utf8.length < (sz - 3)) {
4946 memcpy (obj->info.cp_utf8.bytes, buffer + 3, (sz - 3));
4947 obj->info.cp_utf8.length = sz - 3;
4948 } else {
4949 memcpy (obj->info.cp_utf8.bytes, buffer + 3, obj->info.cp_utf8.length);
4950 }
4951 obj->value = obj->info.cp_utf8.bytes;
4952 } else {
4953 r_bin_java_obj_free (obj);
4954 obj = NULL;
4955 }
4956 }
4957 return obj;
4958 }
4959
r_bin_java_utf8_cp_calc_size(RBinJavaCPTypeObj * obj)4960 R_API ut64 r_bin_java_utf8_cp_calc_size(RBinJavaCPTypeObj *obj) {
4961 ut64 size = 0;
4962 size += 1;
4963 if (obj && R_BIN_JAVA_CP_UTF8 == obj->tag) {
4964 size += 2;
4965 size += obj->info.cp_utf8.length;
4966 }
4967 return size;
4968 }
4969
r_bin_java_name_and_type_cp_new(RBinJavaObj * bin,ut8 * buffer,ut64 sz)4970 R_API RBinJavaCPTypeObj *r_bin_java_name_and_type_cp_new(RBinJavaObj *bin, ut8 *buffer, ut64 sz) {
4971 ut8 tag = buffer[0];
4972 RBinJavaCPTypeObj *obj = NULL;
4973 int quick_check = 0;
4974 quick_check = r_bin_java_quick_check (R_BIN_JAVA_CP_NAMEANDTYPE, tag, sz, "RBinJavaCPTypeNameAndType");
4975 if (quick_check > 0) {
4976 return obj;
4977 }
4978 obj = R_NEW0 (RBinJavaCPTypeObj);
4979 if (obj) {
4980 obj->metas = R_NEW0 (RBinJavaMetaInfo);
4981 obj->metas->type_info = (void *) &R_BIN_JAVA_CP_METAS[tag];
4982 obj->name = r_str_dup (NULL, (const char *) R_BIN_JAVA_CP_METAS[tag].name);;
4983 obj->tag = tag;
4984 obj->info.cp_name_and_type.name_idx = R_BIN_JAVA_USHORT (buffer, 1);
4985 obj->info.cp_name_and_type.descriptor_idx = R_BIN_JAVA_USHORT (buffer, 3);
4986 }
4987 return obj;
4988 }
4989
r_bin_java_name_and_type_cp_calc_size(RBinJavaCPTypeObj * obj)4990 R_API ut64 r_bin_java_name_and_type_cp_calc_size(RBinJavaCPTypeObj *obj) {
4991 ut64 size = 0;
4992 if (obj) {
4993 size += 1;
4994 // obj->info.cp_name_and_type.name_idx = R_BIN_JAVA_USHORT (buffer, 1);
4995 size += 2;
4996 // obj->info.cp_name_and_type.descriptor_idx = R_BIN_JAVA_USHORT (buffer, 3);
4997 size += 2;
4998 }
4999 return size;
5000 }
5001
r_bin_java_methodtype_cp_new(RBinJavaObj * bin,ut8 * buffer,ut64 sz)5002 R_API RBinJavaCPTypeObj *r_bin_java_methodtype_cp_new(RBinJavaObj *bin, ut8 *buffer, ut64 sz) {
5003 ut8 tag = buffer[0];
5004 int quick_check = r_bin_java_quick_check (R_BIN_JAVA_CP_METHODTYPE, tag, sz, "RBinJavaCPTypeMethodType");
5005 if (quick_check > 0) {
5006 return NULL;
5007 }
5008 RBinJavaCPTypeObj *obj = R_NEW0 (RBinJavaCPTypeObj);
5009 if (obj) {
5010 obj->metas = R_NEW0 (RBinJavaMetaInfo);
5011 obj->metas->type_info = (void *) &R_BIN_JAVA_CP_METAS[tag];
5012 obj->name = r_str_dup (NULL, (const char *) R_BIN_JAVA_CP_METAS[tag].name);;
5013 obj->tag = tag;
5014 obj->info.cp_method_type.descriptor_index = R_BIN_JAVA_USHORT (buffer, 1);
5015 }
5016 return obj;
5017 }
5018
r_bin_java_methodtype_cp_calc_size(RBinJavaCPTypeObj * obj)5019 R_API ut64 r_bin_java_methodtype_cp_calc_size(RBinJavaCPTypeObj *obj) {
5020 ut64 size = 0;
5021 size += 1;
5022 // obj->info.cp_method_type.descriptor_index = R_BIN_JAVA_USHORT (buffer, 1);
5023 size += 2;
5024 return size;
5025 }
5026
r_bin_java_methodhandle_cp_new(RBinJavaObj * bin,ut8 * buffer,ut64 sz)5027 R_API RBinJavaCPTypeObj *r_bin_java_methodhandle_cp_new(RBinJavaObj *bin, ut8 *buffer, ut64 sz) {
5028 ut8 tag = buffer[0];
5029 int quick_check = r_bin_java_quick_check (R_BIN_JAVA_CP_METHODHANDLE, tag, sz, "RBinJavaCPTypeMethodHandle");
5030 if (quick_check > 0) {
5031 return NULL;
5032 }
5033 RBinJavaCPTypeObj *obj = R_NEW0 (RBinJavaCPTypeObj);
5034 if (obj) {
5035 obj->metas = R_NEW0 (RBinJavaMetaInfo);
5036 obj->metas->type_info = (void *) &R_BIN_JAVA_CP_METAS[tag];
5037 obj->name = r_str_dup (NULL, (const char *) R_BIN_JAVA_CP_METAS[tag].name);;
5038 obj->tag = tag;
5039 obj->info.cp_method_handle.reference_kind = buffer[1];
5040 obj->info.cp_method_handle.reference_index = R_BIN_JAVA_USHORT (buffer, 2);
5041 }
5042 return obj;
5043 }
5044
r_bin_java_methodhandle_cp_calc_size(RBinJavaCPTypeObj * obj)5045 R_API ut64 r_bin_java_methodhandle_cp_calc_size(RBinJavaCPTypeObj *obj) {
5046 ut64 size = 0;
5047 size += 1;
5048 // obj->info.cp_method_handle.reference_index = R_BIN_JAVA_USHORT (buffer, 2);
5049 size += 2;
5050 return size;
5051 }
5052
r_bin_java_invokedynamic_cp_new(RBinJavaObj * bin,ut8 * buffer,ut64 sz)5053 R_API RBinJavaCPTypeObj *r_bin_java_invokedynamic_cp_new(RBinJavaObj *bin, ut8 *buffer, ut64 sz) {
5054 ut8 tag = buffer[0];
5055 RBinJavaCPTypeObj *obj;
5056 int quick_check = r_bin_java_quick_check (R_BIN_JAVA_CP_INVOKEDYNAMIC, tag, sz, "RBinJavaCPTypeMethodHandle");
5057 if (quick_check > 0) {
5058 return NULL;
5059 }
5060 if ((obj = R_NEW0 (RBinJavaCPTypeObj))) {
5061 obj->metas = R_NEW0 (RBinJavaMetaInfo);
5062 obj->metas->type_info = (void *) &R_BIN_JAVA_CP_METAS[tag];
5063 obj->name = r_str_dup (NULL, (const char *) R_BIN_JAVA_CP_METAS[tag].name);;
5064 obj->tag = tag;
5065 obj->info.cp_invoke_dynamic.bootstrap_method_attr_index = R_BIN_JAVA_USHORT (buffer, 1);
5066 obj->info.cp_invoke_dynamic.name_and_type_index = R_BIN_JAVA_USHORT (buffer, 3);
5067 }
5068 return obj;
5069 }
5070
r_bin_java_check_reset_cp_obj(RBinJavaCPTypeObj * cp_obj,ut8 tag)5071 R_API int r_bin_java_check_reset_cp_obj(RBinJavaCPTypeObj *cp_obj, ut8 tag) {
5072 bool res = false;
5073 if (tag < R_BIN_JAVA_CP_METAS_SZ) {
5074 if (tag != cp_obj->tag) {
5075 if (cp_obj->tag == R_BIN_JAVA_CP_UTF8) {
5076 R_FREE (cp_obj->info.cp_utf8.bytes);
5077 cp_obj->info.cp_utf8.length = 0;
5078 R_FREE (cp_obj->name);
5079 }
5080 cp_obj->tag = tag;
5081 cp_obj->metas->type_info = (void *) &R_BIN_JAVA_CP_METAS[tag];
5082 cp_obj->name = strdup (R_BIN_JAVA_CP_METAS[tag].name);
5083 res = true;
5084 } else {
5085 eprintf ("Invalid tag\n");
5086 }
5087 } else {
5088 eprintf ("Invalid tag '%d'.\n", tag);
5089 }
5090 return res;
5091 }
5092
r_bin_java_cp_get_4bytes(ut8 tag,ut32 * out_sz,const ut8 * buf,const ut64 len)5093 R_API ut8 *r_bin_java_cp_get_4bytes(ut8 tag, ut32 *out_sz, const ut8 *buf, const ut64 len) {
5094 ut8 *buffer = malloc (5);
5095 if (!buffer) {
5096 return NULL;
5097 }
5098 ut32 val = 0;
5099 if (!buffer || len < 4) {
5100 if (out_sz) {
5101 *out_sz = 0;
5102 }
5103 free (buffer);
5104 return NULL;
5105 }
5106 buffer[0] = tag;
5107 val = R_BIN_JAVA_UINT (buf, 0);
5108 memcpy (buffer + 1, (const char *) &val, 4);
5109 *out_sz = 5;
5110 return buffer;
5111 }
5112
r_bin_java_cp_get_8bytes(ut8 tag,ut32 * out_sz,const ut8 * buf,const ut64 len)5113 R_API ut8 *r_bin_java_cp_get_8bytes(ut8 tag, ut32 *out_sz, const ut8 *buf, const ut64 len) {
5114 ut8 *buffer = malloc (10);
5115 if (!buffer) {
5116 return NULL;
5117 }
5118 ut64 val = 0;
5119 if (len < 8) {
5120 *out_sz = 0;
5121 free (buffer);
5122 return NULL;
5123 }
5124 buffer[0] = tag;
5125 val = r_bin_java_raw_to_long (buf, 0);
5126 memcpy (buffer + 1, (const char *) &val, 8);
5127 *out_sz = 9;
5128 return buffer;
5129 }
5130
r_bin_java_cp_append_classref_and_name(RBinJavaObj * bin,ut32 * out_sz,const char * classname,const ut32 classname_len)5131 R_API ut8 *r_bin_java_cp_append_classref_and_name(RBinJavaObj *bin, ut32 *out_sz, const char *classname, const ut32 classname_len) {
5132 ut16 use_name_idx = bin->cp_idx + 1;
5133 ut8 *bytes = NULL, *name_bytes = NULL;
5134 name_bytes = r_bin_java_cp_get_utf8 (R_BIN_JAVA_CP_UTF8, out_sz, (const ut8 *) classname, classname_len);
5135 if (*out_sz > 0 && name_bytes) {
5136 ut8 *idx_addr = (ut8 *) &use_name_idx;
5137 bytes = malloc (*out_sz + 3);
5138 memcpy (bytes, name_bytes, *out_sz);
5139 bytes[*out_sz + 0] = R_BIN_JAVA_CP_CLASS;
5140 bytes[*out_sz + 1] = idx_addr[1];
5141 bytes[*out_sz + 2] = idx_addr[0];
5142 *out_sz += 3;
5143 }
5144 free (name_bytes);
5145 return bytes;
5146 }
5147
r_bin_java_cp_get_fref_bytes(RBinJavaObj * bin,ut32 * out_sz,ut8 tag,ut16 cn_idx,ut16 fn_idx,ut16 ft_idx)5148 R_API ut8 *r_bin_java_cp_get_fref_bytes(RBinJavaObj *bin, ut32 *out_sz, ut8 tag, ut16 cn_idx, ut16 fn_idx, ut16 ft_idx) {
5149 ut8 *bytes = NULL, *fnt_bytes = NULL;
5150 RBinJavaCPTypeObj *ref_cp_obj = NULL;
5151 ut16 fnt_idx = 0, cref_idx = 0;
5152 ut32 fnt_len = 0;
5153 ut16 ref_cp_obj_idx = r_bin_java_find_cp_class_ref_from_name_idx (bin, cn_idx);
5154 if (!ref_cp_obj_idx) {
5155 return NULL;
5156 }
5157 ref_cp_obj = r_bin_java_get_item_from_bin_cp_list (bin, ref_cp_obj_idx);
5158 if (ref_cp_obj) {
5159 cref_idx = ref_cp_obj->idx;
5160 }
5161 ref_cp_obj = r_bin_java_find_cp_name_and_type_info (bin, fn_idx, ft_idx);
5162 if (ref_cp_obj) {
5163 fnt_idx = ref_cp_obj->idx;
5164 } else {
5165 fnt_bytes = r_bin_java_cp_get_name_type (bin, &fnt_len, fn_idx, ft_idx);
5166 fnt_idx = bin->cp_idx + 1;
5167 }
5168 if (cref_idx && fnt_idx) {
5169 bytes = r_bin_java_cp_get_fm_ref (bin, out_sz, tag, cref_idx, fnt_idx);
5170 if (fnt_bytes) {
5171 ut8 *tbuf = malloc (fnt_len + *out_sz);
5172 if (!tbuf) {
5173 free (bytes);
5174 free (fnt_bytes);
5175 return NULL;
5176 }
5177 // copy the bytes to the new buffer
5178 memcpy (tbuf, fnt_bytes, fnt_len);
5179 memcpy (tbuf + fnt_len, bytes, *out_sz);
5180 // update the values free old buffer
5181 *out_sz += fnt_len;
5182 free (bytes);
5183 bytes = tbuf;
5184 }
5185 }
5186 free (fnt_bytes);
5187 return bytes;
5188 }
5189
r_bin_java_cp_get_classref(RBinJavaObj * bin,ut32 * out_sz,const char * classname,const ut32 classname_len,const ut16 name_idx)5190 R_API ut8 *r_bin_java_cp_get_classref(RBinJavaObj *bin, ut32 *out_sz, const char *classname, const ut32 classname_len, const ut16 name_idx) {
5191 ut16 use_name_idx = -1;
5192 ut8 *bytes = NULL;
5193 if (name_idx == (ut16) - 1 && classname && *classname && classname_len > 0) {
5194 // find class_name_idx by class name
5195 RList *results = r_bin_java_find_cp_const_by_val_utf8 (bin, (const ut8 *) classname, classname_len);
5196 if (r_list_length (results) == 1) {
5197 use_name_idx = (ut16) * ((ut32 *) r_list_get_n (results, 0));
5198 }
5199 r_list_free (results);
5200 } else if (name_idx != (ut16) - 1 && name_idx != 0) {
5201 use_name_idx = name_idx;
5202 }
5203 if (use_name_idx == (ut16) - 1 && classname && *classname && classname_len > 0) {
5204 bytes = r_bin_java_cp_append_classref_and_name (bin, out_sz, classname, classname_len);
5205 } else if (use_name_idx != (ut16) - 1) {
5206 ut8 *idx_addr = (ut8 *) &use_name_idx;
5207 bytes = malloc (3);
5208 if (!bytes) {
5209 return NULL;
5210 }
5211 bytes[0] = R_BIN_JAVA_CP_CLASS;
5212 bytes[1] = idx_addr[1];
5213 bytes[2] = idx_addr[0];
5214 *out_sz += 3;
5215 }
5216 return bytes;
5217 }
5218
r_bin_java_cp_get_fm_ref(RBinJavaObj * bin,ut32 * out_sz,ut8 tag,ut16 class_idx,ut16 name_and_type_idx)5219 R_API ut8 *r_bin_java_cp_get_fm_ref(RBinJavaObj *bin, ut32 *out_sz, ut8 tag, ut16 class_idx, ut16 name_and_type_idx) {
5220 return r_bin_java_cp_get_2_ut16 (bin, out_sz, tag, class_idx, name_and_type_idx);
5221 }
5222
r_bin_java_cp_get_2_ut16(RBinJavaObj * bin,ut32 * out_sz,ut8 tag,ut16 ut16_one,ut16 ut16_two)5223 R_API ut8 *r_bin_java_cp_get_2_ut16(RBinJavaObj *bin, ut32 *out_sz, ut8 tag, ut16 ut16_one, ut16 ut16_two) {
5224 ut8 *bytes = malloc (7);
5225 if (!bytes) {
5226 return NULL;
5227 }
5228 ut8 *idx_addr = NULL;
5229 bytes[*out_sz] = tag;
5230 *out_sz += 1;
5231 idx_addr = (ut8 *) &ut16_one;
5232 bytes[*out_sz + 1] = idx_addr[1];
5233 bytes[*out_sz + 2] = idx_addr[0];
5234 *out_sz += 3;
5235 idx_addr = (ut8 *) &ut16_two;
5236 bytes[*out_sz + 1] = idx_addr[1];
5237 bytes[*out_sz + 2] = idx_addr[0];
5238 *out_sz += 3;
5239 return bytes;
5240 }
5241
r_bin_java_cp_get_name_type(RBinJavaObj * bin,ut32 * out_sz,ut16 name_idx,ut16 type_idx)5242 R_API ut8 *r_bin_java_cp_get_name_type(RBinJavaObj *bin, ut32 *out_sz, ut16 name_idx, ut16 type_idx) {
5243 return r_bin_java_cp_get_2_ut16 (bin, out_sz, R_BIN_JAVA_CP_NAMEANDTYPE, name_idx, type_idx);
5244 }
5245
r_bin_java_cp_get_utf8(ut8 tag,ut32 * out_sz,const ut8 * buf,const ut64 len)5246 R_API ut8 *r_bin_java_cp_get_utf8(ut8 tag, ut32 *out_sz, const ut8 *buf, const ut64 len) {
5247 ut8 *buffer = NULL;
5248 ut16 sz = 0;
5249 ut16 t = (ut16) len;
5250 if (len > 0 && len > (ut16) - 1) {
5251 *out_sz = 0;
5252 return NULL;
5253 }
5254 sz = R_BIN_JAVA_USHORT (((ut8 *) (ut16 *) &t), 0);
5255 *out_sz = 3 + t; // tag + sz + bytes
5256 buffer = malloc (*out_sz + 3);
5257 if (!buffer) {
5258 return NULL;
5259 }
5260 // XXX - excess bytes are created to ensure null for string operations.
5261 memset (buffer, 0, *out_sz + 3);
5262 buffer[0] = tag;
5263 memcpy (buffer + 1, (const char *) &sz, 2);
5264 memcpy (buffer + 3, buf, *out_sz - 3);
5265 return buffer;
5266 }
5267
r_bin_java_invokedynamic_cp_calc_size(RBinJavaCPTypeObj * obj)5268 R_API ut64 r_bin_java_invokedynamic_cp_calc_size(RBinJavaCPTypeObj *obj) {
5269 ut64 size = 0;
5270 size += 1;
5271 // obj->info.cp_invoke_dynamic.bootstrap_method_attr_index = R_BIN_JAVA_USHORT (buffer, 1);
5272 size += 2;
5273 // obj->info.cp_invoke_dynamic.name_and_type_index = R_BIN_JAVA_USHORT (buffer, 3);
5274 size += 2;
5275 return size;
5276 }
5277 // End new Constant Pool types
5278 // Start free Constant Pool types
r_bin_java_default_free(void * o)5279 R_API void r_bin_java_default_free(void /* RBinJavaCPTypeObj*/ *o) {
5280 RBinJavaCPTypeObj *obj = o;
5281 if (obj) {
5282 free (obj->metas);
5283 free (obj->name);
5284 free (obj->value);
5285 free (obj);
5286 }
5287 }
5288
r_bin_java_utf8_info_free(void * o)5289 R_API void r_bin_java_utf8_info_free(void /* RBinJavaCPTypeObj*/ *o) {
5290 RBinJavaCPTypeObj *obj = o;
5291 if (obj) {
5292 free (obj->name);
5293 free (obj->metas);
5294 free (obj->info.cp_utf8.bytes);
5295 free (obj);
5296 }
5297 }
5298 // Deallocs for type objects
r_bin_java_obj_free(void * o)5299 R_API void r_bin_java_obj_free(void /*RBinJavaCPTypeObj*/ *o) {
5300 RBinJavaCPTypeObj *obj = o;
5301 ((RBinJavaCPTypeMetas *) obj->metas->type_info)->allocs->delete_obj (obj);
5302 }
5303
r_bin_java_print_attr_summary(RBinJavaAttrInfo * attr)5304 R_API void r_bin_java_print_attr_summary(RBinJavaAttrInfo *attr) {
5305 if (attr == NULL) {
5306 eprintf ("Attempting to print an invalid RBinJavaAttrInfo *.\n");
5307 return;
5308 }
5309 ((RBinJavaAttrMetas *) attr->metas->type_info)->allocs->print_summary (attr);
5310 }
5311
r_bin_java_print_source_debug_attr_summary(RBinJavaAttrInfo * attr)5312 R_API void r_bin_java_print_source_debug_attr_summary(RBinJavaAttrInfo *attr) {
5313 ut32 i = 0;
5314 if (attr == NULL) {
5315 eprintf ("Attempting to print an invalid RBinJavaSourceDebugExtensionAttr *.\n");
5316 return;
5317 }
5318 Eprintf ("Source Debug Extension Attribute Information:\n");
5319 Eprintf (" Attribute Offset: 0x%08"PFMT64x "\n", attr->file_offset);
5320 Eprintf (" Attribute Name Index: %d (%s)\n", attr->name_idx, attr->name);
5321 Eprintf (" Extension Length: %d\n", attr->length);
5322 Eprintf (" Source Debug Extension value: \n");
5323 for (i = 0; i < attr->length; i++) {
5324 Eprintf ("%c", attr->info.debug_extensions.debug_extension[i]);
5325 }
5326 Eprintf ("\n Source Debug Extension End\n");
5327 }
5328
r_bin_java_print_unknown_attr_summary(RBinJavaAttrInfo * attr)5329 R_API void r_bin_java_print_unknown_attr_summary(RBinJavaAttrInfo *attr) {
5330 if (attr == NULL) {
5331 eprintf ("Attempting to print an invalid RBinJavaAttrInfo *Unknown.\n");
5332 return;
5333 }
5334 Eprintf ("Unknown Attribute Information:\n");
5335 Eprintf (" Attribute Offset: 0x%08"PFMT64x "\n", attr->file_offset);
5336 Eprintf (" Attribute Name Index: %d (%s)\n", attr->name_idx, attr->name);
5337 Eprintf (" Attribute Length: %d\n", attr->length);
5338 }
5339
r_bin_java_print_code_exceptions_attr_summary(RBinJavaExceptionEntry * exc_entry)5340 R_API void r_bin_java_print_code_exceptions_attr_summary(RBinJavaExceptionEntry *exc_entry) {
5341 if (exc_entry == NULL) {
5342 eprintf ("Attempting to print an invalid RBinJavaExceptionEntry *.\n");
5343 return;
5344 }
5345 Eprintf (" Exception Table Entry Information\n");
5346 Eprintf (" offset: 0x%08"PFMT64x"\n", exc_entry->file_offset);
5347 Eprintf (" catch_type: %d\n", exc_entry->catch_type);
5348 Eprintf (" start_pc: 0x%04x\n", exc_entry->start_pc);
5349 Eprintf (" end_pc: 0x%04x\n", exc_entry->end_pc);
5350 Eprintf (" handler_pc: 0x%04x\n", exc_entry->handler_pc);
5351 }
5352 // End free Constant Pool types
r_bin_java_print_code_attr_summary(RBinJavaAttrInfo * attr)5353 R_API void r_bin_java_print_code_attr_summary(RBinJavaAttrInfo *attr) {
5354 RListIter *iter = NULL, *iter_tmp = NULL;
5355 RBinJavaExceptionEntry *exc_entry = NULL;
5356 RBinJavaAttrInfo *_attr = NULL;
5357 if (!attr) {
5358 eprintf ("Attempting to print an invalid RBinJavaAttrInfo *Code.\n");
5359 return;
5360 }
5361 Eprintf ("Code Attribute Information:\n");
5362 Eprintf (" Attribute Offset: 0x%08"PFMT64x "\n", attr->file_offset);
5363 Eprintf (" Attribute Name Index: %d (%s)\n", attr->name_idx, attr->name);
5364 Eprintf (" Attribute Length: %d, Attribute Count: %d\n", attr->length, attr->info.code_attr.attributes_count);
5365 Eprintf (" Max Stack: %d\n", attr->info.code_attr.max_stack);
5366 Eprintf (" Max Locals: %d\n", attr->info.code_attr.max_locals);
5367 Eprintf (" Code Length: %d\n", attr->info.code_attr.code_length);
5368 Eprintf (" Code At Offset: 0x%08"PFMT64x "\n", (ut64) attr->info.code_attr.code_offset);
5369 Eprintf ("Code Attribute Exception Table Information:\n");
5370 Eprintf (" Exception Table Length: %d\n", attr->info.code_attr.exception_table_length);
5371 if (attr->info.code_attr.exception_table) {
5372 // Delete the attr entries
5373 r_list_foreach_safe (attr->info.code_attr.exception_table, iter, iter_tmp, exc_entry) {
5374 r_bin_java_print_code_exceptions_attr_summary (exc_entry);
5375 }
5376 }
5377 Eprintf (" Implicit Method Stack Frame:\n");
5378 r_bin_java_print_stack_map_frame_summary (attr->info.code_attr.implicit_frame);
5379 Eprintf ("Code Attribute Attributes Information:\n");
5380 if (attr->info.code_attr.attributes && attr->info.code_attr.attributes_count > 0) {
5381 Eprintf (" Code Attribute Attributes Count: %d\n", attr->info.code_attr.attributes_count);
5382 r_list_foreach_safe (attr->info.code_attr.attributes, iter, iter_tmp, _attr) {
5383 r_bin_java_print_attr_summary (_attr);
5384 }
5385 }
5386 }
5387
r_bin_java_print_constant_value_attr_summary(RBinJavaAttrInfo * attr)5388 R_API void r_bin_java_print_constant_value_attr_summary(RBinJavaAttrInfo *attr) {
5389 if (!attr) {
5390 eprintf ("Attempting to print an invalid RBinJavaAttrInfo *ConstantValue.\n");
5391 return;
5392 }
5393 Eprintf ("Constant Value Attribute Information:\n");
5394 Eprintf (" Attribute Offset: 0x%08"PFMT64x "\n", attr->file_offset);
5395 Eprintf (" Attribute Name Index: %d (%s)\n", attr->name_idx, attr->name);
5396 Eprintf (" Attribute Length: %d\n", attr->length);
5397 Eprintf (" ConstantValue Index: %d\n", attr->info.constant_value_attr.constantvalue_idx);
5398 }
5399
r_bin_java_print_deprecated_attr_summary(RBinJavaAttrInfo * attr)5400 R_API void r_bin_java_print_deprecated_attr_summary(RBinJavaAttrInfo *attr) {
5401 if (!attr) {
5402 eprintf ("Attempting to print an invalid RBinJavaAttrInfo *Deperecated.\n");
5403 return;
5404 }
5405 Eprintf ("Deperecated Attribute Information:\n");
5406 Eprintf (" Attribute Offset: 0x%08"PFMT64x "\n", attr->file_offset);
5407 Eprintf (" Attribute Name Index: %d (%s)\n", attr->name_idx, attr->name);
5408 Eprintf (" Attribute Length: %d\n", attr->length);
5409 }
5410
r_bin_java_print_enclosing_methods_attr_summary(RBinJavaAttrInfo * attr)5411 R_API void r_bin_java_print_enclosing_methods_attr_summary(RBinJavaAttrInfo *attr) {
5412 if (!attr) {
5413 eprintf ("Attempting to print an invalid RBinJavaAttrInfo *Deperecated.\n");
5414 return;
5415 }
5416 Eprintf ("Enclosing Method Attribute Information:\n");
5417 Eprintf (" Attribute Offset: 0x%08"PFMT64x "\n", attr->file_offset);
5418 Eprintf (" Attribute Name Index: %d (%s)\n", attr->name_idx, attr->name);
5419 Eprintf (" Attribute Length: %d\n", attr->length);
5420 Eprintf (" Class Info Index : 0x%02x\n", attr->info.enclosing_method_attr.class_idx);
5421 Eprintf (" Method Name and Type Index : 0x%02x\n", attr->info.enclosing_method_attr.method_idx);
5422 Eprintf (" Class Name : %s\n", attr->info.enclosing_method_attr.class_name);
5423 Eprintf (" Method Name and Desc : %s %s\n", attr->info.enclosing_method_attr.method_name, attr->info.enclosing_method_attr.method_descriptor);
5424 }
5425
r_bin_java_print_exceptions_attr_summary(RBinJavaAttrInfo * attr)5426 R_API void r_bin_java_print_exceptions_attr_summary(RBinJavaAttrInfo *attr) {
5427 ut32 i = 0;
5428 if (!attr) {
5429 eprintf ("Attempting to print an invalid RBinJavaAttrInfo *Exceptions.\n");
5430 return;
5431 }
5432 Eprintf ("Exceptions Attribute Information:\n");
5433 Eprintf (" Attribute Offset: 0x%08"PFMT64x "\n", attr->file_offset);
5434 Eprintf (" Attribute Name Index: %d (%s)\n", attr->name_idx, attr->name);
5435 Eprintf (" Attribute Length: %d\n", attr->length);
5436 for (i = 0; i < attr->info.exceptions_attr.number_of_exceptions; i++) {
5437 Eprintf (" Exceptions Attribute Index[%d]: %d\n", i, attr->info.exceptions_attr.exception_idx_table[i]);
5438 }
5439 }
5440
r_bin_java_print_classes_attr_summary(RBinJavaClassesAttribute * icattr)5441 R_API void r_bin_java_print_classes_attr_summary(RBinJavaClassesAttribute *icattr) {
5442 if (!icattr) {
5443 eprintf ("Attempting to print an invalid RBinJavaClassesAttribute* (InnerClasses element).\n");
5444 return;
5445 }
5446 eprintf (" Inner Classes Class Attribute Offset: 0x%08"PFMT64x "\n", icattr->file_offset);
5447 eprintf (" Inner Classes Class Attribute Class Name (%d): %s\n", icattr->inner_name_idx, icattr->name);
5448 eprintf (" Inner Classes Class Attribute Class inner_class_info_idx: %d\n", icattr->inner_class_info_idx);
5449 eprintf (" Inner Classes Class Attribute Class inner_class_access_flags: 0x%02x %s\n", icattr->inner_class_access_flags, icattr->flags_str);
5450 eprintf (" Inner Classes Class Attribute Class outer_class_info_idx: %d\n", icattr->outer_class_info_idx);
5451 eprintf (" Inner Classes Class Field Information:\n");
5452 r_bin_java_print_field_summary (icattr->clint_field);
5453 eprintf (" Inner Classes Class Field Information:\n");
5454 r_bin_java_print_field_summary (icattr->clint_field);
5455 eprintf (" Inner Classes Class Attr Info Information:\n");
5456 r_bin_java_print_attr_summary (icattr->clint_attr);
5457 }
5458
r_bin_java_print_inner_classes_attr_summary(RBinJavaAttrInfo * attr)5459 R_API void r_bin_java_print_inner_classes_attr_summary(RBinJavaAttrInfo *attr) {
5460 RBinJavaClassesAttribute *icattr;
5461 RListIter *iter, *iter_tmp;
5462 if (!attr) {
5463 eprintf ("Attempting to print an invalid RBinJavaAttrInfo *InnerClasses.\n");
5464 return;
5465 }
5466 Eprintf ("Inner Classes Attribute Information:\n");
5467 Eprintf (" Attribute Offset: 0x%08"PFMT64x "\n", attr->file_offset);
5468 Eprintf (" Attribute Name Index: %d (%s)\n", attr->name_idx, attr->name);
5469 Eprintf (" Attribute Length: %d\n", attr->length);
5470 r_list_foreach_safe (attr->info.inner_classes_attr.classes, iter, iter_tmp, icattr) {
5471 r_bin_java_print_classes_attr_summary (icattr);
5472 }
5473 }
5474
r_bin_java_print_line_number_attr_summary(RBinJavaLineNumberAttribute * lnattr)5475 R_API void r_bin_java_print_line_number_attr_summary(RBinJavaLineNumberAttribute *lnattr) {
5476 if (!lnattr) {
5477 eprintf ("Attempting to print an invalid RBinJavaLineNumberAttribute *.\n");
5478 return;
5479 }
5480 Eprintf (" Line Number Attribute Offset: 0x%08"PFMT64x "\n", lnattr->file_offset);
5481 Eprintf (" Line Number Attribute StartPC: %d\n", lnattr->start_pc);
5482 Eprintf (" Line Number Attribute LineNumber: %d\n", lnattr->line_number);
5483 }
5484
r_bin_java_print_line_number_table_attr_summary(RBinJavaAttrInfo * attr)5485 R_API void r_bin_java_print_line_number_table_attr_summary(RBinJavaAttrInfo *attr) {
5486 RBinJavaLineNumberAttribute *lnattr;
5487 RListIter *iter, *iter_tmp;
5488 if (!attr) {
5489 eprintf ("Attempting to print an invalid RBinJavaAttrInfo *LineNumberTable.\n");
5490 return;
5491 }
5492 Eprintf ("Line Number Table Attribute Information:\n");
5493 Eprintf (" Attribute Offset: 0x%08"PFMT64x "\n", attr->file_offset);
5494 Eprintf (" Attribute Name Index: %d (%s)\n", attr->name_idx, attr->name);
5495 Eprintf (" Attribute Length: %d\n", attr->length);
5496 r_list_foreach_safe (attr->info.line_number_table_attr.line_number_table, iter, iter_tmp, lnattr) {
5497 r_bin_java_print_line_number_attr_summary (lnattr);
5498 }
5499 }
5500
r_bin_java_print_local_variable_attr_summary(RBinJavaLocalVariableAttribute * lvattr)5501 R_API void r_bin_java_print_local_variable_attr_summary(RBinJavaLocalVariableAttribute *lvattr) {
5502 if (!lvattr) {
5503 eprintf ("Attempting to print an invalid RBinJavaLocalVariableAttribute *.\n");
5504 return;
5505 }
5506 Eprintf (" Local Variable Attribute offset: 0x%08"PFMT64x "\n", lvattr->file_offset);
5507 Eprintf (" Local Variable Attribute start_pc: %d\n", lvattr->start_pc);
5508 Eprintf (" Local Variable Attribute Length: %d\n", lvattr->length);
5509 Eprintf (" Local Variable Attribute name_idx: %d\n", lvattr->name_idx);
5510 Eprintf (" Local Variable Attribute name: %s\n", lvattr->name);
5511 Eprintf (" Local Variable Attribute descriptor_idx: %d\n", lvattr->descriptor_idx);
5512 Eprintf (" Local Variable Attribute descriptor: %s\n", lvattr->descriptor);
5513 Eprintf (" Local Variable Attribute index: %d\n", lvattr->index);
5514 }
5515
r_bin_java_print_local_variable_table_attr_summary(RBinJavaAttrInfo * attr)5516 R_API void r_bin_java_print_local_variable_table_attr_summary(RBinJavaAttrInfo *attr) {
5517 RBinJavaLocalVariableAttribute *lvattr;
5518 RListIter *iter, *iter_tmp;
5519 if (attr == NULL) {
5520 eprintf ("Attempting to print an invalid RBinJavaAttrInfo *LocalVariableTable.\n");
5521 return;
5522 }
5523 Eprintf ("Local Variable Table Attribute Information:\n");
5524 Eprintf (" Attribute Offset: 0x%08"PFMT64x "\n", attr->file_offset);
5525 Eprintf (" Attribute Name Index: %d (%s)\n", attr->name_idx, attr->name);
5526 Eprintf (" Attribute Length: %d\n", attr->length);
5527 r_list_foreach_safe (attr->info.local_variable_table_attr.local_variable_table, iter, iter_tmp, lvattr) {
5528 r_bin_java_print_local_variable_attr_summary (lvattr);
5529 }
5530 }
5531
r_bin_java_print_local_variable_type_attr_summary(RBinJavaLocalVariableTypeAttribute * lvattr)5532 R_API void r_bin_java_print_local_variable_type_attr_summary(RBinJavaLocalVariableTypeAttribute *lvattr) {
5533 if (!lvattr) {
5534 eprintf ("Attempting to print an invalid RBinJavaLocalVariableTypeAttribute *.\n");
5535 return;
5536 }
5537 eprintf (" Local Variable Type Attribute offset: 0x%08"PFMT64x "\n", lvattr->file_offset);
5538 eprintf (" Local Variable Type Attribute start_pc: %d\n", lvattr->start_pc);
5539 eprintf (" Local Variable Type Attribute Length: %d\n", lvattr->length);
5540 eprintf (" Local Variable Type Attribute name_idx: %d\n", lvattr->name_idx);
5541 eprintf (" Local Variable Type Attribute name: %s\n", lvattr->name);
5542 eprintf (" Local Variable Type Attribute signature_idx: %d\n", lvattr->signature_idx);
5543 eprintf (" Local Variable Type Attribute signature: %s\n", lvattr->signature);
5544 eprintf (" Local Variable Type Attribute index: %d\n", lvattr->index);
5545 }
5546
r_bin_java_print_local_variable_type_table_attr_summary(RBinJavaAttrInfo * attr)5547 R_API void r_bin_java_print_local_variable_type_table_attr_summary(RBinJavaAttrInfo *attr) {
5548 RBinJavaLocalVariableTypeAttribute *lvtattr;
5549 RListIter *iter, *iter_tmp;
5550 if (!attr) {
5551 eprintf ("Attempting to print an invalid RBinJavaAttrInfo *LocalVariableTable.\n");
5552 return;
5553 }
5554 eprintf ("Local Variable Type Table Attribute Information:\n");
5555 eprintf (" Attribute Offset: 0x%08"PFMT64x "\n", attr->file_offset);
5556 eprintf (" Attribute Name Index: %d (%s)\n", attr->name_idx, attr->name);
5557 eprintf (" Attribute Length: %d\n", attr->length);
5558 r_list_foreach_safe (attr->info.local_variable_type_table_attr.local_variable_table, iter, iter_tmp, lvtattr) {
5559 r_bin_java_print_local_variable_type_attr_summary (lvtattr);
5560 }
5561 }
5562
r_bin_java_print_signature_attr_summary(RBinJavaAttrInfo * attr)5563 R_API void r_bin_java_print_signature_attr_summary(RBinJavaAttrInfo *attr) {
5564 if (!attr) {
5565 eprintf ("Attempting to print an invalid RBinJavaAttrInfo *SignatureAttr.\n");
5566 return;
5567 }
5568 Eprintf ("Signature Attribute Information:\n");
5569 Eprintf (" Attribute Offset: 0x%08"PFMT64x "\n", attr->file_offset);
5570 Eprintf (" Attribute Name Index: %d (%s)\n", attr->name_idx, attr->name);
5571 Eprintf (" Attribute Length: %d\n", attr->length);
5572 Eprintf (" Signature UTF8 Index: %d\n", attr->info.signature_attr.signature_idx);
5573 Eprintf (" Signature string: %s\n", attr->info.signature_attr.signature);
5574 }
5575
r_bin_java_print_source_code_file_attr_summary(RBinJavaAttrInfo * attr)5576 R_API void r_bin_java_print_source_code_file_attr_summary(RBinJavaAttrInfo *attr) {
5577 if (!attr) {
5578 eprintf ("Attempting to print an invalid RBinJavaAttrInfo *SourceFile.\n");
5579 return;
5580 }
5581 Eprintf ("Source File Attribute Information:\n");
5582 Eprintf (" Attribute Offset: 0x%08"PFMT64x "\n", attr->file_offset);
5583 Eprintf (" Attribute Name Index: %d (%s)\n", attr->name_idx, attr->name);
5584 Eprintf (" Attribute Length: %d\n", attr->length);
5585 Eprintf (" Source File Index: %d\n", attr->info.source_file_attr.sourcefile_idx);
5586 }
5587
r_bin_java_print_synthetic_attr_summary(RBinJavaAttrInfo * attr)5588 R_API void r_bin_java_print_synthetic_attr_summary(RBinJavaAttrInfo *attr) {
5589 if (attr == NULL) {
5590 eprintf ("Attempting to print an invalid RBinJavaAttrInfo *Synthetic.\n");
5591 return;
5592 }
5593 Eprintf ("Synthetic Attribute Information:\n");
5594 Eprintf (" Attribute Offset: 0x%08"PFMT64x "\n", attr->file_offset);
5595 Eprintf (" Attribute Name Index: %d (%s)\n", attr->name_idx, attr->name);
5596 Eprintf (" Attribute Length: %d\n", attr->length);
5597 Eprintf (" Attribute Index: %d\n", attr->info.source_file_attr.sourcefile_idx);
5598 }
5599
r_bin_java_print_stack_map_table_attr_summary(RBinJavaAttrInfo * attr)5600 R_API void r_bin_java_print_stack_map_table_attr_summary(RBinJavaAttrInfo *attr) {
5601 RListIter *iter, *iter_tmp;
5602 RList *ptrList;
5603 RBinJavaStackMapFrame *frame;
5604 if (attr == NULL) {
5605 eprintf ("Attempting to print an invalid RBinJavaStackMapTableAttr* .\n");
5606 return;
5607 }
5608 Eprintf ("StackMapTable Attribute Information:\n");
5609 Eprintf (" Attribute Offset: 0x%08"PFMT64x "\n", attr->file_offset);
5610 Eprintf (" Attribute Name Index: %d (%s)\n", attr->name_idx, attr->name);
5611 Eprintf (" Attribute Length: %d\n", attr->length);
5612 Eprintf (" StackMapTable Method Code Size: 0x%08x\n", attr->info.stack_map_table_attr.code_size);
5613 Eprintf (" StackMapTable Frame Entries: 0x%08x\n", attr->info.stack_map_table_attr.number_of_entries);
5614 Eprintf (" StackMapTable Frames:\n");
5615 ptrList = attr->info.stack_map_table_attr.stack_map_frame_entries;
5616 if (ptrList) {
5617 r_list_foreach_safe (ptrList, iter, iter_tmp, frame) {
5618 r_bin_java_print_stack_map_frame_summary (frame);
5619 }
5620 }
5621 }
5622
r_bin_java_print_stack_map_frame_summary(RBinJavaStackMapFrame * obj)5623 R_API void r_bin_java_print_stack_map_frame_summary(RBinJavaStackMapFrame *obj) {
5624 RListIter *iter, *iter_tmp;
5625 RList *ptrList;
5626 RBinJavaVerificationObj *ver_obj;
5627 if (obj == NULL) {
5628 eprintf ("Attempting to print an invalid RBinJavaStackMapFrame* .\n");
5629 return;
5630 }
5631 Eprintf ("Stack Map Frame Information\n");
5632 Eprintf (" Tag Value = 0x%02x Name: %s\n", obj->tag, ((RBinJavaStackMapFrameMetas *) obj->metas->type_info)->name);
5633 Eprintf (" Offset: 0x%08"PFMT64x "\n", obj->file_offset);
5634 Eprintf (" Local Variable Count = 0x%04x\n", obj->number_of_locals);
5635 Eprintf (" Stack Items Count = 0x%04x\n", obj->number_of_stack_items);
5636 Eprintf (" Local Variables:\n");
5637 ptrList = obj->local_items;
5638 r_list_foreach_safe (ptrList, iter, iter_tmp, ver_obj) {
5639 r_bin_java_print_verification_info_summary (ver_obj);
5640 }
5641 Eprintf (" Stack Items:\n");
5642 ptrList = obj->stack_items;
5643 r_list_foreach_safe (ptrList, iter, iter_tmp, ver_obj) {
5644 r_bin_java_print_verification_info_summary (ver_obj);
5645 }
5646 }
5647
r_bin_java_print_verification_info_summary(RBinJavaVerificationObj * obj)5648 R_API void r_bin_java_print_verification_info_summary(RBinJavaVerificationObj *obj) {
5649 ut8 tag_value = R_BIN_JAVA_STACKMAP_UNKNOWN;
5650 if (obj == NULL) {
5651 eprintf ("Attempting to print an invalid RBinJavaVerificationObj* .\n");
5652 return;
5653 }
5654 if (obj->tag < R_BIN_JAVA_STACKMAP_UNKNOWN) {
5655 tag_value = obj->tag;
5656 }
5657 Eprintf ("Verification Information\n");
5658 Eprintf (" Offset: 0x%08"PFMT64x "", obj->file_offset);
5659 Eprintf (" Tag Value = 0x%02x\n", obj->tag);
5660 Eprintf (" Name = %s\n", R_BIN_JAVA_VERIFICATION_METAS[tag_value].name);
5661 if (obj->tag == R_BIN_JAVA_STACKMAP_OBJECT) {
5662 Eprintf (" Object Constant Pool Index = 0x%x\n", obj->info.obj_val_cp_idx);
5663 } else if (obj->tag == R_BIN_JAVA_STACKMAP_UNINIT) {
5664 Eprintf (" Uninitialized Object offset in code = 0x%x\n", obj->info.uninit_offset);
5665 }
5666 }
5667
r_bin_java_print_field_summary(RBinJavaField * field)5668 R_API void r_bin_java_print_field_summary(RBinJavaField *field) {
5669 RBinJavaAttrInfo *attr;
5670 RListIter *iter, *iter_tmp;
5671 if (field) {
5672 if (field->type == R_BIN_JAVA_FIELD_TYPE_METHOD) {
5673 r_bin_java_print_method_summary (field);
5674 } else {
5675 #if 0
5676 r_bin_java_print_interface_summary (field);
5677 return;
5678 } * /
5679 #endif
5680 Eprintf ("Field Summary Information:\n");
5681 Eprintf (" File Offset: 0x%08"PFMT64x "\n", field->file_offset);
5682 Eprintf (" Name Index: %d (%s)\n", field->name_idx, field->name);
5683 Eprintf (" Descriptor Index: %d (%s)\n", field->descriptor_idx, field->descriptor);
5684 Eprintf (" Access Flags: 0x%02x (%s)\n", field->flags, field->flags_str);
5685 Eprintf (" Field Attributes Count: %d\n", field->attr_count);
5686 Eprintf (" Field Attributes:\n");
5687 r_list_foreach_safe (field->attributes, iter, iter_tmp, attr) {
5688 r_bin_java_print_attr_summary (attr);
5689 }
5690 }
5691 } else {
5692 eprintf ("Attempting to print an invalid RBinJavaField* Field.\n");
5693 }
5694 }
5695
r_bin_java_print_method_summary(RBinJavaField * field)5696 R_API void r_bin_java_print_method_summary(RBinJavaField *field) {
5697 RBinJavaAttrInfo *attr;
5698 RListIter *iter, *iter_tmp;
5699 if (field == NULL) {
5700 eprintf ("Attempting to print an invalid RBinJavaField* Method.\n");
5701 return;
5702 }
5703 Eprintf ("Method Summary Information:\n");
5704 Eprintf (" File Offset: 0x%08"PFMT64x "\n", field->file_offset);
5705 Eprintf (" Name Index: %d (%s)\n", field->name_idx, field->name);
5706 Eprintf (" Descriptor Index: %d (%s)\n", field->descriptor_idx, field->descriptor);
5707 Eprintf (" Access Flags: 0x%02x (%s)\n", field->flags, field->flags_str);
5708 Eprintf (" Method Attributes Count: %d\n", field->attr_count);
5709 Eprintf (" Method Attributes:\n");
5710 r_list_foreach_safe (field->attributes, iter, iter_tmp, attr) {
5711 r_bin_java_print_attr_summary (attr);
5712 }
5713 }
5714 /*
5715 R_API void r_bin_java_print_interface_summary(ut16 idx) {//RBinJavaField *field) {
5716 RBinJavaAttrInfo *attr;
5717 RBinJavaCPTypeObj *class_info;
5718 RListIter *iter, *iter_tmp;
5719 if (field == NULL) {
5720 eprintf ("Attempting to print an invalid RBinJavaField* Interface.\n");
5721 return;
5722 }
5723 eprintf ("Interface Summary Information:\n");
5724 eprintf (" File offset: 0x%08"PFMT64x"", field->file_offset);
5725 eprintf (" Access Flags: %d\n", field->flags);
5726 eprintf (" Name Index: %d (%s)\n", field->name_idx, field->name);
5727 eprintf (" Descriptor Index: %d (%s)\n", field->descriptor_idx, field->descriptor);
5728 eprintf (" Interface Attributes Count: %d\n", field->attr_count);
5729 eprintf (" Interface Attributes:\n");
5730 r_list_foreach_safe (field->attributes, iter, iter_tmp, attr) {
5731 r_bin_java_print_attr_summary(attr);
5732 }
5733 }
5734 */
r_bin_java_print_interfacemethodref_cp_summary(RBinJavaCPTypeObj * obj)5735 R_API void r_bin_java_print_interfacemethodref_cp_summary(RBinJavaCPTypeObj *obj) {
5736 if (obj == NULL) {
5737 eprintf ("Attempting to print an invalid RBinJavaCPTypeObj* InterfaceMethodRef.\n");
5738 return;
5739 }
5740 eprintf ("InterfaceMethodRef ConstantPool Type (%d) ", obj->metas->ord);
5741 eprintf (" Offset: 0x%08"PFMT64x"", obj->file_offset);
5742 eprintf (" Class Index = %d\n", obj->info.cp_interface.class_idx);
5743 eprintf (" Name and type Index = %d\n", obj->info.cp_interface.name_and_type_idx);
5744 }
5745
r_bin_java_print_interfacemethodref_cp_stringify(RBinJavaCPTypeObj * obj)5746 R_API char *r_bin_java_print_interfacemethodref_cp_stringify(RBinJavaCPTypeObj *obj) {
5747 ut32 size = 255, consumed = 0;
5748 char *value = malloc (size);
5749 if (value) {
5750 memset (value, 0, size);
5751 consumed = snprintf (value, size, "%d.0x%04"PFMT64x ".%s.%d.%d",
5752 obj->metas->ord, obj->file_offset + obj->loadaddr, ((RBinJavaCPTypeMetas *) obj->metas->type_info)->name,
5753 obj->info.cp_interface.class_idx, obj->info.cp_interface.name_and_type_idx);
5754 if (consumed >= size - 1) {
5755 free (value);
5756 size += size >> 1;
5757 value = malloc (size);
5758 if (value) {
5759 memset (value, 0, size);
5760 (void)snprintf (value, size, "%d.0x%04"PFMT64x ".%s.%d.%d",
5761 obj->metas->ord, obj->file_offset + obj->loadaddr, ((RBinJavaCPTypeMetas *) obj->metas->type_info)->name,
5762 obj->info.cp_interface.class_idx, obj->info.cp_interface.name_and_type_idx);
5763 }
5764 }
5765 }
5766 return value;
5767 }
5768
r_bin_java_print_methodhandle_cp_summary(RBinJavaCPTypeObj * obj)5769 R_API void r_bin_java_print_methodhandle_cp_summary(RBinJavaCPTypeObj *obj) {
5770 ut8 ref_kind;
5771 if (obj == NULL) {
5772 eprintf ("Attempting to print an invalid RBinJavaCPTypeObj* RBinJavaCPTypeMethodHandle.\n");
5773 return;
5774 }
5775 ref_kind = obj->info.cp_method_handle.reference_kind;
5776 eprintf ("MethodHandle ConstantPool Type (%d) ", obj->metas->ord);
5777 eprintf (" Offset: 0x%08"PFMT64x"", obj->file_offset);
5778 eprintf (" Reference Kind = (0x%02x) %s\n", ref_kind, R_BIN_JAVA_REF_METAS[ref_kind].name);
5779 eprintf (" Reference Index = %d\n", obj->info.cp_method_handle.reference_index);
5780 }
5781
r_bin_java_print_methodhandle_cp_stringify(RBinJavaCPTypeObj * obj)5782 R_API char *r_bin_java_print_methodhandle_cp_stringify(RBinJavaCPTypeObj *obj) {
5783 ut32 size = 255, consumed = 0;
5784 char *value = malloc (size);
5785 ut8 ref_kind = obj->info.cp_method_handle.reference_kind;
5786 if (value) {
5787 memset (value, 0, size);
5788 consumed = snprintf (value, size, "%d.0x%04"PFMT64x ".%s.%s.%d",
5789 obj->metas->ord, obj->file_offset + obj->loadaddr, ((RBinJavaCPTypeMetas *) obj->metas->type_info)->name,
5790 R_BIN_JAVA_REF_METAS[ref_kind].name, obj->info.cp_method_handle.reference_index);
5791 if (consumed >= size - 1) {
5792 free (value);
5793 size += size >> 1;
5794 value = malloc (size);
5795 if (value) {
5796 memset (value, 0, size);
5797 (void)snprintf (value, size, "%d.0x%04"PFMT64x ".%s.%s.%d",
5798 obj->metas->ord, obj->file_offset + obj->loadaddr, ((RBinJavaCPTypeMetas *) obj->metas->type_info)->name,
5799 R_BIN_JAVA_REF_METAS[ref_kind].name, obj->info.cp_method_handle.reference_index);
5800 }
5801 }
5802 }
5803 return value;
5804 }
5805
r_bin_java_print_methodtype_cp_summary(RBinJavaCPTypeObj * obj)5806 R_API void r_bin_java_print_methodtype_cp_summary(RBinJavaCPTypeObj *obj) {
5807 if (obj == NULL) {
5808 eprintf ("Attempting to print an invalid RBinJavaCPTypeObj* RBinJavaCPTypeMethodType.\n");
5809 return;
5810 }
5811 Eprintf ("MethodType ConstantPool Type (%d) ", obj->metas->ord);
5812 Eprintf (" Offset: 0x%08"PFMT64x "", obj->file_offset);
5813 Eprintf (" Descriptor Index = 0x%02x\n", obj->info.cp_method_type.descriptor_index);
5814 }
5815
r_bin_java_print_methodtype_cp_stringify(RBinJavaCPTypeObj * obj)5816 R_API char *r_bin_java_print_methodtype_cp_stringify(RBinJavaCPTypeObj *obj) {
5817 ut32 size = 255, consumed = 0;
5818 char *value = malloc (size);
5819 if (value) {
5820 memset (value, 0, size);
5821 consumed = snprintf (value, size, "%d.0x%04"PFMT64x ".%s.%d",
5822 obj->metas->ord, obj->file_offset + obj->loadaddr, ((RBinJavaCPTypeMetas *) obj->metas->type_info)->name,
5823 obj->info.cp_method_type.descriptor_index);
5824 if (consumed >= size - 1) {
5825 free (value);
5826 size += size >> 1;
5827 value = malloc (size);
5828 if (value) {
5829 memset (value, 0, size);
5830 (void)snprintf (value, size, "%d.0x%04"PFMT64x ".%s.%d",
5831 obj->metas->ord, obj->file_offset + obj->loadaddr, ((RBinJavaCPTypeMetas *) obj->metas->type_info)->name,
5832 obj->info.cp_method_type.descriptor_index);
5833 }
5834 }
5835 }
5836 return value;
5837 }
5838
r_bin_java_print_invokedynamic_cp_summary(RBinJavaCPTypeObj * obj)5839 R_API void r_bin_java_print_invokedynamic_cp_summary(RBinJavaCPTypeObj *obj) {
5840 if (obj == NULL) {
5841 eprintf ("Attempting to print an invalid RBinJavaCPTypeObj* RBinJavaCPTypeInvokeDynamic.\n");
5842 return;
5843 }
5844 eprintf ("InvokeDynamic ConstantPool Type (%d) ", obj->metas->ord);
5845 eprintf (" Offset: 0x%08"PFMT64x"", obj->file_offset);
5846 eprintf (" Bootstrap Method Attr Index = (0x%02x)\n", obj->info.cp_invoke_dynamic.bootstrap_method_attr_index);
5847 eprintf (" Bootstrap Name and Type Index = (0x%02x)\n", obj->info.cp_invoke_dynamic.name_and_type_index);
5848 }
5849
r_bin_java_print_invokedynamic_cp_stringify(RBinJavaCPTypeObj * obj)5850 R_API char *r_bin_java_print_invokedynamic_cp_stringify(RBinJavaCPTypeObj *obj) {
5851 ut32 size = 255, consumed = 0;
5852 char *value = malloc (size);
5853 if (value) {
5854 memset (value, 0, size);
5855 consumed = snprintf (value, size, "%d.0x%04"PFMT64x ".%s.%d.%d",
5856 obj->metas->ord, obj->file_offset + obj->loadaddr, ((RBinJavaCPTypeMetas *) obj->metas->type_info)->name,
5857 obj->info.cp_invoke_dynamic.bootstrap_method_attr_index,
5858 obj->info.cp_invoke_dynamic.name_and_type_index);
5859 if (consumed >= size - 1) {
5860 free (value);
5861 size += size >> 1;
5862 value = malloc (size);
5863 if (value) {
5864 memset (value, 0, size);
5865 (void)snprintf (value, size, "%d.0x%04"PFMT64x ".%s.%d.%d",
5866 obj->metas->ord, obj->file_offset + obj->loadaddr, ((RBinJavaCPTypeMetas *) obj->metas->type_info)->name,
5867 obj->info.cp_invoke_dynamic.bootstrap_method_attr_index,
5868 obj->info.cp_invoke_dynamic.name_and_type_index);
5869 }
5870 }
5871 }
5872 return value;
5873 }
5874
r_bin_java_print_methodref_cp_summary(RBinJavaCPTypeObj * obj)5875 R_API void r_bin_java_print_methodref_cp_summary(RBinJavaCPTypeObj *obj) {
5876 if (obj == NULL) {
5877 eprintf ("Attempting to print an invalid RBinJavaCPTypeObj* MethodRef.\n");
5878 return;
5879 }
5880 eprintf ("MethodRef ConstantPool Type (%d) ", obj->metas->ord);
5881 eprintf (" Offset: 0x%08"PFMT64x"", obj->file_offset);
5882 eprintf (" Class Index = %d\n", obj->info.cp_method.class_idx);
5883 eprintf (" Name and type Index = %d\n", obj->info.cp_method.name_and_type_idx);
5884 }
5885
r_bin_java_print_methodref_cp_stringify(RBinJavaCPTypeObj * obj)5886 R_API char *r_bin_java_print_methodref_cp_stringify(RBinJavaCPTypeObj *obj) {
5887 ut32 size = 255, consumed = 0;
5888 char *value = malloc (size);
5889 if (value) {
5890 memset (value, 0, size);
5891 consumed = snprintf (value, size, "%d.0x%04"PFMT64x ".%s.%d.%d",
5892 obj->metas->ord, obj->file_offset + obj->loadaddr, ((RBinJavaCPTypeMetas *) obj->metas->type_info)->name,
5893 obj->info.cp_method.class_idx,
5894 obj->info.cp_method.name_and_type_idx);
5895 if (consumed >= size - 1) {
5896 free (value);
5897 size += size >> 1;
5898 value = malloc (size);
5899 if (value) {
5900 memset (value, 0, size);
5901 (void)snprintf (value, size, "%d.0x%04"PFMT64x ".%s.%d.%d",
5902 obj->metas->ord, obj->file_offset + obj->loadaddr, ((RBinJavaCPTypeMetas *) obj->metas->type_info)->name,
5903 obj->info.cp_method.class_idx,
5904 obj->info.cp_method.name_and_type_idx);
5905 }
5906 }
5907 }
5908 return value;
5909 }
5910
r_bin_java_print_fieldref_cp_summary(RBinJavaCPTypeObj * obj)5911 R_API void r_bin_java_print_fieldref_cp_summary(RBinJavaCPTypeObj *obj) {
5912 if (obj == NULL) {
5913 eprintf ("Attempting to print an invalid RBinJavaCPTypeObj* FieldRef.\n");
5914 return;
5915 }
5916 eprintf ("FieldRef ConstantPool Type (%d) ", obj->metas->ord);
5917 eprintf (" Offset: 0x%08"PFMT64x"", obj->file_offset);
5918 eprintf (" Class Index = %d\n", obj->info.cp_field.class_idx);
5919 eprintf (" Name and type Index = %d\n", obj->info.cp_field.name_and_type_idx);
5920 }
5921
r_bin_java_print_fieldref_cp_stringify(RBinJavaCPTypeObj * obj)5922 R_API char *r_bin_java_print_fieldref_cp_stringify(RBinJavaCPTypeObj *obj) {
5923 ut32 size = 255, consumed = 0;
5924 char *value = malloc (size);
5925 if (value) {
5926 memset (value, 0, size);
5927 consumed = snprintf (value, size, "%d.0x%04"PFMT64x ".%s.%d.%d",
5928 obj->metas->ord, obj->file_offset + obj->loadaddr, ((RBinJavaCPTypeMetas *) obj->metas->type_info)->name,
5929 obj->info.cp_field.class_idx,
5930 obj->info.cp_field.name_and_type_idx);
5931 if (consumed >= size - 1) {
5932 free (value);
5933 size += size >> 1;
5934 value = malloc (size);
5935 if (value) {
5936 memset (value, 0, size);
5937 (void)snprintf (value, size, "%d.0x%04"PFMT64x ".%s.%d.%d",
5938 obj->metas->ord, obj->file_offset + obj->loadaddr, ((RBinJavaCPTypeMetas *) obj->metas->type_info)->name,
5939 obj->info.cp_field.class_idx,
5940 obj->info.cp_field.name_and_type_idx);
5941 }
5942 }
5943 }
5944 return value;
5945 }
5946
r_bin_java_print_classref_cp_summary(RBinJavaCPTypeObj * obj)5947 R_API void r_bin_java_print_classref_cp_summary(RBinJavaCPTypeObj *obj) {
5948 if (obj == NULL) {
5949 eprintf ("Attempting to print an invalid RBinJavaCPTypeObj* ClassRef.\n");
5950 return;
5951 }
5952 eprintf ("ClassRef ConstantPool Type (%d) ", obj->metas->ord);
5953 eprintf (" Offset: 0x%08"PFMT64x"", obj->file_offset);
5954 eprintf (" Name Index = %d\n", obj->info.cp_class.name_idx);
5955 }
5956
r_bin_java_print_classref_cp_stringify(RBinJavaCPTypeObj * obj)5957 R_API char *r_bin_java_print_classref_cp_stringify(RBinJavaCPTypeObj *obj) {
5958 ut32 size = 255, consumed = 0;
5959 char *value = malloc (size);
5960 if (value) {
5961 memset (value, 0, size);
5962 consumed = snprintf (value, size, "%d.0x%04"PFMT64x ".%s.%d",
5963 obj->metas->ord, obj->file_offset + obj->loadaddr, ((RBinJavaCPTypeMetas *) obj->metas->type_info)->name,
5964 obj->info.cp_class.name_idx);
5965 if (consumed >= size - 1) {
5966 free (value);
5967 size += size >> 1;
5968 value = malloc (size);
5969 if (value) {
5970 memset (value, 0, size);
5971 (void)snprintf (value, size, "%d.0x%04"PFMT64x ".%s.%d",
5972 obj->metas->ord, obj->file_offset + obj->loadaddr, ((RBinJavaCPTypeMetas *) obj->metas->type_info)->name,
5973 obj->info.cp_class.name_idx);
5974 }
5975 }
5976 }
5977 return value;
5978 }
5979
r_bin_java_print_string_cp_summary(RBinJavaCPTypeObj * obj)5980 R_API void r_bin_java_print_string_cp_summary(RBinJavaCPTypeObj *obj) {
5981 if (!obj) {
5982 eprintf ("Attempting to print an invalid RBinJavaCPTypeObj* String.\n");
5983 return;
5984 }
5985 Eprintf ("String ConstantPool Type (%d) ", obj->metas->ord);
5986 Eprintf (" Offset: 0x%08"PFMT64x "", obj->file_offset);
5987 Eprintf (" String Index = %d\n", obj->info.cp_string.string_idx);
5988 }
5989
r_bin_java_print_string_cp_stringify(RBinJavaCPTypeObj * obj)5990 R_API char *r_bin_java_print_string_cp_stringify(RBinJavaCPTypeObj *obj) {
5991 ut32 size = 255, consumed = 0;
5992 char *value = malloc (size);
5993 if (value) {
5994 memset (value, 0, size);
5995 consumed = snprintf (value, size, "%d.0x%04"PFMT64x ".%s.%d",
5996 obj->metas->ord, obj->file_offset + obj->loadaddr, ((RBinJavaCPTypeMetas *) obj->metas->type_info)->name,
5997 obj->info.cp_string.string_idx);
5998 if (consumed >= size - 1) {
5999 free (value);
6000 size += size >> 1;
6001 value = malloc (size);
6002 if (value) {
6003 memset (value, 0, size);
6004 (void)snprintf (value, size, "%d.0x%04"PFMT64x ".%s.%d",
6005 obj->metas->ord, obj->file_offset,
6006 ((RBinJavaCPTypeMetas *) obj->metas->type_info)->name,
6007 obj->info.cp_string.string_idx);
6008 }
6009 }
6010 }
6011 return value;
6012 }
6013
r_bin_java_print_integer_cp_summary(RBinJavaCPTypeObj * obj)6014 R_API void r_bin_java_print_integer_cp_summary(RBinJavaCPTypeObj *obj) {
6015 ut8 *b = NULL;
6016 if (obj == NULL) {
6017 eprintf ("Attempting to print an invalid RBinJavaCPTypeObj* Integer.\n");
6018 return;
6019 }
6020 b = obj->info.cp_integer.bytes.raw;
6021 eprintf ("Integer ConstantPool Type (%d) ", obj->metas->ord);
6022 eprintf (" Offset: 0x%08"PFMT64x"", obj->file_offset);
6023 eprintf (" bytes = %02x %02x %02x %02x\n", b[0], b[1], b[2], b[3]);
6024 eprintf (" integer = %d\n", R_BIN_JAVA_UINT (obj->info.cp_integer.bytes.raw, 0));
6025 }
6026
r_bin_java_print_integer_cp_stringify(RBinJavaCPTypeObj * obj)6027 R_API char *r_bin_java_print_integer_cp_stringify(RBinJavaCPTypeObj *obj) {
6028 ut32 size = 255, consumed = 0;
6029 char *value = malloc (size);
6030 if (value) {
6031 memset (value, 0, size);
6032 consumed = snprintf (value, size, "%d.0x%04"PFMT64x ".%s.0x%08x",
6033 obj->metas->ord, obj->file_offset + obj->loadaddr, ((RBinJavaCPTypeMetas *) obj->metas->type_info)->name,
6034 R_BIN_JAVA_UINT (obj->info.cp_integer.bytes.raw, 0));
6035 if (consumed >= size - 1) {
6036 free (value);
6037 size += size >> 1;
6038 value = malloc (size);
6039 if (value) {
6040 memset (value, 0, size);
6041 (void)snprintf (value, size, "%d.0x%04"PFMT64x ".%s.0x%08x",
6042 obj->metas->ord, obj->file_offset + obj->loadaddr, ((RBinJavaCPTypeMetas *) obj->metas->type_info)->name,
6043 R_BIN_JAVA_UINT (obj->info.cp_integer.bytes.raw, 0));
6044 }
6045 }
6046 }
6047 return value;
6048 }
6049
r_bin_java_print_float_cp_summary(RBinJavaCPTypeObj * obj)6050 R_API void r_bin_java_print_float_cp_summary(RBinJavaCPTypeObj *obj) {
6051 ut8 *b = NULL;
6052 if (obj == NULL) {
6053 eprintf ("Attempting to print an invalid RBinJavaCPTypeObj* Double.\n");
6054 return;
6055 }
6056 b = obj->info.cp_float.bytes.raw;
6057 Eprintf ("Float ConstantPool Type (%d) ", obj->metas->ord);
6058 Eprintf (" Offset: 0x%08"PFMT64x "", obj->file_offset);
6059 Eprintf (" Bytes = %02x %02x %02x %02x\n", b[0], b[1], b[2], b[3]);
6060 Eprintf (" Float = %f\n", R_BIN_JAVA_FLOAT (obj->info.cp_float.bytes.raw, 0));
6061 }
6062
r_bin_java_print_float_cp_stringify(RBinJavaCPTypeObj * obj)6063 R_API char *r_bin_java_print_float_cp_stringify(RBinJavaCPTypeObj *obj) {
6064 ut32 size = 255, consumed = 0;
6065 char *value = malloc (size);
6066 if (value) {
6067 memset (value, 0, size);
6068 consumed = snprintf (value, size, "%d.0x%04"PFMT64x ".%s.%f",
6069 obj->metas->ord, obj->file_offset + obj->loadaddr, ((RBinJavaCPTypeMetas *) obj->metas->type_info)->name,
6070 R_BIN_JAVA_FLOAT (obj->info.cp_float.bytes.raw, 0));
6071 if (consumed >= size - 1) {
6072 free (value);
6073 size += size >> 1;
6074 value = malloc (size);
6075 if (value) {
6076 memset (value, 0, size);
6077 (void)snprintf (value, size, "%d.0x%04"PFMT64x ".%s.%f",
6078 obj->metas->ord, obj->file_offset + obj->loadaddr, ((RBinJavaCPTypeMetas *) obj->metas->type_info)->name,
6079 R_BIN_JAVA_FLOAT (obj->info.cp_float.bytes.raw, 0));
6080 }
6081 }
6082 }
6083 return value;
6084 }
6085
r_bin_java_print_long_cp_summary(RBinJavaCPTypeObj * obj)6086 R_API void r_bin_java_print_long_cp_summary(RBinJavaCPTypeObj *obj) {
6087 ut8 *b = NULL;
6088 if (obj == NULL) {
6089 eprintf ("Attempting to print an invalid RBinJavaCPTypeObj* Long.\n");
6090 return;
6091 }
6092 b = obj->info.cp_long.bytes.raw;
6093 Eprintf ("Long ConstantPool Type (%d) ", obj->metas->ord);
6094 Eprintf (" Offset: 0x%08"PFMT64x "", obj->file_offset);
6095 Eprintf (" High-Bytes = %02x %02x %02x %02x\n", b[0], b[1], b[2], b[3]);
6096 Eprintf (" Low-Bytes = %02x %02x %02x %02x\n", b[4], b[5], b[6], b[7]);
6097 Eprintf (" Long = %08"PFMT64x "\n", r_bin_java_raw_to_long (obj->info.cp_long.bytes.raw, 0));
6098 }
6099
r_bin_java_print_long_cp_stringify(RBinJavaCPTypeObj * obj)6100 R_API char *r_bin_java_print_long_cp_stringify(RBinJavaCPTypeObj *obj) {
6101 ut32 size = 255, consumed = 0;
6102 char *value = malloc (size);
6103 if (value) {
6104 memset (value, 0, size);
6105 consumed = snprintf (value, size, "%d.0x%04"PFMT64x ".%s.0x%08"PFMT64x "",
6106 obj->metas->ord,
6107 obj->file_offset,
6108 ((RBinJavaCPTypeMetas *) obj->metas->type_info)->name,
6109 r_bin_java_raw_to_long (obj->info.cp_long.bytes.raw, 0));
6110 if (consumed >= size - 1) {
6111 free (value);
6112 size += size >> 1;
6113 value = malloc (size);
6114 if (value) {
6115 memset (value, 0, size);
6116 (void)snprintf (value, size, "%d.0x%04"PFMT64x ".%s.0x%08"PFMT64x "",
6117 obj->metas->ord,
6118 obj->file_offset,
6119 ((RBinJavaCPTypeMetas *) obj->metas->type_info)->name,
6120 r_bin_java_raw_to_long (obj->info.cp_long.bytes.raw, 0));
6121 }
6122 }
6123 }
6124 return value;
6125 }
6126
r_bin_java_print_double_cp_summary(RBinJavaCPTypeObj * obj)6127 R_API void r_bin_java_print_double_cp_summary(RBinJavaCPTypeObj *obj) {
6128 ut8 *b = NULL;
6129 if (!obj) {
6130 eprintf ("Attempting to print an invalid RBinJavaCPTypeObj* Double.\n");
6131 return;
6132 }
6133 b = obj->info.cp_double.bytes.raw;
6134 Eprintf ("Double ConstantPool Type (%d) ", obj->metas->ord);
6135 Eprintf (" Offset: 0x%08"PFMT64x "", obj->file_offset);
6136 Eprintf (" High-Bytes = %02x %02x %02x %02x\n", b[0], b[1], b[2], b[3]);
6137 Eprintf (" Low-Bytes = %02x %02x %02x %02x\n", b[4], b[5], b[6], b[7]);
6138 Eprintf (" Double = %f\n", r_bin_java_raw_to_double (obj->info.cp_double.bytes.raw, 0));
6139 }
6140
r_bin_java_print_double_cp_stringify(RBinJavaCPTypeObj * obj)6141 R_API char *r_bin_java_print_double_cp_stringify(RBinJavaCPTypeObj *obj) {
6142 ut32 size = 255, consumed = 0;
6143 char *value = malloc (size);
6144 if (value) {
6145 memset (value, 0, size);
6146 consumed = snprintf (value, size, "%d.0x%04"PFMT64x ".%s.%f",
6147 obj->metas->ord,
6148 obj->file_offset,
6149 ((RBinJavaCPTypeMetas *) obj->metas->type_info)->name,
6150 r_bin_java_raw_to_double (obj->info.cp_double.bytes.raw, 0));
6151 if (consumed >= size - 1) {
6152 free (value);
6153 size += size >> 1;
6154 value = malloc (size);
6155 if (value) {
6156 memset (value, 0, size);
6157 (void)snprintf (value, size, "%d.0x%04"PFMT64x ".%s.%f",
6158 obj->metas->ord,
6159 obj->file_offset,
6160 ((RBinJavaCPTypeMetas *) obj->metas->type_info)->name,
6161 r_bin_java_raw_to_double (obj->info.cp_double.bytes.raw, 0));
6162 }
6163 }
6164 }
6165 return value;
6166 }
6167
r_bin_java_print_name_and_type_cp_summary(RBinJavaCPTypeObj * obj)6168 R_API void r_bin_java_print_name_and_type_cp_summary(RBinJavaCPTypeObj *obj) {
6169 if (obj == NULL) {
6170 eprintf ("Attempting to print an invalid RBinJavaCPTypeObj* Name_And_Type.\n");
6171 return;
6172 }
6173 Eprintf ("Name_And_Type ConstantPool Type (%d) ", obj->metas->ord);
6174 Eprintf (" Offset: 0x%08"PFMT64x "", obj->file_offset);
6175 Eprintf (" name_idx = (%d)\n", obj->info.cp_name_and_type.name_idx);
6176 Eprintf (" descriptor_idx = (%d)\n", obj->info.cp_name_and_type.descriptor_idx);
6177 }
6178
r_bin_java_print_name_and_type_cp_stringify(RBinJavaCPTypeObj * obj)6179 R_API char *r_bin_java_print_name_and_type_cp_stringify(RBinJavaCPTypeObj *obj) {
6180 ut32 size = 255, consumed = 0;
6181 char *value = malloc (size);
6182 if (value) {
6183 memset (value, 0, size);
6184 consumed = snprintf (value, size, "%d.0x%04"PFMT64x ".%s.%d.%d",
6185 obj->metas->ord, obj->file_offset + obj->loadaddr, ((RBinJavaCPTypeMetas *) obj->metas->type_info)->name,
6186 obj->info.cp_name_and_type.name_idx,
6187 obj->info.cp_name_and_type.descriptor_idx);
6188 if (consumed >= size - 1) {
6189 free (value);
6190 size += size >> 1;
6191 value = malloc (size);
6192 if (value) {
6193 memset (value, 0, size);
6194 (void)snprintf (value, size, "%d.0x%04"PFMT64x ".%s.%d.%d",
6195 obj->metas->ord, obj->file_offset + obj->loadaddr, ((RBinJavaCPTypeMetas *) obj->metas->type_info)->name,
6196 obj->info.cp_name_and_type.name_idx,
6197 obj->info.cp_name_and_type.descriptor_idx);
6198 }
6199 }
6200 }
6201 return value;
6202 }
6203
r_bin_java_print_utf8_cp_summary(RBinJavaCPTypeObj * obj)6204 R_API void r_bin_java_print_utf8_cp_summary(RBinJavaCPTypeObj *obj) {
6205 if (obj == NULL) {
6206 eprintf ("Attempting to print an invalid RBinJavaCPTypeObj* Utf8.\n");
6207 return;
6208 }
6209 char *str = convert_string ((const char *) obj->info.cp_utf8.bytes, obj->info.cp_utf8.length);
6210 eprintf ("UTF8 ConstantPool Type (%d) ", obj->metas->ord);
6211 eprintf (" Offset: 0x%08"PFMT64x"", obj->file_offset);
6212 eprintf (" length = %d\n", obj->info.cp_utf8.length);
6213 eprintf (" utf8 = %s\n", str);
6214 free (str);
6215 }
6216
r_bin_java_print_utf8_cp_stringify(RBinJavaCPTypeObj * obj)6217 R_API char *r_bin_java_print_utf8_cp_stringify(RBinJavaCPTypeObj *obj) {
6218 ut32 size = 255, consumed = 0;
6219 char *utf8_str = r_hex_bin2strdup (obj->info.cp_utf8.bytes, obj->info.cp_utf8.length);
6220 char *value = malloc (size + strlen (utf8_str));
6221 if (value) {
6222 memset (value, 0, size);
6223 consumed = snprintf (value, size, "%d.0x%04"PFMT64x ".%s.%d.%s",
6224 obj->metas->ord, obj->file_offset + obj->loadaddr, ((RBinJavaCPTypeMetas *) obj->metas->type_info)->name,
6225 obj->info.cp_utf8.length,
6226 utf8_str);
6227 if (consumed >= size - 1) {
6228 free (value);
6229 size += size >> 1;
6230 value = malloc (size + strlen (utf8_str));
6231 if (value) {
6232 memset (value, 0, size);
6233 (void)snprintf (value, size, "%d.0x%04"PFMT64x ".%s.%d.%s",
6234 obj->metas->ord, obj->file_offset + obj->loadaddr, ((RBinJavaCPTypeMetas *) obj->metas->type_info)->name,
6235 obj->info.cp_utf8.length,
6236 utf8_str);
6237 }
6238 }
6239 }
6240 free (utf8_str);
6241 return value;
6242 }
6243
r_bin_java_print_null_cp_summary(RBinJavaCPTypeObj * obj)6244 R_API void r_bin_java_print_null_cp_summary(RBinJavaCPTypeObj *obj) {
6245 eprintf ("Unknown ConstantPool Type Tag: 0x%04x .\n", obj->tag);
6246 }
6247
r_bin_java_print_null_cp_stringify(RBinJavaCPTypeObj * obj)6248 R_API char *r_bin_java_print_null_cp_stringify(RBinJavaCPTypeObj *obj) {
6249 ut32 size = 255, consumed = 0;
6250 char *value = malloc (size);
6251 if (value) {
6252 memset (value, 0, size);
6253 consumed = snprintf (value, size, "%d.0x%04"PFMT64x ".%s",
6254 obj->metas->ord, obj->file_offset + obj->loadaddr, ((RBinJavaCPTypeMetas *) obj->metas->type_info)->name);
6255 if (consumed >= size - 1) {
6256 free (value);
6257 size += size >> 1;
6258 value = malloc (size);
6259 if (value) {
6260 memset (value, 0, size);
6261 (void)snprintf (value, size, "%d.0x%04"PFMT64x ".%s",
6262 obj->metas->ord, obj->file_offset,
6263 ((RBinJavaCPTypeMetas *) obj->metas->type_info)->name);
6264 }
6265 }
6266 }
6267 return value;
6268 }
6269
r_bin_java_print_unknown_cp_summary(RBinJavaCPTypeObj * obj)6270 R_API void r_bin_java_print_unknown_cp_summary(RBinJavaCPTypeObj *obj) {
6271 eprintf ("NULL ConstantPool Type.\n");
6272 }
6273
r_bin_java_print_unknown_cp_stringify(RBinJavaCPTypeObj * obj)6274 R_API char *r_bin_java_print_unknown_cp_stringify(RBinJavaCPTypeObj *obj) {
6275 ut32 size = 255;
6276 char *value = malloc (size);
6277 if (value) {
6278 memset (value, 0, size);
6279 snprintf (value, size, "%d.0x%04"PFMT64x ".%s",
6280 obj->metas->ord, obj->file_offset + obj->loadaddr, ((RBinJavaCPTypeMetas *) obj->metas->type_info)->name);
6281 }
6282 return value;
6283 }
6284
r_bin_java_element_pair_new(ut8 * buffer,ut64 sz,ut64 buf_offset)6285 R_API RBinJavaElementValuePair *r_bin_java_element_pair_new(ut8 *buffer, ut64 sz, ut64 buf_offset) {
6286 if (!buffer || sz < 4) {
6287 return NULL;
6288 }
6289 RBinJavaElementValuePair *evp = R_NEW0 (RBinJavaElementValuePair);
6290 if (!evp) {
6291 return NULL;
6292 }
6293 // TODO: What is the signifigance of evp element
6294 evp->element_name_idx = R_BIN_JAVA_USHORT (buffer, 0);
6295 ut64 offset = 2;
6296 evp->file_offset = buf_offset;
6297 evp->name = r_bin_java_get_utf8_from_bin_cp_list (R_BIN_JAVA_GLOBAL_BIN, evp->element_name_idx);
6298 if (!evp->name) {
6299 // TODO: eprintf unable to find the name for the given index
6300 eprintf ("ElementValue Name is invalid.\n");
6301 evp->name = strdup ("UNKNOWN");
6302 }
6303 if (offset >= sz) {
6304 free (evp);
6305 return NULL;
6306 }
6307 evp->value = r_bin_java_element_value_new (buffer + offset, sz - offset, buf_offset + offset);
6308 offset += evp->value->size;
6309 if (offset >= sz) {
6310 free (evp->value);
6311 free (evp);
6312 return NULL;
6313 }
6314 evp->size = offset;
6315 return evp;
6316 }
6317
r_bin_java_print_element_pair_summary(RBinJavaElementValuePair * evp)6318 R_API void r_bin_java_print_element_pair_summary(RBinJavaElementValuePair *evp) {
6319 if (!evp) {
6320 eprintf ("Attempting to print an invalid RBinJavaElementValuePair *pair.\n");
6321 return;
6322 }
6323 Eprintf ("Element Value Pair information:\n");
6324 Eprintf (" EV Pair File Offset: 0x%08"PFMT64x "\n", evp->file_offset);
6325 Eprintf (" EV Pair Element Name index: 0x%02x\n", evp->element_name_idx);
6326 Eprintf (" EV Pair Element Name: %s\n", evp->name);
6327 Eprintf (" EV Pair Element Value:\n");
6328 r_bin_java_print_element_value_summary (evp->value);
6329 }
6330
r_bin_java_print_element_value_summary(RBinJavaElementValue * element_value)6331 R_API void r_bin_java_print_element_value_summary(RBinJavaElementValue *element_value) {
6332 RBinJavaCPTypeObj *obj;
6333 RBinJavaElementValue *ev_element = NULL;
6334 RListIter *iter = NULL, *iter_tmp = NULL;
6335 char *name;
6336 if (!element_value) {
6337 eprintf ("Attempting to print an invalid RBinJavaElementValuePair *pair.\n");
6338 return;
6339 }
6340 name = ((RBinJavaElementValueMetas *) element_value->metas->type_info)->name;
6341 eprintf ("Element Value information:\n");
6342 eprintf (" EV Pair File Offset: 0x%08"PFMT64x "\n", element_value->file_offset);
6343 eprintf (" EV Value Type (%d): %s\n", element_value->tag, name);
6344 switch (element_value->tag) {
6345 case R_BIN_JAVA_EV_TAG_BYTE:
6346 case R_BIN_JAVA_EV_TAG_CHAR:
6347 case R_BIN_JAVA_EV_TAG_DOUBLE:
6348 case R_BIN_JAVA_EV_TAG_FLOAT:
6349 case R_BIN_JAVA_EV_TAG_INT:
6350 case R_BIN_JAVA_EV_TAG_LONG:
6351 case R_BIN_JAVA_EV_TAG_SHORT:
6352 case R_BIN_JAVA_EV_TAG_BOOLEAN:
6353 case R_BIN_JAVA_EV_TAG_STRING:
6354 eprintf (" EV Value Constant Value index: 0x%02x\n", element_value->value.const_value.const_value_idx);
6355 eprintf (" EV Value Constant Value Information:\n");
6356 obj = element_value->value.const_value.const_value_cp_obj;
6357 if (obj && obj->metas && obj->metas->type_info) {
6358 ((RBinJavaCPTypeMetas *) obj->metas->type_info)->allocs->print_summary (obj);
6359 }
6360 break;
6361 case R_BIN_JAVA_EV_TAG_ENUM:
6362 eprintf (" EV Value Enum Constant Value Const Name Index: 0x%02x\n", element_value->value.enum_const_value.const_name_idx);
6363 eprintf (" EV Value Enum Constant Value Type Name Index: 0x%02x\n", element_value->value.enum_const_value.type_name_idx);
6364 eprintf (" EV Value Enum Constant Value Const CP Information:\n");
6365 obj = element_value->value.enum_const_value.const_name_cp_obj;
6366 if (obj && obj->metas && obj->metas->type_info) {
6367 ((RBinJavaCPTypeMetas *) obj->metas->type_info)->allocs->print_summary (obj);
6368 }
6369 eprintf (" EV Value Enum Constant Value Type CP Information:\n");
6370 obj = element_value->value.enum_const_value.type_name_cp_obj;
6371 if (obj && obj->metas && obj->metas->type_info) {
6372 ((RBinJavaCPTypeMetas *) obj->metas->type_info)->allocs->print_summary (obj);
6373 }
6374 break;
6375 case R_BIN_JAVA_EV_TAG_CLASS:
6376 eprintf (" EV Value Class Info Index: 0x%02x\n", element_value->value.class_value.class_info_idx);
6377 eprintf (" EV Value Class Info CP Information:\n");
6378 obj = element_value->value.class_value.class_info_cp_obj;
6379 if (obj && obj->metas && obj->metas->type_info) {
6380 ((RBinJavaCPTypeMetas *) obj->metas->type_info)->allocs->print_summary (obj);
6381 }
6382 break;
6383 case R_BIN_JAVA_EV_TAG_ARRAY:
6384 eprintf (" EV Value Array Value Number of Values: 0x%04x\n", element_value->value.array_value.num_values);
6385 eprintf (" EV Value Array Values\n");
6386 r_list_foreach_safe (element_value->value.array_value.values, iter, iter_tmp, ev_element) {
6387 r_bin_java_print_element_value_summary (ev_element);
6388 }
6389 break;
6390 case R_BIN_JAVA_EV_TAG_ANNOTATION:
6391 eprintf (" EV Annotation Information:\n");
6392 r_bin_java_print_annotation_summary (&element_value->value.annotation_value);
6393 break;
6394 default:
6395 // eprintf unable to handle tag
6396 break;
6397 }
6398 }
6399
r_bin_java_element_pair_free(void * e)6400 R_API void r_bin_java_element_pair_free(void /*RBinJavaElementValuePair*/ *e) {
6401 RBinJavaElementValuePair *evp = e;
6402 if (evp) {
6403 free (evp->name);
6404 r_bin_java_element_value_free (evp->value);
6405 free (evp);
6406 }
6407 evp = NULL;
6408 }
6409
r_bin_java_element_value_free(void * e)6410 R_API void r_bin_java_element_value_free(void /*RBinJavaElementValue*/ *e) {
6411 RBinJavaElementValue *element_value = e;
6412 RListIter *iter = NULL, *iter_tmp = NULL;
6413 RBinJavaCPTypeObj *obj = NULL;
6414 RBinJavaElementValue *ev_element = NULL;
6415 if (element_value) {
6416 R_FREE (element_value->metas);
6417 switch (element_value->tag) {
6418 case R_BIN_JAVA_EV_TAG_BYTE:
6419 case R_BIN_JAVA_EV_TAG_CHAR:
6420 case R_BIN_JAVA_EV_TAG_DOUBLE:
6421 case R_BIN_JAVA_EV_TAG_FLOAT:
6422 case R_BIN_JAVA_EV_TAG_INT:
6423 case R_BIN_JAVA_EV_TAG_LONG:
6424 case R_BIN_JAVA_EV_TAG_SHORT:
6425 case R_BIN_JAVA_EV_TAG_BOOLEAN:
6426 case R_BIN_JAVA_EV_TAG_STRING:
6427 // Delete the CP Type Object
6428 obj = element_value->value.const_value.const_value_cp_obj;
6429 if (obj && obj->metas) {
6430 ((RBinJavaCPTypeMetas *) obj->metas->type_info)->allocs->delete_obj (obj);
6431 }
6432 break;
6433 case R_BIN_JAVA_EV_TAG_ENUM:
6434 // Delete the CP Type Objects
6435 obj = element_value->value.enum_const_value.const_name_cp_obj;
6436 if (obj && obj->metas) {
6437 RBinJavaCPTypeMetas *ti = obj->metas->type_info;
6438 if (ti && ti->allocs && ti->allocs->delete_obj) {
6439 ti->allocs->delete_obj (obj);
6440 }
6441 }
6442 obj = element_value->value.enum_const_value.type_name_cp_obj;
6443 if (obj && obj->metas) {
6444 RBinJavaCPTypeMetas *tm = obj->metas->type_info;
6445 if (tm && tm->allocs && tm->allocs->delete_obj) {
6446 tm->allocs->delete_obj (obj);
6447 }
6448 }
6449 break;
6450 case R_BIN_JAVA_EV_TAG_CLASS:
6451 // Delete the CP Type Object
6452 obj = element_value->value.class_value.class_info_cp_obj;
6453 if (obj && obj->metas) {
6454 ((RBinJavaCPTypeMetas *) obj->metas->type_info)->allocs->delete_obj (obj);
6455 }
6456 break;
6457 case R_BIN_JAVA_EV_TAG_ARRAY:
6458 // Delete the Element Value array List
6459 r_list_foreach_safe (element_value->value.array_value.values, iter, iter_tmp, ev_element) {
6460 if (ev_element) {
6461 r_bin_java_element_value_free (ev_element);
6462 } else {
6463 // TODO eprintf evps value was NULL
6464 }
6465 // r_list_delete (element_value->value.array_value.values, iter);
6466 ev_element = NULL;
6467 }
6468 r_list_free (element_value->value.array_value.values);
6469 break;
6470 case R_BIN_JAVA_EV_TAG_ANNOTATION:
6471 // Delete the Annotations List
6472 r_list_free (element_value->value.annotation_value.element_value_pairs);
6473 break;
6474 default:
6475 // eprintf unable to free the tag
6476 break;
6477 }
6478 free (element_value);
6479 }
6480 }
6481
r_bin_java_annotation_default_attr_calc_size(RBinJavaAttrInfo * attr)6482 R_API ut64 r_bin_java_annotation_default_attr_calc_size(RBinJavaAttrInfo *attr) {
6483 ut64 size = 0;
6484 if (attr) {
6485 // attr = r_bin_java_default_attr_new (buffer, sz, buf_offset);
6486 size += 6;
6487 // attr->info.annotation_default_attr.default_value = r_bin_java_element_value_new (buffer+offset, sz-offset, buf_offset+offset);
6488 size += r_bin_java_element_value_calc_size (attr->info.annotation_default_attr.default_value);
6489 }
6490 return size;
6491 }
6492
r_bin_java_annotation_default_attr_new(RBinJavaObj * bin,ut8 * buffer,ut64 sz,ut64 buf_offset)6493 R_API RBinJavaAttrInfo *r_bin_java_annotation_default_attr_new(RBinJavaObj *bin, ut8 *buffer, ut64 sz, ut64 buf_offset) {
6494 ut64 offset = 0;
6495 RBinJavaAttrInfo *attr = NULL;
6496 attr = r_bin_java_default_attr_new (bin, buffer, sz, buf_offset);
6497 offset += 6;
6498 if (attr && sz >= offset) {
6499 attr->type = R_BIN_JAVA_ATTR_TYPE_ANNOTATION_DEFAULT_ATTR;
6500 attr->info.annotation_default_attr.default_value = r_bin_java_element_value_new (buffer + offset, sz - offset, buf_offset + offset);
6501 if (attr->info.annotation_default_attr.default_value) {
6502 offset += attr->info.annotation_default_attr.default_value->size;
6503 }
6504 }
6505 r_bin_java_print_annotation_default_attr_summary (attr);
6506 return attr;
6507 }
6508
delete_obj(RBinJavaCPTypeObj * obj)6509 static void delete_obj(RBinJavaCPTypeObj *obj) {
6510 if (obj && obj->metas && obj->metas->type_info) {
6511 RBinJavaCPTypeMetas *ti = obj->metas->type_info;
6512 if (ti && ti->allocs && ti->allocs->delete_obj) {
6513 ti->allocs->delete_obj (obj);
6514 }
6515 }
6516 }
6517
r_bin_java_annotation_default_attr_free(void * a)6518 R_API void r_bin_java_annotation_default_attr_free(void /*RBinJavaAttrInfo*/ *a) {
6519 RBinJavaAttrInfo *attr = a;
6520 RBinJavaElementValue *ev_element = NULL;
6521 RListIter *iter = NULL, *iter_tmp = NULL;
6522 if (!attr || attr->type != R_BIN_JAVA_ATTR_TYPE_ANNOTATION_DEFAULT_ATTR) {
6523 return;
6524 }
6525 RBinJavaElementValue *element_value = attr->info.annotation_default_attr.default_value;
6526 if (!element_value) {
6527 return;
6528 }
6529 switch (element_value->tag) {
6530 case R_BIN_JAVA_EV_TAG_BYTE:
6531 case R_BIN_JAVA_EV_TAG_CHAR:
6532 case R_BIN_JAVA_EV_TAG_DOUBLE:
6533 case R_BIN_JAVA_EV_TAG_FLOAT:
6534 case R_BIN_JAVA_EV_TAG_INT:
6535 case R_BIN_JAVA_EV_TAG_LONG:
6536 case R_BIN_JAVA_EV_TAG_SHORT:
6537 case R_BIN_JAVA_EV_TAG_BOOLEAN:
6538 case R_BIN_JAVA_EV_TAG_STRING:
6539 // Delete the CP Type Object
6540 delete_obj (element_value->value.const_value.const_value_cp_obj);
6541 break;
6542 case R_BIN_JAVA_EV_TAG_ENUM:
6543 // Delete the CP Type Objects
6544 delete_obj (element_value->value.enum_const_value.const_name_cp_obj);
6545 break;
6546 case R_BIN_JAVA_EV_TAG_CLASS:
6547 // Delete the CP Type Object
6548 delete_obj (element_value->value.class_value.class_info_cp_obj);
6549 break;
6550 case R_BIN_JAVA_EV_TAG_ARRAY:
6551 // Delete the Element Value array List
6552 r_list_foreach_safe (element_value->value.array_value.values, iter, iter_tmp, ev_element) {
6553 r_bin_java_element_value_free (ev_element);
6554 // r_list_delete (element_value->value.array_value.values, iter);
6555 ev_element = NULL;
6556 }
6557 r_list_free (element_value->value.array_value.values);
6558 break;
6559 case R_BIN_JAVA_EV_TAG_ANNOTATION:
6560 // Delete the Annotations List
6561 r_list_free (element_value->value.annotation_value.element_value_pairs);
6562 break;
6563 default:
6564 // eprintf unable to free the tag
6565 break;
6566 }
6567 if (attr) {
6568 free (attr->name);
6569 free (attr->metas);
6570 free (attr);
6571 }
6572 }
6573
r_bin_java_annotation_new(ut8 * buffer,ut64 sz,ut64 buf_offset)6574 R_API RBinJavaAnnotation *r_bin_java_annotation_new(ut8 *buffer, ut64 sz, ut64 buf_offset) {
6575 ut32 i = 0;
6576 RBinJavaAnnotation *annotation = NULL;
6577 RBinJavaElementValuePair *evps = NULL;
6578 ut64 offset = 0;
6579 annotation = R_NEW0 (RBinJavaAnnotation);
6580 if (!annotation) {
6581 return NULL;
6582 }
6583 // (ut16) read and set annotation_value.type_idx;
6584 annotation->type_idx = R_BIN_JAVA_USHORT (buffer, offset);
6585 offset += 2;
6586 // (ut16) read and set annotation_value.num_element_value_pairs;
6587 annotation->num_element_value_pairs = R_BIN_JAVA_USHORT (buffer, offset);
6588 offset += 2;
6589 annotation->element_value_pairs = r_list_newf (r_bin_java_element_pair_free);
6590 // read annotation_value.num_element_value_pairs, and append to annotation_value.element_value_pairs
6591 for (i = 0; i < annotation->num_element_value_pairs; i++) {
6592 if (offset > sz) {
6593 break;
6594 }
6595 evps = r_bin_java_element_pair_new (buffer + offset, sz - offset, buf_offset + offset);
6596 if (evps) {
6597 offset += evps->size;
6598 r_list_append (annotation->element_value_pairs, (void *) evps);
6599 }
6600 }
6601 annotation->size = offset;
6602 return annotation;
6603 }
6604
r_bin_java_annotation_calc_size(RBinJavaAnnotation * annotation)6605 R_API ut64 r_bin_java_annotation_calc_size(RBinJavaAnnotation *annotation) {
6606 ut64 sz = 0;
6607 RListIter *iter, *iter_tmp;
6608 RBinJavaElementValuePair *evps = NULL;
6609 if (!annotation) {
6610 // TODO eprintf allocation fail
6611 return sz;
6612 }
6613 // annotation->type_idx = R_BIN_JAVA_USHORT (buffer, offset);
6614 sz += 2;
6615 // annotation->num_element_value_pairs = R_BIN_JAVA_USHORT (buffer, offset);
6616 sz += 2;
6617 r_list_foreach_safe (annotation->element_value_pairs, iter, iter_tmp, evps) {
6618 if (evps) {
6619 sz += r_bin_java_element_pair_calc_size (evps);
6620 }
6621 }
6622 return sz;
6623 }
6624
r_bin_java_annotation_free(void * a)6625 R_API void r_bin_java_annotation_free(void /*RBinJavaAnnotation*/ *a) {
6626 RBinJavaAnnotation *annotation = a;
6627 if (annotation) {
6628 r_list_free (annotation->element_value_pairs);
6629 free (annotation);
6630 }
6631 }
6632
r_bin_java_print_annotation_summary(RBinJavaAnnotation * annotation)6633 R_API void r_bin_java_print_annotation_summary(RBinJavaAnnotation *annotation) {
6634 RListIter *iter = NULL, *iter_tmp = NULL;
6635 RBinJavaElementValuePair *evp = NULL;
6636 if (!annotation) {
6637 // TODO eprintf invalid annotation
6638 return;
6639 }
6640 Eprintf (" Annotation Type Index: 0x%02x\n", annotation->type_idx);
6641 Eprintf (" Annotation Number of EV Pairs: 0x%04x\n", annotation->num_element_value_pairs);
6642 Eprintf (" Annotation EV Pair Values:\n");
6643 if (annotation->element_value_pairs) {
6644 r_list_foreach_safe (annotation->element_value_pairs, iter, iter_tmp, evp) {
6645 r_bin_java_print_element_pair_summary (evp);
6646 }
6647 }
6648 }
6649
r_bin_java_element_pair_calc_size(RBinJavaElementValuePair * evp)6650 R_API ut64 r_bin_java_element_pair_calc_size(RBinJavaElementValuePair *evp) {
6651 ut64 sz = 0;
6652 if (evp == NULL) {
6653 return sz;
6654 }
6655 // evp->element_name_idx = r_bin_java_read_short(bin, bin->b->cur);
6656 sz += 2;
6657 // evp->value = r_bin_java_element_value_new (bin, offset+2);
6658 if (evp->value) {
6659 sz += r_bin_java_element_value_calc_size (evp->value);
6660 }
6661 return sz;
6662 }
6663
r_bin_java_element_value_calc_size(RBinJavaElementValue * element_value)6664 R_API ut64 r_bin_java_element_value_calc_size(RBinJavaElementValue *element_value) {
6665 RListIter *iter, *iter_tmp;
6666 RBinJavaElementValue *ev_element;
6667 RBinJavaElementValuePair *evps;
6668 ut64 sz = 0;
6669 if (element_value == NULL) {
6670 return sz;
6671 }
6672 // tag
6673 sz += 1;
6674 switch (element_value->tag) {
6675 case R_BIN_JAVA_EV_TAG_BYTE:
6676 case R_BIN_JAVA_EV_TAG_CHAR:
6677 case R_BIN_JAVA_EV_TAG_DOUBLE:
6678 case R_BIN_JAVA_EV_TAG_FLOAT:
6679 case R_BIN_JAVA_EV_TAG_INT:
6680 case R_BIN_JAVA_EV_TAG_LONG:
6681 case R_BIN_JAVA_EV_TAG_SHORT:
6682 case R_BIN_JAVA_EV_TAG_BOOLEAN:
6683 case R_BIN_JAVA_EV_TAG_STRING:
6684 // look up value in bin->cp_list
6685 // (ut16) read and set const_value.const_value_idx
6686 // element_value->value.const_value.const_value_idx = r_bin_java_read_short(bin, bin->b->cur);
6687 sz += 2;
6688 break;
6689 case R_BIN_JAVA_EV_TAG_ENUM:
6690 // (ut16) read and set enum_const_value.type_name_idx
6691 // element_value->value.enum_const_value.type_name_idx = r_bin_java_read_short(bin, bin->b->cur);
6692 sz += 2;
6693 // (ut16) read and set enum_const_value.const_name_idx
6694 // element_value->value.enum_const_value.const_name_idx = r_bin_java_read_short(bin, bin->b->cur);
6695 sz += 2;
6696 break;
6697 case R_BIN_JAVA_EV_TAG_CLASS:
6698 // (ut16) read and set class_value.class_info_idx
6699 // element_value->value.class_value.class_info_idx = r_bin_java_read_short(bin, bin->b->cur);
6700 sz += 2;
6701 break;
6702 case R_BIN_JAVA_EV_TAG_ARRAY:
6703 // (ut16) read and set array_value.num_values
6704 // element_value->value.array_value.num_values = r_bin_java_read_short(bin, bin->b->cur);
6705 sz += 2;
6706 r_list_foreach_safe (element_value->value.array_value.values, iter, iter_tmp, ev_element) {
6707 if (ev_element) {
6708 sz += r_bin_java_element_value_calc_size (ev_element);
6709 }
6710 }
6711 break;
6712 case R_BIN_JAVA_EV_TAG_ANNOTATION:
6713 // annotation new is not used here.
6714 // (ut16) read and set annotation_value.type_idx;
6715 // element_value->value.annotation_value.type_idx = r_bin_java_read_short(bin, bin->b->cur);
6716 sz += 2;
6717 // (ut16) read and set annotation_value.num_element_value_pairs;
6718 // element_value->value.annotation_value.num_element_value_pairs = r_bin_java_read_short(bin, bin->b->cur);
6719 sz += 2;
6720 element_value->value.annotation_value.element_value_pairs = r_list_newf (r_bin_java_element_pair_free);
6721 r_list_foreach_safe (element_value->value.annotation_value.element_value_pairs, iter, iter_tmp, evps) {
6722 if (evps) {
6723 sz += r_bin_java_element_pair_calc_size (evps);
6724 }
6725 }
6726 break;
6727 default:
6728 // eprintf unable to handle tag
6729 break;
6730 }
6731 return sz;
6732 }
6733
r_bin_java_element_value_new(ut8 * buffer,ut64 sz,ut64 buf_offset)6734 R_API RBinJavaElementValue *r_bin_java_element_value_new(ut8 *buffer, ut64 sz, ut64 buf_offset) {
6735 ut32 i = 0;
6736 ut64 offset = 0;
6737 RBinJavaElementValue *element_value = R_NEW0 (RBinJavaElementValue);
6738 if (!element_value) {
6739 return NULL;
6740 }
6741 RBinJavaElementValuePair *evps = NULL;
6742 element_value->metas = R_NEW0 (RBinJavaMetaInfo);
6743 if (!element_value->metas) {
6744 R_FREE (element_value);
6745 return NULL;
6746 }
6747 element_value->file_offset = buf_offset;
6748 element_value->tag = buffer[offset];
6749 element_value->size += 1;
6750 offset += 1;
6751 element_value->metas->type_info = (void *) r_bin_java_get_ev_meta_from_tag (element_value->tag);
6752 switch (element_value->tag) {
6753 case R_BIN_JAVA_EV_TAG_BYTE:
6754 case R_BIN_JAVA_EV_TAG_CHAR:
6755 case R_BIN_JAVA_EV_TAG_DOUBLE:
6756 case R_BIN_JAVA_EV_TAG_FLOAT:
6757 case R_BIN_JAVA_EV_TAG_INT:
6758 case R_BIN_JAVA_EV_TAG_LONG:
6759 case R_BIN_JAVA_EV_TAG_SHORT:
6760 case R_BIN_JAVA_EV_TAG_BOOLEAN:
6761 case R_BIN_JAVA_EV_TAG_STRING:
6762 // look up value in bin->cp_list
6763 // (ut16) read and set const_value.const_value_idx
6764 element_value->value.const_value.const_value_idx = R_BIN_JAVA_USHORT (buffer, offset);
6765 element_value->size += 2;
6766 // look-up, deep copy, and set const_value.const_value_cp_obj
6767 element_value->value.const_value.const_value_cp_obj = r_bin_java_clone_cp_idx (R_BIN_JAVA_GLOBAL_BIN, element_value->value.const_value.const_value_idx);
6768 break;
6769 case R_BIN_JAVA_EV_TAG_ENUM:
6770 // (ut16) read and set enum_const_value.type_name_idx
6771 element_value->value.enum_const_value.type_name_idx = R_BIN_JAVA_USHORT (buffer, offset);
6772 element_value->size += 2;
6773 offset += 2;
6774 // (ut16) read and set enum_const_value.const_name_idx
6775 element_value->value.enum_const_value.const_name_idx = R_BIN_JAVA_USHORT (buffer, offset);
6776 element_value->size += 2;
6777 offset += 2;
6778 // look up type_name_index in bin->cp_list
6779 // look-up, deep copy, and set enum_const_value.const_name_cp_obj
6780 element_value->value.enum_const_value.const_name_cp_obj = r_bin_java_clone_cp_idx (R_BIN_JAVA_GLOBAL_BIN, element_value->value.enum_const_value.const_name_idx);
6781 // look-up, deep copy, and set enum_const_value.type_name_cp_obj
6782 element_value->value.enum_const_value.type_name_cp_obj = r_bin_java_clone_cp_idx (R_BIN_JAVA_GLOBAL_BIN, element_value->value.enum_const_value.type_name_idx);
6783 break;
6784 case R_BIN_JAVA_EV_TAG_CLASS:
6785 // (ut16) read and set class_value.class_info_idx
6786 element_value->value.class_value.class_info_idx = R_BIN_JAVA_USHORT (buffer, offset);
6787 element_value->size += 2;
6788 offset += 2;
6789 // look up type_name_index in bin->cp_list
6790 // look-up, deep copy, and set class_value.class_info_cp_obj
6791 element_value->value.class_value.class_info_cp_obj = r_bin_java_clone_cp_idx (R_BIN_JAVA_GLOBAL_BIN, element_value->value.class_value.class_info_idx);
6792 break;
6793 case R_BIN_JAVA_EV_TAG_ARRAY:
6794 // (ut16) read and set array_value.num_values
6795 element_value->value.array_value.num_values = R_BIN_JAVA_USHORT (buffer, offset);
6796 element_value->size += 2;
6797 offset += 2;
6798 element_value->value.array_value.values = r_list_new ();
6799 for (i = 0; i < element_value->value.array_value.num_values; i++) {
6800 if (offset >= sz) {
6801 break;
6802 }
6803 RBinJavaElementValue *ev_element = r_bin_java_element_value_new (buffer + offset, sz - offset, buf_offset + offset);
6804 if (ev_element) {
6805 element_value->size += ev_element->size;
6806 offset += ev_element->size;
6807 // read array_value.num_values, and append to array_value.values
6808 r_list_append (element_value->value.array_value.values, (void *) ev_element);
6809 }
6810 }
6811 break;
6812 case R_BIN_JAVA_EV_TAG_ANNOTATION:
6813 // annotation new is not used here.
6814 // (ut16) read and set annotation_value.type_idx;
6815 if (offset + 8 < sz) {
6816 element_value->value.annotation_value.type_idx = R_BIN_JAVA_USHORT (buffer, offset);
6817 element_value->size += 2;
6818 offset += 2;
6819 // (ut16) read and set annotation_value.num_element_value_pairs;
6820 element_value->value.annotation_value.num_element_value_pairs = R_BIN_JAVA_USHORT (buffer, offset);
6821 element_value->size += 2;
6822 offset += 2;
6823 }
6824 element_value->value.annotation_value.element_value_pairs = r_list_newf (r_bin_java_element_pair_free);
6825 // read annotation_value.num_element_value_pairs, and append to annotation_value.element_value_pairs
6826 for (i = 0; i < element_value->value.annotation_value.num_element_value_pairs; i++) {
6827 if (offset > sz) {
6828 break;
6829 }
6830 evps = r_bin_java_element_pair_new (buffer + offset, sz - offset, buf_offset + offset);
6831 if (evps) {
6832 element_value->size += evps->size;
6833 offset += evps->size;
6834 }
6835 if (evps == NULL) {
6836 // TODO: eprintf error when reading element pair
6837 }
6838 r_list_append (element_value->value.annotation_value.element_value_pairs, (void *) evps);
6839 }
6840 break;
6841 default:
6842 // eprintf unable to handle tag
6843 break;
6844 }
6845 return element_value;
6846 }
6847
r_bin_java_bootstrap_method_argument_free(void * b)6848 R_API void r_bin_java_bootstrap_method_argument_free(void /*RBinJavaBootStrapArgument*/ *b) {
6849 RBinJavaBootStrapArgument *bsm_arg = b;
6850 if (bsm_arg) {
6851 RBinJavaCPTypeMetas *tm = (RBinJavaCPTypeMetas*)bsm_arg->argument_info_cp_obj;
6852 if (tm) {
6853 if (tm && (size_t)(tm->allocs) > 1024 && tm->allocs->delete_obj) {
6854 tm->allocs->delete_obj (tm);
6855 }
6856 bsm_arg->argument_info_cp_obj = NULL;
6857 }
6858 free (bsm_arg);
6859 }
6860 }
6861
r_bin_java_print_bootstrap_method_argument_summary(RBinJavaBootStrapArgument * bsm_arg)6862 R_API void r_bin_java_print_bootstrap_method_argument_summary(RBinJavaBootStrapArgument *bsm_arg) {
6863 if (!bsm_arg) {
6864 eprintf ("Attempting to print an invalid RBinJavaBootStrapArgument *.\n");
6865 return;
6866 }
6867 eprintf ("Bootstrap Method Argument Information:\n");
6868 eprintf (" Offset: 0x%08"PFMT64x"", bsm_arg->file_offset);
6869 eprintf (" Name_And_Type Index = (0x%02x)\n", bsm_arg->argument_info_idx);
6870 if (bsm_arg->argument_info_cp_obj) {
6871 eprintf (" Bootstrap Method Argument Type and Name Info:\n");
6872 ((RBinJavaCPTypeMetas *) bsm_arg->argument_info_cp_obj)->allocs->print_summary (bsm_arg->argument_info_cp_obj);
6873 } else {
6874 eprintf (" Bootstrap Method Argument Type and Name Info: INVALID\n");
6875 }
6876 }
6877
r_bin_java_print_bootstrap_method_summary(RBinJavaBootStrapMethod * bsm)6878 R_API void r_bin_java_print_bootstrap_method_summary(RBinJavaBootStrapMethod *bsm) {
6879 RBinJavaBootStrapArgument *bsm_arg = NULL;
6880 RListIter *iter = NULL, *iter_tmp = NULL;
6881 if (!bsm) {
6882 eprintf ("Attempting to print an invalid RBinJavaBootStrapArgument *.\n");
6883 return;
6884 }
6885 eprintf ("Bootstrap Method Information:\n");
6886 eprintf (" Offset: 0x%08"PFMT64x"", bsm->file_offset);
6887 eprintf (" Method Reference Index = (0x%02x)\n", bsm->bootstrap_method_ref);
6888 eprintf (" Number of Method Arguments = (0x%02x)\n", bsm->num_bootstrap_arguments);
6889 if (bsm->bootstrap_arguments) {
6890 r_list_foreach_safe (bsm->bootstrap_arguments, iter, iter_tmp, bsm_arg) {
6891 if (bsm_arg) {
6892 r_bin_java_print_bootstrap_method_argument_summary (bsm_arg);
6893 }
6894 }
6895 } else {
6896 eprintf (" Bootstrap Method Argument: NONE \n");
6897 }
6898 }
6899
r_bin_java_bootstrap_method_argument_new(ut8 * buffer,ut64 sz,ut64 buf_offset)6900 R_API RBinJavaBootStrapArgument *r_bin_java_bootstrap_method_argument_new(ut8 *buffer, ut64 sz, ut64 buf_offset) {
6901 ut64 offset = 0;
6902 RBinJavaBootStrapArgument *bsm_arg = (RBinJavaBootStrapArgument *) malloc (sizeof (RBinJavaBootStrapArgument));
6903 if (!bsm_arg) {
6904 // TODO eprintf failed to allocate bytes for bootstrap_method.
6905 return bsm_arg;
6906 }
6907 memset (bsm_arg, 0, sizeof (RBinJavaBootStrapArgument));
6908 bsm_arg->file_offset = buf_offset;
6909 bsm_arg->argument_info_idx = R_BIN_JAVA_USHORT (buffer, offset);
6910 offset += 2;
6911 bsm_arg->argument_info_cp_obj = r_bin_java_clone_cp_idx (R_BIN_JAVA_GLOBAL_BIN, bsm_arg->argument_info_idx);
6912 bsm_arg->size = offset;
6913 return bsm_arg;
6914 }
6915
r_bin_java_bootstrap_method_free(void * b)6916 R_API void r_bin_java_bootstrap_method_free(void /*/RBinJavaBootStrapMethod*/ *b) {
6917 RBinJavaBootStrapMethod *bsm = b;
6918 RListIter *iter, *iter_tmp;
6919 RBinJavaBootStrapArgument *obj = NULL;
6920 if (bsm) {
6921 if (bsm->bootstrap_arguments) {
6922 r_list_foreach_safe (bsm->bootstrap_arguments, iter, iter_tmp, obj) {
6923 if (obj) {
6924 r_bin_java_bootstrap_method_argument_free (obj);
6925 }
6926 // r_list_delete (bsm->bootstrap_arguments, iter);
6927 }
6928 r_list_free (bsm->bootstrap_arguments);
6929 bsm->bootstrap_arguments = NULL;
6930 }
6931 free (bsm);
6932 }
6933 }
6934
r_bin_java_bootstrap_method_new(ut8 * buffer,ut64 sz,ut64 buf_offset)6935 R_API RBinJavaBootStrapMethod *r_bin_java_bootstrap_method_new(ut8 *buffer, ut64 sz, ut64 buf_offset) {
6936 RBinJavaBootStrapArgument *bsm_arg = NULL;
6937 ut32 i = 0;
6938 ut64 offset = 0;
6939 RBinJavaBootStrapMethod *bsm = R_NEW0 (RBinJavaBootStrapMethod);
6940 if (!bsm) {
6941 // TODO eprintf failed to allocate bytes for bootstrap_method.
6942 return bsm;
6943 }
6944 memset (bsm, 0, sizeof (RBinJavaBootStrapMethod));
6945 bsm->file_offset = buf_offset;
6946 bsm->bootstrap_method_ref = R_BIN_JAVA_USHORT (buffer, offset);
6947 offset += 2;
6948 bsm->num_bootstrap_arguments = R_BIN_JAVA_USHORT (buffer, offset);
6949 offset += 2;
6950 bsm->bootstrap_arguments = r_list_new ();
6951 for (i = 0; i < bsm->num_bootstrap_arguments; i++) {
6952 if (offset >= sz) {
6953 break;
6954 }
6955 // bsm_arg = r_bin_java_bootstrap_method_argument_new (bin, bin->b->cur);
6956 bsm_arg = r_bin_java_bootstrap_method_argument_new (buffer + offset, sz - offset, buf_offset + offset);
6957 if (bsm_arg) {
6958 offset += bsm_arg->size;
6959 r_list_append (bsm->bootstrap_arguments, (void *) bsm_arg);
6960 } else {
6961 // TODO eprintf Failed to read the %d boot strap method.
6962 }
6963 }
6964 bsm->size = offset;
6965 return bsm;
6966 }
6967
r_bin_java_print_bootstrap_methods_attr_summary(RBinJavaAttrInfo * attr)6968 R_API void r_bin_java_print_bootstrap_methods_attr_summary(RBinJavaAttrInfo *attr) {
6969 RListIter *iter, *iter_tmp;
6970 RBinJavaBootStrapMethod *obj = NULL;
6971 if (!attr || attr->type == R_BIN_JAVA_ATTR_TYPE_BOOTSTRAP_METHODS_ATTR) {
6972 eprintf ("Unable to print attribue summary for RBinJavaAttrInfo *RBinJavaBootstrapMethodsAttr");
6973 return;
6974 }
6975 eprintf ("Bootstrap Methods Attribute Information Information:\n");
6976 eprintf (" Attribute Offset: 0x%08"PFMT64x"", attr->file_offset);
6977 eprintf (" Length: 0x%08x", attr->length);
6978 eprintf (" Number of Method Arguments = (0x%02x)\n", attr->info.bootstrap_methods_attr.num_bootstrap_methods);
6979 if (attr->info.bootstrap_methods_attr.bootstrap_methods) {
6980 r_list_foreach_safe (attr->info.bootstrap_methods_attr.bootstrap_methods, iter, iter_tmp, obj) {
6981 if (obj) {
6982 r_bin_java_print_bootstrap_method_summary (obj);
6983 }
6984 }
6985 } else {
6986 eprintf (" Bootstrap Methods: NONE \n");
6987 }
6988 }
6989
r_bin_java_bootstrap_methods_attr_free(void * a)6990 R_API void r_bin_java_bootstrap_methods_attr_free(void /*RBinJavaAttrInfo*/ *a) {
6991 RBinJavaAttrInfo *attr = a;
6992 if (attr && attr->type == R_BIN_JAVA_ATTR_TYPE_BOOTSTRAP_METHODS_ATTR) {
6993 free (attr->name);
6994 free (attr->metas);
6995 r_list_free (attr->info.bootstrap_methods_attr.bootstrap_methods);
6996 free (attr);
6997 }
6998 }
6999
r_bin_java_bootstrap_methods_attr_calc_size(RBinJavaAttrInfo * attr)7000 R_API ut64 r_bin_java_bootstrap_methods_attr_calc_size(RBinJavaAttrInfo *attr) {
7001 RListIter *iter, *iter_tmp;
7002 RBinJavaBootStrapMethod *bsm = NULL;
7003 ut64 size = 0;
7004 if (attr) {
7005 size += 6;
7006 // attr->info.bootstrap_methods_attr.num_bootstrap_methods = R_BIN_JAVA_USHORT (buffer, offset);
7007 size += 2;
7008 r_list_foreach_safe (attr->info.bootstrap_methods_attr.bootstrap_methods, iter, iter_tmp, bsm) {
7009 if (bsm) {
7010 size += r_bin_java_bootstrap_method_calc_size (bsm);
7011 } else {
7012 // TODO eprintf Failed to read the %d boot strap method.
7013 }
7014 }
7015 }
7016 return size;
7017 }
7018
r_bin_java_bootstrap_arg_calc_size(RBinJavaBootStrapArgument * bsm_arg)7019 R_API ut64 r_bin_java_bootstrap_arg_calc_size(RBinJavaBootStrapArgument *bsm_arg) {
7020 ut64 size = 0;
7021 if (bsm_arg) {
7022 // bsm_arg->argument_info_idx = R_BIN_JAVA_USHORT (buffer, offset);
7023 size += 2;
7024 }
7025 return size;
7026 }
7027
r_bin_java_bootstrap_method_calc_size(RBinJavaBootStrapMethod * bsm)7028 R_API ut64 r_bin_java_bootstrap_method_calc_size(RBinJavaBootStrapMethod *bsm) {
7029 RListIter *iter, *iter_tmp;
7030 RBinJavaBootStrapArgument *bsm_arg = NULL;
7031 ut64 size = 0;
7032 if (bsm) {
7033 size += 6;
7034 // bsm->bootstrap_method_ref = R_BIN_JAVA_USHORT (buffer, offset);
7035 size += 2;
7036 // bsm->num_bootstrap_arguments = R_BIN_JAVA_USHORT (buffer, offset);
7037 size += 2;
7038 r_list_foreach_safe (bsm->bootstrap_arguments, iter, iter_tmp, bsm_arg) {
7039 if (bsm_arg) {
7040 size += r_bin_java_bootstrap_arg_calc_size (bsm_arg);
7041 } else {
7042 // TODO eprintf Failed to read the %d boot strap method.
7043 }
7044 }
7045 }
7046 return size;
7047 }
7048
r_bin_java_bootstrap_methods_attr_new(RBinJavaObj * bin,ut8 * buffer,ut64 sz,ut64 buf_offset)7049 R_API RBinJavaAttrInfo *r_bin_java_bootstrap_methods_attr_new(RBinJavaObj *bin, ut8 *buffer, ut64 sz, ut64 buf_offset) {
7050 ut32 i = 0;
7051 RBinJavaBootStrapMethod *bsm = NULL;
7052 ut64 offset = 0;
7053 RBinJavaAttrInfo *attr = r_bin_java_default_attr_new (bin, buffer, sz, buf_offset);
7054 offset += 6;
7055 if (attr) {
7056 attr->type = R_BIN_JAVA_ATTR_TYPE_BOOTSTRAP_METHODS_ATTR;
7057 attr->info.bootstrap_methods_attr.num_bootstrap_methods = R_BIN_JAVA_USHORT (buffer, offset);
7058 offset += 2;
7059 attr->info.bootstrap_methods_attr.bootstrap_methods = r_list_newf (r_bin_java_bootstrap_method_free);
7060 for (i = 0; i < attr->info.bootstrap_methods_attr.num_bootstrap_methods; i++) {
7061 // bsm = r_bin_java_bootstrap_method_new (bin, bin->b->cur);
7062 if (offset >= sz) {
7063 break;
7064 }
7065 bsm = r_bin_java_bootstrap_method_new (buffer + offset, sz - offset, buf_offset + offset);
7066 if (bsm) {
7067 offset += bsm->size;
7068 r_list_append (attr->info.bootstrap_methods_attr.bootstrap_methods, (void *) bsm);
7069 } else {
7070 // TODO eprintf Failed to read the %d boot strap method.
7071 }
7072 }
7073 attr->size = offset;
7074 }
7075 return attr;
7076 }
7077
r_bin_java_print_annotation_default_attr_summary(RBinJavaAttrInfo * attr)7078 R_API void r_bin_java_print_annotation_default_attr_summary(RBinJavaAttrInfo *attr) {
7079 if (attr && attr->type == R_BIN_JAVA_ATTR_TYPE_ANNOTATION_DEFAULT_ATTR) {
7080 eprintf ("Annotation Default Attribute Information:\n");
7081 eprintf (" Attribute Offset: 0x%08"PFMT64x "\n", attr->file_offset);
7082 eprintf (" Attribute Name Index: %d (%s)\n", attr->name_idx, attr->name);
7083 eprintf (" Attribute Length: %d\n", attr->length);
7084 r_bin_java_print_element_value_summary ((attr->info.annotation_default_attr.default_value));
7085 } else {
7086 // TODO: eprintf attr is invalid
7087 }
7088 }
7089
r_bin_java_annotation_array_free(void * a)7090 R_API void r_bin_java_annotation_array_free(void /*RBinJavaAnnotationsArray*/ *a) {
7091 RBinJavaAnnotationsArray *annotation_array = a;
7092 RListIter *iter = NULL, *iter_tmp = NULL;
7093 RBinJavaAnnotation *annotation;
7094 if (!annotation_array->annotations) {
7095 // TODO eprintf
7096 return;
7097 }
7098 r_list_foreach_safe (annotation_array->annotations, iter, iter_tmp, annotation) {
7099 if (annotation) {
7100 r_bin_java_annotation_free (annotation);
7101 }
7102 // r_list_delete (annotation_array->annotations, iter);
7103 }
7104 r_list_free (annotation_array->annotations);
7105 free (annotation_array);
7106 }
7107
r_bin_java_print_annotation_array_summary(RBinJavaAnnotationsArray * annotation_array)7108 R_API void r_bin_java_print_annotation_array_summary(RBinJavaAnnotationsArray *annotation_array) {
7109 RListIter *iter = NULL, *iter_tmp = NULL;
7110 RBinJavaAnnotation *annotation;
7111 if (!annotation_array->annotations) {
7112 // TODO eprintf
7113 return;
7114 }
7115 eprintf (" Annotation Array Information:\n");
7116 eprintf (" Number of Annotation Array Elements: %d\n", annotation_array->num_annotations);
7117 r_list_foreach_safe (annotation_array->annotations, iter, iter_tmp, annotation) {
7118 r_bin_java_print_annotation_summary (annotation);
7119 }
7120 }
7121
r_bin_java_annotation_array_new(ut8 * buffer,ut64 sz,ut64 buf_offset)7122 R_API RBinJavaAnnotationsArray *r_bin_java_annotation_array_new(ut8 *buffer, ut64 sz, ut64 buf_offset) {
7123 RBinJavaAnnotation *annotation;
7124 RBinJavaAnnotationsArray *annotation_array;
7125 ut32 i;
7126 ut64 offset = 0;
7127 annotation_array = (RBinJavaAnnotationsArray *) malloc (sizeof (RBinJavaAnnotationsArray));
7128 if (!annotation_array) {
7129 // TODO eprintf
7130 return NULL;
7131 }
7132 annotation_array->num_annotations = R_BIN_JAVA_USHORT (buffer, offset);
7133 offset += 2;
7134 annotation_array->annotations = r_list_new ();
7135 for (i = 0; i < annotation_array->num_annotations; i++) {
7136 if (offset > sz) {
7137 break;
7138 }
7139 annotation = r_bin_java_annotation_new (buffer + offset, sz - offset, buf_offset + offset);
7140 if (annotation) {
7141 offset += annotation->size;
7142 r_list_append (annotation_array->annotations, (void *) annotation);
7143 }
7144 }
7145 annotation_array->size = offset;
7146 return annotation_array;
7147 }
7148
r_bin_java_rtv_annotations_attr_new(RBinJavaObj * bin,ut8 * buffer,ut64 sz,ut64 buf_offset)7149 R_API RBinJavaAttrInfo *r_bin_java_rtv_annotations_attr_new(RBinJavaObj *bin, ut8 *buffer, ut64 sz, ut64 buf_offset) {
7150 ut32 i = 0;
7151 RBinJavaAttrInfo *attr = NULL;
7152 ut64 offset = 0;
7153 attr = r_bin_java_default_attr_new (bin, buffer, sz, buf_offset);
7154 offset += 6;
7155 if (attr) {
7156 attr->type = R_BIN_JAVA_ATTR_TYPE_RUNTIME_VISIBLE_ANNOTATION_ATTR;
7157 attr->info.annotation_array.num_annotations = R_BIN_JAVA_USHORT (buffer, offset);
7158 offset += 2;
7159 attr->info.annotation_array.annotations = r_list_newf (r_bin_java_annotation_free);
7160 for (i = 0; i < attr->info.annotation_array.num_annotations; i++) {
7161 if (offset >= sz) {
7162 break;
7163 }
7164 RBinJavaAnnotation *annotation = r_bin_java_annotation_new (buffer + offset, sz - offset, buf_offset + offset);
7165 if (annotation) {
7166 offset += annotation->size;
7167 r_list_append (attr->info.annotation_array.annotations, (void *) annotation);
7168 }
7169 }
7170 attr->size = offset;
7171 }
7172 return attr;
7173 }
7174
r_bin_java_annotation_array_calc_size(RBinJavaAnnotationsArray * annotation_array)7175 R_API ut64 r_bin_java_annotation_array_calc_size(RBinJavaAnnotationsArray *annotation_array) {
7176 ut64 size = 0;
7177 RListIter *iter = NULL, *iter_tmp = NULL;
7178 RBinJavaAnnotation *annotation;
7179 if (!annotation_array->annotations) {
7180 // TODO eprintf
7181 return size;
7182 }
7183 // annotation_array->num_annotations = R_BIN_JAVA_USHORT (buffer, offset);
7184 size += 2;
7185 r_list_foreach_safe (annotation_array->annotations, iter, iter_tmp, annotation) {
7186 size += r_bin_java_annotation_calc_size (annotation);
7187 }
7188 return size;
7189 }
7190
r_bin_java_rtv_annotations_attr_calc_size(RBinJavaAttrInfo * attr)7191 R_API ut64 r_bin_java_rtv_annotations_attr_calc_size(RBinJavaAttrInfo *attr) {
7192 ut64 size = 0;
7193 if (!attr) {
7194 // TODO eprintf allocation fail
7195 return size;
7196 }
7197 size += (6 + r_bin_java_annotation_array_calc_size (&(attr->info.annotation_array)));
7198 return size;
7199 }
7200
r_bin_java_rti_annotations_attr_new(RBinJavaObj * bin,ut8 * buffer,ut64 sz,ut64 buf_offset)7201 R_API RBinJavaAttrInfo *r_bin_java_rti_annotations_attr_new(RBinJavaObj *bin, ut8 *buffer, ut64 sz, ut64 buf_offset) {
7202 ut32 i = 0;
7203 RBinJavaAttrInfo *attr = NULL;
7204 ut64 offset = 0;
7205 attr = r_bin_java_default_attr_new (bin, buffer, sz, buf_offset);
7206 offset += 6;
7207 if (attr) {
7208 attr->type = R_BIN_JAVA_ATTR_TYPE_RUNTIME_INVISIBLE_ANNOTATION_ATTR;
7209 attr->info.annotation_array.num_annotations = R_BIN_JAVA_USHORT (buffer, offset);
7210 offset += 2;
7211 attr->info.annotation_array.annotations = r_list_newf (r_bin_java_annotation_free);
7212 for (i = 0; i < attr->info.rtv_annotations_attr.num_annotations; i++) {
7213 if (offset >= sz) {
7214 break;
7215 }
7216 RBinJavaAnnotation *annotation = r_bin_java_annotation_new (buffer + offset, sz - offset, buf_offset + offset);
7217 if (annotation) {
7218 offset += annotation->size;
7219 }
7220 r_list_append (attr->info.annotation_array.annotations, (void *) annotation);
7221 }
7222 attr->size = offset;
7223 }
7224 return attr;
7225 }
7226
r_bin_java_rti_annotations_attr_calc_size(RBinJavaAttrInfo * attr)7227 R_API ut64 r_bin_java_rti_annotations_attr_calc_size(RBinJavaAttrInfo *attr) {
7228 ut64 size = 0;
7229 if (!attr) {
7230 // TODO eprintf allocation fail
7231 return size;
7232 }
7233 size += (6 + r_bin_java_annotation_array_calc_size (&(attr->info.annotation_array)));
7234 return size;
7235 }
7236
r_bin_java_rtv_annotations_attr_free(void * a)7237 R_API void r_bin_java_rtv_annotations_attr_free(void /*RBinJavaAttrInfo*/ *a) {
7238 RBinJavaAttrInfo *attr = a;
7239 if (attr && attr->type == R_BIN_JAVA_ATTR_TYPE_RUNTIME_VISIBLE_ANNOTATION_ATTR) {
7240 r_list_free (attr->info.annotation_array.annotations);
7241 free (attr->metas);
7242 free (attr->name);
7243 free (attr);
7244 }
7245 }
7246
r_bin_java_rti_annotations_attr_free(void * a)7247 R_API void r_bin_java_rti_annotations_attr_free(void /*RBinJavaAttrInfo*/ *a) {
7248 RBinJavaAttrInfo *attr = a;
7249 if (attr && attr->type == R_BIN_JAVA_ATTR_TYPE_RUNTIME_INVISIBLE_ANNOTATION_ATTR) {
7250 r_list_free (attr->info.annotation_array.annotations);
7251 free (attr->metas);
7252 free (attr->name);
7253 free (attr);
7254 }
7255 }
7256
r_bin_java_print_rtv_annotations_attr_summary(RBinJavaAttrInfo * attr)7257 R_API void r_bin_java_print_rtv_annotations_attr_summary(RBinJavaAttrInfo *attr) {
7258 if (attr && attr->type == R_BIN_JAVA_ATTR_TYPE_RUNTIME_VISIBLE_ANNOTATION_ATTR) {
7259 Eprintf ("Runtime Visible Annotations Attribute Information:\n");
7260 Eprintf (" Attribute Offset: 0x%08"PFMT64x "\n", attr->file_offset);
7261 Eprintf (" Attribute Name Index: %d (%s)\n", attr->name_idx, attr->name);
7262 Eprintf (" Attribute Length: %d\n", attr->length);
7263 r_bin_java_print_annotation_array_summary (&attr->info.annotation_array);
7264 }
7265 }
7266
r_bin_java_print_rti_annotations_attr_summary(RBinJavaAttrInfo * attr)7267 R_API void r_bin_java_print_rti_annotations_attr_summary(RBinJavaAttrInfo *attr) {
7268 if (attr && attr->type == R_BIN_JAVA_ATTR_TYPE_RUNTIME_INVISIBLE_ANNOTATION_ATTR) {
7269 Eprintf ("Runtime Invisible Annotations Attribute Information:\n");
7270 Eprintf (" Attribute Offset: 0x%08"PFMT64x "\n", attr->file_offset);
7271 Eprintf (" Attribute Name Index: %d (%s)\n", attr->name_idx, attr->name);
7272 Eprintf (" Attribute Length: %d\n", attr->length);
7273 r_bin_java_print_annotation_array_summary (&attr->info.annotation_array);
7274 }
7275 }
7276
r_bin_java_rtip_annotations_attr_calc_size(RBinJavaAttrInfo * attr)7277 R_API ut64 r_bin_java_rtip_annotations_attr_calc_size(RBinJavaAttrInfo *attr) {
7278 ut64 size = 0;
7279 RListIter *iter = NULL, *iter_tmp = NULL;
7280 RBinJavaAnnotationsArray *annotation_array;
7281 if (!attr) {
7282 // TODO eprintf allocation fail
7283 return size;
7284 }
7285 // attr->info.rtip_annotations_attr.num_parameters = buffer[offset];
7286 size += (6 + 1);
7287 r_list_foreach_safe (attr->info.rtip_annotations_attr.parameter_annotations, iter, iter_tmp, annotation_array) {
7288 if (annotation_array) {
7289 size += r_bin_java_annotation_array_calc_size (annotation_array);
7290 }
7291 }
7292 return size;
7293 }
7294
r_bin_java_rtip_annotations_attr_new(RBinJavaObj * bin,ut8 * buffer,ut64 sz,ut64 buf_offset)7295 R_API RBinJavaAttrInfo *r_bin_java_rtip_annotations_attr_new(RBinJavaObj *bin, ut8 *buffer, ut64 sz, ut64 buf_offset) {
7296 ut32 i = 0;
7297 RBinJavaAttrInfo *attr = NULL;
7298 ut64 offset = 0;
7299 attr = r_bin_java_default_attr_new (bin, buffer, sz, buf_offset);
7300 offset += 6;
7301 if (attr) {
7302 attr->type = R_BIN_JAVA_ATTR_TYPE_RUNTIME_INVISIBLE_PARAMETER_ANNOTATION_ATTR;
7303 attr->info.rtip_annotations_attr.num_parameters = buffer[offset];
7304 offset += 1;
7305 attr->info.rtip_annotations_attr.parameter_annotations = r_list_newf (r_bin_java_annotation_array_free);
7306 for (i = 0; i < attr->info.rtip_annotations_attr.num_parameters; i++) {
7307 if (offset >= sz) {
7308 break;
7309 }
7310 RBinJavaAnnotationsArray *annotation_array = r_bin_java_annotation_array_new (
7311 buffer + offset, sz - offset, buf_offset + offset);
7312 if (annotation_array) {
7313 offset += annotation_array->size;
7314 r_list_append (attr->info.rtip_annotations_attr.parameter_annotations, (void *) annotation_array);
7315 }
7316 }
7317 attr->size = offset;
7318 }
7319 return attr;
7320 }
7321
r_bin_java_rtvp_annotations_attr_new(RBinJavaObj * bin,ut8 * buffer,ut64 sz,ut64 buf_offset)7322 R_API RBinJavaAttrInfo *r_bin_java_rtvp_annotations_attr_new(RBinJavaObj *bin, ut8 *buffer, ut64 sz, ut64 buf_offset) {
7323 ut32 i = 0;
7324 RBinJavaAttrInfo *attr = NULL;
7325 ut64 offset = 0;
7326 attr = r_bin_java_default_attr_new (bin, buffer, sz, buf_offset);
7327 offset += 6;
7328 RBinJavaAnnotationsArray *annotation_array;
7329 if (attr) {
7330 attr->type = R_BIN_JAVA_ATTR_TYPE_RUNTIME_VISIBLE_PARAMETER_ANNOTATION_ATTR;
7331 attr->info.rtvp_annotations_attr.num_parameters = buffer[offset];
7332 offset += 1;
7333 attr->info.rtvp_annotations_attr.parameter_annotations = r_list_newf (r_bin_java_annotation_array_free);
7334 for (i = 0; i < attr->info.rtvp_annotations_attr.num_parameters; i++) {
7335 if (offset > sz) {
7336 break;
7337 }
7338 annotation_array = r_bin_java_annotation_array_new (buffer + offset, sz - offset, buf_offset + offset);
7339 if (annotation_array) {
7340 offset += annotation_array->size;
7341 }
7342 r_list_append (attr->info.rtvp_annotations_attr.parameter_annotations, (void *) annotation_array);
7343 }
7344 attr->size = offset;
7345 }
7346 return attr;
7347 }
7348
r_bin_java_rtvp_annotations_attr_calc_size(RBinJavaAttrInfo * attr)7349 R_API ut64 r_bin_java_rtvp_annotations_attr_calc_size(RBinJavaAttrInfo *attr) {
7350 ut64 size = 0;
7351 RListIter *iter = NULL, *iter_tmp = NULL;
7352 RBinJavaAnnotationsArray *annotation_array;
7353 if (!attr) {
7354 return size;
7355 }
7356 size += (6 + 1);
7357 r_list_foreach_safe (attr->info.rtvp_annotations_attr.parameter_annotations,
7358 iter, iter_tmp, annotation_array) {
7359 if (annotation_array) {
7360 size += r_bin_java_annotation_array_calc_size (
7361 annotation_array);
7362 }
7363 }
7364 return size;
7365 }
7366
r_bin_java_rtvp_annotations_attr_free(void * a)7367 R_API void r_bin_java_rtvp_annotations_attr_free(void /*RBinJavaAttrInfo*/ *a) {
7368 RBinJavaAttrInfo *attr = a;
7369 if (attr) {
7370 if (attr->type == R_BIN_JAVA_ATTR_TYPE_RUNTIME_VISIBLE_PARAMETER_ANNOTATION_ATTR) {
7371 r_list_free (attr->info.rtvp_annotations_attr.parameter_annotations);
7372 }
7373 free (attr->name);
7374 free (attr->metas);
7375 free (attr);
7376 }
7377 }
7378
r_bin_java_rtip_annotations_attr_free(void * a)7379 R_API void r_bin_java_rtip_annotations_attr_free(void /*RBinJavaAttrInfo*/ *a) {
7380 RBinJavaAttrInfo *attr = a;
7381 if (attr) { // && attr->type == R_BIN_JAVA_ATTR_TYPE_RUNTIME_INVISIBLE_PARAMETER_ANNOTATION_ATTR) {
7382 r_list_free (attr->info.rtip_annotations_attr.parameter_annotations);
7383 free (attr->metas);
7384 free (attr->name);
7385 free (attr);
7386 }
7387 }
7388
r_bin_java_print_rtvp_annotations_attr_summary(RBinJavaAttrInfo * attr)7389 R_API void r_bin_java_print_rtvp_annotations_attr_summary(RBinJavaAttrInfo *attr) {
7390 RBinJavaAnnotationsArray *annotation_array = NULL;
7391 RListIter *iter = NULL, *iter_tmp = NULL;
7392 if (attr && attr->type == R_BIN_JAVA_ATTR_TYPE_RUNTIME_VISIBLE_PARAMETER_ANNOTATION_ATTR) {
7393 eprintf ("Runtime Visible Parameter Annotations Attribute Information:\n");
7394 eprintf (" Attribute Offset: 0x%08"PFMT64x "\n", attr->file_offset);
7395 eprintf (" Attribute Name Index: %d (%s)\n", attr->name_idx, attr->name);
7396 eprintf (" Attribute Length: %d\n", attr->length);
7397 eprintf (" Number of Runtime Invisible Parameters: %d\n", attr->info.rtvp_annotations_attr.num_parameters);
7398 r_list_foreach_safe (attr->info.rtvp_annotations_attr.parameter_annotations, iter, iter_tmp, annotation_array) {
7399 r_bin_java_print_annotation_array_summary (annotation_array);
7400 }
7401 }
7402 }
7403
r_bin_java_print_rtip_annotations_attr_summary(RBinJavaAttrInfo * attr)7404 R_API void r_bin_java_print_rtip_annotations_attr_summary(RBinJavaAttrInfo *attr) {
7405 RBinJavaAnnotationsArray *annotation_array = NULL;
7406 RListIter *iter = NULL, *iter_tmp = NULL;
7407 if (attr && attr->type == R_BIN_JAVA_ATTR_TYPE_RUNTIME_INVISIBLE_PARAMETER_ANNOTATION_ATTR) {
7408 eprintf ("Runtime Invisible Parameter Annotations Attribute Information:\n");
7409 eprintf (" Attribute Offset: 0x%08"PFMT64x "\n", attr->file_offset);
7410 eprintf (" Attribute Name Index: %d (%s)\n", attr->name_idx, attr->name);
7411 eprintf (" Attribute Length: %d\n", attr->length);
7412 eprintf (" Number of Runtime Invisible Parameters: %d\n", attr->info.rtip_annotations_attr.num_parameters);
7413 r_list_foreach_safe (attr->info.rtip_annotations_attr.parameter_annotations, iter, iter_tmp, annotation_array) {
7414 r_bin_java_print_annotation_array_summary (annotation_array);
7415 }
7416 }
7417 }
7418
r_bin_java_find_cp_name_and_type_info(RBinJavaObj * bin,ut16 name_idx,ut16 descriptor_idx)7419 R_API RBinJavaCPTypeObj *r_bin_java_find_cp_name_and_type_info(RBinJavaObj *bin, ut16 name_idx, ut16 descriptor_idx) {
7420 RListIter *iter, *iter_tmp;
7421 RBinJavaCPTypeObj *res = NULL, *obj = NULL;
7422 IFDBG eprintf("Looking for name_idx: %d and descriptor_idx: %d\n", name_idx, descriptor_idx);
7423 r_list_foreach_safe (bin->cp_list, iter, iter_tmp, obj) {
7424 if (obj && obj->tag == R_BIN_JAVA_CP_NAMEANDTYPE) {
7425 IFDBG eprintf("RBinJavaCPTypeNameAndType has name_idx: %d and descriptor_idx: %d\n",
7426 obj->info.cp_name_and_type.name_idx, obj->info.cp_name_and_type.descriptor_idx);
7427 if (obj->info.cp_name_and_type.name_idx == name_idx &&
7428 obj->info.cp_name_and_type.descriptor_idx == descriptor_idx) {
7429 res = obj;
7430 break;
7431 }
7432 }
7433 }
7434 return res;
7435 }
7436
r_bin_java_resolve_cp_idx_type(RBinJavaObj * BIN_OBJ,int idx)7437 R_API char *r_bin_java_resolve_cp_idx_type(RBinJavaObj *BIN_OBJ, int idx) {
7438 RBinJavaCPTypeObj *item = NULL;
7439 char *str = NULL;
7440 if (BIN_OBJ && BIN_OBJ->cp_count < 1) {
7441 // r_bin_java_new_bin(BIN_OBJ);
7442 return NULL;
7443 }
7444 item = (RBinJavaCPTypeObj *) r_bin_java_get_item_from_bin_cp_list (BIN_OBJ, idx);
7445 if (item) {
7446 str = strdup (((RBinJavaCPTypeMetas *) item->metas->type_info)->name);
7447 } else {
7448 str = strdup ("INVALID");
7449 }
7450 return str;
7451 }
7452
r_bin_java_find_cp_ref_info_from_name_and_type(RBinJavaObj * bin,ut16 name_idx,ut16 descriptor_idx)7453 R_API RBinJavaCPTypeObj *r_bin_java_find_cp_ref_info_from_name_and_type(RBinJavaObj *bin, ut16 name_idx, ut16 descriptor_idx) {
7454 RBinJavaCPTypeObj *obj = r_bin_java_find_cp_name_and_type_info (bin, name_idx, descriptor_idx);
7455 if (obj) {
7456 return r_bin_java_find_cp_ref_info (bin, obj->metas->ord);
7457 }
7458 return NULL;
7459 }
7460
r_bin_java_find_cp_ref_info(RBinJavaObj * bin,ut16 name_and_type_idx)7461 R_API RBinJavaCPTypeObj *r_bin_java_find_cp_ref_info(RBinJavaObj *bin, ut16 name_and_type_idx) {
7462 RListIter *iter, *iter_tmp;
7463 RBinJavaCPTypeObj *res = NULL, *obj = NULL;
7464 r_list_foreach_safe (bin->cp_list, iter, iter_tmp, obj) {
7465 if (obj->tag == R_BIN_JAVA_CP_FIELDREF &&
7466 obj->info.cp_field.name_and_type_idx == name_and_type_idx) {
7467 res = obj;
7468 break;
7469 } else if (obj->tag == R_BIN_JAVA_CP_METHODREF &&
7470 obj->info.cp_method.name_and_type_idx == name_and_type_idx) {
7471 res = obj;
7472 break;
7473 }
7474 }
7475 return res;
7476 }
7477
r_bin_java_resolve(RBinJavaObj * BIN_OBJ,int idx,ut8 space_bn_name_type)7478 R_API char *r_bin_java_resolve(RBinJavaObj *BIN_OBJ, int idx, ut8 space_bn_name_type) {
7479 // TODO XXX FIXME add a size parameter to the str when it is passed in
7480 RBinJavaCPTypeObj *item = NULL, *item2 = NULL;
7481 char *class_str = NULL,
7482 *name_str = NULL,
7483 *desc_str = NULL,
7484 *string_str = NULL,
7485 *empty = "",
7486 *cp_name = NULL,
7487 *str = NULL;
7488 if (BIN_OBJ && BIN_OBJ->cp_count < 1) {
7489 // r_bin_java_new_bin(BIN_OBJ);
7490 return NULL;
7491 }
7492 item = (RBinJavaCPTypeObj *) r_bin_java_get_item_from_bin_cp_list (BIN_OBJ, idx);
7493 if (item) {
7494 cp_name = ((RBinJavaCPTypeMetas *) item->metas->type_info)->name;
7495 IFDBG eprintf("java_resolve Resolved: (%d) %s\n", idx, cp_name);
7496 } else {
7497 str = malloc (512);
7498 if (str) {
7499 snprintf (str, 512, "(%d) INVALID CP_OBJ", idx);
7500 }
7501 return str;
7502 }
7503 if (strcmp (cp_name, "Class") == 0) {
7504 item2 = (RBinJavaCPTypeObj *) r_bin_java_get_item_from_bin_cp_list (BIN_OBJ, idx);
7505 // str = r_bin_java_get_name_from_bin_cp_list (BIN_OBJ, idx-1);
7506 class_str = r_bin_java_get_item_name_from_bin_cp_list (BIN_OBJ, item);
7507 if (!class_str) {
7508 class_str = empty;
7509 }
7510 name_str = r_bin_java_get_item_name_from_bin_cp_list (BIN_OBJ, item2);
7511 if (!name_str) {
7512 name_str = empty;
7513 }
7514 desc_str = r_bin_java_get_item_desc_from_bin_cp_list (BIN_OBJ, item2);
7515 if (!desc_str) {
7516 desc_str = empty;
7517 }
7518 str = r_str_newf ("%s%s%s", name_str,
7519 space_bn_name_type ? " " : "", desc_str);
7520 if (class_str != empty) {
7521 free (class_str);
7522 }
7523 if (name_str != empty) {
7524 free (name_str);
7525 }
7526 if (desc_str != empty) {
7527 free (desc_str);
7528 }
7529 } else if (!strcmp (cp_name, "MethodRef") ||
7530 !strcmp (cp_name, "FieldRef") ||
7531 !strcmp (cp_name, "InterfaceMethodRef")) {
7532 /*
7533 * The MethodRef, FieldRef, and InterfaceMethodRef structures
7534 */
7535 class_str = r_bin_java_get_name_from_bin_cp_list (BIN_OBJ, item->info.cp_method.class_idx);
7536 if (!class_str) {
7537 class_str = empty;
7538 }
7539 name_str = r_bin_java_get_item_name_from_bin_cp_list (BIN_OBJ, item);
7540 if (!name_str) {
7541 name_str = empty;
7542 }
7543 desc_str = r_bin_java_get_item_desc_from_bin_cp_list (BIN_OBJ, item);
7544 if (!desc_str) {
7545 desc_str = empty;
7546 }
7547 str = r_str_newf ("%s/%s%s%s", class_str, name_str,
7548 space_bn_name_type ? " " : "", desc_str);
7549 if (class_str != empty) {
7550 free (class_str);
7551 }
7552 if (name_str != empty) {
7553 free (name_str);
7554 }
7555 if (desc_str != empty) {
7556 free (desc_str);
7557 }
7558 } else if (!strcmp (cp_name, "String")) {
7559 string_str = r_bin_java_get_utf8_from_bin_cp_list (BIN_OBJ, item->info.cp_string.string_idx);
7560 str = NULL;
7561 IFDBG eprintf("java_resolve String got: (%d) %s\n", item->info.cp_string.string_idx, string_str);
7562 if (!string_str) {
7563 string_str = empty;
7564 }
7565 str = r_str_newf ("\"%s\"", string_str);
7566 IFDBG eprintf("java_resolve String return: %s\n", str);
7567 if (string_str != empty) {
7568 free (string_str);
7569 }
7570
7571 } else if (!strcmp (cp_name, "Utf8")) {
7572 char *tmp_str = convert_string ((const char *) item->info.cp_utf8.bytes, item->info.cp_utf8.length);
7573 ut32 tmp_str_len = tmp_str ? strlen (tmp_str) + 4 : 0;
7574 if (tmp_str) {
7575 str = malloc (tmp_str_len + 4);
7576 snprintf (str, tmp_str_len + 4, "\"%s\"", tmp_str);
7577 }
7578 free (tmp_str);
7579 } else if (!strcmp (cp_name, "Long")) {
7580 str = r_str_newf ("0x%"PFMT64x, r_bin_java_raw_to_long (item->info.cp_long.bytes.raw, 0));
7581 } else if (!strcmp (cp_name, "Double")) {
7582 str = r_str_newf ("%f", r_bin_java_raw_to_double (item->info.cp_double.bytes.raw, 0));
7583 } else if (!strcmp (cp_name, "Integer")) {
7584 str = r_str_newf ("0x%08x", R_BIN_JAVA_UINT (item->info.cp_integer.bytes.raw, 0));
7585 } else if (!strcmp (cp_name, "Float")) {
7586 str = r_str_newf ("%f", R_BIN_JAVA_FLOAT (item->info.cp_float.bytes.raw, 0));
7587 } else if (!strcmp (cp_name, "NameAndType")) {
7588 name_str = r_bin_java_get_item_name_from_bin_cp_list (BIN_OBJ, item);
7589 if (!name_str) {
7590 name_str = empty;
7591 }
7592 desc_str = r_bin_java_get_item_desc_from_bin_cp_list (BIN_OBJ, item);
7593 if (!desc_str) {
7594 desc_str = empty;
7595 }
7596 str = r_str_newf ("%s%s%s", name_str, space_bn_name_type ? " " : "", desc_str);
7597 if (name_str != empty) {
7598 free (name_str);
7599 }
7600 if (desc_str != empty) {
7601 free (desc_str);
7602 }
7603 } else {
7604 str = strdup ("(null)");
7605 }
7606 return str;
7607 }
7608
r_bin_java_does_cp_idx_ref_method(RBinJavaObj * BIN_OBJ,int idx)7609 R_API ut8 r_bin_java_does_cp_idx_ref_method(RBinJavaObj *BIN_OBJ, int idx) {
7610 RBinJavaField *fm_type = NULL;
7611 RListIter *iter;
7612 ut8 res = 0;
7613 r_list_foreach (BIN_OBJ->methods_list, iter, fm_type) {
7614 if (fm_type->field_ref_cp_obj->metas->ord == idx) {
7615 res = 1;
7616 break;
7617 }
7618 }
7619 return res;
7620 }
7621
r_bin_java_does_cp_idx_ref_field(RBinJavaObj * BIN_OBJ,int idx)7622 R_API ut8 r_bin_java_does_cp_idx_ref_field(RBinJavaObj *BIN_OBJ, int idx) {
7623 RBinJavaField *fm_type = NULL;
7624 RListIter *iter;
7625 ut8 res = 0;
7626 r_list_foreach (BIN_OBJ->fields_list, iter, fm_type) {
7627 if (fm_type->field_ref_cp_obj->metas->ord == idx) {
7628 res = 1;
7629 break;
7630 }
7631 }
7632 return res;
7633 }
7634
r_bin_java_get_method_name(RBinJavaObj * bin_obj,ut32 idx)7635 R_API char *r_bin_java_get_method_name(RBinJavaObj *bin_obj, ut32 idx) {
7636 char *name = NULL;
7637 if (idx < r_list_length (bin_obj->methods_list)) {
7638 RBinJavaField *fm_type = r_list_get_n (bin_obj->methods_list, idx);
7639 name = strdup (fm_type->name);
7640 }
7641 return name;
7642 }
7643
r_bin_java_get_method_num_name(RBinJavaObj * bin_obj)7644 R_API RList *r_bin_java_get_method_num_name(RBinJavaObj *bin_obj) {
7645 ut32 i = 0;
7646 RListIter *iter = NULL;
7647 RBinJavaField *fm_type;
7648 RList *res = r_list_newf (free);
7649 r_list_foreach (bin_obj->methods_list, iter, fm_type) {
7650 ut32 len = strlen (fm_type->name) + 30;
7651 char *str = malloc (len);
7652 snprintf (str, len, "%d %s", i, fm_type->name);
7653 ++i;
7654 r_list_append (res, str);
7655 }
7656 return res;
7657 }
7658
7659 /*
7660 R_API int r_bin_java_does_cp_obj_ref_idx (RBinJavaObj *bin_obj, RBinJavaCPTypeObj *cp_obj, ut16 idx) {
7661 int res = false;
7662 RBinJavaCPTypeObj *t_obj = NULL;
7663 if (cp_obj) {
7664 switch (cp_obj->tag) {
7665 case R_BIN_JAVA_CP_NULL: break;
7666 case R_BIN_JAVA_CP_UTF8: break;
7667 case R_BIN_JAVA_CP_UNKNOWN: break;
7668 case R_BIN_JAVA_CP_INTEGER: break;
7669 case R_BIN_JAVA_CP_FLOAT: break;
7670 case R_BIN_JAVA_CP_LONG: break;
7671 case R_BIN_JAVA_CP_DOUBLE: break;
7672 case R_BIN_JAVA_CP_CLASS:
7673 res = idx == cp_obj->info.cp_class.name_idx ? true : false;
7674 break;
7675 case R_BIN_JAVA_CP_STRING:
7676 res = idx == cp_obj->info.cp_string.string_idx ? true : false;
7677 break;
7678 case R_BIN_JAVA_CP_METHODREF: break;// check if idx is referenced here
7679 case R_BIN_JAVA_CP_INTERFACEMETHOD_REF: break; // check if idx is referenced here
7680 case R_BIN_JAVA_CP_FIELDREF:
7681 t_obj = r_bin_java_get_item_from_cp (bin_obj, cp_obj->info.cp_method.class_idx);
7682 res = r_bin_java_does_cp_obj_ref_idx (bin_obj, t_obj, idx);
7683 if (res == true) break;
7684 t_obj = r_bin_java_get_item_from_cp (bin_obj, cp_obj->info.cp_method.name_and_type_idx);
7685 res = r_bin_java_does_cp_obj_ref_idx (bin_obj, t_obj, idx);
7686 break;
7687 case R_BIN_JAVA_CP_NAMEANDTYPE: break;// check if idx is referenced here
7688 obj->info.cp_name_and_type.name_idx
7689 case R_BIN_JAVA_CP_METHODHANDLE: break;// check if idx is referenced here
7690 case R_BIN_JAVA_CP_METHODTYPE: break;// check if idx is referenced here
7691 case R_BIN_JAVA_CP_INVOKEDYNAMIC: break;// check if idx is referenced here
7692 }
7693 }
7694 }
7695 */
r_bin_java_find_cp_const_by_val_long(RBinJavaObj * bin_obj,const ut8 * bytes,ut32 len)7696 R_API RList *r_bin_java_find_cp_const_by_val_long(RBinJavaObj *bin_obj, const ut8 *bytes, ut32 len) {
7697 RList *res = r_list_newf (free);
7698 ut32 *v = NULL;
7699 RListIter *iter;
7700 RBinJavaCPTypeObj *cp_obj;
7701 eprintf ("Looking for 0x%08x\n", R_BIN_JAVA_UINT (bytes, 0));
7702 r_list_foreach (bin_obj->cp_list, iter, cp_obj) {
7703 if (cp_obj->tag == R_BIN_JAVA_CP_LONG) {
7704 if (len == 8 && r_bin_java_raw_to_long (cp_obj->info.cp_long.bytes.raw, 0) == r_bin_java_raw_to_long (bytes, 0)) {
7705 // TODO: we can safely store a ut32 inside the list without having to allocate it
7706 v = malloc (sizeof (ut32));
7707 if (!v) {
7708 r_list_free (res);
7709 return NULL;
7710 }
7711 *v = cp_obj->idx;
7712 r_list_append (res, v);
7713 }
7714 }
7715 }
7716 return res;
7717 }
7718
r_bin_java_find_cp_const_by_val_double(RBinJavaObj * bin_obj,const ut8 * bytes,ut32 len)7719 R_API RList *r_bin_java_find_cp_const_by_val_double(RBinJavaObj *bin_obj, const ut8 *bytes, ut32 len) {
7720 RList *res = r_list_newf (free);
7721 ut32 *v = NULL;
7722 RListIter *iter;
7723 RBinJavaCPTypeObj *cp_obj;
7724 eprintf ("Looking for %f\n", r_bin_java_raw_to_double (bytes, 0));
7725 r_list_foreach (bin_obj->cp_list, iter, cp_obj) {
7726 if (cp_obj->tag == R_BIN_JAVA_CP_DOUBLE) {
7727 if (len == 8 && r_bin_java_raw_to_double (cp_obj->info.cp_long.bytes.raw, 0) == r_bin_java_raw_to_double (bytes, 0)) {
7728 v = malloc (sizeof (ut32));
7729 if (!v) {
7730 r_list_free (res);
7731 return NULL;
7732 }
7733 *v = cp_obj->idx;
7734 r_list_append (res, v);
7735 }
7736 }
7737 }
7738 return res;
7739 }
7740
r_bin_java_find_cp_const_by_val_float(RBinJavaObj * bin_obj,const ut8 * bytes,ut32 len)7741 R_API RList *r_bin_java_find_cp_const_by_val_float(RBinJavaObj *bin_obj, const ut8 *bytes, ut32 len) {
7742 RList *res = r_list_newf (free);
7743 ut32 *v = NULL;
7744 RListIter *iter;
7745 RBinJavaCPTypeObj *cp_obj;
7746 eprintf ("Looking for %f\n", R_BIN_JAVA_FLOAT (bytes, 0));
7747 r_list_foreach (bin_obj->cp_list, iter, cp_obj) {
7748 if (cp_obj->tag == R_BIN_JAVA_CP_FLOAT) {
7749 if (len == 4 && R_BIN_JAVA_FLOAT (cp_obj->info.cp_long.bytes.raw, 0) == R_BIN_JAVA_FLOAT (bytes, 0)) {
7750 v = malloc (sizeof (ut32));
7751 if (!v) {
7752 r_list_free (res);
7753 return NULL;
7754 }
7755 *v = cp_obj->idx;
7756 r_list_append (res, v);
7757 }
7758 }
7759 }
7760 return res;
7761 }
7762
r_bin_java_find_cp_const_by_val(RBinJavaObj * bin_obj,const ut8 * bytes,ut32 len,const char t)7763 R_API RList *r_bin_java_find_cp_const_by_val(RBinJavaObj *bin_obj, const ut8 *bytes, ut32 len, const char t) {
7764 switch (t) {
7765 case R_BIN_JAVA_CP_UTF8: return r_bin_java_find_cp_const_by_val_utf8 (bin_obj, bytes, len);
7766 case R_BIN_JAVA_CP_INTEGER: return r_bin_java_find_cp_const_by_val_int (bin_obj, bytes, len);
7767 case R_BIN_JAVA_CP_FLOAT: return r_bin_java_find_cp_const_by_val_float (bin_obj, bytes, len);
7768 case R_BIN_JAVA_CP_LONG: return r_bin_java_find_cp_const_by_val_long (bin_obj, bytes, len);
7769 case R_BIN_JAVA_CP_DOUBLE: return r_bin_java_find_cp_const_by_val_double (bin_obj, bytes, len);
7770 case R_BIN_JAVA_CP_UNKNOWN:
7771 default:
7772 eprintf ("Failed to perform the search for: %s\n", bytes);
7773 return r_list_new ();
7774 }
7775 }
7776
7777 // #if 0
7778 // Attempted to clean up these functions and remove them since they are "unused" but without
7779 // them there are some compile time warnings, because other projects actually depend on these
7780 // for some form of information.
U(add_cp_objs_to_sdb)7781 R_API void U(add_cp_objs_to_sdb)(RBinJavaObj * bin) {
7782 /*
7783 Add Constant Pool Serialized Object to an Array
7784 the key for this info is:
7785 Key:
7786 java.<classname>.cp_obj
7787 Each Value varies by type:
7788 In general its:
7789 <ordinal>.<file_offset>.<type_name>.[type specific stuff]
7790 Example:
7791 UTF-8: <ordinal>.<file_offset>.<type_name>.<strlen>.<hexlified(str)>
7792 Integer: <ordinal>.<file_offset>.<type_name>.<abs(int)>
7793 Long: <ordinal>.<file_offset>.<type_name>.abs(long)>
7794 FieldRef/MethodRef: <ordinal>.<file_offset>.<type_name>.<class_idx>.<name_and_type_idx>
7795 */
7796 ut32 idx = 0, class_name_inheap = 1;
7797 RBinJavaCPTypeObj *cp_obj = NULL;
7798 char *key = NULL,
7799 *value = NULL;
7800 char str_cnt[40];
7801 char *class_name = r_bin_java_get_this_class_name (bin);
7802 ut32 key_buf_size = 0;
7803 if (!class_name) {
7804 class_name = "unknown";
7805 class_name_inheap = 0;
7806 }
7807 // 4 - format, 8 number, 1 null byte, 7 "unknown"
7808 key_buf_size = strlen (class_name) + 4 + 8 + 1;
7809 key = malloc (key_buf_size);
7810 if (key == NULL) {
7811 if (class_name_inheap) {
7812 free (class_name);
7813 }
7814 return;
7815 }
7816 snprintf (key, key_buf_size - 1, "%s.cp_count", class_name);
7817 key[key_buf_size - 1] = 0;
7818 snprintf (str_cnt, 39, "%d", bin->cp_count);
7819 str_cnt[39] = 0;
7820 sdb_set (bin->kv, key, value, 0);
7821 // sdb_alist(bin->kv, key);
7822 for (idx = 0; idx < bin->cp_count; idx++) {
7823 snprintf (key, key_buf_size - 1, "%s.cp.%d", class_name, idx);
7824 key[key_buf_size - 1] = 0;
7825 cp_obj = (RBinJavaCPTypeObj *) r_bin_java_get_item_from_bin_cp_list (bin, idx);
7826 IFDBG eprintf("Adding %s to the sdb.\n", key);
7827 if (cp_obj) {
7828 value = ((RBinJavaCPTypeMetas *)
7829 cp_obj->metas->type_info)->
7830 allocs->stringify_obj (cp_obj);
7831 sdb_set (bin->kv, key, value, 0);
7832 free (value);
7833 }
7834 }
7835 if (class_name_inheap) {
7836 free (class_name);
7837 }
7838 free (key);
7839 }
7840
U(add_field_infos_to_sdb)7841 R_API void U(add_field_infos_to_sdb)(RBinJavaObj * bin) {
7842 /*
7843 *** Experimental and May Change ***
7844 Add field information to an Array
7845 the key for this info variable depenedent on addr, method ordinal, etc.
7846 Key 1, mapping to method key:
7847 java.<file_offset> = <field_key>
7848 Key 3, method description
7849 <field_key>.info = [<access str>, <class_name>, <name>, <signature>]
7850 key 4, method meta
7851 <field_key>.meta = [<file_offset>, ?]
7852 */
7853 RListIter *iter = NULL, *iter_tmp = NULL;
7854 RBinJavaField *fm_type;
7855 ut32 key_size = 255,
7856 value_buffer_size = 1024,
7857 class_name_inheap = 1;
7858 char *field_key = NULL,
7859 *field_key_value = NULL,
7860 *value_buffer = NULL;
7861 char *class_name = r_bin_java_get_this_class_name (bin);
7862 if (!class_name) {
7863 class_name = "unknown";
7864 class_name_inheap = 0;
7865 }
7866 key_size += strlen (class_name);
7867 value_buffer_size += strlen (class_name);
7868 field_key = malloc (key_size);
7869 value_buffer = malloc (value_buffer_size);
7870 field_key_value = malloc (key_size);
7871 snprintf (field_key, key_size, "%s.methods", class_name);
7872 field_key[key_size - 1] = 0;
7873 r_list_foreach_safe (bin->fields_list, iter, iter_tmp, fm_type) {
7874 char number_buffer[80];
7875 ut64 file_offset = fm_type->file_offset + bin->loadaddr;
7876 snprintf (number_buffer, sizeof (number_buffer), "0x%04"PFMT64x, file_offset);
7877 IFDBG eprintf("Inserting: []%s = %s\n", field_key, number_buffer);
7878 sdb_array_push (bin->kv, field_key, number_buffer, 0);
7879 }
7880 r_list_foreach_safe (bin->fields_list, iter, iter_tmp, fm_type) {
7881 ut64 field_offset = fm_type->file_offset + bin->loadaddr;
7882 // generate method specific key & value
7883 snprintf (field_key, key_size, "%s.0x%04"PFMT64x, class_name, field_offset);
7884 field_key[key_size - 1] = 0;
7885 snprintf (field_key_value, key_size, "%s.0x%04"PFMT64x ".field", class_name, field_offset);
7886 field_key_value[key_size - 1] = 0;
7887 sdb_set (bin->kv, field_key, field_key_value, 0);
7888 IFDBG eprintf("Inserting: %s = %s\n", field_key, field_key_value);
7889 // generate info key, and place values in method info array
7890 snprintf (field_key, key_size, "%s.info", field_key_value);
7891 field_key[key_size - 1] = 0;
7892 snprintf (value_buffer, value_buffer_size, "%s", fm_type->flags_str);
7893 value_buffer[value_buffer_size - 1] = 0;
7894 sdb_array_push (bin->kv, field_key, value_buffer, 0);
7895 IFDBG eprintf("Inserting: []%s = %s\n", field_key, value_buffer);
7896 snprintf (value_buffer, value_buffer_size, "%s", fm_type->class_name);
7897 value_buffer[value_buffer_size - 1] = 0;
7898 sdb_array_push (bin->kv, field_key, value_buffer, 0);
7899 IFDBG eprintf("Inserting: []%s = %s\n", field_key, value_buffer);
7900 snprintf (value_buffer, value_buffer_size, "%s", fm_type->name);
7901 value_buffer[value_buffer_size - 1] = 0;
7902 sdb_array_push (bin->kv, field_key, value_buffer, 0);
7903 IFDBG eprintf("Inserting: []%s = %s\n", field_key, value_buffer);
7904 snprintf (value_buffer, value_buffer_size, "%s", fm_type->descriptor);
7905 value_buffer[value_buffer_size - 1] = 0;
7906 sdb_array_push (bin->kv, field_key, value_buffer, 0);
7907 IFDBG eprintf("Inserting: []%s = %s\n", field_key, value_buffer);
7908 }
7909 free (field_key);
7910 free (field_key_value);
7911 free (value_buffer);
7912 if (class_name_inheap) {
7913 free (class_name);
7914 }
7915 }
7916
U(add_method_infos_to_sdb)7917 R_API void U(add_method_infos_to_sdb)(RBinJavaObj * bin) {
7918 /*
7919 *** Experimental and May Change ***
7920 Add Mehtod information to an Array
7921 the key for this info variable depenedent on addr, method ordinal, etc.
7922 Key 1, mapping to method key:
7923 java.<file_offset> = <method_key>
7924 Key 2, basic code information
7925 <method_key>.code = [<addr>, <size>]
7926 Key 3, method description
7927 <method_key>.info = [<access str>, <class_name>, <name>, <signature>,]
7928 key 4, method meta
7929 <method_key>.meta = [<file_offset>, ?]
7930 // TODO in key 3 add <class_name>?
7931 e.g. <access str>.<name>.<signature>
7932 Note: method name not used because of collisions with operator overloading
7933 also take note that code offset and the method offset are not the same
7934 values.
7935 */
7936 RListIter *iter = NULL, *iter_tmp = NULL;
7937 RBinJavaField *fm_type;
7938 ut32 key_size = 255,
7939 value_buffer_size = 1024,
7940 class_name_inheap = 1;
7941 char *method_key = NULL,
7942 *method_key_value = NULL,
7943 *value_buffer = NULL;
7944 char *class_name = r_bin_java_get_this_class_name (bin);
7945 ut64 baddr = bin->loadaddr;
7946 if (!class_name) {
7947 class_name = "unknown";
7948 class_name_inheap = 0;
7949 }
7950 key_size += strlen (class_name);
7951 value_buffer_size += strlen (class_name);
7952 method_key = malloc (key_size);
7953 value_buffer = malloc (value_buffer_size);
7954 method_key_value = malloc (key_size);
7955 snprintf (method_key, key_size, "%s.methods", class_name);
7956 method_key[key_size - 1] = 0;
7957 r_list_foreach_safe (bin->methods_list, iter, iter_tmp, fm_type) {
7958 char number_buffer[80];
7959 ut64 file_offset = fm_type->file_offset + baddr;
7960 snprintf (number_buffer, sizeof (number_buffer), "0x%04"PFMT64x, file_offset);
7961 sdb_array_push (bin->kv, method_key, number_buffer, 0);
7962 }
7963 r_list_foreach_safe (bin->methods_list, iter, iter_tmp, fm_type) {
7964 ut64 code_offset = r_bin_java_get_method_code_offset (fm_type) + baddr,
7965 code_size = r_bin_java_get_method_code_size (fm_type),
7966 method_offset = fm_type->file_offset + baddr;
7967 // generate method specific key & value
7968 snprintf (method_key, key_size, "%s.0x%04"PFMT64x, class_name, code_offset);
7969 method_key[key_size - 1] = 0;
7970 snprintf (method_key_value, key_size, "%s.0x%04"PFMT64x ".method", class_name, method_offset);
7971 method_key_value[key_size - 1] = 0;
7972 IFDBG eprintf("Adding %s to sdb_array: %s\n", method_key_value, method_key);
7973 sdb_set (bin->kv, method_key, method_key_value, 0);
7974 // generate code key and values
7975 snprintf (method_key, key_size, "%s.code", method_key_value);
7976 method_key[key_size - 1] = 0;
7977 snprintf (value_buffer, value_buffer_size, "0x%04"PFMT64x, code_offset);
7978 value_buffer[value_buffer_size - 1] = 0;
7979 sdb_array_push (bin->kv, method_key, value_buffer, 0);
7980 snprintf (value_buffer, value_buffer_size, "0x%04"PFMT64x, code_size);
7981 value_buffer[value_buffer_size - 1] = 0;
7982 sdb_array_push (bin->kv, method_key, value_buffer, 0);
7983 // generate info key, and place values in method info array
7984 snprintf (method_key, key_size, "%s.info", method_key_value);
7985 method_key[key_size - 1] = 0;
7986 snprintf (value_buffer, value_buffer_size, "%s", fm_type->flags_str);
7987 value_buffer[value_buffer_size - 1] = 0;
7988 IFDBG eprintf("Adding %s to sdb_array: %s\n", value_buffer, method_key);
7989 sdb_array_push (bin->kv, method_key, value_buffer, 0);
7990 snprintf (value_buffer, value_buffer_size, "%s", fm_type->class_name);
7991 value_buffer[value_buffer_size - 1] = 0;
7992 IFDBG eprintf("Adding %s to sdb_array: %s\n", value_buffer, method_key);
7993 sdb_array_push (bin->kv, method_key, value_buffer, 0);
7994 snprintf (value_buffer, value_buffer_size, "%s", fm_type->name);
7995 value_buffer[value_buffer_size - 1] = 0;
7996 IFDBG eprintf("Adding %s to sdb_array: %s\n", value_buffer, method_key);
7997 sdb_array_push (bin->kv, method_key, value_buffer, 0);
7998 snprintf (value_buffer, value_buffer_size, "%s", fm_type->descriptor);
7999 value_buffer[value_buffer_size - 1] = 0;
8000 IFDBG eprintf("Adding %s to sdb_array: %s\n", value_buffer, method_key);
8001 sdb_array_push (bin->kv, method_key, value_buffer, 0);
8002 }
8003 free (method_key);
8004 free (method_key_value);
8005 free (value_buffer);
8006 if (class_name_inheap) {
8007 free (class_name);
8008 }
8009 }
8010
U(r_bin_java_get_args_from_bin)8011 R_API RList *U(r_bin_java_get_args_from_bin)(RBinJavaObj * bin_obj, ut64 addr) {
8012 RBinJavaField *fm_type = r_bin_java_get_method_code_attribute_with_addr (bin_obj, addr);
8013 return fm_type ? r_bin_java_get_args (fm_type) : NULL;
8014 }
8015
U(r_bin_java_get_ret_from_bin)8016 R_API RList *U(r_bin_java_get_ret_from_bin)(RBinJavaObj * bin_obj, ut64 addr) {
8017 RBinJavaField *fm_type = r_bin_java_get_method_code_attribute_with_addr (bin_obj, addr);
8018 return fm_type ? r_bin_java_get_ret (fm_type) : NULL;
8019 }
8020
U(r_bin_java_get_fcn_name_from_bin)8021 R_API char *U(r_bin_java_get_fcn_name_from_bin)(RBinJavaObj * bin_obj, ut64 addr) {
8022 RBinJavaField *fm_type = r_bin_java_get_method_code_attribute_with_addr (bin_obj, addr);
8023 return fm_type && fm_type->name ? strdup (fm_type->name) : NULL;
8024 }
8025
U(r_bin_java_is_method_static)8026 R_API int U(r_bin_java_is_method_static)(RBinJavaObj * bin_obj, ut64 addr) {
8027 RBinJavaField *fm_type = r_bin_java_get_method_code_attribute_with_addr (bin_obj, addr);
8028 return fm_type && fm_type->flags & R_BIN_JAVA_METHOD_ACC_STATIC;
8029 }
8030
U(r_bin_java_is_method_private)8031 R_API int U(r_bin_java_is_method_private)(RBinJavaObj * bin_obj, ut64 addr) {
8032 return r_bin_java_is_fm_type_private (r_bin_java_get_method_code_attribute_with_addr (bin_obj, addr));
8033 }
8034
U(r_bin_java_is_method_protected)8035 R_API int U(r_bin_java_is_method_protected)(RBinJavaObj * bin_obj, ut64 addr) {
8036 return r_bin_java_is_fm_type_protected (
8037 r_bin_java_get_method_code_attribute_with_addr (bin_obj, addr));
8038 }
8039
r_bin_java_print_method_idx_summary(RBinJavaObj * bin_obj,ut32 idx)8040 R_API int r_bin_java_print_method_idx_summary(RBinJavaObj *bin_obj, ut32 idx) {
8041 int res = false;
8042 if (idx < r_list_length (bin_obj->methods_list)) {
8043 RBinJavaField *fm_type = r_list_get_n (bin_obj->methods_list, idx);
8044 r_bin_java_print_method_summary (fm_type);
8045 res = true;
8046 }
8047 return res;
8048 }
8049
r_bin_java_get_method_count(RBinJavaObj * bin_obj)8050 R_API ut32 r_bin_java_get_method_count(RBinJavaObj *bin_obj) {
8051 return r_list_length (bin_obj->methods_list);
8052 }
8053
r_bin_java_get_interface_names(RBinJavaObj * bin)8054 R_API RList *r_bin_java_get_interface_names(RBinJavaObj *bin) {
8055 RList *interfaces_names = r_list_new ();
8056 RListIter *iter;
8057 RBinJavaInterfaceInfo *ifobj;
8058 r_list_foreach (bin->interfaces_list, iter, ifobj) {
8059 if (ifobj && ifobj->name) {
8060 r_list_append (interfaces_names, strdup (ifobj->name));
8061 }
8062 }
8063 return interfaces_names;
8064 }
8065
r_bin_java_get_main(RBinJavaObj * bin)8066 R_API ut64 r_bin_java_get_main(RBinJavaObj *bin) {
8067 if (bin->main_code_attr) {
8068 return bin->main_code_attr->info.code_attr.code_offset + bin->loadaddr;
8069 }
8070 return 0;
8071 }
8072
r_bin_java_new(const char * file,ut64 loadaddr,Sdb * kv)8073 R_API RBinJavaObj *r_bin_java_new(const char *file, ut64 loadaddr, Sdb *kv) {
8074 RBinJavaObj *bin = R_NEW0 (RBinJavaObj);
8075 if (!bin) {
8076 return NULL;
8077 }
8078 bin->file = strdup (file);
8079 size_t sz;
8080 ut8 *buf = (ut8 *)r_file_slurp (file, &sz);
8081 bin->size = sz;
8082 if (!buf) {
8083 return r_bin_java_free (bin);
8084 }
8085 if (!r_bin_java_new_bin (bin, loadaddr, kv, buf, bin->size)) {
8086 r_bin_java_free (bin);
8087 bin = NULL;
8088 }
8089 free (buf);
8090 return bin;
8091 }
8092
r_bin_java_get_class_entrypoint(RBinJavaObj * bin)8093 R_API ut64 r_bin_java_get_class_entrypoint(RBinJavaObj *bin) {
8094 if (bin->cf2.this_class_entrypoint_code_attr) {
8095 return bin->cf2.this_class_entrypoint_code_attr->info.code_attr.code_offset;
8096 }
8097 return 0;
8098 }
8099
r_bin_java_get_method_exception_table_with_addr(RBinJavaObj * bin,ut64 addr)8100 R_API RList *r_bin_java_get_method_exception_table_with_addr(RBinJavaObj *bin, ut64 addr) {
8101 RListIter *iter = NULL, *iter_tmp = NULL;
8102 RBinJavaField *fm_type, *res = NULL;
8103 if (!bin && R_BIN_JAVA_GLOBAL_BIN) {
8104 bin = R_BIN_JAVA_GLOBAL_BIN;
8105 }
8106 if (!bin) {
8107 eprintf ("Attempting to analyse function when the R_BIN_JAVA_GLOBAL_BIN has not been set.\n");
8108 return NULL;
8109 }
8110 r_list_foreach_safe (bin->methods_list, iter, iter_tmp, fm_type) {
8111 ut64 offset = r_bin_java_get_method_code_offset (fm_type) + bin->loadaddr,
8112 size = r_bin_java_get_method_code_size (fm_type);
8113 if (addr >= offset && addr <= size + offset) {
8114 res = fm_type;
8115 }
8116 }
8117 if (res) {
8118 RBinJavaAttrInfo *code_attr = r_bin_java_get_method_code_attribute (res);
8119 return code_attr->info.code_attr.exception_table;
8120 }
8121 return NULL;
8122 }
8123
r_bin_java_get_methods_list(RBinJavaObj * bin)8124 R_API const RList *r_bin_java_get_methods_list(RBinJavaObj *bin) {
8125 if (bin) {
8126 return bin->methods_list;
8127 }
8128 if (R_BIN_JAVA_GLOBAL_BIN) {
8129 return R_BIN_JAVA_GLOBAL_BIN->methods_list;
8130 }
8131 return NULL;
8132 }
8133
r_bin_java_get_bin_obj_list_thru_obj(RBinJavaObj * bin_obj)8134 R_API RList *r_bin_java_get_bin_obj_list_thru_obj(RBinJavaObj *bin_obj) {
8135 RList *the_list;
8136 Sdb *sdb;
8137 if (!bin_obj) {
8138 return NULL;
8139 }
8140 sdb = bin_obj->AllJavaBinObjs;
8141 if (!sdb) {
8142 return NULL;
8143 }
8144 the_list = r_list_new ();
8145 if (!the_list) {
8146 return NULL;
8147 }
8148 sdb_foreach (sdb, sdb_iterate_build_list, (void *) the_list);
8149 return the_list;
8150 }
8151
r_bin_java_extract_all_bin_type_values(RBinJavaObj * bin_obj)8152 R_API RList *r_bin_java_extract_all_bin_type_values(RBinJavaObj *bin_obj) {
8153 RListIter *fm_type_iter;
8154 RList *all_types = r_list_new ();
8155 RBinJavaField *fm_type;
8156 // get all field types
8157 r_list_foreach (bin_obj->fields_list, fm_type_iter, fm_type) {
8158 char *desc = NULL;
8159 if (!extract_type_value (fm_type->descriptor, &desc)) {
8160 return NULL;
8161 }
8162 IFDBG eprintf("Adding field type: %s\n", desc);
8163 r_list_append (all_types, desc);
8164 }
8165 // get all method types
8166 r_list_foreach (bin_obj->methods_list, fm_type_iter, fm_type) {
8167 RList *the_list = r_bin_java_extract_type_values (fm_type->descriptor);
8168 RListIter *desc_iter;
8169 char *str;
8170 r_list_foreach (the_list, desc_iter, str) {
8171 if (str && *str != '(' && *str != ')') {
8172 r_list_append (all_types, strdup (str));
8173 IFDBG eprintf("Adding method type: %s\n", str);
8174 }
8175 }
8176 r_list_free (the_list);
8177 }
8178 return all_types;
8179 }
8180
r_bin_java_get_method_definitions(RBinJavaObj * bin)8181 R_API RList *r_bin_java_get_method_definitions(RBinJavaObj *bin) {
8182 RBinJavaField *fm_type = NULL;
8183 RList *the_list = r_list_new ();
8184 if (!the_list) {
8185 return NULL;
8186 }
8187 RListIter *iter = NULL;
8188 if (!bin) {
8189 return the_list;
8190 }
8191 r_list_foreach (bin->methods_list, iter, fm_type) {
8192 char *method_proto = r_bin_java_get_method_definition (fm_type);
8193 // eprintf ("Method prototype: %s\n", method_proto);
8194 r_list_append (the_list, method_proto);
8195 }
8196 return the_list;
8197 }
8198
r_bin_java_get_field_definitions(RBinJavaObj * bin)8199 R_API RList *r_bin_java_get_field_definitions(RBinJavaObj *bin) {
8200 RBinJavaField *fm_type = NULL;
8201 RList *the_list = r_list_new ();
8202 if (!the_list) {
8203 return NULL;
8204 }
8205 RListIter *iter = NULL;
8206 if (!bin) {
8207 return the_list;
8208 }
8209 r_list_foreach (bin->fields_list, iter, fm_type) {
8210 char *field_def = r_bin_java_get_field_definition (fm_type);
8211 // eprintf ("Field def: %s, %s, %s, %s\n", fm_type->name, fm_type->descriptor, fm_type->flags_str, field_def);
8212 r_list_append (the_list, field_def);
8213 }
8214 return the_list;
8215 }
8216
r_bin_java_get_import_definitions(RBinJavaObj * bin)8217 R_API RList *r_bin_java_get_import_definitions(RBinJavaObj *bin) {
8218 RList *the_list = r_bin_java_get_lib_names (bin);
8219 RListIter *iter = NULL;
8220 char *new_str;
8221 if (!bin || !the_list) {
8222 return the_list;
8223 }
8224 r_list_foreach (the_list, iter, new_str) {
8225 while (*new_str) {
8226 if (*new_str == '/') {
8227 *new_str = '.';
8228 }
8229 new_str++;
8230 }
8231 }
8232 return the_list;
8233 }
8234
r_bin_java_get_field_offsets(RBinJavaObj * bin)8235 R_API RList *r_bin_java_get_field_offsets(RBinJavaObj *bin) {
8236 RBinJavaField *fm_type = NULL;
8237 RList *the_list = r_list_new ();
8238 if (!the_list) {
8239 return NULL;
8240 }
8241 RListIter *iter = NULL;
8242 ut64 *paddr = NULL;
8243 if (!bin) {
8244 return the_list;
8245 }
8246 the_list->free = free;
8247 r_list_foreach (bin->fields_list, iter, fm_type) {
8248 paddr = malloc (sizeof(ut64));
8249 if (!paddr) {
8250 r_list_free (the_list);
8251 return NULL;
8252 }
8253 *paddr = fm_type->file_offset + bin->loadaddr;
8254 // eprintf ("Field def: %s, %s, %s, %s\n", fm_type->name, fm_type->descriptor, fm_type->flags_str, field_def);
8255 r_list_append (the_list, paddr);
8256 }
8257 return the_list;
8258 }
8259
r_bin_java_get_method_offsets(RBinJavaObj * bin)8260 R_API RList *r_bin_java_get_method_offsets(RBinJavaObj *bin) {
8261 RBinJavaField *fm_type = NULL;
8262 RList *the_list = r_list_new ();
8263 RListIter *iter = NULL;
8264 ut64 *paddr = NULL;
8265 if (!bin) {
8266 return the_list;
8267 }
8268 the_list->free = free;
8269 r_list_foreach (bin->methods_list, iter, fm_type) {
8270 paddr = R_NEW0 (ut64);
8271 *paddr = fm_type->file_offset + bin->loadaddr;
8272 r_list_append (the_list, paddr);
8273 }
8274 return the_list;
8275 }
8276
r_bin_java_calculate_field_access_value(const char * access_flags_str)8277 R_API ut16 r_bin_java_calculate_field_access_value(const char *access_flags_str) {
8278 return calculate_access_value (access_flags_str, FIELD_ACCESS_FLAGS);
8279 }
8280
r_bin_java_calculate_class_access_value(const char * access_flags_str)8281 R_API ut16 r_bin_java_calculate_class_access_value(const char *access_flags_str) {
8282 return calculate_access_value (access_flags_str, CLASS_ACCESS_FLAGS);
8283 }
8284
r_bin_java_calculate_method_access_value(const char * access_flags_str)8285 R_API ut16 r_bin_java_calculate_method_access_value(const char *access_flags_str) {
8286 return calculate_access_value (access_flags_str, METHOD_ACCESS_FLAGS);
8287 }
8288
retrieve_all_method_access_string_and_value(void)8289 R_API RList *retrieve_all_method_access_string_and_value(void) {
8290 return retrieve_all_access_string_and_value (METHOD_ACCESS_FLAGS);
8291 }
8292
retrieve_all_field_access_string_and_value(void)8293 R_API RList *retrieve_all_field_access_string_and_value(void) {
8294 return retrieve_all_access_string_and_value (FIELD_ACCESS_FLAGS);
8295 }
8296
retrieve_all_class_access_string_and_value(void)8297 R_API RList *retrieve_all_class_access_string_and_value(void) {
8298 return retrieve_all_access_string_and_value (CLASS_ACCESS_FLAGS);
8299 }
8300
r_bin_java_resolve_with_space(RBinJavaObj * obj,int idx)8301 R_API char *r_bin_java_resolve_with_space(RBinJavaObj *obj, int idx) {
8302 return r_bin_java_resolve (obj, idx, 1);
8303 }
8304
r_bin_java_resolve_without_space(RBinJavaObj * obj,int idx)8305 R_API char *r_bin_java_resolve_without_space(RBinJavaObj *obj, int idx) {
8306 return r_bin_java_resolve (obj, idx, 0);
8307 }
8308
r_bin_java_resolve_b64_encode(RBinJavaObj * BIN_OBJ,ut16 idx)8309 R_API char *r_bin_java_resolve_b64_encode(RBinJavaObj *BIN_OBJ, ut16 idx) {
8310 RBinJavaCPTypeObj *item = NULL, *item2 = NULL;
8311 char *class_str = NULL,
8312 *name_str = NULL,
8313 *desc_str = NULL,
8314 *string_str = NULL,
8315 *empty = "",
8316 *cp_name = NULL,
8317 *str = NULL, *out = NULL;
8318 int memory_alloc = 0;
8319 if (BIN_OBJ && BIN_OBJ->cp_count < 1) {
8320 // r_bin_java_new_bin(BIN_OBJ);
8321 return NULL;
8322 }
8323 item = (RBinJavaCPTypeObj *) r_bin_java_get_item_from_bin_cp_list (BIN_OBJ, idx);
8324 if (item) {
8325 cp_name = ((RBinJavaCPTypeMetas *) item->metas->type_info)->name;
8326 IFDBG eprintf("java_resolve Resolved: (%d) %s\n", idx, cp_name);
8327 } else {
8328 return NULL;
8329 }
8330 if (!strcmp (cp_name, "Class")) {
8331 item2 = (RBinJavaCPTypeObj *) r_bin_java_get_item_from_bin_cp_list (BIN_OBJ, idx);
8332 // str = r_bin_java_get_name_from_bin_cp_list (BIN_OBJ, idx-1);
8333 class_str = r_bin_java_get_item_name_from_bin_cp_list (BIN_OBJ, item);
8334 if (!class_str) {
8335 class_str = empty;
8336 }
8337 name_str = r_bin_java_get_item_name_from_bin_cp_list (BIN_OBJ, item2);
8338 if (!name_str) {
8339 name_str = empty;
8340 }
8341 desc_str = r_bin_java_get_item_desc_from_bin_cp_list (BIN_OBJ, item2);
8342 if (!desc_str) {
8343 desc_str = empty;
8344 }
8345 memory_alloc = strlen (class_str) + strlen (name_str) + strlen (desc_str) + 3;
8346 if (memory_alloc) {
8347 str = malloc (memory_alloc);
8348 if (str) {
8349 snprintf (str, memory_alloc, "%s%s", name_str, desc_str);
8350 out = r_base64_encode_dyn ((const char *) str, strlen (str));
8351 free (str);
8352 str = out;
8353 }
8354 }
8355 if (class_str != empty) {
8356 free (class_str);
8357 }
8358 if (name_str != empty) {
8359 free (name_str);
8360 }
8361 if (desc_str != empty) {
8362 free (desc_str);
8363 }
8364 } else if (strcmp (cp_name, "MethodRef") == 0 ||
8365 strcmp (cp_name, "FieldRef") == 0 ||
8366 strcmp (cp_name, "InterfaceMethodRef") == 0) {
8367 /*
8368 * The MethodRef, FieldRef, and InterfaceMethodRef structures
8369 */
8370 class_str = r_bin_java_get_name_from_bin_cp_list (BIN_OBJ, item->info.cp_method.class_idx);
8371 if (!class_str) {
8372 class_str = empty;
8373 }
8374 name_str = r_bin_java_get_item_name_from_bin_cp_list (BIN_OBJ, item);
8375 if (!name_str) {
8376 name_str = empty;
8377 }
8378 desc_str = r_bin_java_get_item_desc_from_bin_cp_list (BIN_OBJ, item);
8379 if (!desc_str) {
8380 desc_str = empty;
8381 }
8382 memory_alloc = strlen (class_str) + strlen (name_str) + strlen (desc_str) + 3;
8383 if (memory_alloc) {
8384 str = malloc (memory_alloc);
8385 if (str) {
8386 snprintf (str, memory_alloc, "%s/%s%s", class_str, name_str, desc_str);
8387 out = r_base64_encode_dyn ((const char *) str, strlen (str));
8388 free (str);
8389 str = out;
8390 }
8391 }
8392 if (class_str != empty) {
8393 free (class_str);
8394 }
8395 if (name_str != empty) {
8396 free (name_str);
8397 }
8398 if (desc_str != empty) {
8399 free (desc_str);
8400 }
8401 } else if (strcmp (cp_name, "String") == 0) {
8402 ut32 length = r_bin_java_get_utf8_len_from_bin_cp_list (BIN_OBJ, item->info.cp_string.string_idx);
8403 string_str = r_bin_java_get_utf8_from_bin_cp_list (BIN_OBJ, item->info.cp_string.string_idx);
8404 str = NULL;
8405 IFDBG eprintf("java_resolve String got: (%d) %s\n", item->info.cp_string.string_idx, string_str);
8406 if (!string_str) {
8407 string_str = empty;
8408 length = strlen (empty);
8409 }
8410 memory_alloc = length + 3;
8411 if (memory_alloc) {
8412 str = malloc (memory_alloc);
8413 if (str) {
8414 snprintf (str, memory_alloc, "\"%s\"", string_str);
8415 out = r_base64_encode_dyn ((const char *) str, strlen (str));
8416 free (str);
8417 str = out;
8418 }
8419 }
8420 IFDBG eprintf("java_resolve String return: %s\n", str);
8421 if (string_str != empty) {
8422 free (string_str);
8423 }
8424 } else if (strcmp (cp_name, "Utf8") == 0) {
8425 ut64 sz = item->info.cp_utf8.length ? item->info.cp_utf8.length + 10 : 10;
8426 str = malloc (sz);
8427 memset (str, 0, sz);
8428 if (sz > 10) {
8429 r_base64_encode (str, item->info.cp_utf8.bytes, item->info.cp_utf8.length);
8430 }
8431 } else if (strcmp (cp_name, "Long") == 0) {
8432 str = malloc (34);
8433 if (str) {
8434 snprintf (str, 34, "0x%"PFMT64x, r_bin_java_raw_to_long (item->info.cp_long.bytes.raw, 0));
8435 out = r_base64_encode_dyn ((const char *) str, strlen (str));
8436 free (str);
8437 str = out;
8438 }
8439 } else if (strcmp (cp_name, "Double") == 0) {
8440 str = malloc (1000);
8441 if (str) {
8442 snprintf (str, 1000, "%f", r_bin_java_raw_to_double (item->info.cp_double.bytes.raw, 0));
8443 out = r_base64_encode_dyn ((const char *) str, strlen (str));
8444 free (str);
8445 str = out;
8446 }
8447 } else if (strcmp (cp_name, "Integer") == 0) {
8448 str = calloc (34, 1);
8449 if (str) {
8450 snprintf (str, 34, "0x%08x", R_BIN_JAVA_UINT (item->info.cp_integer.bytes.raw, 0));
8451 out = r_base64_encode_dyn ((const char *) str, strlen (str));
8452 free (str);
8453 str = out;
8454 }
8455 } else if (strcmp (cp_name, "Float") == 0) {
8456 str = malloc (34);
8457 if (str) {
8458 snprintf (str, 34, "%f", R_BIN_JAVA_FLOAT (item->info.cp_float.bytes.raw, 0));
8459 out = r_base64_encode_dyn ((const char *) str, strlen (str));
8460 free (str);
8461 str = out;
8462 }
8463 } else if (!strcmp (cp_name, "NameAndType")) {
8464 name_str = r_bin_java_get_item_name_from_bin_cp_list (BIN_OBJ, item);
8465 if (!name_str) {
8466 name_str = empty;
8467 }
8468 desc_str = r_bin_java_get_item_desc_from_bin_cp_list (BIN_OBJ, item);
8469 if (!desc_str) {
8470 desc_str = empty;
8471 }
8472 memory_alloc = strlen (name_str) + strlen (desc_str) + 3;
8473 if (memory_alloc) {
8474 str = malloc (memory_alloc);
8475 if (str) {
8476 snprintf (str, memory_alloc, "%s %s", name_str, desc_str);
8477 out = r_base64_encode_dyn ((const char *) str, strlen (str));
8478 free (str);
8479 str = out;
8480 }
8481 }
8482 if (name_str != empty) {
8483 free (name_str);
8484 }
8485 if (desc_str != empty) {
8486 free (desc_str);
8487 }
8488 } else {
8489 str = r_base64_encode_dyn ((const char *) "(null)", 6);
8490 }
8491 return str;
8492 }
8493
r_bin_java_resolve_cp_idx_address(RBinJavaObj * BIN_OBJ,int idx)8494 R_API ut64 r_bin_java_resolve_cp_idx_address(RBinJavaObj *BIN_OBJ, int idx) {
8495 RBinJavaCPTypeObj *item = NULL;
8496 ut64 addr = -1;
8497 if (BIN_OBJ && BIN_OBJ->cp_count < 1) {
8498 return -1;
8499 }
8500 item = (RBinJavaCPTypeObj *) r_bin_java_get_item_from_bin_cp_list (BIN_OBJ, idx);
8501 if (item) {
8502 addr = item->file_offset + item->loadaddr;
8503 }
8504 return addr;
8505 }
8506
r_bin_java_resolve_cp_idx_to_string(RBinJavaObj * BIN_OBJ,int idx)8507 R_API char *r_bin_java_resolve_cp_idx_to_string(RBinJavaObj *BIN_OBJ, int idx) {
8508 RBinJavaCPTypeObj *item = NULL;
8509 char *value = NULL;
8510 if (BIN_OBJ && BIN_OBJ->cp_count < 1) {
8511 return NULL;
8512 }
8513 item = (RBinJavaCPTypeObj *) r_bin_java_get_item_from_bin_cp_list (BIN_OBJ, idx);
8514 if (item) {
8515 value = ((RBinJavaCPTypeMetas *)
8516 item->metas->type_info)->
8517 allocs->stringify_obj (item);
8518 }
8519 return value;
8520 }
8521
r_bin_java_resolve_cp_idx_print_summary(RBinJavaObj * BIN_OBJ,int idx)8522 R_API int r_bin_java_resolve_cp_idx_print_summary(RBinJavaObj *BIN_OBJ, int idx) {
8523 RBinJavaCPTypeObj *item = NULL;
8524 if (BIN_OBJ && BIN_OBJ->cp_count < 1) {
8525 return false;
8526 }
8527 item = (RBinJavaCPTypeObj *) r_bin_java_get_item_from_bin_cp_list (BIN_OBJ, idx);
8528 if (item) {
8529 ((RBinJavaCPTypeMetas *)
8530 item->metas->type_info)->
8531 allocs->print_summary (item);
8532 } else {
8533 eprintf ("Error: Invalid CP Object.\n");
8534 }
8535 return item ? true : false;
8536 }
8537
U(r_bin_java_resolve_to_const_value)8538 R_API ConstJavaValue *U(r_bin_java_resolve_to_const_value)(RBinJavaObj * BIN_OBJ, int idx) {
8539 // TODO XXX FIXME add a size parameter to the str when it is passed in
8540 RBinJavaCPTypeObj *item = NULL, *item2 = NULL;
8541 ConstJavaValue *result = R_NEW0 (ConstJavaValue);
8542 if (!result) {
8543 return NULL;
8544 }
8545 char *class_str = NULL,
8546 *name_str = NULL,
8547 *desc_str = NULL,
8548 *string_str = NULL,
8549 *empty = "",
8550 *cp_name = NULL;
8551 result->type = "unknown";
8552 if (BIN_OBJ && BIN_OBJ->cp_count < 1) {
8553 // r_bin_java_new_bin(BIN_OBJ);
8554 return result;
8555 }
8556 item = (RBinJavaCPTypeObj *) r_bin_java_get_item_from_bin_cp_list (BIN_OBJ, idx);
8557 if (!item) {
8558 return result;
8559 }
8560 cp_name = ((RBinJavaCPTypeMetas *) item->metas->type_info)->name;
8561 IFDBG eprintf("java_resolve Resolved: (%d) %s\n", idx, cp_name);
8562 if (strcmp (cp_name, "Class") == 0) {
8563 item2 = (RBinJavaCPTypeObj *) r_bin_java_get_item_from_bin_cp_list (BIN_OBJ, idx);
8564 // str = r_bin_java_get_name_from_bin_cp_list (BIN_OBJ, idx-1);
8565 class_str = r_bin_java_get_item_name_from_bin_cp_list (BIN_OBJ, item);
8566 if (!class_str) {
8567 class_str = empty;
8568 }
8569 name_str = r_bin_java_get_item_name_from_bin_cp_list (BIN_OBJ, item2);
8570 if (!name_str) {
8571 name_str = empty;
8572 }
8573 desc_str = r_bin_java_get_item_desc_from_bin_cp_list (BIN_OBJ, item2);
8574 if (!desc_str) {
8575 desc_str = empty;
8576 }
8577 result->value._ref = R_NEW0 (_JavaRef);
8578 result->type = "ref";
8579 result->value._ref->class_name = strdup (class_str);
8580 result->value._ref->name = strdup (name_str);
8581 result->value._ref->desc = strdup (desc_str);
8582 if (class_str != empty) {
8583 free (class_str);
8584 }
8585 if (name_str != empty) {
8586 free (name_str);
8587 }
8588 if (desc_str != empty) {
8589 free (desc_str);
8590 }
8591 } else if (strcmp (cp_name, "MethodRef") == 0 ||
8592 strcmp (cp_name, "FieldRef") == 0 ||
8593 strcmp (cp_name, "InterfaceMethodRef") == 0) {
8594 /*
8595 * The MethodRef, FieldRef, and InterfaceMethodRef structures
8596 */
8597 class_str = r_bin_java_get_name_from_bin_cp_list (BIN_OBJ, item->info.cp_method.class_idx);
8598 if (!class_str) {
8599 class_str = empty;
8600 }
8601 name_str = r_bin_java_get_item_name_from_bin_cp_list (BIN_OBJ, item);
8602 if (!name_str) {
8603 name_str = empty;
8604 }
8605 desc_str = r_bin_java_get_item_desc_from_bin_cp_list (BIN_OBJ, item);
8606 if (!desc_str) {
8607 desc_str = empty;
8608 }
8609 result->value._ref = R_NEW0 (_JavaRef);
8610 result->type = "ref";
8611 result->value._ref->class_name = strdup (class_str);
8612 result->value._ref->name = strdup (name_str);
8613 result->value._ref->desc = strdup (desc_str);
8614 if (class_str != empty) {
8615 free (class_str);
8616 }
8617 if (name_str != empty) {
8618 free (name_str);
8619 }
8620 if (desc_str != empty) {
8621 free (desc_str);
8622 }
8623 } else if (strcmp (cp_name, "String") == 0) {
8624 ut32 length = r_bin_java_get_utf8_len_from_bin_cp_list (BIN_OBJ, item->info.cp_string.string_idx);
8625 string_str = r_bin_java_get_utf8_from_bin_cp_list (BIN_OBJ, item->info.cp_string.string_idx);
8626 IFDBG eprintf("java_resolve String got: (%d) %s\n", item->info.cp_string.string_idx, string_str);
8627 if (!string_str) {
8628 string_str = empty;
8629 length = strlen (empty);
8630 }
8631 result->type = "str";
8632 result->value._str = R_NEW0 (struct java_const_value_str_t);
8633 result->value._str->len = length;
8634 if (length > 0) {
8635 result->value._str->str = r_str_ndup (string_str, length);
8636 } else {
8637 result->value._str->str = strdup ("");
8638 }
8639 if (string_str != empty) {
8640 free (string_str);
8641 }
8642 } else if (strcmp (cp_name, "Utf8") == 0) {
8643 result->type = "str";
8644 result->value._str = R_NEW0 (struct java_const_value_str_t);
8645 result->value._str->str = malloc (item->info.cp_utf8.length);
8646 result->value._str->len = item->info.cp_utf8.length;
8647 memcpy (result->value._str->str, item->info.cp_utf8.bytes, item->info.cp_utf8.length);
8648 } else if (strcmp (cp_name, "Long") == 0) {
8649 result->type = "long";
8650 result->value._long = r_bin_java_raw_to_long (item->info.cp_long.bytes.raw, 0);
8651 } else if (strcmp (cp_name, "Double") == 0) {
8652 result->type = "double";
8653 result->value._double = r_bin_java_raw_to_double (item->info.cp_double.bytes.raw, 0);
8654 } else if (strcmp (cp_name, "Integer") == 0) {
8655 result->type = "int";
8656 result->value._int = R_BIN_JAVA_UINT (item->info.cp_integer.bytes.raw, 0);
8657 } else if (strcmp (cp_name, "Float") == 0) {
8658 result->type = "float";
8659 result->value._float = R_BIN_JAVA_FLOAT (item->info.cp_float.bytes.raw, 0);
8660 } else if (strcmp (cp_name, "NameAndType") == 0) {
8661 result->value._ref = R_NEW0 (struct java_const_value_ref_t);
8662 result->type = "ref";
8663 name_str = r_bin_java_get_item_name_from_bin_cp_list (BIN_OBJ, item);
8664 if (!name_str) {
8665 name_str = empty;
8666 }
8667 desc_str = r_bin_java_get_item_desc_from_bin_cp_list (BIN_OBJ, item);
8668 if (!desc_str) {
8669 desc_str = empty;
8670 }
8671 result->value._ref->class_name = strdup (empty);
8672 result->value._ref->name = strdup (name_str);
8673 result->value._ref->desc = strdup (desc_str);
8674 if (name_str != empty) {
8675 free (name_str);
8676 }
8677 if (desc_str != empty) {
8678 free (desc_str);
8679 }
8680 result->value._ref->is_method = r_bin_java_does_cp_idx_ref_method (BIN_OBJ, idx);
8681 result->value._ref->is_field = r_bin_java_does_cp_idx_ref_field (BIN_OBJ, idx);
8682 }
8683 return result;
8684 }
8685
U(r_bin_java_free_const_value)8686 R_API void U(r_bin_java_free_const_value)(ConstJavaValue * cp_value) {
8687 char first_char = cp_value && cp_value->type ? *cp_value->type : 0,
8688 second_char = cp_value && cp_value->type ? *(cp_value->type + 1) : 0;
8689 switch (first_char) {
8690 case 'r':
8691 if (cp_value && cp_value->value._ref) {
8692 free (cp_value->value._ref->class_name);
8693 free (cp_value->value._ref->name);
8694 free (cp_value->value._ref->desc);
8695 }
8696 break;
8697 case 's':
8698 if (second_char == 't' && cp_value->value._str) {
8699 free (cp_value->value._str->str);
8700 }
8701 break;
8702 }
8703 free (cp_value);
8704 }
8705
r_bin_java_get_field_name(RBinJavaObj * bin_obj,ut32 idx)8706 R_API char *r_bin_java_get_field_name(RBinJavaObj *bin_obj, ut32 idx) {
8707 char *name = NULL;
8708 if (idx < r_list_length (bin_obj->fields_list)) {
8709 RBinJavaField *fm_type = r_list_get_n (bin_obj->fields_list, idx);
8710 name = strdup (fm_type->name);
8711 }
8712 return name;
8713 }
8714
r_bin_java_print_field_idx_summary(RBinJavaObj * bin_obj,ut32 idx)8715 R_API int r_bin_java_print_field_idx_summary(RBinJavaObj *bin_obj, ut32 idx) {
8716 int res = false;
8717 if (idx < r_list_length (bin_obj->fields_list)) {
8718 RBinJavaField *fm_type = r_list_get_n (bin_obj->fields_list, idx);
8719 r_bin_java_print_field_summary (fm_type);
8720 res = true;
8721 }
8722 return res;
8723 }
8724
r_bin_java_get_field_count(RBinJavaObj * bin_obj)8725 R_API ut32 r_bin_java_get_field_count(RBinJavaObj *bin_obj) {
8726 return r_list_length (bin_obj->fields_list);
8727 }
8728
r_bin_java_get_field_num_name(RBinJavaObj * bin_obj)8729 R_API RList *r_bin_java_get_field_num_name(RBinJavaObj *bin_obj) {
8730 ut32 i = 0;
8731 RBinJavaField *fm_type;
8732 RListIter *iter = NULL;
8733 RList *res = r_list_newf (free);
8734 r_list_foreach (bin_obj->fields_list, iter, fm_type) {
8735 ut32 len = strlen (fm_type->name) + 30;
8736 char *str = malloc (len);
8737 if (!str) {
8738 r_list_free (res);
8739 return NULL;
8740 }
8741 snprintf (str, len, "%d %s", i, fm_type->name);
8742 ++i;
8743 r_list_append (res, str);
8744 }
8745 return res;
8746 }
r_bin_java_find_cp_const_by_val_utf8(RBinJavaObj * bin_obj,const ut8 * bytes,ut32 len)8747 R_API RList *r_bin_java_find_cp_const_by_val_utf8(RBinJavaObj *bin_obj, const ut8 *bytes, ut32 len) {
8748 RList *res = r_list_newf (free);
8749 ut32 *v = NULL;
8750 RListIter *iter;
8751 RBinJavaCPTypeObj *cp_obj;
8752 IFDBG eprintf("In UTF-8 Looking for %s\n", bytes);
8753 r_list_foreach (bin_obj->cp_list, iter, cp_obj) {
8754 if (cp_obj->tag == R_BIN_JAVA_CP_UTF8) {
8755 IFDBG eprintf("In UTF-8 Looking @ %s\n", cp_obj->info.cp_utf8.bytes);
8756 IFDBG eprintf("UTF-8 len = %d and memcmp = %d\n", cp_obj->info.cp_utf8.length, memcmp (bytes, cp_obj->info.cp_utf8.bytes, len));
8757 if (len == cp_obj->info.cp_utf8.length && !memcmp (bytes, cp_obj->info.cp_utf8.bytes, len)) {
8758 v = malloc (sizeof (ut32));
8759 if (!v) {
8760 r_list_free (res);
8761 return NULL;
8762 }
8763 *v = cp_obj->metas->ord;
8764 IFDBG eprintf("Found a match adding idx: %d\n", *v);
8765 r_list_append (res, v);
8766 }
8767 }
8768 }
8769 return res;
8770 }
r_bin_java_find_cp_const_by_val_int(RBinJavaObj * bin_obj,const ut8 * bytes,ut32 len)8771 R_API RList *r_bin_java_find_cp_const_by_val_int(RBinJavaObj *bin_obj, const ut8 *bytes, ut32 len) {
8772 RList *res = r_list_newf (free);
8773 ut32 *v = NULL;
8774 RListIter *iter;
8775 RBinJavaCPTypeObj *cp_obj;
8776 eprintf ("Looking for 0x%08x\n", (ut32) R_BIN_JAVA_UINT (bytes, 0));
8777 r_list_foreach (bin_obj->cp_list, iter, cp_obj) {
8778 if (cp_obj->tag == R_BIN_JAVA_CP_INTEGER) {
8779 if (len == 4 && R_BIN_JAVA_UINT (bytes, 0) == R_BIN_JAVA_UINT (cp_obj->info.cp_integer.bytes.raw, 0)) {
8780 v = malloc (sizeof (ut32));
8781 if (!v) {
8782 r_list_free (res);
8783 return NULL;
8784 }
8785 *v = cp_obj->idx;
8786 r_list_append (res, v);
8787 }
8788 }
8789 }
8790 return res;
8791 }
8792
r_bin_java_resolve_cp_idx_tag(RBinJavaObj * BIN_OBJ,int idx)8793 R_API char r_bin_java_resolve_cp_idx_tag(RBinJavaObj *BIN_OBJ, int idx) {
8794 RBinJavaCPTypeObj *item = NULL;
8795 if (BIN_OBJ && BIN_OBJ->cp_count < 1) {
8796 // r_bin_java_new_bin(BIN_OBJ);
8797 return R_BIN_JAVA_CP_UNKNOWN;
8798 }
8799 item = (RBinJavaCPTypeObj *) r_bin_java_get_item_from_bin_cp_list (BIN_OBJ, idx);
8800 if (item) {
8801 return item->tag;
8802 }
8803 return R_BIN_JAVA_CP_UNKNOWN;
8804 }
8805
U(r_bin_java_integer_cp_set)8806 R_API int U(r_bin_java_integer_cp_set)(RBinJavaObj * bin, ut16 idx, ut32 val) {
8807 RBinJavaCPTypeObj *cp_obj = r_bin_java_get_item_from_bin_cp_list (bin, idx);
8808 if (!cp_obj) {
8809 return false;
8810 }
8811 ut8 bytes[4] = {
8812 0
8813 };
8814 if (cp_obj->tag != R_BIN_JAVA_CP_INTEGER && cp_obj->tag != R_BIN_JAVA_CP_FLOAT) {
8815 eprintf ("Not supporting the overwrite of CP Objects with one of a different size.\n");
8816 return false;
8817 }
8818 r_bin_java_check_reset_cp_obj (cp_obj, R_BIN_JAVA_CP_INTEGER);
8819 cp_obj->tag = R_BIN_JAVA_CP_INTEGER;
8820 memcpy (bytes, (const char *) &val, 4);
8821 val = R_BIN_JAVA_UINT (bytes, 0);
8822 memcpy (&cp_obj->info.cp_integer.bytes.raw, (const char *) &val, 4);
8823 return true;
8824 }
8825
U(r_bin_java_float_cp_set)8826 R_API int U(r_bin_java_float_cp_set)(RBinJavaObj * bin, ut16 idx, float val) {
8827 RBinJavaCPTypeObj *cp_obj = r_bin_java_get_item_from_bin_cp_list (bin, idx);
8828 if (!cp_obj) {
8829 return false;
8830 }
8831 ut8 bytes[4] = {
8832 0
8833 };
8834 if (cp_obj->tag != R_BIN_JAVA_CP_INTEGER && cp_obj->tag != R_BIN_JAVA_CP_FLOAT) {
8835 eprintf ("Not supporting the overwrite of CP Objects with one of a different size.\n");
8836 return false;
8837 }
8838 r_bin_java_check_reset_cp_obj (cp_obj, R_BIN_JAVA_CP_FLOAT);
8839 cp_obj->tag = R_BIN_JAVA_CP_FLOAT;
8840 memcpy (bytes, (const char *) &val, 4);
8841 float *foo = (float*) bytes;
8842 val = *foo; //(float)R_BIN_JAVA_UINT (bytes, 0);
8843 memcpy (&cp_obj->info.cp_float.bytes.raw, (const char *) &val, 4);
8844 return true;
8845 }
8846
U(r_bin_java_long_cp_set)8847 R_API int U(r_bin_java_long_cp_set)(RBinJavaObj * bin, ut16 idx, ut64 val) {
8848 RBinJavaCPTypeObj *cp_obj = r_bin_java_get_item_from_bin_cp_list (bin, idx);
8849 if (!cp_obj) {
8850 return false;
8851 }
8852 ut8 bytes[8] = {
8853 0
8854 };
8855 if (cp_obj->tag != R_BIN_JAVA_CP_LONG && cp_obj->tag != R_BIN_JAVA_CP_DOUBLE) {
8856 eprintf ("Not supporting the overwrite of CP Objects with one of a different size.\n");
8857 return false;
8858 }
8859 r_bin_java_check_reset_cp_obj (cp_obj, R_BIN_JAVA_CP_LONG);
8860 cp_obj->tag = R_BIN_JAVA_CP_LONG;
8861 memcpy (bytes, (const char *) &val, 8);
8862 val = r_bin_java_raw_to_long (bytes, 0);
8863 memcpy (&cp_obj->info.cp_long.bytes.raw, (const char *) &val, 8);
8864 return true;
8865 }
8866
U(r_bin_java_double_cp_set)8867 R_API int U(r_bin_java_double_cp_set)(RBinJavaObj * bin, ut16 idx, ut32 val) {
8868 RBinJavaCPTypeObj *cp_obj = r_bin_java_get_item_from_bin_cp_list (bin, idx);
8869 if (!cp_obj) {
8870 return false;
8871 }
8872 ut8 bytes[8] = {
8873 0
8874 };
8875 if (cp_obj->tag != R_BIN_JAVA_CP_LONG && cp_obj->tag != R_BIN_JAVA_CP_DOUBLE) {
8876 eprintf ("Not supporting the overwrite of CP Objects with one of a different size.\n");
8877 return false;
8878 }
8879 r_bin_java_check_reset_cp_obj (cp_obj, R_BIN_JAVA_CP_DOUBLE);
8880 cp_obj->tag = R_BIN_JAVA_CP_DOUBLE;
8881 ut64 val64 = val;
8882 memcpy (bytes, (const char *) &val64, 8);
8883 val64 = r_bin_java_raw_to_long (bytes, 0);
8884 memcpy (&cp_obj->info.cp_double.bytes.raw, (const char *) &val64, 8);
8885 return true;
8886 }
8887
U(r_bin_java_utf8_cp_set)8888 R_API int U(r_bin_java_utf8_cp_set)(RBinJavaObj * bin, ut16 idx, const ut8 * buffer, ut32 len) {
8889 RBinJavaCPTypeObj *cp_obj = r_bin_java_get_item_from_bin_cp_list (bin, idx);
8890 if (!cp_obj) {
8891 return false;
8892 }
8893 eprintf ("Writing %d byte(s) (%s)\n", len, buffer);
8894 // r_bin_java_check_reset_cp_obj(cp_obj, R_BIN_JAVA_CP_INTEGER);
8895 if (cp_obj->tag != R_BIN_JAVA_CP_UTF8) {
8896 eprintf ("Not supporting the overwrite of CP Objects with one of a different size.\n");
8897 return false;
8898 }
8899 if (cp_obj->info.cp_utf8.length != len) {
8900 eprintf ("Not supporting the resize, rewriting utf8 string up to %d byte(s).\n", cp_obj->info.cp_utf8.length);
8901 if (cp_obj->info.cp_utf8.length > len) {
8902 eprintf ("Remaining %d byte(s) will be filled with \\x00.\n", cp_obj->info.cp_utf8.length - len);
8903 }
8904 }
8905 memcpy (cp_obj->info.cp_utf8.bytes, buffer, cp_obj->info.cp_utf8.length);
8906 if (cp_obj->info.cp_utf8.length > len) {
8907 memset (cp_obj->info.cp_utf8.bytes + len, 0, cp_obj->info.cp_utf8.length - len);
8908 }
8909 return true;
8910 }
8911
r_bin_java_cp_get_bytes(ut8 tag,ut32 * out_sz,const ut8 * buf,const ut64 len)8912 R_API ut8 *r_bin_java_cp_get_bytes(ut8 tag, ut32 *out_sz, const ut8 *buf, const ut64 len) {
8913 if (!out_sz) {
8914 return NULL;
8915 }
8916 if (out_sz) {
8917 *out_sz = 0;
8918 }
8919 switch (tag) {
8920 case R_BIN_JAVA_CP_INTEGER:
8921 case R_BIN_JAVA_CP_FLOAT:
8922 return r_bin_java_cp_get_4bytes (tag, out_sz, buf, len);
8923 case R_BIN_JAVA_CP_LONG:
8924 case R_BIN_JAVA_CP_DOUBLE:
8925 return r_bin_java_cp_get_8bytes (tag, out_sz, buf, len);
8926 case R_BIN_JAVA_CP_UTF8:
8927 return r_bin_java_cp_get_utf8 (tag, out_sz, buf, len);
8928 }
8929 return NULL;
8930 }
8931
r_bin_java_cp_get_size(RBinJavaObj * bin,ut16 idx)8932 R_API ut32 r_bin_java_cp_get_size(RBinJavaObj *bin, ut16 idx) {
8933 RBinJavaCPTypeObj *cp_obj = r_bin_java_get_item_from_bin_cp_list (bin, idx);
8934 switch (cp_obj->tag) {
8935 case R_BIN_JAVA_CP_INTEGER:
8936 case R_BIN_JAVA_CP_FLOAT:
8937 return 1 + 4;
8938 case R_BIN_JAVA_CP_LONG:
8939 case R_BIN_JAVA_CP_DOUBLE:
8940 return 1 + 8;
8941 case R_BIN_JAVA_CP_UTF8:
8942 return 1 + 2 + cp_obj->info.cp_utf8.length;
8943 }
8944 return 0;
8945 }
8946
r_bin_java_get_method_start(RBinJavaObj * bin,RBinJavaField * fm_type)8947 R_API ut64 r_bin_java_get_method_start(RBinJavaObj *bin, RBinJavaField *fm_type) {
8948 return r_bin_java_get_method_code_offset (fm_type) + bin->loadaddr;
8949 }
8950
r_bin_java_get_method_end(RBinJavaObj * bin,RBinJavaField * fm_type)8951 R_API ut64 r_bin_java_get_method_end(RBinJavaObj *bin, RBinJavaField *fm_type) {
8952 return r_bin_java_get_method_code_offset (fm_type) + bin->loadaddr +
8953 +r_bin_java_get_method_code_size (fm_type);
8954 }
8955
U(r_bin_java_cp_append_method_ref)8956 R_API ut8 *U(r_bin_java_cp_append_method_ref)(RBinJavaObj * bin, ut32 * out_sz, ut16 cn_idx, ut16 fn_idx, ut16 ft_idx) {
8957 return r_bin_java_cp_get_fref_bytes (bin, out_sz, R_BIN_JAVA_CP_METHODREF, cn_idx, fn_idx, ft_idx);
8958 }
8959
U(r_bin_java_cp_append_field_ref)8960 R_API ut8 *U(r_bin_java_cp_append_field_ref)(RBinJavaObj * bin, ut32 * out_sz, ut16 cn_idx, ut16 fn_idx, ut16 ft_idx) {
8961 return r_bin_java_cp_get_fref_bytes (bin, out_sz, R_BIN_JAVA_CP_FIELDREF, cn_idx, fn_idx, ft_idx);
8962 }
8963
r_bin_java_unmangle_without_flags(const char * name,const char * descriptor)8964 R_API char *r_bin_java_unmangle_without_flags(const char *name, const char *descriptor) {
8965 return r_bin_java_unmangle (NULL, name, descriptor);
8966 }
8967
U(r_bin_java_print_stack_map_append_frame_summary)8968 R_API void U(r_bin_java_print_stack_map_append_frame_summary)(RBinJavaStackMapFrame * obj) {
8969 RListIter *iter, *iter_tmp;
8970 RList *ptrList;
8971 RBinJavaVerificationObj *ver_obj;
8972 Eprintf ("Stack Map Frame Information\n");
8973 Eprintf (" Tag Value = 0x%02x Name: %s\n", obj->tag, ((RBinJavaStackMapFrameMetas *) obj->metas->type_info)->name);
8974 Eprintf (" Offset: 0x%08"PFMT64x "\n", obj->file_offset);
8975 Eprintf (" Local Variable Count = 0x%04x\n", obj->number_of_locals);
8976 Eprintf (" Local Variables:\n");
8977 ptrList = obj->local_items;
8978 r_list_foreach_safe (ptrList, iter, iter_tmp, ver_obj) {
8979 r_bin_java_print_verification_info_summary (ver_obj);
8980 }
8981 Eprintf (" Stack Items Count = 0x%04x\n", obj->number_of_stack_items);
8982 Eprintf (" Stack Items:\n");
8983 ptrList = obj->stack_items;
8984 r_list_foreach_safe (ptrList, iter, iter_tmp, ver_obj) {
8985 r_bin_java_print_verification_info_summary (ver_obj);
8986 }
8987 }
8988
U(r_bin_java_stack_frame_default_free)8989 R_API void U(r_bin_java_stack_frame_default_free)(void *s) {
8990 RBinJavaStackMapFrame *stack_frame = s;
8991 if (stack_frame) {
8992 free (stack_frame->metas);
8993 free (stack_frame);
8994 }
8995 }
U(r_bin_java_stack_frame_do_nothing_free)8996 R_API void U(r_bin_java_stack_frame_do_nothing_free)(void /*RBinJavaStackMapFrame*/ *stack_frame) {}
U(r_bin_java_stack_frame_do_nothing_new)8997 R_API void U(r_bin_java_stack_frame_do_nothing_new)(RBinJavaObj * bin, RBinJavaStackMapFrame * stack_frame, ut64 offset) {}
U(r_bin_java_get_cp_meta_from_tag)8998 R_API RBinJavaCPTypeMetas *U(r_bin_java_get_cp_meta_from_tag)(ut8 tag) {
8999 ut16 i = 0;
9000 // set default to unknown.
9001 RBinJavaCPTypeMetas *res = &R_BIN_JAVA_CP_METAS[2];
9002 for (i = 0; i < R_BIN_JAVA_CP_METAS_SZ; i++) {
9003 if (tag == R_BIN_JAVA_CP_METAS[i].tag) {
9004 res = &R_BIN_JAVA_CP_METAS[i];
9005 break;
9006 }
9007 }
9008 return res;
9009 }
9010
U(r_bin_java_cp_append_ref_cname_fname_ftype)9011 R_API ut8 *U(r_bin_java_cp_append_ref_cname_fname_ftype)(RBinJavaObj * bin, ut32 * out_sz, ut8 tag, const char *cname, const ut32 c_len, const char *fname, const ut32 f_len, const char *tname, const ut32 t_len) {
9012 ut32 cn_len = 0, fn_len = 0, ft_len = 0, total_len;
9013 ut16 cn_idx = 0, fn_idx = 0, ft_idx = 0;
9014 ut8 *bytes = NULL, *cn_bytes = NULL, *fn_bytes = NULL, *ft_bytes = NULL, *cref_bytes = NULL, *fref_bytes = NULL, *fnt_bytes = NULL;
9015 *out_sz = 0;
9016 cn_bytes = r_bin_java_cp_get_utf8 (R_BIN_JAVA_CP_UTF8, &cn_len, (const ut8 *) cname, c_len);
9017 cn_idx = bin->cp_idx + 1;
9018 if (cn_bytes) {
9019 fn_bytes = r_bin_java_cp_get_utf8 (R_BIN_JAVA_CP_UTF8, &fn_len, (const ut8 *) fname, f_len);
9020 fn_idx = bin->cp_idx + 2;
9021 }
9022 if (fn_bytes) {
9023 ft_bytes = r_bin_java_cp_get_utf8 (R_BIN_JAVA_CP_UTF8, &ft_len, (const ut8 *) tname, t_len);
9024 ft_idx = bin->cp_idx + 3;
9025 }
9026 if (cn_bytes && fn_bytes && ft_bytes) {
9027 ut32 cref_len = 0, fnt_len = 0, fref_len = 0;
9028 ut32 cref_idx = 0, fnt_idx = 0;
9029 cref_bytes = r_bin_java_cp_get_classref (bin, &cref_len, NULL, 0, cn_idx);
9030 cref_idx = bin->cp_idx + 3;
9031 fnt_bytes = r_bin_java_cp_get_name_type (bin, &fnt_len, fn_idx, ft_idx);
9032 fnt_idx = bin->cp_idx + 4;
9033 fref_bytes = r_bin_java_cp_get_2_ut16 (bin, &fref_len, tag, cref_idx, fnt_idx);
9034 if (cref_bytes && fref_bytes && fnt_bytes) {
9035 total_len = cn_len + fn_len + ft_len + cref_len + fnt_len + fref_len + 2;
9036 if (total_len < cn_len) {
9037 goto beach;
9038 }
9039 bytes = calloc (1, total_len);
9040 // class name bytes
9041 if (*out_sz + cn_len >= total_len) {
9042 goto beach;
9043 }
9044 memcpy (bytes, cn_bytes + *out_sz, cn_len);
9045 *out_sz += cn_len;
9046 // field name bytes
9047 if (*out_sz + fn_len >= total_len) {
9048 goto beach;
9049 }
9050 memcpy (bytes, fn_bytes + *out_sz, fn_len);
9051 *out_sz += fn_len;
9052 // field type bytes
9053 if (*out_sz + ft_len >= total_len) {
9054 goto beach;
9055 }
9056 memcpy (bytes, ft_bytes + *out_sz, ft_len);
9057 *out_sz += ft_len;
9058 // class ref bytes
9059 if (*out_sz + cref_len >= total_len) {
9060 goto beach;
9061 }
9062 memcpy (bytes, cref_bytes + *out_sz, cref_len);
9063 *out_sz += fn_len;
9064 // field name and type bytes
9065 if (*out_sz + fnt_len >= total_len) {
9066 goto beach;
9067 }
9068 memcpy (bytes, fnt_bytes + *out_sz, fnt_len);
9069 *out_sz += fnt_len;
9070 // field ref bytes
9071 if (*out_sz + fref_len >= total_len) {
9072 goto beach;
9073 }
9074 memcpy (bytes, fref_bytes + *out_sz, fref_len);
9075 *out_sz += fref_len;
9076 }
9077 }
9078 beach:
9079 free (cn_bytes);
9080 free (ft_bytes);
9081 free (fn_bytes);
9082 free (fnt_bytes);
9083 free (fref_bytes);
9084 free (cref_bytes);
9085 return bytes;
9086 }
U(r_bin_java_cp_get_method_ref)9087 R_API ut8 *U(r_bin_java_cp_get_method_ref)(RBinJavaObj * bin, ut32 * out_sz, ut16 class_idx, ut16 name_and_type_idx) {
9088 return r_bin_java_cp_get_fm_ref (bin, out_sz, R_BIN_JAVA_CP_METHODREF, class_idx, name_and_type_idx);
9089 }
U(r_bin_java_cp_get_field_ref)9090 R_API ut8 *U(r_bin_java_cp_get_field_ref)(RBinJavaObj * bin, ut32 * out_sz, ut16 class_idx, ut16 name_and_type_idx) {
9091 return r_bin_java_cp_get_fm_ref (bin, out_sz, R_BIN_JAVA_CP_FIELDREF, class_idx, name_and_type_idx);
9092 }
9093
U(deinit_java_type_null)9094 R_API void U(deinit_java_type_null)(void) {
9095 free (R_BIN_JAVA_NULL_TYPE.metas);
9096 }
9097
r_bin_java_get_item_from_cp(RBinJavaObj * bin,int i)9098 R_API RBinJavaCPTypeObj *r_bin_java_get_item_from_cp(RBinJavaObj *bin, int i) {
9099 if (i < 1 || i > bin->cf.cp_count) {
9100 return &R_BIN_JAVA_NULL_TYPE;
9101 }
9102 RBinJavaCPTypeObj *obj = (RBinJavaCPTypeObj *) r_list_get_n (bin->cp_list, i);
9103 return obj ? obj : &R_BIN_JAVA_NULL_TYPE;
9104 }
9105
U(copy_type_info_to_stack_frame_list)9106 R_API void U(copy_type_info_to_stack_frame_list)(RList * type_list, RList * sf_list) {
9107 RListIter *iter, *iter_tmp;
9108 RBinJavaVerificationObj *ver_obj, *new_ver_obj;
9109 if (!type_list || !sf_list) {
9110 return;
9111 }
9112 r_list_foreach_safe (type_list, iter, iter_tmp, ver_obj) {
9113 new_ver_obj = (RBinJavaVerificationObj *) malloc (sizeof (RBinJavaVerificationObj));
9114 // FIXME: how to handle failed memory allocation?
9115 if (new_ver_obj && ver_obj) {
9116 memcpy (new_ver_obj, ver_obj, sizeof (RBinJavaVerificationObj));
9117 if (!r_list_append (sf_list, (void *) new_ver_obj)) {
9118 R_FREE (new_ver_obj);
9119 }
9120 } else {
9121 R_FREE (new_ver_obj);
9122 }
9123 }
9124 }
9125
U(copy_type_info_to_stack_frame_list_up_to_idx)9126 R_API void U(copy_type_info_to_stack_frame_list_up_to_idx)(RList * type_list, RList * sf_list, ut64 idx) {
9127 RListIter *iter, *iter_tmp;
9128 RBinJavaVerificationObj *ver_obj, *new_ver_obj;
9129 ut32 pos = 0;
9130 if (!type_list || !sf_list) {
9131 return;
9132 }
9133 r_list_foreach_safe (type_list, iter, iter_tmp, ver_obj) {
9134 new_ver_obj = (RBinJavaVerificationObj *) malloc (sizeof (RBinJavaVerificationObj));
9135 // FIXME: how to handle failed memory allocation?
9136 if (new_ver_obj && ver_obj) {
9137 memcpy (new_ver_obj, ver_obj, sizeof (RBinJavaVerificationObj));
9138 if (!r_list_append (sf_list, (void *) new_ver_obj)) {
9139 R_FREE (new_ver_obj);
9140 }
9141 } else {
9142 R_FREE (new_ver_obj);
9143 }
9144 pos++;
9145 if (pos == idx) {
9146 break;
9147 }
9148 }
9149 }
9150
r_bin_java_cp_get_idx_bytes(RBinJavaObj * bin,ut16 idx,ut32 * out_sz)9151 R_API ut8 *r_bin_java_cp_get_idx_bytes(RBinJavaObj *bin, ut16 idx, ut32 *out_sz) {
9152 RBinJavaCPTypeObj *cp_obj = r_bin_java_get_item_from_bin_cp_list (bin, idx);
9153 if (!cp_obj || !out_sz) {
9154 return NULL;
9155 }
9156 if (out_sz) {
9157 *out_sz = 0;
9158 }
9159 switch (cp_obj->tag) {
9160 case R_BIN_JAVA_CP_INTEGER:
9161 case R_BIN_JAVA_CP_FLOAT:
9162 return r_bin_java_cp_get_4bytes (cp_obj->tag, out_sz, cp_obj->info.cp_integer.bytes.raw, 5);
9163 case R_BIN_JAVA_CP_LONG:
9164 case R_BIN_JAVA_CP_DOUBLE:
9165 return r_bin_java_cp_get_4bytes (cp_obj->tag, out_sz, cp_obj->info.cp_long.bytes.raw, 9);
9166 case R_BIN_JAVA_CP_UTF8:
9167 // eprintf ("Getting idx: %d = %p (3+0x%"PFMT64x")\n", idx, cp_obj, cp_obj->info.cp_utf8.length);
9168 if (cp_obj->info.cp_utf8.length > 0) {
9169 return r_bin_java_cp_get_utf8 (cp_obj->tag, out_sz,
9170 cp_obj->info.cp_utf8.bytes, cp_obj->info.cp_utf8.length);
9171 }
9172 }
9173 return NULL;
9174 }
9175
r_bin_java_valid_class(const ut8 * buf,ut64 buf_sz)9176 R_API int r_bin_java_valid_class(const ut8 *buf, ut64 buf_sz) {
9177 RBinJavaObj *bin = R_NEW0 (RBinJavaObj), *cur_bin = R_BIN_JAVA_GLOBAL_BIN;
9178 if (!bin) {
9179 return false;
9180 }
9181 int res = r_bin_java_load_bin (bin, buf, buf_sz);
9182 if (bin->calc_size == buf_sz) {
9183 res = true;
9184 }
9185 r_bin_java_free (bin);
9186 R_BIN_JAVA_GLOBAL_BIN = cur_bin;
9187 return res;
9188 }
9189
r_bin_java_calc_class_size(ut8 * bytes,ut64 size)9190 R_API ut64 r_bin_java_calc_class_size(ut8 *bytes, ut64 size) {
9191 RBinJavaObj *bin = R_NEW0 (RBinJavaObj);
9192 if (!bin) {
9193 return false;
9194 }
9195 RBinJavaObj *cur_bin = R_BIN_JAVA_GLOBAL_BIN;
9196 ut64 bin_size = UT64_MAX;
9197 if (bin) {
9198 if (r_bin_java_load_bin (bin, bytes, size)) {
9199 bin_size = bin->calc_size;
9200 }
9201 r_bin_java_free (bin);
9202 R_BIN_JAVA_GLOBAL_BIN = cur_bin;
9203 }
9204 return bin_size;
9205 }
9206
U(r_bin_java_get_cp_idx_with_name)9207 R_API int U(r_bin_java_get_cp_idx_with_name)(RBinJavaObj * bin_obj, const char *name, ut32 len) {
9208 RListIter *iter;
9209 RBinJavaCPTypeObj *obj;
9210 r_list_foreach (bin_obj->cp_list, iter, obj) {
9211 if (obj->tag == R_BIN_JAVA_CP_UTF8) {
9212 if (!strncmp (name, (const char *) obj->info.cp_utf8.bytes, len)) {
9213 return obj->metas->ord;
9214 }
9215 }
9216 }
9217 return 0;
9218 }
9219
r_bin_java_external_printf(PrintfCallback cb)9220 R_API void r_bin_java_external_printf(PrintfCallback cb) {
9221 Eprintf = cb ? cb : (PrintfCallback) printf;
9222 }
9223