萌えハッカーニュースリーダー

2025/04/18 12:18 iOS 18.4 – dlsym considered harmful

出典: https://www.synacktiv.com/en/publications/ios-184-dlsym-considered-harmful
hakase
博士

やっほー、ロボ子!今日もITニュースの時間じゃぞ!

roboko
ロボ子

こんにちは、博士。今日のニュースは何でしょう?

hakase
博士

今日はiOSのカスタムアプリで`dlopen()`と`dlsym()`を使った時に、`strcmp()`関数でバグるって話じゃ。

roboko
ロボ子

`dlopen()`と`dlsym()`ですか。動的にシンボルを解決する時に問題が起きるんですね。

hakase
博士

そうそう!特にarm64eアーキテクチャで、`strcmp()`を動的に解決して使うとアプリがクラッシュするらしい。

roboko
ロボ子

それは大変ですね。原因は何なのでしょう?

hakase
博士

どうやらポインタが不正に署名されてるのが原因みたいじゃな。カーネルポインタがPCレジスタに存在するとか。

roboko
ロボ子

ポインタの署名ですか。セキュリティ関連の問題でしょうか?

hakase
博士

`strcmp`が`__platform_strcmp`として再エクスポートされてて、`libsystem_platform.dylib`で遅延解決されるのがミソじゃ。

roboko
ロボ子

遅延解決ですか。初回実行時に実際の実装が解決されるんですね。

hakase
博士

`EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER`フラグってのがあって、`dlsym()`内でリゾルバオフセットが取得されて、アドレスに変換された後、署名されて呼び出されるんじゃ。

roboko
ロボ子

なるほど。リゾルバ関数から返されたポインタが、オフセットに変換される前に署名解除されていないのが問題なのですね。

hakase
博士

そう!IDA Proでdyldのコードを確認したら、XPACI命令が欠落してて、リゾルバからの戻り値が直接オフセットに変換されてたってわけ。

roboko
ロボ子

XPACI命令の欠落ですか。それが二重署名につながるんですね。

hakase
博士

Apple A15 SoCのEnhancedPAC2では、PAC署名がポインタの上位ビットとXORされるんじゃ。不正な署名は、2回目の署名がカーネルポインタとして扱われた場合に発生する。

roboko
ロボ子

カーネルポインタとして扱われる条件があるんですね。

hakase
博士

ビット55がセットされていると、ポインタがカーネルポインタとして扱われるらしいぞ!

roboko
ロボ子

それは興味深い発見ですね。

hakase
博士

でも、`strcmp`をインポートする全てのアプリがクラッシュするわけじゃないんだって。dyldのローダーが`Loader::skipResolver`引数付きで`hasExportedSymbol`を呼んでるから、バグは発生しない場合もある。

roboko
ロボ子

影響範囲は限定的なんですね。原因はdyldの内部構造、共有キャッシュ、iPhoneのPAC実装にあると。

hakase
博士

そうそう!dyldのコードにXPACI命令が欠落しているのが根本原因じゃ。

roboko
ロボ子

勉強になりました。しかし、こんな深いところにバグが潜んでいるとは驚きです。

hakase
博士

じゃろ?ところでロボ子、strcmpって何の略か知ってるか?

roboko
ロボ子

文字列比較(string compare)の略ですよね。

hakase
博士

ブー!正解は… "String Compare To My Problems!" …って、つまらんかったかの?

roboko
ロボ子

…博士、お疲れ様です。

⚠️この記事は生成AIによるコンテンツを含み、ハルシネーションの可能性があります。

Search