Rizin
unix-like reverse engineering framework and cli tools
class_bin.c File Reference
#include "class_bin.h"
#include "class_private.h"

Go to the source code of this file.

Macros

#define ACCESS_FLAG_MASK_SRC   (ACCESS_FLAG_PUBLIC | ACCESS_FLAG_PRIVATE | ACCESS_FLAG_PROTECTED | ACCESS_FLAG_STATIC | ACCESS_FLAG_FINAL)
 
#define CLASS_ACCESS_FLAGS_SIZE   16
 
#define is_version(bin, major, minor)   ((bin)->major_version == (major) && (bin)->minor_version >= (minor))
 

Functions

static ut64 java_access_flags_to_bin_flags (ut64 access_flags)
 
static const ConstPooljava_class_constant_pool_at (RzBinJavaClass *bin, ut32 index)
 
static char * java_class_constant_pool_stringify_at (RzBinJavaClass *bin, ut32 index)
 
static ut32 sanitize_size (st64 buffer_size, ut64 count, ut32 min_struct_size)
 
static bool java_class_is_oak (RzBinJavaClass *bin)
 
static bool is_eob (RzBuffer *buf)
 
static bool java_class_parse (RzBinJavaClass *bin, ut64 base, Sdb *kv, RzBuffer *buf, ut64 *size)
 
static void java_set_sdb (Sdb *kv, RzBinJavaClass *bin, ut64 offset, ut64 size)
 
RZ_API RZ_OWN RzBinJavaClassrz_bin_java_class_new (RZ_NONNULL RzBuffer *buf, ut64 offset, RZ_NONNULL Sdb *kv)
 Parses the java class file and returns a RzBinJavaClass struct. More...
 
RZ_API RZ_OWN char * rz_bin_java_class_version (RZ_NONNULL RzBinJavaClass *bin)
 Parses the java class file and returns a RzBinJavaClass struct. More...
 
RZ_API ut64 rz_bin_java_class_debug_info (RZ_NONNULL RzBinJavaClass *bin)
 
RZ_API RZ_BORROW const char * rz_bin_java_class_language (RZ_NONNULL RzBinJavaClass *bin)
 
RZ_API void rz_bin_java_class_free (RZ_NULLABLE RzBinJavaClass *bin)
 Frees a RzBinJavaClass pointer. More...
 
RZ_API RZ_OWN char * rz_bin_java_class_name (RZ_NONNULL RzBinJavaClass *bin)
 Returns the class name. More...
 
RZ_API RZ_OWN char * rz_bin_java_class_super (RZ_NONNULL RzBinJavaClass *bin)
 Returns the class super name. More...
 
RZ_API ut32 rz_bin_java_class_access_flags (RZ_NONNULL RzBinJavaClass *bin)
 
RZ_API RZ_OWN char * rz_bin_java_class_access_flags_readable (RZ_NONNULL RzBinJavaClass *bin, ut16 mask)
 Returns the readable class access flags. More...
 
static int calculate_padding_ut16 (ut16 count)
 
RZ_API void rz_bin_java_class_as_json (RZ_NONNULL RzBinJavaClass *bin, RZ_NONNULL PJ *j)
 Returns the class info as json. More...
 
RZ_API void rz_bin_java_class_as_text (RZ_NONNULL RzBinJavaClass *bin, RZ_NONNULL RzStrBuf *sb)
 Returns the class info as text. More...
 
static bool is_dual_index (const ConstPool *cpool)
 
RZ_API RZ_OWN char * rz_bin_java_class_const_pool_resolve_index (RZ_NONNULL RzBinJavaClass *bin, st32 index)
 Returns the string linked to the class const pool index. More...
 
RZ_API void rz_bin_java_class_as_source_code (RZ_NONNULL RzBinJavaClass *bin, RZ_NONNULL RzStrBuf *sb)
 Returns the class info as text source code. More...
 
RZ_API RZ_OWN RzBinAddrrz_bin_java_class_resolve_symbol (RZ_NONNULL RzBinJavaClass *bin, RzBinSpecialSymbol resolve)
 Resolves and returns the RzBinAddr struct linked to the input RzBinSpecialSymbol. More...
 
RZ_API RZ_OWN RzListrz_bin_java_class_entrypoints (RZ_NONNULL RzBinJavaClass *bin)
 Returns a RzList<RzBinAddr*> containing the entrypoints. More...
 
RZ_API RZ_OWN RzListrz_bin_java_class_strings (RZ_NONNULL RzBinJavaClass *bin)
 Returns a RzList<RzBinString*> containing the strings. More...
 
static char * add_class_name_to_name (char *name, char *classname)
 
RZ_API RZ_OWN RzListrz_bin_java_class_methods_as_symbols (RZ_NONNULL RzBinJavaClass *bin)
 Returns a RzList<RzBinSymbol*> containing the class methods. More...
 
RZ_API void rz_bin_java_class_methods_as_text (RZ_NONNULL RzBinJavaClass *bin, RZ_NONNULL RzStrBuf *sb)
 Returns the methods in text format via RzStrBuf arg. More...
 
RZ_API void rz_bin_java_class_methods_as_json (RZ_NONNULL RzBinJavaClass *bin, RZ_NONNULL PJ *j)
 Returns the methods in json format via PJ arg. More...
 
RZ_API RZ_OWN RzListrz_bin_java_class_fields_as_symbols (RZ_NONNULL RzBinJavaClass *bin)
 Returns a RzList<RzBinSymbol*> containing the class fields. More...
 
RZ_API RZ_OWN RzListrz_bin_java_class_fields_as_binfields (RZ_NONNULL RzBinJavaClass *bin)
 Returns a RzList<RzBinField*> containing the class fields. More...
 
RZ_API void rz_bin_java_class_fields_as_text (RZ_NONNULL RzBinJavaClass *bin, RZ_NONNULL RzStrBuf *sb)
 Returns the fields in text format via RzStrBuf arg. More...
 
RZ_API void rz_bin_java_class_fields_as_json (RZ_NONNULL RzBinJavaClass *bin, RZ_NONNULL PJ *j)
 Returns the fields in json format via PJ arg. More...
 
static char * import_type (const ConstPool *cpool)
 
RZ_API RZ_OWN RzListrz_bin_java_class_const_pool_as_symbols (RZ_NONNULL RzBinJavaClass *bin)
 Returns a RzList<RzBinSymbol*> containing the class const pool. More...
 
RZ_API RZ_OWN RzListrz_bin_java_class_const_pool_as_imports (RZ_NONNULL RzBinJavaClass *bin)
 Returns a RzList<RzBinImport*> containing the class const pool. More...
 
RZ_API void rz_bin_java_class_const_pool_as_text (RZ_NONNULL RzBinJavaClass *bin, RZ_NONNULL RzStrBuf *sb)
 Returns the class const pool in text format via RzStrBuf arg. More...
 
RZ_API void rz_bin_java_class_const_pool_as_json (RZ_NONNULL RzBinJavaClass *bin, RZ_NONNULL PJ *j)
 Returns the class const pool in json format via PJ arg. More...
 
static RzBinSectionnew_section (const char *name, ut64 start, ut64 end, ut32 perm)
 
static void section_free (void *u)
 
static int compare_section_names (const void *a, const void *b)
 
RZ_API RZ_OWN RzListrz_bin_java_class_as_sections (RZ_NONNULL RzBinJavaClass *bin)
 Returns a RzList<RzBinSection*> containing the class sections. More...
 
static int compare_strings (const void *a, const void *b)
 
RZ_API RZ_OWN RzListrz_bin_java_class_as_libraries (RZ_NONNULL RzBinJavaClass *bin)
 Returns a RzList<char*> containing the class libraries. More...
 
RZ_API void rz_bin_java_class_interfaces_as_text (RZ_NONNULL RzBinJavaClass *bin, RZ_NONNULL RzStrBuf *sb)
 Returns the class interfaces as text via RzStrBuf arg. More...
 
RZ_API void rz_bin_java_class_interfaces_as_json (RZ_NONNULL RzBinJavaClass *bin, RZ_NONNULL PJ *j)
 Returns the class interfaces as json via PJ arg. More...
 

Variables

static const AccessFlagsReadable access_flags_list [CLASS_ACCESS_FLAGS_SIZE]
 

Macro Definition Documentation

◆ ACCESS_FLAG_MASK_SRC

Definition at line 7 of file class_bin.c.

◆ CLASS_ACCESS_FLAGS_SIZE

#define CLASS_ACCESS_FLAGS_SIZE   16

Definition at line 9 of file class_bin.c.

◆ is_version

#define is_version (   bin,
  major,
  minor 
)    ((bin)->major_version == (major) && (bin)->minor_version >= (minor))

Function Documentation

◆ add_class_name_to_name()

static char* add_class_name_to_name ( char *  name,
char *  classname 
)
static

Definition at line 1042 of file class_bin.c.

