In the Reversing Java: Part I, I’ve described the main structure of Java class file bytes. In this part, I’ll continue decompiling the HelloWorld example.
Again the bytes of compiled class files is inserted:
We have analyzed till constant pool. Each constant pool entry has the following structure:
cp_info {
u1 tag;
u1 info[];
}
The tag indicates what type of constant is the following constant and the info (length of info) depends of the tag type. List of allowed tags are:
Constant Type | Value |
CONSTANT_Class | 7 |
CONSTANT_Fieldref | 9 |
CONSTANT_Methodref | 10 |
CONSTANT_InterfaceMethodref | 11 |
CONSTANT_String | 8 |
CONSTANT_Integer | 3 |
CONSTANT_Float | 4 |
CONSTANT_Long | 5 |
CONSTANT_Double | 6 |
CONSTANT_NameAndType | 12 |
CONSTANT_Utf8 | 1 |
Constant Pool (from [1] to [28]):
Constant Pool = cp
cp[1]: {tag = 0a} => CONSTANT_Methodref
The info[] of method ref contains four bytes for the method. Two bytes for class name and two bytes for name and type => class name: 00 06 (cp[6]), name and type: 00 0f (cp[15])
cp[2]: {tag = 09} => CONSTANT_Fieldref
info[] part is just like class ref => class name: 00 10 (cp[16]), name and type: 00 11 (cp[17])
cp[3]: {tag = 08} => CONSTANT_String
info[] part has reference for string itself (two bytes). 00 12 means that the real string is in cp[18].
cp[4]: {tag = 0a} => CONSTANT_Methodref
class name: 00 13 (cp[19]), name and type: 00 14 (cp[20])
cp[5]: {tag = 07} => CONSTANT_Class
info[] part has two bytes indicating the class. 00 15 (cp[21])
cp[6]: {tag = 07} => CONSTANT_Class
00 16 (cp[22])
cp[7]: {tag = 01} => CONSTANT_Utf8
info[] part has two bytes indicating string length and the remaining length bytes is string itself encoded in UTF8. 00 06 => String has 6 bytes.
(next 6 bytes): 3c 69 6e 69 74 3e => <init>
cp[8]: {tag = 01} => CONSTANT_Utf8
length: 00 03 (3)
String: 28 29 56 => ()V
cp[9]: {tag = 01} => CONSTANT_Utf8
length: 00 04 (4)
String: 43 6f 64 65 => Code
cp[10]: {tag = 01} => CONSTANT_Utf8
length: 00 0f (15)
String: 4c 69 6e 65 4e 75 6d 62 65 72 54 61 62 6c 65 => LineNumberTable
cp[11]: {tag = 01} => CONSTANT_Utf8
length: 00 04 (4)
String: 6d 61 69 6e => main
cp[12]: {tag = 01} => CONSTANT_Utf8
length: 00 16 (22)
String: 28 5b 4c 6a 61 76 61 2f 6c 61 6e 67 2f 53 74 72 69 6e 67 3b 29 56 => ([Ljava/lang/String;)V
cp[13]: {tag = 01} => CONSTANT_Utf8
length: 00 0a (10)
String: 53 6f 75 72 63 65 46 69 6c 65 => SourceFile
cp[14]: {tag = 01} => CONSTANT_Utf8
length: 00 0f (15)
String: 48 65 6c 6c 6f 57 6f 72 6c 64 2e 6a 61 76 61 => HelloWorld.java
cp[15]: {tag = 0c} => CONSTANT_NameAndType
info[] has four bytes, two for name two for descriptor:
name: 00 07 (cp[07]), descriptor: 00 08 (cp[08])
cp[16]: {tag = 07} => CONSTANT_ClassInfo
class name: 00 17 (cp[23])
cp[17]: {tag = 0c} => CONSTANT_NameAndType
name: 00 18 (cp[24]), descriptor: 00 19 (cp[25])
cp[18]: {tag = 01} => CONSTANT_Utf8
length: 00 0c (12)
String: 48 65 6c 6c 6f 20 57 6f 72 6c 64 21 => Hello World!
cp[19]: {tag = 07} => CONSTANT_ClassInfo
class name: 00 1a (cp[26])
cp[20]: {tag = 0c} => CONSTANT_NameAndType
name: 00 1b (cp[27]), descriptor: 00 1c (cp[28])
cp[21]: {tag = 01} => CONSTANT_Utf8
length: 00 0a (10)
String: 48 65 6c 6c 6f 57 6f 72 6c 64 => HelloWorld
cp[22]: {tag = 01} => CONSTANT_Utf8
length: 00 10 (16)
String: 01 20 10 6a 61 76 61 2f 6c 61 6e 67 2f 53 79 73 => java/lang/Object
cp[23]: {tag = 01} => CONSTANT_Utf8
length: 00 10 (16)
String: 6a 61 76 61 2f 6c 61 6e 67 2f 53 79 73 74 65 6d => java/lang/System
cp[24]: {tag = 01} => CONSTANT_Utf8
length: 00 03 (03)
String: 6f 75 74 => out
cp[25]: {tag = 01} => CONSTANT_Utf8
length: 00 15 (21)
String: 4c 6a 61 76 61 2f 69 6f 2f 50 72 69 6e 74 53 74 72 65 61 6d 3b => Ljava/io/PrintStream;
cp[26]: {tag = 01} => CONSTANT_Utf8
length: 00 13 (19)
String: 6a 61 76 61 2f 69 6f 2f 50 72 69 6e 74 53 74 72 65 61 6d => java/io/PrintStream;
cp[27]: {tag = 01} => CONSTANT_Utf8
length: 00 07 (07)
String: 70 72 69 6e 74 6c 6e => println
cp[28]: {tag = 01} => CONSTANT_Utf8
length: 00 15 (21)
String: 28 4c 6a 61 76 61 2f 6c 61 6e 67 2f 53 74 72 69 6e 67 3b 29 56 => (Ljava/lang/String;)V
The above fields were constant fields in a simple java class. The remaining bytes will be discussed in the next tutorial.
For more information you may refer to:
[1] https://docs.oracle.com/javase/specs/jvms/se8/jvms8.pdf
[2] https://docs.oracle.com/javase/specs/jvms/se7/jvms7.pdf
[3] http://se.inf.ethz.ch/old/teaching/ss2007/0284/Slides/Lect9-2.pdf
You can Read the rest of this article in reversing-java-part-iii.