🦀

Rust製バイナリを探してみる

2022/12/02に公開約2,600字

はじめに

https://twitter.com/dwizzzleMSFT/status/1578532292662005760

少し前にこのようなツイートを見かけました。「MicrosoftがいつのまにかWindowsの中にRust製のDLLをリリースしていた」という話です。
プロダクションでのRustの採用はまだそれほどメジャーでないこともあり、採用している側は積極的に情報公開して注目を集めようとする傾向があるように思いますが、このようにこっそり使っているケースは実は結構あるのかもしれません。
そこでこっそりRustが使われているものを調べる方法を考えてみました。

Rust製バイナリを調べる

先ほどのツイートではバイナリに埋め込まれたソースコードのパス・ファイル名からRust製であると判定していました。しかし一般的なバイナリではこれらの情報が残っているとは限りませんし、単純に静的な文字列として "rust" を含んでいるバイナリを誤判定してしまう可能性があります。そこでもう少し汎用的な方法を考えてみます。

Rust製バイナリの中身を "rust" で検索してみるとソースコードのパス名の他にいくつかの関数名がヒットします。そのうちの1つが rust_panic です。
これはRustのプログラムにおいてパニックが発生したときに呼ばれるパニックハンドラで、多くのRust製バイナリに含まれていると考えられます。
このようにRustコンパイラが挿入する関数のシンボル名を手掛かりにするのが比較的良さそうです。

うまくいかないケースとして、手元でいくつか試した限りでは、LTOを行った場合にシンボル名では判定できなくなりました。またCのバイナリで rust_panic というシンボルを公開することは当然可能なので誤判定はあり得ます。

というわけで ELF/PE バイナリのシンボルテーブルを検索してRustっぽいシンボル名を探してみることにしました。
探すシンボル名はいろいろ考えられますがとりあえず rust_panicrust_eh_personality としました。(前者がなくて後者だけあるバイナリがあったため)

rustified

https://github.com/dalance/rustified

というわけで作ったプログラムがこちらです。
そのものずばりな elfクレートexeクレート があったのでそれぞれを使って ELF と PE のシンボルテーブルから先ほどのシンボル名を探すプログラムです。

探してみる

Windows

さっそく元ツイートのファイルを探してみると、確かに見つかりました。
(2つあるのはバージョンが違うもののようです)

C:\Program Files>rustified
.\WindowsApps\Microsoft.YourPhone....\DWriteCore.dll (function "rust_panic" is found)
.\WindowsApps\Microsoft.YourPhone....\DWriteCore.dll (function "rust_panic" is found)

ちなみにこの WindowsApps フォルダはデフォルトでは管理者でもアクセスできないので、事前に明示的にアクセス権を付与しておく必要があります。

Android

せっかくなのでもう1つ探してみました。ちょうど以下の記事で Android13 におけるRustの使用について書かれているのでそれを探してみます。

https://security.googleblog.com/2022/12/memory-safe-languages-in-android-13.html

まず、Google Pixel用の Android13 のファクトリーイメージをダウンロードしてきます。

https://developers.google.com/android/images

今回はPixel 7 Pro 用のイメージを使いました。
このzipを展開し、system.img をマウントします。

$ sudo mount -t ext4 -o ro,loop system.img system

次にこの system ディレクトリから以下の UWB スタックのパッケージを取り出します。

system/apex/com.google.android.uwb.apex

これは Android Pony EXpress(APEX)コンテナ形式 という形式で、実体としては zip アーカイブの中に ext4 イメージが入っています。

zip を展開してマウントします。

$ unzip com.google.android.uwb.apex
$ unzip original_apex
$ sudo mount -t ext4 -o ro,loop apex_payload.img mnt

そうすると以下のように中身を取り出せます。

mnt/lib64/libuwb_uci_jni_rust.so

ファイル名からしてあからさまにRustっぽいですが一応確認します。

$ rustified
./libuwb_uci_jni_rust.so (function "rust_eh_personality" is found)

というわけで無事こちらも確認できました。

Discussion

ログインするとコメントできます