第九章 Android 系統(tǒng)信息與安全機(jī)制

玩了這么久的Android設(shè)備,作為一個(gè)開(kāi)發(fā)者,其實(shí)需要比普通用戶知道更多關(guān)于Android 系統(tǒng)的信息,就算不知道,也需要知道怎么輕松獲取的方式

  • Android系統(tǒng)信息的獲取
  • PackageManager的使用
  • ActivityManager的使用
  • Android安全機(jī)制
Android系統(tǒng)信息的獲取

由于android手機(jī)的開(kāi)源性,手機(jī)的配置各種各樣,那些優(yōu)化大師之類的東西,都可以跑分和看配置信息,那他們是從哪里知道這些信息的呢?遙想獲取系統(tǒng)的配置信息,通??梢詮囊韵聝蓚€(gè)方面獲取

  • android.os.Build
  • SystemProperty
1.android.os.Build

android.os.Build類里面的信息非常的豐富,它包含了系統(tǒng)編譯時(shí)的大量設(shè)備,配置信息,我們列舉一點(diǎn)

  • Build.BOARD——主板
  • Build.BRAND——Android系統(tǒng)定制商
  • Build.SUPPORTED_ABIS——CPU指令集
  • Build.DEVICE——設(shè)備參數(shù)
  • Build.DISPLAY——顯示屏參數(shù)
  • Build.FINGERPRINT——唯一編號(hào)
  • Build.SERIAL——硬件序列號(hào)
  • Build.ID——修訂版本列表
  • Build.MANUFACTURER——硬件制造商
  • Build.MODEL——版本
  • Build.HARDWARE——硬件名
  • Build.PRODUCT——手機(jī)產(chǎn)品名
  • Build.TAGS——描述Build的標(biāo)簽
  • Build.TYPE——Builder類型
  • Build.VERSION.CODENAME——當(dāng)前開(kāi)發(fā)代號(hào)
  • Build.VERSION.INCREMENTAL——源碼控制版本號(hào)
  • Build.VERSION.RELEASE——版本字符串
  • Build.VERSION.SDK_INT——版本號(hào)
  • Build.HOST——host值
  • Build.USER——User名
  • Build.TIME——編譯時(shí)間

上面的一些參數(shù)沒(méi)有注釋,他們來(lái)自系統(tǒng)的RO值中,這些值都是手機(jī)生產(chǎn)商配置的只讀的參數(shù)值,根據(jù)廠家的配置不同而不同,接下來(lái)我們?cè)賮?lái)看一下另一個(gè)存儲(chǔ)設(shè)備軟硬件信息的類——SystemProperty

2.SystemProperty

SystemProperty類包含了許多系統(tǒng)配置屬性值和參數(shù),很多信息和上面通過(guò)android.os.Build獲取的值是相同的,我們列舉一些常用的

  • os.version——OS版本
  • os.name——OS名稱
  • os.arch——OS架構(gòu)
  • user.home——home屬性
  • user.name——name屬性
  • user.dir——Dir屬性
  • user.timezone——時(shí)區(qū)
  • 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屬性
3. Android系統(tǒng)信息實(shí)例

