吴忠躺衫网络科技有限公司

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

Android App環(huán)境檢測(cè)分析

哆啦安全 ? 來源:哆啦安全 ? 2023-12-01 10:26 ? 次閱讀

1.檢測(cè)是否調(diào)試APP

這個(gè)原理就是APP的AndroidManifest.xml文件中application是否配置了android:debuggable="true",設(shè)置true支持動(dòng)態(tài)調(diào)試

public static boolean isAppDebuggable(Context context) {
    return (context.getApplicationInfo().flags & 2) != 0;
}

檢測(cè)當(dāng)前APP是否被動(dòng)態(tài)調(diào)試中

public static boolean isDebuggerAttached() {
    return Debug.isDebuggerConnected() || Debug.waitingForDebugger();
}

2.檢測(cè)是否模擬

這里獲取了Android id,如果Android id是null,就是模擬器?如果包含GOLDFISH字符串也屬于模擬器

public static boolean isEmulator(Context context) {
    return Build.PRODUCT.contains(SDK) || Build.HARDWARE.contains(GOLDFISH) || Build.HARDWARE.contains(RANCHU) || Settings.Secure.getString(context.getContentResolver(), "android_id") == null;
}

3.Root檢測(cè)

檢測(cè)系統(tǒng)的tags是不是test-keys。

檢測(cè)是不是安裝了supersu的APP,檢測(cè)su文件是否存在。

public static boolean isRooted(Context context) {
        boolean isEmulator = isEmulator(context);
        String str = Build.TAGS;
        if ((isEmulator || str == null || !str.contains("test-keys")) && !new File("/system/app/Superuser.apk").exists()) {
            return !isEmulator && new File("/system/xbin/su").exists();
        }
        return true;
}

判斷一些root的APP是否安裝

private final boolean a(List list) {
        PackageManager packageManager = this.b.getPackageManager();
        boolean z = false;
        for (String str : list) {
            try {
                packageManager.getPackageInfo(str, 0);
                C0339Io.h.e(str + " ROOT management app detected!");
                z = true;
            } catch (PackageManager.NameNotFoundException unused) {
            }
        }
        return z;
}

通過which su尋找su文件

public final boolean f() {
        /*
            r5 = this;
            r0 = 0
            r1 = 0
            java.lang.Runtime r2 = java.lang.Runtime.getRuntime()     // Catch: java.lang.Throwable -> L2f
            java.lang.String r3 = "which"
            java.lang.String r4 = "su"
            java.lang.String[] r3 = new java.lang.String[]{r3, r4}     // Catch: java.lang.Throwable -> L2f
            java.lang.Process r1 = r2.exec(r3)     // Catch: java.lang.Throwable -> L2f
            java.io.BufferedReader r2 = new java.io.BufferedReader     // Catch: java.lang.Throwable -> L2f
            java.io.InputStreamReader r3 = new java.io.InputStreamReader     // Catch: java.lang.Throwable -> L2f
            java.io.InputStream r4 = r1.getInputStream()     // Catch: java.lang.Throwable -> L2f
            r3.(r4)     // Catch: java.lang.Throwable -> L2f
            java.io.Reader r3 = (java.io.Reader) r3     // Catch: java.lang.Throwable -> L2f
            r2.(r3)     // Catch: java.lang.Throwable -> L2f
            java.lang.String r2 = r2.readLine()     // Catch: java.lang.Throwable -> L2f
            if (r2 == 0) goto L29
            r0 = 1
        L29:
            if (r1 == 0) goto L32
        L2b:
            r1.destroy()
            goto L32
        L2f:
            if (r1 == 0) goto L32
            goto L2b
        L32:
            return r0
        */
        throw new UnsupportedOperationException("Method not decompiled: jmgldvb.C6107cme.f():boolean");
}

4.分區(qū)讀寫檢測(cè)

