有2种方法,第一种方法需要全编,第二种方法不需要全编,二种方法各有利弊,结尾处会说明,先说第一种需要全编的方法

1.现象 模块使用了 co.sitic.pp (/system/priv-app/ SysdllAA3 ) 之后,单编模块push到手机里面重启,发现手机卡在开机logo界面,开不了机
2.抓取logcat看log打印会发现如下图片中的打印,主要的关键词为Privileged permissions not in privapp-permissions whitelist

03-04 01:22:12.906  4708  4708 E System  : ******************************************
03-04 01:22:12.906  4708  4719 W JHwRemoteBinder: BinderProxy is being destroyed but the application did not call unlinkToDeath to unlink all of its death recipients beforehand.  Releasing leaked death recipient: com.android.server.usb.UsbDeviceManager$UsbHandlerHal$UsbGadgetDeathRecipient
03-04 01:22:12.907  4708  4708 E System  : ************ Failure starting system services
03-04 01:22:12.907  4708  4708 E System  : java.lang.IllegalStateException: Signature|privileged permissions not in privapp-permissions whitelist: {co.sitic.pp (/system/priv-app/SysdllAA3): android.permission.REAL_GET_TASKS}
03-04 01:22:12.907  4708  4708 E System  :     at com.android.server.pm.permission.PermissionManagerService.systemReady(PermissionManagerService.java:4760)
03-04 01:22:12.907  4708  4708 E System  :     at com.android.server.pm.permission.PermissionManagerService.access$500(PermissionManagerService.java:182)
03-04 01:22:12.907  4708  4708 E System  :     at com.android.server.pm.permission.PermissionManagerService$PermissionManagerServiceInternalImpl.systemReady(PermissionManagerService.java:4843)
03-04 01:22:12.907  4708  4708 E System  :     at com.android.server.pm.PackageManagerService.systemReady(PackageManagerService.java:21980)
03-04 01:22:12.907  4708  4708 E System  :     at com.android.server.SystemServer.startOtherServices(SystemServer.java:2265)
03-04 01:22:12.907  4708  4708 E System  :     at com.android.server.SystemServer.run(SystemServer.java:631)
03-04 01:22:12.907  4708  4708 E System  :     at com.android.server.SystemServer.main(SystemServer.java:433)
03-04 01:22:12.907  4708  4708 E System  :     at java.lang.reflect.Method.invoke(Native Method)
03-04 01:22:12.907  4708  4708 E System  :     at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:612)
03-04 01:22:12.907  4708  4708 E System  :     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:975)
3. adb shell pm list packages -f > f.txt
获取应用的包名信息
4.adb命令从手机中导出权限配置文件,并修改,然后手动添加权限重启验证
adb pull /etc/permissions/privapp-permissions-platform.xml

adb push privapp-permissions-platform.xml /etc/permissions/
5.修改后可以开机了,开机回复
6. 特许权限白 名单

特权应用是位于系统映像某个分区上  priv-app  目录下的系统应用。各 Android 版本中,该分区为:
Android 8.1 及更低版本 -  /system
Android 9 及更高版本 -  /system, /product, /vendor


在本页面中, /etc/permissions/priv-app  解析为  partition /etc/permissions/priv-app 。
过去,设备制造商几乎无法控制可对特权应用授予哪些 签名|特许 权限。从 Android 8.0 开始,制造商必须在  /etc/permissions  目录下的系统配置 XML 文件中明确授予特许权限。从 Android 9 开始,实现人员必须明确授予或拒绝授予所有特许权限,否则设备将无法启动。
privapp-permissions.xml  文件只有在与特权应用位于同一分区时才能授予或拒绝授予该应用权限。例如,如果  /vendor  分区上的应用请求特许权限,则只能由同样位于  /vendor  上的  privapp-permissions.xml  文件来同意或拒绝该请求。
注意 :必须列入白名单的只有核心平台(“android”软件包)所定义的权限。设备制造商定义的特许权限仍将自动授予。在  privapp-permissions.xml  文件中,请仅列出实际存在于该分区上的应用。如果应用不在该分区上,系统将忽略所列条目。
添加白名单
应用的权限白名单可列在位于  frameworks/base/etc/permissions  目录下的单个或多个 XML 文件中,如下所示:
/etc/permissions/privapp-permissions- OEM_NAME .xml
/etc/permissions/privapp-permissions- DEVICE_NAME .xml
对于如何组织内容,没有严格的规则。设备实现人员可以决定内容结构,只要  /system/priv-app  下的所有应用均列入白名单即可。例如,Google 针对由 Google 开发的所有特权应用提供了一个白名单,并建议使用以下组织方式:
对于已包含在 Android 开源项目 (AOSP) 树中的应用,请将其权限列在  /etc/permissions/privapp-permissions-platform.xml  中。
对于 Google 应用,请将其权限列在  /etc/permissions/privapp-permissions-google.xml  中。
对于其他应用,请使用以下格式的文件: /etc/permissions/privapp-permissions- DEVICE_NAME .xml 。


