Rizin
unix-like reverse engineering framework and cli tools
class_const_pool.c
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2021 deroad <wargio@libero.it>
2 // SPDX-License-Identifier: LGPL-3.0-only
3 
4 #include "class_const_pool.h"
5 
7  if (size < 1) {
8  return cpool;
9  }
10  cpool->size = size;
11  cpool->buffer = (ut8 *)malloc(size);
12  if (!cpool->buffer || rz_buf_read(buf, cpool->buffer, size) != size) {
13  free(cpool);
15  return NULL;
16  }
17  return cpool;
18 }
19 
21  ConstPool *cpool = RZ_NEW0(ConstPool);
23  cpool->offset = offset;
24  return cpool;
25 }
26 
28  ConstPool *cpool = RZ_NEW0(ConstPool);
30 
31  cpool->offset = offset;
32  if (!rz_buf_read8(buf, &cpool->tag)) {
33  free(cpool);
34  return NULL;
35  }
36 
37  ut16 string_len;
38 
39  switch (cpool->tag) {
40  case CONSTANT_POOL_ZERO:
41  return cpool;
42  case CONSTANT_POOL_UTF8:
44  if (!rz_buf_read_be16(buf, &string_len)) {
45  free(cpool);
46  return NULL;
47  }
48  return constant_pool_copy_from_buffer(buf, cpool, string_len);
49  case CONSTANT_POOL_LONG:
51  return constant_pool_copy_from_buffer(buf, cpool, 8);
60  return constant_pool_copy_from_buffer(buf, cpool, 4);
62  return constant_pool_copy_from_buffer(buf, cpool, 3);
68  return constant_pool_copy_from_buffer(buf, cpool, 2);
69  default:
70  RZ_LOG_ERROR("java bin: invalid constant pool tag: %u at 0x%" PFMT64x "\n", cpool->tag, offset);
71  break;
72  }
74  free(cpool);
75  return NULL;
76 }
77 
79  if (!cpool) {
80  return;
81  }
82  free(cpool->buffer);
83  free(cpool);
84 }
85 
86 const char *java_constant_pool_tag_name(const ConstPool *cpool) {
88  switch (cpool->tag) {
89  case CONSTANT_POOL_ZERO:
90  return "Zero";
91  case CONSTANT_POOL_UTF8:
92  return "Utf8";
94  return "Unicode";
96  return "Integer";
98  return "Float";
99  case CONSTANT_POOL_LONG:
100  return "Long";
102  return "Double";
103  case CONSTANT_POOL_CLASS:
104  return "Class";
106  return "String";
108  return "Fieldref";
110  return "Methodref";
112  return "InterfaceMethodref";
114  return "NameAndType";
116  return "MethodHandle";
118  return "MethodType";
120  return "Dynamic";
122  return "InvokeDynamic";
124  return "Module";
126  return "Package";
127  default:
128  return NULL;
129  }
130 }
131 
133  rz_return_val_if_fail(cpool, false);
134  return cpool->tag == CONSTANT_POOL_UTF8 || cpool->tag == CONSTANT_POOL_UNICODE;
135 }
136 
138  rz_return_val_if_fail(cpool, false);
139  return cpool->tag == CONSTANT_POOL_INTEGER ||
140  cpool->tag == CONSTANT_POOL_FLOAT ||
141  cpool->tag == CONSTANT_POOL_LONG ||
142  cpool->tag == CONSTANT_POOL_DOUBLE;
143 }
144 
146  rz_return_val_if_fail(cpool, false);
147  return cpool->tag == CONSTANT_POOL_METHODREF ||
149  cpool->tag == CONSTANT_POOL_FIELDREF;
150 }
151 
153  rz_return_val_if_fail(cpool, false);
154  // https://github.com/openjdk/jdk/blob/master/src/jdk.jdeps/share/classes/com/sun/tools/javap/ConstantWriter.java#L73
155  // https://github.com/openjdk/jdk/blob/master/src/jdk.jdeps/share/classes/com/sun/tools/javap/ConstantWriter.java#L116
156  return cpool->tag == CONSTANT_POOL_DOUBLE || cpool->tag == CONSTANT_POOL_LONG;
157 }
158 
160  rz_return_val_if_fail(cpool, NULL);
161 
162  switch (cpool->tag) {
163  case CONSTANT_POOL_UTF8:
164  case CONSTANT_POOL_UNICODE: {
165  if (!cpool->size) {
166  return NULL;
167  }
168  return rz_str_escape_mutf8_for_json((const char *)cpool->buffer, cpool->size);
169  }
170  case CONSTANT_POOL_LONG: {
171  st64 value = rz_read_be64(cpool->buffer);
172  return rz_str_newf("0x%" PFMT64x, value);
173  }
174  case CONSTANT_POOL_DOUBLE: {
175  double value = rz_read_be_double(cpool->buffer);
176  return rz_str_newf("%.16lgd", value);
177  }
178  case CONSTANT_POOL_INTEGER: {
179  st32 value = rz_read_be32(cpool->buffer);
180  return rz_str_newf("0x%" PFMT32x, value);
181  }
182  case CONSTANT_POOL_FLOAT: {
183  float value = rz_read_be_float(cpool->buffer);
184  return rz_str_newf("%6gf", value);
185  }
187  ut16 kind = cpool->buffer[0];
188  ut16 index = rz_read_be16(cpool->buffer + 1);
189  return rz_str_newf("%u:#%u", kind, index);
190  }
197  ut16 arg0 = rz_read_be16(cpool->buffer);
198  ut16 arg1 = rz_read_be16(cpool->buffer + 2);
199  return rz_str_newf("#%u:#%u", arg0, arg1);
200  }
202  case CONSTANT_POOL_CLASS:
205  case CONSTANT_POOL_PACKAGE: {
206  ut16 value = rz_read_be16(cpool->buffer);
207  return rz_str_newf("#%u", value);
208  }
209  default:
210  break;
211  }
212  return NULL;
213 }
214 
215 ut32 java_constant_pool_resolve(const ConstPool *cpool, ut16 *arg0, ut16 *arg1) {
216  rz_return_val_if_fail(cpool, 0);
217  ut16 unused1;
218  if (!arg1) {
219  arg1 = &unused1;
220  }
221 
222  switch (cpool->tag) {
224  *arg0 = rz_read_be16(cpool->buffer + 1);
225  return 1;
226  }
233  *arg0 = rz_read_be16(cpool->buffer);
234  *arg1 = rz_read_be16(cpool->buffer + 2);
235  return 2;
236  }
238  case CONSTANT_POOL_CLASS:
241  case CONSTANT_POOL_PACKAGE: {
242  *arg0 = rz_read_be16(cpool->buffer);
243  return 1;
244  }
245  default:
246  break;
247  }
248  return 0;
249 }
#define PFMT32x
bool java_constant_pool_requires_null(const ConstPool *cpool)
bool java_constant_pool_is_string(const ConstPool *cpool)
void java_constant_pool_free(ConstPool *cpool)
ut32 java_constant_pool_resolve(const ConstPool *cpool, ut16 *arg0, ut16 *arg1)
char * java_constant_pool_stringify(const ConstPool *cpool)
const char * java_constant_pool_tag_name(const ConstPool *cpool)
ConstPool * java_constant_pool_new(RzBuffer *buf, ut64 offset)
static ConstPool * constant_pool_copy_from_buffer(RzBuffer *buf, ConstPool *cpool, const st64 size)
ConstPool * java_constant_null_new(ut64 offset)
bool java_constant_pool_is_number(const ConstPool *cpool)
bool java_constant_pool_is_import(const ConstPool *cpool)
@ CONSTANT_POOL_PACKAGE
@ CONSTANT_POOL_MODULE
@ CONSTANT_POOL_FIELDREF
@ CONSTANT_POOL_METHODHANDLE
@ CONSTANT_POOL_FLOAT
@ CONSTANT_POOL_ZERO
@ CONSTANT_POOL_METHODREF
@ CONSTANT_POOL_INTERFACEMETHODREF
@ CONSTANT_POOL_LONG
@ CONSTANT_POOL_METHODTYPE
@ CONSTANT_POOL_NAMEANDTYPE
@ CONSTANT_POOL_DYNAMIC
@ CONSTANT_POOL_INVOKEDYNAMIC
@ CONSTANT_POOL_UNICODE
@ CONSTANT_POOL_INTEGER
@ CONSTANT_POOL_CLASS
@ CONSTANT_POOL_DOUBLE
@ CONSTANT_POOL_UTF8
@ CONSTANT_POOL_STRING
static int value
Definition: cmd_api.c:93
#define NULL
Definition: cris-opc.c:27
uint16_t ut16
uint32_t ut32
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
voidpf void uLong size
Definition: ioapi.h:138
voidpf uLong offset
Definition: ioapi.h:144
voidpf void * buf
Definition: ioapi.h:138
uint8_t ut8
Definition: lh5801.h:11
void * malloc(size_t size)
Definition: malloc.c:123
#define rz_warn_if_reached()
Definition: rz_assert.h:29
#define rz_return_val_if_fail(expr, val)
Definition: rz_assert.h:108
RZ_API st64 rz_buf_seek(RZ_NONNULL RzBuffer *b, st64 addr, int whence)
Modify the current cursor position in the buffer.
Definition: buf.c:1166
#define rz_buf_read_be16(b, result)
Definition: rz_buf.h:280
RZ_API bool rz_buf_read8(RZ_NONNULL RzBuffer *b, RZ_NONNULL RZ_OUT ut8 *result)
Read a byte at the cursor in the buffer.
Definition: buf.c:860
RZ_API st64 rz_buf_read(RZ_NONNULL RzBuffer *b, RZ_NONNULL RZ_OUT ut8 *buf, ut64 len)
static ut64 rz_read_be64(const void *src)
Definition: rz_endian.h:108
static double rz_read_be_double(const void *src)
Definition: rz_endian.h:157
static ut32 rz_read_be32(const void *src)
Definition: rz_endian.h:87
static float rz_read_be_float(const void *src)
Definition: rz_endian.h:129
static ut16 rz_read_be16(const void *src)
Definition: rz_endian.h:50
#define RZ_LOG_ERROR(fmtstr,...)
Definition: rz_log.h:58
RZ_API char * rz_str_newf(const char *fmt,...) RZ_PRINTF_CHECK(1
RZ_API char * rz_str_escape_mutf8_for_json(const char *s, int len)
Definition: str.c:1838
#define RZ_NEW0(x)
Definition: rz_types.h:284
#define PFMT64x
Definition: rz_types.h:393
#define st64
Definition: rz_types_base.h:10
#define st32
Definition: rz_types_base.h:12
ut64(WINAPI *w32_GetEnabledXStateFeatures)()
#define SEEK_SET
Definition: zip.c:88