繁体   English   中英

如何从PackageInstaller获取sideloaded APK的签名

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

我正在尝试为设备构建自定义Android(基于AOSP 7.1)。 我想获得通过USB进行侧载的应用程序的签名。 应用程序尚未安装在系统上。 我最终的目标是比较APK与平台签名的签名,如下所示: https//gist.github.com/scottyab/b849701972d57cf9562e

我找到了很多指南,包括这一个 - 如何获得APK签名签名?

并按照盛峰李对接受的答案的评论 - “你需要将未安装的apk推送到你编程的位置可以获得apk,如SD_CARD,然后使用context.getPackageManager().getPackageAchiveInfo(NOT_INSTALL_APK_PATH,PackageManager.GET_SIGNATURES) .signatures[0]得到它的hashCode。并比较它们“

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

我像这样修改了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;

签名验证功能

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;

}

我希望获得APK签名的哈希,但它抛出这个错误,(来自adb logcat) W System.err: java.lang.NullPointerException: Attempt to get length of null array

可能来自试用部分for (Signature signature : mPkgInfo.signatures) 我怀疑PackageParser.generatePackageInfo部分是错误的,它没有返回任何签名。 有人可以开导我吗? 非常感谢。

附录:我发现PackageInstaller应用程序确实没有签名。 我跟踪代码并在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函数来自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);
        }
    }

它接受标志,但PackageUtil.java没有传递任何标志,我认为这是我没有得到任何apk文件签名的原因。 我想如果我想要签名collectCertificates(Package, int)我可能需要从PackageParser.java调用collectCertificates(Package, int)

我是在正确的轨道上吗? 您的意见得到高度赞赏。

由于@ChrisStratton的评论,我设法解决了这个问题。 我需要从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