Android中级——系统信息与安全机制

news2024/11/13 3:35:38

系统信息与安全机制

  • 系统信息获取
    • /system/build.prop
    • /proc
    • android.os.build
    • SystemProperty
    • PackageManager
    • ActivityManager
    • packages.xml
      • permissions标签
      • package标签
      • perms标签
  • 安全机制
  • Apk反编译
    • apktool
    • dex2jar
    • jd-gui
  • Apk加密

系统信息获取

/system/build.prop

存放一些配置信息(需要Google apis的模拟器才能运行su)

在这里插入图片描述

此外,还可以通过 getprop 获取上面的信息

在这里插入图片描述

/proc

存储系统运行时各个程序的相关信息

在这里插入图片描述

android.os.build

包含了系统编译时的设备、配置信息

Log.d(TAG, "主板: " + Build.BOARD);
Log.d(TAG, "Android系统定制商: " + Build.BRAND);
for (int i = 0; i < Build.SUPPORTED_ABIS.length; i++) {
    Log.d(TAG, "CPU指令集" + "[" + i + "]" + Build.SUPPORTED_ABIS[i]);
}
Log.d(TAG, "设备参数: " + Build.DEVICE);
Log.d(TAG, "显示屏参数: " + Build.DISPLAY);
Log.d(TAG, "唯一编号: " + Build.FINGERPRINT);
Log.d(TAG, "硬件序列号: " + Build.SERIAL);
Log.d(TAG, "修订版本列表: " + Build.ID);
Log.d(TAG, "硬件制造商: " + Build.MANUFACTURER);
Log.d(TAG, "版本: " + Build.MODEL);
Log.d(TAG, "硬件名: " + Build.HARDWARE);
Log.d(TAG, "手机产品名: " + Build.PRODUCT);
Log.d(TAG, "描述Build的标签: " + Build.TAGS);
Log.d(TAG, "Builder类型: " + Build.TYPE);
Log.d(TAG, "当前开发代号: " + Build.VERSION.CODENAME);
Log.d(TAG, "源码控制版本号: " + Build.VERSION.INCREMENTAL);
Log.d(TAG, "版本字符串: " + Build.VERSION.RELEASE);
Log.d(TAG, "版本号: " + Build.VERSION.SDK_INT);
Log.d(TAG, "host值: " + Build.HOST);
Log.d(TAG, "User名: " + Build.USER);
Log.d(TAG, "编译时间: " + Build.TIME);

模拟器打印如下

主板: goldfish_x86_64
Android系统定制商: google
CPU指令集[0]: x86_64
CPU指令集[1]: x86
设备参数: generic_x86_64
显示屏参数: sdk_gphone_x86_64-userdebug 9 PSR1.180720.093 5456446 dev-keys
唯一编号: google/sdk_gphone_x86_64/generic_x86_64:9/PSR1.180720.093/5456446:userdebug/dev-keys
硬件序列号: unknown
修订版本列表: PSR1.180720.093
硬件制造商: Google
版本: Android SDK built for x86_64
硬件名: ranchu
手机产品名: sdk_gphone_x86_64
描述Build的标签: dev-keys
Builder类型: userdebug
当前开发代号: REL
源码控制版本号: 5456446
版本字符串: 9
版本号: 28
host值: xpce4.ams.corp.google.com
User名: android-build
编译时间: 1554935165000

SystemProperty

包含了许多系统配置属性值和参数

Log.d(TAG, "OS版本: " + System.getProperty("os.version"));
Log.d(TAG, "OS名称: " + System.getProperty("os.name"));
Log.d(TAG, "OS架构: " + System.getProperty("os.arch"));
Log.d(TAG, "Home属性: " + System.getProperty("user.home"));
Log.d(TAG, "Name属性: " + System.getProperty("user.name"));
Log.d(TAG, "Dir属性: " + System.getProperty("user.dir"));
Log.d(TAG, "时区: " + System.getProperty("user.timezone"));
Log.d(TAG, "路径分隔符: " + System.getProperty("path.separator"));
Log.d(TAG, "行分隔符: " + System.getProperty("line.separator"));
Log.d(TAG, "文件分隔符: " + System.getProperty("file.separator"));
Log.d(TAG, "Java vender Url属性: " + System.getProperty("java.vendor.url"));
Log.d(TAG, "Java Class路径: " + System.getProperty("java.class.path"));
Log.d(TAG, "Java Class版本: " + System.getProperty("java.class.version"));
Log.d(TAG, "Java Vender属性: " + System.getProperty("java.vendor"));
Log.d(TAG, "Java版本: " + System.getProperty("java.version"));
Log.d(TAG, "Java Home属性: " + System.getProperty("java.home"));

