Android Root 环境下修改系统源码方案

参考博客:在有root权限下破解Android系统签名,安装未系统签名的APK

本文将为您介绍在 Android 系统 Root 后,如何安装系统级别的 App 。也是对参考文章《在有root权限下破解Android系统签名,未安装系统签名的APK》的实践记录。关于 Root 方法,请自行检索学习。

在一些功能需要使用到系统级 App 才能使用的权限时,最直接的方案就是将你的应用升级为系统应用。如此需要以下步骤:

  • 确保您的手机已 Root 或自行编译的 Android 系统(能够提取到系统签名文件)。

  • 您的 App 签名应该是系统签名;若您的应用不是系统签名,将会报错

    Installation did not succeed.
    The application could not be installed: INSTALL_FAILED_SHARED_USER_INCOMPATIBLE
  • 在您的项目中,AndroidManifest.xml 中 manifest 标签中增加以下内容:

    android:sharedUserId="android.uid.system"

首先通过 adb 连接到手机,并切换到超级权限:

adb root

从系统中拉取文件:

adb pull /system/framework/services.jar /你的电脑自定义目录

对文件进行解压:

unzip services.jar 

你将获得以下文件:

Android Root 环境下修改系统源码方案执行命令查找包含签名报错相关内容的 dex 文件:

grep -lr "has no signatures that match those in shared user" services

此时会输出:services/classes.dex ,下一步就是使用 baksmali 工具对 classes.dex 进行反编译。

baksmali 下载地址:https://bitbucket.org/JesusFreke/smali/downloads/

java -jar baksmali-2.5.2.jar d classes.dex

此时当前目录下会生成一个 out 文件夹,生成对应的所有 smali 文件。对该文件下的内容进行修改,修改后重新打包成 services.jar 。

此时在文件中搜索 “has no signatures that match those in shared user” ,文件会过滤出 PackageManagerServiceUtils.smali 文件:

Android Root 环境下修改系统源码方案
image-20230105183207055.png

说明相关逻辑在 PackageManagerServiceUtils 中,去 Android 源码中查找相关内容,会找到相关文件:

frameworks/base/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java

在代码中搜索上面的相关字段,会找到验证签名逻辑的方法,注意查找你的 Android 系统版本的源码:

Android Root 环境下修改系统源码方案
image-20230105190023401.png

相关逻辑在 verifySignatures 方法中:

           if (!match) {
                throw new PackageManagerException(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE,
                        "Package " + packageName
                        + " has no signatures that match those in shared user "
                        + sharedUserSetting.name + "; ignoring!");
            }

            // ...

            // If the lineage of this package diverges from the lineage of the sharedUserId then
            // do not allow the installation to proceed.
            if (!parsedSignatures.hasCommonAncestor(
                    sharedUserSetting.signatures.mSigningDetails)) {
                throw new PackageManagerException(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE,
                        "Package " + packageName + " has a signing lineage "
                                + "that diverges from the lineage of the sharedUserId");
            }

在 PackageManagerServiceUtils.smali 中查找对应的相关字段,会定位到相应位置:

//689 行判断了 if(!match)
.line 689 
    :cond_109
    const/4 p3, -0x8

    if-eqz p1, :cond_18d // if-nez p1, :cond_18d


// 725 行判断了 if (!parsedSignatures.hasCommonAncestor(...))
.line 725
    invoke-virtual {p2, p0}, Landroid/content/pm/PackageParser$SigningDetails;->hasCommonAncestor(Landroid/content/pm/PackageParser$SigningDetails;)Z

    move-result p0

    if-eqz p0, :cond_173 // if-nez p0, :cond_173 即 if==0 改为 if !=0

    goto :goto_1b5

    .line 727
    :cond_173
    new-instance p0, Lcom/android/server/pm/PackageManagerException;
...

此时需要你去熟悉一下 smali 语法,这里主要是将 if-eqz 修改为 if-nez ,相关语法可参考下面这篇文章:

https://github.com/JnuSimba/AndroidSecNotes/blob/master/Android%E9%80%86%E5%90%91%E5%9F%BA%E7%A1%80/smali%20%E8%AF%AD%E6%B3%95.md

修改位置有两处, 689 行的判断条件:

 if (!match) {
     throw new PackageManagerException(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE,
         "Package " + packageName
         + " has no signatures that match those in shared user "
         + sharedUserSetting.name + "; ignoring!");
}

725 行判断逻辑:

if (!parsedSignatures.hasCommonAncestor(sharedUserSetting.signatures.mSigningDetails)) {
    throw new PackageManagerException(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE,
        "Package " + packageName + " has a signing lineage "
        + "that diverges from the lineage of the sharedUserId");
}

修改含义是将其判断条件不成立,不进入抛出异常逻辑即可。

然后对修改后的文件重新打包,这里需要用到 smali 进行打包,

下载链接:https://bitbucket.org/JesusFreke/smali/downloads/

执行命令:

java -jar smali-2.5.2.jar a out

此时会在当前目录下生成一个 out.dex 文件,将这个文件替换原来的 class.dex 并重新打包 jar 文件。

jar cvfm services1.jar unzip/META-INF/MANIFEST.MF -C unzip/ . &>/dev/null

这里 unzip 目录就是之前解压 service.jar 后的文件所在目录

执行完该命令后,当前文件夹会生成 services1.jar 文件,将修改后的 services1.jar 重命名为 services.jar 并 push 到设备重启:

adb root
adb remount
adb push services.jar /system/framework/services.jar
adb reboot

如此,就可以将 App 安装到手机上了(虽然安装成功了但直接 ANR) 。尽管后续存在一些问题,但是本文提供了修改系统源码逻辑的手段。了解反编译、修改 smali 文件、编译的整体流程。


原文始发于微信公众号(八千里路山与海):Android Root 环境下修改系统源码方案

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/84984.html

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!