Android修煉之檢測非SDK介面

奇舞移動發表於2019-03-01

前言

上篇文章Android修煉之Pie 適配的搬運工中介紹了Android P的一些行為變更並提供了一些對齊劉海和非SDK介面的適配建議,大部分人還是更加關心非SDK介面的問題,所以本文來說一下如何檢測非SDK介面。

區分SDK介面和非SDK介面

一般來說,SDK介面是指在Android框架軟體包索引中記錄的介面,其對立面自然就叫非SDK介面了。Android 9引入了針對非SDK介面的使用限制,無論是直接使用還是通過反射或JNI間接使用。這意味著,通過反射之類的語義來操作某個類時,不應訪問SDK中未列出的函式或欄位(通常都有@hide標誌)。

Android 9將非SDK介面都放在了各名單中:

  1. 白名單:自然就是可以直接使用的SDK介面;
  2. 淺灰名單:仍可以訪問的非 SDK 函式/欄位;
  3. 深灰名單:包含我們在開發期間未看到使用,但是我們可能已經忽視的函式/欄位。列入深灰名單的函式/欄位是那些與SDK和淺灰名單中的公開介面緊密相關的函式/欄位。
    • 對於目標SDK低於API級別28的應用,允許使用深灰名單介面;
    • 對於目標SDK為API 28或更高階別的應用:行為與黑名單相同;
  4. 黑名單:受限,無論目標SDK如何。平臺將表現為似乎介面並不存在。

這些名單都可以在:非SDK介面名單中找到。如果不想編譯AOSP,可以直接下載該頁的tgz檔案,解壓即可看到對應的txt檔案。

如何檢測非SDK介面?

檢視logcat日誌

在Android 9的系統中,如你的應用中使用了非SDK介面,系統將會在APP執行時列印日誌;如果訪問了某些“列入灰名單的”非SDK介面,系統還可能顯示Toast;如果訪問了“列入黑名單的”非SDK介面,系統將引發異常。

日誌訊息

在開發過程中,我們可以通過AS的logcat來檢視日誌,否則就是通過adb logcat了。非SDK介面的日誌會顯示在正在執行的應用的PID下,大概格式是:

Accessing hidden field Landroid/net/wifi/WifiManager;->WIFI_SCAN_AVAILABLE:Ljava/lang/String; (dark greylist, reflection)
複製程式碼
  • Accessing hidden:固定格式
  • field:可能是method,表示呼叫的是屬性還是方法
  • Landroid/net/wifi/WifiManager:表示呼叫的類名
  • ->WIFI_SCAN_AVAILABLE:Ljava/lang/String;:表示呼叫的屬性和方法名
  • (dark greylist, reflection):前半部分表示該非SDK介面在哪個名單中,後半部分表示被呼叫的方式,比如:reflection(反射)和JNI

這裡給出幾個示例:

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_third);

        WifiManager wifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
        Field field = null;
        try {
            field = wifiManager.getClass().getDeclaredField("WIFI_SCAN_AVAILABLE");
            Log.d("ThirdActivity", (String) field.get(wifiManager));
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }

    // 直接在淺灰名單中找的介面
    public void testLightGreyList(View view) {
        ReflectUtils.getMethod(TelephonyManager.class, "isMultiSimEnabled");
    }

    // 直接在深灰名單中找的介面
    @TargetApi(Build.VERSION_CODES.M)
    public void testDarkGreyList(View view) {
        ReflectUtils.getField(CarrierConfigManager.class, "KEY_ALWAYS_PLAY_REMOTE_HOLD_TONE_BOOL");
    }

    // 直接在黑名單中找的介面
    public void testBlackList(View view) {
        try {
            ReflectUtils.getMethod(ReflectUtils.getClass("android.net.util.IpUtils"), "ipChecksum", ByteBuffer.class, int.class);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
複製程式碼

他們的日誌如下:

Accessing hidden field Landroid/net/wifi/WifiManager;->WIFI_SCAN_AVAILABLE:Ljava/lang/String; (dark greylist, reflection)
Accessing hidden method Landroid/telephony/TelephonyManager;->isMultiSimEnabled()Z (light greylist, reflection)
Accessing hidden field Landroid/telephony/CarrierConfigManager;->KEY_ALWAYS_PLAY_REMOTE_HOLD_TONE_BOOL:Ljava/lang/String; (dark greylist, reflection)
Accessing hidden method Landroid/net/util/IpUtils;->ipChecksum(Ljava/nio/ByteBuffer;I)S (blacklist, reflection)
複製程式碼

注意:在debug的時候,只有觸發了對應的呼叫邏輯,才會列印日誌,而不是靜態檢測。所以新專案中,我們在開發過程中就要注意非SDK介面的呼叫。

Toast和Dialog提示

可能因為我的模擬器用的是Android P的正式版,去除了Toast提示。所以,在測試的時候並沒有看到相關的Toast提示。在預覽版中應該有Toast提示功能。當然,也可能是我沒有觸發“某些灰名單中的非SDK介面”(官方文件原話)的原因。

不過,當我把TargetSDK改為27時,出現過這種對話方塊提示:

Dialog提示

引發異常

官方說明:

非SDK介面引發後果

經測試,只有深灰名單黑名單中的非SDK介面會引發異常和錯誤。

注意:當TargetSDK>=28時,深灰名單和黑名單都會引發異常;而當TargetSDK<28時,只有黑名單會引發異常。示例結果如下:

深灰名單引發異常

黑名單引發異常

使用veridex檢測工具

谷歌提供了一個靜態檢測工具:veridex,可以幫助我們檢測apk中是否使用了非SDK介面。這裡使用veridex-linux.zip進行測試,解壓後目錄結構如下:

veridex
可以看到它裡面包含了各名單的txt檔案,其中appcompat.sh就是執行指令碼。

將待檢測的apk檔案拷貝到veridex目錄下,執行以下命令即可:

./appcompat.sh --dex-file=檔名.apk --imprecise
複製程式碼

結果:

示例檢測結果
這裡顯示的數量明顯比我們示例中的多,這是為什麼?觀察詳細內容,發現veridex把Android自己呼叫的也檢測出來了。

如果去掉--imprecise會檢測不出來黑名單的介面。

示例檢測結果2
我們可以通過重定向將日誌儲存在檔案中,再進行細緻的分析。

我們主要關注黑名單和深灰名單。可以看到,日誌中給出了呼叫非SDK介面的位置,很容易定位。

定位問題

總結

  1. 在開發過程中可以通過日誌檢視是否呼叫了非SDK介面;
  2. 主要注意深灰名單和黑名單的介面呼叫,雖然程式中經常寫有try catch,但還是竟可能找到繞過或者替代的方案;
  3. 使用veridex分析apk時,最好帶上--imprecise引數,可以看到更多詳細的資訊;
  4. 示例程式碼:github.com/zjxstar/And…

參考資料

  1. 官網
  2. 史上最嚴管控,Android P非SDK介面管控特性解讀及適配
  3. Android P非SDK的隱藏API呼叫檢測

關注微信公眾號,最新技術乾貨實時推送

image

相關文章