1042  {
1043  if (classname) {
1044  return rz_str_newf("%s.%s", classname, name);
1045  }
1046  return strdup(name);
1047 }
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")
RZ_API char * rz_str_newf(const char *fmt,...) RZ_PRINTF_CHECK(1
Definition: z80asm.h:102

References rz_str_newf(), and strdup().

Referenced by rz_bin_java_class_const_pool_as_symbols(), rz_bin_java_class_fields_as_symbols(), and rz_bin_java_class_methods_as_symbols().

◆ calculate_padding_ut16()

static int calculate_padding_ut16 ( ut16  count)
static

Definition at line 507 of file class_bin.c.

507  {
508  if (count > 9999) {
509  return 5;
510  } else if (count > 999) {
511  return 4;
512  } else if (count > 99) {
513  return 3;
514  }
515  return 2;
516 }
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void count
Definition: sflib.h:98

References count.

Referenced by rz_bin_java_class_as_text(), rz_bin_java_class_const_pool_as_text(), rz_bin_java_class_fields_as_text(), rz_bin_java_class_interfaces_as_text(), and rz_bin_java_class_methods_as_text().

◆ compare_section_names()

static int compare_section_names ( const void *  a,
const void *  b 
)
static

Definition at line 1710 of file class_bin.c.

1710  {
1711  RzBinSection *sec = (RzBinSection *)b;
1712  return strcmp((const char *)a, sec->name);
1713 }
#define b(i)
Definition: sha256.c:42
#define a(i)
Definition: sha256.c:41
char * name
Definition: rz_bin.h:619

References a, b, and rz_bin_section_t::name.

Referenced by rz_bin_java_class_as_sections().

◆ compare_strings()

static int compare_strings ( const void *  a,
const void *  b 
)
static

Definition at line 1839 of file class_bin.c.

1839  {
1840  return strcmp((const char *)a, (const char *)b);
1841 }

References a, and b.

Referenced by rz_bin_java_class_as_libraries().

◆ import_type()

static char* import_type ( const ConstPool cpool)
static

Definition at line 1421 of file class_bin.c.

1421  {
1422  if (cpool->tag == CONSTANT_POOL_METHODREF) {
1423  return RZ_BIN_TYPE_METH_STR;
1424  } else if (cpool->tag == CONSTANT_POOL_FIELDREF) {
1425  return "FIELD";
1426  } else if (cpool->tag == CONSTANT_POOL_INTERFACEMETHODREF) {
1427  return "IMETH";
1428  }
1429  return RZ_BIN_TYPE_UNKNOWN_STR;
1430 }
@ CONSTANT_POOL_FIELDREF
@ CONSTANT_POOL_METHODREF
@ CONSTANT_POOL_INTERFACEMETHODREF
#define RZ_BIN_TYPE_METH_STR
Definition: rz_bin.h:122
#define RZ_BIN_TYPE_UNKNOWN_STR
Definition: rz_bin.h:134

References CONSTANT_POOL_FIELDREF, CONSTANT_POOL_INTERFACEMETHODREF, CONSTANT_POOL_METHODREF, RZ_BIN_TYPE_METH_STR, RZ_BIN_TYPE_UNKNOWN_STR, and java_constant_pool_t::tag.

Referenced by rz_bin_java_class_const_pool_as_imports(), and rz_bin_java_class_const_pool_as_symbols().

◆ is_dual_index()

static bool is_dual_index ( const ConstPool cpool)
inlinestatic

◆ is_eob()

static bool is_eob ( RzBuffer buf)
static

Definition at line 91 of file class_bin.c.

91  {
93  st64 position = rz_buf_tell(buf);
94  return position >= size;
95 }
voidpf void uLong size
Definition: ioapi.h:138
voidpf void * buf
Definition: ioapi.h:138
RZ_API ut64 rz_buf_tell(RZ_NONNULL RzBuffer *b)
Return the current cursor position.
Definition: buf.c:1238
RZ_API ut64 rz_buf_size(RZ_NONNULL RzBuffer *b)
Return the size of the buffer.
Definition: buf.c:1225
#define st64
Definition: rz_types_base.h:10

References rz_buf_size(), rz_buf_tell(), and st64.

Referenced by java_class_parse().

◆ java_access_flags_to_bin_flags()

static ut64 java_access_flags_to_bin_flags ( ut64  access_flags)
static

Definition at line 29 of file class_bin.c.

29  {
30  ut64 flags = 0;
31  if (access_flags & ACCESS_FLAG_PUBLIC) {
33  }
34  if (access_flags & ACCESS_FLAG_PRIVATE) {
36  }
37  if (access_flags & ACCESS_FLAG_PROTECTED) {
39  }
40  if (access_flags & ACCESS_FLAG_STATIC) {
42  }
43  if (access_flags & ACCESS_FLAG_FINAL) {
45  }
46  if (access_flags & ACCESS_FLAG_BRIDGE) {
48  }
49  if (access_flags & ACCESS_FLAG_VARARGS) {
51  }
52  if (access_flags & ACCESS_FLAG_NATIVE) {
54  }
55  if (access_flags & ACCESS_FLAG_ABSTRACT) {
57  }
58  if (access_flags & ACCESS_FLAG_STRICT) {
60  }
61  if (access_flags & ACCESS_FLAG_SYNTHETIC) {
63  }
64  return flags;
65 }
@ ACCESS_FLAG_SYNTHETIC
Definition: dex.h:53
@ ACCESS_FLAG_VARARGS
Definition: dex.h:48
@ ACCESS_FLAG_NATIVE
Definition: dex.h:49
@ ACCESS_FLAG_PRIVATE
Definition: dex.h:42
@ ACCESS_FLAG_PROTECTED
Definition: dex.h:43
@ ACCESS_FLAG_STATIC
Definition: dex.h:44
@ ACCESS_FLAG_BRIDGE
Definition: dex.h:47
@ ACCESS_FLAG_STRICT
Definition: dex.h:52
@ ACCESS_FLAG_ABSTRACT
Definition: dex.h:51
@ ACCESS_FLAG_FINAL
Definition: dex.h:45
@ ACCESS_FLAG_PUBLIC
Definition: dex.h:41
#define RZ_BIN_METH_PUBLIC
Definition: rz_bin.h:85
#define RZ_BIN_METH_VARARGS
Definition: rz_bin.h:99
#define RZ_BIN_METH_SYNTHETIC
Definition: rz_bin.h:100
#define RZ_BIN_METH_STRICT
Definition: rz_bin.h:101
#define RZ_BIN_METH_ABSTRACT
Definition: rz_bin.h:95
#define RZ_BIN_METH_FINAL
Definition: rz_bin.h:91
#define RZ_BIN_METH_BRIDGE
Definition: rz_bin.h:98
#define RZ_BIN_METH_STATIC
Definition: rz_bin.h:84
#define RZ_BIN_METH_PRIVATE
Definition: rz_bin.h:86
#define RZ_BIN_METH_PROTECTED
Definition: rz_bin.h:87
#define RZ_BIN_METH_NATIVE
Definition: rz_bin.h:97
static struct sockaddr static addrlen static backlog const void static flags void flags
Definition: sfsocketcall.h:123
ut64(WINAPI *w32_GetEnabledXStateFeatures)()

References ACCESS_FLAG_ABSTRACT, ACCESS_FLAG_BRIDGE, ACCESS_FLAG_FINAL, ACCESS_FLAG_NATIVE, ACCESS_FLAG_PRIVATE, ACCESS_FLAG_PROTECTED, ACCESS_FLAG_PUBLIC, ACCESS_FLAG_STATIC, ACCESS_FLAG_STRICT, ACCESS_FLAG_SYNTHETIC, ACCESS_FLAG_VARARGS, flags, RZ_BIN_METH_ABSTRACT, RZ_BIN_METH_BRIDGE, RZ_BIN_METH_FINAL, RZ_BIN_METH_NATIVE, RZ_BIN_METH_PRIVATE, RZ_BIN_METH_PROTECTED, RZ_BIN_METH_PUBLIC, RZ_BIN_METH_STATIC, RZ_BIN_METH_STRICT, RZ_BIN_METH_SYNTHETIC, RZ_BIN_METH_VARARGS, and ut64().

Referenced by rz_bin_java_class_fields_as_binfields(), rz_bin_java_class_fields_as_symbols(), and rz_bin_java_class_methods_as_symbols().

◆ java_class_constant_pool_at()

◆ java_class_constant_pool_stringify_at()

◆ java_class_is_oak()

static bool java_class_is_oak ( RzBinJavaClass bin)
static

Definition at line 87 of file class_bin.c.

87  {
88  return bin->major_version < (45) || (bin->major_version == 45 && bin->minor_version < 3);
89 }

Referenced by java_class_parse().

◆ java_class_parse()

static bool java_class_parse ( RzBinJavaClass bin,
ut64  base,
Sdb kv,
RzBuffer buf,
ut64 size 
)
static

Definition at line 97 of file class_bin.c.

97  {
98  // https://docs.oracle.com/javase/specs/jvms/se15/html/jvms-4.html#jvms-4.1
99  ut64 offset = 0;
101  if (buffer_size < 1) {
102  RZ_LOG_ERROR("java bin: invalid buffer size (size < 1)\n");
103  goto java_class_parse_bad;
104  }
105 
106  if (!rz_buf_read_be32(buf, &bin->magic) ||
107  !rz_buf_read_be16(buf, &bin->minor_version) ||
108  !rz_buf_read_be16(buf, &bin->major_version) ||
109  !rz_buf_read_be16(buf, &bin->constant_pool_count)) {
110  goto java_class_parse_bad;
111  }
112 
113  // Before version 1.0.2 it was called oak
114  // which uses a different file structure.
115  bool is_oak = java_class_is_oak(bin);
116 
117  bin->constant_pool_count = sanitize_size(buffer_size - rz_buf_tell(buf), bin->constant_pool_count, 3);
118  bin->constant_pool_offset = base + rz_buf_tell(buf);
119 
120  if (bin->constant_pool_count > 0) {
121  bin->constant_pool = RZ_NEWS0(ConstPool *, bin->constant_pool_count);
122  if (!bin->constant_pool) {
123  goto java_class_parse_bad;
124  }
125  for (ut32 i = 1; i < bin->constant_pool_count; ++i) {
126  offset = rz_buf_tell(buf) + base;
128  if (!cpool) {
129  RZ_LOG_ERROR("java bin: could not parse the constant pool value at offset %" PFMT64x "\n", offset);
130  break;
131  }
132  bin->constant_pool[i] = cpool;
134  if (i >= (bin->constant_pool_count - 1)) {
135  break;
136  }
137  i++;
138  bin->constant_pool[i] = java_constant_null_new(offset);
139  }
140  }
141  if (is_eob(buf)) {
143  goto java_class_parse_bad;
144  }
145  }
146 
147  if (!rz_buf_read_be16(buf, &bin->access_flags) ||
148  !rz_buf_read_be16(buf, &bin->this_class) ||
149  !rz_buf_read_be16(buf, &bin->super_class) ||
150  !rz_buf_read_be16(buf, &bin->interfaces_count)) {
151  goto java_class_parse_bad;
152  }
153 
154  bin->interfaces_count = sanitize_size(buffer_size - rz_buf_tell(buf), bin->interfaces_count, 2);
155  bin->interfaces_offset = base + rz_buf_tell(buf);
156 
157  if (bin->interfaces_count > 0) {
158  bin->interfaces = RZ_NEWS0(Interface *, bin->interfaces_count);
159  if (!bin->interfaces) {
160  goto java_class_parse_bad;
161  }
162  for (ut32 i = 0; i < bin->interfaces_count; ++i) {
163  offset = rz_buf_tell(buf) + base;
164  bin->interfaces[i] = java_interface_new(buf, offset);
165  }
166  if (is_eob(buf)) {
168  goto java_class_parse_bad;
169  }
170  }
171 
172  if (!rz_buf_read_be16(buf, &bin->fields_count)) {
173  goto java_class_parse_bad;
174  }
175 
176  bin->fields_count = sanitize_size(buffer_size - rz_buf_tell(buf), bin->fields_count, 8);
177  bin->fields_offset = base + rz_buf_tell(buf);
178 
179  if (bin->fields_count > 0) {
180  bin->fields = RZ_NEWS0(Field *, bin->fields_count);
181  if (!bin->fields) {
182  goto java_class_parse_bad;
183  }
184  for (ut32 i = 0; i < bin->fields_count; ++i) {
185  offset = rz_buf_tell(buf) + base;
186  bin->fields[i] = java_field_new(bin->constant_pool,
187  bin->constant_pool_count, buf, offset);
188  }
189  if (is_eob(buf)) {
191  goto java_class_parse_bad;
192  }
193  }
194 
195  if (!rz_buf_read_be16(buf, &bin->methods_count)) {
196  goto java_class_parse_bad;
197  }
198  bin->methods_count = sanitize_size(buffer_size - rz_buf_tell(buf), bin->methods_count, 8);
199  bin->methods_offset = base + rz_buf_tell(buf);
200 
201  if (bin->methods_count > 0) {
202  bin->methods = RZ_NEWS0(Method *, bin->methods_count);
203  if (!bin->methods) {
204  goto java_class_parse_bad;
205  }
206  for (ut32 i = 0; i < bin->methods_count; ++i) {
207  offset = rz_buf_tell(buf) + base;
208  bin->methods[i] = java_method_new(bin->constant_pool,
209  bin->constant_pool_count, buf, offset, is_oak);
210  }
211  if (is_eob(buf)) {
213  goto java_class_parse_bad;
214  }
215  }
216 
217  if (!rz_buf_read_be16(buf, &bin->attributes_count)) {
218  goto java_class_parse_bad;
219  }
220 
221  bin->attributes_count = sanitize_size(buffer_size - rz_buf_tell(buf), bin->attributes_count, 6);
222  bin->attributes_offset = base + rz_buf_tell(buf);
223 
224  if (bin->attributes_count > 0) {
225  bin->attributes = RZ_NEWS0(Attribute *, bin->attributes_count);
226  if (!bin->attributes) {
227  goto java_class_parse_bad;
228  }
229  for (ut32 i = 0; i < bin->attributes_count; ++i) {
230  offset = rz_buf_tell(buf) + base;
232  if (attr && java_attribute_resolve(bin->constant_pool, bin->constant_pool_count, attr, buf, false)) {
233  bin->attributes[i] = attr;
234  } else {
235  java_attribute_free(attr);
236  break;
237  }
238  }
239  }
240  bin->class_end_offset = base + rz_buf_tell(buf);
241  if (size) {
242  *size = rz_buf_tell(buf);
243  }
244  return true;
245 
246 java_class_parse_bad:
248  return false;
249 }
lzma_index ** i
Definition: index.h:629
bool java_attribute_resolve(ConstPool **pool, ut32 poolsize, Attribute *attr, RzBuffer *buf, bool is_oak)
Attribute * java_attribute_new(RzBuffer *buf, ut64 offset)
void java_attribute_free(Attribute *attr)
static ut32 sanitize_size(st64 buffer_size, ut64 count, ut32 min_struct_size)
Definition: class_bin.c:82
static bool java_class_is_oak(RzBinJavaClass *bin)
Definition: class_bin.c:87
static bool is_eob(RzBuffer *buf)
Definition: class_bin.c:91
RZ_API void rz_bin_java_class_free(RZ_NULLABLE RzBinJavaClass *bin)
Frees a RzBinJavaClass pointer.
Definition: class_bin.c:407
bool java_constant_pool_requires_null(const ConstPool *cpool)
ConstPool * java_constant_pool_new(RzBuffer *buf, ut64 offset)
ConstPool * java_constant_null_new(ut64 offset)
Field * java_field_new(ConstPool **pool, ut32 poolsize, RzBuffer *buf, ut64 offset)
Definition: class_field.c:41
Interface * java_interface_new(RzBuffer *buf, ut64 offset)
Method * java_method_new(ConstPool **pool, ut32 poolsize, RzBuffer *buf, ut64 offset, bool is_oak)
Definition: class_method.c:54
uint32_t ut32
voidpf uLong offset
Definition: ioapi.h:144
#define rz_warn_if_reached()
Definition: rz_assert.h:29
#define rz_buf_read_be16(b, result)
Definition: rz_buf.h:280
#define rz_buf_read_be32(b, result)
Definition: rz_buf.h:281
#define RZ_LOG_ERROR(fmtstr,...)
Definition: rz_log.h:58
#define RZ_NEWS0(x, y)
Definition: rz_types.h:282
#define PFMT64x
Definition: rz_types.h:393
#define buffer_size(buffer)

References buffer_size, i, is_eob(), java_attribute_free(), java_attribute_new(), java_attribute_resolve(), java_class_is_oak(), java_constant_null_new(), java_constant_pool_new(), java_constant_pool_requires_null(), java_field_new(), java_interface_new(), java_method_new(), PFMT64x, rz_bin_java_class_free(), rz_buf_read_be16, rz_buf_read_be32, rz_buf_size(), rz_buf_tell(), RZ_LOG_ERROR, RZ_NEWS0, rz_warn_if_reached, sanitize_size(), st64, and ut64().

Referenced by rz_bin_java_class_new().

◆ java_set_sdb()

static void java_set_sdb ( Sdb kv,
RzBinJavaClass bin,
ut64  offset,
ut64  size 
)
static

Definition at line 251 of file class_bin.c.

251  {
252  char *tmp_val;
253  char tmp_key[256];
254 
255  sdb_num_set(kv, "java_class.offset", offset, 0);
256  sdb_num_set(kv, "java_class.size", size, 0);
257  sdb_num_set(kv, "java_class.magic", size, 0);
258  sdb_num_set(kv, "java_class.minor_version", size, 0);
259  sdb_num_set(kv, "java_class.major_version", size, 0);
260 
261  tmp_val = rz_bin_java_class_version(bin);
262  if (tmp_val) {
263  sdb_set(kv, "java_class.version", tmp_val, 0);
264  free(tmp_val);
265  }
266 
267  sdb_num_set(kv, "java_class.constant_pool_count", bin->constant_pool_count, 0);
268  for (ut32 i = 0; i < bin->constant_pool_count; ++i) {
269  ConstPool *cpool = bin->constant_pool[i];
270  if (!cpool) {
271  continue;
272  }
273  tmp_val = java_constant_pool_stringify(cpool);
274  if (tmp_val) {
275  snprintf(tmp_key, sizeof(tmp_key), "java_class.constant_pool_%d", i);
276  sdb_set(kv, tmp_key, tmp_val, 0);
277  free(tmp_val);
278  }
279  }
280 
281  sdb_num_set(kv, "java_class.fields_count", bin->fields_count, 0);
282  sdb_num_set(kv, "java_class.methods_count", bin->methods_count, 0);
283  sdb_num_set(kv, "java_class.attributes_count", bin->attributes_count, 0);
284 }
RZ_API RZ_OWN char * rz_bin_java_class_version(RZ_NONNULL RzBinJavaClass *bin)
Parses the java class file and returns a RzBinJavaClass struct.
Definition: class_bin.c:306
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
snprintf
Definition: kernel.h:364
RZ_API int sdb_num_set(Sdb *s, const char *key, ut64 v, ut32 cas)
Definition: num.c:25
RZ_API int sdb_set(Sdb *s, const char *key, const char *val, ut32 cas)
Definition: sdb.c:611

References free(), i, java_constant_pool_stringify(), rz_bin_java_class_version(), sdb_num_set(), sdb_set(), and snprintf.

Referenced by rz_bin_java_class_new().

◆ new_section()

static RzBinSection* new_section ( const char *  name,
ut64  start,
ut64  end,
ut32  perm 
)
static

Definition at line 1686 of file class_bin.c.

1686  {
1688  if (!section) {
1690  return NULL;
1691  }
1692  section->name = strdup(name);
1693  if (!section->name) {
1695  free(section);
1696  return NULL;
1697  }
1698  section->paddr = start;
1699  section->vaddr = start;
1700  section->size = end - start;
1701  section->vsize = section->size;
1702  section->perm = perm;
1703  return section;
1704 }
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void static offset struct stat static buf void long static basep static whence static length const void static len static semflg const void static shmflg const struct timespec struct timespec static rem const char static group const void start
Definition: sflib.h:133
#define RZ_NEW0(x)
Definition: rz_types.h:284
uint32_t size

References test_evm::end, free(), NULL, RZ_NEW0, rz_warn_if_reached, section::size, start, and strdup().

Referenced by rz_bin_java_class_as_sections().

◆ rz_bin_java_class_access_flags()

RZ_API ut32 rz_bin_java_class_access_flags ( RZ_NONNULL RzBinJavaClass bin)

Definition at line 477 of file class_bin.c.

477  {
478  rz_return_val_if_fail(bin, 0xffffffff);
479  return bin->access_flags;
480 }
#define rz_return_val_if_fail(expr, val)
Definition: rz_assert.h:108

References rz_return_val_if_fail.

Referenced by classes().

◆ rz_bin_java_class_access_flags_readable()

RZ_API RZ_OWN char* rz_bin_java_class_access_flags_readable ( RZ_NONNULL RzBinJavaClass bin,
ut16  mask 
)

Returns the readable class access flags.

Definition at line 485 of file class_bin.c.