廢話不多說(shuō),直接上例子吧

        textView = findViewById(R.id.textView);

        stringBuilder = new StringBuilder();
        stringBuilder.append("\n Build.BOARD ==="+ Build.BOARD);
        stringBuilder.append("\n Build.BRAND ==="+ Build.BRAND);
        stringBuilder.append("\n Build.SUPPORTED_ABIS ==="+ Build.SUPPORTED_ABIS);
        stringBuilder.append("\n Build.DEVICE ==="+ Build.DEVICE);
        stringBuilder.append("\n Build.DISPLAY ==="+ Build.DISPLAY);
        stringBuilder.append("\n Build.FINGERPRINT ==="+ Build.FINGERPRINT);
        stringBuilder.append("\n Build.SERIAL ==="+ Build.SERIAL);

        stringBuilder.append("\n Build.HOST ==="+ Build.HOST);
        stringBuilder.append("\n Build.USER ==="+ Build.USER);
        stringBuilder.append("\n Build.TIME ==="+ Build.TIME);
        stringBuilder.append("\n ================================");
        stringBuilder.append("\n version ==="+ System.getProperty("os.version"));
        stringBuilder.append("\n name ==="+ System.getProperty("os.name"));
        stringBuilder.append("\n arch ==="+ System.getProperty("os.arch"));
        stringBuilder.append("\n home ==="+ System.getProperty("user.home"));
        stringBuilder.append("\n name ==="+ System.getProperty("user.name"));
        stringBuilder.append("\n dir ==="+ System.getProperty("user.dir"));
        stringBuilder.append("\n timezone ==="+ System.getProperty("user.timezone"));
        stringBuilder.append("\n path separator ==="+ System.getProperty("path.separator"));
        stringBuilder.append("\n line separator ==="+ System.getProperty("line.separator"));
        stringBuilder.append("\n file separator ==="+ System.getProperty("file.separator"));
        stringBuilder.append("\n java.vendor.url ==="+ System.getProperty("java.vendor.url"));
        stringBuilder.append("\n java.class.path ==="+ System.getProperty("java.class.path"));
        stringBuilder.append("\n java.class.version ==="+ System.getProperty("java.class.version"));
        stringBuilder.append("\n java.vendor ==="+ System.getProperty("java.vendor"));
        stringBuilder.append("\n java.version ==="+ System.getProperty("java.version"));
        stringBuilder.append("\n java.home ==="+ System.getProperty("java.home"));

        textView.setText(stringBuilder);

Android Apk 應(yīng)用信息獲取之 PackageManager

  • PackageManager


    Package結(jié)構(gòu)

最里面的框就代表整個(gè)Activity的信息,系統(tǒng)提供了ActivityInfo類來(lái)進(jìn)行封裝
而Android提供了PackageManager來(lái)負(fù)責(zé)管理所有已安裝的App,PackageManager可以獲得AndroidManifest中不同節(jié)點(diǎn)的封裝信息,下面是一些常用的封裝信息:

  • ActivityInfo

ActivityInfo封裝在了Mainfest文件中的< activity >和< receiver>之間的所有信息,包括name、icon、label、launchMode等。

  • ServiceInfo

ServiceInfo與ActivityInfo類似,封裝了< service>之間的所有信息。

  • ApplicationInfo

它封裝了< application>之間的信息,特別的是,ApplicationInfo包含了很多Flag,F(xiàn)LAG_SYSTEM表示為系統(tǒng)應(yīng)用,F(xiàn)LAG_EXTERNAL_STORAGE表示為安裝在SDcard上的應(yīng)用,通過(guò)這些flag可以很方便的判斷應(yīng)用的類型。

  • PackageInfo

PackageInfo包含了所有的Activity和Service信息。

  • ResolveInfo

ResolveInfo包含了< intent>信息的上級(jí)信息,所以它可以返回ActivityInfo、ServiceInfo等包含了< intent>的信息,經(jīng)常用來(lái)幫助找到那些包含特定intent條件的信息,如帶分享功能、播放功能的應(yīng)用。
有了這些封裝的信息后,還需要有特定的方法來(lái)獲取它們,下面就是PackageManager中封裝的用來(lái)獲取這些信息的方法:

  • getPackageManager()——通過(guò)這個(gè)方法可以返回一個(gè)PackageManager對(duì)象。

  • getApplicationInfo()——以ApplicationInfo的形式返回指定包名的ApplicationInfo。

  • getApplicationIcon()——返回指定包名的Icon。

  • getInstalledApplications()——以ApplicationInfo的形式返回安裝的應(yīng)用。

  • getInstalledPackages()——以PackageInfo的形式返回安裝的應(yīng)用。

  • queryIntentActivities()——返回指定Intent的ResolveInfo對(duì)象、Activity集合。

  • queryIntentServices()——返回指定Intent的ResolveInfo對(duì)象、Service集合。

  • resolveActivity()——返回指定Intent的Activity。

  • resolveService()——返回指定Intent的Service。

