热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

APKAnalyzer(1):命令行操作体验与功能解析

在对apkChecker进行深入研究后,自然而然地关注到了AndroidStudio中的APK分析功能。将APK文件导入IDE中,系统会自动解析并展示其中各类文件的详细信息。官方文档提供了详细的命令行工具使用指南,帮助开发者快速上手。本文以一个RecyclerView的Adapter代理开源库为例,探讨了如何利用这些工具进行高效的APK分析。

分析过apkChecker之后,很自然的会想起android studio中的APK分析功能,把一个APK文件丢到IDE里面,会自动分析出里面各种文件的信息。官网上也有相关说明—— Analyze your build with APK Analyzer 。从黑盒上讲,两个 工具 都是通过APK文件的输入,获取一堆相关的分析结果出来,那么这两个工具在具体实现上有哪些异同,在同一个功能点上使用了哪些分析工具,整体上的功能对比是什么样的呢。

通过官网上的说明,可以知道相关的命令行工具 apkanalyzer 。既然可以使用命令行工具实现相关的分析功能,那么AS IDE上的功能对应的底层实现,也逃不掉这个命令行工具了。大致根据文档翻一下这个命令工具的功能如下:

  • 展示APK文件属性
    • 简要信息(application ID,版本号,版本名)
    • 大小、需要的features
    • 两个APK文件对比
  • 展示APK文件的整体结构
    • APK内部文件结构树
    • 内部文件内容
  • 展示manifest文件信息
  • 获取dex文件信息
    • 打印dex文件列表
    • 打印dex文件中的方法数
    • 打印dex文件中的类、包关系树
    • 打印dex中某个类、方法的smali代码【m】
  • 展示res文件夹和resources.arsc中的资源文件信息
    • 打印定义在资源表中的包列表
    • 查询指定类型的资源配置列表
    • 根据配置、名称和类型获取资源值
    • 根据配置和类型获取资源名列表
    • 把二进制XML文件的转换成可读的XML文件打印出来【m】

先体验下如何使用。找了一个RecyclerView的Adapter代理开源库 AdapterDelegates 打出来的APK文件做测试。前面三个基本就是把APK文件解压后能获取到的数据,当然其中有解析二进制的manifest文件的功能。这里主要看对dex和resource文件的解析。

