Как получить надежное и действительное содержимое манифеста APK-файла, даже используя InputStream?Android

Форум для тех, кто программирует под Android
Anonymous
Как получить надежное и действительное содержимое манифеста APK-файла, даже используя InputStream?

Сообщение Anonymous »

Справочная информация

Мне хотелось получить информацию об APK-файлах (включая разделенные APK-файлы), даже если они находятся внутри сжатых zip-файлов (без их распаковки). В моем случае это включает в себя различные вещи, такие как имя пакета, код версии, имя версии, метка приложения, значок приложения, а также то, является ли это разделенным APK-файлом или нет.

Обратите внимание, что я хочу сделать все это внутри приложения Android, а не с помощью ПК, поэтому некоторые инструменты могут быть недоступны для использования.

Проблема

Это означает, что я не могу используйте функцию getPackageArchiveInfo, так как для этой функции требуется путь к APK-файлу, и она работает только с файлами без разделения apk.

Короче говоря, для этого не существует встроенной функции, поэтому мне нужно найти способ сделать это, перейдя в заархивированный файл, используя входной поток в качестве входных данных для его анализа в функции.

В Интернете есть различные решения, в том числе за пределами Android, но я не знаю ни одного стабильного и работающего во всех случаях. Многие из них могут быть хороши даже для Android (пример здесь), но при синтаксическом анализе может произойти сбой, и вместо Uri/InputStream может потребоваться путь к файлу.

Что я нашел и попробовал

Я нашел это на StackOverflow, но, к сожалению, согласно моим тестам, он всегда генерирует контент, но в некоторых редких случаях это недопустимый XML content.

На данный момент я обнаружил имена пакетов этих приложений и коды их версий, которые анализатору не удалось проанализировать, поскольку выходной XML-контент недействителен:
  • com.farproc.wifi.analyzer 139
  • com.teslacoilsw.launcherclientproxy 2
  • com.hotornot.app 3072
  • android 29 (это само системное приложение «Android System»)
  • com.google.android.videos 41300042
  • com.facebook.katana 201518851
  • com.keramidas.TitaniumBackupPro 10
  • com.google.android.apps.tachyon 2985033
  • com.google.android.apps.photos 3594753
Использование XML просмотрщик и XML-валидатор, вот проблемы с этими приложениями:
  • Для #1, #2 я получил очень странный контент, начиная с
    return decompressXML(zipInputStream.readBytes())
    // }
    }
    }
    }
    return null
    }

    /**
    * Binary XML doc ending Tag
    */
    private var endDocTag = 0x00100101

    /**
    * Binary XML start Tag
    */
    private var startTag = 0x00100102

    /**
    * Binary XML end Tag
    */
    private var endTag = 0x00100103

    /**
    * Reference var for spacing
    * Used in prtIndent()
    */
    private var spaces = " "

    /**
    * Parse the 'compressed' binary form of Android XML docs
    * such as for AndroidManifest.xml in .apk files
    * Source: http://stackoverflow.com/questions/2097 ... 89#4761689
    *
    * @param xml Encoded XML content to decompress
    */
    private fun decompressXML(xml: ByteArray): String {

    val resultXml = StringBuilder()

    // Compressed XML file/bytes starts with 24x bytes of data,
    // 9 32 bit words in little endian order (LSB first):
    // 0th word is 03 00 08 00
    // 3rd word SEEMS TO BE: Offset at then of StringTable
    // 4th word is: Number of strings in string table
    // WARNING: Sometime I indiscriminently display or refer to word in
    // little endian storage format, or in integer format (ie MSB first).
    val numbStrings = lew(xml, 4 * 4)

    // StringIndexTable starts at offset 24x, an array of 32 bit LE offsets
    // of the length/string data in the StringTable.
    val sitOff = 0x24 // Offset of start of StringIndexTable

    // StringTable, each string is represented with a 16 bit little endian
    // character count, followed by that number of 16 bit (LE) (Unicode) chars.
    val stOff = sitOff + numbStrings * 4 // StringTable follows StrIndexTable

    // XMLTags, The XML tag tree starts after some unknown content after the
    // StringTable. There is some unknown data after the StringTable, scan
    // forward from this point to the flag for the start of an XML start tag.
    var xmlTagOff = lew(xml, 3 * 4) // Start from the offset in the 3rd word.
    // Scan forward until we find the bytes: 0x02011000(x00100102 in normal int)
    run {
    var ii = xmlTagOff
    while (ii < xml.size - 4) {
    if (lew(xml, ii) == startTag) {
    xmlTagOff = ii
    break
    }
    ii += 4
    }
    } // end of hack, scanning for start of first start tag

    // XML tags and attributes:
    // Every XML start and end tag consists of 6 32 bit words:
    // 0th word: 02011000 for startTag and 03011000 for endTag
    // 1st word: a flag?, like 38000000
    // 2nd word: Line of where this tag appeared in the original source file
    // 3rd word: FFFFFFFF ??
    // 4th word: StringIndex of NameSpace name, or FFFFFFFF for default NS
    // 5th word: StringIndex of Element Name
    // (Note: 01011000 in 0th word means end of XML document, endDocTag)

    // Start tags (not end tags) contain 3 more words:
    // 6th word: 14001400 meaning??
    // 7th word: Number of Attributes that follow this tag(follow word 8th)
    // 8th word: 00000000 meaning??

    // Attributes consist of 5 words:
    // 0th word: StringIndex of Attribute Name's Namespace, or FFFFFFFF
    // 1st word: StringIndex of Attribute Name
    // 2nd word: StringIndex of Attribute Value, or FFFFFFF if ResourceId used
    // 3rd word: Flags?
    // 4th word: str ind of attr value again, or ResourceId of value

    // TMP, dump string table to tr for debugging
    //tr.addSelect("strings", null);
    //for (int ii=0; ii

Вернуться в «Android»