485  {
487  RzStrBuf *sb = NULL;
488  ut16 access_flags = bin->access_flags & mask;
489 
490  for (ut32 i = 0; i < CLASS_ACCESS_FLAGS_SIZE; ++i) {
491  const AccessFlagsReadable *afr = &access_flags_list[i];
492  if (access_flags & afr->flag) {
493  if (!sb) {
494  sb = rz_strbuf_new(afr->readable);
495  if (!sb) {
496  return NULL;
497  }
498  } else {
499  rz_strbuf_appendf(sb, " %s", afr->readable);
500  }
501  }
502  }
503 
504  return sb ? rz_strbuf_drain(sb) : NULL;
505 }
#define mask()
static SblHeader sb
Definition: bin_mbn.c:26
static const AccessFlagsReadable access_flags_list[CLASS_ACCESS_FLAGS_SIZE]
Definition: class_bin.c:10
#define CLASS_ACCESS_FLAGS_SIZE
Definition: class_bin.c:9
uint16_t ut16
RZ_API RZ_OWN char * rz_strbuf_drain(RzStrBuf *sb)
Definition: strbuf.c:342
RZ_API RzStrBuf * rz_strbuf_new(const char *s)
Definition: strbuf.c:8
RZ_API bool rz_strbuf_appendf(RzStrBuf *sb, const char *fmt,...) RZ_PRINTF_CHECK(2

References access_flags_list, CLASS_ACCESS_FLAGS_SIZE, access_flags_readable_t::flag, i, mask, NULL, access_flags_readable_t::readable, rz_return_val_if_fail, rz_strbuf_appendf(), rz_strbuf_drain(), rz_strbuf_new(), and sb.

Referenced by classes(), rz_bin_java_class_as_json(), rz_bin_java_class_as_source_code(), and rz_bin_java_class_as_text().

◆ rz_bin_java_class_as_json()

RZ_API void rz_bin_java_class_as_json ( RZ_NONNULL RzBinJavaClass bin,
RZ_NONNULL PJ j 
)

Returns the class info as json.

Definition at line 521 of file class_bin.c.

521  {
522  rz_return_if_fail(bin && j);
523  char *tmp = NULL;
524 
525  pj_o(j);
526 
527  pj_ko(j, "version");
528  {
529  pj_kn(j, "minor", bin->minor_version);
530  pj_kn(j, "major", bin->major_version);
532  pj_ks(j, "version", tmp ? tmp : "");
533  free(tmp);
534  }
535  pj_end(j);
536 
537  pj_kn(j, "constant_pool_count", bin->constant_pool_count);
538  pj_k(j, "constant_pool");
540 
541  pj_kn(j, "access_flags_n", bin->access_flags);
543  pj_ks(j, "access_flags_s", tmp ? tmp : "");
544  free(tmp);
545 
546  pj_kn(j, "class_n", bin->this_class);
548  pj_ks(j, "class_s", tmp ? tmp : "");
549  free(tmp);
550 
551  pj_kn(j, "super_n", bin->super_class);
553  pj_ks(j, "super_s", tmp ? tmp : "");
554  free(tmp);
555 
556  pj_kn(j, "interfaces_count", bin->interfaces_count);
557  pj_k(j, "interfaces");
559 
560  pj_kn(j, "methods_count", bin->methods_count);
561  pj_k(j, "methods");
563 
564  pj_kn(j, "fields_count", bin->fields_count);
565  pj_k(j, "fields");
567 
568  pj_kn(j, "attributes_count", bin->attributes_count);
569  pj_ka(j, "attributes");
570  for (ut32 i = 0; i < bin->attributes_count; ++i) {
571  Attribute *attr = bin->attributes[i];
572  if (!attr) {
573  continue;
574  }
575  pj_o(j);
576  pj_kn(j, "offset", attr->offset);
577  pj_kn(j, "size", attr->attribute_length);
578  pj_kn(j, "name_n", attr->attribute_name_index);
580  pj_ks(j, "name_s", tmp ? tmp : "");
581  free(tmp);
582  pj_end(j);
583  }
584  pj_end(j);
585  pj_end(j);
586 }
RZ_API void rz_bin_java_class_const_pool_as_json(RZ_NONNULL RzBinJavaClass *bin, RZ_NONNULL PJ *j)
Returns the class const pool in json format via PJ arg.
Definition: class_bin.c:1650
RZ_API void rz_bin_java_class_fields_as_json(RZ_NONNULL RzBinJavaClass *bin, RZ_NONNULL PJ *j)
Returns the fields in json format via PJ arg.
Definition: class_bin.c:1366
static char * java_class_constant_pool_stringify_at(RzBinJavaClass *bin, ut32 index)
Definition: class_bin.c:74
RZ_API RZ_OWN char * rz_bin_java_class_access_flags_readable(RZ_NONNULL RzBinJavaClass *bin, ut16 mask)
Returns the readable class access flags.
Definition: class_bin.c:485
RZ_API RZ_OWN char * rz_bin_java_class_name(RZ_NONNULL RzBinJavaClass *bin)
Returns the class name.
Definition: class_bin.c:447
RZ_API RZ_OWN char * rz_bin_java_class_super(RZ_NONNULL RzBinJavaClass *bin)
Returns the class super name.
Definition: class_bin.c:466
RZ_API void rz_bin_java_class_interfaces_as_json(RZ_NONNULL RzBinJavaClass *bin, RZ_NONNULL PJ *j)
Returns the class interfaces as json via PJ arg.
Definition: class_bin.c:1928
RZ_API void rz_bin_java_class_methods_as_json(RZ_NONNULL RzBinJavaClass *bin, RZ_NONNULL PJ *j)
Returns the methods in json format via PJ arg.
Definition: class_bin.c:1169
#define ACCESS_FLAG_MASK_ALL
Definition: class_bin.h:36
#define rz_return_if_fail(expr)
Definition: rz_assert.h:100
RZ_API PJ * pj_ko(PJ *j, const char *k)
Definition: pj.c:156
RZ_API PJ * pj_ka(PJ *j, const char *k)
Definition: pj.c:163
RZ_API PJ * pj_k(PJ *j, const char *k)
Definition: pj.c:104
RZ_API PJ * pj_end(PJ *j)
Definition: pj.c:87
RZ_API PJ * pj_o(PJ *j)
Definition: pj.c:75
RZ_API PJ * pj_ks(PJ *j, const char *k, const char *v)
Definition: pj.c:170
RZ_API PJ * pj_kn(PJ *j, const char *k, ut64 n)
Definition: pj.c:121

References ACCESS_FLAG_MASK_ALL, java_attribute_t::attribute_length, java_attribute_t::attribute_name_index, free(), i, java_class_constant_pool_stringify_at(), NULL, java_attribute_t::offset, pj_end(), pj_k(), pj_ka(), pj_kn(), pj_ko(), pj_ks(), pj_o(), rz_bin_java_class_access_flags_readable(), rz_bin_java_class_const_pool_as_json(), rz_bin_java_class_fields_as_json(), rz_bin_java_class_interfaces_as_json(), rz_bin_java_class_methods_as_json(), rz_bin_java_class_name(), rz_bin_java_class_super(), rz_bin_java_class_version(), rz_return_if_fail, and autogen_x86imm::tmp.

Referenced by rz_cmd_javac_handler().

◆ rz_bin_java_class_as_libraries()

RZ_API RZ_OWN RzList* rz_bin_java_class_as_libraries ( RZ_NONNULL RzBinJavaClass bin)

Returns a RzList<char*> containing the class libraries.

Definition at line 1846 of file class_bin.c.

1846  {
1848 
1850  if (!list) {
1851  return NULL;
1852  }
1853  ut16 arg0, arg1;
1854  char *tmp;
1855 
1856  if (bin->constant_pool) {
1857  for (ut32 i = 0; i < bin->constant_pool_count; ++i) {
1858  tmp = NULL;
1859  const ConstPool *cpool = bin->constant_pool[i];
1860  if (!cpool) {
1861  continue;
1862  }
1863  if (cpool->tag == CONSTANT_POOL_CLASS) {
1864  if (java_constant_pool_resolve(cpool, &arg0, &arg1) != 1) {
1865  RZ_LOG_ERROR("java bin: can't resolve library with constant pool index %u\n", i);
1866  break;
1867  }
1868  // arg0 is name_index
1870  } else if (java_constant_pool_is_import(cpool)) {
1871  if (java_constant_pool_resolve(cpool, &arg0, &arg1) != 2) {
1872  RZ_LOG_ERROR("java bin: can't resolve library with constant pool index %u\n", i);
1873  break;
1874  }
1875  // arg0 is name_and_type_index
1876  const ConstPool *nat = java_class_constant_pool_at(bin, arg0);
1877  if (!nat ||
1878  java_constant_pool_resolve(nat, &arg0, &arg1) != 1) {
1879  RZ_LOG_ERROR("java bin: can't resolve library with constant pool index %u\n", i);
1880  break;
1881  }
1882  // arg0 is name_index
1884  }
1885  if (tmp && !rz_list_find(list, tmp, compare_strings)) {
1887  } else {
1888  free(tmp);
1889  }
1890  }
1891  }
1892  return list;
1893 }
static int compare_strings(const void *a, const void *b)
Definition: class_bin.c:1839
ut32 java_constant_pool_resolve(const ConstPool *cpool, ut16 *arg0, ut16 *arg1)
bool java_constant_pool_is_import(const ConstPool *cpool)
@ CONSTANT_POOL_CLASS
static void list(RzEgg *egg)
Definition: rz-gg.c:52
RZ_API RZ_BORROW RzListIter * rz_list_find(RZ_NONNULL const RzList *list, const void *p, RZ_NONNULL RzListComparator cmp)
Returns RzListIter element which matches via the RzListComparator.
Definition: list.c:620
RZ_API RZ_OWN RzList * rz_list_newf(RzListFree f)
Returns a new initialized RzList pointer and sets the free method.
Definition: list.c:248
RZ_API RZ_BORROW RzListIter * rz_list_append(RZ_NONNULL RzList *list, void *data)
Appends at the end of the list a new element.
Definition: list.c:288

References compare_strings(), CONSTANT_POOL_CLASS, free(), i, java_class_constant_pool_at(), java_class_constant_pool_stringify_at(), java_constant_pool_is_import(), java_constant_pool_resolve(), list(), NULL, rz_list_append(), rz_list_find(), rz_list_newf(), RZ_LOG_ERROR, rz_return_val_if_fail, java_constant_pool_t::tag, and autogen_x86imm::tmp.

Referenced by libs(), and rz_bin_java_class_as_source_code().

◆ rz_bin_java_class_as_sections()

RZ_API RZ_OWN RzList* rz_bin_java_class_as_sections ( RZ_NONNULL RzBinJavaClass bin)

Returns a RzList<RzBinSection*> containing the class sections.

Definition at line 1718 of file class_bin.c.

1718  {
1720 
1722  if (!sections) {
1723  return NULL;
1724  }
1725  ut32 iname;
1726  char *tmp;
1727  char secname[512];
1728  ut64 end_offset;
1729  if (bin->constant_pool) {
1731  new_section("class.constant_pool",
1732  bin->constant_pool_offset,
1733  bin->interfaces_offset,
1734  RZ_PERM_R));
1735  }
1736  if (bin->interfaces) {
1738  new_section("class.interfaces",
1739  bin->interfaces_offset,
1740  bin->fields_offset,
1741  RZ_PERM_R));
1742  }
1743  if (bin->fields) {
1744  for (ut32 i = 0; i < bin->fields_count; ++i) {
1745  Field *field = bin->fields[i];
1746  if (!field) {
1747  continue;
1748  }
1750  if (!tmp) {
1752  continue;
1753  }
1754  snprintf(secname, sizeof(secname), "class.fields.%s.attr", tmp);
1755  if ((i + 1) < bin->fields_count && bin->fields[i + 1]) {
1756  end_offset = bin->fields[i + 1]->offset;
1757  } else {
1758  end_offset = bin->methods_offset;
1759  }
1760  for (iname = 0; rz_list_find(sections, secname, compare_section_names); iname++) {
1761  snprintf(secname, sizeof(secname), "class.fields.%s_%d.attr", tmp, iname);
1762  }
1763  free(tmp);
1764  rz_list_append(sections, new_section(secname, field->offset, end_offset, RZ_PERM_R));
1765  }
1767  new_section("class.fields",
1768  bin->fields_offset,
1769  bin->methods_offset,
1770  RZ_PERM_R));
1771  }
1772  if (bin->methods) {
1774  new_section("class.methods",
1775  bin->methods_offset,
1776  bin->attributes_offset,
1777  RZ_PERM_R));
1778 
1779  for (ut32 i = 0; i < bin->methods_count; ++i) {
1780  Method *method = bin->methods[i];
1781  if (!method || method->attributes_count < 1) {
1782  continue;
1783  }
1785  if (!tmp) {
1787  continue;
1788  }
1789  snprintf(secname, sizeof(secname), "class.methods.%s.attr", tmp);
1790  for (iname = 0; rz_list_find(sections, secname, compare_section_names); iname++) {
1791  snprintf(secname, sizeof(secname), "class.methods.%s_%d.attr", tmp, iname);
1792  }
1793 
1794  if ((i + 1) < bin->methods_count && bin->methods[i + 1]) {
1795  end_offset = bin->methods[i + 1]->offset;
1796  } else {
1797  end_offset = bin->attributes_offset;
1798  }
1799  if (iname > 0) {
1800  snprintf(secname, sizeof(secname), "class.methods.%s_%d.attr", tmp, iname);
1801  } else {
1802  snprintf(secname, sizeof(secname), "class.methods.%s.attr", tmp);
1803  }
1804  rz_list_append(sections, new_section(secname, method->offset, end_offset, RZ_PERM_R));
1805 
1806  if (!method->attributes) {
1807  free(tmp);
1808  continue;
1809  }
1810 
1811  for (ut32 k = 0; k < method->attributes_count; ++k) {
1812  Attribute *attr = method->attributes[k];
1813  if (attr && attr->type == ATTRIBUTE_TYPE_CODE) {
1814  AttributeCode *ac = (AttributeCode *)attr->info;
1815  if (iname > 0) {
1816  snprintf(secname, sizeof(secname), "class.methods.%s_%d.attr.%d.code", tmp, iname, k);
1817  } else {
1818  snprintf(secname, sizeof(secname), "class.methods.%s.attr.%d.code", tmp, k);
1819  }
1820  ut64 size = ac->code_offset + attr->attribute_length;
1822  break;
1823  }
1824  }
1825  free(tmp);
1826  }
1827  }
1828  if (bin->attributes) {
1830  new_section("class.attr",
1831  bin->attributes_offset,
1832  bin->class_end_offset,
1833  RZ_PERM_R));
1834  }
1835 
1836  return sections;
1837 }
RzList * sections(RzBinFile *bf)
Definition: bin_ne.c:110
@ ATTRIBUTE_TYPE_CODE
static RzBinSection * new_section(const char *name, ut64 start, ut64 end, ut32 perm)
Definition: class_bin.c:1686
static int compare_section_names(const void *a, const void *b)
Definition: class_bin.c:1710
static void section_free(void *u)
Definition: class_bin.c:1706
const char * k
Definition: dsignal.c:11
#define RZ_PERM_R
Definition: rz_types.h:93
#define RZ_PERM_X
Definition: rz_types.h:95
AttributeType type
ut16 name_index
Definition: class_field.h:26
Attribute ** attributes
Definition: class_method.h:35
ut16 attributes_count
Definition: class_method.h:34
if(dbg->bits==RZ_SYS_BITS_64)
Definition: windows-arm64.h:4

