mk中的android:sharedUserId和LOCAL_CERTIFICATE作用(一)

Android中如何修改系统时间(应用程序获得系统权限)
在 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运行在一个进程中,这样可以共享数据,应该会很有用的。


2. A和B使用相同的sharedUserId(参考:Android权限之sharedUserId和签名)

最近在做个东西,巧合碰到了sharedUserId的问题,所以收集了一些资料,存存档备份。

安装在设备中的每一个apk文件,Android给每个APK进程分配一个单独的用户空间,其manifest中的userid就是对应一个Linux用户都会被分配到一个属于自己的统一的Linux用户ID,并且为它创建一个沙箱,以防止影响其他应用程序(或者其他应用程序影响它)。用户ID 在应用程序安装到设备中时被分配,并且在这个设备中保持它的永久性。

通过Shared User id,拥有同一个User id的多个APK可以配置成运行在同一个进程中.所以默认就是可以互相访问任意数据. 也可以配置成运行成不同的进程, 同时可以访问其他APK的数据目录下的数据库和文件.就像访问本程序的数据一样.

对于一个APK来说,如果要使用某个共享UID的话,必须做三步:

1、在Manifest节点中增加android:sharedUserId属性。

2、在Android.mk中增加LOCAL_CERTIFICATE的定义。

如果增加了上面的属性但没有定义与之对应的LOCAL_CERTIFICATE的话,APK是安装不上去的。提示错误是:Package com.test.MyTest has no signatures that match those in shared user android.uid.system; ignoring!也就是说,仅有相同签名和相同sharedUserID标签的两个应用程序签名都会被分配相同的用户ID。例如所有和media/download相关的APK都使用android.media作为sharedUserId的话,那么它们必须有相同的签名media。

3、把APK的源码放到packages/apps/目录下,用mm进行编译。

举例说明一下。

系统中所有使用android.uid.system作为共享UID的APK,都会首先在manifest节点中增加android:sharedUserId="android.uid.system",然后在Android.mk中增加LOCAL_CERTIFICATE := platform。可以参见Settings等

系统中所有使用android.uid.shared作为共享UID的APK,都会在manifest节点中增加android:sharedUserId="android.uid.shared",然后在Android.mk中增加LOCAL_CERTIFICATE := shared。可以参见Launcher等

系统中所有使用android.media作为共享UID的APK,都会在manifest节点中增加android:sharedUserId="android.media",然后在Android.mk中增加LOCAL_CERTIFICATE := media。可以参见Gallery等。

另外,应用创建的任何文件都会被赋予应用的用户标识,并且正常情况下不能被其他包访问。当通过getSharedPreferences(String,int)、openFileOutput(String、int)或者openOrCreate Database(String、int、SQLiteDatabase.CursorFactory)创建一个新文件时,开发者可以同时或分别使用MODE_WORLD_READABLE和MODE_WORLD_RITEABLE标志允许其他包读/写此文件。当设置了这些标志后,这个文件仍然属于自己的应用程序,但是它的全局读/写和读/写权限已经设置,所以其他任何应用程序可以看到它。

关于签名:

build/target/product/security目录中有四组默认签名供Android.mk在编译APK使用:

1、testkey:普通APK,默认情况下使用。

2、platform:该APK完成一些系统的核心功能。经过对系统中存在的文件夹的访问测试,这种方式编译出来的APK所在进程的UID为system。

3、shared:该APK需要和home/contacts进程共享数据。

4、media:该APK是media/download系统中的一环。

应用程序的Android.mk中有一个LOCAL_CERTIFICATE字段,由它指定用哪个key签名,未指定的默认用testkey.


对于使用eclipse编译的apk,可以使用signapk.jar来手动进行签名,其源码在build/tools/signapk下,编译后在out/host/linux-x86/framework/signapk.jar,也可以从网上下载。使用方法,以platform为例:java -jar ./signapk platform.x509.pem platform.pk8 input.apk output.apk (platform.x509.pem platform.pk8在build/target/product/security获取)


另外还看到了这样的问题,没太看懂:http://groups.google.com/group/android-developers/browse_thread/thread/1d426975a7513124

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Android权限之sharedUserId和签名(二)