生成白名单
如需针对系统映像上可用的所有应用自动生成白名单,请使用位于以下位置的 AOSP 命令行工具: development/tools/privapp_permissions/privapp_permissions.py 。如需生成适用于特定设备的  privapp-permissions.xml  的初始版本,请执行以下操作:
1.必须先全编,构建系统映像:
. build/envsetup.sh
lunch PRODUCT_NAME
make -j
2.运行  privapp_permissions.py  脚本以生成一个  privapp-permissions.xml  文件,该文件会列出所有需要列入白名单的签名|特许权限:
(1)进入此路径 development/tools/privapp_permissions

(2)执行脚本     ./privapp_permissions.py
此工具会输出可在  /etc/permissions  目录路径下作为单个文件或拆分为多个文件的 XML 内容。如果设备的  /etc/permissions  目录下已经包含白名单,则该工具将仅输出差异内容(例如,需要列入白名单但尚未列入的签名|特许权限)。这对审核也很有用,当添加新版本的应用时,该工具会检测所需的额外权限。
将生成的文件复制到相应的  /etc/permissions  目录下,系统将在启动过程中从这里读取这些文件。
自定义白名单
AOSP 包含可根据需要自定义的白名单实现。对于包含在 AOSP 中的应用,其权限已在  /etc/permissions/privapp-permissions-platform.xml  中列入白名单。
默认情况下, privapp_permissions.py  脚本会生成输出,自动授予特权应用所请求的任何权限。如果有不应授予的权限,请修改 XML,用“deny-permission”标记代替“permission”标记。示例:

<!--
This XML file declares which signature|privileged permissions should be
granted to privileged apps that come with the platform
-->
<permissions>
<privapp-permissions package="com.android.backupconfirm">
<permission name="android.permission.BACKUP"/>
<permission name="android.permission.CRYPT_KEEPER"/>
</privapp-permissions>
<privapp-permissions package="com.android.cellbroadcastreceiver">
<!-- don't allow application to interact across users -->
<deny-permission name="android.permission.INTERACT_ACROSS_USERS"/>
<permission name="android.permission.MANAGE_USERS"/>
<permission name="android.permission.MODIFY_PHONE_STATE"/>
<permission name="android.permission.READ_PRIVILEGED_PHONE_STATE"/>
<permission name="android.permission.RECEIVE_EMERGENCY_BROADCAST"/>
</privapp-permissions>


...
查找缺少的权限
如需在启动新设备时查找缺少的权限,请启用过渡日志模式:
ro.control_privapp_permissions=log
违规行为会记录在日志文件中,但非特许权限仍将得到准许。这样,在提供违规行为列表的同时,设备仍能正常运行。下面是错误消息格式:
PackageManager: Privileged permission {PERMISSION_NAME} for package {PACKAGE_NAME} - not in privapp-permissions whitelist
必须将缺少的权限加入相应的白名单来解决所有违规行为。
在 Android 8.0 及更低版本中,受影响的应用即使位于  priv-app  路径中也不会被授予缺少的权限。
在 Android 9 及更高版本中,违规行为(缺少特许权限)意味着 设备无法启动 。您必须明确准许或拒绝授予所有特许权限。
执行白名单
白名单列好后,可设置 build 属性  ro.control_privapp_permissions=enforce  使其在运行时生效。

