Как получить подпись стороннего APK из PackageInstaller - PullRequest
0 голосов
/ 28 марта 2019

Я пытаюсь создать собственный 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.сравните их "

Я изменяю приложение PackageInstaller, которое находится в AOSP (https://github.com/aosp-mirror/platform_packages_apps_packageinstaller/blob/master/src/com/android/packageinstaller/PackageInstallerActivity.java).

Я изменил processPackageUri функцию PackageInstallerActivity.java следующим образом (добавлен флаг 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 неверна и не возвращает никакой подписи. Может кто-нибудь просветить меня, пожалуйста? Большое спасибо.

Приложение: Я обнаружил, что пакПриложение geInstaller действительно не получало подписи.Я проследил коды и нашел следующее в 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, если я хочу подписи.

Я на правильном пути?Ваш вклад высоко ценится.

1 Ответ

0 голосов
/ 30 марта 2019

Мне удалось решить эту проблему, благодаря комментарию @ChrisStratton. Мне нужно было позвонить collectCertificates с PackageInstallerActivity.java, вот так:

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;
...