public final boolean k() {
        String str;
        String str2;
        String[] strArr;
        int i;
        boolean z;
        String str3;
        String[] e = e();
        int i2 = 0;
        if (e == null) {
            return false;
        }
        int i3 = Build.VERSION.SDK_INT;
        int length = e.length;
        int i4 = 0;
        boolean z2 = false;
        while (i4 < length) {
            String str4 = e[i4];
            Object[] array = new Regex(StringUtils.SPACE).split(str4, i2).toArray(new String[i2]);
            Intrinsics.checkNotNull(array, "null cannot be cast to non-null type kotlin.Array");
            String[] strArr2 = (String[]) array;
            int i5 = 23;
            if ((i3 > 23 || strArr2.length >= 4) && (i3 <= 23 || strArr2.length >= 6)) {
                boolean z3 = true;
                if (i3 > 23) {
                    str = strArr2[2];
                    str2 = strArr2[5];
                } else {
                    str = strArr2[1];
                    str2 = strArr2[3];
                }
                String[] strArr3 = C4631btu.g;
                int length2 = strArr3.length;
                String str5 = str2;
                int i6 = i2;
                while (i6 < length2) {
                    String str6 = strArr3[i6];
                    if (StringsKt.equals(str, str6, z3)) {
                        if (Build.VERSION.SDK_INT > i5) {
                            str3 = str6;
                            str5 = StringsKt.replace$default(StringsKt.replace$default(str5, "(", "", false, 4, (Object) null), ")", "", false, 4, (Object) null);
                        } else {
                            str3 = str6;
                        }
                        strArr = e;
                        Object[] array2 = new Regex(",").split(str5, i2).toArray(new String[i2]);
                        Intrinsics.checkNotNull(array2, "null cannot be cast to non-null type kotlin.Array");
                        String[] strArr4 = (String[]) array2;
                        int length3 = strArr4.length;
                        int i7 = i2;
                        while (true) {
                            if (i7 >= length3) {
                                i = i3;
                                z = true;
                                break;
                            }
                            String[] strArr5 = strArr4;
                            i = i3;
                            z = true;
                            if (StringsKt.equals(strArr4[i7], "rw", true)) {
                                C0339Io.b(str3 + " path is mounted with rw permissions! " + str4);
                                z2 = true;
                                break;
                            }
                            i7++;
                            strArr4 = strArr5;
                            i3 = i;
                        }
                    } else {
                        strArr = e;
                        i = i3;
                        z = z3;
                    }
                    i6++;
                    z3 = z;
                    e = strArr;
                    i3 = i;
                    i2 = 0;
                    i5 = 23;
                }
            } else {
                C0339Io.h.e("Error formatting mount line: " + str4);
            }
            i4++;
            e = e;
            i3 = i3;
            i2 = 0;
        }
        return z2;
}

5.面具檢測(cè)

通過which命令查找面具可執(zhí)行文件。

public final boolean m() {
    return a("magisk");
}

6.APP安裝時(shí)間檢測(cè)

通過日志發(fā)現(xiàn)每次啟動(dòng)都會(huì)檢測(cè)APP的安裝,更新時(shí)間。

PackageInfoUtils_generatePackageInfo_1 com.CTION, firstInstallTime: 1701134370160, lastUpdateTime: 1701134626468

7.ROM檢測(cè)

如果是開發(fā)版的ROM,通常tags都是:test-keys

public final boolean q() {
        String str = Build.TAGS;
        return str != null && StringsKt.contains$default((CharSequence) str, (CharSequence) "test-keys", false, 2, (Object) null);
}

8.掛載信息獲取

這個(gè)mount會(huì)把掛載信息返回,可以檢測(cè)掛載信息中是否有magisk或者zygisk字符串等。

private final String[] e() {
        try {
            InputStream inputStream = Runtime.getRuntime().exec("mount").getInputStream();
            if (inputStream == null) {
                return null;
            }
            String propVal = new Scanner(inputStream).useDelimiter("\A").next();
            Intrinsics.checkNotNullExpressionValue(propVal, "propVal");
            Object[] array = new Regex(StringUtils.LF).split(propVal, 0).toArray(new String[0]);
            Intrinsics.checkNotNull(array, "null cannot be cast to non-null type kotlin.Array");
            return (String[]) array;
        } catch (IOException e) {
            C0339Io.a((Exception) e);
            return null;
        } catch (NoSuchElementException e2) {
            C0339Io.a((Exception) e2);
            return null;
        }
}

9.讀取系統(tǒng)屬性

讀取了系統(tǒng)的全部屬性,應(yīng)該手機(jī)手機(jī)型號(hào),廠商等等信息。

