国产成人精品亚洲777人妖,欧美日韩精品一区视频,最新亚洲国产,国产乱码精品一区二区亚洲

您的位置:首頁(yè)技術(shù)文章
文章詳情頁(yè)

Android 繞過(guò)反射黑名單的方法

瀏覽:56日期:2022-09-20 18:11:12
限制原理

Google 從 Android P 開(kāi)始引入了針對(duì)非公開(kāi) API 的限制,這一點(diǎn)可以從 Native 相關(guān)的源碼中找到限制的原理,從而從中找到解決辦法,不過(guò)非必要原因不太建議去挑戰(zhàn)這種限制,畢竟不清楚在后續(xù)的版本中會(huì)不會(huì)做限制,維護(hù)起來(lái)挺麻煩的。

在 Native 層有幾個(gè)訪問(wèn)級(jí)別:

class HiddenApiAccessFlags { public: enum ApiList { kWhitelist = 0, kLightGreylist, kDarkGreylist, kBlacklist, };}

另外還有幾個(gè)對(duì)應(yīng)的響應(yīng)級(jí)別:

enum Action { kAllow, //通過(guò) kAllowButWarn, //通過(guò),但日志警告 kAllowButWarnAndToast, //通過(guò),且日志警告和彈窗 kDeny //拒絕訪問(wèn)};

這里介紹一下網(wǎng)上的一些解決方式,此外,還可以把我們調(diào)用了反射方法的類的類加載器設(shè)置為系統(tǒng)類加載器,這樣就可以繞過(guò) Native 層的限制了。

系統(tǒng)類偽裝

黑名單在系統(tǒng)中有一個(gè) fn_caller_is_trusted 的條件:如果調(diào)用者是系統(tǒng)類,那么就允許被調(diào)用。即如果我們能以系統(tǒng)類的身份去反射,那么就能暢通無(wú)阻:

首先通過(guò)反射 API 拿到 getDeclaredMethod 方法。getDeclaredMethod 是 public 的,不存在問(wèn)題;這個(gè)通過(guò)反射拿到的方法網(wǎng)上稱之為元反射方法。 然后通過(guò)剛剛的元反射方法去反射調(diào)用 getDeclardMethod。這里我們就實(shí)現(xiàn)了以系統(tǒng)身份去反射的目的——反射相關(guān)的 API 都是系統(tǒng)類,因此我們的元反射方法也是被系統(tǒng)類加載的方法;所以我們的元反射方法調(diào)用的 getDeclardMethod 會(huì)被認(rèn)為是系統(tǒng)調(diào)用的,可以反射任意的方法。

偽代碼如下:

// 公開(kāi)API,無(wú)問(wèn)題Method metaGetDeclaredMethod = Class.class.getDeclaredMethod('getDeclardMethod');// 系統(tǒng)類通過(guò)反射使用隱藏 API,檢查直接通過(guò)。Method hiddenMethod = metaGetDeclaredMethod.invoke(hiddenClass, 'hiddenMethod', 'hiddenMethod參數(shù)列表');// 正確找到 Method 直接反射調(diào)用hiddenMethod.invoke豁免條件

隱藏 API 的調(diào)用有「豁免」條件,即只要它是豁免的,則即使它在黑名單中,也會(huì)被放行。這種方式暴露給了 Java 層,因此可以通過(guò) VMRuntime.setHiddenApiExemptions 方法來(lái)實(shí)現(xiàn)。再結(jié)合上面這個(gè)方法,我們只需要通過(guò) 「元反射」 來(lái)反射調(diào)用 VMRuntime.setHiddenApiExemptions 就能將我們自己要使用的隱藏 API 全部都豁免掉了。另外系統(tǒng)在檢查豁免時(shí)是通過(guò)方法簽名進(jìn)行前綴匹配的,而 Java 方法簽名都是 L 開(kāi)頭的,因此我們可以把直接傳個(gè) L 進(jìn)去,那么所有的隱藏API全部被赦免了!

源碼直接參考網(wǎng)上大佬的開(kāi)源項(xiàng)目: FreeReflection。

public final class BootstrapClass { private static final String TAG = 'BootstrapClass'; private static Object sVmRuntime; private static Method setHiddenApiExemptions; static { if (SDK_INT >= Build.VERSION_CODES.P) { try {Method forName = Class.class.getDeclaredMethod('forName', String.class);Method getDeclaredMethod = Class.class.getDeclaredMethod('getDeclaredMethod', String.class, Class[].class);Class<?> vmRuntimeClass = (Class<?>) forName.invoke(null, 'dalvik.system.VMRuntime');Method getRuntime = (Method) getDeclaredMethod.invoke(vmRuntimeClass, 'getRuntime', null);setHiddenApiExemptions = (Method) getDeclaredMethod.invoke(vmRuntimeClass, 'setHiddenApiExemptions', new Class[]{String[].class});sVmRuntime = getRuntime.invoke(null); } catch (Throwable e) {Log.w(TAG, 'reflect bootstrap failed:', e); } } } /** * make the method exempted from hidden API check. * * @param method the method signature prefix. * @return true if success. */ public static boolean exempt(String method) { return exempt(new String[]{method}); } /** * make specific methods exempted from hidden API check. * * @param methods the method signature prefix, such as 'Ldalvik/system', 'Landroid' or even 'L' * @return true if success */ public static boolean exempt(String... methods) { if (sVmRuntime == null || setHiddenApiExemptions == null) { return false; } try { setHiddenApiExemptions.invoke(sVmRuntime, new Object[]{methods}); return true; } catch (Throwable e) { return false; } } /** * Make all hidden API exempted. * * @return true if success. */ public static boolean exemptAll() { return exempt(new String[]{'L'}); }}

以上就是Android 繞過(guò)反射黑名單的方法的詳細(xì)內(nèi)容,更多關(guān)于Android 繞過(guò)反射黑名單的資料請(qǐng)關(guān)注好吧啦網(wǎng)其它相關(guān)文章!

標(biāo)簽: Android
相關(guān)文章:
主站蜘蛛池模板: 葫芦岛市| 东兰县| 汝州市| 雷山县| 信丰县| 育儿| 泸州市| 禹州市| 麻栗坡县| 广州市| 文水县| 抚顺市| 江山市| 吴川市| 兴宁市| 长寿区| 潜江市| 荆门市| 武安市| 吉木乃县| 宁武县| 镇康县| 文山县| 越西县| 奈曼旗| 澄迈县| 杭州市| 陆良县| 黎城县| 班玛县| 嘉定区| 五华县| 光泽县| 宜春市| 婺源县| 山阴县| 苍山县| 涞水县| 福安市| 衡山县| 尚义县|