分类: android之底层学习 5133人阅读 评论(9) 收藏 举报

最近在做个东西,巧合碰到了sharedUserId的问题,所以收集了一些资料,存存档备份。

安装在设备中的每一个apk文件,Android给每个APK进程分配一个单独的用户空间,其manifest中的userid就是对应一个Linux用户都会被分配到一个属于自己的统一的Linux用户ID,并且为它创建一个沙箱,以防止影响其他应用程序(或者其他应用程序影响它)。用户ID 在应用程序安装到设备中时被分配,并且在这个设备中保持它的永久性。

通过Shared User id,拥有同一个User id的多个APK可以配置成运行在同一个进程中.所以默认就是可以互相访问任意数据. 也可以配置成运行成不同的进程, 同时可以访问其他APK的数据目录下的数据库和文件.就像访问本程序的数据一样.

对于一个APK来说,如果要使用某个共享UID的话,必须做三步:

1、在Manifest节点中增加android:sharedUserId属性。

2、在Android.mk中增加LOCAL_CERTIFICATE的定义。

如果增加了上面的属性但没有定义与之对应的LOCAL_CERTIFICATE的话,APK是安装不上去的。提示错误是:Package com.test.MyTest has no signatures that match those in shared user android.uid.system; ignoring!也就是说,仅有相同签名和相同sharedUserID标签的两个应用程序签名都会被分配相同的用户ID。例如所有和media/download相关的APK都使用android.media作为sharedUserId的话,那么它们必须有相同的签名media。

3、把APK的源码放到packages/apps/目录下,用mm进行编译。

举例说明一下。

系统中所有使用android.uid.system作为共享UID的APK,都会首先在manifest节点中增加android:sharedUserId="android.uid.system",然后在Android.mk中增加LOCAL_CERTIFICATE := platform。可以参见Settings等

系统中所有使用android.uid.shared作为共享UID的APK,都会在manifest节点中增加android:sharedUserId="android.uid.shared",然后在Android.mk中增加LOCAL_CERTIFICATE := shared。可以参见Launcher等

系统中所有使用android.media作为共享UID的APK,都会在manifest节点中增加android:sharedUserId="android.media",然后在Android.mk中增加LOCAL_CERTIFICATE := media。可以参见Gallery等。

另外,应用创建的任何文件都会被赋予应用的用户标识,并且正常情况下不能被其他包访问。当通过getSharedPreferences(String,int)、openFileOutput(String、int)或者openOrCreate Database(String、int、SQLiteDatabase.CursorFactory)创建一个新文件时,开发者可以同时或分别使用MODE_WORLD_READABLE和MODE_WORLD_RITEABLE标志允许其他包读/写此文件。当设置了这些标志后,这个文件仍然属于自己的应用程序,但是它的全局读/写和读/写权限已经设置,所以其他任何应用程序可以看到它。

关于签名:

build/target/product/security目录中有四组默认签名供Android.mk在编译APK使用:

1、testkey:普通APK,默认情况下使用。

2、platform:该APK完成一些系统的核心功能。经过对系统中存在的文件夹的访问测试,这种方式编译出来的APK所在进程的UID为system。

3、shared:该APK需要和home/contacts进程共享数据。

4、media:该APK是media/download系统中的一环。

应用程序的Android.mk中有一个LOCAL_CERTIFICATE字段,由它指定用哪个key签名,未指定的默认用testkey.

对于使用eclipse编译的apk,可以使用signapk.jar来手动进行签名,其源码在build/tools/signapk下,编译后在out/host/linux-x86/framework/signapk.jar,也可以从网上下载。使用方法,以platform为例:java -jar ./signapk platform.x509.pem platform.pk8 input.apk output.apk (platform.x509.pem platform.pk8在build/target/product/security获取)

Android APP权限之sharedUserId和签名(三)

热度 1已有 113 次阅读2012-6-15 17:50|个人分类:android|android,sharedUserId,签名,进程空间