private final String[] g() {
        try {
            InputStream inputStream = Runtime.getRuntime().exec("getprop").getInputStream();
            if (inputStream == null) {
                return null;
            }
            String propVal = new Scanner(inputStream).useDelimiter("\A").next();
            Intrinsics.checkNotNullExpressionValue(propVal, "propVal");
            Object[] array = new Regex(StringUtils.LF).split(propVal, 0).toArray(new String[0]);
            Intrinsics.checkNotNull(array, "null cannot be cast to non-null type kotlin.Array");
            return (String[]) array;
        } catch (IOException e) {
            C0339Io.a((Exception) e);
            return null;
        } catch (NoSuchElementException e2) {
            C0339Io.a((Exception) e2);
            return null;
        }
}

判斷是不是模擬器:ro.kernel.qemu

獲取手機(jī)廠商ro.product.manufacturer

品牌:ro.build.product

指紋:ro.build.fingerprint

10.開發(fā)者模式adb檢測(cè)

Settings中獲取adb狀態(tài)。

Settings.Secure

Global getInt : adb_enabled

Secure getInt : adb_wifi_enabled

11.可疑的二進(jìn)制文件

這里就是可以傳遞su,magisk等等參數(shù)

public final boolean a(String filename) {
        String[] a;
        Intrinsics.checkNotNullParameter(filename, "filename");
        boolean z = false;
        for (String str : C4631btu.d.a()) {
            String str2 = str + filename;
            if (new File(str, filename).exists()) {
                C0339Io.b(str2 + " binary detected!");
                z = true;
            }
        }
        return z;
}

12.ro.debuggable檢測(cè)

ro.debuggable這個(gè)系統(tǒng)屬性,在user版本的系統(tǒng)中是0,如果發(fā)現(xiàn)是1可以判斷當(dāng)前系統(tǒng)是可調(diào)試狀態(tài)和root狀態(tài)。

public final boolean b() {
        HashMap hashMap = new HashMap();
        hashMap.put("ro.debuggable", "1");
        hashMap.put("ro.secure", "0");
        String[] g = g();
        if (g == null) {
            return false;
        }
        boolean z = false;
        for (String str : g) {
            for (String str2 : hashMap.keySet()) {
                String str3 = str;
                if (StringsKt.contains$default((CharSequence) str3, (CharSequence) str2, false, 2, (Object) null)) {
                    String str4 = "[" + ((String) hashMap.get(str2)) + ']';
                    if (StringsKt.contains$default((CharSequence) str3, (CharSequence) str4, false, 2, (Object) null)) {
                        C0339Io.b(str2 + " = " + str4 + " detected!");
                        z = true;
                    }
                }
            }
        }
        return z;
}

13.無障礙檢測(cè)

getEnabledAccessibilityServiceList

獲取當(dāng)前無障礙服務(wù)的激活的APP信息,這里拿到了激活了無障礙的APP,只有發(fā)現(xiàn)有,APP直接崩潰。

private final List getPackageAccessibilityServiceEnabledList(Context context) {
        PackageInfo packageInfo;
        List enabledAccessibilityServiceList = getAccessibilityService(context).getEnabledAccessibilityServiceList(-1);
        Intrinsics.checkNotNullExpressionValue(enabledAccessibilityServiceList, "accessibilityManager.get…ceInfo.FEEDBACK_ALL_MASK)");
        List list = enabledAccessibilityServiceList;
        ArrayList arrayList = new ArrayList(CollectionsKt.collectionSizeOrDefault(list, 10));
        for (AccessibilityServiceInfo accessibilityServiceInfo : list) {
            ServiceInfo serviceInfo = accessibilityServiceInfo.getResolveInfo().serviceInfo;
            try {
                packageInfo = context.getPackageManager().getPackageInfo(serviceInfo.packageName, 0);
            } catch (PackageManager.NameNotFoundException unused) {
                PackageInfo packageInfo2 = new PackageInfo();
                packageInfo2.packageName = serviceInfo.packageName;
                packageInfo2.applicationInfo = serviceInfo.applicationInfo;
                packageInfo = packageInfo2;
            }
            arrayList.add(packageInfo);
        }
        return arrayList;
}

14.獲取APP安裝列表

獲取了用戶安裝的所有APP,應(yīng)該是收集上傳,判斷是否裝了一些root有關(guān)的APP。

