简体   繁体   English

如何从PackageInstaller获取sideloaded APK的签名

[英]How to get signature of a sideloaded APK from PackageInstaller

I am trying to build a custom Android (based on AOSP 7.1) for a device. 我正在尝试为设备构建自定义Android(基于AOSP 7.1)。 I would like to get the signature of apps that is to be sideloaded via USB. 我想获得通过USB进行侧载的应用程序的签名。 The apps are not installed on the system yet. 应用程序尚未安装在系统上。 My eventual goal is to compare the signature of an APK vs platform signature like this: https://gist.github.com/scottyab/b849701972d57cf9562e 我最终的目标是比较APK与平台签名的签名,如下所示: https//gist.github.com/scottyab/b849701972d57cf9562e

I found many guides, including this one - How to get APK signing signature? 我找到了很多指南,包括这一个 - 如何获得APK签名签名?

and followed the comment by Shengfeng Li on the accepted answer - "You need to push the not installed apk to the location where you program can get the apk such as SD_CARD, then use context.getPackageManager().getPackageAchiveInfo(NOT_INSTALL_APK_PATH,PackageManager.GET_SIGNATURES) .signatures[0] to get its hashCode. and compare them" 并按照盛峰李对接受的答案的评论 - “你需要将未安装的apk推送到你编程的位置可以获得apk,如SD_CARD,然后使用context.getPackageManager().getPackageAchiveInfo(NOT_INSTALL_APK_PATH,PackageManager.GET_SIGNATURES) .signatures[0]得到它的hashCode。并比较它们“

I am modifying the PackageInstaller app that is in AOSP ( https://github.com/aosp-mirror/platform_packages_apps_packageinstaller/blob/master/src/com/android/packageinstaller/PackageInstallerActivity.java ). 我正在修改AOSP中的PackageInstaller应用程序( https://github.com/aosp-mirror/platform_packages_apps_packageinstaller/blob/master/src/com/android/packageinstaller/PackageInstallerActivity.java )。

I modified the processPackageUri function of the PackageInstallerActivity.java like this (added PackageManager.GET_SIGNATURES flag): 我像这样修改了PackageInstallerActivity.javaprocessPackageUri函数(添加了PackageManager.GET_SIGNATURES标志):

case SCHEME_FILE: {
    File sourceFile = new File(packageUri.getPath());
    PackageParser.Package parsed = PackageUtil.getPackageInfo(sourceFile);

    // Check for parse errors
    if (parsed == null) {
        Log.w(TAG, "Parse error when parsing manifest. Discontinuing installation");
        showDialogInner(DLG_PACKAGE_ERROR);
        setPmResult(PackageManager.INSTALL_FAILED_INVALID_APK);
        return false;
    }
    mPkgInfo = PackageParser.generatePackageInfo(parsed, null,
            PackageManager.GET_PERMISSIONS|PackageManager.GET_SIGNATURES, 0, 0, null,
            new PackageUserState());

    as = PackageUtil.getAppSnippet(this, mPkgInfo.applicationInfo, sourceFile);
} break;

Signature validation function 签名验证功能

public boolean validateAppSignature() throws NameNotFoundException {
        boolean sigMatch = false;

        try {
            for (Signature signature : mPkgInfo.signatures) {
                // SHA1 the signature
                String sha1 = getSHA1(signature.toByteArray());
                // check if it matches hardcoded value
                sigMatch = PLATFORM_SIGNATURE.equals(sha1);
                if (sigMatch){
                  return sigMatch;  
                }
            }
        } catch (Exception e) {
                e.printStackTrace();
            }

        return false;

}

I hope to get the hash of the signature of the APKs but it is throwing this error, (from adb logcat) W System.err: java.lang.NullPointerException: Attempt to get length of null array 我希望获得APK签名的哈希,但它抛出这个错误,(来自adb logcat) W System.err: java.lang.NullPointerException: Attempt to get length of null array

probably from the try part for (Signature signature : mPkgInfo.signatures) . 可能来自试用部分for (Signature signature : mPkgInfo.signatures) I suspect that PackageParser.generatePackageInfo part is wrong and it is not returning any signature. 我怀疑PackageParser.generatePackageInfo部分是错误的,它没有返回任何签名。 Can someone enlighten me please? 有人可以开导我吗? Thanks a lot. 非常感谢。

Addendum: I found that the PackageInstaller app was indeed getting no signatures. 附录:我发现PackageInstaller应用程序确实没有签名。 I traced the codes and found the following in src/com/android/packageinstaller/PackageUtil.java : 我跟踪代码并在src/com/android/packageinstaller/PackageUtil.java找到以下src/com/android/packageinstaller/PackageUtil.java

public static PackageParser.Package getPackageInfo(File sourceFile) {
    final PackageParser parser = new PackageParser();
    try {
        return parser.parsePackage(sourceFile, 0);
    } catch (PackageParserException e) {
        return null;
    }
}

parsePackage function is from frameworks/base/core/java/android/content/pm/PackageParser.java which like this: parsePackage函数来自frameworks/base/core/java/android/content/pm/PackageParser.java ,它们是这样的:

public Package parsePackage(File packageFile, int flags) throws PackageParserException {
        if (packageFile.isDirectory()) {
            return parseClusterPackage(packageFile, flags);
        } else {
            return parseMonolithicPackage(packageFile, flags);
        }
    }

It accepts flags but PackageUtil.java passes no flags to it and I think that's the reason I am not getting any signatures of the apk files. 它接受标志,但PackageUtil.java没有传递任何标志,我认为这是我没有得到任何apk文件签名的原因。 I think I may need to call collectCertificates(Package, int) from PackageParser.java if I want the signatures. 我想如果我想要签名collectCertificates(Package, int)我可能需要从PackageParser.java调用collectCertificates(Package, int)

Am I on the right track? 我是在正确的轨道上吗? Your inputs are highly appreciated. 您的意见得到高度赞赏。

I managed to solve this, thanks to the comment by @ChrisStratton. 由于@ChrisStratton的评论,我设法解决了这个问题。 I needed to call collectCertificates from PackageInstallerActivity.java , like so: 我需要从PackageInstallerActivity.java调用collectCertificates ,如下所示:

case SCHEME_FILE: {
    File sourceFile = new File(packageUri.getPath());

    PackageParser.Package parsed = PackageUtil.getPackageInfoMod(sourceFile, PackageManager.GET_PERMISSIONS|PackageManager.GET_SIGNATURES);

    // Check for parse errors
    if (parsed == null) {
        Log.w(TAG, "Parse error when parsing manifest. Discontinuing installation");
        showDialogInner(DLG_PACKAGE_ERROR);
        setPmResult(PackageManager.INSTALL_FAILED_INVALID_APK);
        return false;
    }
    else {
        try {
            PackageParser.collectCertificates(parsed, PackageManager.GET_SIGNATURES);
        } 
            catch (Exception e) {
            e.printStackTrace();
        }
    }
    mPkgInfo = PackageParser.generatePackageInfo(parsed, null,
            PackageManager.GET_PERMISSIONS|PackageManager.GET_SIGNATURES, 0, 0, null,
            new PackageUserState());
    as = PackageUtil.getAppSnippet(this, mPkgInfo.applicationInfo, sourceFile);
} break;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM