• APK 逆向工程 - 解析 apk 基本信息和方法调用图


    导读

    在 Android 开发中, 我们很少使用 Android 逆向去分析 apk 文件的, 但是作为一个测试人员,我们要对这个 apk 文件进行一系列的分析,审核,测试。这篇文章讲解如何解析一个 apk 文件,主要从下面几方面介绍:

    ● 解析前准备环境介绍

    ● 解析出 apk 的一些基本信息

    ● 解析出方法调用图

    01

    解析前环境介绍

    使用语言:python

    使用的python库androguard

    本章使用的apk文件:自己编写一个apk,apk文件最好不要混淆

    我们先对 APK 文件进行一些简单的介绍

    我们解压一个 apk 文件,解压后的目录如上图所示

    ● META-INF目录

    信息描述,签名等用途。

    ● res 目录

    工程的资源文件,以主工程为主,其他文件(jar包)会合并到该目录下;但values文件将不会出现在此目录下,因为已经将其编译到resource.arsc文件中;raw文件会保持原有内容不会被编译。

    ● resources.arsc

    编译后的二进制资源文件, 在网上查了说,很多做汉化补丁就是修改这个资源包进行汉化的。

    ● classes.dex

    虚拟机执行的文件

    ● AndroidManifest.xml

    清仓文件

    def unzip_file(zip_src, dst_dir):
        print(dst_dir)
        r = zipfile.is_zipfile(zip_src)
        if r:
            fz = zipfile.ZipFile(zip_src, 'r')
            for file in fz.namelist():
            fz.extract(file, dst_dir)
            searchDirFile(dst_dir)
        else:
            print('This is not zip')
    
    

    02

    解析APK的一些基本信息

    from androguard.misc import AnalyzeAPK
    apk, dex, dx = AnalyzeAPK(filePath)
    
    

    这三个对象对应的类别是:下面会分别介绍

    androguard.core.bytecodes.apk.APK
    
    
    androguard.core.bytecodes.dvm.DalvikVMFormat
    
    
    androguard.core.analysis.analysis.Analysis
    
    

    这个 apk 文件对象,其实就是读取 AndroidManifest.xml 文件, 了解过Android 的程序员应该知道,这个文件中就是清仓文件, 我们申请一些权限,注册 Activity, Service, Broadcast,ContentProvader 都在清仓文件中申请。

    特别注意

    我们一般在编写代码的时候,有一些注册文件可能只注册了,但是没有实际的实现,我们在编译项目的时候,这些文件注册虽然会报错,但是不影响编译,运行的时候也不会报错,所以apk只是单纯的读取AndroidManifest.xml 文件,并不会验证读取文件的有效性。解决方法我们下面在具体介绍。

    permissions = apk.get_permissions() # APK 获取权限信息
    activities = apk.get_activities()   # APK 全部的 activity
    service = apk.get_services()        # APK 全部的 service
    receiver = apk.get_receivers()      # APK 全部的 广播
    provider = apk.get_providers()      # APK 全部的 providers
    packagename = apk.get_package()     # 获取当前 APK 的名字
    appname = apk.get_app_name()        # 获取当前 appName
    
    

    03

    解析出方法调用图

    有兴趣可以参考

    https://www.jianshu.com/p/c753184ac90c 
    
    

    我们可以使用 dex 对象, 获取文件中所有类的,所有方法,所有的成员变量和字符串。注意, 这边获取的 dex 对象是一个 list

    看起来很完美了,也可以解决我们上面提到的问题。但是和我们最终目标还有有点远,就是获取的方法调用图。我们最后一个 dx 即将登场。

    classAnalysis = dx.classes['Lcom/example/songzekun/myapplication/MainActivity;']
        for meth in classAnalysis.get_methods():
            for _, call, _ in meth.get_xref_from():
                print("from -> {} -- {}".format(call.class_name, call.name))
            for _, call, _ in meth.get_xref_to():
                print("to -> {} -- {}".format(call.class_name, call.name))
    
    

    from 是方法的调用来源, to 是当前方法中执行了那些方法, 我们可以根据这样的关系, 来构建整个应用的类,方法之间的调用图。

    当然你还需要对一些 api 的方法进行一些过滤。下面代码是我对一些基本信息的过滤,过滤结束后,就是我们真正实现的方法。

    # 我们排除一下
    def screenClass(packagename, activities, service, receiver, provider):
        packagename = packagename.replace('.', '/')
        classAnalysis = dx.get_internal_classes()
        className = []
        activityName = []
        serviceName = []
        receiverName = []
        providerName = []
        for item in classAnalysis:
            if packagename in item.name:
               className.append(item.name)
        for item in activities:
            item = changeClass(item)
            if item in className:
                activityName.append(item)
        for server in service:
            item = changeClass(item)
            if server in className:
                serviceName.append(server)
        for rece in receiver:
            item = changeClass(item)
            if rece in className:
                receiverName.append(rece)
        for pro in provider:
            item = changeClass(item)
            if pro in className:
                providerName.append(pro)
        return className, activityName, serviceName, receiverName, providerName
    
    

    04

    总结

    到这里,我也介绍完毕,总体说来,就是apk的静态扫描技术,我个人就以这些技术做一些应用场景,欢迎大家留言讨论。

    APK 代码结构展示

    精准测试用例推荐

    APK上架自动检测

    根据 APK 文件直接提取代码特征,应用特征,对当前的APK 做分类(比如一些木马病毒的的APK), 对APK进行风险评估, 也可以作APK错误扫描,崩溃预测,敏感权限申请等等。

    来呀!来呀!关注我吧!!

  • 相关阅读:
    【网络安全】文件包含漏洞解析
    Beyong compare 介绍
    uos服务器系统安装达梦8数据库
    CS224W1.1——图机器学习介绍
    【算法基础】数学知识
    从零备战蓝桥杯——动态规划(背包dp篇)
    MYSQL学习之——约束
    【数字通信原理】第三章—信源编码理论
    炫酷转换:Java实现Excel转换为图片的方法
    【MyBatis】五、MyBatis的缓存机制与逆向工程
  • 原文地址:https://blog.csdn.net/Hogwartstester/article/details/126951897