dex

  • 打印文件列表,很容易理解,即打印出APK文件中所有dex文件的文件名。也是解压后就能看到的信息

     lee@MacBook-Pro-34   ~/develop/android/android-sdk/tools/bin/apkanalyzer -h dex  list  app-debug.apk
    classes.dex
    
  • 打印指定dex中的方法数,这个就需要解析dex文件中的方法内容了

    lee@MacBook-Pro-34   ~/develop/android/android-sdk/tools/bin/apkanalyzer -h dex  references  app-debug.apk
    classes.dex	19807
    
  • 打印APK中的类、包关系

    如果不指定具体的参数,这个指令输出结果很大。使用重定向的方法把输出结果放到文件中。

    lee@MacBook-Pro-34   ~/develop/android/android-sdk/tools/bin/apkanalyzer -h dex  packages  app-debug.apk > ./packages_result.txt
    

    apkanalyzer(1)-命令使用体验

    可以看到,APK文件也就1.8M,但是其中所有的类/包关系信息会输出3.2M的纯文本内容。打开输出文件,随便找一个开源代码中的类作为关键字,比如AbsListItemAdapterDelegate,可以看到文件输出形式是这样的:

    P d 125 135 16.1KB com.hannesdorfmann.adapterdelegates3

    P d 66 76 9.4KB com.hannesdorfmann.adapterdelegates3.sample

    P d 41 41 4.5KB com.hannesdorfmann.adapterdelegates3.sample.adapterdelegates

    C d 7 7 645B com.hannesdorfmann.adapterdelegates3.sample.adapterdelegates.SnakeListItemAdapterDelegate

    M d 1 1 80B com.hannesdorfmann.adapterdelegates3.sample.adapterdelegates.SnakeListItemAdapterDelegate

    (android.app.Activity)

    M d 1 1 78B com.hannesdorfmann.adapterdelegates3.sample.adapterdelegates.SnakeListItemAdapterDelegate boolean isForViewType(com.hannesdorfmann.adapterdelegates3.sample.model.DisplayableItem,java.util.List,int)

    M d 1 1 74B com.hannesdorfmann.adapterdelegates3.sample.adapterdelegates.SnakeListItemAdapterDelegate boolean isForViewType(java.lang.Object,java.util.List,int)

    M d 1 1 105B com.hannesdorfmann.adapterdelegates3.sample.adapterdelegates.SnakeListItemAdapterDelegate void onBindViewHolder(com.hannesdorfmann.adapterdelegates3.sample.model.Snake,com.hannesdorfmann.adapterdelegates3.sample.adapterdelegates.SnakeListItemAdapterDelegate$SnakeViewHolder,java.util.List)

    M d 1 1 76B com.hannesdorfmann.adapterdelegates3.sample.adapterdelegates.SnakeListItemAdapterDelegate void onBindViewHolder(java.lang.Object,android.support.v7.widget.RecyclerView$ViewHolder,java.util.List)

    M d 1 1 64B com.hannesdorfmann.adapterdelegates3.sample.adapterdelegates.SnakeListItemAdapterDelegate android.support.v7.widget.RecyclerView$ViewHolder onCreateViewHolder(android.view.ViewGroup)

    根据文档,每行的每个输出格式如下:

    Example output (type / state / defined methods / referenced methods / byte size / name)
    
  • 打印dex中某个类、方法的smali代码。这就涉及到把dex中的某个类反编译成smali格式的代码。从上面的输出结果中选一个类,试一下结果:

    lee@MacBook-Pro-34   ~/develop/android/android-sdk/tools/bin/apkanalyzer -h dex code --class com.hannesdorfmann.adapterdelegates3.AbsListItemAdapterDelegate  app-debug.apk > ./class_result.txt
    

    某个类的话还好,只有几KB大小,里面还包括文件本身的成本。截取一段smali瞧瞧:

    .class public abstract Lcom/hannesdorfmann/adapterdelegates3/AbsListItemAdapterDelegate;
    .super Lcom/hannesdorfmann/adapterdelegates3/AdapterDelegate;
    .source "AbsListItemAdapterDelegate.java"
    
    
    # annotations
    .annotation system Ldalvik/annotation/Signature;
        value = {
            "",
            "Lcom/hannesdorfmann/adapterdelegates3/AdapterDelegate",
            "<",
            "Ljava/util/List",
            ";>;"
        }
    .end annotation
    
    
    # direct methods
    .method public constructor ()V
        .registers 1
    
        .prologue
        .line 40
        .local p0, "this":Lcom/hannesdorfmann/adapterdelegates3/AbsListItemAdapterDelegate;, "Lcom/hannesdorfmann/adapterdelegates3/AbsListItemAdapterDelegate;"
        invoke-direct {p0}, Lcom/hannesdorfmann/adapterdelegates3/AdapterDelegate;->()V
    
        return-void
    .end method
    

    因为只是采用了Debug包,没有配置混淆。所以这两个命令测试拿到的结果可读性都还好。如果是混淆后的包,可以使用【—proguard】相关参数,传入mapping等相关文件做解析映射。

resource

所谓资源文件解析,实际上就是对 resources.arsc的解析。可以参考网上一些解析arsc的博客,了解下文件结构和定义说明。

Android resources.arsc的解析