根據(jù)ApplicationInfo的flag來(lái)判斷App的類型:

  • 如果當(dāng)前應(yīng)用的flags & ApplicationInfo.FLAG_SYSTEM != 0則為系統(tǒng)應(yīng)用

  • 如果flags & ApplicationInfo.FLAG_SYSTEM <= 0 則為第三方應(yīng)用

  • 特殊的當(dāng)系統(tǒng)應(yīng)用升級(jí)后也會(huì)成為第三方應(yīng)用,此時(shí) flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP != 0;

  • 如果flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE != 0 則為安裝在SDCard上的應(yīng)用。

主要代碼粘過(guò)來(lái),很簡(jiǎn)單的

package com.example.androidsystem;

import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.ListView;

import java.util.ArrayList;
import java.util.List;

/**
* Created by Younger on 2018/3/12.
*/
public class PMManageActivity extends AppCompatActivity implements View.OnClickListener {
   private PackageManager mPackageManager;

   private ListView mListView;
   private PackageAdapter mAdapter;
   List<PMBean> result;
   @Override
   protected void onCreate(@Nullable Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       setContentView(R.layout.main_list_activity);
       mPackageManager = getPackageManager();
       mListView = (ListView) findViewById(R.id.mListView);
       mAdapter = new PackageAdapter(this);
       mListView.setAdapter(mAdapter);
       findViewById(R.id.btn_all).setOnClickListener(this);
       findViewById(R.id.btn_other).setOnClickListener(this);
       findViewById(R.id.btn_system).setOnClickListener(this);

   }

   @Override
   public void onClick(View view) {
       switch (view.getId()) {
           case R.id.btn_all:
               result = getAppInfo(R.id.btn_all);
               break;
           case R.id.btn_other:
               result = getAppInfo(R.id.btn_other);
               break;
           case R.id.btn_system:
               result = getAppInfo(R.id.btn_system);
               break;
           default:
               result = new ArrayList<>();
       }
       mAdapter.addAll(result);
   }

