標籤:storage ionic mis 位元組 port 保護 tag product 活動
- 9.1 Android系統資訊擷取
- 9.1.1 android.os.Build
- 9.1.2 SystemProperty
- 9.1.3 Android系統資訊執行個體
- 9.2 Android Apk應用資訊擷取之PackageManager
- 9.3 Android Apk應用資訊擷取之ActivityManager
- 9.4 解析Packages.xml擷取系統資訊
- 9.5 Android安全機制
- 9.5.1 Android安全機制簡介
- 9.5.2 Android系統安全隱患
- 9.5.3 Android Apk反編譯
- 9.5.4 Android Apk加密
要擷取系統的配置資訊,通常可以從以下兩個方面擷取:
- android.os.Build
- SystemProperty
該類包含系統編譯時間大量裝置、配置資訊:
- Build.BOARD:主板
- Build.BRAND:Android系統定製商
- Build.SUPPORTED_ABIS:CPU指令集
- Build.DEVICE:裝置參數
- Build.DISPLAY:顯示屏參數
- Build.FINGERPRINT:唯一編號
- Build.SERIAL:硬體序號
- Build.ID:修訂版本列表
- Build.MANUFACTURER:硬體製造商
- Build.MODEL:版本
- Build.HARDWARE:硬體名
- Build.PRODUCT:手機產品名
- Build.TAGS:描述Build的標籤
- Build.TYPE:Builder類型
- Build.VERSION.CODENAME:當前開發代號
- Build.VERSION.INCREMENTAL:源碼控製版本號
- Build.VERSION.RELEASE:版本字串
- Build.VERSION.SDK_INT:版本號碼
- Build.HOST:host值
- Build.USER:User名
- Build.TIME:編譯時間
SystemProperty包含了許多系統配置屬性值和參數:
- os.version:OS版本
- os.name:OS名稱
- os.arch:OS架構
- user.home:Home屬性
- user.name:Name屬性
- user.dir:Dir屬性
- user.timezone:時區
- path.separator:路徑分隔字元
- line.separator:行分隔字元
- file.separator:檔案分隔字元
- java.vendor.url:Java vender Url屬性
- java.class.path:Java Class屬性
- java.class.version:Java Class版本
- java.vendor:Java Vender屬性
- java.version:Java版本
- java.home:Java Home屬性
上面列舉了那麼多,讓我們通過代碼擷取他們的系統資訊:
我們還可以通過命令列模式查看系統資訊:
- 命令列模式進入system/build.prop檔案目錄,使用cat build.prop命令查看檔案資訊
我們還可以通過adb shell的getprop來擷取對應的屬性值:
- 進入adb shell,使用getprop ro.build.id擷取資訊
還有一個非常重要的目錄存放系統資訊,那就是/proc目錄:
- 命令列模式進入/proc檔案目錄,使用cat cpuinfo命令開啟cpuinfo檔案查看系統資訊
看了這麼多系統資訊,應該看Apk應用資訊了,在ADB Shell命令中,有兩個非常強大的助手,PM和AM,PM主宰著應用的包管理,而AM主宰著應用的活動管理
- ActivityInfo
ActivityInfo封裝在了Mainfest檔案中的< activity >和< eceiver>之間的所有資訊,包括name、icon、label、launchMode等。
- ServiceInfo
ServiceInfo與ActivityInfo類似,封裝了< service>之間的所有資訊。
- ApplicationInfo
它封裝了< application>之間的資訊,特別的是,ApplicationInfo包含了很多Flag
- FLAG_SYSTEM表示為系統應用
- FLAG_EXTERNAL_STORAGE表示為安裝在SDcard上的應用
- PackageInfo
PackageInfo與前面三個Info類類似,都是用於封裝Manifest檔案的相關節點資訊,而PageageInfo包含了所有的Activity和Service資訊。
- ResolveInfo
ResolveInfo包含了< intent>資訊的上一級資訊,所以它可以返回ActivityInfo、ServiceInfo等包含了< intent>的資訊
- PackageManager中封裝的用來擷取這些資訊的方法:
- getPackageManager():通過這個方法可以返回一個PackageManager對象
- getApplicationInfo():以ApplicationInfo的形式返回指定包名的ApplicationInfo
- getApplicationIcon():返回指定包名的Icon
- getInstalledApplications():以ApplicationInfo的形式返回安裝的應用
- getInstalledPackages():以PackageInfo的形式返回安裝的應用
- queryIntentActivities():返回指定Intent的ResolveInfo對象、Activity集合
- queryIntentServices():返回指定Intent的ResolveInfo對象、Service集合
- resolveActivity():返回指定Intent的Activity
- resolveService():返回指定Intent的Service
下面通過一個實際的例子通過PackageManager篩選不同類型的App,利用ApplicationInfo中的FLAG_SYSTEM來判斷:
- 如果當前應用的flags & ApplicationInfo.FLAG_SYSTEM !=0則為系統應用
- 如果flags & ApplicationInfo.FLAG_SYSTEM <=0 則為第三方應用
- 特殊的,當系統應用升級後,也將會成為第三方應用: flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP !=0
- 如果當前應用的flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE !=0 則為安裝在SDCard上的應用
我們封裝一個Bean來儲存我們所需的欄位:
接下來,通過上面所說的判斷方法來判斷各種類型的應用:
ActivityManager擷取應用程式資訊封裝了不少Bean對象:
- ActivityManager.MemoryInfo
MemoryInfo有幾個非常重要的欄位:availMem(系統可用記憶體),totalMem(總記憶體),threshold(低記憶體的閾值,即區分是否低記憶體的臨界值),lowMemory(是否處於低記憶體)
- Debug.MemoryInfo
這個MemoryInfo用於統計進程下的記憶體資訊
- RunningAppProcessInfo
運行進程的資訊,儲存的欄位有:processName(進程名),pid(進程pid),uid(進程uid),pkgList(該進程下的所有包)
- RunningServiceInfo
啟動並執行服務資訊,在它裡面同樣包含了一些服務進程資訊,同時還有一些其他資訊,activeSince(第一次被啟用的時間、方式),foreground(服務是否在後台執行)
下面同樣通過例子來看看如何使用ActivityManager,我們封裝一個Bean來儲存我們所需的欄位:
接下來,調用getRunningAppProcesses方法,返回當前啟動並執行進程資訊,並將我們關心的資訊儲存到Bean中:
在系統初始化的時候,PackageManager的底層實作類別PackageManagerService會去掃描系統的一些特定目錄,並且解析其中的Apk檔案,同時,Android把它擷取到的應用資訊,儲存到XML檔案中,做成一個應用的花名冊,當系統中的APK安裝、刪除、升級時,它也會被更新
這個packages.xml位於/data/system/目錄下,我們用adb pull命令把他匯出來,進行查看分析:
無知識點
- 第一道防線:代碼安全機制——代碼混淆proguard
proguard可以混淆關鍵代碼、替換命名讓破壞者閱讀難,同樣也可以壓縮代碼,最佳化編譯後的Java位元組碼
- 第二道防線:應用接入許可權控制——資訊清單檔許可權聲明,許可權檢查機制
任何App在使用Android受限資源的時候,都需要顯示向系統聲明所需的許可權,只有當一個應用App具有相應的許可權,才能申請受限資源的時候,通過許可權機制的檢查並使用系統的Binder對象完成對系統服務的調用,但是這道防線也有先天性不足,如以下幾項:
- 被授與權限無法停止
- 在應用聲明App使用許可權的時,使用者無法針對部分許可權進行限制
- 許可權的聲明機制與使用者的安全理念相關
Android系統通常按照以下順序來檢查操作者的許可權:
- 首先,判斷permission名稱,如果為空白則直接返回PERMISSION_DENIED
- 其次,判斷Uid,如果為0則為root許可權,不做許可權控制,如果為System Service的Uid則為系統服務,不做許可權控制,如果Uid與參數中的請求Uid不同則返回PERMISSION_DENIED
- 最後,通過調用packagemanageservice.checkUidPermission()方法來判斷該Uid是否具有相應的許可權,該方法會去XML的許可權列表和系統級的platform.xml中進行尋找
- 第三道防線:應用簽名機制一數位憑證
Android中所有的App都會有一個數位憑證,這就是App的簽名,數位憑證用於保護App的作者和其App的信任關係,只有擁有相同數位簽章的App,才會在升級時被認為是同一App,而且Android系統不會安裝沒有簽名的App
- 第四道防線:Linux核心層安全機制一一Uid 存取權限控制
Animid本質是基於Linux核心開發的,所以Android同樣繼承了Linux的安全特性,托福和雅思比如檔案系統的許可權控制是由user,group,other與讀(r),寫(w),執行(x)的不同組合來實現的,同樣,Android也實現了這套機制,通常情況下,只有System、root使用者才有許可權訪問到系統檔案,而一般使用者無法訪問
- 第五道防線:Android虛擬機器沙箱機制——沙箱隔流
Android的App運行在虛擬機器中,因此才有沙箱機制,可以讓應用之間相互隔離,通常情況下,不同的應用之間不能互相訪問,每個App都有與之對應的Uid,每個App也運行在單獨的虛似機中,與其他應用完全隔離,在實現安全機制的基礎上,也讓應用之間能夠互不影響,即時一個應用崩潰,,也不會導致其他應用異常
- 代碼漏洞
- Root風險
- 安全機制不健全
- 使用者安全意識
- Android開發原則與安全
書本列舉的幾個點相信大家也都比較熟悉,所以不做解釋了
這裡個人的部落格有簡單的介紹:Android四大組件——Activity轉場效果、殺死進程、殺死所有Activity、安裝及反編譯
為了能夠對編譯好的JavaClass檔案進行一些保護,通常會用ProGuard混淆代碼:
- ProGuard:用無意義的字母來重新命名類、欄位、方法和屬性
- 刪除無用的類、欄位、方法和屬性,以及刪除沒用的注釋,最大限度地最佳化位元組碼檔案
使用ProGuard也簡單,在Android Studio中可以開啟build.gradle(Module:app):
這裡的minifyEnabled就是開啟ProGuard的開關,proGuardFiles屬於配置混淆檔案,分為兩部分:
- 使用預設的混淆檔案,位於< SDK目錄>/tools/proguard/proguard-android.txt目錄下
- 使用自訂混淆檔案,可以在項目的App檔案夾找到這個檔案,在這個檔案裡可以定義引入的第三方依賴包的混淆規則
Android群英傳知識點回顧——第九章:Android系統資訊與安全機制