今天去面试,问我Settings这个APK是属于那个进程的?我痴呆。。。没答出来。。。
Android会根据manifest中声明的userid给每个APK进程分配一个单独的用户空间,所以不同APK(用户)间互相访问数据默认是禁止的。 但是它也提供了2种APK间共享数据的形式:
1. Share Preference. / Content Provider APK可以指定接口和数据给任何其他APK读取. 需要自己实现接口和Share的数据. 本文对于这个不做详细解释
2. Shared User id 通过Shared User id,拥有同一个User id的多个APK可以配置成运行在同一个进程中.所以默认就是 可以互相访问任意数据. 也可以配置成运行成不同的进程, 同时可以访问其他APK的数据目录下的 数据库和文件.就像访问本程序的数据一样. 比如某个公司开发了多个Android 程序, 那么可以把数据,图片等资源集中放到APK A中去. 然后 这个公司的所有APK都使用同一个User ID, 那么所有的资源都可以从APK A中读取. 举个例子: APK A 和APK B 都是C公司的产品,那么如果用户从APK A中登陆成功.那么打开APK B的时候就不用 再次登陆. 具体实现就是 A和B设置成同一个User ID: * 在2个APK的AndroidManifest.xml 配置User ID: <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.android.demo.a1" android:sharedUserId="com.c"> 这个"com.c" 就是user id, 然后packagename APK A就是上面的内容, APK B可能 是"com.android.demo.b1" 这个没有限制
这个设定好之后, APK B就可以像打开本地数据库那样 打开APK A中的数据库了. APK A把登陆信息存放在A的数据目录下面. APK B每次启动的时候读取APK A下面的数据库 判断是否已经登陆: APK B中的代码: friendContext = this.createPackageContext( "com.android.demo.a1", Context.CONTEXT_IGNORE_SECURITY); 通过A的package name 就可以得到A的 packagecontext,通过这个context就可以直接打开数据库

android:sharedUserId问题( 四)

分类: android 317人阅读 评论(0) 收藏 举报 android:sharedUserId问题

Android给每个APK进程分配一个单独的用户空间,其manifest中的userid就是对应一个Linux用户

Shared User id
通过Shared User id,拥有同一个User id的多个APK可以配置成运行在同一个进程中.所以默认就是
可以互相访问任意数据. 也可以配置成运行成不同的进程, 同时可以访问其他APK的数据目录下的
数据库和文件.就像访问本程序的数据一样.

如果编译Settings或者android manifest XML中 shared user id 包含android.uid.shared等系统权限的时候,则会报以下错误。

Installation error: INSTALL_FAILED_UPDATE_INCOMPATIBLE
Installation error: INSTALL_FAILED_SHARED_USER_INCOMPATIBLE

INSTALL_FAILED_UPDATE_INCOMPATIBLE
1、由于卸载没有完全,可以使用设置中卸载相应应用,或者adb uninstall com.android.***

INSTALL_FAILED_SHARED_USER_INCOMPATIBLE
主要是由于使用了android.uid.shared导致的问题。
解决方案如下
第一个方法简单点,不过需要在Android系统源码的环境下用make来编译:

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

2. 查看Android.mk文件,加入LOCAL_CERTIFICATE := 这一行,根据这行的内容,选择相应的签名。
platform----->platform.pk8和platform.x509.pem
shared ----->shared.pk8和shared.x509.pem
3. 使用目标系统的platform密钥来重新给apk文件签名。这步比较麻烦,
首先找到密钥文件,在我的Android源码目录中的位置
是"build\target\product\security",下面的platform.pk8和platform.x509.pem
两个文件。
然后用Android提供的Signapk工具来签名,signapk的源代码是
在"build\tools\signapk"下,
用法为"java -jar signapk.jar platform.x509.pem platform.pk8 input.apk output.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运行在一个进程中,这样可以共享数据,应该会很有用的

在AndroidMenifest.xml中我们可以看到android:sharedUserId="android.uid.system"
但是有了这句后,就无法对sd卡进行读写操作,比如在SD卡中创建一个新文件夹,是创建不成功的。但是如果把android:sharedUserId="android.uid.system"注释掉,就可以在SD卡进行IO操作了。

