Android開発のこと

リフレクションで非公開のAPIを使ってみた

Amazonのアソシエイトとして、8796.jp管理日誌は適格販売により収入を得ています。

image

なんとなく smali 見てたら面白そうな API があったけど呼び出し方がわからない!

ってことで色々調べてたらてくぶさん。

リフレクションをつかってメソッドを呼び出す – Tech Booster

なるほどリフレクション。こういうのもあるのか。

以下の感じで使うらしい。※一部伏字

ポイントは smali から発見した面白そうなクラス名を Class.forName で指定すること。

smali の1行目にあるこんなのを

.class public Lcom/moto????/internal/telephony/SbmNamHandler;
"com.moto????.internal.telephony.SbmNamHandler"

にして使う。

次のポイントは getMethod でメソッド名と引数を指定すること。引数は型を間違うとそんなメソッド無いって怒られる。じゅうよう!

smali の該当部分はこれ

.method public static getSbmNamID(ZLjava/lang/String;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;

メソッド名は「getSbmNamID」ってのはわかる。引数は Z = boolean.class で Ljava/lang/String = String.class なのでこうなる

Method m = c.getMethod("getSbmNamID", boolean.class, String.class, String.class, String.class);

呼び出しは invoke です。今回は元が static なので第1引数は null らしいです。ということで、まとめるとこんな感じになります。

TelephonyManager tm = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);

try {
    Class<?> c = Class
            .forName("com.moto????.internal.telephony.SbmNamHandler");
    try {
        Method m = c.getMethod("getSbmNamID", boolean.class,
                String.class, String.class, String.class);
        Object ret = m.invoke(null, true, tm.getLine1Number(),
                tm.getDeviceId(), tm.getSubscriberId());
        sbmid = ret.toString();
        Log.d("sbmcgm", "ID:" + sbmid);
    } catch (Exception e) {
        e.printStackTrace();
    }
} catch (ClassNotFoundException e) {
    e.printStackTrace();
}

こんな感じにすると RAZR M 201M で forgsmartphone の ID とか Pass がわかるようになります。これで SIM ロックされてない Band I 対応端末でも通信できますが、いくら 4G が全盛期の1%の速度も出なくなったからとはいえ正直 Band I だけだとドコモのほうがマシなんじゃねーの?

非公式 API で色々できそうなのは楽しそうな気がしました。めでたしめでたし。

コメント

タイトルとURLをコピーしました