android4.4 去掉授权,安卓4.4特殊权限授权机制

如下代码见PackageManagerService.java:private void grantPermissionsLPw(PackageParser.Package pkg, boolean replace) {

final PackageSetting ps = (PackageSetting) pkg.mExtras;

if (ps == null) {

return;

}

final GrantedPermissions gp = ps.sharedUser != null ? ps.sharedUser : ps;

HashSet origPermissions = gp.grantedPermissions;

boolean changedPermission = false;

if (replace) {

ps.permissionsFixed = false;

if (gp == ps) {

origPermissions = new HashSet(gp.grantedPermissions);

gp.grantedPermissions.clear();

gp.gids = mGlobalGids;

}

}

if (gp.gids == null) {

gp.gids = mGlobalGids;

}

//获取需要授权的权限列表

final int N = pkg.requestedPermissions.size();

for (int i=0; i

//权限名称

final String name = pkg.requestedPermissions.get(i);

//已获取的权限中是否包含该权限

final boolean required = pkg.requestedPermissionsRequired.get(i);

//由权限名获取封装的工具类BasePermission

final BasePermission bp = mSettings.mPermissions.get(name);

if (DEBUG_INSTALL) {

if (gp != ps) {

Log.i(TAG, "Package " + pkg.packageName + " checking " + name + ": " + bp);

}

}

if (bp == null || bp.packageSetting == null) {

Slog.w(TAG, "Unknown permission " + name

+ " in package " + pkg.packageName);

continue;

}

//权限名称

final String perm = bp.name;

boolean allowed;

boolean allowedSig = false;

final int level = bp.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE;

//PermissionInfo.PROTECTION_NORMAL = 0 ;

//PermissionInfo.PROTECTION_DANGEROUS = 1 ;

//以android.permission.INSTALL_PACKAGES,该权限的protectionLevel = 2,会走else if (level == PermissionInfo.PROTECTION_SIGNATURE)

//的case

if (level == PermissionInfo.PROTECTION_NORMAL

|| level == PermissionInfo.PROTECTION_DANGEROUS) {

// We grant a normal or dangerous permission if any of the following

// are true:

// 1) The permission is required

// 2) The permission is optional, but was granted in the past

// 3) The permission is optional, but was requested by an

// app in /system (not /data)

//

// Otherwise, reject the permission.

//以下4种情况同意申请

allowed = (required || origPermissions.contains(perm)

|| (isSystemApp(ps) && !isUpdatedSystemApp(ps)));

} else if (bp.packageSetting == null) {

// This permission is invalid; skip it.

allowed = false;

//PermissionInfo.PROTECTION_SIGNATURE = 2;

//android.permission.INSTALL_PACKAGES 会走这个case

} else if (level == PermissionInfo.PROTECTION_SIGNATURE) {

allowed = grantSignaturePermission(perm, pkg, bp, origPermissions);

if (allowed) {

allowedSig = true;

}

} else {

allowed = false;

}

if (DEBUG_INSTALL) {

if (gp != ps) {

Log.i(TAG, "Package " + pkg.packageName + " granting " + perm);

}

}

//如果同意权限申请则更新权限列表

if (allowed) {

if (!isSystemApp(ps) && ps.permissionsFixed) {

// If this is an existing, non-system package, then

// we can't add any new permissions to it.

if (!allowedSig && !gp.grantedPermissions.contains(perm)) {

// Except... if this is a permission that was added

// to the platform (note: need to only do this when

// updating the platform).

allowed = isNewPlatformPermissionForPackage(perm, pkg);

}

}

if (allowed) {

if (!gp.grantedPermissions.contains(perm)) {

changedPermission = true;

gp.grantedPermissions.add(perm);

gp.gids = appendInts(gp.gids, bp.gids);

} else if (!ps.haveGids) {

gp.gids = appendInts(gp.gids, bp.gids);

}

} else {

Slog.w(TAG, "Not granting permission " + perm

+ " to package " + pkg.packageName

+ " because it was previously installed without");

}

} else {

if (gp.grantedPermissions.remove(perm)) {

changedPermission = true;

gp.gids = removeInts(gp.gids, bp.gids);

Slog.i(TAG, "Un-granting permission " + perm

+ " from package " + pkg.packageName

+ " (protectionLevel=" + bp.protectionLevel

+ " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)

+ ")");

} else {

Slog.w(TAG, "Not granting permission " + perm

+ " to package " + pkg.packageName

+ " (protectionLevel=" + bp.protectionLevel

+ " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)

+ ")");

}

}

}

另外一个重要方法为:private boolean grantSignaturePermission(String perm, PackageParser.Package pkg,

BasePermission bp, HashSet origPermissions) {

boolean allowed;

//我用自定义签名的apk申请android.permission.INSTALL_PACKAGES,则签名比较是返回为false

allowed = (compareSignatures(

bp.packageSetting.signatures.mSignatures, pkg.mSignatures)

== PackageManager.SIGNATURE_MATCH)

|| (compareSignatures(mPlatformPackage.mSignatures, pkg.mSignatures)

== PackageManager.SIGNATURE_MATCH);

Log.d("PM_DEBUG","allowed1 is " + allowed + " for pkg " + pkg.packageName + " permission is " + perm);

//自定义签名apk申请会接着进入下述case

//因为level = bp.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE = bp.protectionLevel & 0xf

//所以bp.protectionLevel = 0x0010

//PermissionInfo.PROTECTION_FLAG_SYSTEM = 0x10

if (!allowed && (bp.protectionLevel

& PermissionInfo.PROTECTION_FLAG_SYSTEM) != 0) {

//如果是系统APK判断之前是否有授权

if (isSystemApp(pkg)) {

// For updated system applications, a system permission

// is granted only if it had been defined by the original application.

//如果是升级后的系统APK

if (isUpdatedSystemApp(pkg)) {

final PackageSetting sysPs = mSettings

.getDisabledSystemPkgLPr(pkg.packageName);

final GrantedPermissions origGp = sysPs.sharedUser != null

? sysPs.sharedUser : sysPs;

//判断之前是否有授权

if (origGp.grantedPermissions.contains(perm)) {

// If the original was granted this permission, we take

// that grant decision as read and propagate it to the

// update.

allowed = true;

Log.d("PM_DEBUG","allowed2 is " + allowed + " for pkg " + pkg.packageName + " permission is " + perm);

} else {

// The system apk may have been updated with an older

// version of the one on the data partition, but which

// granted a new system permission that it didn't have

// before. In this case we do want to allow the app to

// now get the new permission if the ancestral apk is

// privileged to get it.

// 若之前无授权则进一步判断是否有特权

isSystemApp包含system/app 和 system/priv-app 目录下面的APK

if (sysPs.pkg != null && sysPs.isPrivileged()) {

//有特权则判断之前是否有授权

for (int j=0;

j

if (perm.equals(

sysPs.pkg.requestedPermissions.get(j))) {

allowed = true;

Log.d("PM_DEBUG","allowed3 is " + allowed + " for pkg " + pkg.packageName + " permission is " + perm);

break;

}

}

}

}

} else {

//如果不是升级的系统APK

//isSystemApp包含system/app 和 system/priv-app 目录下面的APK

//只要放在priv-app即是isPrivilegedApp

allowed = isPrivilegedApp(pkg);

Log.d("PM_DEBUG","allowed4 is " + allowed + " for pkg " + pkg.packageName + " permission is " + perm);

}

}

}

if (!allowed && (bp.protectionLevel

& PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0) {

// For development permissions, a development permission

// is granted only if it was already granted.

allowed = origPermissions.contains(perm);

Log.d("PM_DEBUG","allowed5 is " + allowed + " for pkg " + pkg.packageName + " permission is " + perm);

}

return allowed;

}

以上,当我们的apk需要特殊权限时如:android.permission.INSTALL_PACKAGES时可以将其放置在

system/priv-app 目录下即可绕过系统签名的限制。

其他的权限我们在grantSignaturePermission函数中做一些workaround也可以绕过签名的限制。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值