Rizin
unix-like reverse engineering framework and cli tools
asm_java.c
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2021 deroad <wargio@libero.it>
2 // SPDX-License-Identifier: LGPL-3.0-only
3 
4 #include <rz_types.h>
5 #include <rz_util.h>
6 #include <rz_lib.h>
7 #include <rz_asm.h>
8 #include <rz_core.h>
9 
10 #include "../arch/java/jvm.h"
11 #include "../arch/java/assembler.h"
12 
13 typedef struct java_analysis_context_t {
16  ut16 switchop;
17  ut64 pc;
19  ut32 count;
21 
23  ctx->count++;
24  if (ctx->switchop == BYTECODE_AA_TABLESWITCH && ctx->count > ctx->ts.length) {
25  ctx->switchop = BYTECODE_00_NOP;
26  } else if (ctx->switchop == BYTECODE_AB_LOOKUPSWITCH && ctx->count > ctx->ls.npairs) {
27  ctx->switchop = BYTECODE_00_NOP;
28  }
29 }
30 
31 static int java_disassemble(RzAsm *a, RzAsmOp *op, const ut8 *buf, int len) {
32  JavaAsmContext *ctx = (JavaAsmContext *)a->plugin_data;
33  rz_strbuf_set(&op->buf_asm, "invalid");
34 
35  if (a->pc < ctx->last) {
36  ctx->switchop = BYTECODE_00_NOP;
37  }
38  ctx->last = a->pc;
39  switch (ctx->switchop) {
41  if (len < 4) {
42  RZ_LOG_ERROR("[!] java_analysis: no enough data for lookupswitch case.\n");
43  return -1;
44  }
45  op->size = 4;
46  ut64 jump = ctx->pc + rz_read_be32(buf);
47  rz_strbuf_setf(&op->buf_asm, "case %d: goto 0x%" PFMT64x, ctx->count + ctx->ts.low, jump);
49  return op->size;
50  }
52  if (len < 8) {
53  RZ_LOG_ERROR("[!] java_analysis: no enough data for lookupswitch case.\n");
54  return -1;
55  }
56  op->size = 8;
57  st32 number = (st32)rz_read_be32(buf);
58  ut64 jump = ctx->pc + rz_read_at_be32(buf, 4);
59  rz_strbuf_setf(&op->buf_asm, "case %d: goto 0x%" PFMT64x, number, jump);
61  return op->size;
62  }
63  default:
64  break;
65  }
66 
67  JavaVM vm = { 0 };
68  Bytecode bc = { 0 };
69 
70  rz_strbuf_set(&op->buf_asm, "invalid");
71 
72  ut64 section = a->pc;
73  if (a->binb.bin) {
74  const RzBinSection *sec = a->binb.get_vsect_at(a->binb.bin, a->pc);
75  if (sec) {
76  section = sec->paddr;
77  }
78  }
79 
80  if (!jvm_init(&vm, buf, len, a->pc, section)) {
81  RZ_LOG_ERROR("[!] java_disassemble: bad or invalid data.\n");
82  return -1;
83  }
84  op->size = 1;
85  if (jvm_fetch(&vm, &bc)) {
86  op->size = bc.size;
87  bytecode_snprint(&op->buf_asm, &bc);
88  if (bc.opcode == BYTECODE_AA_TABLESWITCH) {
89  ctx->count = 0;
90  ctx->switchop = BYTECODE_AA_TABLESWITCH;
91  ctx->ts = *((TableSwitch *)bc.extra);
92  ctx->pc = a->pc;
93  } else if (bc.opcode == BYTECODE_AB_LOOKUPSWITCH) {
94  ctx->count = 0;
95  ctx->switchop = BYTECODE_AB_LOOKUPSWITCH;
96  ctx->ls = *((LookupSwitch *)bc.extra);
97  ctx->pc = a->pc;
98  }
99  bytecode_clean(&bc);
100  } else {
101  RZ_LOG_ERROR("[!] java_disassemble: jvm fetch failed.\n");
102  return -1;
103  }
104  return op->size;
105 }
106 
107 static bool java_init(void **user) {
109  if (!ctx) {
110  return false;
111  }
112  *user = ctx;
113  return true;
114 }
115 
116 static bool java_fini(void *user) {
117  if (!user) {
118  return false;
119  }
120  JavaAsmContext *ctx = (JavaAsmContext *)user;
121  free(ctx);
122  return true;
123 }
124 
125 static int java_assemble(RzAsm *a, RzAsmOp *ao, const char *str) {
126  ut8 buffer[128];
127  st32 written = 0;
128  st32 slen = strlen(str);
129 
130  if (!java_assembler(str, slen, buffer, sizeof(buffer), a->pc, &written)) {
131  return -1;
132  }
133 
134  rz_strbuf_setbin(&ao->buf, (const ut8 *)&buffer, written);
135  return written;
136 }
137 
139  .name = "java",
140  .desc = "Java bytecode disassembler",
141  .arch = "java",
142  .license = "LGPL-3",
143  .author = "deroad",
144  .bits = 32,
145  .endian = RZ_SYS_ENDIAN_BIG,
146  .init = java_init,
147  .fini = java_fini,
148  .disassemble = &java_disassemble,
149  .assemble = &java_assemble,
150 };
151 
152 #ifndef RZ_PLUGIN_INCORE
155  .data = &rz_asm_plugin_java,
157 };
158 #endif
size_t len
Definition: 6502dis.c:15
static bool java_init(void **user)
Definition: asm_java.c:107
static int java_disassemble(RzAsm *a, RzAsmOp *op, const ut8 *buf, int len)
Definition: asm_java.c:31
struct java_analysis_context_t JavaAsmContext
RZ_API RzLibStruct rizin_plugin
Definition: asm_java.c:153
static bool java_fini(void *user)
Definition: asm_java.c:116
static void update_context(JavaAsmContext *ctx)
Definition: asm_java.c:22
static int java_assemble(RzAsm *a, RzAsmOp *ao, const char *str)
Definition: asm_java.c:125
RzAsmPlugin rz_asm_plugin_java
Definition: asm_java.c:138
int jump(int a, int b)
Definition: bcj_test.c:35
#define BYTECODE_00_NOP
Definition: bytecode.h:8
#define BYTECODE_AA_TABLESWITCH
Definition: bytecode.h:178
#define BYTECODE_AB_LOOKUPSWITCH
Definition: bytecode.h:179
#define RZ_API
uint16_t ut16
uint32_t ut32
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
voidpf void * buf
Definition: ioapi.h:138
bool java_assembler(const char *input, st32 input_size, ut8 *output, st32 output_size, ut64 pc, st32 *written)
Definition: assembler.c:472
bool jvm_fetch(JavaVM *jvm, Bytecode *bytecode)
Definition: jvm.c:1553
bool jvm_init(JavaVM *jvm, const ut8 *buffer, const ut32 size, ut64 pc, ut64 section)
Definition: jvm.c:1541
void bytecode_clean(Bytecode *bytecode)
Definition: jvm.c:1536
void bytecode_snprint(RzStrBuf *sb, Bytecode *bytecode)
Definition: jvm.c:1458
uint8_t ut8
Definition: lh5801.h:11
static ut32 rz_read_at_be32(const void *src, size_t offset)
Definition: rz_endian.h:93
static ut32 rz_read_be32(const void *src)
Definition: rz_endian.h:87
@ RZ_LIB_TYPE_ASM
Definition: rz_lib.h:72
#define RZ_LOG_ERROR(fmtstr,...)
Definition: rz_log.h:58
RZ_API const char * rz_strbuf_set(RzStrBuf *sb, const char *s)
Definition: strbuf.c:153
RZ_API const char * rz_strbuf_setf(RzStrBuf *sb, const char *fmt,...) RZ_PRINTF_CHECK(2
RZ_API bool rz_strbuf_setbin(RzStrBuf *sb, const ut8 *s, size_t len)
Definition: strbuf.c:85
#define RZ_SYS_ENDIAN_BIG
Definition: rz_types.h:527
#define RZ_NEW0(x)
Definition: rz_types.h:284
#define PFMT64x
Definition: rz_types.h:393
#define st32
Definition: rz_types_base.h:12
#define RZ_VERSION
Definition: rz_version.h:8
#define a(i)
Definition: sha256.c:41
Definition: buffer.h:15
void * extra
Definition: bytecode.h:244
ut16 opcode
Definition: bytecode.h:237
ut16 size
Definition: bytecode.h:238
Definition: jvm.h:10
RzStrBuf buf
Definition: rz_asm.h:71
const char * name
Definition: rz_asm.h:130
const char * version
Definition: rz_asm.h:133
Definition: dis.c:32
ut64(WINAPI *w32_GetEnabledXStateFeatures)()