resources.arsc解析

  • 打印定义在资源表中的包名列表【1】

    lee@MacBook-Pro-34   ~/develop/android/android-sdk/tools/bin/apkanalyzer -h resources packages  app-debug.apk
    com.hannesdorfmann.adapterdelegates.sample
    

    关于包列表,上面引用的arsc相关文章有说明。一般的应用只有一个包名。

  • 查询指定类型的资源配置列表【2】

    lee@MacBook-Pro-34  ~/develop/temp/apkanalyzer  ~/develop/android/android-sdk/tools/bin/apkanalyzer -h resources configs --type layout  app-debug.apk
    default
    v11
    v13
    v16
    v17
    v21
    v22
     lee@MacBook-Pro-34  ~/develop/temp/apkanalyzer  ~/develop/android/android-sdk/tools/bin/apkanalyzer -h resources configs --type drawable  app-debug.apk
    default
    v11
    v21
    v23
    xhdpi-v4
    xxhdpi-v4
    ldrtl-xxhdpi-v17
     lee@MacBook-Pro-34  ~/develop/temp/apkanalyzer  ~/develop/android/android-sdk/tools/bin/apkanalyzer -h resources configs --type string  app-debug.apk
    default
    ca
    da
    sw
    bs-rBA
    fr-rCA
    lo-rLA
    

    截取部分结果如上。type都有哪些呢,不去看arsc文件数据结构的话,凭借开发经验也可以猜出一二。源代码目录res里面找找大概就可以了,诸如layout、drawable、string这些都属于类型,返回的则是应用包含这些资源类型的各个子文件夹列表,比如string类型,就返回所有字符串资源的语种,对应的则是源码中不同values文件夹的后缀名。这些返回结果,对应的就是后面命令需要使用的configs。

  • 根据配置、名称和类型获取资源值【3】

     ✘ lee@MacBook-Pro-34 ~/develop/android/android-sdk/tools/bin/apkanalyzer -h resources value --name item_unknown_reptile --config default --type layout  app-debug.apk
    res/layout/item_unknown_reptile.xml
    

    这个功能在文档上会有些倒置的感觉,因为要先知道资源名是什么,才能传 —name 的参数。从结果上看,返回的是在解压后res目录下的文件路径。

  • 根据配置和类型获取资源名列表【4】

    lee@MacBook-Pro-34  ~/develop/temp/apkanalyzer  ~/develop/android/android-sdk/tools/bin/apkanalyzer -h resources names --config default  --type layout  app-debug.apk
    abc_action_bar_title_item
    abc_action_bar_up_container
    abc_action_bar_view_list_nav_layout
    abc_action_menu_item_layout
    

    截取部分结果如上。这里获取指定config、指定type下的资源文件名列表。

  • 把二进制XML文件的转换成可读的XML文件打印出来【5】

     lee@MacBook-Pro-34  ~/develop/android/android-sdk/tools/bin/apkanalyzer -h resources xml --file res/layout/item_unknown_reptile.xml  app-debug.apk
    
    
    

    xml功能对应的参数实际上是第【3】个命令获取的文件路径。该命令会把指定的资源文件,解析成可读的xml文件。或者可以说resource这一系列命令,最终的目的就是定位到文件,然后解析成xml格式。

小结

草草体验了一遍工具功能之后,再对比下AS上的分析功能。基本上对apkanalyzer有一个简单的认知。

  • 解压能力
  • 解析dex文件
  • 解析xml文件

跟apkChecker相比,apkanalyzer会纯粹一点。它只是解析APK文件本身有哪些东西,没有做进一步的静态质量类的分析。当然,最终的解析姿势可能不一样,但是原理都是一样的——根据APK文件内部结构的特点、dex&arsc文件的数据结构,来反编译得到结果。

后面会简单走读下apkanalyzer的实现原理。


以上所述就是小编给大家介绍的《apkanalyzer(1)-命令使用体验》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 我们 的支持!