模拟器打印如下

OS版本: 4.4.124+
OS名称: Linux
OS架构: x86_64
Home属性: 
Name属性: root
Dir属性: /
时区: null
路径分隔符: :
行分隔符: 
文件分隔符: /
Java vender Url属性: http://www.android.com/
Java Class路径: .
Java Class版本: 50.0
Java Vender属性: The Android Project
Java版本: 0
Java Home属性: /system

PackageManager

用于获取应用的包信息,如

  • ActivityInfo:Mainifest中<activity>和<receiver>标签之间的信息
  • ServiceInfo:Mainifest中<service>标签之间的信息
  • ApplicationInfo:Mainifest中<Application>标签之间的信息
  • PackageInfo:所有的Activity和Service信息
  • ResolveInfo:<intent>的上一级信息,如ActivityInfo、ServiceInfo,通常用于查找包含特定Intent的信息

如下创建bean类存储App的标签、图标和包名

public class PMAppInfo {

    private String appLabel;
    private Drawable appIcon;
    private String pkgName;

    public PMAppInfo() {
    }

    public String getAppLabel() {
        return appLabel;
    }

    public void setAppLabel(String appLabel) {
        this.appLabel = appLabel;
    }

    public Drawable getAppIcon() {
        return appIcon;
    }

    public void setAppIcon(Drawable appIcon) {
        this.appIcon = appIcon;
    }

    public String getPkgName() {
        return pkgName;
    }

    public void setPkgName(String pkgName) {
        this.pkgName = pkgName;
    }
}

创建适配布局list_item.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/empty"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center_vertical"
    android:orientation="horizontal">

    <ImageView
        android:id="@+id/iv_icon"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_marginLeft="15dp"
        android:orientation="vertical">

        <TextView
            android:id="@+id/tv_label"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />

        <TextView
            android:id="@+id/tv_pkg_name"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
    </LinearLayout>

</LinearLayout>

创建适配器

public class PkgAdapter extends BaseAdapter {
    private Context mContext;
    private List<PMAppInfo> mList;

    public PkgAdapter(Context context) {
        mContext = context;
        mList = new ArrayList<>();
    }

    public void setData(List<PMAppInfo> list) {
        mList.clear();
        mList.addAll(list);
    }

    @Override
    public int getCount() {
        return mList.size();
    }

    @Override
    public PMAppInfo getItem(int position) {
        return mList.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder;
        PMAppInfo item = getItem(position);
        if (convertView == null) {
            holder = new ViewHolder();
            convertView = LayoutInflater.from(mContext).inflate(R.layout.list_item, parent, false);
            holder.mIcon = (ImageView) convertView.findViewById(R.id.iv_icon);
            holder.mLabel = (TextView) convertView.findViewById(R.id.tv_label);
            holder.mPkgName = (TextView) convertView.findViewById(R.id.tv_pkg_name);
            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }
        holder.mIcon.setImageDrawable(item.getAppIcon());
        holder.mLabel.setText(item.getAppLabel());
        holder.mPkgName.setText(item.getPkgName());
        return convertView;
    }

    static class ViewHolder {
        ImageView mIcon;
        TextView mLabel;
        TextView mPkgName;
    }
}

activity_main.xml布局如下,根据点击的按钮加载ListView

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <Button
        android:id="@+id/btn_all"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="All APP"
        android:textAllCaps="false" />

    <Button
        android:id="@+id/btn_system"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="System App"
        android:textAllCaps="false" />

    <Button
        android:id="@+id/btn_third"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Other App"
        android:textAllCaps="false" />

    <Button
        android:id="@+id/btn_sdcard"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Sdcard App"
        android:textAllCaps="false" />

    <ListView
        android:id="@+id/app_info"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</LinearLayout>