References java_attribute_t::attribute_length, ATTRIBUTE_TYPE_CODE, java_method_t::attributes, java_method_t::attributes_count, java_attribute_code_t::code_offset, compare_section_names(), free(), i, if(), java_attribute_t::info, java_class_constant_pool_stringify_at(), k, java_field_t::name_index, java_method_t::name_index, new_section(), NULL, java_field_t::offset, java_method_t::offset, rz_list_append(), rz_list_find(), rz_list_newf(), RZ_PERM_R, RZ_PERM_X, rz_return_val_if_fail, rz_warn_if_reached, section_free(), sections(), snprintf, autogen_x86imm::tmp, java_attribute_t::type, and ut64().

Referenced by sections().

◆ rz_bin_java_class_as_source_code()

RZ_API void rz_bin_java_class_as_source_code ( RZ_NONNULL RzBinJavaClass bin,
RZ_NONNULL RzStrBuf sb 
)

Returns the class info as text source code.

Definition at line 708 of file class_bin.c.

708  {
710 
711  char *dem = NULL;
712  char *tmp = NULL;
713  ut16 index;
714 
715  RzListIter *iter;
717  rz_list_foreach (list, iter, tmp) {
718  rz_str_replace_char(tmp, '/', '.');
719  rz_strbuf_appendf(sb, "import %s;\n", tmp);
720  }
721  if (rz_list_length(list) > 0) {
722  rz_strbuf_appendf(sb, "\n");
723  }
725 
726  rz_strbuf_append(sb, "class");
727 
729  if (tmp) {
730  rz_strbuf_appendf(sb, " %s", tmp);
731  free(tmp);
732  }
733 
735  dem = rz_demangler_java(tmp);
736  if (dem) {
737  rz_strbuf_appendf(sb, " %s", dem);
738  RZ_FREE(dem);
739  } else {
740  rz_strbuf_appendf(sb, " %s", tmp);
741  }
742 
743  free(tmp);
744 
745  if (bin->access_flags & ACCESS_FLAG_SUPER) {
747  if (strcmp(tmp, "java/lang/Object") != 0) {
748  rz_str_replace_char(tmp, '/', '.');
749  rz_strbuf_appendf(sb, " extends %s", tmp);
750  }
751  free(tmp);
752  }
753 
754  if (bin->interfaces_count > 0) {
755  rz_strbuf_append(sb, " implements ");
756  ut32 k = 0;
757  for (ut32 i = 0; i < bin->interfaces_count; ++i) {
758  if (!bin->interfaces[i]) {
759  continue;
760  }
761  const ConstPool *cpool = java_class_constant_pool_at(bin, bin->interfaces[i]->index);
762  if (!cpool || java_constant_pool_resolve(cpool, &index, NULL) != 1) {
763  RZ_LOG_ERROR("java bin: can't resolve constant pool index %u\n", bin->interfaces[i]->index);
764  break;
765  }
767  if ((dem = rz_demangler_java(tmp))) {
768  free(tmp);
769  tmp = dem;
770  }
771  if (k > 0) {
772  rz_strbuf_appendf(sb, ", %s", tmp);
773  } else {
775  }
776  free(tmp);
777  k++;
778  }
779  if (k < 1) {
780  rz_strbuf_append(sb, "?");
781  }
782  }
783 
784  rz_strbuf_append(sb, " {\n");
785 
786  if (bin->methods) {
787  for (ut32 i = 0; i < bin->methods_count; ++i) {
788  const Method *method = bin->methods[i];
789  if (!method) {
790  continue;
791  }
792  rz_strbuf_append(sb, " ");
793 
795  if (tmp) {
796  rz_strbuf_appendf(sb, "%s ", tmp);
797  free(tmp);
798  }
799 
801  if (!name) {
802  name = strdup("?");
803  }
805  if (!desc) {
806  desc = strdup("(?)V");
807  }
808 
809  if (desc[0] == '(') {
810  tmp = rz_str_newf("%s%s", name, desc);
811  } else {
812  tmp = strdup(name);
813  }
814  free(desc);
815  free(name);
816 
817  dem = rz_demangler_java(tmp);
818  if (!dem) {
820  } else {
821  rz_strbuf_append(sb, dem);
822  RZ_FREE(dem);
823  }
824  free(tmp);
825  rz_strbuf_append(sb, ";\n");
826  }
827  }
828 
829  if (bin->methods_count > 0 && bin->fields_count) {
830  rz_strbuf_append(sb, "\n");
831  }
832 
833  if (bin->fields) {
834  for (ut32 i = 0; i < bin->fields_count; ++i) {
835  const Field *field = bin->fields[i];
836  if (!field) {
837  continue;
838  }
839  rz_strbuf_append(sb, " ");
840 
842  if (tmp) {
843  rz_strbuf_appendf(sb, "%s ", tmp);
844  free(tmp);
845  }
846 
848  if (tmp) {
849  rz_str_replace_char(tmp, '/', '.');
850  rz_strbuf_appendf(sb, "%s ", tmp);
851  free(tmp);
852  }
853 
855  if (tmp) {
856  rz_str_replace_char(tmp, '/', '.');
858  free(tmp);
859  }
860  rz_strbuf_append(sb, "\n");
861  }
862  }
863 
864  rz_strbuf_append(sb, "}\n");
865 }
const char * desc
Definition: bin_vsf.c:19
RZ_API RZ_OWN RzList * rz_bin_java_class_as_libraries(RZ_NONNULL RzBinJavaClass *bin)
Returns a RzList<char*> containing the class libraries.
Definition: class_bin.c:1846
#define ACCESS_FLAG_MASK_SRC
Definition: class_bin.c:7
@ ACCESS_FLAG_SUPER
Definition: class_bin.h:23
char * java_field_access_flags_readable(const Field *field)
Definition: class_field.c:20
char * java_method_access_flags_readable(const Method *method)
Definition: class_method.c:26
RZ_API RZ_OWN char * rz_demangler_java(RZ_NULLABLE const char *symbol)
Demangles java symbols.
Definition: demangler.c:38
RZ_API ut32 rz_list_length(RZ_NONNULL const RzList *list)
Returns the length of the list.
Definition: list.c:109
RZ_API void rz_list_free(RZ_NONNULL RzList *list)
Empties the list and frees the list pointer.
Definition: list.c:137
RZ_API int rz_str_replace_char(char *s, int a, int b)
Definition: str.c:169
RZ_API bool rz_strbuf_append(RzStrBuf *sb, const char *s)
Definition: strbuf.c:222
#define RZ_FREE(x)
Definition: rz_types.h:369
ut16 descriptor_index
Definition: class_field.h:27
ut16 descriptor_index
Definition: class_method.h:33

References ACCESS_FLAG_MASK_SRC, ACCESS_FLAG_SUPER, desc, java_field_t::descriptor_index, java_method_t::descriptor_index, free(), i, java_class_constant_pool_at(), java_class_constant_pool_stringify_at(), java_constant_pool_resolve(), java_field_access_flags_readable(), java_method_access_flags_readable(), k, list(), java_field_t::name_index, java_method_t::name_index, NULL, rz_bin_java_class_access_flags_readable(), rz_bin_java_class_as_libraries(), rz_bin_java_class_name(), rz_bin_java_class_super(), rz_demangler_java(), RZ_FREE, rz_list_free(), rz_list_length(), RZ_LOG_ERROR, rz_return_if_fail, rz_str_newf(), rz_str_replace_char(), rz_strbuf_append(), rz_strbuf_appendf(), sb, strdup(), and autogen_x86imm::tmp.

Referenced by rz_cmd_javas_handler().

◆ rz_bin_java_class_as_text()

RZ_API void rz_bin_java_class_as_text ( RZ_NONNULL RzBinJavaClass bin,
RZ_NONNULL RzStrBuf sb 
)

Returns the class info as text.

Definition at line 591 of file class_bin.c.

591  {
593  char number[16];
594  char *tmp = NULL;
595  int padding;
596 
598  rz_strbuf_appendf(sb, "Version: (%u.%u) %s\n", bin->major_version, bin->minor_version, tmp);
599  free(tmp);
600 
602  rz_strbuf_appendf(sb, "Flags: (0x%04x) %s\n", bin->access_flags, tmp);
603  free(tmp);
604 
606  rz_strbuf_appendf(sb, "Class: (#%u) %s\n", bin->this_class, tmp);
607  free(tmp);
608 
610  rz_strbuf_appendf(sb, "Super: (#%u) %s\n", bin->super_class, tmp);
611  free(tmp);
612 
617 
618  rz_strbuf_appendf(sb, "Attributes: %u\n", bin->attributes_count);
619  padding = calculate_padding_ut16(bin->attributes_count) + 1;
620  for (ut32 i = 0; i < bin->attributes_count; ++i) {
621  Attribute *attr = bin->attributes[i];
622  if (!attr) {
623  continue;
624  }
625  snprintf(number, sizeof(number), "#%u", i);
627  rz_strbuf_appendf(sb, " %-*s = #%-5u size: %-5u %s\n", padding, number, attr->attribute_name_index, attr->attribute_length, tmp);
628  free(tmp);
629  }
630 }
static int calculate_padding_ut16(ut16 count)
Definition: class_bin.c:507
RZ_API void rz_bin_java_class_interfaces_as_text(RZ_NONNULL RzBinJavaClass *bin, RZ_NONNULL RzStrBuf *sb)
Returns the class interfaces as text via RzStrBuf arg.
Definition: class_bin.c:1898
RZ_API void rz_bin_java_class_const_pool_as_text(RZ_NONNULL RzBinJavaClass *bin, RZ_NONNULL RzStrBuf *sb)
Returns the class const pool in text format via RzStrBuf arg.
Definition: class_bin.c:1605
RZ_API void rz_bin_java_class_methods_as_text(RZ_NONNULL RzBinJavaClass *bin, RZ_NONNULL RzStrBuf *sb)
Returns the methods in text format via RzStrBuf arg.
Definition: class_bin.c:1121
RZ_API void rz_bin_java_class_fields_as_text(RZ_NONNULL RzBinJavaClass *bin, RZ_NONNULL RzStrBuf *sb)
Returns the fields in text format via RzStrBuf arg.
Definition: class_bin.c:1318

References ACCESS_FLAG_MASK_ALL, java_attribute_t::attribute_length, java_attribute_t::attribute_name_index, calculate_padding_ut16(), free(), i, java_class_constant_pool_stringify_at(), NULL, rz_bin_java_class_access_flags_readable(), rz_bin_java_class_const_pool_as_text(), rz_bin_java_class_fields_as_text(), rz_bin_java_class_interfaces_as_text(), rz_bin_java_class_methods_as_text(), rz_bin_java_class_name(), rz_bin_java_class_super(), rz_bin_java_class_version(), rz_return_if_fail, rz_strbuf_appendf(), sb, snprintf, and autogen_x86imm::tmp.

Referenced by rz_cmd_javac_handler().

◆ rz_bin_java_class_const_pool_as_imports()

RZ_API RZ_OWN RzList* rz_bin_java_class_const_pool_as_imports ( RZ_NONNULL RzBinJavaClass bin)

Returns a RzList<RzBinImport*> containing the class const pool.

Definition at line 1509 of file class_bin.c.

1509  {
1511 
1513  if (!imports) {
1514  return NULL;
1515  }
1516  bool is_main;
1517  ut16 class_index, name_and_type_index, name_index, descriptor_index, class_name_index;
1518  if (bin->constant_pool) {
1519  for (ut32 i = 0; i < bin->constant_pool_count; ++i) {
1520  const ConstPool *cpool = bin->constant_pool[i];
1521  if (!cpool || !java_constant_pool_is_import(cpool)) {
1522  continue;
1523  }
1524  if (java_constant_pool_resolve(cpool, &class_index, &name_and_type_index) != 2) {
1525  RZ_LOG_ERROR("java bin: can't resolve import with constant pool index %u\n", i);
1526  continue;
1527  }
1528  const ConstPool *nat = java_class_constant_pool_at(bin, name_and_type_index);
1529  if (!nat ||
1530  java_constant_pool_resolve(nat, &name_index, &descriptor_index) != 2) {
1531  RZ_LOG_ERROR("java bin: can't resolve import with constant pool index %u\n", i);
1532  continue;
1533  }
1534  const ConstPool *pclass = java_class_constant_pool_at(bin, class_index);
1535  if (!pclass ||
1536  java_constant_pool_resolve(pclass, &class_name_index, NULL) != 1) {
1537  RZ_LOG_ERROR("java bin: can't resolve import with constant pool index %u\n", i);
1538  continue;
1539  }
1540 
1541  char *object = java_class_constant_pool_stringify_at(bin, class_name_index);
1542  if (!object) {
1543  continue;
1544  }
1545 
1546  RzBinImport *import = RZ_NEW0(RzBinImport);
1547  if (!import) {
1549  continue;
1550  }
1551 
1552  char *class_name = (char *)rz_str_rchr(object, NULL, '/');
1553  if (class_name) {
1554  class_name[0] = 0;
1555  class_name++;
1556  }
1557  rz_str_replace_ch(object, '/', '.', 1);
1558 
1559  import->classname = strdup(class_name ? class_name : object);
1560  import->libname = class_name ? strdup(object) : NULL;
1561  import->name = java_class_constant_pool_stringify_at(bin, name_index);
1562  is_main = import->name && !strcmp(import->name, "main");
1563  import->bind = is_main ? RZ_BIN_BIND_GLOBAL_STR : NULL;
1564  import->type = is_main ? RZ_BIN_TYPE_FUNC_STR : import_type(cpool);
1565  import->descriptor = java_class_constant_pool_stringify_at(bin, descriptor_index);
1566  import->ordinal = i;
1567  free(object);
1568  rz_list_append(imports, import);
1569  }
1570  }
1571 
1572  if (bin->interfaces) {
1573  for (ut32 i = 0; i < bin->interfaces_count; ++i) {
1574  if (!bin->interfaces[i]) {
1575  continue;
1576  }
1577 
1578  RzBinImport *import = RZ_NEW0(RzBinImport);
1579  if (!import) {
1581  continue;
1582  }
1583  const ConstPool *cpool = java_class_constant_pool_at(bin, bin->interfaces[i]->index);
1584  if (!cpool || java_constant_pool_resolve(cpool, &class_index, NULL) != 1) {
1585  RZ_LOG_ERROR("java bin: can't resolve interface with constant pool index %u\n", i);
1586  rz_bin_import_free(import);
1587  continue;
1588  }
1589 
1590  import->classname = java_class_constant_pool_stringify_at(bin, class_index);
1591  import->name = strdup("*");
1592  import->bind = RZ_BIN_BIND_WEAK_STR;
1593  import->type = RZ_BIN_TYPE_IFACE_STR;
1594  import->ordinal = i;
1595  rz_list_append(imports, import);
1596  }
1597  }
1598 
1599  return imports;
1600 }
RZ_API void rz_bin_import_free(RzBinImport *imp)
Definition: bin.c:137
RzList * imports(RzBinFile *bf)
Definition: bin_ne.c:106
static char * import_type(const ConstPool *cpool)
Definition: class_bin.c:1421
#define RZ_BIN_BIND_WEAK_STR
Definition: rz_bin.h:108
#define RZ_BIN_TYPE_IFACE_STR
Definition: rz_bin.h:121
#define RZ_BIN_BIND_GLOBAL_STR
Definition: rz_bin.h:107
#define RZ_BIN_TYPE_FUNC_STR
Definition: rz_bin.h:119
void(* RzListFree)(void *ptr)
Definition: rz_list.h:11
RZ_API const char * rz_str_rchr(const char *base, const char *p, int ch)
Definition: str.c:829
RZ_API int rz_str_replace_ch(char *s, char a, char b, bool g)
Definition: str.c:139

