Xamarin アプリ

Tip

AWSハッキングを学び、実践する:HackTricks Training AWS Red Team Expert (ARTE)
GCPハッキングを学び、実践する:HackTricks Training GCP Red Team Expert (GRTE) Azureハッキングを学び、実践する:HackTricks Training Azure Red Team Expert (AzRTE)

HackTricksをサポートする

基本情報

Xamarin は、.NET と C# フレームワークを使用して iOS、Android、Windows 向けのアプリを構築する 開発者向けの オープンソースのプラットフォーム です。このプラットフォームは、モダンなアプリケーションを効率的に作成するための多数のツールや拡張機能へのアクセスを提供します。

Xamarin のアーキテクチャ

  • For Android, Xamarin は Android と Java の名前空間を .NET バインディングを通じて統合し、Android Runtime (ART) と並んで Mono 実行環境内で動作します。Managed Callable Wrappers (MCW) と Android Callable Wrappers (ACW) は Mono と ART 間の通信を仲介し、どちらも Linux kernel 上に構築されています。
  • For iOS, アプリケーションは Mono runtime 上で動作し、C# .NET コードを ARM アセンブリ言語に変換するフル Ahead of Time (AOT) コンパイルを利用します。このプロセスは Objective-C Runtime と並行して UNIX-like kernel 上で実行されます。

.NET Runtime and Mono Framework

.NET framework はアプリケーション開発用のアセンブリ、クラス、名前空間を含み、.NET Runtime がコード実行を管理します。プラットフォーム独立性と後方互換性を提供します。Mono Framework は .NET framework のオープンソース版で、2005 年に .NET を Linux に拡張するために開始され、現在は Microsoft によってサポートされ、Xamarin が主導しています。

Reverse Engineering Xamarin Apps

Decompilation of Xamarin Assemblies

デコンパイルはコンパイル済みコードをソースコードに戻すプロセスです。Windows では Visual Studio の Modules window でデコンパイル対象のモジュールを特定でき、サードパーティのコードへの直接アクセスや解析のためのソースコード抽出が可能になります。

JIT vs AOT Compilation

  • Android は Just-In-Time (JIT) と Ahead-Of-Time (AOT) の両方をサポートしており、実行速度を最適化するための Hybrid AOT モードがあります。Full AOT は Enterprise ライセンス専用です。
  • iOS は Apple の動的コード実行制限のため、AOT コンパイルのみを採用しています。

Extracting dll Files from APK/IPA

APK/IPA 内のアセンブリにアクセスするには、ファイルを unzip して assemblies ディレクトリを調べます。Android の場合、XamAsmUnZxamarin-decompress のようなツールで dll ファイルを解凍できます。

python3 xamarin-decompress.py -o /path/to/decompressed/apk

APKを逆コンパイルした後に unknown/assemblies/ フォルダ内に .dll ファイルが見える場合、dnSpy.dlls に対して直接使用して解析することが可能です。しかし、場合によっては unknown/assemblies/ フォルダ内に assemblies.blobassemblies.manifest ファイルが存在します。ツール pyxamstore は Xamarin アプリの assemblies.blob ファイルを展開し、.NET アセンブリへアクセスしてさらなる解析を可能にします:

pyxamstore unpack -d /path/to/decompressed/apk/assemblies/
# After patching DLLs, rebuild the store
pyxamstore pack

.NET MAUI 9 / .NET for Android のアセンブリストアが ELF .so 内に格納される

最近の Android MAUI 9 ビルドでは assemblies.blob が直接公開されなくなりました。代わりに、各 ABI は lib/arm64-v8a/libassemblies.arm64-v8a.blob.so のような ELF コンテナを同梱します。これはカスタムの payload セクションを持つ有効な共有ライブラリで、その中にマネージドアセンブリストアが格納されています。

Quick workflow:

unzip app.apk -d app_unpacked
llvm-readelf --section-headers app_unpacked/lib/arm64-v8a/libassemblies.arm64-v8a.blob.so
llvm-objcopy --dump-section=payload=payload.bin \
app_unpacked/lib/arm64-v8a/libassemblies.arm64-v8a.blob.so
hexdump -c -n 4 payload.bin   # XABA

llvm-readelfpayload セクションを示す場合、それをダンプして抽出されたブロブが XABA (0x41424158) で始まることを確認してください。 その payload は .NET for Android によって文書化されたアセンブリストアであり、単一の DLL ではありません。