推荐阅读
  • 为了优化直播应用底部聊天框的弹出机制,确保在不同设备上的布局稳定性和兼容性,特别是在配备虚拟按键的设备上,我们对用户交互流程进行了调整。首次打开应用时,需先点击首个输入框以准确获取键盘高度,避免直接点击第二个输入框导致的整体布局挤压问题。此优化通过调整 `activity_main.xml` 布局文件实现,确保了更好的用户体验和界面适配。 ... [详细]
  • 在 Linux 系统中,`/proc` 目录实现了一种特殊的文件系统,称为 proc 文件系统。与传统的文件系统不同,proc 文件系统主要用于提供内核和进程信息的动态视图,通过文件和目录的形式呈现。这些信息包括系统状态、进程细节以及各种内核参数,为系统管理员和开发者提供了强大的诊断和调试工具。此外,proc 文件系统还支持实时读取和修改某些内核参数,增强了系统的灵活性和可配置性。 ... [详细]
  • 深入解析 Android Drawable:第六阶段进阶指南 ... [详细]
  • Android ListView 自定义 CheckBox 实现列表项多选功能详解
    本文详细介绍了在Android开发中如何在ListView的每一行添加CheckBox,以实现列表项的多选功能。用户不仅可以通过点击复选框来选择项目,还可以通过点击列表的任意一行来完成选中操作,提升了用户体验和操作便捷性。同时,文章还探讨了相关的事件处理机制和布局优化技巧,帮助开发者更好地实现这一功能。 ... [详细]
  • 如何在Android应用中设计和实现专业的启动欢迎界面(Splash Screen)
    在Android应用开发中,设计与实现一个专业的启动欢迎界面(Splash Screen)至关重要。尽管Android设计指南对使用Splash Screen的态度存在争议,但一个精心设计的启动界面不仅能提升用户体验,还能增强品牌识别度。本文将探讨如何在遵循最佳实践的同时,通过技术手段实现既美观又高效的启动欢迎界面,包括加载动画、过渡效果以及性能优化等方面。 ... [详细]
  • 掌握DSP必备的56个核心问题,我已经将其收藏以备不时之需! ... [详细]
  • 在Java应用程序中调用`response.getStatus()`方法时遇到了`NoSuchMethodError`异常,经过分析,初步判断为依赖冲突问题。通过检查项目依赖树发现,当前项目版本与某些库的版本不兼容,导致该方法无法被正确识别。建议通过更新相关依赖版本或使用依赖管理工具(如Maven或Gradle)来解决此问题,确保所有依赖项版本一致且兼容。 ... [详细]
  • 在自定义Android CheckBox时,可以通过设置 `android:button="@null"` 来隐藏默认的选择框,同时使用 `android:textColor="@drawable/selector_text"` 来实现文本选中状态的颜色变化。本文详细介绍了这两种方法的具体实现步骤,并提供了示例代码,帮助开发者更好地理解和应用这些技巧。此外,文章还探讨了其他一些常用的自定义属性和最佳实践,以提升用户体验和界面美观度。 ... [详细]
  • DHCP三层交换机设置方式全局模式和接口模式设置方式和命令resetsave回车输入yreboot输入n输入y重启后就恢复默认设置了默认用户名密码adminAdmin@huawei ... [详细]
  • 本文提供了 RabbitMQ 3.7 的快速上手指南,详细介绍了环境搭建、生产者和消费者的配置与使用。通过官方教程的指引,读者可以轻松完成初步测试和实践,快速掌握 RabbitMQ 的核心功能和基本操作。 ... [详细]
  • 在MFC开发过程中,利用Windows内置的文件对话框可以显著提高文件操作的效率。本文总结了使用文件对话框进行文件选择和处理的经验,详细介绍了相关API的调用方法和参数设置,如`CFileDialog`类的使用、结构体`OPENFILENAME`的配置以及如何获取选中的文件路径。通过这些技巧,开发者可以快速实现文件的打开、保存等功能,提升应用程序的用户体验。 ... [详细]
  • 本文探讨了将PEBuilder转换为DIBooter.sh的方法,重点介绍了如何将DI工具集成到启动层,实现离线镜像引导安装。通过使用DD命令替代传统的grub-install工具,实现了GRUB的离线安装。此外,还详细解析了bootice工具的工作原理及其在该过程中的应用,确保系统在无网络环境下也能顺利引导和安装。 ... [详细]
  • 在Windows环境中优化提交Spark任务的方法与实践
    在Windows环境中优化提交Spark任务的方法与实践 ... [详细]
  • 本文深入探讨了 C# 中 `SqlCommand` 和 `SqlDataAdapter` 的核心差异及其应用场景。`SqlCommand` 主要用于执行单一的 SQL 命令,并通过 `DataReader` 获取结果,具有较高的执行效率,但灵活性较低。相比之下,`SqlDataAdapter` 则适用于复杂的数据操作,通过 `DataSet` 提供了更多的数据处理功能,如数据填充、更新和批量操作,更适合需要频繁数据交互的场景。 ... [详细]
  • 在 Linux 环境下,深入探讨 GTK+3.0 的高级开发技巧,涵盖组件定制、事件处理及多线程应用等核心内容,帮助开发者提升应用界面的交互性和性能。 ... [详细]
author-avatar
迎风拂忆_768
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有