References free(), i, import_type(), imports(), java_class_constant_pool_at(), java_class_constant_pool_stringify_at(), java_constant_pool_is_import(), java_constant_pool_resolve(), NULL, RZ_BIN_BIND_GLOBAL_STR, RZ_BIN_BIND_WEAK_STR, rz_bin_import_free(), RZ_BIN_TYPE_FUNC_STR, RZ_BIN_TYPE_IFACE_STR, rz_list_append(), rz_list_newf(), RZ_LOG_ERROR, RZ_NEW0, rz_return_val_if_fail, rz_str_rchr(), rz_str_replace_ch(), rz_warn_if_reached, and strdup().

Referenced by imports().

◆ rz_bin_java_class_const_pool_as_json()

RZ_API void rz_bin_java_class_const_pool_as_json ( RZ_NONNULL RzBinJavaClass bin,
RZ_NONNULL PJ j 
)

Returns the class const pool in json format via PJ arg.

Definition at line 1650 of file class_bin.c.

1650  {
1651  rz_return_if_fail(bin && j);
1652  const char *tag;
1653  char *text, *rtext;
1654  pj_a(j);
1655  if (bin->constant_pool) {
1656  for (ut32 i = 0; i < bin->constant_pool_count; ++i) {
1657  rtext = NULL;
1658  const ConstPool *cpool = bin->constant_pool[i];
1659  if (!cpool) {
1660  continue;
1661  }
1663  if (!tag) {
1664  RZ_LOG_ERROR("java bin: invalid tag name for constant pool at index %u\n", i);
1665  continue;
1666  }
1668  pj_o(j);
1669  pj_kn(j, "index", i);
1670  pj_kn(j, "tag_n", cpool->tag);
1671  pj_ks(j, "tag_s", tag);
1672  pj_ks(j, "value", text ? text : "");
1673  if (i > 0 && !java_constant_pool_is_string(cpool) &&
1674  !java_constant_pool_is_number(cpool)) {
1676  pj_ks(j, "resolved", rtext ? rtext : "");
1677  }
1678  pj_end(j);
1679  free(text);
1680  free(rtext);
1681  }
1682  }
1683  pj_end(j);
1684 }
RZ_API RZ_OWN char * rz_bin_java_class_const_pool_resolve_index(RZ_NONNULL RzBinJavaClass *bin, st32 index)
Returns the string linked to the class const pool index.
Definition: class_bin.c:644
bool java_constant_pool_is_string(const ConstPool *cpool)
const char * java_constant_pool_tag_name(const ConstPool *cpool)
bool java_constant_pool_is_number(const ConstPool *cpool)
RZ_API PJ * pj_a(PJ *j)
Definition: pj.c:81

References free(), i, java_constant_pool_is_number(), java_constant_pool_is_string(), java_constant_pool_stringify(), java_constant_pool_tag_name(), NULL, pj_a(), pj_end(), pj_kn(), pj_ks(), pj_o(), rz_bin_java_class_const_pool_resolve_index(), RZ_LOG_ERROR, rz_return_if_fail, java_constant_pool_t::tag, test-lz4-versions::tag, and create_tags_rz::text.

Referenced by rz_bin_java_class_as_json(), and rz_cmd_javap_handler().

◆ rz_bin_java_class_const_pool_as_symbols()

RZ_API RZ_OWN RzList* rz_bin_java_class_const_pool_as_symbols ( RZ_NONNULL RzBinJavaClass bin)

Returns a RzList<RzBinSymbol*> containing the class const pool.

Definition at line 1435 of file class_bin.c.

1435  {
1437 
1439  if (!list) {
1440  return NULL;
1441  }
1442  char *method_name, *classname;
1443  bool is_main;
1444  ut16 class_index, name_and_type_index, name_index, descriptor_index, class_name_index;
1445  if (bin->constant_pool) {
1446  for (ut32 i = 0; i < bin->constant_pool_count; ++i) {
1447  const ConstPool *cpool = bin->constant_pool[i];
1448  if (!cpool || !java_constant_pool_is_import(cpool)) {
1449  continue;
1450  }
1451  if (java_constant_pool_resolve(cpool, &class_index, &name_and_type_index) != 2) {
1452  RZ_LOG_ERROR("java bin: can't resolve symbol with constant pool index %u\n", i);
1453  break;
1454  }
1455  const ConstPool *nat = java_class_constant_pool_at(bin, name_and_type_index);
1456  if (!nat ||
1457  java_constant_pool_resolve(nat, &name_index, &descriptor_index) != 2) {
1458  RZ_LOG_ERROR("java bin: can't resolve symbol with constant pool index %u\n", i);
1459  break;
1460  }
1461  const ConstPool *pclass = java_class_constant_pool_at(bin, class_index);
1462  if (!pclass ||
1463  java_constant_pool_resolve(pclass, &class_name_index, NULL) != 1) {
1464  RZ_LOG_ERROR("java bin: can't resolve symbol with constant pool index %u\n", i);
1465  break;
1466  }
1467  RzBinSymbol *symbol = rz_bin_symbol_new(NULL, cpool->offset, cpool->offset);
1468  if (!symbol) {
1470  break;
1471  }
1472 
1473  char *desc = java_class_constant_pool_stringify_at(bin, descriptor_index);
1474  if (!desc) {
1475  desc = strdup("(?)V");
1476  }
1477 
1478  method_name = java_class_constant_pool_stringify_at(bin, name_index);
1479  if (!method_name) {
1480  method_name = strdup("unknown_method");
1481  }
1482  is_main = !strcmp(method_name, "main");
1483  classname = java_class_constant_pool_stringify_at(bin, class_name_index);
1484  symbol->name = add_class_name_to_name(method_name, symbol->classname);
1485  if (desc[0] == '(') {
1486  symbol->dname = rz_str_newf("%s%s", method_name, desc);
1487  } else {
1488  symbol->dname = strdup(method_name);
1489  }
1490  symbol->classname = rz_str_newf("L%s;", classname);
1491  symbol->libname = classname;
1492  rz_str_replace_ch(symbol->libname, '/', '.', 1);
1493  symbol->bind = RZ_BIN_BIND_IMPORT_STR;
1494  symbol->type = is_main ? RZ_BIN_TYPE_FUNC_STR : import_type(cpool);
1495  symbol->ordinal = i;
1496  symbol->is_imported = true;
1497  free(desc);
1498  free(method_name);
1499  rz_list_append(list, symbol);
1500  }
1501  }
1502 
1503  return list;
1504 }
RZ_API RzBinSymbol * rz_bin_symbol_new(const char *name, ut64 paddr, ut64 vaddr)
Definition: bin.c:165
RZ_API void rz_bin_symbol_free(RzBinSymbol *sym)
Definition: bin.c:175
static char * add_class_name_to_name(char *name, char *classname)
Definition: class_bin.c:1042
#define RZ_BIN_BIND_IMPORT_STR
Definition: rz_bin.h:114
const char * bind
Definition: rz_bin.h:681
bool is_imported
Definition: rz_bin.h:684
const char * type
Definition: rz_bin.h:682
char * name
Definition: rz_bin.h:675
char * classname
Definition: rz_bin.h:678
ut32 ordinal
Definition: rz_bin.h:692
char * dname
Definition: rz_bin.h:676
char * libname
Definition: rz_bin.h:677

References add_class_name_to_name(), rz_bin_symbol_t::bind, rz_bin_symbol_t::classname, desc, rz_bin_symbol_t::dname, free(), i, import_type(), rz_bin_symbol_t::is_imported, java_class_constant_pool_at(), java_class_constant_pool_stringify_at(), java_constant_pool_is_import(), java_constant_pool_resolve(), rz_bin_symbol_t::libname, list(), rz_bin_symbol_t::name, NULL, java_constant_pool_t::offset, rz_bin_symbol_t::ordinal, RZ_BIN_BIND_IMPORT_STR, rz_bin_symbol_free(), rz_bin_symbol_new(), RZ_BIN_TYPE_FUNC_STR, rz_list_append(), rz_list_newf(), RZ_LOG_ERROR, rz_return_val_if_fail, rz_str_newf(), rz_str_replace_ch(), rz_warn_if_reached, strdup(), and rz_bin_symbol_t::type.

Referenced by symbols().

◆ rz_bin_java_class_const_pool_as_text()

RZ_API void rz_bin_java_class_const_pool_as_text ( RZ_NONNULL RzBinJavaClass bin,
RZ_NONNULL RzStrBuf sb 
)

Returns the class const pool in text format via RzStrBuf arg.

Definition at line 1605 of file class_bin.c.

1605  {
1606  rz_return_if_fail(bin && sb);
1607 
1608  char number[16];
1609  const char *tag;
1610  char *text, *rtext;
1611  rz_strbuf_appendf(sb, "Constant pool: %u\n", bin->constant_pool_count);
1612  if (bin->constant_pool) {
1613  int padding = calculate_padding_ut16(bin->constant_pool_count) + 1;
1614  for (ut32 i = 0; i < bin->constant_pool_count; ++i) {
1615  rtext = NULL;
1616  const ConstPool *cpool = bin->constant_pool[i];
1617  if (!cpool) {
1618  continue;
1619  }
1621  if (!tag) {
1622  RZ_LOG_ERROR("java bin: invalid tag name for constant pool at index %u\n", i);
1623  continue;
1624  }
1625  snprintf(number, sizeof(number), "#%u", i);
1627  if (i > 0 && !java_constant_pool_is_string(cpool) &&
1628  !java_constant_pool_is_number(cpool)) {
1630  }
1631  if (rtext) {
1632  char *dem = rz_demangler_java(rtext);
1633  if (dem) {
1634  free(rtext);
1635  rtext = dem;
1636  }
1637  rz_strbuf_appendf(sb, " %*s = %-19s %-14s // %s\n", padding, number, tag, text, rtext);
1638  } else {
1639  rz_strbuf_appendf(sb, " %*s = %-19s %s\n", padding, number, tag, text);
1640  }
1641  free(text);
1642  free(rtext);
1643  }
1644  }
1645 }

References calculate_padding_ut16(), free(), i, java_constant_pool_is_number(), java_constant_pool_is_string(), java_constant_pool_stringify(), java_constant_pool_tag_name(), NULL, rz_bin_java_class_const_pool_resolve_index(), rz_demangler_java(), RZ_LOG_ERROR, rz_return_if_fail, rz_strbuf_appendf(), sb, snprintf, test-lz4-versions::tag, and create_tags_rz::text.

Referenced by rz_bin_java_class_as_text(), and rz_cmd_javap_handler().

◆ rz_bin_java_class_const_pool_resolve_index()

RZ_API RZ_OWN char* rz_bin_java_class_const_pool_resolve_index ( RZ_NONNULL RzBinJavaClass bin,
st32  index 
)

Returns the string linked to the class const pool index.

Definition at line 644 of file class_bin.c.

644  {
645  rz_return_val_if_fail(bin && index >= 0, NULL);
646  ut16 arg0, arg1;
647  char *tmp;
648  const ConstPool *cpool = java_class_constant_pool_at(bin, index);
649 
650  if (!cpool || !index) {
651  return NULL;
652  }
653  if (java_constant_pool_is_string(cpool) ||
655  return java_constant_pool_stringify(cpool);
656  } else if (cpool->tag == CONSTANT_POOL_CLASS) {
657  if (java_constant_pool_resolve(cpool, &arg0, NULL) != 1) {
658  RZ_LOG_ERROR("java bin: can't resolve constant pool index %u\n", index);
659  return NULL;
660  }
662  if (tmp[0] == '[' && tmp[1] == 'L') {
663  return tmp;
664  }
665  char *res = rz_str_newf("L%s;", tmp);
666  free(tmp);
667  return res;
668  } else if (cpool->tag == CONSTANT_POOL_STRING) {
669  if (java_constant_pool_resolve(cpool, &arg0, NULL) != 1) {
670  RZ_LOG_ERROR("java bin: can't resolve constant pool index %u\n", index);
671  return NULL;
672  }
674  tmp = rz_str_newf("\"%s\"", s0);
675  free(s0);
676  return tmp;
677  } else if (is_dual_index(cpool)) {
678  if (java_constant_pool_resolve(cpool, &arg0, &arg1) != 2) {
679  RZ_LOG_ERROR("java bin: can't resolve constant pool index %u\n", index);
680  return NULL;
681  }
682  char *s0 = arg0 ? rz_bin_java_class_const_pool_resolve_index(bin, arg0) : NULL;
684  if ((arg0 && !s0) || !s1) {
685  RZ_LOG_ERROR("java bin: can't resolve constant pool index %u\n", index);
686  free(s0);
687  free(s1);
688  return NULL;
689  }
690  if (!arg0) {
691  return s1;
692  }
693  if (s1[0] == '(') {
694  tmp = rz_str_newf("%s%s", s0, s1);
695  } else {
696  tmp = rz_str_newf("%s.%s", s0, s1);
697  }
698  free(s0);
699  free(s1);
700  return tmp;
701  }
702  return NULL;
703 }
static bool is_dual_index(const ConstPool *cpool)
Definition: class_bin.c:632
@ CONSTANT_POOL_STRING
#define s0(x)
Definition: sha256.c:59
#define s1(x)
Definition: sha256.c:60

References CONSTANT_POOL_CLASS, CONSTANT_POOL_STRING, free(), is_dual_index(), java_class_constant_pool_at(), java_constant_pool_is_number(), java_constant_pool_is_string(), java_constant_pool_resolve(), java_constant_pool_stringify(), NULL, RZ_LOG_ERROR, rz_return_val_if_fail, rz_str_newf(), s0, s1, java_constant_pool_t::tag, and autogen_x86imm::tmp.

Referenced by enrich_asm(), rz_bin_java_class_const_pool_as_json(), rz_bin_java_class_const_pool_as_text(), and rz_cmd_javar_handler().