   private List<PMBean> getAppInfo(int flag) {
       List<ApplicationInfo> appInfos = mPackageManager.getInstalledApplications(
               PackageManager.GET_UNINSTALLED_PACKAGES);
       List<PMBean> list = new ArrayList<>();
       //根據(jù)不同的flag來(lái)切換顯示不同的App類型
       switch (flag) {
           case R.id.btn_all:
               list.clear();
               for (ApplicationInfo appInfo : appInfos) {
                   list.add(makeAppInfo(appInfo));
               }

               break;
           case R.id.btn_other:
               list.clear();
               for (ApplicationInfo appInfo : appInfos) {
                   if ((appInfo.flags & ApplicationInfo.FLAG_SYSTEM) <= 0) {
                       list.add(makeAppInfo(appInfo));
                   } else if ((appInfo.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0){
                       list.add(makeAppInfo(appInfo));
                   }
               }
               break;
           case R.id.btn_system:
               list.clear();
               for (ApplicationInfo appInfo : appInfos) {
                   if ((appInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
                       list.add(makeAppInfo(appInfo));
                   }
               }
               break;
       }
       return list;
   }

   private PMBean makeAppInfo(ApplicationInfo appInfo) {
       PMBean info = new PMBean();
       info.setAppIcon(appInfo.loadIcon(mPackageManager));
       info.setAppLabel(appInfo.loadLabel(mPackageManager).toString());
       info.setPkgName(appInfo.packageName);
       return info;
   }

}

Android Apk 應(yīng)用信息獲取之 ActivityManager

PackageManager 重點(diǎn)在于獲得應(yīng)用的包信息,ActivityManager 重點(diǎn)在于獲取運(yùn)行的應(yīng)用程序信息, 同PackageManager一樣,ActivityManager也封裝了不少的Bean對(duì)象,我們選幾個(gè)重點(diǎn)來(lái)說(shuō)一下

  • ActivityManager.MemoryInfo

MemoryInfo有幾個(gè)非常重要的字段:availMem(系統(tǒng)可用內(nèi)存),totalMem(總內(nèi)存),threshold(低內(nèi)存的閾值,即區(qū)分是否低內(nèi)存的臨界值),lowMemory(是否處于低內(nèi)存)。

  • Debug.MemoryInfo

這個(gè)MemoryInfo用于統(tǒng)計(jì)進(jìn)程下的內(nèi)存信息。

  • RunningAppProcessInfo

運(yùn)行進(jìn)程的信息,存儲(chǔ)的字段有:processName(進(jìn)程名),pid(進(jìn)程pid),uid(進(jìn)程uid),pkgList(該進(jìn)程下的所有包)

  • RunningServiceInfo

運(yùn)行的服務(wù)信息,在它里面同樣包含了一些服務(wù)進(jìn)程信息,同時(shí)還有一些其他信息。activeSince(第一次被激活的時(shí)間、方式),foreground(服務(wù)是否在后臺(tái)執(zhí)行)。

獲取ActivityManager
activityManager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
/**
     * 正在運(yùn)行
     * @return
     */
    private List<ActivityManager.RunningAppProcessInfo> getRunningProcossInfo(){
        mAMProcessInfo = new ArrayList<>();
        List<ActivityManager.RunningAppProcessInfo>appRunningList = activityManager.getRunningAppProcesses();

        for (int i = 0;i<appRunningList.size();i++){
            ActivityManager.RunningAppProcessInfo info = appRunningList.get(i);
            int pid = info.pid;
            int uid = info.uid;
            String procossName = info.processName;
            int[]memoryPid = new int[]{pid};
            Debug.MemoryInfo[] memoryInfos = activityManager.getProcessMemoryInfo(memoryPid);

            int memorySize = memoryInfos[0].getTotalPss();

            AMProcessInfo processInfo = new AMProcessInfo();
            processInfo.setPid(""+pid);
            processInfo.setUid(""+uid);
            processInfo.setMemorySize(""+memorySize);
            processInfo.setProcessName(procossName);
            appRunningList.add(processInfo);
        }
        return  appRunningList;
    }
解析Packages.xml獲取系統(tǒng)信息

熟悉Android開(kāi)機(jī)啟動(dòng)流程的朋友大概知道,在系統(tǒng)初始化到時(shí)候,packagemanager的底層實(shí)現(xiàn)類packagemanagerService會(huì)去掃描系統(tǒng)的一些特定目錄,并且解析其中的Apk文件,同時(shí)Android把他獲取到的應(yīng)用信息保存到xml中,做成一個(gè)應(yīng)用的花名冊(cè),就是data/system/apckages.xml,我們用adb pull命令把他導(dǎo)出來(lái),里面的信息也太多了,但是我們只要知道結(jié)果根節(jié)點(diǎn)就可以了

  • < permissions>標(biāo)簽

permissions標(biāo)簽定義了現(xiàn)在系統(tǒng)所有的權(quán)限,也分兩類,系統(tǒng)定義的和app定義的

  • < package>標(biāo)簽

package代表的是一個(gè)apk的屬性

其中各節(jié)點(diǎn)的信息含義大致為

  • name:APK的包名
  • cadePath:APK安裝路徑,主要在system/app和data/app兩種,前者放系統(tǒng)級(jí)別的,后者放系統(tǒng)安裝的
  • userid:用戶ID
  • version:版本
  • < perms>標(biāo)簽

通過(guò)這個(gè)xml文件的標(biāo)簽,可以獲取到很多手機(jī)應(yīng)用的信息,通常在進(jìn)行系統(tǒng)層開(kāi)發(fā)的時(shí)候,可以通過(guò)這個(gè)xml獲取更多有意義的東西

Android安全機(jī)制
  • 第一道防線

代碼安全機(jī)制——代碼混淆proguard
由于java語(yǔ)言的特殊性,即使是編譯成apk的應(yīng)用程序也存在反編譯的風(fēng)險(xiǎn),而proguard則是在代碼從上對(duì)app的第一道程序,他混淆關(guān)鍵代碼,替換命名,讓破壞者閱讀難,同樣也可以壓縮代碼,優(yōu)化編譯后的字節(jié)

  • 第二道防線

應(yīng)用接入權(quán)限控制——清單文件權(quán)限聲明,權(quán)限檢查機(jī)制,
任何app在使用Android受限資源的時(shí)候,都需要顯示向系統(tǒng)生命權(quán)限,只有當(dāng)一個(gè)應(yīng)用app具有相應(yīng)的權(quán)限,才能申請(qǐng)相應(yīng)的資源,通過(guò)權(quán)限機(jī)制的檢查并且使用并且使用系統(tǒng)的Binder對(duì)象完成對(duì)系統(tǒng)服務(wù)的調(diào)用,但是這道防線也有先天的不足,如以下幾項(xiàng)

  • 被授予的權(quán)限無(wú)法停止
  • 在應(yīng)用聲明app使用權(quán)限的時(shí)候,用戶無(wú)法針對(duì)部分權(quán)限進(jìn)行限制
  • 權(quán)限的判斷機(jī)制與用戶的安全理念相關(guān)

Android系統(tǒng)通常按照以下順序來(lái)檢查操作者的權(quán)限.
首先,判斷permission名稱.如果為空則直接返回PERMISSION_DENIED
其次。判斷Uid,如果為0則為root權(quán)限,不做權(quán)限控制,如果為systyemsystem service的uid則為系統(tǒng)服務(wù).不做權(quán)限控制:如果Uid與參數(shù)中的請(qǐng)求uid不同則返回PERMISSION_DENIED
最后,通過(guò)調(diào)用packagemanageservice.checkUidPermission()方法來(lái)判斷該uid是否具有相應(yīng)的權(quán)限,該方法會(huì)去xml的權(quán)限列表和系統(tǒng)級(jí)的權(quán)限進(jìn)行查找
通過(guò)上面的步驟Android就確定了使用者是否具有某項(xiàng)使用權(quán)限

  • 第三道防線

應(yīng)用簽名機(jī)制一數(shù)字證書(shū)。
Android中所有的app都會(huì)有個(gè)數(shù)字證書(shū),這就是app的簽名.數(shù)字證書(shū)用于保護(hù)app的作者和其app的信任關(guān)系,只有擁有相同數(shù)字簽名的app,才會(huì)在升級(jí)時(shí)被認(rèn)為是同一app,而且Android系統(tǒng)不會(huì)安裝沒(méi)有簽名的App

  • 第四道防線

Linux內(nèi)核層安全機(jī)制一一Uid 訪問(wèn)權(quán)限控制。
Animid本質(zhì)是基于Linux內(nèi)核開(kāi)發(fā)的,所以Android同樣繼承了Linux的安全特性,比如Linux文件系統(tǒng)的權(quán)限控制是由user,group,other與讀,寫(xiě),執(zhí)行的不同組合來(lái)實(shí)現(xiàn)的,同樣,Android也實(shí)現(xiàn)了這套機(jī)制”通常情況下.只有system,root用戶才有權(quán)限訪問(wèn)到系統(tǒng)文件,而一般用戶無(wú)法訪問(wèn)。

  • 第五道防線

Android虛擬機(jī)沙箱機(jī)制——沙箱隔離
Android的App運(yùn)行在虛擬機(jī)中 因此才有沙箱機(jī)制,可以讓?xiě)?yīng)用之間相互隔離,通常情況下.不同的應(yīng)用之間不能互相訪問(wèn).每個(gè)App都單獨(dú)的運(yùn)行在虛似機(jī)中,與其他應(yīng)用完全隔離.在實(shí)現(xiàn)安全機(jī)制的基礎(chǔ)上,也讓?xiě)?yīng)用之間能夠互不影響,即時(shí)一個(gè)應(yīng)用崩潰,,也不會(huì)導(dǎo)致其他應(yīng)用異常

雖然通過(guò)以上的五道防線.仍然不能完全保證Android的核心安全”但卻可以在最大程度上給破壞者增加難度,從另一方面來(lái)說(shuō)”這些破壞者的破解也真是推動(dòng)Android安全機(jī)制逐漸健全的動(dòng)力.

Android系統(tǒng)安全隱患
  • 1.代碼漏洞

這個(gè)問(wèn)題存在世界上所有的程序中,沒(méi)有誰(shuí)敢保證自己的程序沒(méi)有bug,有漏洞,如果遇到這種問(wèn)題,大家只能盡快的升級(jí)版本,更新補(bǔ)丁,才能杜絕利用漏洞的攻擊裝,比如Android的LaunchAnyWhere,FakeId,這些都是bug,就是在編寫(xiě)的時(shí)候產(chǎn)生的漏洞,只有期待官方的更新了

    1. root風(fēng)險(xiǎn)

Root權(quán)限是指Android的系統(tǒng)管理員權(quán)限,類似于windows系統(tǒng)中的Administrator。具有Root權(quán)限的用戶可以訪問(wèn)和修改手機(jī)中幾乎所有的文件,“Root”在一段時(shí)間內(nèi)一度成為Android的代名詞, 無(wú)Root,不Android”。的確,Root掉手機(jī)后,可以解鎖很多普通用戶無(wú)法完成的工作,如限制各個(gè)應(yīng)用app的數(shù)據(jù)流量.系統(tǒng)文件管理丶自定義修改系統(tǒng)等,但同時(shí)手機(jī)的安全性也會(huì)因此大打折扣。隨著android系統(tǒng)越來(lái)越完善,root的必要性也越來(lái)越低普通用戶在不root的情況下,完全可以正常使用大部分App。需要Root權(quán)限的大多為一些開(kāi)發(fā)者,由于開(kāi)發(fā)的需要,不得不將手機(jī)root,而root后的手機(jī),就少了一層Linux的天然屏障,整個(gè)系統(tǒng)核心就完全暴露在人侵者面前,在你沒(méi)有察覺(jué)的情況下大肆破壞。所以,針對(duì)普通用戶,希望都盡量不要Root手機(jī)以免帶來(lái)不必要的損失

    1. 安全機(jī)制不健全

由于Android的權(quán)限管理機(jī)制并不完美,所以很多手機(jī)開(kāi)發(fā)商,通常會(huì)在RoM中增加自己的一套權(quán)限管理工具來(lái)幫助用戶控制手機(jī)中應(yīng)用的權(quán)限,如應(yīng)用許可

  • 4.用戶安全意識(shí)

用戶對(duì)于安全隱患的察覺(jué)里也是保護(hù)手機(jī)安全的一個(gè)重要因素。用戶可以通過(guò)在正規(guī)的應(yīng)用市場(chǎng)下載和安裝應(yīng)用時(shí)通過(guò)列出來(lái)的應(yīng)用權(quán)限申請(qǐng)信息來(lái)大致判斷一個(gè)應(yīng)用的安全性,比如我們?cè)?jīng)十分喜歡用的xx神器”,其實(shí)沒(méi)有一點(diǎn)技術(shù)含量,無(wú)非就是在你安裝了應(yīng)用之后遍歷一遍你的聯(lián)系人并發(fā)送帶有鏈接的短信而已當(dāng)用戶在安裝不明來(lái)源的應(yīng)用時(shí)如果一個(gè)娛樂(lè)類型的app生命權(quán)限的時(shí)候不僅要聯(lián)系人又要短信權(quán)限,這個(gè)時(shí)候就需要警惕了,用戶也可以在市場(chǎng)上下載一些安全類App,如LEB安全大師,360安全等, 雖然這些軟件會(huì)加重系統(tǒng)負(fù)擔(dān),但是為了安全也是值得的

    1. Android開(kāi)發(fā)原則與安全

眾所周知,Android與ioS系統(tǒng)一個(gè)非常顯著的區(qū)別就是_一個(gè)是開(kāi)放系統(tǒng),一個(gè)是封閉系統(tǒng),開(kāi)放自然有開(kāi)放的好處,技術(shù)進(jìn)步快,產(chǎn)品豐富,封閉也有封閉的好處,安全性高,可控性高,Google本著開(kāi)源的精神開(kāi)放了Android的源代碼,但隨之而來(lái)的各種安全問(wèn)題也讓Android倍受詬病,過(guò)度的開(kāi)放與可定制化,不僅造成了Android的碎片化嚴(yán)重, 同時(shí)也給很多不法應(yīng)用以可乘之機(jī),但可喜的是,隨著Android的發(fā)展日益壯大,Google也在著手處理開(kāi)發(fā)與安全的問(wèn)題,相信在不久的將來(lái),這一矛盾會(huì)越來(lái)越小

Android Apk反編譯

關(guān)于反編譯,看這篇文章就行了 http://unclechen.github.io/2016/09/07/Android%E5%8F%8D%E7%BC%96%E8%AF%91%E6%8A%80%E6%9C%AF%E6%80%BB%E7%BB%93/

好了 ,就這些了;

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容