Reverse Engineering for Beginners

(avery) #1

CHAPTER 54. JAVA CHAPTER 54. JAVA


This way of passing constants is not unique to JVM. MIPS, ARM and other RISC CPUs also can’t encode a 32-bit number in a
32-bit opcode, so the RISC CPU code (including MIPS and ARM) has to construct the value in several steps, or to keep it in
the data segment: 28.3 on page 425,29.1 on page 428.


MIPS code also traditionally has a constant pool, named “literal pool”, the segments are called “.lit4” (for 32-bit single
precision floating point number constants) and “.lit8” (for 64-bit double precision floating point number constants).


Let’s try some other data types!


Boolean:


public class ret
{
public static boolean main(String[] args)
{
return true;
}
}


public static boolean main(java.lang.String[]);
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=1, locals=1, args_size=1
0: iconst_1
1: ireturn

This JVM bytecode is no different from one returning integer 1. 32-bit data slots in the stack are also used here for boolean
values, like in C/C++. But one could not use returned boolean value as integer or vice versa—type information is stored in
the class file and checked at runtime.


It’s the same story with a 16-bitshort:


public class ret
{
public static short main(String[] args)
{
return 1234;
}
}


public static short main(java.lang.String[]);
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=1, locals=1, args_size=1
0: sipush 1234
3: ireturn

...andchar!


public class ret
{
public static char main(String[] args)
{
return 'A';
}
}


public static char main(java.lang.String[]);
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=1, locals=1, args_size=1
0: bipush 65
2: ireturn

bipushmeans “push byte”. Needless to say that acharin Java is 16-bit UTF-16 character, and it’s equivalent toshort, but
the ASCII code of the “A” character is 65, and it’s possible to use the instruction for pushing a byte in the stack.


Let’s also try abyte:

Free download pdf