Android Java Apk 反組譯分析 decompile reflection應用--BigFont為例

有需求才有動機,最近看到一款 BigFont 的 Apk 可以修改沒有root權限的手機的系統字型大小,我覺得算實用,該作者也滿厲害的,可以持續在Android上賺錢,我都放棄了(謎之聲:沒有開始哪來放棄Orz)

直接切入正題,安裝完確定他的功能可以Work之後,就隨便google了一下關於字型放大的API,網路上有人在教root完之後可以放大的,但確定沒有官方的API。

於是讓我想玩玩看 java 反組譯的技術,所以下載了工具 dex2jar跟jd-gui 
就可以把原始碼撈出來了。初步來看感覺是有混淆過的,沒想到一個小小的程式用了這麼多個Java
先從有名稱的 Java 看起,有一個明顯的是 SetFontWnd.java,於是進去看,配合應用程式的操作流程,我首先由字串找起,像是要開始設定之前,會出現甚麼提示文字,或是之後會出現甚麼文字,搜尋了"Normal" 跟 "Wait" 都沒有看到,看起來是 dex2jar 並沒有解出 android 的資源檔。於是開始做苦工,大略看了一下,看到了BgSrvc的叫用,看起來主功能就是在這個java裡面了,於是打開。


在BgSrvc.b()的呼叫,還滿像的,因為修改系統字型大小只有一個參數,float paramFloat


開頭如下,看起來很恐怖。

      Object localObject1 = Class.forName(c).getMethod(d, new Class[0]).invoke(null, new Object[0]);
      Object localObject2 = localObject1.getClass();
      Configuration localConfiguration = (Configuration)((Class)localObject2).getMethod(e, new Class[0]).invoke(localObject1, new Object[0]);
      localConfiguration.fontScale = paramFloat;
  
最近同事剛好問我 Reflection 是甚麼?上面就是他的應用,其實iOS的一些非官方API也是透過Reflection來叫用的,看起來 BigFont的作者有去研究Android Source Code。程式碼看到一堆 字串變數,例如 c,d,e,f。繼續找下去

      c = com.a0soft.gphone.a.f.a("YW5kcm9pZC5hcHAuQWN0aXZpdHlNYW5hZ2VyTmF0aXZl");
      d = com.a0soft.gphone.a.f.a("Z2V0RGVmYXVsdA==");
      e = com.a0soft.gphone.a.f.a("Z2V0Q29uZmlndXJhdGlvbg==");
      f = com.a0soft.gphone.a.f.a("dXBkYXRlQ29uZmlndXJhdGlvbg==");
      g = com.a0soft.gphone.a.f.a("dXBkYXRlUGVyc2lzdGVudENvbmZpZ3VyYXRpb24=");
    
    看到了有點熟悉的編碼方式,不確定是不是BASE64,但因為我自己也常在用,也是讓別人麻煩的,不希望人家一點就看到明碼,所以先用線上的 Base64 解碼看看,Bingo!! 解出來是合理的字串。所以接下來我就把 BgSrvc.b 這個參數修改了,改完當然要測試一下。
下面就是我的 MainActivity.java


@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// this.A.add(Float.valueOf(0.85F));
// this.A.add(Float.valueOf(0.9F));
// this.A.add(Float.valueOf(1.0F));
// this.A.add(Float.valueOf(1.1F));
// this.A.add(Float.valueOf(1.15F));
// this.A.add(Float.valueOf(1.3F));
ChangeFont(1.0F);
}

public void ChangeFont(float NewFontSize) {
boolean bool;
try {
Object localObject1 = Class.forName(
"android.app.ActivityManagerNative").getMethod(
"getDefault", new Class[0]).invoke(null, new Object[0]);
Object localObject2 = localObject1.getClass();
Configuration localConfiguration = (Configuration) ((Class) localObject2).getMethod("getConfiguration", new Class[0]).invoke(
localObject1, new Object[0]);
localConfiguration.fontScale = NewFontSize;
Class[] localObject3 = new Class[1];

// Check SDK Version
// if (h.b() < 14)
{

localObject3[0] = Configuration.class;
localObject2 = ((Class) localObject2).getMethod(
"updateConfiguration", localObject3);
((Method) localObject2)
.invoke(localObject1, localConfiguration);

}
localObject3 = new Class[1];
localObject3[0] = Configuration.class;
localObject2 = ((Class) localObject2).getMethod(
"updatePersistentConfiguration", localObject3);
} catch (Exception ex) {
Log.i("JianFont", ex.getMessage());
ex.printStackTrace();
int x = 0;
}
}

於是拿來手機來試試,執行之後,疑,沒改Orz。於是中斷在exception裡面,沒有權限修改系統設定,懶得去找 android 是哪一個 permission 了,直接把 BigFont.apk 改名為 BigFont.zip,解壓,透過 AXMLPrinter2.jar 取得他的 AndroidManifest.xml 看到就簡單兩個設定




加上去之後大功告成。
其間我發現 Android 並沒有限制縮放的倍數,你也可以放大一百倍Orz

打完收工~

附錄:

Reflection & Serialization 學習記錄

留言

這個網誌中的熱門文章

好貴的東元冷氣維修--馬達啟動電容

台大醫院 婁培人 耳鼻喉科 就診

機車無法充電之整流器壞掉--$650