而且在debug過程中,會一直反覆更改訊息
不過Log這個函式 也隱藏了安全性風險
- 風險1:若發佈成apk供使用者下載後,沒有註解掉 Log 訊息, Logcat視窗會輸出開發時的Log訊息
- 風險2:apk若被反解譯 ,Log函式訊息會被看到,程式邏輯可能曝光
通常我們為了解決風險1 會使用
private boolean DEBUG = true ; if(DEBUG) { Log.d(TAG,"this is (DEBUG) msg!") ; }
當要release apk 時, 會把 DEBUG 改成 false
來防止Log 訊息 輸出到 Logcat 視窗
不過 若apk 被反編譯成 jar 檔案
可以看到反編譯後的原始碼
if (this.Debug) Log.d(this.Tag, "this is (DEBUG) msg!");
若訊息是重要的程式邏輯點資訊 還是有邏輯曝光的風險
因此 我們希望把 Log.d 的訊息 在 反編譯後 不被看見
可以使用 proGuard 混淆器
打開 proguard 設定
[project.properties]
proguard.config=${sdk.dir}/tools/proguard/proguard-android-optimize.txt:proguard-project.txt
過濾掉 Log 的函式
[proguard-project.txt]
-assumenosideeffects class android.util.Log { *; }
反編譯後 整個 Log.d 函式消失 被過濾掉了 而且加入了 proGuard 混淆器後 節省了 if (Debug){} 的程式碼
不過目前有個新問題
如果Log 訊息 是經過字串組合的 並非一次印出
例如
String user1 = "peter" ; Log.d(TAG,"first man is"+user1) ;
反編譯後
new StringBuilder("first man is").append("peter");
Log.d 函式被更改成 new StringBuilder 不過 字串還是會被看出來
最後參考了這篇部落格
裏面提到了可以透過
1.自訂的 Logger函式
2.proGuard 設定
[proguard-project.txt]
-assumenosideeffects class com.example.disablelogtest.Logger { *; }
[Logger.java]
package com.example.disablelogtest; import android.util.Log; public final class Logger { public static void d(String tag, String message, Object... args) { Log.d(tag, String.format(message, args)); } public static void i(String tag, String message, Object... args) { Log.i(tag, String.format(message, args)); } public static void e(String tag, Exception e) { Log.e(tag, e.getMessage(), e); } public static void e(String tag, String message, Exception e) { Log.e(tag, message, e); } }
Logger 用法
Logger.d(TAG, "Batman goes like %d, %d, %d, \"%s\"", 1, 2, 3, "Pow!"); * //prints: Batman goes like 1, 2, 3, "Pow!"
反編譯前
String user1 = "tom" ; String user2= getUserName(0) ; Logger.d(Tag, "this is (DEBUG) msg! firstOne=%s , secondOne=%s",user1,user2) ; private String getUserName(int id) { String[] objUser = {"peter" ,"john"} ; if (id >(objUser.length-1)) { return "nobody" ; } return objUser[id] ; }
反編譯後
String[] arrayOfString = { "peter", "john" }; if (-1 + arrayOfString.length < 0); for (String str = "nobody"; ; str = arrayOfString[0]) { new Object[] { "tom", str }; return; }我們可以看到
"this is (DEBUG) msg! firstOne=%s , secondOne=%s"
的字串已經看不出來
不過這邊要特別注意的是
若組合的字串是寫死的 例如 上面例子寫死的"tom" 還是會出現
不過若是 經過 呼叫 function得到之 字串 則不會直接的顯示出來
總結
最終解決方案為
1.開啟proGuard混淆器
proguard.config=${sdk.dir}/tools/proguard/proguard-android-optimize.txt:proguard-project.txt
2.設定proGuard混淆器
-assumenosideeffects class com.example.disablelogtest.Logger { *; }
3.使用 自用 Logger 函式
Logger.d(TAG, "Batman goes like %d, %d, %d, \"%s\"", 1, 2, 3, "Pow!");以上 就能在程式碼中 保留 Log 訊息
並且 Logcat 不會噴出訊息 , 反解譯之後也不容易被看出邏輯 ^^
沒有留言:
張貼留言