DEXレベルで類似点と違いを探してみよう

少し前、被害者に対してスパイ行為を行うVertuの偽アプリ、Android/Smsilence.A!tr.spyの2つのよく似たサンプルの分析を行いました。サンプルの1つは日本のエンドユーザー狙ったものであり、もう1つは韓国のエンドユーザーを狙ったものでした。そこで、類似点(と違い)を見つけてみようと思ったのです。
(逆コンパイルした)ソースコードのレベルで、すぐに類似点がみつかりました。どちらのサンプルも受信するSMSメッセージをチェックし、メッセージの本文に113というキーワードが含まれていると別のペイロードをダウンロードし、もしSMSが1588366から送られてきている場合はそのメッセージを削除します。下記をご覧ください。コードが同一になっている個所を黄色いボックスでハイライトしてあります。

ここまでは簡単でした。しかし、DEXファイルではどこに位置付けされているのでしょうか?こちらはもう少し難しくなりそうです。この部分のコードがDEXファイルではどこで始まるのかを特定しなければなりません。こういう場合には010 Editorが役に立ちます。サンプルのDEXファイルを読み込み、それにDEX Templateを当てはめてみます。
探したいコードはclass catchsms2のonReceive()というメソッドのなかにあります。010 Editorで、そのメソッドとコードの構造を見つけました(code_item)。このメソッドのバイトコードは、バイトごとにinsnsという名前の配列に入っています。配列は0xb30というオフセットで始まります。

まだ終わりではありません。なぜなら、特定した同一個所がこのメソッドの初めの部分に見当たらないからです。メソッド内でこの部分のオフセットを探してみましょう。010 Editorが示すinsnsテーブルには、メソッドにおける各Dalvik指示のオペコードが入っています。この方法で正しいオペコードを見つけるのは大変です。代わりに、Androguardを使うことにします。onReceive()のDalvikバイトコードはこのようになっています。

$ ./androlyze -s
In [1]: a, d, dx = AnalyzeAPK('vertu.jp.apk', decompiler="dad")
In [2] d.CLASS_Lcom_vertu_jp_catchsms2.METHOD_onReceive.pretty_show()

このバイトコード内に、メッセージ本文に113というキーワードが含まれているどうかをマルウェアがテストする個所が見つかりました。私たちが探していた個所はaget-objectの指示で始まっています。隣の16進数をご覧ください。メソッド内のオフセット、0x32aです。

つまり、同一コードはDEXファイル内の0xb30 + 0x32a = 0xe5aというオフセットにあるということです。チェックしてみますか? 私のスクリプト、androdis.pyを使って、その場所でDEXファイルを逆コンパイルしてみましょう。

ありました!(aget-object指示で始まっていますよね)DEXファイル内でのオペコードは、46 17 0d 06 74 01 0e 00などです。
楽しんでいただけましたか?

- the Crypto Girl