根据PackageManager获取所有App,利用ApplicationInfo的flag判断应用类型

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    private static final String TAG = "MainActivity";
    private PackageManager pm;
    private ListView mListView;
    private PkgAdapter mAdapter;

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        pm = getPackageManager();
        mListView = (ListView) findViewById(R.id.app_info);
        mAdapter = new PkgAdapter(this);
        mListView.setAdapter(mAdapter);
        findViewById(R.id.btn_all).setOnClickListener(this);
        findViewById(R.id.btn_third).setOnClickListener(this);
        findViewById(R.id.btn_system).setOnClickListener(this);
        findViewById(R.id.btn_sdcard).setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        mAdapter.setData(getAppInfo(v.getId()));
        mAdapter.notifyDataSetChanged();
    }

    private List<PMAppInfo> getAppInfo(int flag) {
        List<ApplicationInfo> applicationInfoList = pm.getInstalledApplications(
                PackageManager.GET_UNINSTALLED_PACKAGES);
        List<PMAppInfo> pmAppInfoList = new ArrayList<>();
        switch (flag) {
            case R.id.btn_all:
                pmAppInfoList.clear();
                for (ApplicationInfo info : applicationInfoList) {
                    pmAppInfoList.add(makeAppInfo(info));
                }
                break;
            case R.id.btn_system:
                pmAppInfoList.clear();
                for (ApplicationInfo appInfo : applicationInfoList) {
                    if ((appInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {   //系统预装应用
                        pmAppInfoList.add(makeAppInfo(appInfo));
                    }
                }
                break;
            case R.id.btn_third:
                pmAppInfoList.clear();
                for (ApplicationInfo appInfo : applicationInfoList) {
                    if ((appInfo.flags & ApplicationInfo.FLAG_SYSTEM) <= 0) {   //第三方应用
                        pmAppInfoList.add(makeAppInfo(appInfo));
                    } else if ((appInfo.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0) {//系统预装应用升级后变成第三方应用
                        pmAppInfoList.add(makeAppInfo(appInfo));
                    }
                }
                break;
            case R.id.btn_sdcard:
                pmAppInfoList.clear();
                for (ApplicationInfo appInfo : applicationInfoList) {
                    if ((appInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { //安装在Sdcard的应用
                        pmAppInfoList.add(makeAppInfo(appInfo));
                    }
                }
                break;
        }
        return pmAppInfoList;
    }

    private PMAppInfo makeAppInfo(ApplicationInfo applicationInfo) {
        PMAppInfo appInfo = new PMAppInfo();
        appInfo.setAppLabel(applicationInfo.loadLabel(pm).toString());
        appInfo.setAppIcon(applicationInfo.loadIcon(pm));
        appInfo.setPkgName(applicationInfo.packageName);
        return appInfo;
    }
}

效果如下

在这里插入图片描述

ActivityManager

用于获取运行时的应用程序信息,如

  • ActivityManager.MemoryInfo:全局内存信息(可用内存、总内存、是否处于低内存)
  • Debug.MemoryInfo:进程下内存信息
  • RunningAppProcessInfo:运行时进程信息(进程名、pid、uid)
  • RunningServiceInfo:运行时服务信息(服务是否在后台执行)
private void getRunningProcessInfo() {
    ActivityManager mActivityManager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
    List<ActivityManager.RunningAppProcessInfo> appProcessList = mActivityManager.getRunningAppProcesses();
    for (int i = 0; i < appProcessList.size(); i++) {
        ActivityManager.RunningAppProcessInfo info = appProcessList.get(i);
        Log.d(TAG, "getRunningProcessInfo: pid = " + info.pid);
        Log.d(TAG, "getRunningProcessInfo: uid = " + info.uid);
        Log.d(TAG, "getRunningProcessInfo: processName = " + info.processName);
        Debug.MemoryInfo[] memoryInfo = mActivityManager.getProcessMemoryInfo(new int[]{info.uid});
        int memorySize = memoryInfo[0].getTotalPss();
        Log.d(TAG, "getRunningProcessInfo: memorySize = " + memorySize);
    }
}

如上打印

pid = 5593
uid = 10091
processName = com.demo.demo0
memorySize = 0

packages.xml

Apk安装、删除、升级等状态,会记录到/data/system/packages.xml中

permissions标签

定义系统中的所有权限,根据package属性分为2类

  • 为android的是系统定义权限
  • 为包名的是Apk定义权限

package标签

  • name:包名
  • codePath:安装路径,/system/app存放预装应用,/data/app存放第三方应用
  • userId:用户ID
  • version:版本号

perms标签

对应Apk的AndroidManifest中的<uses-permission>标签,记录权限信息

安全机制

  • 代码安全机制:代码混淆可使代码无法阅读,同时也可压缩代码,优化字节码
  • 权限控制:App使用系统受限资源时,都需要在AndroidMainifest声明权限,并接受系统检查
  • 数字证书:即App的签名,未签名的App无法安装,相同数字签名的App在升级时才会被认为是同一App
  • Linux内核安全机制:文件系统权限控制,如文件的rwx或selinux权限
  • Android虚拟机沙箱机制:沙箱可以让应用之间互相隔离,互不影响

Apk反编译

Apk本质是一个压缩文件,可通过解压缩软件获取里面的内容,如下

在这里插入图片描述

但解压后的文件无源码文件src,同时xml文件乱码,只能查看res目录下的图片资源

apktool

apktool 用于反编译apk中的xml文件,运行下面命令,会生成一个对应名字的文件夹,可正常查看里面的xml文件(多用于汉化)

在这里插入图片描述

利用参数b可重新打包,会生成build和dist文件夹,Apk位于dist文件夹内

在这里插入图片描述

dex2jar

dex2jar 用于将apk中的.dex文件反编译成.jar文件,将.dex放到根目录运行如下命令,生成对应名字的.jar文件

在这里插入图片描述

jd-gui

jd-gui 用于查看.jar文件,如下打开上面反编译的.jar文件,查看MainAcitivity,内容一模一样

在这里插入图片描述

Apk加密

ProGuard可对Apk进行混淆处理

  • 用无意义的字母来重命名类、字段、方法和属性
  • 此外还可以删除无用的类、字段、方法和属性、注释等以优化字节码

在Gradle Scripts / build.gradle(Module: app)文件中

  • minifyEnabled:是否启用ProGuard
  • proguardFiles:配置混淆文件,一个是系统默认混淆文件(位于SDK/tool/proguard/),一个是自定义混淆文件
buildTypes {
    release {
        minifyEnabled false
        proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/420642.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Seaborn 变量分布分析

文章目录一、数据集1.1 下载数据集1.2 字段含义说明1.3 导入数据集二、初步分析2.1 缺失值分布查看2.2 异常值分布查看2.3 查看变量分布三、数值变量分析3.1 replot()&#xff1a;多个变量之间的关联关系3.2 lmplot()/regplot&#xff1a;分析两个变量的线性关系3.3 displot()&…

从前序与中序遍历序列构造二叉树——力扣105

题目描述 法一&#xff09;递归 复杂度分析 代码如下 class Solution { private:unordered_map<int, int> index;public:TreeNode* myBuildTree(const vector<int>& preorder, const vector<int>& inorder, int preorder_left, int preorder_ri…

Qt Quick - StackView

StackView 使用总结一、概述二、在应用中使用StackView三、基本的导航1. push Item2. pop Item3. replace Item四、深度链接五、寻找Item六、转换六、Item的所有权七、大小一、概述 StackView可以与一组相互链接的信息页面一起使用。例如&#xff0c;电子邮件应用程序具有单独…

HTML5 <img> 标签

HTML5 <img> 标签 实例 HTML5 <img>标签用于向网页中添加相关图片。 如何插入图像&#xff1a; <img src"smiley-2.gif" alt"Smiley face" width"42" height"42">尝试一下 &#xff08;更多实例见页面底部&…

基于营销类系统运营活动增长带来的数据库设计演进

一、前言 为了支持业务数据的不断增长&#xff0c;在数据库层面的性能提升主要体现在几个维度&#xff1a;1&#xff09;数据降级&#xff1b;2&#xff09;数据主题分而治之&#xff1b;3&#xff09;实时交易转异步&#xff1b;4&#xff09;硬件扩容&#xff0c;当然网上一…

question

4、Mysql高可用有几种方案&#xff0c;分别有什么特点? 特点优点缺点mysql group replication(MGR)组复制组内一半节点同意即可提交更改操作、最多支持 9 个节点、基于MRG插件、多节点写入支持、故障自动检测、引擎必须为 innodb、必须有主键、binlog 为 row强一致、paxos协议…

Arcgis Engine之打开MXD文档

Arcgis Engine之打开MXD文档概述方法一&#xff1a;方法二&#xff1a;概述 图层加载功能将用到MapControl 控件提供的LoadMxFile 方法。 该方法通过指定的*. Mxd文档路径直接获取 该方法第一个参数是文件路径&#xff0c; 第二个参数是MExd文档中地图的名称或索引&#xff0…

1.初识Earth Engine

Earth Engine平台是一个集科学分析和地理信息可视化的综合性平台&#xff0c;该平台提供丰富的API&#xff0c;以及工具帮助方便查看、计算、处理、分析大范围的各种影像等GIS数据。 基础数据 目前Earth Engine上已由几十PB的影像栅格数据及矢量数据数据地址。数据主要分为以…

Prometheus+Grafana从0到1搭建jvm监控

目 录1. 准备工作2. 添加配置2.1 添加maven依赖2.2 application.properties增加配置2.3 新增配置类2.4 配置Prometheus2.5 配置Grafana3. 小结在上一篇博客《 PrometheusMysqld_exporterGrafana从0到1搭建MySQL的可视化监控》&#xff0c;我们完成了对数据库的可视化监控搭建&a…

都说程序员就是吃青春饭,35岁就会被淘汰,我用自己的经历来告诉你事实

上个假期我回家了&#xff0c;遇到三姑六婆总会问我读研没读、工作怎么样、薪资多少等等问题&#xff0c;相信大家也都遇到过。我一般会用“在做程序员&#xff0c;写代码的这种话”来敷衍他们&#xff0c;但没想到他们懂得还挺多的&#xff0c;又搬出了一套关于程序员的理论&a…

当AI遇上元宇宙:智能科技如何助力虚拟世界的发展?

欢迎来到Hubbleverse &#x1f30d; 关注我们 关注宇宙新鲜事 &#x1f4cc; 预计阅读时长&#xff1a;10分钟 本文仅代表作者个人观点&#xff0c;不代表平台意见&#xff0c;不构成投资建议。 人工智能和元宇宙是21世纪最突出的技术之一。它们各自可以在许多方面提高人们…

MySQL、PostgreSQL、Oracle、SQL Server数据库触发器实现同步数据

数据库触发器是一种在数据库中设置的程序&#xff0c;当满足某些特定条件时&#xff0c;它会自动执行。触发器通常与数据表的操作&#xff08;例如插入、更新和删除&#xff09;相关联&#xff0c;它们可以帮助保证数据的完整性和一致性。在本篇博客中&#xff0c;我将介绍各种…

对SQL注入进行的一些总结

简介 SQL注入作为一种攻击方式最早可以追溯到20世纪90年代中期&#xff0c;当时Web应用程序开始流行并广泛使用数据库作为其后端数据存储。最早的SQL注入攻击是通过简单地在Web表单输入框中输入SQL代码来实现的&#xff0c;攻击者可以通过修改输入参数来篡改数据库查询的行为&a…

Pytorch 容器 - 2. Module的属性访问 modules(), children(), parameters(), buffers()等

目录 1. modules() 和 named_modules() 2. children() 和 named_children() 3. parameters() 和 named_parameters() 4. buffers() 和 named_buffers() Module类内置了很多函数&#xff0c;其中本文主要介绍常用的属性访问函数&#xff0c;包括&#xff1a; modules(), nam…

Spring事务源码-EnableTransactionManagement实现解析

Transactional注解 Transactional是spring中声明式事务管理的注解配置方式。Transactional注解可以帮助我们标注事务开启、提交、者回滚、事务传播、事务隔离、超时时间等操作。 而EnableTransactionManagement是开启Spring 事务的入口。 EnableTransactionManagement 标注启…

什么是数字人?数字人可以应用在哪些行业?

数字人指的是由计算机技术、人工智能技术和大数据技术等多种技术手段构建的一种虚拟的人类形态。数字人通常具备丰富的信息处理能力、模拟能力和学习能力&#xff0c;可以根据人们的需求进行智能化定制服务。 数字人 在很多行业领域&#xff0c;数字人都被广泛应用&#xff0…

【并发编程】ConcurrentHashMap源码分析(一)

ConcurrentHashMap源码分析CHM的使用CHM的存储结构和实现CHM源码put源码分析initTable 初始化tabletreeifyBin()和tryPresize()transfer 扩容和数据迁移高低位的迁移ConcurrentHashMap是一个高性能的&#xff0c;线程安全的HashMapHashTable线程安全&#xff0c;直接在get,put方…

spring security 的AuthenticationSuccessHandler 没有调用 ,无法生效

今天想不明白&#xff0c;我控制层写了一个登录的接口。结果验证成功了&#xff0c;我发现AuthenticationSuccessHandler 没有调用 &#xff0c;而且也不生效啊&#xff0c;最后研究终于发现是因为我们需要配置登录的url 这个url 我们访问&#xff0c;中间的什么控制器什么的框…

Win10怎么取消开机密码?这样做就可以!

集美们&#xff0c;我每次开电脑都要输入密码&#xff0c;感觉太麻烦了&#xff0c;想把开机密码取消掉&#xff0c;应该怎么做呀&#xff1f;感谢回答&#xff01;】 在Windows 10操作系统中&#xff0c;用户可以设置开机密码来保护计算机的安全性。然而&#xff0c;有时候用…

【CSS】使用绝对定位 / 浮动解决外边距塌陷问题 ( 为父容器 / 子元素设置内边距 / 边框 | 为子元素设置浮动 | 为子元素设置绝对定位 )

文章目录一、外边距塌陷描述1、没有塌陷的情况2、外边距塌陷情况二、传统方法解决外边距塌陷 - 为父容器 / 子元素设置内边距 / 边框三、使用浮动解决外边距塌陷 - 为子元素设置浮动四、使用绝对定位解决外边距塌陷 - 为子元素设置绝对定位一、外边距塌陷描述 在 标准流的父盒子…