ストアのレイアウトは、アセンブリを手動で切り出す必要がある場合や抽出器を検証する際に便利です:

  • ヘッダー: struct.unpack('<5I', ...)magic, version, entry_count, index_entry_count, index_size
  • ディスクリプタ: entry_count 件の struct.unpack('<7I', ...) レコード(data_offset / data_size と任意の debug/config オフセットを含む)
  • インデックス: index_size バイトをスキップ
  • 名前: uint32 length + UTF-8 バイト
  • データ: 各 data_offset にシークして data_size バイトを <name>.dll として書き出す

抽出されたエントリの一部は、さらに XALZ でラップされているため dnSpy/ILSpy/dotPeek で直接開けないことがあります。その場合:

  • 抽出した各ファイルの先頭4バイトが XALZ か確認する
  • バイト 8:12 からリトルエンディアンの uint32 として非圧縮サイズを読む
  • バイト 12:lz4.block.decompress(...) で展開する

最小限の展開ロジック:

import struct
import lz4.block

def decompress_xalz(data):
size = struct.unpack('<I', data[8:12])[0]
return lz4.block.decompress(data[12:], uncompressed_size=size)

ストアを手動で解析したくない場合、pymauistore は MAUI 9 APK の ELF ペイロード抽出、XABA ストア解析、XALZ の解凍を自動化します。

古い Xamarin/MAUI ビルドの一部は、/assemblies.blob/resources/assemblies 内に XALZ 形式で圧縮されたアセンブリを格納しています。これらは xamarout ライブラリで素早く解凍できます:

from xamarout import xalz
import os
for root, _, files in os.walk("."):
for f in files:
if open(os.path.join(root, f), 'rb').read(4) == b"XALZ":
xa = xalz.XamarinCompressedAssembly(os.path.join(root, f))
xa.write("decompressed/" + f)

iOSのdllファイルは逆コンパイルに容易にアクセス可能で、アプリケーションコードの大部分が明らかになり、異なるプラットフォーム間で共通の基盤を共有していることが多い。

AOT on iOS: 管理された IL はネイティブの *.aotdata.* ファイルにコンパイルされます。DLLだけをパッチしてもロジックは変わりません。IL 本体は空のプレースホルダになっているため、ネイティブスタブをフックする必要があります(例: Frida を使用して)。

Static Analysis

.dll を入手すれば、dnSpyILSpy などのツールで .Net コードを静的に解析し、アプリのコードを変更することが可能です。例えば保護を回避する目的でアプリを改変する際に非常に役立ちます。
変更後はアプリを再パッケージして再署名する必要があることに注意してください。

dnSpy はアーカイブされていますが、dnSpyEx のようなメンテナンスされたフォークは .NET 8/MAUI アセンブリで動作し、再保存時にデバッグシンボルを保持します。

Dynamic Analysis

Dynamic Analysis では SSL pinning の確認や、Xamarin アプリ内の .NET バイナリをランタイムで改変するために Fridax のようなツールを使用します。Frida スクリプトは root 検出や SSL pinning をバイパスするために利用でき、解析能力を向上させます。

その他の興味深い Frida スクリプト:

更新された Frida-xamarin-unpin (Mono >=6) は System.Net.Http.HttpClient.SendAsync をフックし、ハンドラを許容的なものに差し替えるため、カスタムハンドラで pinning が実装されている場合でも機能します。アプリ起動後に実行してください:

frida -U -l dist/xamarin-unpin.js com.target.app --no-pause

バンドルされた frida-mono-api を使ってマネージドメソッドを hook するための簡易テンプレート:

const mono = require('frida-mono-api');
Mono.ensureInitialized();
Mono.enumerateLoadedImages().forEach(i => console.log(i.name));
const klass = Mono.classFromName("Namespace", "Class");
const m = Mono.methodFromName(klass, "Method", 2);
Mono.intercept(m, { onEnter(args){ console.log(args[1].toInt32()); } });

再署名

The tool Uber APK Signer は、同じキーで複数のAPKに署名する作業を簡素化し、アプリに変更を加えた後に再署名するために使用できます。

参考資料

Tip

AWSハッキングを学び、実践する:HackTricks Training AWS Red Team Expert (ARTE)
GCPハッキングを学び、実践する:HackTricks Training GCP Red Team Expert (GRTE) Azureハッキングを学び、実践する:HackTricks Training Azure Red Team Expert (AzRTE)

HackTricksをサポートする