Upgrade to Pro — share decks privately, control downloads, hide ads and more …

バイナリビューアを使ってクラスファイルを読んでみよう! #jjug_ccc

YujiSoftware
November 11, 2023

バイナリビューアを使ってクラスファイルを読んでみよう! #jjug_ccc

11月11日(土)に開催された、JJUG CCC 2023 Fall のセッション資料です。
関連資料: https://github.com/YujiSoftware/binary

YujiSoftware

November 11, 2023
Tweet

More Decks by YujiSoftware

Other Decks in Programming

Transcript

  1. バイナリビューアを使って
    クラスファイルを読んでみよう!
    @YujiSoftware
    https://yuji.software/binary/

    View full-size slide

  2. 自己紹介
    CA FE BA BE 00 00 00 41 00 26 0A 00 02 00 03 07 00 04 0C 00 05 00 06 01 00 10 6A 61 76 61 2F 6C
    61 6E 67 2F 4F 62 6A 65 63 74 01 00 06 3C 69 6E 69 74 3E 01 00 03 28 29 56 09 00 08 00 09 07 00
    0A 0C 00 0B 00 0C 01 00 10 6A 61 76 61 2F 6C 61 6E 67 2F 53 79 73 74 65 6D 01 00 03 6F 75 74 01
    00 15 4C 6A 61 76 61 2F 69 6F 2F 50 72 69 6E 74 53 74 72 65 61 6D 3B 08 00 0E 01 00 15 E9 A0 91
    E5 BC B5 E3 82 8A E3 81 BE E3 81 99 ED A0 BD ED B9 82 0A 00 10 00 11 07 00 12 0C 00 13 00 14 01
    00 13 6A 61 76 61 2F 69 6F 2F 50 72 69 6E 74 53 74 72 65 61 6D 01 00 07 70 72 69 6E 74 6C 6E 01
    00 15 28 4C 6A 61 76 61 2F 6C 61 6E 67 2F 53 74 72 69 6E 67 3B 29 56 07 00 16 01 00 04 4D 61 69
    6E 01 00 07 54 57 49 54 54 45 52 01 00 12 4C 6A 61 76 61 2F 6C 61 6E 67 2F 53 74 72 69 6E 67 3B
    01 00 0D 43 6F 6E 73 74 61 6E 74 56 61 6C 75 65 08 00 1B 01 00 0D 40 59 75 6A 69 53 6F 66 74 77
    61 72 65 01 00 03 41 47 45 01 00 01 4A 05 00 00 00 00 00 00 00 26 01 00 04 43 6F 64 65 01 00 0F
    4C 69 6E 65 4E 75 6D 62 65 72 54 61 62 6C 65 01 00 04 6D 61 69 6E 01 00 16 28 5B 4C 6A 61 76 61
    2F 6C 61 6E 67 2F 53 74 72 69 6E 67 3B 29 56 01 00 0A 53 6F 75 72 63 65 46 69 6C 65 01 00 09 4D
    61 69 6E 2E 6A 61 76 61 00 21 00 15 00 02 00 00 00 02 00 19 00 17 00 18 00 01 00 19 00 00 00 02
    00 1A 00 19 00 1C 00 1D 00 01 00 19 00 00 00 02 00 1E 00 02 00 01 00 05 00 06 00 01 00 20 00 00
    00 1D 00 01 00 01 00 00 00 05 2A B7 00 01 B1 00 00 00 01 00 21 00 00 00 06 00 01 00 00 00 02 00
    09 00 22 00 23 00 01 00 20 00 00 00 25 00 02 00 01 00 00 00 09 B2 00 07 12 0D B6 00 0F B1 00 00
    00 01 00 21 00 00 00 0A 00 02 00 00 00 07 00 08 00 08 00 01 00 24 00 00 00 02 00 25

    View full-size slide

  3. 本日の目標: これを読めるようになる!
    CA FE BA BE 00 00 00 41 00 26 0A 00 02 00 03 07 00 04 0C 00 05 00 06 01 00 10 6A 61 76 61 2F 6C
    61 6E 67 2F 4F 62 6A 65 63 74 01 00 06 3C 69 6E 69 74 3E 01 00 03 28 29 56 09 00 08 00 09 07 00
    0A 0C 00 0B 00 0C 01 00 10 6A 61 76 61 2F 6C 61 6E 67 2F 53 79 73 74 65 6D 01 00 03 6F 75 74 01
    00 15 4C 6A 61 76 61 2F 69 6F 2F 50 72 69 6E 74 53 74 72 65 61 6D 3B 08 00 0E 01 00 15 E9 A0 91
    E5 BC B5 E3 82 8A E3 81 BE E3 81 99 ED A0 BD ED B9 82 0A 00 10 00 11 07 00 12 0C 00 13 00 14 01
    00 13 6A 61 76 61 2F 69 6F 2F 50 72 69 6E 74 53 74 72 65 61 6D 01 00 07 70 72 69 6E 74 6C 6E 01
    00 15 28 4C 6A 61 76 61 2F 6C 61 6E 67 2F 53 74 72 69 6E 67 3B 29 56 07 00 16 01 00 04 4D 61 69
    6E 01 00 07 54 57 49 54 54 45 52 01 00 12 4C 6A 61 76 61 2F 6C 61 6E 67 2F 53 74 72 69 6E 67 3B
    01 00 0D 43 6F 6E 73 74 61 6E 74 56 61 6C 75 65 08 00 1B 01 00 0D 40 59 75 6A 69 53 6F 66 74 77
    61 72 65 01 00 03 41 47 45 01 00 01 4A 05 00 00 00 00 00 00 00 26 01 00 04 43 6F 64 65 01 00 0F
    4C 69 6E 65 4E 75 6D 62 65 72 54 61 62 6C 65 01 00 04 6D 61 69 6E 01 00 16 28 5B 4C 6A 61 76 61
    2F 6C 61 6E 67 2F 53 74 72 69 6E 67 3B 29 56 01 00 0A 53 6F 75 72 63 65 46 69 6C 65 01 00 09 4D
    61 69 6E 2E 6A 61 76 61 00 21 00 15 00 02 00 00 00 02 00 19 00 17 00 18 00 01 00 19 00 00 00 02
    00 1A 00 19 00 1C 00 1D 00 01 00 19 00 00 00 02 00 1E 00 02 00 01 00 05 00 06 00 01 00 20 00 00
    00 1D 00 01 00 01 00 00 00 05 2A B7 00 01 B1 00 00 00 01 00 21 00 00 00 06 00 01 00 00 00 02 00
    09 00 22 00 23 00 01 00 20 00 00 00 25 00 02 00 01 00 00 00 09 B2 00 07 12 0D B6 00 0F B1 00 00
    00 01 00 21 00 00 00 0A 00 02 00 00 00 07 00 08 00 08 00 01 00 24 00 00 00 02 00 25

    View full-size slide

  4. 目次
    • 自己紹介
    • クラスファイルとは何か
    • ツールの紹介
    • クラスファイルを読む
    • まとめ

    View full-size slide

  5. クラスファイルとは?
    • Java のソースコードをコンパイルしてできるバイナリーファイル
    • 実行に必要な情報が含まれている
    • クラス定義
    • フィールド定義
    • メソッド定義
    • バイトコード(プログラム本体) など
    • バイナリーなので…
    • コンピューターで処理しやすい
    • ふつうの人間には読みにくい(≠読めない)
    • javap というツールで、逆アセンブル(解析)できる

    View full-size slide

  6. クラスファイルの位置づけ
    .java
    (ソースコード)
    テキスト形式
    .class
    (クラスファイル)
    バイナリー形式
    JVM
    (Java仮想マシン)
    javac java
    javap
    コンパイル 実行
    逆アセンブル結果
    テキスト形式
    OS / CPU
    命令
    javap の詳細やクラスファイルの中身
    については、前回の資料を参照
    https://yuji.software/javap/

    View full-size slide

  7. 早速、エディタで
    クラスファイルを見てみましょう

    View full-size slide

  8. エディタでクラスファイルを見る

    View full-size slide

  9. 使うのはバイナリエディタ or ビューア
    • 通常、エディタといえばテキストエディタ
    • バイナリを文字符号化方式に沿ってテキストに変換して表示する
    • バイナリエディタは、バイナリをそのまま表示する
    • 代表的なバイナリエディタ・ビューア
    • Windows
    • Binary Editor BZ
    https://gitlab.com/devill.tamachan/binaryeditorbz/
    • Linux / UNIX
    • hexdump –C <ファイル名>

    View full-size slide

  10. IDE でバイナリを読む方法
    • Visual Studio Code
    • Hex Editor プラグインを導入
    https://marketplace.visualstudio.com/items?itemName=ms-
    vscode.hexeditor
    • Vim
    • :%! xxd で16進数表示に切り替え、終わったら :%! xxd –r で戻す
    • Emacs
    • M-x hexl-mode に切り替える
    https://www.gnu.org/software/emacs/manual/html_node/emacs/E
    diting-Binary-Files.html

    View full-size slide

  11. バイナリエディタでクラスファイルを見る

    View full-size slide

  12. 結局、なにも分からない
    (´・ω・`)

    View full-size slide

  13. バイナリーを理解するには
    • 何も知らないと、数字(16進数)の羅列に見える
    • でも、それぞれの数字には意味がある
    • どこに、どんな内容があるのか
    → 構造(フォーマット)を知ろう!
    • 数字が何を意味しているのか
    → 数字の読み方を知ろう!

    View full-size slide

  14. Java のクラスファイルフォーマット
    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];
    }
    https://docs.oracle.com/javase/
    specs/jvms/se21/html/jvms-4.html
    ← 時間の関係で、今日はここまで

    View full-size slide

  15. バイナリに当てはめる
    • u4 … 符号なし 4byte データ
    • u2 … 符号なし 2byte データ
    • cp_info … 定数プール構造体
    u4: CA FE BA BE magic;
    u2: 00 00 minor_version;
    u2: 00 41 major_version;
    u2: 00 26 constant_pool_count;
    cp_info: 0A 00 02 00 03 constant_pool[constant_pool_count – 1];
    07 00 04
    0C 00 05 00 06

    u2: 00 21 access_flags;

    View full-size slide

  16. 数字の意味を詳しく
    見ていきましょう

    View full-size slide

  17. u4: magic
    • バイナリーの種類を識別するため値(マジック・ナンバー)
    • 大抵のバイナリーには、最初のあたりにマジック・ナンバーがある
    • クラスファイルの場合、0xCAFEBABE という固定値
    • James Gosling(Java の生みの親)が決めた
    • 0xCAFE で始まる16進数を探して、これがいい感じだったから
    https://en.wikipedia.org/wiki/Java_class_file#Magic_Number
    CA FE BA BE 00 00 00 41 00 26 0A 00 02 00 03 07 …

    View full-size slide

  18. u2: minor_version, u2: major_version
    • minor_version
    • 基本的に 0x0000
    • --preview でコンパイルすると
    0xFFFF
    • major_version
    • Java 21 で 0x0041 (= 65)
    • どの環境でコンパイルしても
    ビッグエンディアンで格納
    CA FE BA BE 00 00 00 41 00 26 0A 00 02 00 03 07 …
    Javaリリース クラスファイルバージョン
    Java 1.0 45.0
    Java 1.1 45.3
    Java 1.2 46.0
    Java 1.3 47.0
    … …
    Java 20 64.0
    Java 21 65.0
    Java 22 66.0
    … …
    Java 65491 65535.0

    View full-size slide

  19. エンディアン?
    • 複数バイトのデータを、どのような順番で格納するかの規則
    • バイトオーダーとも言う
    • 例えば、同じ 0x1234ABCD というデータでも…
    • ビッグエンディアン(上位から)
    • リトルエンディアン(下位から)
    • どちらを採用しているか、バイナリを読む際は要注意
    12 34 AB CD
    CD AB 34 12

    View full-size slide

  20. 次は constant_pool(定数プール)
    CA FE BA BE 00 00 00 41 00 26 0A 00 02 00 03 07 00 04 0C 00 05 00 06 01 00 10 6A 61 76 61 2F 6C
    61 6E 67 2F 4F 62 6A 65 63 74 01 00 06 3C 69 6E 69 74 3E 01 00 03 28 29 56 09 00 08 00 09 07 00
    0A 0C 00 0B 00 0C 01 00 10 6A 61 76 61 2F 6C 61 6E 67 2F 53 79 73 74 65 6D 01 00 03 6F 75 74 01
    00 15 4C 6A 61 76 61 2F 69 6F 2F 50 72 69 6E 74 53 74 72 65 61 6D 3B 08 00 0E 01 00 15 E9 A0 91
    E5 BC B5 E3 82 8A E3 81 BE E3 81 99 ED A0 BD ED B9 82 0A 00 10 00 11 07 00 12 0C 00 13 00 14 01
    00 13 6A 61 76 61 2F 69 6F 2F 50 72 69 6E 74 53 74 72 65 61 6D 01 00 07 70 72 69 6E 74 6C 6E 01
    00 15 28 4C 6A 61 76 61 2F 6C 61 6E 67 2F 53 74 72 69 6E 67 3B 29 56 07 00 16 01 00 04 4D 61 69
    6E 01 00 07 54 57 49 54 54 45 52 01 00 12 4C 6A 61 76 61 2F 6C 61 6E 67 2F 53 74 72 69 6E 67 3B
    01 00 0D 43 6F 6E 73 74 61 6E 74 56 61 6C 75 65 08 00 1B 01 00 0D 40 59 75 6A 69 53 6F 66 74 77
    61 72 65 01 00 03 41 47 45 01 00 01 4A 05 00 00 00 00 00 00 00 26 01 00 04 43 6F 64 65 01 00 0F
    4C 69 6E 65 4E 75 6D 62 65 72 54 61 62 6C 65 01 00 04 6D 61 69 6E 01 00 16 28 5B 4C 6A 61 76 61
    2F 6C 61 6E 67 2F 53 74 72 69 6E 67 3B 29 56 01 00 0A 53 6F 75 72 63 65 46 69 6C 65 01 00 09 4D
    61 69 6E 2E 6A 61 76 61 00 21 00 15 00 02 00 00 00 02 00 19 00 17 00 18 00 01 00 19 00 00 00 02
    00 1A 00 19 00 1C 00 1D 00 01 00 19 00 00 00 02 00 1E 00 02 00 01 00 05 00 06 00 01 00 20 00 00
    00 1D 00 01 00 01 00 00 00 05 2A B7 00 01 B1 00 00 00 01 00 21 00 00 00 06 00 01 00 00 00 02 00
    09 00 22 00 23 00 01 00 20 00 00 00 25 00 02 00 01 00 00 00 09 B2 00 07 12 0D B6 00 0F B1 00 00
    00 01 00 21 00 00 00 0A 00 02 00 00 00 07 00 08 00 08 00 01 00 24 00 00 00 02 00 25

    View full-size slide

  21. 定数プールとは?
    • いろいろな種類の定数を表現するための構造体の配列
    • 文字列
    • 数値
    • クラス名
    • フィールド名
    • … など
    • フィールド情報やメソッド情報などから、インデックスで参照
    • 各要素は、先頭1バイト目のタグによって区別

    View full-size slide

  22. 定数プールの中身
    • クラスファイルを javap したもの(抜粋)
    • これが、バイナリーでどのように表現されているのか
    Constant pool:
    #1 = Methodref #2.#3 // java/lang/Object."":()V
    #2 = Class #4 // java/lang/Object
    #3 = NameAndType #5:#6 // "":()V
    #4 = Utf8 java/lang/Object
    #5 = Utf8
    #6 = Utf8 ()V
    #7 = Fieldref #8.#9 // java/lang/System.out:Ljava/io/PrintStream;
    #8 = Class #10 // java/lang/System

    View full-size slide

  23. u2: constant_pool_count,
    cp_info: constant_pool[constant_pool_count-1];
    • constant_pool_count
    • 定数の個数 + 1
    • 今回は 0x0026 (= 38)
    • constant_pool
    • 定数プール(= 配列)
    • インデックスは、最初が 1 で、最後が constant_pool_count – 1
    • インデックス 0 は「何もない」という用途に使う
    https://stackoverflow.com/a/56808835/1932017
    00 26 0A 00 02 00 03 07 00 04 0C 00 05 00 06 01 00 …

    View full-size slide

  24. 定数プールの構造
    • 1バイト目
    • 定数の種類を表す番号(タグ)
    • 全部で17種類
    • Java 11 で CONSTANT_Dynamic
    が追加された
    • 2バイト目以降
    • タグの中身
    • 詳細は、種類によって異なる
    • 長さがバラバラで読みにくい…
    定数の種類 タグ 長さ Java SE
    CONSTANT_Utf8 0x01 可変 1.0.3
    CONSTANT_Integer 0x03 5 1.0.3
    CONSTANT_Float 0x04 5 1.0.3
    CONSTANT_Long 0x05 7 1.0.3
    CONSTANT_Double 0x06 7 1.0.3
    CONSTANT_Class 0x07 3 1.0.3
    CONSTANT_String 0x08 3 1.0.3
    CONSTANT_Fieldref 0x09 5 1.0.3
    CONSTANT_Methodref 0x0A 5 1.0.3
    CONSTANT_InterfaceMethodref 0x0B 5 1.0.3
    CONSTANT_NameAndType 0x0C 5 1.0.3
    CONSTANT_MethodHandle 0x0E 4 7
    CONSTANT_MethodType 0x10 3 7
    CONSTANT_Dynamic 0x11 5 11
    CONSTANT_InvokeDynamic 0x12 5 7
    CONSTANT_Module 0x13 3 9
    CONSTANT_Package 0x14 3 9

    View full-size slide

  25. constant_pool(#1)
    • 1バイト目:0x0A = CONSTANT_Methodref(メソッド参照)
    • CONSTANT_Methodref_info に当てはめて読む
    • 定数プールのクラス定義と名前&型定義を参照している
    00 26 0A 00 02 00 03 07 00 04 0C 00 05 00 06 01 00 …
    CONSTANT_Methodref_info {
    u1 tag; // タグ(0x0A)
    u2 class_index; // クラス定義のインデックス(0x0002)
    u2 name_and_type_index; // 名前&型定義のインデックス(0x0003)
    }

    View full-size slide

  26. constant_pool(#2)
    • 1バイト目:0x07 = CONSTANT_Class(クラス定義)
    • CONSTANT_Class_info に当てはめて読む
    • クラス名として、定数プール#4の文字列を参照している
    00 26 0A 00 02 00 03 07 00 04 0C 00 05 00 06 01 00 …
    CONSTANT_Class_info {
    u1 tag; // タグ(0x07)
    u2 name_index; // クラス名のインデックス(0x0004)
    }

    View full-size slide

  27. constant_pool(#3)
    • 1バイト目:0x0C = CONSTANT_NameAndType(名前&型定義)
    • CONSTANT_NameAndType_info に当てはめて読む
    • 定数プールの名前と記述子(型定義)を参照している
    00 26 0A 00 02 00 03 07 00 04 0C 00 05 00 06 01 00 …
    CONSTANT_NameAndType_info {
    u1 tag; // タグ(0x0C)
    u2 name_index; // 名前のインデックス(0x0005)
    u2 descriptor_index; // 記述子(型定義)のインデックス(0x0006)
    }

    View full-size slide

  28. つまり…
    • #1 は java.lang.Object クラスの ()V メソッド(= 引数
    なしコンストラクタ)を参照している
    インデックス 種類 データ
    #1 Methodref クラス定義:#2、名前&型定義:#3
    #2 Class クラス名:#4
    #3 NameAndType 名前:#5、型定義:#6
    #4 UTF8 java/lang/Object
    #5 UTF8
    #6 UTF8 ()V

    View full-size slide

  29. 定数プールの構造
    (再掲)
    • このうち読み方で注意が
    必要なものを解説
    • Constant_UTF8
    • Constant_Long
    定数の種類 タグ 長さ Java SE
    CONSTANT_Utf8 0x01 可変 1.0.3
    CONSTANT_Integer 0x03 5 1.0.3
    CONSTANT_Float 0x04 5 1.0.3
    CONSTANT_Long 0x05 7 1.0.3
    CONSTANT_Double 0x06 7 1.0.3
    CONSTANT_Class 0x07 3 1.0.3
    CONSTANT_String 0x08 3 1.0.3
    CONSTANT_Fieldref 0x09 5 1.0.3
    CONSTANT_Methodref 0x0A 5 1.0.3
    CONSTANT_InterfaceMethodref 0x0B 5 1.0.3
    CONSTANT_NameAndType 0x0C 5 1.0.3
    CONSTANT_MethodHandle 0x0E 4 7
    CONSTANT_MethodType 0x10 3 7
    CONSTANT_Dynamic 0x11 5 11
    CONSTANT_InvokeDynamic 0x12 5 7
    CONSTANT_Module 0x13 3 9
    CONSTANT_Package 0x14 3 9

    View full-size slide

  30. CONSTANT_Utf8 (文字列)
    • 長さの上限は UTF-8 で 0xFFFF = 65535bytes まで
    • それを超える文字列リテラルは、コンパイル時にエラーになる
    • クラス名やメソッド名も、文字列定数として格納している
    • そのため、上記の長さの制限を受ける
    CONSTANT_Utf8_info {
    u1 tag; // タグ (0x01)
    u2 length; // 文字列の長さ(0x0010)
    u1 bytes[length]; // 修正 UTF-8 文字列(6A 61 76 61 2F 6C 61 6E 67 …)
    }
    01 00 10 6A 61 76 61 2F 6C 61 6E 67 2F 4F 62 6A 65 …

    View full-size slide

  31. 文字列の形式
    • 修正UTF-8:通常の UTF-8 に、少し変更を加えた形式
    • 0x00(¥0)は、代わりに 0xF0FF を使う
    • 0xF0FF をデコードすると、0x00 になる
    • 文字列中の 0x00 と、C言語の文字列終端を表す 0x00 を区別するため?
    • UTF-8 で4バイト以上の文字(絵文字とか)はサロゲートペアを使う
    • 例: 🙂 (UTF-8: F0 9F 99 82) は、ED A0 BD ED B9 82 になる
    • 初期の Unicode では、3バイトを超えることを想定していなかった
    • C言語と異なり、末尾の ¥0 はない
    • 長さが定義されているので、必要ない

    View full-size slide

  32. CONSTANT_Long (64ビット整数)
    • 仕様上、4バイト(32ビット)2つに分かれている
    • 2つ分のエントリーを使う
    • つまり、このインデックス + 1 は使わない(次ページ参照)
    • CONSTANT_Double_info(64ビット浮動小数) も同様
    CONSTANT_Long_info {
    u1 tag; // タグ (0x05)
    u4 high_bytes; // 上位バイト(0x00000000)
    u4 low_bytes; // 下位バイト(0x00000026)
    }
    05 00 00 00 00 00 00 00 26

    View full-size slide

  33. javap で確認
    • この設計は、 poor choice (悪い選択だった)と設計書にコメ
    ントがある
    Constant pool:
    ...
    #28 = Utf8 AGE
    #29 = Utf8 J
    #30 = Long 38l
    #32 = Utf8 Code
    #33 = Utf8 LineNumberTable
    Long のあとは一つインデックスが飛ぶ
    (インデックス #31 が存在しない)

    View full-size slide

  34. Java のクラスファイルフォーマット(再掲)
    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];
    }
    https://docs.oracle.com/javase/
    specs/jvms/se21/html/jvms-4.html
    ← 次の説明

    View full-size slide

  35. u2: access_flags
    • クラスやインターフェイスのアクセス
    許可や属性を示すフラグ
    • ACC_INTERFACE / ACC_MODULE がな
    ければ、クラス
    • 今回の値は、0x0021
    • 表に該当するものがない…?
    00 21 00 15 00 02 00 00 00 02 00 19 00 17 00 18 00 …
    フラグ名 値
    ACC_PUBLIC 0x0001
    ACC_FINAL 0x0010
    ACC_SUPER 0x0020
    ACC_INTERFACE 0x0200
    ACC_ABSTRACT 0x0400
    ACC_SYNTHETIC 0x1000
    ACC_ANNOTATION 0x2000
    ACC_ENUM 0x4000
    ACC_MODULE 0x8000

    View full-size slide

  36. access_flags の判定方法
    • ビットフラグになっている
    • 0x0021 は、ACC_PUBLIC と ACC_SUPERがセットされた値
    フラグ名 16進数 2進数
    (今回の値) 0x0021 - - - - - - - - - - 1 - - - - 1
    ACC_PUBLIC 0x0001 - - - - - - - - - - - - - - - 1
    ACC_FINAL 0x0010 - - - - - - - - - - - 1 - - - -
    ACC_SUPER 0x0020 - - - - - - - - - - 1 - - - - -
    ACC_INTERFACE 0x0200 - - - - - - 1 - - - - - - - - -
    ACC_ABSTRACT 0x0400 - - - - - 1 - - - - - - - - - -
    ACC_SYNTHETIC 0x1000 - - - 1 - - - - - - - - - - - -

    View full-size slide

  37. これ以降もだいたい同じ

    View full-size slide

  38. これが読めるになった!?
    CA FE BA BE 00 00 00 41 00 26 0A 00 02 00 03 07 00 04 0C 00 05 00 06 01 00 10 6A 61 76 61 2F 6C
    61 6E 67 2F 4F 62 6A 65 63 74 01 00 06 3C 69 6E 69 74 3E 01 00 03 28 29 56 09 00 08 00 09 07 00
    0A 0C 00 0B 00 0C 01 00 10 6A 61 76 61 2F 6C 61 6E 67 2F 53 79 73 74 65 6D 01 00 03 6F 75 74 01
    00 15 4C 6A 61 76 61 2F 69 6F 2F 50 72 69 6E 74 53 74 72 65 61 6D 3B 08 00 0E 01 00 15 E9 A0 91
    E5 BC B5 E3 82 8A E3 81 BE E3 81 99 ED A0 BD ED B9 82 0A 00 10 00 11 07 00 12 0C 00 13 00 14 01
    00 13 6A 61 76 61 2F 69 6F 2F 50 72 69 6E 74 53 74 72 65 61 6D 01 00 07 70 72 69 6E 74 6C 6E 01
    00 15 28 4C 6A 61 76 61 2F 6C 61 6E 67 2F 53 74 72 69 6E 67 3B 29 56 07 00 16 01 00 04 4D 61 69
    6E 01 00 07 54 57 49 54 54 45 52 01 00 12 4C 6A 61 76 61 2F 6C 61 6E 67 2F 53 74 72 69 6E 67 3B
    01 00 0D 43 6F 6E 73 74 61 6E 74 56 61 6C 75 65 08 00 1B 01 00 0D 40 59 75 6A 69 53 6F 66 74 77
    61 72 65 01 00 03 41 47 45 01 00 01 4A 05 00 00 00 00 00 00 00 26 01 00 04 43 6F 64 65 01 00 0F
    4C 69 6E 65 4E 75 6D 62 65 72 54 61 62 6C 65 01 00 04 6D 61 69 6E 01 00 16 28 5B 4C 6A 61 76 61
    2F 6C 61 6E 67 2F 53 74 72 69 6E 67 3B 29 56 01 00 0A 53 6F 75 72 63 65 46 69 6C 65 01 00 09 4D
    61 69 6E 2E 6A 61 76 61 00 21 00 15 00 02 00 00 00 02 00 19 00 17 00 18 00 01 00 19 00 00 00 02
    00 1A 00 19 00 1C 00 1D 00 01 00 19 00 00 00 02 00 1E 00 02 00 01 00 05 00 06 00 01 00 20 00 00
    00 1D 00 01 00 01 00 00 00 05 2A B7 00 01 B1 00 00 00 01 00 21 00 00 00 06 00 01 00 00 00 02 00
    09 00 22 00 23 00 01 00 20 00 00 00 25 00 02 00 01 00 00 00 09 B2 00 07 12 0D B6 00 0F B1 00 00
    00 01 00 21 00 00 00 0A 00 02 00 00 00 07 00 08 00 08 00 01 00 24 00 00 00 02 00 25

    View full-size slide

  39. まとめ
    • クラスファイルは、Java のソースコードをコンパイルしてでき
    るバイナリーファイル
    • バイナリビューアを使って読める
    • バイナリを読むには、構造と読み方を知る必要がある
    • 構造:何ビット目は何を意味しているのか
    • 読み方:エンディアン / 文字列 / ビットフラグ
    • どんなバイナリーでも、基本は同じ
    • ぜひ、いろんなバイナリを読んでみましょう!

    View full-size slide

  40. バイナリビューアを使って
    クラスファイルを読んでみよう!
    @YujiSoftware
    https://yuji.software/binary/

    View full-size slide