`

Android权限获取机制与常见权限不足问题分析

 
阅读更多
Android系统是运行在Linux内核上的,Android与Linux分别有自己的一套严格的安全及权限机制,

    很多像我这样的新手,尤其是习惯了windows低安全限制的用户,很容易在这方面弄混淆,下面是我总结的Android系统权限相关的内容,

    作为这段时间对android权限学习的总结,也希望能对大家有所帮助,不正确之处请指出。

    首先分清两个概念:

    要区分apk运行时的拥有的权限与在文件系统上被访问(读写执行)的权限两个概念。

    apk程序是运行在虚拟机上的,对应的是Android独特的权限机制,只有体现到文件系统上时才使用linux的权限设置。

    (一)linux文件系统上的权限

    -rwxr-x--x system system 4156 2010-04-30 16:13 test.apk

    代表的是相应的用户/用户组及其他人对此文件的访问权限,与此文件运行起来具有的权限完全不相关。

    比如上面的例子只能说明system用户拥有对此文件的读写执行权限;system组的用户对此文件拥有读、执行权限;其他人对此文件只具有执行权限。

    而test.apk运行起来后可以干哪些事情,跟这个就不相关了。

    千万不要看apk文件系统上属于system/system用户及用户组,或者root/root用户及用户组,就认为apk具有system或root权限。

    (二)Android的权限规则

    (1)Android中的apk必须签名

    这种签名不是基于权威证书的,不会决定某个应用允不允许安装,而是一种自签名证书。

    重要的是,android系统有的权限是基于签名的。比如:system等级的权限有专门对应的签名,签名不对,权限也就获取不到。

    默认生成的APK文件是debug签名的。

    获取system权限时用到的签名,见:如何使Android应用程序获取系统权限

    (2)基于UserID的进程级别的安全机制

    大家都知道,进程有独立的地址空间,进程与进程间默认是不能互相访问的,是一种很可靠的保护机制。

    Android通过为每一个安装在设备上的包(apk)分配唯一的linux userID来实现,名称为"app_"加一个数字,比如app_43

    不同的UserID,运行在不同的进程,所以apk之间默认便不能相互访问。

    Android提供了如下的一种机制,可以使两个apk打破前面讲的这种壁垒。

    在AndroidManifest.xml中利用sharedUserId属性给不同的package分配相同的userID,通过这样做,两个package可以被当做同一个程序,

    系统会分配给两个程序相同的UserID。当然,基于安全考虑,两个package需要有相同的签名,否则没有验证也就没有意义了。

    (这里补充一点:并不是说分配了同样的UserID,两程序就运行在同一进程, 下面为PS指令摘取的,

    显然,system、app_2分别对应的两个进程的PID都不同,不知Android到底是怎样实现它的机制的)

    User PID PPID

    system 953 883 ffffffff afe0cbcc S system_server

    app_2 1072 883 ffffffff afe0dcc4 S com.android.inputmethod.

    system 1083 883 ffffffff afe0dcc4 S android.process.omsservi

    app_2 1088 883 ffffffff afe0dcc4 S android.process.acore

    (3)默认apk生成的数据对外是不可见的

    实现方法是:Android会为程序存储的数据分配该程序的UserID。

    借助于Linux严格的文件系统访问权限,便实现了apk之间不能相互访问似有数据的机制。

    例:我的应用创建的一个文件,默认权限如下,可以看到只有UserID为app_21的程序才能读写该文件。

    -rw------- app_21 app_21 2000-01-01 09:48 test.txt

    如何对外开放?

    <1> 使用MODE_WORLD_READABLE and/or MODE_WORLD_WRITEABLE 标记。

    When creating a new file with getSharedPreferences(String, int), openFileOutput(String, int), or openOrCreateDatabase(String, int, SQLiteDatabase.CursorFactory), you can use the MODE_WORLD_READABLE and/or MODE_WORLD_WRITEABLE flags to allow any other package to read/write the file. When setting these flags, the file is still owned by your application, but its global read and/or write permissions have been set appropriately so any other application can see it.

    (4)AndroidManifest.xml中的显式权限声明

    Android默认应用是没有任何权限去操作其他应用或系统相关特性的,应用在进行某些操作时都需要显式地去申请相应的权限。

    一般以下动作时都需要申请相应的权限:

    A particular permission may be enforced at a number of places during your program's operation:

    在应用安装的时候,package installer会检测该应用请求的权限,根据该应用的签名或者提示用户来分配相应的权限。

    在程序运行期间是不检测权限的。如果安装时权限获取失败,那执行就会出错,不会提示用户权限不够。

    大多数情况下,权限不足导致的失败会引发一个 SecurityException, 会在系统log(system log)中有相关记录。

    (5)权限继承/UserID继承

    当我们遇到apk权限不足时,我们有时会考虑写一个linux程序,然后由apk调用它去完成某个它没有权限完成的事情,很遗憾,这种方法是行不通的。

    前面讲过,android权限是经营在进程层面的,也就是说一个apk应用启动的子进程的权限不可能超越其父进程的权限(即apk的权限),

    即使单独运行某个应用有权限做某事,但如果它是由一个apk调用的,那权限就会被限制。

    实际上,android是通过给子进程分配父进程的UserID实现这一机制的。

    (三)常见权限不足问题分析

    首先要知道,普通apk程序是运行在非root、非system层级的,也就是说看要访问的文件的权限时,看的是最后三位。

    另外,通过system/app安装的apk的权限一般比直接安装或adb install安装的apk的权限要高一些。

    言归正传,运行一个android应用程序过程中遇到权限不足,一般分为两种情况:

    (1)Log中可明显看到权限不足的提示。

    此种情况一般是AndroidManifest.xml中缺少相应的权限设置,好好查找一番权限列表,应该就可解决,是最易处理的情况。

    有时权限都加上了,但还是报权限不足,是什么情况呢?

    Android系统有一些API及权限是需要apk具有一定的等级才能运行的。

    比如 SystemClock.setCurrentTimeMillis()修改系统时间,WRITE_SECURE_SETTINGS权限 好像都是需要有system级的权限才行。

    也就是说UserID是system.

    (2)Log里没有报权限不足,而是一些其他Exception的提示,这也有可能是权限不足造成的。

    比如:我们常会想读/写一个配置文件或其他一些不是自己创建的文件,常会报java.io.FileNotFoundException错误。

    系统认为比较重要的文件一般权限设置的也会比较严格,特别是一些很重要的(配置)文件或目录。

    如

    -r--r----- bluetooth bluetooth 935 2010-07-09 20:21 dbus.conf

    drwxrwx--x system system 2010-07-07 02:05 data

    dbus.conf好像是蓝牙的配置文件,从权限上来看,根本就不可能改动,非bluetooth用户连读的权利都没有。

    /data目录下存的是所有程序的私有数据,默认情况下android是不允许普通apk访问/data目录下内容的,通过data目录的权限设置可知,其他用户没有读的权限。

    所以adb普通权限下在data目录下敲ls命令,会得到opendir failed, Permission denied的错误,通过代码file.listfiles()也无法获得data目录下的内容。

    上面两种情况,一般都需要提升apk的权限,apk能提升到的权限就是system 在 android 的API中有提供 SystemClock.setCurrentTimeMillis()函数来修改系统时间,可惜无论你怎么调用这个函数都是没用的,无论模拟器还是真机,在logcat中总会得到"Unable to open alarm driver: Permission denied ".这个函数需要root权限或者运行与系统进程中才可以用。

    本来以为就没有办法在应用程序这一层改系统时间了,后来在网上搜了好久,知道这个目的还是可以达到的。

    第一个方法简单点,不过需要在Android系统源码的环境下用make来编译:

    1. 在应用程序的AndroidManifest.xml中的manifest节点中加入android:sharedUserId="android.uid.system"这个属性。

    2. 修改Android.mk文件,加入LOCAL_CERTIFICATE := platform这一行

    3. 使用mm命令来编译,生成的apk就有修改系统时间的权限了。

    第二个方法麻烦点,不过不用开虚拟机跑到源码环境下用make来编译:

    1. 同上,加入android:sharedUserId="android.uid.system"这个属性。

    2. 使用eclipse编译出apk文件,但是这个apk文件是不能用的。

    3. 用压缩软件打开apk文件,删掉META-INF目录下的CERT.SF和CERT.RSA两个文件。

    4. 使用目标系统的platform密钥来重新给apk文件签名。这步比较麻烦,首先找到密钥文件,在我的Android源码目录中的位置是"build\target\product\security",下面的platform.pk8和platform.x509.pem两个文件。然后用Android提供的Signapk工具来签名,signapk的源代码是在"build\tools\signapk"下,用法为"signapk platform.x509.pem platform.pk8 input.apk output.apk",文件名最好使用绝对路径防止找不到,也可以修改源代码直接使用。

    这样最后得到的apk和第一个方法是一样的。

    最后解释一下原理,首先加入android:sharedUserId="android.uid.system"这个属性。通过Shared User id,拥有同一个User id的多个APK可以配置成运行在同一个进程中。那么把程序的UID配成android.uid.system,也就是要让程序运行在系统进程中,这样就有权限来修改系统时间了。

    只是加入UID还不够,如果这时候安装APK的话发现无法安装,提示签名不符,原因是程序想要运行在系统进程中还要有目标系统的platform key,就是上面第二个方法提到的platform.pk8和platform.x509.pem两个文件。用这两个key签名后apk才真正可以放入系统进程中。第一个方法中加入LOCAL_CERTIFICATE := platform其实就是用这两个key来签名。

    这也有一个问题,就是这样生成的程序只有在原始的Android系统或者是自己编译的系统中才可以用,因为这样的系统才可以拿到platform.pk8和platform.x509.pem两个文件。要是别家公司做的Android上连安装都安装不了。试试原始的Android中的key来签名,程序在模拟器上运行OK,不过放到G3上安装直接提示"Package ... has no signatures that match those in shared user android.uid.system",这样也是保护了系统的安全。

    最最后还说下,这个android:sharedUserId属性不只可以把apk放到系统进程中,也可以配置多个APK运行在一个进程中,这样可以共享数据,应该会很有用的。 博主补充:

    signapk编译结束后在 android目录下/out/host/linux-x86/framework/signapk.jar

    使用方法:java -jar signapk.jar platform.x509.pem platform.pk8 test.apk test_signed.apk

    实践证明,第二种方法不需要删掉META-INF目录下的CERT.SF和CERT.RSA两个文件,直接signapk就可以。

    编写使用root权限的android应用程序这个是如何执行su命令的使用

    publicstaticboolean runRootCommand(String command){

      Process process =null;

      DataOutputStream os =null;

      try{

           process =Runtime.getRuntime().exec("su");

           os =newDataOutputStream(process.getOutputStream());

           os.writeBytes(command+"\n");

           os.writeBytes("exit\n");

          os.flush();

           process.waitFor();

      }catch(Exception e){

          Log.d("*** DEBUG ***", "Unexpected error - Here is what I know: "+e.getMessage());

          return false;

      }finally{

          try{

              if(os !=null){

                      os.close();

                    }

                    process.destroy();

                    }catch(Exception e){

                      // nothing

                    }

            }returntrue;

          }

      }
分享到:
评论
1 楼 huangbo_2020 2012-02-21  
java -jar signapk.jar  ../../../../build/target/product/security/platform.x509.pem  ../../../../build/target/product/security/platform.pk8  ../../../../out/target/product/vanzo73_gb/system/app/XX.apk   ~/XX.apk

相关推荐

    android DHCP获取IP失败分析解决.pdf

    Android DHCP 获取 IP 失败分析和解决 ...通过检查 DHCP 获取 IP 的流程和常见的错误原因,我们可以更好地理解 Android 中的网络通信机制。同时,通过解决方法,我们可以更好地解决 DHCP 获取 IP 失败的问题。

    android5.0权限问题解决办法

    随着Android系统的不断升级与完善,为了更好地保护用户数据的安全性,从Android 5.x版本开始,系统引入了更为严格的SELinux(Security Enhanced Linux)权限管理机制。这一机制有效地提高了Android系统的安全性,但...

    Android逆向分析权限和API提取工具

    首先,我们要明白Android权限系统是保护应用数据和资源的关键机制。每个Android应用在安装时都需要声明它所需的权限,这些权限控制着应用能够访问哪些系统资源和服务。例如,一个应用如果需要读取联系人信息,就需要...

    android6.0的新权限问题说明

    ### Android 6.0的新权限管理机制详解 随着Android 6.0(Marshmallow)的发布,谷歌在系统层面上引入了一套全新的权限管理机制,旨在更好地保护用户的隐私和个人信息安全。这一新机制允许用户对应用请求的具体权限...

    Android权限检测

    Android权限检测是指通过特定工具或程序来检查应用程序是否具备运行所需的各种权限,以及这些权限的使用情况。本篇文章将详细探讨Android权限检测的重要性、原理、实现方式及相关的开发实践。 首先,Android权限...

    android studio 简单获取天气案例

    综上所述,"android studio 简单获取天气案例"涵盖了Android开发中的网络请求、JSON解析、UI设计、异步处理、权限管理、生命周期管理、数据缓存、测试与调试以及发布准备等多个重要知识点。通过实践这个案例,开发者...

    android获取GPS经纬度,并根据经纬度获取准确地址( 纯原生)

    在Android开发中,获取设备的GPS经纬度以及根据这些坐标获取准确地址是常见的需求。这里我们将深入探讨如何实现这一功能。 首先,我们需要了解Android中的Location服务。Location服务是Android系统提供的一种定位...

    Android录音 获取录音文件 录音时间

    在Android平台上进行录音操作是移动应用开发中常见的功能,它涉及到多媒体处理、文件操作以及用户交互等多个方面。本文将深入探讨如何在Android中实现录音、获取录音文件以及控制录音时间,同时也会提及与动画和文件...

    Android系统Root权限获取与检测.pdf

    绍了Android系统Root权限的获取方法以及检测Root状态的相关技术。Android系统是基于Linux内核构建的,其安全模型依赖于Linux的沙箱机制(Sandbox),每个应用程序都在自己的进程中运行,具有特定的用户ID(UID)和组...

    Android权限列表permission说明.

    Android权限机制通过一系列的权限声明和权限检查来实现这一目标。本文将详细介绍部分Android权限,并解释它们的作用与应用场景。 #### 二、详细权限介绍 1. **ACCESS_COARSE_LOCATION** - **定义**:此权限用于...

    android获取手机号码_获取手机运营商

    在Android开发中,获取设备的手机号码和运营商信息是常见的需求,这主要涉及到对设备硬件信息的访问。本文将详细讲解如何在Android中实现这些功能,并提供相关的代码示例。 首先,我们需要理解Android系统的权限...

    钉钉 请求通讯录权限获取手机号和邮箱报权限不足

    总的来说,理解和解决“钉钉 请求通讯录权限获取手机号和邮箱报权限不足”的问题,需要用户检查自己的设备设置,同时开发者需要确保应用遵循正确的权限请求流程,并在设计时考虑到各种可能的用户环境。对于企业来说...

    Android开发之获取通知栏的内容源码

    在Android开发中,获取通知栏的内容是一项常见的需求,特别是在做系统监控、日志记录或者定制化功能时。本文将深入探讨如何通过源码实现这一功能,主要涉及Android的通知系统架构和相关API的使用。 首先,我们需要...

    Android OS手机平台的安全机制分析和应用研究

    在实验部分,文章选取了一个常见的应用场景——媒体播放器,来具体分析Android安全机制的实际运作原理。通过这一示例,我们可以更直观地了解Android如何利用其安全特性来保护用户的数据安全和系统安全。 1. **权限...

    Android——华为手机(G9)调用Camera需要手动申请权限

    在标题中提到的问题,即在华为G9上开发应用调用相机时,需要手动申请权限,这是Android 6.0(API级别23)引入的动态权限管理机制所导致的。 Android 6.0之前的版本,应用在安装时会一次性获取所有所需权限,而在6.0...

    android自动获取验证码

    在Android平台上,自动获取验证码是一项常见的...通过合理地运用这些技术,可以实现高效、安全的验证码获取机制,提高用户的使用体验。在开发过程中,注意遵守隐私政策,确保用户体验的同时,也要注重数据的安全性。

    android 获取天气信息

    在Android应用开发中,获取天气信息是常见的功能之一,它能为用户提供实时的气象和环境质量数据。在本例中,我们关注的是如何通过点击主界面的下拉菜单来展示天气信息,特别是空气质量指数(AQI)和PM25值。下面将...

    Android配置文件,所有权限

    在Android操作系统中,权限管理系统是保障应用安全性和用户隐私的关键机制。配置文件中列出的权限涉及到多个方面,包括位置访问、网络状态、账户管理、系统服务绑定、设备控制以及通信等。下面将详细解释这些权限的...

    前端H5获取Android原生相册文件和拍照功能直接重新WebView的方法即可

    这里需要注意的是,Android权限管理机制,需要在AndroidManifest.xml中添加读取外部存储的权限: ```xml &lt;uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/&gt; ``` 同时,对于拍照功能,...

    android 获取经纬度demo

    在Android开发中,获取设备当前的经纬度是常见的需求,特别是在构建地图应用或者与位置相关的服务时。这个“android 获取经纬度demo”提供了一个实例,教我们如何利用Android的网络定位服务来获取地理位置信息。下面...

Global site tag (gtag.js) - Google Analytics