如何读取APK的Activity(Python实现)

2020/04/30 08:00
阅读数 765

一、前言

在优化移动端稳定性评测过程中,设定控制特定几个Activity运行monkey是一种提高发现问题效率的方式。那么问题来了,我们如何获取APP完整的Activity List呢?对此,本文简单介绍小编调研和实现的历程,最后使用python脚本实现相关功能。

二、通过什么方式获取Activity

1. adb

adb是我们日常工作每天都会接触的,也是最简单有效。通过adb命令我们可以查看当前手机内应用的包名和Activity信息。常用的命令例如:

adb shell pm list package -f  //查看包名adb shell dumpsys dumpsys activity //查询AMS服务相关信息adb shell logcat | grep android.intent.category.LAUNCHER //logcat日志抓取LAUNCHE

但是基于我们的需求,在配置参数时,不太可能要先连接手机通过adb查找相关信息。

2. appium

在appium的设置页,设置apk包路径就可以解析获取相关的包名和activity信息,如果之前手动需要临时查看部分信息,这是一种非常不错的方式。 

3. 查看源码

查看源码是最直接的方式,有源码,就没有什么看不了的秘密了。

但是并不是所有人都有源码权限。同时,有时候我们需要测试SDK接入第三方应用后的稳定性,也不可能和第三方应用说,请把你的源码给我看看吧。 

4.Android APK逆向解析

通过工具对应用市场的APP进行反编译或者逆向工程,可以从APK中获取相关信息(比如清单文件AndroidManifest.xml里面的package、versionName和versionCode等等)。这里大家都了解,在apk中的AndroidManifest.xml是经过编译的,即是二进制格式,如果直接用编辑器打开,显示会是乱码。只有通过APP反编译获取原始的清单文件AndroidManifest.xml,才能对其进行解析就能方便的获取包名,所有activity等信息。

三、确定获取Activity的思路和技术方案

通过对目标和方法的分析,我们确定的大致思路:实现通过任意市场APP的APK文件,都要能获取应用相关的基本信息。那么,通过脚本封装工具反编译获得原始的清单文件AndroidManifest.xml就能解决这件事情了。

问题又来了:业界有哪些反编译和逆向分析工具呢?

1. apktool

apktool是Android领域反编译最常用的开源工具,可以对AndroidAPK直接进行反编译(也可以在反编译得到的目录基础上进行回编,生成apk)

2.jadx

可以将dex文件和apk文件反编译成可阅读的格式,主要涉及java代码和AndroidManifest.xml查看。同时提供了Python binding-PyJadx,方便当时编写python脚本对目标APK进行反编译。

3.ClassyShark

ClassyShark是google官方为Android开发者推出的独立的二进制文件检查工具,因此其权威性和强大毋庸赘言,且得到较好的维护和更新。其github地址为:[https://github.com/google/android-classyshark],其支持多种文件格式的解析,包括:库文件 (.dex, .aar, .so), 可执行文件 (.apk, .jar, .class) 和所有的Android二进制XML格式文件如AndroidManifest, resources, layouts等等。

4. aapt

Android SDK中自带的aapt工具,可以用于解析APK,包括清单文件AndroidManifest.xml中的信息。aapt工具的功能很强大,子命令和参数非常丰富。同时其功能实现不依赖于GUI,可以将其封装进脚本,用于编写自动化工具去解析和执行,这对于构建自动化测试或者自动打包流程等非常有用。

5. AXMLParser

AXMLParser仅仅是用于解析APK里面的二进制AndroidManifest.xml,从而得到与原始工程里的AndroidManifest.xml内容一致的可读xml。较轻量级,适用于只想查看和AndroidManifest.xml里面包含的信息,比如包名package,versionCode和versionName,启动Activity等。

四、代码如何实现Activity的获取

上述的方法均可以满足我们的需求,由于本次需求只是需要获取AndroidManifest.xml进行信息查看和处理就可以,所以这里使用轻量级的AXMLParser完成AndroidManifest.xml的反编译,进而通过对AndroidManifest.xml的解析获取应用所有的Activity。

1.AXMLPrint的python实现
class AXMLPrinter(object):    def __init__(self, raw_buff):        self.axml = AXMLParser(raw_buff)                self.xmlns = False                self.buff = u''                        while True andself.axml.is_valid():                        _type = self.axml.next()                                    if _type ==START_DOCUMENT:                                self.buff +=u'<?xml version="1.0" encoding="utf-8"?>\n'                        elif _type == START_TAG:                            self.buff += u'<'+ self.getPrefix(self.axml.getPrefix()) + self.axml.getName() + u'\n'                self.buff += self.axml.getXMLNS()                                for i in range(0,self.axml.getAttributeCount()):                     self.buff +="%s%s=\"%s\"\n" % (self.getPrefix(                                               self.axml.getAttributePrefix(i)), self.axml.getAttributeName(i),                        self._escape(self.getAttributeValue(i)))                                            self.buff +=u'>\n'            elif _type == END_TAG:                self.buff +="</%s%s>\n" % (self.getPrefix(self.axml.getPrefix()),self.axml.getName())            elif _type == TEXT:                self.buff +="%s\n" % self.axml.getText()            elif _type ==END_DOCUMENT:                break
解析后的AndroidManifest.xml如下所示
 
2.应用activity获取的python实现
def get_activities(self):    l = []    for i in self.xml:        for item in self.xml[i].getElementsByTagName("activity"):            value = item.getAttributeNS(NS_ANDROID_URI,"name")            value =self.format_value(value)            l.append(str(value))    return l
Activity 获取结果如下所示:

五、结束语

这里简单介绍使用AXMLParser实现方法,使用其他的方法也可以实现相关需求,大家可以尝试实现

搜狗测试微信号

搜狗测试QQ粉丝群



本文分享自微信公众号 - 搜狗测试(SogouQA)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

展开阅读全文
加载中
点击引领话题📣 发布并加入讨论🔥
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部