Rizin
unix-like reverse engineering framework and cli tools
java.c
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2021 deroad <wargio@libero.it>
2 // SPDX-License-Identifier: LGPL-3.0-only
3 #include "demangler_util.h"
4 #include <rz_libdemangle.h>
5 
6 #define is_native_type(x) ((x) && !IS_UPPER(x))
7 #define is_varargs(x) ((x)[0] == '.' && (x)[1] == '.' && (x)[2] == '.')
8 
9 static inline bool demangle_type(char *type, DemString *sb, size_t *used) {
10  bool array = false, varargs = false;
11  char *end = NULL;
12  size_t type_len = 1;
13  if (is_varargs(type)) {
14  varargs = true;
15  type += 3;
16  }
17  if (type[0] == '[') {
18  array = true;
19  type++;
20  }
21 
22  switch (type[0]) {
23  case 'L':
24  if (!(end = strchr(type, ';'))) {
25  return false;
26  }
27  end[0] = 0;
28  type_len = strlen(type);
29  dem_string_append_n(sb, type + 1, type_len - 1);
30  type_len++;
31  break;
32  case 'B':
33  if (is_native_type(type[1])) {
34  return false;
35  }
36  dem_string_append(sb, "byte");
37  break;
38  case 'C':
39  if (is_native_type(type[1])) {
40  return false;
41  }
42  dem_string_append(sb, "char");
43  break;
44  case 'D':
45  if (is_native_type(type[1])) {
46  return false;
47  }
48  dem_string_append(sb, "double");
49  break;
50  case 'F':
51  if (is_native_type(type[1])) {
52  return false;
53  }
54  dem_string_append(sb, "float");
55  break;
56  case 'I':
57  if (is_native_type(type[1])) {
58  return false;
59  }
60  dem_string_append(sb, "int");
61  break;
62  case 'J':
63  if (is_native_type(type[1])) {
64  return false;
65  }
66  dem_string_append(sb, "long");
67  break;
68  case 'S':
69  if (is_native_type(type[1])) {
70  return false;
71  }
72  dem_string_append(sb, "short");
73  break;
74  case 'V':
75  if (is_native_type(type[1])) {
76  return false;
77  }
78  dem_string_append(sb, "void");
79  break;
80  case 'Z':
81  if (is_native_type(type[1])) {
82  return false;
83  }
84  dem_string_append(sb, "boolean");
85  break;
86  default:
87  return false;
88  }
89  if (varargs) {
90  dem_string_append(sb, "...");
91  type_len += 3;
92  }
93  if (array) {
94  if (!varargs) {
95  dem_string_append(sb, "[]");
96  }
97  type_len++;
98  }
99  if (used) {
100  *used = type_len;
101  }
102  return true;
103 }
104 
105 static char *demangle_method(char *name, char *arguments, char *return_type) {
106  // example: Lsome/class/Object;.myMethod([F)I
107  // name = Lsome/class/Object;.myMethod
108  // args = [F
109  // rett = I
110  DemString *sb = NULL;
111  size_t args_length = 0;
112 
113  sb = dem_string_new();
114  if (!sb) {
115  goto demangle_method_bad;
116  }
117 
118  arguments[0] = 0;
119  arguments++;
120  args_length = return_type - arguments;
121 
122  return_type[0] = 0;
123  return_type++;
124 
125  if (!demangle_type(return_type, sb, NULL)) {
126  goto demangle_method_bad;
127  }
128 
129  dem_string_append(sb, " ");
130 
131  const char *t = NULL;
132  if (name[0] == 'L' && (t = strchr(name, ';')) && !demangle_type(name, sb, NULL)) {
133  goto demangle_method_bad;
134  } else if (name[0] == 'L' && t) {
135  dem_string_append(sb, t + 1);
136  } else {
138  }
139 
140  dem_string_append(sb, "(");
141  for (size_t pos = 0, used = 0; pos < args_length;) {
142  if (!demangle_type(arguments + pos, sb, &used)) {
143  goto demangle_method_bad;
144  }
145  pos += used;
146  if (pos < args_length) {
147  dem_string_append(sb, ", ");
148  }
149  }
150  dem_string_append(sb, ")");
151 
152  free(name);
153  dem_string_replace_char(sb, '/', '.');
154  return dem_string_drain(sb);
155 
156 demangle_method_bad:
158  free(name);
159  return NULL;
160 }
161 
162 static char *demangle_class_object(char *object, char *name) {
163  // example: Lsome/class/Object;.myMethod.I
164  // object = Lsome/class/Object;
165  // name = myMethod.I
166  DemString *sb = NULL;
167  char *type = NULL;
168 
169  sb = dem_string_new();
170  if (!sb) {
171  goto demangle_class_object_bad;
172  }
173 
174  name[0] = 0;
175  name++;
176 
177  type = strchr(name, '.');
178 
179  if (!demangle_type(object, sb, NULL)) {
180  goto demangle_class_object_bad;
181  }
182 
183  if (type) {
184  type[0] = 0;
185  type++;
186  dem_string_appendf(sb, ".%s:", name);
187  if (!demangle_type(type, sb, NULL)) {
188  goto demangle_class_object_bad;
189  }
190  } else {
191  dem_string_appendf(sb, ".%s", name);
192  }
193 
194  free(object);
195  dem_string_replace_char(sb, '/', '.');
196  return dem_string_drain(sb);
197 
198 demangle_class_object_bad:
200  free(object);
201  return NULL;
202 }
203 
204 static char *demangle_object_with_type(char *name, char *object) {
205  // example: myMethod.Lsome/class/Object;
206  // name = myMethod
207  // object = Lsome/class/Object;
209  if (!sb) {
210  goto demangle_object_with_type_bad;
211  }
212 
213  object[0] = 0;
214  object++;
215 
216  dem_string_appendf(sb, "%s:", name);
217  if (!demangle_type(object, sb, NULL)) {
218  goto demangle_object_with_type_bad;
219  }
220 
221  free(name);
222  dem_string_replace_char(sb, '/', '.');
223  return dem_string_drain(sb);
224 
225 demangle_object_with_type_bad:
227  free(name);
228  return NULL;
229 }
230 
231 static char *demangle_any(char *mangled) {
233  if (!sb) {
234  return NULL;
235  }
236 
237  if (!demangle_type(mangled, sb, NULL)) {
238  free(mangled);
240  return NULL;
241  }
242  free(mangled);
243 
244  dem_string_replace_char(sb, '/', '.');
245  return dem_string_drain(sb);
246 }
247 
260 char *libdemangle_handler_java(const char *mangled) {
261  if (!mangled) {
262  return NULL;
263  }
264 
265  char *name = NULL;
266  char *arguments = NULL;
267  char *return_type = NULL;
268 
269  name = strdup(mangled);
270  if (!name) {
271  return NULL;
272  }
273 
274  name = dem_str_replace(name, "java/lang/", "", 1);
275  if ((arguments = strchr(name, '(')) && (return_type = strchr(arguments, ')'))) {
276  return demangle_method(name, arguments, return_type);
277  } else if (name[0] == 'L' && (arguments = strchr(name, '.'))) {
278  return demangle_class_object(name, arguments);
279  } else if ((arguments = strchr(name, '.'))) {
280  return demangle_object_with_type(name, arguments);
281  }
282  return demangle_any(name);
283 }
static SblHeader sb
Definition: bin_mbn.c:26
#define NULL
Definition: cris-opc.c:27
char * dem_string_drain(DemString *ds)
char * dem_str_replace(char *str, const char *key, const char *val, int g)
void dem_string_free(DemString *ds)
DemString * dem_string_new()
bool dem_string_append(DemString *ds, const char *string)
bool dem_string_appendf(DemString *ds, const char *fmt,...)
bool dem_string_append_n(DemString *ds, const char *string, size_t size)
void dem_string_replace_char(DemString *ds, char ch, char rp)
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
static char * demangle_class_object(char *object, char *name)
Definition: java.c:162
char * libdemangle_handler_java(const char *mangled)
Demangles java classes/methods/fields.
Definition: java.c:260
static char * demangle_object_with_type(char *name, char *object)
Definition: java.c:204
static char * demangle_any(char *mangled)
Definition: java.c:231
#define is_native_type(x)
Definition: java.c:6
#define is_varargs(x)
Definition: java.c:7
static char * demangle_method(char *name, char *arguments, char *return_type)
Definition: java.c:105
static bool demangle_type(char *type, DemString *sb, size_t *used)
Definition: java.c:9
return strdup("=SP r13\n" "=LR r14\n" "=PC r15\n" "=A0 r0\n" "=A1 r1\n" "=A2 r2\n" "=A3 r3\n" "=ZF zf\n" "=SF nf\n" "=OF vf\n" "=CF cf\n" "=SN or0\n" "gpr lr .32 56 0\n" "gpr pc .32 60 0\n" "gpr cpsr .32 64 0 ____tfiae_________________qvczn\n" "gpr or0 .32 68 0\n" "gpr tf .1 64.5 0 thumb\n" "gpr ef .1 64.9 0 endian\n" "gpr jf .1 64.24 0 java\n" "gpr qf .1 64.27 0 sticky_overflow\n" "gpr vf .1 64.28 0 overflow\n" "gpr cf .1 64.29 0 carry\n" "gpr zf .1 64.30 0 zero\n" "gpr nf .1 64.31 0 negative\n" "gpr itc .4 64.10 0 if_then_count\n" "gpr gef .4 64.16 0 great_or_equal\n" "gpr r0 .32 0 0\n" "gpr r1 .32 4 0\n" "gpr r2 .32 8 0\n" "gpr r3 .32 12 0\n" "gpr r4 .32 16 0\n" "gpr r5 .32 20 0\n" "gpr r6 .32 24 0\n" "gpr r7 .32 28 0\n" "gpr r8 .32 32 0\n" "gpr r9 .32 36 0\n" "gpr r10 .32 40 0\n" "gpr r11 .32 44 0\n" "gpr r12 .32 48 0\n" "gpr r13 .32 52 0\n" "gpr r14 .32 56 0\n" "gpr r15 .32 60 0\n" "gpr r16 .32 64 0\n" "gpr r17 .32 68 0\n")
int type
Definition: mipsasm.c:17
Definition: z80asm.h:102
int pos
Definition: main.c:11