radare2/shlr/java/code.c

342 lines
9.1 KiB
C
Raw Normal View History

/* radare - LGPL - Copyright 2007-2016 - pancake */
#include <r_types.h>
2012-12-13 17:32:26 +00:00
#include <r_util.h>
#include <r_list.h>
#include <r_anal.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
#include "ops.h"
#include "code.h"
Squashed commit of the following: commit 109915c7812305b9a442d3a0febd9bc43f7104b5 Author: Adam Pridgen <adam.pridgen@thecoverofnight.com> Date: Wed Sep 4 09:50:08 2013 -0500 - Added author rewrite tag commit 5fe0d07f3a318f871bc5d6a8499afd9ceab26e33 Author: Adam Pridgen <adam.pridgen@thecoverofnight.com> Date: Wed Sep 4 09:37:57 2013 -0500 - Added a print statement for the number of attributes in the Code Attribute - Added a default stack frame creation commit 4b1bca0d79c53421c1d7a9c59da070a5463ba05b Author: Adam Pridgen <adam.pridgen@thecoverofnight.com> Date: Wed Sep 4 08:58:55 2013 -0500 - Added the R_API prefix to all function declarations and definitions - Removed the offset<=size from loops. Not sure why this check is failing, but it needs to be added in the future (probably add it to the list of defects.) - Code appears to parse the classfile correctly commit 5f5a28302da8c605800946df739c67a0f4f80b0d Author: Adam Pridgen <adam.pridgen@thecoverofnight.com> Date: Tue Sep 3 23:11:00 2013 -0500 - still minor bug in the parsing code on the Type Verification or somewhere in the StackMapAttr. The right number of bytes are being read, but not all the bytes are being consumed commit 1c9d8b490c8d7d8592f898e019aed3b56f9406c8 Author: Adam Pridgen <adam.pridgen@thecoverofnight.com> Date: Tue Sep 3 20:59:08 2013 -0500 - fixed some compiler warnings in class.c commit c185248aa478c6c78f6dbe14cf65ee3396287302 Author: Adam Pridgen <adam.pridgen@thecoverofnight.com> Date: Tue Sep 3 20:58:21 2013 -0500 - Propogated the change to code.c from changes from classes. commit 927542a0672f37b41b23345533bc7e6f2d1a5369 Author: Adam Pridgen <adam.pridgen@thecoverofnight.com> Date: Tue Sep 3 17:10:40 2013 -0500 Fixed some minor parsing bugs: code_attr offet was not updated correctly after reading the length of the attribute attr_buf was not initialized correctly before use commit b43a7189e9934369d1fdbd96de020edcab907430 Author: Adam Pridgen <adam.pridgen@thecoverofnight.com> Date: Tue Sep 3 16:33:36 2013 -0500 - Code compiles. Time to test. commit ea7b332d84b88baca1abc466d02b00b2b8739bca Author: Adam Pridgen <adam.pridgen@thecoverofnight.com> Date: Mon Sep 2 23:55:44 2013 -0500 - Added in size calculations for the CP Objects. - Need to add method or field references calculations for size after compiling commit ba55375dc0e835fb46550d0063758e419ec0ed7b Author: Adam Pridgen <adam.pridgen@thecoverofnight.com> Date: Mon Sep 2 22:56:56 2013 -0500 - Revamped all of the attribute parsing. The parsers will handle buffers rather than simply parsing straight from the file. - added a size calculator for each of the attributes, which opens up the way for creating writers for the attributes and such. commit be6f2e038f01beeb56ace7d4daaf4d90ad3fdad7 Author: Adam Pridgen <adam.pridgen@thecoverofnight.com> Date: Sat Aug 31 12:19:18 2013 -0500 - Cleaned up code and removed some of the compiler warnings. commit 4c81812f2609e4a80c7036053d122306039dd6ef Author: Adam Pridgen <adam.pridgen@thecoverofnight.com> Date: Fri Aug 30 15:24:15 2013 -0500 - Compiler and linker errors have been resolved. - Need to work on testing commit 429ed30621d9abff1eec99ef50a35c57bbed76ad Author: Adam Pridgen <adam.pridgen@thecoverofnight.com> Date: Fri Aug 30 13:35:39 2013 -0500 Added the RunTime Annotations and Parameter annotations. Time to start compiling and testing. commit b6044e1c74cc10874902bd34da7c8fcbdb5713cc Author: Adam Pridgen <adam.pridgen@thecoverofnight.com> Date: Fri Aug 30 12:34:14 2013 -0500 Added BootstrapMethodsAttr Parsing code along with supporting stuff, like creating the method and argument structures and mapping the REF_types to strings More should be done to map the REF_types to specific resolutions. Added in the MethodType, MethodHandle, and InvokeDynamic ConstantPool Objects commit 2c9317be5d2be0608131fb9aa10f713885c89471 Author: Adam Pridgen <adam.pridgen@thecoverofnight.com> Date: Fri Aug 30 00:21:34 2013 -0500 Finished drafting the code for annotation, element values, element value pairs, and annotation default attribute. TODO: RTI, RTV, and then Bootstrap attributes. commit cbee3a10c18342f6a8fb941245568de885fe5666 Author: Adam Pridgen <adam.pridgen@thecoverofnight.com> Date: Thu Aug 29 15:42:00 2013 -0500 Fixed the r_bin_java_element_value_new function definition. commit ab98a76fabf2bd7764a51f3363d821c5a4cf1200 Author: Adam Pridgen <adam.pridgen@thecoverofnight.com> Date: Thu Aug 29 15:39:28 2013 -0500 - worked out some of the initial compile errors. - worked out an outline for parsing the element_values - need to work through parsing the element value, freeing the element value, and then printing a summary. commit b543d904f2aebd0d1f9c0ac8ec8401b6ab698f36 Author: Adam Pridgen <adam.pridgen@thecoverofnight.com> Date: Thu Aug 29 08:21:33 2013 -0500 Most of the heavy lifting is done for attributes. Need to implement a few of the methods, and then compiling should be able to happen. Added in all attribute values to the enums, the function call tables, and then the Metas information. Need implement an ElementValue parser bleh. Need to implement RuntimeAnnotations, Annotations, ElementValue parsing and make sure that the attribute unions are all updated. commit 81f9ca2da2ed7e007a97a20ecb8eb260dfd55e7e Author: Adam Pridgen <adam.pridgen@thecoverofnight.com> Date: Wed Aug 28 22:33:43 2013 -0500 Finished adding some logic to handle the StackMapFrame types. commit 9a0965cc06021ad56d2127d279b918eef613bec9 Author: Adam Pridgen <adam.pridgen@thecoverofnight.com> Date: Wed Aug 28 17:54:52 2013 -0500 Got some of the StackMapTable Atrribute parsing working. Right now, only the FullStackFrame will correctly parse. commit ea12bd6a8ae9969fa05cbcab622651c8b426917a Author: Adam Pridgen <adam.pridgen@thecoverofnight.com> Date: Fri Aug 23 17:51:33 2013 -0500 Added some debugging code while trying to figure out how to parse the StackMapTable. commit 6141b57ee94c7bd0569d0ea76725fdce1ac50edf Author: Adam Pridgen <adam.pridgen@thecoverofnight.com> Date: Fri Aug 23 17:00:12 2013 -0500 Code compiles. commit a7ad14050eb6184a1171620c4dcdba71b2f791aa Author: Adam Pridgen <adam.pridgen@thecoverofnight.com> Date: Fri Aug 23 10:29:17 2013 -0500 - Added a basic Signature element - Added declarations for the new functions to handle the parsing of the StackMapTable related structures. commit 54cca3d9af60463dbfa77e23ef1d562ae82d6e5a Author: Adam Pridgen <adam.pridgen@thecoverofnight.com> Date: Fri Aug 23 10:18:50 2013 -0500 Finished an initial coding implementation of the StackMapTable. -- Will perform testing later in the day. -- Need to look-up the Signature Attribute commit a14238eece865f4d1c5f2d6b1f482b000d10d94e Author: Adam Pridgen <adam.pridgen@thecoverofnight.com> Date: Thu Aug 22 20:23:45 2013 -0500 StackMap stuff is wip. commit f011a5d948d31cc6197eed1bbea497a4dde362aa Author: Adam Pridgen <adam.pridgen@thecoverofnight.com> Date: Thu Aug 22 18:44:23 2013 -0500 Made the globals match the R_* standard. Also tried to clean up naming stuff. commit 6e61e15572744c2ed722ac3df8d988cc02f1316c Author: Adam Pridgen <adam.pridgen@thecoverofnight.com> Date: Thu Aug 22 16:40:08 2013 -0500 Plugging progress into the repo. Adding fixes to handle the Java Class file appropriately. This modification is mostly a re-write of the Class File parser, and it "tries" to do a better job of creating better objects for each of the Classfile elements. Currently this code is experimental, and current TODOs are: 1) Testing 2) StackMapTable 3) LocalVariableTypeTable
2013-09-04 15:04:36 +00:00
#include "class.h"
#define V if (verbose)
#define DO_THE_DBG 0
#define IFDBG if(DO_THE_DBG)
2014-06-25 02:11:43 +00:00
#ifndef R_API
#define R_API
#endif
static void init_switch_op(void);
static int enter_switch_op(ut64 addr, const ut8 * bytes, int len);
static int update_switch_op(ut64 addr, const ut8 * bytes);
static int update_bytes_consumed(int sz);
static int handle_switch_op(ut64 addr, const ut8 * bytes, char *output, int outlen);
static ut8 IN_SWITCH_OP = 0;
typedef struct current_table_switch_t {
ut64 addr;
int def_jmp;
int min_val;
int max_val;
int cur_val;
} CurrentTableSwitch;
static CurrentTableSwitch SWITCH_OP;
static ut64 BYTES_CONSUMED = 0LL;
//static RBinJavaObj *BIN_OBJ = NULL;
Squashed commit of the following: commit 109915c7812305b9a442d3a0febd9bc43f7104b5 Author: Adam Pridgen <adam.pridgen@thecoverofnight.com> Date: Wed Sep 4 09:50:08 2013 -0500 - Added author rewrite tag commit 5fe0d07f3a318f871bc5d6a8499afd9ceab26e33 Author: Adam Pridgen <adam.pridgen@thecoverofnight.com> Date: Wed Sep 4 09:37:57 2013 -0500 - Added a print statement for the number of attributes in the Code Attribute - Added a default stack frame creation commit 4b1bca0d79c53421c1d7a9c59da070a5463ba05b Author: Adam Pridgen <adam.pridgen@thecoverofnight.com> Date: Wed Sep 4 08:58:55 2013 -0500 - Added the R_API prefix to all function declarations and definitions - Removed the offset<=size from loops. Not sure why this check is failing, but it needs to be added in the future (probably add it to the list of defects.) - Code appears to parse the classfile correctly commit 5f5a28302da8c605800946df739c67a0f4f80b0d Author: Adam Pridgen <adam.pridgen@thecoverofnight.com> Date: Tue Sep 3 23:11:00 2013 -0500 - still minor bug in the parsing code on the Type Verification or somewhere in the StackMapAttr. The right number of bytes are being read, but not all the bytes are being consumed commit 1c9d8b490c8d7d8592f898e019aed3b56f9406c8 Author: Adam Pridgen <adam.pridgen@thecoverofnight.com> Date: Tue Sep 3 20:59:08 2013 -0500 - fixed some compiler warnings in class.c commit c185248aa478c6c78f6dbe14cf65ee3396287302 Author: Adam Pridgen <adam.pridgen@thecoverofnight.com> Date: Tue Sep 3 20:58:21 2013 -0500 - Propogated the change to code.c from changes from classes. commit 927542a0672f37b41b23345533bc7e6f2d1a5369 Author: Adam Pridgen <adam.pridgen@thecoverofnight.com> Date: Tue Sep 3 17:10:40 2013 -0500 Fixed some minor parsing bugs: code_attr offet was not updated correctly after reading the length of the attribute attr_buf was not initialized correctly before use commit b43a7189e9934369d1fdbd96de020edcab907430 Author: Adam Pridgen <adam.pridgen@thecoverofnight.com> Date: Tue Sep 3 16:33:36 2013 -0500 - Code compiles. Time to test. commit ea7b332d84b88baca1abc466d02b00b2b8739bca Author: Adam Pridgen <adam.pridgen@thecoverofnight.com> Date: Mon Sep 2 23:55:44 2013 -0500 - Added in size calculations for the CP Objects. - Need to add method or field references calculations for size after compiling commit ba55375dc0e835fb46550d0063758e419ec0ed7b Author: Adam Pridgen <adam.pridgen@thecoverofnight.com> Date: Mon Sep 2 22:56:56 2013 -0500 - Revamped all of the attribute parsing. The parsers will handle buffers rather than simply parsing straight from the file. - added a size calculator for each of the attributes, which opens up the way for creating writers for the attributes and such. commit be6f2e038f01beeb56ace7d4daaf4d90ad3fdad7 Author: Adam Pridgen <adam.pridgen@thecoverofnight.com> Date: Sat Aug 31 12:19:18 2013 -0500 - Cleaned up code and removed some of the compiler warnings. commit 4c81812f2609e4a80c7036053d122306039dd6ef Author: Adam Pridgen <adam.pridgen@thecoverofnight.com> Date: Fri Aug 30 15:24:15 2013 -0500 - Compiler and linker errors have been resolved. - Need to work on testing commit 429ed30621d9abff1eec99ef50a35c57bbed76ad Author: Adam Pridgen <adam.pridgen@thecoverofnight.com> Date: Fri Aug 30 13:35:39 2013 -0500 Added the RunTime Annotations and Parameter annotations. Time to start compiling and testing. commit b6044e1c74cc10874902bd34da7c8fcbdb5713cc Author: Adam Pridgen <adam.pridgen@thecoverofnight.com> Date: Fri Aug 30 12:34:14 2013 -0500 Added BootstrapMethodsAttr Parsing code along with supporting stuff, like creating the method and argument structures and mapping the REF_types to strings More should be done to map the REF_types to specific resolutions. Added in the MethodType, MethodHandle, and InvokeDynamic ConstantPool Objects commit 2c9317be5d2be0608131fb9aa10f713885c89471 Author: Adam Pridgen <adam.pridgen@thecoverofnight.com> Date: Fri Aug 30 00:21:34 2013 -0500 Finished drafting the code for annotation, element values, element value pairs, and annotation default attribute. TODO: RTI, RTV, and then Bootstrap attributes. commit cbee3a10c18342f6a8fb941245568de885fe5666 Author: Adam Pridgen <adam.pridgen@thecoverofnight.com> Date: Thu Aug 29 15:42:00 2013 -0500 Fixed the r_bin_java_element_value_new function definition. commit ab98a76fabf2bd7764a51f3363d821c5a4cf1200 Author: Adam Pridgen <adam.pridgen@thecoverofnight.com> Date: Thu Aug 29 15:39:28 2013 -0500 - worked out some of the initial compile errors. - worked out an outline for parsing the element_values - need to work through parsing the element value, freeing the element value, and then printing a summary. commit b543d904f2aebd0d1f9c0ac8ec8401b6ab698f36 Author: Adam Pridgen <adam.pridgen@thecoverofnight.com> Date: Thu Aug 29 08:21:33 2013 -0500 Most of the heavy lifting is done for attributes. Need to implement a few of the methods, and then compiling should be able to happen. Added in all attribute values to the enums, the function call tables, and then the Metas information. Need implement an ElementValue parser bleh. Need to implement RuntimeAnnotations, Annotations, ElementValue parsing and make sure that the attribute unions are all updated. commit 81f9ca2da2ed7e007a97a20ecb8eb260dfd55e7e Author: Adam Pridgen <adam.pridgen@thecoverofnight.com> Date: Wed Aug 28 22:33:43 2013 -0500 Finished adding some logic to handle the StackMapFrame types. commit 9a0965cc06021ad56d2127d279b918eef613bec9 Author: Adam Pridgen <adam.pridgen@thecoverofnight.com> Date: Wed Aug 28 17:54:52 2013 -0500 Got some of the StackMapTable Atrribute parsing working. Right now, only the FullStackFrame will correctly parse. commit ea12bd6a8ae9969fa05cbcab622651c8b426917a Author: Adam Pridgen <adam.pridgen@thecoverofnight.com> Date: Fri Aug 23 17:51:33 2013 -0500 Added some debugging code while trying to figure out how to parse the StackMapTable. commit 6141b57ee94c7bd0569d0ea76725fdce1ac50edf Author: Adam Pridgen <adam.pridgen@thecoverofnight.com> Date: Fri Aug 23 17:00:12 2013 -0500 Code compiles. commit a7ad14050eb6184a1171620c4dcdba71b2f791aa Author: Adam Pridgen <adam.pridgen@thecoverofnight.com> Date: Fri Aug 23 10:29:17 2013 -0500 - Added a basic Signature element - Added declarations for the new functions to handle the parsing of the StackMapTable related structures. commit 54cca3d9af60463dbfa77e23ef1d562ae82d6e5a Author: Adam Pridgen <adam.pridgen@thecoverofnight.com> Date: Fri Aug 23 10:18:50 2013 -0500 Finished an initial coding implementation of the StackMapTable. -- Will perform testing later in the day. -- Need to look-up the Signature Attribute commit a14238eece865f4d1c5f2d6b1f482b000d10d94e Author: Adam Pridgen <adam.pridgen@thecoverofnight.com> Date: Thu Aug 22 20:23:45 2013 -0500 StackMap stuff is wip. commit f011a5d948d31cc6197eed1bbea497a4dde362aa Author: Adam Pridgen <adam.pridgen@thecoverofnight.com> Date: Thu Aug 22 18:44:23 2013 -0500 Made the globals match the R_* standard. Also tried to clean up naming stuff. commit 6e61e15572744c2ed722ac3df8d988cc02f1316c Author: Adam Pridgen <adam.pridgen@thecoverofnight.com> Date: Thu Aug 22 16:40:08 2013 -0500 Plugging progress into the repo. Adding fixes to handle the Java Class file appropriately. This modification is mostly a re-write of the Class File parser, and it "tries" to do a better job of creating better objects for each of the Classfile elements. Currently this code is experimental, and current TODOs are: 1) Testing 2) StackMapTable 3) LocalVariableTypeTable
2013-09-04 15:04:36 +00:00
static void init_switch_op (void) {
2017-06-24 17:58:48 +00:00
memset (&SWITCH_OP, 0, sizeof (SWITCH_OP));
}
static int enter_switch_op (ut64 addr, const ut8* bytes, int len) {
#if 0
int sz = ((BYTES_CONSUMED+1) % 4)
? (1 + 4 - (BYTES_CONSUMED+1) % 4)
: 1; // + (BYTES_CONSUMED+1) % 4;
#endif
2017-06-24 17:58:48 +00:00
if (len < 16) {
return 0;
2017-06-24 17:58:48 +00:00
}
int sz = 4;
int sz2 = (4 - (addr+1) % 4) + (addr+1) % 4;
IFDBG eprintf ("Addr approach: 0x%04x and BYTES_CONSUMED approach: 0x%04"PFMT64x", BYTES_CONSUMED%%4 = 0x%04x\n",
sz2, BYTES_CONSUMED, sz);
init_switch_op ();
IN_SWITCH_OP = 1;
SWITCH_OP.addr = addr;
SWITCH_OP.def_jmp = (UINT (bytes, sz));
SWITCH_OP.min_val = (UINT (bytes, sz + 4));
SWITCH_OP.max_val = (UINT (bytes, sz + 8));
sz += 12;
return sz;
}
static bool isRelative (ut32 type) {
if (type & R_ANAL_JAVA_CODEOP_CJMP) {
return true;
}
if (type & R_ANAL_JAVA_CODEOP_JMP) {
return true;
}
return false;
}
static int update_bytes_consumed (int sz) {
BYTES_CONSUMED += sz;
return sz;
}
static int update_switch_op (ut64 addr, const ut8 * bytes) {
int sz = 4;
int ccase = SWITCH_OP.cur_val + SWITCH_OP.min_val;
SWITCH_OP.cur_val++;
if (ccase+1 > SWITCH_OP.max_val) {
IN_SWITCH_OP = 0;
}
IFDBG {
eprintf ("Addr approach: 0x%04"PFMT64x
" and BYTES_CONSUMED approach: 0x%04"PFMT64x
"\n", addr, BYTES_CONSUMED);
}
2017-06-24 17:58:48 +00:00
return update_bytes_consumed (sz);
}
static int handle_switch_op (ut64 addr, const ut8 * bytes, char *output, int outlen ) {
int sz = 4;
ut32 jmp = (int)(UINT (bytes, 0)) + SWITCH_OP.addr;
int ccase = SWITCH_OP.cur_val + SWITCH_OP.min_val;
2017-06-24 17:58:48 +00:00
snprintf (output, outlen, "case %d: goto 0x%04x", ccase, jmp);
update_switch_op (addr, bytes);
2017-06-24 17:58:48 +00:00
return update_bytes_consumed (sz);
}
R_API int java_print_opcode(RBinJavaObj *obj, ut64 addr, int idx, const ut8 *bytes, int len, char *output, int outlen) {
char *arg = NULL; //(char *) malloc (1024);
int sz = 0;
2017-06-24 17:58:48 +00:00
ut32 val_one = 0;
ut32 val_two = 0;
ut8 op_byte = JAVA_OPS[idx].byte;
if (IN_SWITCH_OP) {
return handle_switch_op (addr, bytes, output, outlen );
}
#if 0
2017-12-27 17:33:58 +00:00
IFDBG eprintf ("Handling the following opcode %s expects: %d byte(s), BYTES_CONSUMED: 0x%04"PFMT64x"\n",
JAVA_OPS[idx].name, JAVA_OPS[idx].size, BYTES_CONSUMED);
#endif
switch (op_byte) {
case 0x10: // "bipush"
snprintf (output, outlen, "%s %d", JAVA_OPS[idx].name, (char) bytes[1]);
output[outlen-1] = 0;
return update_bytes_consumed (JAVA_OPS[idx].size);
case 0x11:
snprintf (output, outlen, "%s %d", JAVA_OPS[idx].name, (int)USHORT (bytes, 1));
output[outlen-1] = 0;
return update_bytes_consumed (JAVA_OPS[idx].size);
case 0x15: // "iload"
case 0x16: // "lload"
case 0x17: // "fload"
case 0x18: // "dload"
case 0x19: // "aload"
case 0x37: // "lstore"
case 0x38: // "fstore"
case 0x39: // "dstore"
case 0x3a: // "astore"
case 0xbc: // "newarray"
case 0xa9: // ret <var-num>
snprintf (output, outlen, "%s %d", JAVA_OPS[idx].name, bytes[1]);
output[outlen-1] = 0;
return update_bytes_consumed (JAVA_OPS[idx].size);
2013-11-14 01:41:03 +00:00
case 0x12: // ldc
arg = r_bin_java_resolve_without_space (obj, (ut16)bytes[1]);
if (arg) {
snprintf (output, outlen, "%s %s", JAVA_OPS[idx].name, arg);
free (arg);
} else {
snprintf (output, outlen, "%s #%d", JAVA_OPS[idx].name, USHORT (bytes, 1));
}
output[outlen-1] = 0;
return update_bytes_consumed (JAVA_OPS[idx].size);
case 0x13:
case 0x14:
arg = r_bin_java_resolve_without_space (obj, (int)USHORT (bytes, 1));
if (arg) {
snprintf (output, outlen, "%s %s", JAVA_OPS[idx].name, arg);
free (arg);
} else {
snprintf (output, outlen, "%s #%d", JAVA_OPS[idx].name, USHORT (bytes, 1));
}
output[outlen-1] = 0;
return update_bytes_consumed (JAVA_OPS[idx].size);
case 0x84: // iinc
val_one = (ut32)bytes[1];
val_two = (ut32) bytes[2];
snprintf (output, outlen, "%s %d %d", JAVA_OPS[idx].name, val_one, val_two);
output[outlen-1] = 0;
return update_bytes_consumed (JAVA_OPS[idx].size);
case 0x99: // ifeq
case 0x9a: // ifne
case 0x9b: // iflt
case 0x9c: // ifge
case 0x9d: // ifgt
case 0x9e: // ifle
case 0x9f: // if_icmpeq
case 0xa0: // if_icmpne
case 0xa1: // if_icmplt
case 0xa2: // if_icmpge
case 0xa3: // if_icmpgt
case 0xa4: // if_icmple
case 0xa5: // if_acmpne
case 0xa6: // if_acmpne
case 0xa7: // goto
case 0xa8: // jsr
snprintf (output, outlen, "%s 0x%04"PFMT64x, JAVA_OPS[idx].name,
(addr+(short)USHORT (bytes, 1)));
output[outlen-1] = 0;
return update_bytes_consumed (JAVA_OPS[idx].size);
// XXX - Figure out what constitutes the [<high>] value
case 0xab: // tableswitch
case 0xaa: // tableswitch
sz = enter_switch_op (addr, bytes, len);
snprintf (output, outlen, "%s default: 0x%04"PFMT64x,
JAVA_OPS[idx].name,
(ut64)(SWITCH_OP.def_jmp+SWITCH_OP.addr));
return update_bytes_consumed (sz);
case 0xb6: // invokevirtual
case 0xb7: // invokespecial
case 0xb8: // invokestatic
case 0xb9: // invokeinterface
case 0xba: // invokedynamic
arg = r_bin_java_resolve_without_space (obj, (int)USHORT (bytes, 1));
if (arg) {
snprintf (output, outlen, "%s %s", JAVA_OPS[idx].name, arg);
free (arg);
} else {
snprintf (output, outlen, "%s #%d", JAVA_OPS[idx].name, USHORT (bytes, 1) );
}
output[outlen-1] = 0;
return update_bytes_consumed (JAVA_OPS[idx].size);
case 0xbb: // new
case 0xbd: // anewarray
case 0xc0: // checkcast
case 0xc1: // instance of
2016-04-10 23:48:50 +00:00
arg = r_bin_java_resolve_without_space (obj, (int)USHORT (bytes, 1));
if (arg) {
snprintf (output, outlen, "%s %s", JAVA_OPS[idx].name, arg);
free (arg);
} else {
snprintf (output, outlen, "%s #%d", JAVA_OPS[idx].name, USHORT (bytes, 1) );
}
output[outlen-1] = 0;
return update_bytes_consumed (JAVA_OPS[idx].size);
case 0xb2: // getstatic
case 0xb3: // putstatic
case 0xb4: // getfield
case 0xb5: // putfield
arg = r_bin_java_resolve_with_space (obj, (int)USHORT (bytes, 1));
if (arg) {
snprintf (output, outlen, "%s %s", JAVA_OPS[idx].name, arg);
free (arg);
} else {
snprintf (output, outlen, "%s #%d", JAVA_OPS[idx].name, USHORT (bytes, 1) );
}
output[outlen-1] = 0;
return update_bytes_consumed (JAVA_OPS[idx].size);
}
/* process arguments */
switch (JAVA_OPS[idx].size) {
case 1: snprintf (output, outlen, "%s", JAVA_OPS[idx].name);
break;
case 2: snprintf (output, outlen, "%s %d", JAVA_OPS[idx].name, bytes[1]);
break;
case 3: snprintf (output, outlen, "%s 0x%04x 0x%04x", JAVA_OPS[idx].name, bytes[0], bytes[1]);
break;
case 5: snprintf (output, outlen, "%s %d", JAVA_OPS[idx].name, bytes[1]);
break;
}
return update_bytes_consumed (JAVA_OPS[idx].size);
}
R_API void r_java_new_method (void) {
IFDBG eprintf ("Reseting the bytes consumed, they were: 0x%04"PFMT64x".\n", BYTES_CONSUMED);
init_switch_op ();
IN_SWITCH_OP = 0;
BYTES_CONSUMED = 0;
}
2014-05-12 02:06:40 +00:00
R_API void U(r_java_set_obj)(RBinJavaObj *obj) {
// eprintf ("SET CP (%p) %d\n", cp, n);
//BIN_OBJ = obj;
}
R_API int r_java_disasm(RBinJavaObj *obj, ut64 addr, const ut8 *bytes, int len, char *output, int outlen) {
//r_cons_printf ("r_java_disasm (allowed %d): 0x%02x, 0x%0x.\n", outlen, bytes[0], addr);
return java_print_opcode (obj, addr, bytes[0], bytes, len, output, outlen);
}
2017-06-24 17:58:48 +00:00
static int parseJavaArgs(char *str, ut64 *args, int args_sz) {
int i, nargs = -1;
char *q, *p = strchr (str, ' ');
if (p) {
*p++ = 0;
nargs ++;
for (i = 0; i < args_sz; i++) {
nargs ++;
q = strchr (p, ' ');
if (q) {
*q++ = 0;
}
args[i] = r_num_math (NULL, p);
if (q) {
p = q;
} else {
break;
}
}
}
return nargs;
}
R_API int r_java_assemble(ut64 addr, ut8 *bytes, const char *string) {
2017-06-24 17:58:48 +00:00
ut64 args[4] = {0};
int i, a, b, c, d;
char name[128];
2017-06-24 17:58:48 +00:00
strncpy (name, string, sizeof (name) - 1);
name[sizeof (name) - 1] = 0;
int nargs = parseJavaArgs (name, args, 4);
a = args[0];
b = args[1];
c = args[2];
d = args[3];
for (i = 0; JAVA_OPS[i].name != NULL; i++) {
if (!strcmp (name, JAVA_OPS[i].name)) {
bytes[0] = JAVA_OPS[i].byte;
switch (JAVA_OPS[i].size) {
2017-06-24 17:58:48 +00:00
case 2: bytes[1] = a;
break;
case 3:
if (nargs == 2) {
bytes[1] = a;
bytes[2] = b;
} else {
if (isRelative (JAVA_OPS[i].op_type)) {
// relative jmp
a -= addr;
}
2017-06-24 17:58:48 +00:00
bytes[1] = (a >> 8) & 0xff;
bytes[2] = a & 0xff;
}
break;
case 5: bytes[1] = a;
bytes[2] = b;
bytes[3] = c;
bytes[4] = d;
break;
}
return JAVA_OPS[i].size;
}
2017-06-24 17:58:48 +00:00
}
return 0;
}