如何解析apk v2标志块数据?

问题描述 投票:0回答:0

目前我已经获取到apk文件的v2签名块的二进制数据,但是我想分析v2签名块中的签名序列,这样就可以得到签名序列的SHA1摘要值,然后与真正的摘要值进行比较。

我也知道可以通过getPackageManager()方法获取v2签名数据的SHA1摘要信息,但是可能不安全

示例图像是这样的: apk siganture serial sha1 digest

 private static void checkByteOrderLittleEndian(final ByteBuffer buffer) {

        if (buffer.order() != ByteOrder.LITTLE_ENDIAN) {

            throw new IllegalArgumentException("ByteBuffer byte order must be little endian");

        }
    }  

 private static ByteBuffer sliceFromTo(final ByteBuffer source, final int start, final int end) {
        if (start < 0) {
            throw new IllegalArgumentException("start: " + start);
        }
        if (end < start) {
            throw new IllegalArgumentException("end < start: " + end + " < " + start);
        }
        final int capacity = source.capacity();
        if (end > source.capacity()) {
            throw new IllegalArgumentException("end > capacity: " + end + " > " + capacity);
        }
        final int originalLimit = source.limit();
        final int originalPosition = source.position();
        try {
            source.position(0);
            source.limit(end);
            source.position(start);
            final ByteBuffer result = source.slice();
            result.order(source.order());
            return result;
        } finally {
            source.position(0);
            source.limit(originalLimit);
            source.position(originalPosition);
        }
    }


   private static ByteBuffer getByteBuffer(final ByteBuffer source, final int size)
            throws BufferUnderflowException {
        if (size < 0) {
            throw new IllegalArgumentException("size: " + size);
        }
        final int originalLimit = source.limit();
        final int position = source.position();
        final int limit = position + size;
        if ((limit < position) || (limit > originalLimit)) {
            throw new BufferUnderflowException();
        }
        source.limit(limit);
        try {
            final ByteBuffer result = source.slice();
            result.order(source.order());
            source.position(limit);
            return result;
        } finally {
            source.limit(originalLimit);
        }
    }


public static Map<Integer, ByteBuffer> findIdValues(final ByteBuffer apkSigningBlock) throws SignatureNotFoundException {

        checkByteOrderLittleEndian(apkSigningBlock);

        // FORMAT:

        // OFFSET       DATA TYPE  DESCRIPTION

        // * @+0  bytes uint64:    size in bytes (excluding this field)

        // * @+8  bytes pairs

        // * @-24 bytes uint64:    size in bytes (same as the one above)

        // * @-16 bytes uint128:   magic

        final ByteBuffer pairs = sliceFromTo(apkSigningBlock, 8, apkSigningBlock.capacity() - 24);

        final Map<Integer, ByteBuffer> idValues = new LinkedHashMap<Integer, ByteBuffer>(); // keep order

        int entryCount = 0;

        while (pairs.hasRemaining()) {

            entryCount++;

            if (pairs.remaining() < 8) {

                throw new SignatureNotFoundException(

                        "Insufficient data to read size of APK Signing Block entry #" + entryCount);

            }

            final long lenLong = pairs.getLong();

            if ((lenLong < 4) || (lenLong > Integer.MAX_VALUE)) {

                throw new SignatureNotFoundException(

                        "APK Signing Block entry #" + entryCount

                                + " size out of range: " + lenLong);

            }

            final int len = (int) lenLong;

            final int nextEntryPos = pairs.position() + len;

            if (len > pairs.remaining()) {

                throw new SignatureNotFoundException(

                        "APK Signing Block entry #" + entryCount + " size out of range: " + len

                                + ", available: " + pairs.remaining());

            }

            final int id = pairs.getInt();

            idValues.put(id, getByteBuffer(pairs, len - 4));

            pairs.position(nextEntryPos);

        }

        return idValues;

    }

我也是用上面java的方法解析apk v2 sign block数据,但是无法正常使用。 how to invoke this java method

java android c++
© www.soinside.com 2019 - 2024. All rights reserved.