Go 语言解析 APK

Github 上有一个非常棒的 Go 语言的库 https://github.com/shogo82148/androidbinary
虽然 Star 数量有点少,不过代码质量高的惊人。维护人是一位来自日本的shogo82148 对于项目的 Issue 处理的很及时。

使用这个库可以解析 apk 文件中的AndroidManifest.xml以及resources.arsc ,原本解析这些文件需要非常了解这些文件的结构,处理起来非常复杂,但是借助这个库,分析起来就很容易。

例子

举例说明下

package main

import (
    "github.com/shogo82148/androidbinary/apk"
)

func main() {
    pkg, _ := apk.OpenFile("your-android-app.apk")
    defer pkg.Close()

    icon, _ := apk.Icon(nil) // returns the icon of APK as image.Image
    pkgName := pkg.PackageName() // returns the pakcage name
    mainActivity, _ = pkg.MainAcitivty()
}

就这么点代码就可以获取到应用的 packageName 以及应用图标(图标其实最难解析),但是借助这个库,实现起来就很容易。

再次贴一下这个项目的地址 https://github.com/shogo82148/androidbinary

Python 解析 APK

解析 apk 的 Python 库有很多,但是并没有出现一个特别强的,可以一统天下的库。

就用目前我感觉最好的一个库作为例子。

pip install AxmlParserPY==0.0.3

保存下面的代码为 apkparse.py

#!/usr/bin/env python
# coding: utf-8

import zipfile
from xml.dom import minidom
from axmlparserpy.axmlprinter import AXMLPrinter


class Manifest(object):
    def __init__(self, content):
        self._dom = minidom.parseString(content)
        self._permissions = None

    @property
    def package_name(self):
        return self._dom.documentElement.getAttribute('package')

    @property
    def version_code(self):
        return self._dom.documentElement.getAttribute("android:versionCode")

    @property
    def version_name(self):
        return self._dom.documentElement.getAttribute("android:versionName")

    @property
    def permissions(self):
        if self._permissions is not None:
            return self._permissions

        self._permissions = []
        for item in self._dom.getElementsByTagName("uses-permission"):
            self._permissions.append(str(item.getAttribute("android:name")))
        return self._permissions

    @property
    def main_activity(self):
        """
        Returns:
            the name of the main activity
        """
        x = set()
        y = set()

        for item in self._dom.getElementsByTagName("activity"):
            for sitem in item.getElementsByTagName("action"):
                val = sitem.getAttribute("android:name")
                if val == "android.intent.action.MAIN":
                    x.add(item.getAttribute("android:name"))

            for sitem in item.getElementsByTagName("category"):
                val = sitem.getAttribute("android:name")
                if val == "android.intent.category.LAUNCHER":
                    y.add(item.getAttribute("android:name"))

        z = x.intersection(y)
        if len(z) > 0:
            return z.pop()
        return None


def parse_apk(filename):
    '''
    Returns:
        Manifest(Class)
    '''
    with zipfile.ZipFile(filename, 'r') as file:
        manifest = file.read('AndroidManifest.xml')
    return Manifest(AXMLPrinter(manifest).getBuff())

if __name__ == '__main__':
    m = parse_apk("your-apk.apk")
    print m.version_code


↙↙↙阅读原文可查看相关链接,并与作者交流