public List getInstalledApps(PackageManager packageManager) {
        Intrinsics.checkNotNullParameter(packageManager, "packageManager");
        List installedPackages = packageManager.getInstalledPackages(0);
        Intrinsics.checkNotNullExpressionValue(installedPackages, "packageManager.getInstalledPackages(0)");
        return filterNotSystemApp(installedPackages);
}

?

?現(xiàn)在的APP檢測(cè)環(huán)境都挺全

審核編輯:湯梓紅

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • Android
    +關(guān)注

    關(guān)注

    12

    文章

    3945

    瀏覽量

    127927
  • APP
    APP
    +關(guān)注

    關(guān)注

    33

    文章

    1577

    瀏覽量

    72774
  • 調(diào)試
    +關(guān)注

    關(guān)注

    7

    文章

    589

    瀏覽量

    34061
  • 環(huán)境檢測(cè)
    +關(guān)注

    關(guān)注

    0

    文章

    20

    瀏覽量

    7581

原文標(biāo)題:Android App環(huán)境檢測(cè)分析

文章出處:【微信號(hào):哆啦安全,微信公眾號(hào):哆啦安全】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    Android APP如何進(jìn)行訪問硬件驅(qū)動(dòng)

    本文我們要講的是在用 i.MX8 平臺(tái)開發(fā)時(shí),Android APP 如何進(jìn)行訪問硬件驅(qū)動(dòng)。
    的頭像 發(fā)表于 12-04 13:50 ?1776次閱讀
    <b class='flag-5'>Android</b> <b class='flag-5'>APP</b>如何進(jìn)行訪問硬件驅(qū)動(dòng)

    #Android開發(fā) Android開發(fā)環(huán)境搭建_1.9 案例1:我的第一個(gè)App(HiAndroid

    Android
    電子知識(shí)科普
    發(fā)布于 :2022年12月08日 17:55:54

    [資料分享]+《Android軟件安全與逆向分析

    環(huán)境搭建 1  1.1  Windows分析環(huán)境搭建 1  1.1.1  安裝JDK 1  1.1.2  安裝Android SDK 3  1.1.3  安裝
    發(fā)表于 09-26 10:53

    史無前例,詳細(xì)視頻講解開發(fā)AndroidAPP開發(fā)!!

    導(dǎo)讀:本文記錄了一個(gè)機(jī)友-小徐基于機(jī)智云APP開源框架,從搭建Java環(huán)境開始,教你下載JDk、下載AndroidStudio,到控制設(shè)備頁(yè)面等,完成一款正式版安卓APP的開發(fā)過程。擅
    發(fā)表于 07-13 12:16

    如何使用BlueSTSDK Android App檢測(cè)加速事件?

    你好, 我正在使用BlueSTSDK Android應(yīng)用程序接收STEVAL-STLKT01V1 SensorTile通過藍(lán)牙低功耗傳輸?shù)臄?shù)據(jù)。我想用這個(gè)應(yīng)用程序檢測(cè)加速度計(jì)事件作為方向,單擊等
    發(fā)表于 10-16 10:15

    分享一個(gè)不錯(cuò)的單片機(jī)與Android App的通信方案

    源碼傳送門前言本篇文章將圍繞App與單片機(jī)的藍(lán)牙通信來說說lz最近進(jìn)行開發(fā)的一些方案與思考此文分為三部分:單片機(jī)的PWM與串口通信Android的藍(lán)牙開發(fā)單片機(jī)與Android App
    發(fā)表于 01-10 06:25

    怎么實(shí)現(xiàn)Android APP與STM32無線環(huán)境控制系統(tǒng)的設(shè)計(jì)?

    如何實(shí)現(xiàn)Android APP與STM32無線環(huán)境控制系統(tǒng)的設(shè)計(jì)?
    發(fā)表于 01-19 07:15

    Android內(nèi)核鉤子檢測(cè)技術(shù)

    針對(duì)Android平臺(tái)上內(nèi)核級(jí)鉤子檢測(cè)的研究,提出了一種結(jié)合基于特征模式的靜態(tài)檢測(cè)技術(shù)和基于行為分析的動(dòng)態(tài)檢測(cè)技術(shù)的
    發(fā)表于 01-26 18:01 ?1次下載
    <b class='flag-5'>Android</b>內(nèi)核鉤子<b class='flag-5'>檢測(cè)</b>技術(shù)

    Android開發(fā)APP應(yīng)該如何省電

    AndroidManifest.xml中加上DEVICE_POWER的權(quán)限??墒羌恿藱?quán)限之后,ADT又提示錯(cuò)誤“Permission is only granted to system apps”。這下傻眼了,怎么會(huì)說“權(quán)限只授予系統(tǒng)應(yīng)用程序”呢?不過這難不倒我,咱把app
    發(fā)表于 07-30 17:35 ?0次下載
    <b class='flag-5'>Android</b>開發(fā)<b class='flag-5'>APP</b>應(yīng)該如何省電

    基于AndroidAPP安全檢測(cè)技術(shù)淺析

    基于AndroidAPP安全檢測(cè)技術(shù)淺析
    發(fā)表于 06-28 16:03 ?16次下載
    基于<b class='flag-5'>Android</b>的<b class='flag-5'>APP</b>安全<b class='flag-5'>檢測(cè)</b>技術(shù)淺析

    Java代碼加密支持Android App Bundle動(dòng)態(tài)化框架

    傳統(tǒng)App加殼技術(shù)無法應(yīng)用在App Bundle模式生成的數(shù)據(jù)包之上。然而,幾維安全推出的Java2C加固方案完美支持Android App Bundle動(dòng)態(tài)化框架,守護(hù)企業(yè)的核心代碼
    的頭像 發(fā)表于 07-29 16:13 ?2362次閱讀
    Java代碼加密支持<b class='flag-5'>Android</b> <b class='flag-5'>App</b> Bundle動(dòng)態(tài)化框架

    Android 12“App Pairs”功能:改造分屏多任務(wù)能力

    Android 12“App Pairs”功能:新分屏多任務(wù)能力,安卓,app,谷歌,分屏,應(yīng)用程序
    發(fā)表于 02-04 14:45 ?1752次閱讀

    基于Android的果蠅識(shí)別APP

    本文檔的主要內(nèi)容詳細(xì)介紹的是基于Android的果蠅識(shí)別APP采用隨機(jī)森林,神經(jīng)網(wǎng)絡(luò)等多種算法。
    發(fā)表于 03-01 09:28 ?6次下載

    Android使用Wireshark抓包

    Frida逆向分析APP實(shí)戰(zhàn) Objection動(dòng)態(tài)分析App Frida Hook的使用方法 Android逆向
    的頭像 發(fā)表于 11-16 10:07 ?4150次閱讀

    Android App開發(fā)新選擇:使用Chaquopy輕松結(jié)合Python

    當(dāng)今的程式開發(fā)中,Python已經(jīng)成為了一個(gè)非常流行的語(yǔ)言,因?yàn)樗梢钥焖倬帉懗龈咝У拇a。然而,如果要將Python結(jié)合到Android App(應(yīng)用程式)中,需要進(jìn)行一些復(fù)雜的設(shè)置和調(diào)整
    的頭像 發(fā)表于 04-25 20:29 ?2319次閱讀
    <b class='flag-5'>Android</b> <b class='flag-5'>App</b>開發(fā)新選擇:使用Chaquopy輕松結(jié)合Python
    德州扑克底牌| AG百家乐官网大转轮| 百家乐赌博机假在哪里| 百胜滩| 百家乐游戏排行榜| k7娱乐| 真钱百家乐游戏大全| 汉中市| 百家乐投注打三断| 博彩网论坛| 超级百家乐2龙虎斗| 真钱百家乐官网送钱| 百家乐跟路技巧| 百家乐官网百家乐官网视频| 百家乐三号的赢法| 沂水县| 电脑赌百家乐可靠吗| 真人百家乐官网赌博技巧| 千亿百家乐的玩法技巧和规则 | 长沙百家乐的玩法技巧和规则 | 千亿娱百家乐的玩法技巧和规则 | 百家乐官网麻将牌| 麻阳| 百家乐大天堂| 赌场百家乐官网破解| 麻将二八杠游戏| 百家乐官网套利| 豪博| 视频百家乐攻略| 百家乐官网网上投注代理商| 大发888客服端下载| 真钱百家乐赌博| 百家乐官网视频麻将| 百家乐娱乐城博彩通博彩网| 百家乐官网视频打麻将| 百家乐娱乐平台网| 百家乐官网网上玩法| 云顶娱乐| 太原百家乐招聘| 九州百家乐官网的玩法技巧和规则 | 华硕百家乐官网的玩法技巧和规则|