由于全编译耗时时间很长,而平常经常需要预置和更新apk,如何在全编译代码之前,就检查出 apk 使用哪些了"Signature|privileged" 级别的权限?请看方法二

方法二

前提条件:配置Android sdk,让adb、aapt命令可用
1. 基于Android默认自带的privapp_permissions.py脚本,做如下修改:
diff --git a/tools/privapp_permissions/privapp_permissions.py b/tools/privapp_permissions/privapp_permissions.py
index 4016573..95a95d1 100755
--- a/tools/privapp_permissions/privapp_permissions.py
+++ b/tools/privapp_permissions/privapp_permissions.py
@@ -146,6 +146,8 @@ class Resources(object):
                      (apks and DEVICE_PREFIX in '&'.join(apks))
 
         self.adb.serial = self._resolve_serial(use_device, serial)
+        self._is_android_env = True
+        print('============',self._is_android_env)
 
         if self.adb.serial:
             self.adb.call('root')
@@ -159,8 +161,8 @@ class Resources(object):
         self.privapp_apks = self._resolve_apks(apks)
         self.permissions_dir = self._resolve_sys_path('system/etc/permissions')
         self.sysconfig_dir = self._resolve_sys_path('system/etc/sysconfig')
-        self.framework_res_apk = self._resolve_sys_path('system/framework/'
-                                                        'framework-res.apk')
+
+        self.framework_res_apk = "./framework-res.apk"
 
     @staticmethod
     def _resolve_adb(adb_path):
@@ -325,10 +327,7 @@ class Resources(object):
 
     def _resolve_sys_path(self, file_path):
         """Resolves a path that is a part of an Android System Image."""
-        if self._is_android_env:
-            return os.path.join(os.environ['ANDROID_PRODUCT_OUT'], file_path)
-        else:
-            return self.adb.pull(file_path)
+       # self._is_android_env = False
 
 
 def get_output(command):
@@ -399,6 +398,8 @@ def create_permission_file(resources):
     # Parse base XML files in /etc dir, permissions listed there don't have
     # to be re-added
     base_permissions = {}
+    resources.permissions_dir = '/test/system/etc/permissions'
+    resources.sysconfig_dir = '/test/system/etc/permissions'
     base_xml_files = itertools.chain(list_xml_files(resources.permissions_dir),
                                      list_xml_files(resources.sysconfig_dir))
     for xml_file in base_xml_files:
@@ -500,6 +501,11 @@ def extract_priv_permissions(aapt, apk_path):
     """Extract signature|privileged permissions from dump of manifest file."""
     aapt_args = ['d', 'xmltree', apk_path, 'AndroidManifest.xml']
     txt = aapt.call(aapt_args)
+
+    # print(txt) > log.txt
+    # f = open(r'./log.txt')
+    # txt = f.read()
+
     raw_lines = txt.split('\n')

修改后的  privapp_permissions.py 文件,请见附件包

2. 新建 priv-app 目录,将 所有需要检查的apk拷贝到 priv-app 目录
3. 新建 get_privapp_permissions.sh 脚本,该脚本用于遍历 priv-app 目录下面的apk,批量调用 privapp_permissions.py 脚本
get_privapp_permissions.sh 脚本内容:
 
#!/bin/bash

for i in priv-app/*.apk;do
python privapp_permissions.py $i
done

4. 从项目中拷贝一个 framework-res.apk (此文件确保与项目的Android OS的版本一致即可)

5. 运行 get_privapp_permissions.sh 脚本,即可批量打印出 apk是否使用了"Signature|privileged" 级别的权限
6. 运行:./get_privapp_permissions.sh
小结:
1. 方法二的脚本可以独立运行,不需要全编译代码即可检查,节省了预置时间。
2. 方法二也有一个局限,终端列出的权限由于没有与out目录做差异比对,会将apk里面所有"Signature|privileged" 级别的权限全部打印出来,人工添加权限时需要注意,如果之前添加过了,则不必重复添加。
附件压缩包目录结构:
├── get_privapp_permissions.sh
├── priv-app
├── privapp_permissions.py
└── 操作步骤.txt

————————————————
版权声明:本文为CSDN博主「高桐@BILL」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/huangyabin001/article/details/115404355

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