Upgrade to PRO for Only $50/Year—Limited-Time Offer! 🔥

バイナリビューアを使ってクラスファイルを読んでみよう! #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. 自己紹介 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
  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
  3. クラスファイルとは? • Java のソースコードをコンパイルしてできるバイナリーファイル • 実行に必要な情報が含まれている • クラス定義 • フィールド定義

    • メソッド定義 • バイトコード(プログラム本体) など • バイナリーなので… • コンピューターで処理しやすい • ふつうの人間には読みにくい(≠読めない) • javap というツールで、逆アセンブル(解析)できる
  4. クラスファイルの位置づけ .java (ソースコード) テキスト形式 .class (クラスファイル) バイナリー形式 JVM (Java仮想マシン) javac

    java javap コンパイル 実行 逆アセンブル結果 テキスト形式 OS / CPU 命令 javap の詳細やクラスファイルの中身 については、前回の資料を参照 https://yuji.software/javap/
  5. 使うのはバイナリエディタ or ビューア • 通常、エディタといえばテキストエディタ • バイナリを文字符号化方式に沿ってテキストに変換して表示する • バイナリエディタは、バイナリをそのまま表示する •

    代表的なバイナリエディタ・ビューア • Windows • Binary Editor BZ https://gitlab.com/devill.tamachan/binaryeditorbz/ • Linux / UNIX • hexdump –C <ファイル名>
  6. 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
  7. 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 ← 時間の関係で、今日はここまで
  8. バイナリに当てはめる • 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; …
  9. 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 …
  10. 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
  11. エンディアン? • 複数バイトのデータを、どのような順番で格納するかの規則 • バイトオーダーとも言う • 例えば、同じ 0x1234ABCD というデータでも… •

    ビッグエンディアン(上位から) • リトルエンディアン(下位から) • どちらを採用しているか、バイナリを読む際は要注意 12 34 AB CD CD AB 34 12
  12. 次は 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
  13. 定数プールとは? • いろいろな種類の定数を表現するための構造体の配列 • 文字列 • 数値 • クラス名 •

    フィールド名 • … など • フィールド情報やメソッド情報などから、インデックスで参照 • 各要素は、先頭1バイト目のタグによって区別
  14. 定数プールの中身 • クラスファイルを javap したもの(抜粋) • これが、バイナリーでどのように表現されているのか Constant pool: #1

    = Methodref #2.#3 // java/lang/Object."<init>":()V #2 = Class #4 // java/lang/Object #3 = NameAndType #5:#6 // "<init>":()V #4 = Utf8 java/lang/Object #5 = Utf8 <init> #6 = Utf8 ()V #7 = Fieldref #8.#9 // java/lang/System.out:Ljava/io/PrintStream; #8 = Class #10 // java/lang/System …
  15. 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 …
  16. 定数プールの構造 • 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
  17. 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) }
  18. 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) }
  19. 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) }
  20. つまり… • #1 は java.lang.Object クラスの <init>()V メソッド(= 引数 なしコンストラクタ)を参照している

    インデックス 種類 データ #1 Methodref クラス定義:#2、名前&型定義:#3 #2 Class クラス名:#4 #3 NameAndType 名前:#5、型定義:#6 #4 UTF8 java/lang/Object #5 UTF8 <init> #6 UTF8 ()V
  21. 定数プールの構造 (再掲) • このうち読み方で注意が 必要なものを解説 • 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
  22. 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 …
  23. 文字列の形式 • 修正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 はない • 長さが定義されているので、必要ない
  24. 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
  25. javap で確認 • この設計は、 poor choice (悪い選択だった)と設計書にコメ ントがある Constant pool:

    ... #28 = Utf8 AGE #29 = Utf8 J #30 = Long 38l #32 = Utf8 Code #33 = Utf8 LineNumberTable Long のあとは一つインデックスが飛ぶ (インデックス #31 が存在しない)
  26. 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 ← 次の説明
  27. 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
  28. 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 - - - - - - - - - - - -
  29. これが読めるになった!? 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
  30. まとめ • クラスファイルは、Java のソースコードをコンパイルしてでき るバイナリーファイル • バイナリビューアを使って読める • バイナリを読むには、構造と読み方を知る必要がある •

    構造:何ビット目は何を意味しているのか • 読み方:エンディアン / 文字列 / ビットフラグ • どんなバイナリーでも、基本は同じ • ぜひ、いろんなバイナリを読んでみましょう!