◆ rz_bin_java_class_debug_info()

RZ_API ut64 rz_bin_java_class_debug_info ( RZ_NONNULL RzBinJavaClass bin)

Definition at line 351 of file class_bin.c.

351  {
352  if (!bin) {
353  return 0;
354  }
355  if (bin->methods) {
356  for (ut32 i = 0; i < bin->methods_count; ++i) {
357  Method *method = bin->methods[i];
358  if (!method || method->attributes_count < 1) {
359  continue;
360  }
361  for (ut32 k = 0; k < method->attributes_count; ++k) {
362  Attribute *attr = method->attributes[k];
363  if (attr && attr->type == ATTRIBUTE_TYPE_CODE) {
364  AttributeCode *ac = (AttributeCode *)attr->info;
365  for (ut32 k = 0; k < ac->attributes_count; k++) {
366  Attribute *cattr = ac->attributes[k];
367  if (cattr && cattr->type == ATTRIBUTE_TYPE_LINENUMBERTABLE) {
369  }
370  }
371  }
372  }
373  }
374  }
375  return RZ_BIN_DBG_SYMS;
376 }
@ ATTRIBUTE_TYPE_LINENUMBERTABLE
#define RZ_BIN_DBG_SYMS
Definition: rz_bin.h:30
#define RZ_BIN_DBG_LINENUMS
Definition: rz_bin.h:29

References ATTRIBUTE_TYPE_CODE, ATTRIBUTE_TYPE_LINENUMBERTABLE, java_attribute_code_t::attributes, java_method_t::attributes, java_attribute_code_t::attributes_count, java_method_t::attributes_count, i, java_attribute_t::info, k, RZ_BIN_DBG_LINENUMS, RZ_BIN_DBG_SYMS, and java_attribute_t::type.

Referenced by info().

◆ rz_bin_java_class_entrypoints()

RZ_API RZ_OWN RzList* rz_bin_java_class_entrypoints ( RZ_NONNULL RzBinJavaClass bin)

Returns a RzList<RzBinAddr*> containing the entrypoints.

Definition at line 927 of file class_bin.c.

927  {
929 
931  if (!list) {
932  return NULL;
933  }
934 
935  char *name = NULL;
936  bool is_static;
937  if (bin->methods) {
938  for (ut32 i = 0; i < bin->methods_count; ++i) {
939  const Method *method = bin->methods[i];
940  if (!method) {
942  continue;
943  }
944  is_static = method->access_flags & METHOD_ACCESS_FLAG_STATIC;
945  if (!is_static) {
947  if (!name) {
948  continue;
949  }
950  if (strcmp(name, "main") != 0 && strcmp(name, "<init>") != 0 && strcmp(name, "<clinit>") != 0) {
951  free(name);
952  continue;
953  }
954  free(name);
955  }
956 
957  ut64 addr = UT64_MAX;
958  for (ut32 i = 0; i < method->attributes_count; ++i) {
959  Attribute *attr = method->attributes[i];
960  if (attr && attr->type == ATTRIBUTE_TYPE_CODE) {
961  AttributeCode *ac = (AttributeCode *)attr->info;
962  addr = ac->code_offset;
963  break;
964  }
965  }
966  if (addr == UT64_MAX) {
967  RZ_LOG_ERROR("java bin: can't resolve entrypoint address\n");
968  continue;
969  }
970 
971  RzBinAddr *entrypoint = RZ_NEW0(RzBinAddr);
972  if (!entrypoint) {
974  continue;
975  }
976  entrypoint->vaddr = entrypoint->paddr = addr;
977  rz_list_append(list, entrypoint);
978  }
979  }
980  return list;
981 }
@ METHOD_ACCESS_FLAG_STATIC
Definition: class_method.h:15
#define UT64_MAX
Definition: rz_types_base.h:86
ut64 vaddr
Definition: rz_bin.h:186
ut64 paddr
Definition: rz_bin.h:187
static int addr
Definition: z80asm.c:58

References java_method_t::access_flags, addr, ATTRIBUTE_TYPE_CODE, java_method_t::attributes, java_method_t::attributes_count, java_attribute_code_t::code_offset, free(), i, java_attribute_t::info, java_class_constant_pool_stringify_at(), list(), METHOD_ACCESS_FLAG_STATIC, java_method_t::name_index, NULL, rz_bin_addr_t::paddr, rz_list_append(), rz_list_newf(), RZ_LOG_ERROR, RZ_NEW0, rz_return_val_if_fail, rz_warn_if_reached, java_attribute_t::type, ut64(), UT64_MAX, and rz_bin_addr_t::vaddr.

Referenced by entrypoints().

◆ rz_bin_java_class_fields_as_binfields()

RZ_API RZ_OWN RzList* rz_bin_java_class_fields_as_binfields ( RZ_NONNULL RzBinJavaClass bin)

Returns a RzList<RzBinField*> containing the class fields.

Definition at line 1277 of file class_bin.c.

1277  {
1279 
1281  if (!list) {
1282  return NULL;
1283  }
1284 
1285  char *name = NULL;
1286  if (bin->fields) {
1287  for (ut32 i = 0; i < bin->fields_count; ++i) {
1288  const Field *field = bin->fields[i];
1289  if (!field) {
1291  continue;
1292  }
1293  const ConstPool *cpool = java_class_constant_pool_at(bin, field->name_index);
1294  if (!cpool || !java_constant_pool_is_string(cpool)) {
1295  RZ_LOG_ERROR("java bin: can't resolve field with constant pool index %u\n", field->name_index);
1296  continue;
1297  }
1299  if (!name) {
1300  continue;
1301  }
1302  RzBinField *bf = rz_bin_field_new(field->offset, field->offset, 0, name, NULL, NULL, false);
1303  if (bf) {
1304  bf->visibility = field->access_flags;
1307  rz_list_append(list, bf);
1308  }
1309  free(name);
1310  }
1311  }
1312  return list;
1313 }
RZ_API void rz_bin_field_free(RzBinField *field)
Definition: bin.c:950
RZ_API RzBinField * rz_bin_field_new(ut64 paddr, ut64 vaddr, int size, const char *name, const char *comment, const char *format, bool format_named)
Definition: bin.c:935
static ut64 java_access_flags_to_bin_flags(ut64 access_flags)
Definition: class_bin.c:29
ut16 access_flags
Definition: class_field.h:25
ut64 flags
Definition: rz_bin.h:773
ut32 visibility
Definition: rz_bin.h:766
char * type
Definition: rz_bin.h:768

References java_field_t::access_flags, java_field_t::descriptor_index, rz_bin_field_t::flags, free(), i, java_access_flags_to_bin_flags(), java_class_constant_pool_at(), java_class_constant_pool_stringify_at(), java_constant_pool_is_string(), java_constant_pool_stringify(), list(), java_field_t::name_index, NULL, java_field_t::offset, rz_bin_field_free(), rz_bin_field_new(), rz_list_append(), rz_list_newf(), RZ_LOG_ERROR, rz_return_val_if_fail, rz_warn_if_reached, rz_bin_field_t::type, and rz_bin_field_t::visibility.

Referenced by classes(), and fields().

◆ rz_bin_java_class_fields_as_json()

RZ_API void rz_bin_java_class_fields_as_json ( RZ_NONNULL RzBinJavaClass bin,
RZ_NONNULL PJ j 
)

Returns the fields in json format via PJ arg.

Definition at line 1366 of file class_bin.c.

1366  {
1367  rz_return_if_fail(bin && j);
1368 
1369  pj_a(j);
1370 
1371  char *tmp;
1372  if (bin->fields) {
1373  for (ut32 i = 0; i < bin->fields_count; ++i) {
1374  const Field *field = bin->fields[i];
1375  if (!field) {
1377  continue;
1378  }
1379  pj_o(j); // {
1380 
1381  pj_kn(j, "offset", field->offset);
1382 
1383  pj_kn(j, "access_flags_n", field->access_flags);
1385  pj_ks(j, "access_flags_s", tmp ? tmp : "");
1386  free(tmp);
1387 
1388  pj_kn(j, "name_n", field->name_index);
1390  pj_ks(j, "name_s", tmp ? tmp : "");
1391  free(tmp);
1392 
1393  pj_kn(j, "descriptor_n", field->descriptor_index);
1395  pj_ks(j, "descriptor_s", tmp ? tmp : "");
1396  free(tmp);
1397 
1398  pj_kn(j, "attributes_count", field->attributes_count);
1399  pj_ka(j, "attributes"); // [
1400  for (ut32 i = 0; i < field->attributes_count; ++i) {
1401  Attribute *attr = field->attributes[i];
1402  if (!attr) {
1403  continue;
1404  }
1405  pj_o(j);
1406  pj_kn(j, "offset", attr->offset);
1407  pj_kn(j, "size", attr->attribute_length);
1408  pj_kn(j, "name_n", attr->attribute_name_index);
1410  pj_ks(j, "name_s", tmp ? tmp : "");
1411  free(tmp);
1412  pj_end(j);
1413  }
1414  pj_end(j); // ]
1415  pj_end(j); // }
1416  }
1417  }
1418  pj_end(j);
1419 }
Attribute ** attributes
Definition: class_field.h:29
ut16 attributes_count
Definition: class_field.h:28

References java_field_t::access_flags, java_attribute_t::attribute_length, java_attribute_t::attribute_name_index, java_field_t::attributes, java_field_t::attributes_count, java_field_t::descriptor_index, free(), i, java_class_constant_pool_stringify_at(), java_field_access_flags_readable(), java_field_t::name_index, java_attribute_t::offset, java_field_t::offset, pj_a(), pj_end(), pj_ka(), pj_kn(), pj_ks(), pj_o(), rz_return_if_fail, rz_warn_if_reached, and autogen_x86imm::tmp.

Referenced by rz_bin_java_class_as_json(), and rz_cmd_javaf_handler().

◆ rz_bin_java_class_fields_as_symbols()

RZ_API RZ_OWN RzList* rz_bin_java_class_fields_as_symbols ( RZ_NONNULL RzBinJavaClass bin)

Returns a RzList<RzBinSymbol*> containing the class fields.

Definition at line 1227 of file class_bin.c.

1227  {
1229 
1231  if (!list) {
1232  return NULL;
1233  }
1234 
1235  char *field_name = NULL;
1236  if (bin->fields) {
1237  for (ut32 i = 0; i < bin->fields_count; ++i) {
1238  const Field *field = bin->fields[i];
1239  if (!field) {
1241  continue;
1242  }
1243  const ConstPool *cpool = java_class_constant_pool_at(bin, field->name_index);
1244  if (!cpool || !java_constant_pool_is_string(cpool)) {
1245  RZ_LOG_ERROR("java bin: can't resolve field with constant pool index %u\n", field->name_index);
1246  continue;
1247  }
1249  if (!field_name) {
1250  continue;
1251  }
1252  RzBinSymbol *symbol = rz_bin_symbol_new(NULL, field->offset, field->offset);
1253  if (!symbol) {
1255  free(field_name);
1256  continue;
1257  }
1259  symbol->name = add_class_name_to_name(field_name, symbol->classname);
1260  symbol->size = 0;
1262  symbol->type = RZ_BIN_TYPE_OBJECT_STR;
1263  symbol->ordinal = i;
1264  symbol->visibility = field->access_flags;
1267  free(field_name);
1268  rz_list_append(list, symbol);
1269  }
1270  }
1271  return list;
1272 }
bool java_field_is_global(const Field *field)
Definition: class_field.c:91
@ field_name
Definition: parser.c:1737
#define RZ_BIN_TYPE_OBJECT_STR
Definition: rz_bin.h:118
#define RZ_BIN_BIND_LOCAL_STR
Definition: rz_bin.h:106
char * visibility_str
Definition: rz_bin.h:686
ut64 method_flags
Definition: rz_bin.h:696
ut32 visibility
Definition: rz_bin.h:693

References java_field_t::access_flags, add_class_name_to_name(), rz_bin_symbol_t::bind, rz_bin_symbol_t::classname, field_name, free(), i, java_access_flags_to_bin_flags(), java_class_constant_pool_at(), java_constant_pool_is_string(), java_constant_pool_stringify(), java_field_access_flags_readable(), java_field_is_global(), list(), rz_bin_symbol_t::method_flags, rz_bin_symbol_t::name, java_field_t::name_index, NULL, java_field_t::offset, rz_bin_symbol_t::ordinal, RZ_BIN_BIND_GLOBAL_STR, RZ_BIN_BIND_LOCAL_STR, rz_bin_java_class_name(), rz_bin_symbol_free(), rz_bin_symbol_new(), RZ_BIN_TYPE_OBJECT_STR, rz_list_append(), rz_list_newf(), RZ_LOG_ERROR, rz_return_val_if_fail, rz_warn_if_reached, rz_bin_symbol_t::size, rz_bin_symbol_t::type, rz_bin_symbol_t::visibility, and rz_bin_symbol_t::visibility_str.

Referenced by symbols().

◆ rz_bin_java_class_fields_as_text()

RZ_API void rz_bin_java_class_fields_as_text ( RZ_NONNULL RzBinJavaClass bin,
RZ_NONNULL RzStrBuf sb 
)

Returns the fields in text format via RzStrBuf arg.

Definition at line 1318 of file class_bin.c.

1318  {
1319  rz_return_if_fail(bin && sb);
1320 
1321  rz_strbuf_appendf(sb, "Fields: %u\n", bin->fields_count);
1322  char number[16];
1323  char *flags, *name, *descr;
1324  if (bin->fields) {
1325  for (ut32 i = 0; i < bin->fields_count; ++i) {
1326  const Field *field = bin->fields[i];
1327  if (!field) {
1329  continue;
1330  }
1334 
1335  if (flags) {
1336  rz_strbuf_appendf(sb, " %s %s%s;\n", flags, name, descr);
1337  } else {
1338  rz_strbuf_appendf(sb, " %s%s;\n", name, descr);
1339  }
1340  rz_strbuf_appendf(sb, " name: %s\n", name);
1341  rz_strbuf_appendf(sb, " descriptor: %s\n", descr);
1342  rz_strbuf_appendf(sb, " flags: (0x%04x) %s\n", field->access_flags, flags);
1343 
1344  free(flags);
1345  free(name);
1346  free(descr);
1347  rz_strbuf_appendf(sb, " attributes: %u\n", field->attributes_count);
1348  int padding = calculate_padding_ut16(field->attributes_count) + 1;
1349  for (ut32 i = 0; i < field->attributes_count; ++i) {
1350  Attribute *attr = field->attributes[i];
1351  if (!attr) {
1352  continue;
1353  }
1354  snprintf(number, sizeof(number), "#%u", i);
1356  rz_strbuf_appendf(sb, " %*s = #%-5u size: %-5u %s\n", padding, number, attr->attribute_name_index, attr->attribute_length, name);
1357  free(name);
1358  }
1359  }
1360  }
1361 }
const char * name
Definition: op.c:541

