system apk

简介: system apk

1 哪些app属于system app?

为了区分privilege app和system app,这里先说明system app是什么,避免之后的讨论概念混乱。

在PackageManagerService中对是否是system app的判断:

具有ApplicationInfo.FLAG_SYSTEM标记的,被视为System app。

frameworks\base\services\core\java\com\android\server\pm\PackageManagerService.java

final boolean isSystem = isSystemApp(pkgSetting) || isUpdatedSystemApp(pkgSetting);
    private static boolean isSystemApp(PackageSetting ps) {
        return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0;
    }
 
    private static boolean isUpdatedSystemApp(PackageSetting ps) {
        return (ps.pkgFlags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
    }

有两类app属于System app:

1.1 第一类System app: 特定的shared uid的app 属于system app

例如:shared uid为android.uid.system,android.uid.phone,android.uid.log,android.uid.nfc,android.uid.bluetooth,android.uid.shell。这类app都被赋予了ApplicationInfo.FLAG_SYSTEM标志。在PackageManagerService的构造方法中,代码如下:

        mSettings.addSharedUserLPw("android.uid.system", Process.SYSTEM_UID,
                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
        mSettings.addSharedUserLPw("android.uid.phone", RADIO_UID,
                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
        mSettings.addSharedUserLPw("android.uid.log", LOG_UID,
                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
        mSettings.addSharedUserLPw("android.uid.nfc", NFC_UID,
                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
        mSettings.addSharedUserLPw("android.uid.bluetooth", BLUETOOTH_UID,
                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
        mSettings.addSharedUserLPw("android.uid.shell", SHELL_UID,
                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
        mSettings.addSharedUserLPw("android.uid.se", SE_UID,
                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
        mSettings.addSharedUserLPw("android.uid.networkstack", NETWORKSTACK_UID,
                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);

1.2 第二类System app: 特定目录中的app属于system app

特定目录包括:/vendor/overlay,/system/framework,/system/priv-app,/system/app,/vendor/app,/oem/app。这些目录中的app,被视为system app。

在PackageManagerService的构造方法中,代码如下:

// /vendor/overlay folder
File vendorOverlayDir = new File(VENDOR_OVERLAY_DIR);
scanDirLI(vendorOverlayDir, PackageParser.PARSE_IS_SYSTEM
| PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags | SCAN_TRUSTED_OVERLAY, 0);
 
// Find base frameworks (resource packages without code). /system/framework folder
File frameworkDir = new File(Environment.getRootDirectory(), "framework");
scanDirLI(frameworkDir, PackageParser.PARSE_IS_SYSTEM
| PackageParser.PARSE_IS_SYSTEM_DIR
| PackageParser.PARSE_IS_PRIVILEGED,
scanFlags | SCAN_NO_DEX, 0);
 
// Collected privileged system packages. /system/priv-app folder
final File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app");
scanDirLI(privilegedAppDir, PackageParser.PARSE_IS_SYSTEM
| PackageParser.PARSE_IS_SYSTEM_DIR
| PackageParser.PARSE_IS_PRIVILEGED, scanFlags, 0);
 
// Collect ordinary system packages. /system/app folder
final File systemAppDir = new File(Environment.getRootDirectory(), "app");
scanDirLI(systemAppDir, PackageParser.PARSE_IS_SYSTEM
| PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
 
// Collect all vendor packages.
File vendorAppDir = new File("/vendor/app");
scanDirLI(vendorAppDir, PackageParser.PARSE_IS_SYSTEM
| PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
 
// Collect all OEM packages. /oem/app folder
final File oemAppDir = new File(Environment.getOemDirectory(), "app");
scanDirLI(oemAppDir, PackageParser.PARSE_IS_SYSTEM
| PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);

2 什么是privileged app(特权app)

注:privileged app,在本文中称之为 特权app,主要原因是此类特权app可以使用protectionLevel为signatureOrSystem或者protectionLevel为signature|privileged的权限。

从PackageManagerService的isPrivilegedApp()可以看出特权app是具有ApplicationInfo.PRIVATE_FLAG_PRIVILEGED标志的一类app。

resolveInfo.activityInfo.applicationInfo.isPrivilegedApp()
frameworks/base/core/java/android/content/pm/ApplicationInfo.java
public boolean isPrivilegedApp() {
        return (privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0;
    }
 

特权app首先必须是System app。也就是说 System app分为普通的system app和特权的system app。

直观的(但不准确严谨)说,普通的system app就是/system/app目录中的app,特权的system app就是/system/priv-app目录中的app。

区分普通system app和特权app的目的是澄清这个概念:"signatureOrSystem"权限中的System不是为普通system app提供的,而是只有特权app能够使用。

所以,当我们说起system app时,通常指具有特定uid和特定目录中的app,包含了普通的system app和特权app。当我们说起有访问System权限或者privileged权限的app时,通常指特权app。

3 哪些app属于privileged app(特权app)?

特权app首先是System app,然后要具有ApplicationInfo.PRIVATE_FLAG_PRIVILEGED标志。

有两类app属于privileged app(特权app):

参考PackageManagerService的构造方法。

3.1 第一类privileged app: 特定uid的app

shared uid为"android.uid.system","android.uid.phone","android.uid.log","android.uid.nfc","android.uid.bluetooth","android.uid.shell"的app被赋予了privileged的权限。这些app同时也是system app。

代码如下:

        mSettings.addSharedUserLPw("android.uid.system", Process.SYSTEM_UID,
                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
        mSettings.addSharedUserLPw("android.uid.phone", RADIO_UID,
                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
        mSettings.addSharedUserLPw("android.uid.log", LOG_UID,
                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
        mSettings.addSharedUserLPw("android.uid.nfc", NFC_UID,
                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
        mSettings.addSharedUserLPw("android.uid.bluetooth", BLUETOOTH_UID,
                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
        mSettings.addSharedUserLPw("android.uid.shell", SHELL_UID,
                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
        mSettings.addSharedUserLPw("android.uid.se", SE_UID,
                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
        mSettings.addSharedUserLPw("android.uid.networkstack", NETWORKSTACK_UID,
                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);

3.2 第二类privileged app:/system/framework和/system/priv-app目录下的app

/system/framework和/system/priv-app目录下的app被赋予了privileged的权限。

其中/system/framework目录中的apk,只是包含资源,不包含代码(dex)。

/ PackageManagerService的构造方法
// /system/framework
File frameworkDir = new File(Environment.getRootDirectory(), "framework");
scanDirLI(frameworkDir, PackageParser.PARSE_IS_SYSTEM
| PackageParser.PARSE_IS_SYSTEM_DIR
| PackageParser.PARSE_IS_PRIVILEGED,
scanFlags | SCAN_NO_DEX, 0);
 
// /system/priv-app
final File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app");
scanDirLI(privilegedAppDir, PackageParser.PARSE_IS_SYSTEM
| PackageParser.PARSE_IS_SYSTEM_DIR
| PackageParser.PARSE_IS_PRIVILEGED, scanFlags, 0);
 
PackageParser.PARSE_IS_PRIVILEGED标志最终会转换为Package的ApplicationInfo.PRIVATE_FLAG_PRIVILEGED标志。大概的代码流程,如下:
 
scanDirLI(PackageParser.PARSE_IS_PRIVILEGED)
 
-> scanPackageLI(file, parseFlags | PackageParser.PARSE_MUST_BE_APK, scanFlags, currentTime, null);
 
-> PackageParser.Package scannedPkg = scanPackageLI(pkg, parseFlags, scanFlags | SCAN_UPDATE_SIGNATURE, currentTime, user);
 
-> final PackageParser.Package res = scanPackageDirtyLI(pkg, parseFlags, scanFlags, currentTime, user);
 
-> scanPackageDirtyLI()中
if ((parseFlags & PackageParser.PARSE_IS_PRIVILEGED) != 0) {
pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
}

4.1 验证某个app是否获得了某个权限的方法

可以用下面2个命令来验证:

adb shell dumpsys package permission <权限名>

adb shell dumpsys package <包名>

 

其中,adb shell dumpsys package permission <权限名>可以查看某个权限是谁声明的,谁使用了。

adb shell dumpsys package <包名>可以看到某个app是否获得了某个权限。


哪些app可以使用某app提供的signature权限或signatureOrSystem权限?


如果App A声明了signatureOrSystem权限,即android:protectionLevel="signature|privileged"或者android:protectionLevel="signatureOrSystem",则可以使用该权限的app包括:

(1)与App A有相同签名的app

(2)与系统签名相同的app,即与厂商签名(厂商ROM中的系统app签名)相同的app

(3)在/system/priv-app目录中的app,不管是否满足(1)和(2)的条件。即任意app只要放到了/system/priv-app就可以使用App A的signatureOrSystem级别的权限。


如果App A声明了signature权限,即android:protectionLevel="signature",则可以使用该权限的app包括:

(1)与App A有相同签名的app

(2)与系统签名相同的app,即与厂商签名(厂商ROM中的系统app签名)相同的app

注意:与系统签名相同,即与厂商签名相同,这是指厂商推出的app,这些app有很大的访问权限。


目录
相关文章
|
编解码 算法 数据安全/隐私保护
[资料]airplay协议
[资料]airplay协议
430 0
|
Java Android开发
Android9.0/8.1/6.0 默认给系统 app 授予所有权限
Android9.0/8.1/6.0 默认给系统 app 授予所有权限
639 0
|
编解码 监控 安全
【新功能】安卓手机设置“自动”初始化
【新功能】安卓手机设置“自动”初始化
1708 0
|
网络协议 Ubuntu 开发工具
Ubuntu20 自定义DNS永久生效
Ubuntu20 自定义DNS永久生效
2195 0
|
网络协议 Shell Linux
安卓逆向 -- IDA动态调试
安卓逆向 -- IDA动态调试
301 0
|
Android开发
Android中将APK放入系统APK目录中,找不到so文件
如题,将APK直接放入系统目录中,会导致APK找不到so文件,正常情况下的安装是使用PackageManager,它会将so文件拷入系统读取的so文件夹目录下,提供给App使用;系统应用就是不会使用PackageMana...
2252 0
|
Linux
`grep`命令搜索当前目录及其子目录下的所有文件
`grep`命令搜索当前目录及其子目录下的所有文件
4138 1