在Settings中android:sharedUserId="android.uid.system"是不可少的,少了它很多Settings下应用直接开不了,或一开就报错。

解决方法一:


vold 模块里的 Volume.cpp文件
在调用doMount的语句里做一下修改~
doMount(devicePath, path, false, false, false,1000, 1015, 0702, true)

doMount(devicePath, path, false, true, false,1000, 1015, 0002, true)

编译以后试试

解决方法二:

把SD卡操作的功能独立出去,做成一个独立的APK,然后在原项目中调用改功能就可以了。

restartPackage && sharedUserId="android.uid.shared” (五)

分类: Android 692人阅读 评论(0)收藏 举报

我们的任务管理器去关闭一个task,用到的方法是 android.app.ActivityManager.restartPackage。但是这里有一个不完善的地方就是,launcher和contacts都具有android:sharedUserId="android.uid.shared” 属性。restartPackage方法它会关掉与这个ap关联(同ID)的所有ap。

这里我去关掉cantacts,在log里可以看到,andorid会同时关掉launcher,输入法,还有acore进程:

DEBUG/ActivityManager(53): Force removing process ProcessRecord{438a46d0 104:android.process.acore/10001} (android.process.acore/10001)
DEBUG/ActivityManager(53): Force removing process ProcessRecord{43897660 192:com.android.inputmethod.latin/10001} (com.android.inputmethod.latin/10001)

INFO/WindowManager(53): WIN DEATH: Window{43910d90com.android.contacts/com.android.contacts.DialtactsContactsEntryActivity paused=false}
INFO/WindowManager(53): WIN DEATH: Window{4379ea98com.android.launcher/com.android.launcher.Launcher paused=false}
INFO/Process(53): Sending signal. PID: 192 SIG: 9
DEBUG/ActivityManager(53): Force finishing activitycom.android.contacts/.DialtactsContactsEntryActivity

我去看了一个写得比较好的类似软件,它在关contact的时候,lancher也是会被关掉的。但是我们不用去担心用户自己安装的程序也具有android:sharedUserId="android.uid.shared”属性,因为这样的程序只能在build整个系统时放进去(就是系统软件),手动安装是没有权限的。提示错误:

ERROR/PackageManager(53): Package XXXX has no signatures that match those in shared user android.uid.system; ignoring!

另外的关进程的方法,要去获得它的pid,再调用android.os.Process.killProcess(),但是killProcess里明确说明了:packages sharing a common UID will also be able to kill each other's processes.

android.process.acore 應該是一些基本功能的載入程序.
從 Source code 看來, 它應包含以下項目.
1. 聯絡人
2. Google search
3. Global search (不太明瞭它的功能)
4. 程式啟動列表 (就是主畫面下方可往上拉起的來的那鍋)
5. 應用程式清單資料庫處理元件 (Applications Provider)
6. 聯絡人資料庫處理元件 (Contact Provider)
7. Google 聯絡人資料庫處理元件 (Google Contact Provider)
8. 使用者自定詞彙資料庫處理元件 (User Dictionary Provider)


更多相关文章

  1. Android跨进程通信IPC之9——Binder之Framework层C++篇1
  2. Android 多进程之Messenger的使用
  3. JAVA & Android 系统环境变量配置
  4. Android 7.1.2(Android N) Android系统启动流程
  5. Android系统自带样式(@android:style/)
  6. Android xml资源文件中@、@android:type、@*、?、@+的含义和区别
  7. android 布局文件详解
  8. android支持的media文件格式--MediaFile
  9. 学习Android从0开始之背景篇-Android系统介绍

随机推荐

  1. 送1万美元鼓励员工离职创业,亚马逊是疯了
  2. 零代码实现一对一表关系和无限主子表级联
  3. 20210401 微服务测试
  4. GAN毕业手册:从零到一构建自己的GAN模型
  5. JVM内存分配与回收
  6. 百度核心搜索面试
  7. Java 如何有效地避免OOM:善于利用软引用和
  8. 华为发布业界首款AI-Native数据库,挑动了
  9. 存储卡出现“文件或目录结构损坏且无法读
  10. web前端开发都用什么软件?