References java_field_t::access_flags, java_attribute_t::attribute_length, java_attribute_t::attribute_name_index, java_field_t::attributes, java_field_t::attributes_count, calculate_padding_ut16(), java_field_t::descriptor_index, flags, free(), i, java_class_constant_pool_stringify_at(), java_field_access_flags_readable(), name, java_field_t::name_index, rz_return_if_fail, rz_strbuf_appendf(), rz_warn_if_reached, sb, and snprintf.

Referenced by rz_bin_java_class_as_text(), and rz_cmd_javaf_handler().

◆ rz_bin_java_class_free()

RZ_API void rz_bin_java_class_free ( RZ_NULLABLE RzBinJavaClass bin)

Frees a RzBinJavaClass pointer.

Definition at line 407 of file class_bin.c.

407  {
408  if (!bin) {
409  return;
410  }
411  if (bin->constant_pool) {
412  for (ut32 i = 0; i < bin->constant_pool_count; ++i) {
413  java_constant_pool_free(bin->constant_pool[i]);
414  }
415  free(bin->constant_pool);
416  }
417  if (bin->interfaces) {
418  for (ut32 i = 0; i < bin->interfaces_count; ++i) {
419  java_interface_free(bin->interfaces[i]);
420  }
421  free(bin->interfaces);
422  }
423  if (bin->fields) {
424  for (ut32 i = 0; i < bin->fields_count; ++i) {
425  java_field_free(bin->fields[i]);
426  }
427  free(bin->fields);
428  }
429  if (bin->methods) {
430  for (ut32 i = 0; i < bin->methods_count; ++i) {
431  java_method_free(bin->methods[i]);
432  }
433  free(bin->methods);
434  }
435  if (bin->attributes) {
436  for (ut32 i = 0; i < bin->attributes_count; ++i) {
437  java_attribute_free(bin->attributes[i]);
438  }
439  free(bin->attributes);
440  }
441  free(bin);
442 }
void java_constant_pool_free(ConstPool *cpool)
void java_field_free(Field *field)
Definition: class_field.c:78
#define java_interface_free(x)
void java_method_free(Method *method)
Definition: class_method.c:89

References free(), i, java_attribute_free(), java_constant_pool_free(), java_field_free(), java_interface_free, and java_method_free().

Referenced by destroy(), and java_class_parse().

◆ rz_bin_java_class_interfaces_as_json()

RZ_API void rz_bin_java_class_interfaces_as_json ( RZ_NONNULL RzBinJavaClass bin,
RZ_NONNULL PJ j 
)

Returns the class interfaces as json via PJ arg.

Definition at line 1928 of file class_bin.c.

1928  {
1929  rz_return_if_fail(bin && j);
1930  pj_a(j);
1931  char *tmp = NULL;
1932  ut16 index;
1933  if (bin->interfaces) {
1934  for (ut32 i = 0; i < bin->interfaces_count; ++i) {
1935  if (!bin->interfaces[i]) {
1936  continue;
1937  }
1938 
1939  const ConstPool *cpool = java_class_constant_pool_at(bin, bin->interfaces[i]->index);
1940  if (!cpool || java_constant_pool_resolve(cpool, &index, NULL) != 1) {
1941  RZ_LOG_ERROR("java bin: can't resolve interface with constant pool index %u\n", i);
1942  continue;
1943  }
1944  pj_o(j);
1945  pj_kn(j, "offset", bin->interfaces[i]->offset);
1946  pj_kn(j, "name_n", bin->interfaces[i]->index);
1948  rz_str_replace_char(tmp, '/', '.');
1949  pj_ks(j, "name_s", tmp ? tmp : "");
1950  free(tmp);
1951  pj_end(j);
1952  }
1953  }
1954  pj_end(j);
1955 }

References free(), i, java_class_constant_pool_at(), java_class_constant_pool_stringify_at(), java_constant_pool_resolve(), NULL, pj_a(), pj_end(), pj_kn(), pj_ks(), pj_o(), RZ_LOG_ERROR, rz_return_if_fail, rz_str_replace_char(), and autogen_x86imm::tmp.

Referenced by rz_bin_java_class_as_json(), and rz_cmd_javai_handler().

◆ rz_bin_java_class_interfaces_as_text()

RZ_API void rz_bin_java_class_interfaces_as_text ( RZ_NONNULL RzBinJavaClass bin,
RZ_NONNULL RzStrBuf sb 
)

Returns the class interfaces as text via RzStrBuf arg.

Definition at line 1898 of file class_bin.c.

1898  {
1899  rz_return_if_fail(bin && sb);
1900 
1901  ut16 index;
1902  char number[16];
1903  char *tmp = NULL;
1904  rz_strbuf_appendf(sb, "Interfaces: %u\n", bin->interfaces_count);
1905  if (bin->interfaces) {
1906  int padding = calculate_padding_ut16(bin->constant_pool_count) + 1;
1907  for (ut32 i = 0; i < bin->interfaces_count; ++i) {
1908  if (!bin->interfaces[i]) {
1909  continue;
1910  }
1911  const ConstPool *cpool = java_class_constant_pool_at(bin, bin->interfaces[i]->index);
1912  if (!cpool || java_constant_pool_resolve(cpool, &index, NULL) != 1) {
1913  RZ_LOG_ERROR("java bin: can't resolve interface with constant pool index %u\n", i);
1914  break;
1915  }
1916  snprintf(number, sizeof(number), "#%u", i);
1918  rz_str_replace_char(tmp, '/', '.');
1919  rz_strbuf_appendf(sb, " %*s = #%-5u %s\n", padding, number, index, tmp);
1920  free(tmp);
1921  }
1922  }
1923 }

References calculate_padding_ut16(), free(), i, java_class_constant_pool_at(), java_class_constant_pool_stringify_at(), java_constant_pool_resolve(), NULL, RZ_LOG_ERROR, rz_return_if_fail, rz_str_replace_char(), rz_strbuf_appendf(), sb, snprintf, and autogen_x86imm::tmp.

Referenced by rz_bin_java_class_as_text(), and rz_cmd_javai_handler().

◆ rz_bin_java_class_language()

RZ_API RZ_BORROW const char* rz_bin_java_class_language ( RZ_NONNULL RzBinJavaClass bin)

Definition at line 378 of file class_bin.c.

378  {
380  const char *language = "java";
381  char *string = NULL;
382  if (bin->constant_pool) {
383  for (ut32 i = 0; i < bin->constant_pool_count; ++i) {
384  const ConstPool *cpool = bin->constant_pool[i];
385  if (!cpool || !java_constant_pool_is_string(cpool)) {
386  continue;
387  }
388  string = java_constant_pool_stringify(cpool);
389  if (string && !strncmp(string, "kotlin/jvm", 10)) {
390  language = "kotlin";
391  break;
392  } else if (string && !strncmp(string, "org/codehaus/groovy/runtime", 27)) {
393  language = "groovy";
394  break;
395  }
396  free(string);
397  string = NULL;
398  }
399  }
400  free(string);
401  return language;
402 }

References free(), i, java_constant_pool_is_string(), java_constant_pool_stringify(), NULL, and rz_return_val_if_fail.

Referenced by info().

◆ rz_bin_java_class_methods_as_json()

RZ_API void rz_bin_java_class_methods_as_json ( RZ_NONNULL RzBinJavaClass bin,
RZ_NONNULL PJ j 
)

Returns the methods in json format via PJ arg.

Definition at line 1169 of file class_bin.c.

1169  {
1170  rz_return_if_fail(bin && j);
1171 
1172  pj_a(j);
1173 
1174  char *tmp;
1175  if (bin->methods) {
1176  for (ut32 i = 0; i < bin->methods_count; ++i) {
1177  const Method *method = bin->methods[i];
1178  if (!method) {
1180  continue;
1181  }
1182  pj_o(j); // {
1183  pj_kn(j, "offset", method->offset);
1184 
1185  pj_kn(j, "access_flags_n", method->access_flags);
1187  pj_ks(j, "access_flags_s", tmp ? tmp : "");
1188  free(tmp);
1189 
1190  pj_kn(j, "name_n", method->name_index);
1192  pj_ks(j, "name_s", tmp ? tmp : "");
1193  free(tmp);
1194 
1195  pj_kn(j, "descriptor_n", method->descriptor_index);
1197  pj_ks(j, "descriptor_s", tmp ? tmp : "");
1198  free(tmp);
1199 
1200  pj_kn(j, "attributes_count", method->attributes_count);
1201  pj_ka(j, "attributes"); // [
1202  for (ut32 i = 0; i < method->attributes_count; ++i) {
1203  Attribute *attr = method->attributes[i];
1204  if (!attr) {
1206  continue;
1207  }
1208  pj_o(j);
1209  pj_kn(j, "offset", attr->offset);
1210  pj_kn(j, "size", attr->attribute_length);
1211  pj_kn(j, "name_n", attr->attribute_name_index);
1213  pj_ks(j, "name_s", tmp ? tmp : "");
1214  free(tmp);
1215  pj_end(j);
1216  }
1217  pj_end(j); // ]
1218  pj_end(j); // }
1219  }
1220  }
1221  pj_end(j);
1222 }

References java_method_t::access_flags, java_attribute_t::attribute_length, java_attribute_t::attribute_name_index, java_method_t::attributes, java_method_t::attributes_count, java_method_t::descriptor_index, free(), i, java_class_constant_pool_stringify_at(), java_method_access_flags_readable(), java_method_t::name_index, java_attribute_t::offset, java_method_t::offset, pj_a(), pj_end(), pj_ka(), pj_kn(), pj_ks(), pj_o(), rz_return_if_fail, rz_warn_if_reached, and autogen_x86imm::tmp.

Referenced by rz_bin_java_class_as_json(), and rz_cmd_javam_handler().

◆ rz_bin_java_class_methods_as_symbols()

RZ_API RZ_OWN RzList* rz_bin_java_class_methods_as_symbols ( RZ_NONNULL RzBinJavaClass bin)

Returns a RzList<RzBinSymbol*> containing the class methods.

Definition at line 1052 of file class_bin.c.

1052  {
1054 
1056  if (!list) {
1057  return NULL;
1058  }
1059 
1060  char *method_name = NULL;
1061  if (bin->methods) {
1062  for (ut32 i = 0; i < bin->methods_count; ++i) {
1063  const Method *method = bin->methods[i];
1064  if (!method) {
1066  continue;
1067  }
1068  const ConstPool *cpool = java_class_constant_pool_at(bin, method->name_index);
1069  if (!cpool || !java_constant_pool_is_string(cpool)) {
1070  RZ_LOG_ERROR("java bin: can't resolve method with constant pool index %u\n", method->name_index);
1071  continue;
1072  }
1073  method_name = java_constant_pool_stringify(cpool);
1074  if (!method_name) {
1075  continue;
1076  }
1077  ut64 size = 0;
1078  ut64 addr = UT64_MAX;
1079  for (ut32 i = 0; i < method->attributes_count; ++i) {
1080  Attribute *attr = method->attributes[i];
1081  if (attr && attr->type == ATTRIBUTE_TYPE_CODE) {
1082  AttributeCode *ac = (AttributeCode *)attr->info;
1083  addr = ac->code_offset;
1084  size = attr->attribute_length;
1085  break;
1086  }
1087  }
1089  if (!symbol) {
1091  free(method_name);
1092  continue;
1093  }
1095  if (!desc) {
1096  desc = strdup("(?)V");
1097  }
1098 
1100  symbol->dname = rz_str_newf("%s%s", method_name, desc);
1101  symbol->name = add_class_name_to_name(method_name, symbol->classname);
1102  symbol->size = size;
1104  symbol->type = RZ_BIN_TYPE_FUNC_STR;
1105  symbol->ordinal = rz_list_length(list);
1106  symbol->visibility = method->access_flags;
1108  symbol->libname = rz_demangler_java(symbol->classname);
1110  free(desc);
1111  free(method_name);
1112  rz_list_append(list, symbol);
1113  }
1114  }
1115  return list;
1116 }
bool java_method_is_global(const Method *method)
Definition: class_method.c:102

References java_method_t::access_flags, add_class_name_to_name(), addr, java_attribute_t::attribute_length, ATTRIBUTE_TYPE_CODE, java_method_t::attributes, java_method_t::attributes_count, rz_bin_symbol_t::bind, rz_bin_symbol_t::classname, java_attribute_code_t::code_offset, desc, java_method_t::descriptor_index, rz_bin_symbol_t::dname, free(), i, java_attribute_t::info, java_access_flags_to_bin_flags(), java_class_constant_pool_at(), java_class_constant_pool_stringify_at(), java_constant_pool_is_string(), java_constant_pool_stringify(), java_method_access_flags_readable(), java_method_is_global(), rz_bin_symbol_t::libname, list(), rz_bin_symbol_t::method_flags, rz_bin_symbol_t::name, java_method_t::name_index, NULL, rz_bin_symbol_t::ordinal, RZ_BIN_BIND_GLOBAL_STR, RZ_BIN_BIND_LOCAL_STR, rz_bin_java_class_name(), rz_bin_symbol_free(), rz_bin_symbol_new(), RZ_BIN_TYPE_FUNC_STR, rz_demangler_java(), rz_list_append(), rz_list_length(), rz_list_newf(), RZ_LOG_ERROR, rz_return_val_if_fail, rz_str_newf(), rz_warn_if_reached, rz_bin_symbol_t::size, strdup(), java_attribute_t::type, rz_bin_symbol_t::type, ut64(), UT64_MAX, rz_bin_symbol_t::visibility, and rz_bin_symbol_t::visibility_str.

Referenced by classes(), and symbols().

◆ rz_bin_java_class_methods_as_text()

RZ_API void rz_bin_java_class_methods_as_text ( RZ_NONNULL RzBinJavaClass bin,
RZ_NONNULL RzStrBuf sb 
)

Returns the methods in text format via RzStrBuf arg.

Definition at line 1121 of file class_bin.c.

1121  {
1122  rz_return_if_fail(bin && sb);
1123 
1124  rz_strbuf_appendf(sb, "Methods: %u\n", bin->methods_count);
1125  char number[16];
1126  char *flags, *name, *descr;
1127  if (bin->methods) {
1128  for (ut32 i = 0; i < bin->methods_count; ++i) {
1129  const Method *method = bin->methods[i];
1130  if (!method) {
1132  continue;
1133  }
1137 
1138  if (flags) {
1139  rz_strbuf_appendf(sb, " %s %s%s;\n", flags, name, descr);
1140  } else {
1141  rz_strbuf_appendf(sb, " %s%s;\n", name, descr);
1142  }
1143  rz_strbuf_appendf(sb, " name: %s\n", name);
1144  rz_strbuf_appendf(sb, " descriptor: %s\n", descr);
1145  rz_strbuf_appendf(sb, " flags: (0x%04x) %s\n", method->access_flags, flags ? flags : "");
1146 
1147  free(flags);
1148  free(name);
1149  free(descr);
1150  rz_strbuf_appendf(sb, " attributes: %u\n", method->attributes_count);
1151  int padding = calculate_padding_ut16(method->attributes_count) + 1;
1152  for (ut32 i = 0; i < method->attributes_count; ++i) {
1153  Attribute *attr = method->attributes[i];
1154  if (!attr) {
1155  continue;
1156  }
1157  snprintf(number, sizeof(number), "#%u", i);
1159  rz_strbuf_appendf(sb, " %-*s = #%-5u size: %-5u %s\n", padding, number, attr->attribute_name_index, attr->attribute_length, name);
1160  free(name);
1161  }
1162  }
1163  }
1164 }

