您的位置:首页 > 移动开发 > Android开发

Android获取系统权限之sharedUserId和签名及实现关机重启

2013-06-25 16:07 726 查看
系统源码

https://github.com/android

platform_build

已测试使用2.2签名可完成重启超载操作,但不能运行在4.0以上

使用4.0签名不能运行在4.1以上.

4.1 未测试.

4.2 签名signapk.jar 与之前并不相同.使用了org.bouncycastle.cms

android 签名系统级应用

一、Android Apk签名

Apk签名首先要有一个keystore的签名用的文件。

keystore是由jdk自带的工具keytool生成的。

具体生成方式参考:

开始->运行->cmd->cd到你安装的jdk的目录里,我的是C:\Program Files\Java\jdk1.6.0_10\bin

然后输入:

keytool -genkey -alias asaiAndroid.keystore -keyalg RSA -validity 20000 -keystore asaiAndroid.keystore

-alias 后面跟的是别名这里是 asaiAndroid.store

-keyalg 是加密方式这里是RSA

-validity 是有效期 这里是20000

-keystore 就是要生成的keystore的名称 这里是asiAndroid.keystore

然后按回车键

按回车后首先会提示你输入的密码:这个在签名时要用的,要记住

然后会再确认你的密码。

之后会依次叫你输入姓名、组织单位、组织名称、城市区域、省份名称、国家代码(CN)等。

开始签名。

在 C:\Program Files\Java\jdk1.6.0_10\bin 还提供一个工具 jarsigner.exe

运行命令给APK签名:

jarsigner -verbose -keystore asaiAndroid.keystore -signedjar Lotteryonline_signed.apk LotteryOnline.apk asaiAndroid.keystore

-keystore: keystore的名称

LotteryOnline_signed.apk: 签名后的APK

LotteryOnline.apk: 签名前的APK

然后按回车:会要求输入刚才设置的密码,输入后按回车就开始签名了。

二、eclipse源码编译,无需用make来编译(android源码目录<D:\myandroid_mx27>):

1、首先,AndroidManifest.xml中manifest节点中加入android:sharedUserId="android.uid.system"这个属性

2、用eclipse编译出apk(ClockSetting.apk)文件,但这个文件不能用,删掉META-INF目录下的CERT.SF和CERT.RSA两个文件

3、使用当前android系统(android系统可能不同)的platform密钥来重新给apk文件签名(可能还未用用户米要签名)。

首先,找到密钥文件,在我的Android源码目录中的位置是"build\target\product\security",下面的platform.pk8和platform.x509.pem两个文件。

然后,用Android提供的SignApk工具来签名,signapk的源代码是在"build\tools\signapk"下,这时得为下面的编译工作做些准备:

<1>、编译jar

命令行cd到signapk.java代码目录下,

javac signapk.java

获取SignApk$SignatureOutputStream.class和SignApk.class

建立目录s\com\android\signapk,将两个class文件放入目录下

jar cvfm signapk.jar SignApk.mf -C s\ .

注意:"s\"后面的"."前面有空格

生成signapk.jar文件,得到了Android提供的签名程序signapk.jar

<2>、用目标系统的platform密钥签名

将platform.pk8和platform.x509.pem文件复制到"D:\myandroid_mx27\build\tools\signapk"目录下,即signapk.jar和SignApk.mf所在的目录。

java -jar signapk.jar platform.x509.pem platform.pk8 D:\ClockSetting.apk D:\ClockSettingSigned.apk

我的未签名(ClockSetting.apk)和已签名(ClockSettingSigned.apk)apk文件都放在D盘,这样就得到了用Android源码编译的文件。

<3>、打开真机,安装:

adb connect IP:Port (IP为真机IP地址,Port为端口)

adb install D:/ClockSettingSigned.apk

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获取)

使用广播实现的Android关机及重启

最近研究App拥有root权限,弄了好久关机重启都没有成功,特别郁闷。就换另外一种更简单的方式,一试就成功了。

步骤一:编写Java代码
java部分代码:

case R.id.broadcast_reboot:
//重启
[align=left] Log.v("Reboot", "Reboot-->broadcast_reboot");[/align]
[align=left] Intent i = new Intent(Intent.ACTION_REBOOT);[/align]
i.putExtra("nowait",
1);
i.putExtra("interval",
1);
i.putExtra("window",
0);
[align=left] sendBroadcast(i); [/align]

[align=left] break;[/align]
[align=left] [/align]
case R.id.broadcast_shutdown:
//关机
[align=left] Log.v("Reboot", "Reboot-->broadcast_shutdown");[/align]
[align=left] Intent intent = new Intent(Intent.ACTION_REQUEST_SHUTDOWN);[/align]
[align=left] intent.putExtra(Intent.EXTRA_KEY_CONFIRM, false);[/align]
[align=left] intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);[/align]
[align=left] startActivity(intent);[/align]

[align=left] break;[/align]

注:关机可以设置时间设置【定时关机】功能,关机中的Intent.ACTION_REQUEST_SHUTDOWN
及 Intent.EXTRA_KEY_CONFIRM 在IDE中报错,但可以忽略,因为这两个属性不对上层开放,APP在源码中编译就可以直接使用。

[align=left]步骤二:修改Manifest.xml中属性[/align]

<manifestxmlns:android="http://schemas.android.com/apk/res/android"

……

android:sharedUserId="android.uid.system"

……
>

<uses-permissionandroid:name="android.permission.SHUTDOWN"/>

……
</manifest>

[align=left]注:[/align]

android:sharedUserId="android.uid.system" 将app提升到系统权限,需要到源码中编译,还有关机权限:android.permission.SHUTDOWN

[align=left]步骤三:编译APK[/align]
将项目拷贝到Android源码中进行编译,我拷贝到【gingerbread/development/apps/】下,并将项目的bin文件夹给删除,同时最重要的一步在项目下编写mk文件,山寨其它项目的mk文件写如下,不要漏掉LOCAL_CERTIFICATE
:= platform


[align=left]Android.mk:[/align]

[align=left]LOCAL_PATH:= $(call my-dir)[/align]

[align=left]include $(CLEAR_VARS)[/align]

[align=left]LOCAL_MODULE_TAGS := optional[/align]

[align=left]LOCAL_SRC_FILES := $(call all-java-files-under, src)[/align]

[align=left]LOCAL_PACKAGE_NAME := 你的项目名[/align]

[align=left]LOCAL_CERTIFICATE := platform[/align]

[align=left]include $(BUILD_PACKAGE) [/align]

[align=left]步骤四:[/align]
[align=left]通过mm编译生成的apk安装到机器中,就可以操作重启及关机[/align]

[align=left]注:使用相同的方法可以修改系统时间,重点是将应用提升到拥有系统权限,但进过此操作并未获得root权限。[/align]

[align=left]补充:后来使用init.rc启动系统服务的方法也是可行的,之前是因为编写关机 和 重启的sh文件使用了中文符号,使得sh命令有问题[/align]

[align=left]方法二可以参考:http://my.unix-center.net/~Simon_fu/?p=951[/align]

[align=left]PS:想了解进一步定制开机重启功能请点此《为Android系统定制重启功能》[/align]

进一步测试:
通过编译后到apk不能安装,主要是因为系统权限的问题。(Failure
[INSTALL_FAILED_SHARED_USER_INCOMPATIBLE]),需用在相同源码固件的系统才能使用系统签名的应用。

首先AndroidManifest.xml中加入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
见链接:http://bbs.gfan.com/android-85440-1-1.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: