ClassFile
{
u4 magic;
u2 minor_version;
u2 major_version;
u2 constant_pool_count;
cp_info constant_pool[constant_pool_count-1];
u2 access_flags;
u2 this_class;
u2 super_class;
u2 interfaces_count;
u2 interfaces[interfaces_count];
u2 fields_count;
field_info fields[fields_count];
u2 methods_count;
method_info methods[methods_count];
u2 attributes_count;
attribute_info attributes[attributes_count];
}
構造体の形を見る限りこのような構成になっている
となっているから、interfaces
countまでは2バイトづつとっていけば良いだろう。
Interface Fieldsともにカウントがゼロで、メソッドが二つだった。
method_info
{
u2 access_flags;
u2 name_index;
u2 descriptor_index;
u2 attributes_count;
attribute_info attributes[attributes_count];
}
attribute_info
{
u2 attribute_name_index;
u4 attribute_length;
u1 info[attribute_length];
}
これに前回の表をあてはめていく
No |
tag |
Index |
|
|
|
|
1 |
0A |
0006 |
0014 |
|
|
|
2 |
09 |
0015 |
0016 |
|
|
|
3 |
08 |
0017 |
|
|
|
|
4 |
0A |
0018 |
0019 |
|
|
|
5 |
07 |
001A |
|
|
|
|
6 |
07 |
001B |
|
|
|
|
7 |
01 |
|
|
<init> |
|
|
8 |
01 |
|
|
()V |
|
|
9 |
01 |
|
|
Code |
|
|
A |
01 |
|
|
LineNumberTable |
|
|
B |
01 |
|
|
LocalVariableTable |
|
|
C |
01 |
|
|
This |
|
|
D |
01 |
|
|
Ltest/test; |
|
|
E |
01 |
|
|
|
|
|
F |
01 |
|
|
([Ljava/lang/String;)V |
|
|
10 |
01 |
|
|
Args |
|
|
11 |
01 |
|
|
[Ljava/lang/String; |
|
|
12 |
01 |
|
|
SourceFile |
|
|
13 |
0C |
0007 |
0008 |
|
|
|
14 |
07 |
001C |
|
|
|
|
15 |
0C |
001D |
001E |
|
|
|
16 |
01 |
|
|
test.java |
|
|
17 |
07 |
001F |
|
|
|
|
18 |
0C |
0020 |
0021 |
|
|
|
19 |
01 |
|
|
ABCDEFG |
|
|
1A |
01 |
|
|
test/test |
|
|
1B |
01 |
|
|
java/lang/Object |
|
|
1C |
01 |
|
|
java/lang/System |
|
|
1D |
01 |
|
|
Out |
|
|
1E |
01 |
|
|
Ljava/io/PrintStream; |
|
|
1F |
01 |
|
|
java/io/PrintStream |
|
|
20 |
01 |
|
|
Println |
|
|
21 |
01 |
|
|
(Ljava/lang/String;)V |
|
|
|
|
|
|
|
|
|
No |
tag |
Index |
|
|
|
|
1 |
0A |
0006 |
0014 |
class_index java/lang/Object name_and_type_index <init> ()V |
CONSTANT_Methodref_info |
|
2 |
09 |
0015 |
0016 |
class_index Lout LJava/io/Printstream name_and_type_index test.java |
CONSTANT_Fieldref_inf |
|
3 |
08 |
0017 |
|
string_index java/io/printstream |
CONSTANT_String_info |
|
4 |
0A |
0018 |
0019 |
class_index java/io/printstream name_and_type_index “ABCDEFG” |
CONSTANT_Methodref_info |
|
5 |
07 |
001A |
|
Test/test |
CONSTANT_Class_info |
|
6 |
07 |
001B |
|
Java/lang/Object |
CONSTANT_Class_info |
|
13 |
0C |
0007 |
0008 |
name_index <init>
descriptor_index ()V |
CONSTANT_NameAndType_info |
|
14 |
07 |
001C |
|
Java/lang/System |
CONSTANT_Class_info |
|
15 |
0C |
001D |
001E |
name_index LOut. descriptor_index Ljava/io/PrintStream |
CONSTANT_NameAndType_info |
|
17 |
07 |
001F |
|
Java/io/PrintStream |
CONSTANT_Class_info |
|
18 |
0C |
0020 |
0021 |
name_index Println. descriptor_index (Ljava/lang/String) |
CONSTANT_NameAndType_info |
|
Attributeの意味はおいといて、CODEというのがわれわれが捜し求めていたいとしいしと、バイトコードであると推測できる。Init で33バイト・Mainで37バイトのコードを利用している。それぞれのAttributeも仕様が明示されていてCODEも構造が書いてあった。
Code_attribute
{
u2 attribute_name_index;
u4 attribute_length;
u2 max_stack;
u2 max_locals;
u4 code_length;
u1 code[code_length];
u2 exception_table_length;
{ u2 start_pc;
u2 end_pc;
u2 handler_pc;
u2 catch_type;
} exception_table[exception_table_length];
u2 attributes_count;
attribute_info attributes[attributes_count];
}
この構造をあてはめると以下のようになる
ようやく5バイトと9バイトの命令セット(コード本体)が現れた。うれしいのでこれを逆ハンドアセンブルする。
2A/B7/00/01/B1
B2/00/02/12/03/B6/00/04/B1
文法の常識としてオペコード・オペランドとくるはずだ。それぞれの文頭は以下の
aload_0
getstatic
オペコードに対応しているのが分かった。
Aloadはrefference型のロード命令で詳細は不明。その次が、invokespecial ということになるはずで、これは後にバイトのオペランドを必要とするらしく0001の読み込みをこれで行うということになるんではないだろうか。コンスタンとプールの0001はinitなので、これで初期化めそっどを呼び出したことになるのだろう。
Getstatic は0002対して何かやってるので、io.クラスの読み込みか何かだろうか。続いての12はldcで03がオペランドのようだ。次に
invokevirtualを呼び出して0004をインヴォークしている。この0004がprintstream “ABCDEFG”のことになっている。
最後はどちらもB1で恐らく終了コマンドかなにかだろう。調べてみたらreturnということであった。
今までの経緯を逆ハンドアセンブルしてみる
:初期化コード
Aload_0;
Invokespesial <0001>;
Return;
:メインコード
Getstatic <0002>;
Ldc <03>;
Invokevirtual <0004>;
Return;
なんだか真面目にここまでやってタイトルもない。
えんでー、エンエンエーン
おわり