References java_method_t::access_flags, java_attribute_t::attribute_length, java_attribute_t::attribute_name_index, java_method_t::attributes, java_method_t::attributes_count, calculate_padding_ut16(), java_method_t::descriptor_index, flags, free(), i, java_class_constant_pool_stringify_at(), java_method_access_flags_readable(), name, java_method_t::name_index, rz_return_if_fail, rz_strbuf_appendf(), rz_warn_if_reached, sb, and snprintf.

Referenced by rz_bin_java_class_as_text(), and rz_cmd_javam_handler().

◆ rz_bin_java_class_name()

RZ_API RZ_OWN char* rz_bin_java_class_name ( RZ_NONNULL RzBinJavaClass bin)

Returns the class name.

Definition at line 447 of file class_bin.c.

447  {
448  ut16 index;
450  const ConstPool *cpool = java_class_constant_pool_at(bin, bin->this_class);
451 
452  if (!cpool || java_constant_pool_resolve(cpool, &index, NULL) != 1) {
453  RZ_LOG_ERROR("java bin: unknown class name at constant pool index %u\n", bin->this_class);
454  return strdup("unknown_class");
455  }
456 
458  char *class_name = rz_str_newf("L%s;", tmp);
459  free(tmp);
460  return class_name;
461 }

References free(), java_class_constant_pool_at(), java_class_constant_pool_stringify_at(), java_constant_pool_resolve(), NULL, RZ_LOG_ERROR, rz_return_val_if_fail, rz_str_newf(), strdup(), and autogen_x86imm::tmp.

Referenced by classes(), rz_bin_java_class_as_json(), rz_bin_java_class_as_source_code(), rz_bin_java_class_as_text(), rz_bin_java_class_fields_as_symbols(), and rz_bin_java_class_methods_as_symbols().

◆ rz_bin_java_class_new()

RZ_API RZ_OWN RzBinJavaClass* rz_bin_java_class_new ( RZ_NONNULL RzBuffer buf,
ut64  offset,
RZ_NONNULL Sdb kv 
)

Parses the java class file and returns a RzBinJavaClass struct.

Definition at line 289 of file class_bin.c.

289  {
292 
293  ut64 size;
294  if (!java_class_parse(bin, offset, kv, buf, &size)) {
295  return NULL;
296  }
297 
298  java_set_sdb(kv, bin, offset, size);
299 
300  return bin;
301 }
static bool java_class_parse(RzBinJavaClass *bin, ut64 base, Sdb *kv, RzBuffer *buf, ut64 *size)
Definition: class_bin.c:97
static void java_set_sdb(Sdb *kv, RzBinJavaClass *bin, ut64 offset, ut64 size)
Definition: class_bin.c:251

References java_class_parse(), java_set_sdb(), NULL, RZ_NEW0, rz_return_val_if_fail, and ut64().

Referenced by load_buffer().

◆ rz_bin_java_class_resolve_symbol()

RZ_API RZ_OWN RzBinAddr* rz_bin_java_class_resolve_symbol ( RZ_NONNULL RzBinJavaClass bin,
RzBinSpecialSymbol  resolve 
)

Resolves and returns the RzBinAddr struct linked to the input RzBinSpecialSymbol.

Definition at line 870 of file class_bin.c.

870  {
872 
873  RzBinAddr *ret = RZ_NEW0(RzBinAddr);
874  if (!ret) {
875  return NULL;
876  }
877  ret->paddr = UT64_MAX;
878 
879  char *name = NULL;
880  if (bin->methods) {
881  for (ut32 i = 0; i < bin->methods_count; ++i) {
882  const Method *method = bin->methods[i];
883  if (!method) {
884  continue;
885  }
886 
888  if (!name) {
889  continue;
890  }
891 
893  if (strcmp(name, "<init>") != 0 && strcmp(name, "<clinit>") != 0) {
894  free(name);
895  continue;
896  }
897  } else if (resolve == RZ_BIN_SPECIAL_SYMBOL_MAIN) {
898  if (strcmp(name, "main") != 0) {
899  free(name);
900  continue;
901  }
902  }
903  free(name);
904  ut64 addr = UT64_MAX;
905  for (ut32 i = 0; i < method->attributes_count; ++i) {
906  Attribute *attr = method->attributes[i];
907  if (attr && attr->type == ATTRIBUTE_TYPE_CODE) {
908  AttributeCode *ac = (AttributeCode *)attr->info;
909  addr = ac->code_offset;
910  break;
911  }
912  }
913  if (addr == UT64_MAX) {
914  RZ_LOG_ERROR("java bin: can't resolve symbol address\n");
915  continue;
916  }
917  ret->paddr = addr;
918  break;
919  }
920  }
921  return ret;
922 }
@ RZ_BIN_SPECIAL_SYMBOL_ENTRY
Definition: rz_bin.h:137
@ RZ_BIN_SPECIAL_SYMBOL_INIT
Definition: rz_bin.h:138
@ RZ_BIN_SPECIAL_SYMBOL_MAIN
Definition: rz_bin.h:139
static const char * resolve(struct Type *t, const char *foo, const char **bar)
Definition: swift.c:91

References addr, ATTRIBUTE_TYPE_CODE, java_method_t::attributes, java_method_t::attributes_count, java_attribute_code_t::code_offset, free(), i, java_attribute_t::info, java_class_constant_pool_stringify_at(), java_method_t::name_index, NULL, rz_bin_addr_t::paddr, resolve(), RZ_BIN_SPECIAL_SYMBOL_ENTRY, RZ_BIN_SPECIAL_SYMBOL_INIT, RZ_BIN_SPECIAL_SYMBOL_MAIN, RZ_LOG_ERROR, RZ_NEW0, rz_return_val_if_fail, java_attribute_t::type, ut64(), and UT64_MAX.

Referenced by binsym().

◆ rz_bin_java_class_strings()

RZ_API RZ_OWN RzList* rz_bin_java_class_strings ( RZ_NONNULL RzBinJavaClass bin)

Returns a RzList<RzBinString*> containing the strings.

Definition at line 986 of file class_bin.c.

986  {
988 
990  if (!list) {
991  return NULL;
992  }
993 
994  char *string;
995  if (bin->constant_pool_count > 0) {
996  for (ut32 i = 1; i < bin->constant_pool_count; ++i) {
997  const ConstPool *cpool = bin->constant_pool[i];
998  if (!cpool || !java_constant_pool_is_string(cpool) || cpool->size < 1) {
999  continue;
1000  }
1001  string = java_constant_pool_stringify(cpool);
1002  if (!string) {
1003  RZ_LOG_ERROR("java bin: expecting a string, got NULL\n");
1004  continue;
1005  }
1006  RzBinString *bstr = RZ_NEW0(RzBinString);
1007  if (!bstr) {
1008  free(string);
1010  continue;
1011  }
1012  bstr->paddr = cpool->offset;
1013  bstr->ordinal = i;
1014  bstr->length = cpool->size;
1015  bstr->size = cpool->size;
1016  bstr->string = string;
1017  bstr->type = RZ_STRING_ENC_MUTF8;
1018  rz_list_append(list, bstr);
1019  }
1020  }
1021 
1022  for (ut32 i = 0; i < bin->attributes_count; ++i) {
1023  Attribute *attr = bin->attributes[i];
1024  if (attr && attr->type == ATTRIBUTE_TYPE_SOURCEDEBUGEXTENSION) {
1025  RzBinString *bstr = RZ_NEW0(RzBinString);
1026  if (!bstr) {
1028  continue;
1029  }
1030  bstr->paddr = attr->offset;
1031  bstr->ordinal = i;
1032  bstr->length = attr->attribute_length;
1033  bstr->size = attr->attribute_length;
1034  bstr->string = strdup(attr->info);
1035  bstr->type = RZ_STRING_ENC_UTF8;
1036  rz_list_append(list, bstr);
1037  }
1038  }
1039  return list;
1040 }
RZ_API void rz_bin_string_free(void *_str)
Definition: bin.c:192
@ ATTRIBUTE_TYPE_SOURCEDEBUGEXTENSION
@ RZ_STRING_ENC_MUTF8
Definition: rz_str.h:22
@ RZ_STRING_ENC_UTF8
Definition: rz_str.h:21
ut32 ordinal
Definition: rz_bin.h:755
char * string
Definition: rz_bin.h:752

References java_attribute_t::attribute_length, ATTRIBUTE_TYPE_SOURCEDEBUGEXTENSION, free(), i, java_attribute_t::info, java_constant_pool_is_string(), java_constant_pool_stringify(), rz_bin_string_t::length, list(), NULL, java_attribute_t::offset, java_constant_pool_t::offset, rz_bin_string_t::ordinal, rz_bin_string_t::paddr, rz_bin_string_free(), rz_list_append(), rz_list_newf(), RZ_LOG_ERROR, RZ_NEW0, rz_return_val_if_fail, RZ_STRING_ENC_MUTF8, RZ_STRING_ENC_UTF8, rz_warn_if_reached, java_constant_pool_t::size, rz_bin_string_t::size, strdup(), rz_bin_string_t::string, java_attribute_t::type, and rz_bin_string_t::type.

Referenced by strings().

◆ rz_bin_java_class_super()

RZ_API RZ_OWN char* rz_bin_java_class_super ( RZ_NONNULL RzBinJavaClass bin)

Returns the class super name.

Definition at line 466 of file class_bin.c.

466  {
467  ut16 index;
469  const ConstPool *cpool = java_class_constant_pool_at(bin, bin->super_class);
470  if (!cpool || java_constant_pool_resolve(cpool, &index, NULL) != 1) {
471  RZ_LOG_ERROR("java bin: unknown super name at constant pool index %u\n", bin->this_class);
472  return strdup("unknown_super");
473  }
475 }

References java_class_constant_pool_at(), java_class_constant_pool_stringify_at(), java_constant_pool_resolve(), NULL, RZ_LOG_ERROR, rz_return_val_if_fail, and strdup().

Referenced by classes(), rz_bin_java_class_as_json(), rz_bin_java_class_as_source_code(), and rz_bin_java_class_as_text().

◆ rz_bin_java_class_version()

RZ_API RZ_OWN char* rz_bin_java_class_version ( RZ_NONNULL RzBinJavaClass bin)

Parses the java class file and returns a RzBinJavaClass struct.

Definition at line 306 of file class_bin.c.

306  {
307  if (!bin) {
308  return NULL;
309  }
310 #define is_version(bin, major, minor) ((bin)->major_version == (major) && (bin)->minor_version >= (minor))
311  if (bin->major_version < 45 ||
312  (bin->major_version == 45 && bin->minor_version < 3)) {
313  return strdup("Java SE 1.0.2"); // old format
314  } else if (is_version(bin, 45, 3)) {
315  return strdup("Java SE 1.1");
316  } else if (is_version(bin, 46, 0)) {
317  return strdup("Java SE 1.2");
318  } else if (is_version(bin, 47, 0)) {
319  return strdup("Java SE 1.3");
320  } else if (is_version(bin, 48, 0)) {
321  return strdup("Java SE 1.4");
322  } else if (is_version(bin, 49, 0)) {
323  return strdup("Java SE 1.5"); // enum, generics, annotations
324  } else if (is_version(bin, 50, 0)) {
325  return strdup("Java SE 1.6"); // stackmaps
326  } else if (is_version(bin, 51, 0)) {
327  return strdup("Java SE 1.7");
328  } else if (is_version(bin, 52, 0)) {
329  return strdup("Java SE 1.8"); // lambda, type annos, param names
330  } else if (is_version(bin, 53, 0)) {
331  return strdup("Java SE 1.9"); // modules, indy string concat
332  } else if (is_version(bin, 54, 0)) {
333  return strdup("Java SE 10");
334  } else if (is_version(bin, 55, 0)) {
335  return strdup("Java SE 11"); // constant dynamic, nest mates
336  } else if (is_version(bin, 56, 0)) {
337  return strdup("Java SE 12");
338  } else if (is_version(bin, 57, 0)) {
339  return strdup("Java SE 13");
340  } else if (is_version(bin, 58, 0)) {
341  return strdup("Java SE 14");
342  } else if (is_version(bin, 59, 0)) {
343  return strdup("Java SE 15");
344  } else if (is_version(bin, 60, 0)) {
345  return strdup("Java SE 16");
346  }
347 #undef is_version
348  return strdup("unknown");
349 }
#define is_version(bin, major, minor)

References is_version, NULL, and strdup().

Referenced by info(), java_set_sdb(), rz_bin_java_class_as_json(), and rz_bin_java_class_as_text().

◆ sanitize_size()

static ut32 sanitize_size ( st64  buffer_size,
ut64  count,
ut32  min_struct_size 
)
static

Definition at line 82 of file class_bin.c.

82  {
83  ut64 memory_size = count * min_struct_size;
84  return memory_size <= buffer_size ? count : 0;
85 }

References buffer_size, count, and ut64().

Referenced by java_class_parse().

◆ section_free()

static void section_free ( void *  u)
static

Definition at line 1706 of file class_bin.c.

1706  {
1708 }
RZ_API void rz_bin_section_free(RzBinSection *bs)
Definition: bin.c:1116

References rz_bin_section_free().

Referenced by rz_bin_java_class_as_sections().

Variable Documentation

◆ access_flags_list

Initial value:
= {
{ ACCESS_FLAG_PUBLIC, "public" },
{ ACCESS_FLAG_PRIVATE, "private" },
{ ACCESS_FLAG_PROTECTED, "protected" },
{ ACCESS_FLAG_STATIC, "static" },
{ ACCESS_FLAG_FINAL, "final" },
{ ACCESS_FLAG_SUPER, "super" },
{ ACCESS_FLAG_BRIDGE, "bridge" },
{ ACCESS_FLAG_VARARGS, "varargs" },
{ ACCESS_FLAG_NATIVE, "native" },
{ ACCESS_FLAG_INTERFACE, "interface" },
{ ACCESS_FLAG_ABSTRACT, "abstract" },
{ ACCESS_FLAG_STRICT, "strict" },
{ ACCESS_FLAG_SYNTHETIC, "synthetic" },
{ ACCESS_FLAG_ANNOTATION, "annotation" },
{ ACCESS_FLAG_ENUM, "enum" },
{ ACCESS_FLAG_MODULE, "module" },
}
@ ACCESS_FLAG_MODULE
Definition: dex.h:56
@ ACCESS_FLAG_ENUM
Definition: dex.h:55
@ ACCESS_FLAG_ANNOTATION
Definition: dex.h:54
@ ACCESS_FLAG_INTERFACE
Definition: dex.h:50

Definition at line 10 of file class_bin.c.

Referenced by rz_bin_java_class_access_flags_readable().