MASTG-KNOW-0008 デバッグ情報とデバッグシンボル (Debugging Information and Debug Symbols)

Android では、ネイティブライブラリは通常、NDK を使用して C または C++ で開発され、.so 拡張子を持つ ELF 共有オブジェクトにコンパイルされ、APK の lib/ ディレクトリに格納します。これらのライブラリは、多くの場合、Java Native Interface (JNI) を通じて Dalvik から使用される機能を公開します。これらのバイナリ内の デバッグシンボル は、関数名、変数名、ソースファイルマッピングなどの詳細を提供し、リバースエンジニアリング、デバッグ、セキュリティ解析に役立ちます。

プログラムをコンパイルおよびリンクする際、シンボルは関数または変数を表します。ELF (Executable and Linkable Format) ファイルでは、シンボルは異なる役割を果たします。

  • ローカルシンボル: 定義されたファイル内でのみ視認できます。内部的に使用されます。他のファイルからはアクセスできません。

  • グローバルシンボル: 他のファイルから視認できます。異なるオブジェクトファイル間でファイルや変数を共有するために使用されます。

  • ウィークシンボル: グローバルシンボルと似ていますが優先度が低くなります。ストロング (非ウィーク) シンボルとウィークシンボルの両方が存在する場合、ストロングシンボルがウィークシンボルをオーバーライドします。

プロダクションビルドでは、バイナリサイズを削減し、情報開示を制限するために、デバッグ情報を削除する必要があります。しかし、デバッグビルドまたは内部ビルドはバイナリ内または別のコンパニオンファイルにシンボルを保持することがあります。

シンボルの可視性は誤って扱われることがよくあり、シンボルの意図しない外部公開につながり、手動検査を必要とします。

シンボルテーブルと DWARF セクション

ELF 形式は、シンボル情報を格納するためにどのセクションを使用する必要があるかを定義しています。

  • .symtab: リンク時に使用される完全なシンボルテーブル。プロダクションバイナリでは削除されることがよくあります (DT_SYMTAB dtag)。

  • .dynsym: ランタイムリンク時に使用される動的シンボルテーブル。共有オブジェクトには常に存在します。

DWARF は ELF バイナリで使用される標準デバッグ形式です (ただし、Apple エコシステムの MACH-O バイナリなど、他の UNIX ベースのシステムでも使用されています)。主なセクションは以下のとおりです。

  • .debug_info: 型、関数定義、スコープなど、主要なデバッグ情報を含みます。

  • .debug_line: マシンコードをソースコードの行番号にマップします。

  • .debug_str: DWARF エントリで使用される文字列を格納します。

  • .debug_loc, .debug_ranges, .debug_abbrev など: 詳細なデバッグメタデータをサポートします。

さらに、一部のツールチェーンは DWARF データのバイナリサイズを縮小するために zlib 圧縮 を使用します (たとえば clanggcc-gz オプションを使用してこれをサポートしています)。これらのセクションは一般的に .z プレフィックスを使用して名前付けされ (例: .zdebug_info, .zdebug_line, .zdebug_str など)、圧縮されていないセクションと同じ情報を含みます。これらをサポートしていない一部の解析ツールでは、削除されているものとしてバイナリを誤って報告されることがあります。

バイナリ内にこれらのセクションが存在するかどうかをチェックするには、objdump - iOS (-x オプションを使用)、radare2 for Android (iS コマンド)、readelf などのその他のツールを使用できます。

たとえば、radare2 を使用する場合:

重要: これらのセクションが存在するからといって、必ずしもバイナリが削除されていないことを示すわけではありません。一部のツールチェーンではストリップされたバイナリでもこれらのセクションを保持することがありますが、多くの場合、空であるか、最低限の情報のみ含みます。最終的に、重要なのは シンボル自体がまだ存在しているかどうか です。デバッグシンボルの抽出と解析方法の詳細については デバッグ情報とシンボルの取得 (Obtaining Debugging Information and Symbols) を参照してください。

外部デバッグシンボルファイル

Android 開発者ドキュメント では、リリースビルドのネイティブライブラリはデフォルトで削除されると説明しています。シンボル化されたネイティブクラッシュレポートを有効にするには、別途デバッグシンボルファイル (一般的に <variant>/native-debug-symbols.zip にあります) を生成し、Google Play Console にアップロードする必要があります。この ZIP アーカイブは DWARF デバッグ情報を埋め込まれた完全な 削除されていない .so ファイル を含みます。DWARF データは個別のファイル (.dwo など) に分割されず、各 .so 内に残ります。

このシンボル化プロセスは ProGuard または R8 で難読化された Java/Kotlin コードの スタックトレースの難読化解除 するために mapping.txt ファイルをアップロードすることに似ています。

対照的に、iOS は Linux ツールチェーンでおなじみの split DWARF精神的に似た アプローチを使用しています。Apple 開発者ドキュメント に従って、Xcode で DWARF with dSYM File オプションを有効にすると、リリースビルド用に個別のデバッグシンボルファイル (.dSYM) を生成します。これらはクラッシュレポートのシンボル化のために Apple のシンボルサーバーにアップロードできます。

Last updated

Was this helpful?