我的知识来源于我的老师,我的博客文章来源于我的学习笔记
APK包状态检查
1、为什么进行产品状态检查?
实际工作中,测试QA经常被问到,当前测试的apps是什么版本?什么环境?是否混淆?渠道号是多少?什么签名?等一些列问题。经常记不住,如何自动化持续集成的手段来解决问题
版本号如何获得?
发布之后,再反编译之后,AndroidManifest.xml中找到
“android:versionCode="1", android:versionName="1.0.0"”
由于工作交叉性,混淆等操作,应该在APK成型之后拿到的版本号才是真正发布给用户的版本号。
情景1、开发检查没有问题,但是安装APK后就没有版本号,那么要确定成型后的apk包到底有没有变更版本号
2、Ubuntu下进行AndroidManifest.xml分析
2.1打开shell窗口
由图形界面到文字界面 Ctrl + Alt + F1
由文字界面到图形界面 Ctrl + Alt + F7
2.2Ubuntu下的网络设置
ubuntu重启网络跟Red Hat不同,命令:
sudo /etc/init.d/networking restart
2.3安装java的jdk
./jdk.bin
然后修改etc/profile文件增加环境变量
export PATH=/usr/soft/jdk1.5.0_06/bin:$PATH
export JAVA_HOME=/usr/soft/jdk1.5.0_06
然后source /etc/profile立即生效,所有连接的用户必须重新连接才能生效
2.4拷贝apktool工具到linux中
拷贝aapt ,apktool,apktool.jar到实验目录
增加可执行权限chmod a+x aapt apktool之后
执行./apktool d ColaBox-release-unsigned.apk 生成反编译后的文件夹
2.4进入ColaBox-release-unsigned目录抽取关键字
命令:cat ColaBox-release-unsigned/AndroidManifest.xml | grep -e versionCode | awk '{print $2 "\n" $3}'
反编译时可以用 apltool d xx.apk /temp/bukw/xx将xx.apk 反编译到指定目录中
因此完整的checkapkitem.sh脚本内容:
cd temp/bukw ./apktool d xx.apk /temp/bukw/xx将xx.apk cd xx cat ColaBox-release-unsigned/AndroidManifest.xml | grep -e versionCode | awk '{print $2 "\n" $3}' >> checkapkitemresults.txt |
将结果输入到结果文件中(xxx.txt)
2.5检查签名
声明:这里借用了58同城最新版本的app,只用作测试学习使用,无其他目的。
jarsigner -verify 58client_v5.0.0.5_3.apk
linux下不需要加“.”就可以执行。
jarsigner用法参考文章:
-verify 如果它出现在命令行中,则指定的 JAR 文件将被校验,而不是签名。如果校验成功,将显示“jar verified”。如果试图校验未签名的 JAR 文件,或校验被不支持的算法(例如未安装 RSA 提供者时使用的 RSA)签名的 JAR 文件,则将有如下显示: "jar is unsigned. (signatures missing or not parsable)" 。
用grep -c来统计匹配的行数
grep -c 的作用类似grep | wc -l,不同的是,如果是查找多个文件,grep -c会统计每个文件匹配的行数,每行一个文件的列出来,而wc -l 则列出总的统计数字。
另外grep -c 要比 grep | wc -l快一点
#/bin/sh cd /home/mhc/temp/ziyu/ic myFile="checkapkstatus.txt" if [ -f "$myFile" ]; then rm -rf "$myFile" fi
/home/mhc/temp/ziyu/apktool-install-linux-r05-ibot/apktool d /home/mhc/temp/ziyu/ic/ColaBox-release-unsigned.apk cat ColaBox-release-unsigned/AndroidManifest.xml | grep android:version | awk '{print $2,$3}' >> checkapkstatus.txt NUM=`jarsigner -verify -verbose -certs ColaBox-release-unsigned.apk | grep -c unsigned` if [ ${NUM} -ge 0 ];then echo "no signature" >> checkapkstatus.txt else echo "has a signature" >> checkapkstatus.txt NUM1=`jarsigner -verify -verbose -certs ColaBox-release-unsigned.apk | grep -c Debug` if [ ${NUM1} -ge 0 ];then echo "online signature" >> checkapkstatus.txt else echo "debug signature" >> checkapkstatus.txt fi fi |
补充:渠道号
发布之前需要发布小渠道的版本,比如使用木蚂蚁市场(只有5W个用户,占全体用户1000W的比例很小),功能是木蚂蚁市场下载的apk具有升级提示,其他渠道号的apk不会得到提示。必定有个位置上会标记一个渠道号
补充场景:
打包一次需要一定的时间,如果渠道有上百个则会很消耗时间。应该如果操作呢?
Assert目录里面的内容不会被编译,因此将渠道号文件加入这个目录。
作业:找到区分渠道号的方法,然后for循环就可以把渠道号加入到Assert目录中指定文件
2.6、是否允许动态调试(不允许才安全)
修改AndroidManifest.xml文件,在Application标签内加入android:debuggable=“false”,阻止程序调试模式。
命令:
cat AndroidManifest.xml | grep "android:debuggable "
进阶命令,只显示想要的“android:debuggable”:
cat AndroidManifest.xml | grep "android:debuggable" | awk '{print $NF}'|awk -F\> '{print $1}
2.7、检查当前产品的环境
包含测试,预发,上线环境
a) 查看配置文件,会写出哪种环境
b) 有程序开关在代码中进行动态开关,判断线上线下环境。
补充:环境配置最好不要写到代码中,否则QA不容易测试,应该是通过外部配置来选择线上还是线下。
客户端内自身的配置文件,位置可能随意,
实例1:app设计多个部门发布,其中有个部门提供的借口坏掉,但无人关心。如何推进工作?
fildder工具可以抓包,弱网,可以设置代理。
实例2、通过显示不同接口的线上还是线下环境,可以判断出数据来源(线上还是线下),因此可以判断自身服务和依赖服务都是线下,预发还是线上。
例如发版前和发版后的各种配置不一致导致错误的发生。
如果在配置文件中进行配置,则容易检查。
实例3、配置环境代码在代码中写死,如何判断代码中的环境配置?
如果用反编译,则smali语言不熟悉的情况下则很困难,因此应该精准定位代码中具备配置信息的类文件,进行阅读代码检查。
2.8、检查是否混淆
防止被其他人反编译,才使用混淆技术。查看类名和包名如果变成了单一字符,则
com.58.zhaopin.abc混淆之后变为com.a.b.c则证明被混淆。
经验:混淆后的包体积比混淆前小,因为名字变短,所以体积变小。
1、检查文件体积大小
bukw@bukw:~/temp/bukw$ du 58client_v5.0.0.5_3.apk
15264 58client_v5.0.0.5_3.apk
bukw@bukw:~/temp/bukw$ du -h 58client_v5.0.0.5_3.apk
15M 58client_v5.0.0.5_3.apk
2、按字母排序文件(这是一个错误方法)
命令:
ll|sort -k 7 | head -7
注意:此方法不能证明APK包是被混淆的,另外找到混淆文件proguard-project.txt也不能证明是混淆的,因为这个文件只有在被编译之前有效,编译的时候可以进行替换。
3、DextoJar工具
如何将apk反编译,如何将dex文件转换为jar文件,请参考以前的笔记(大概是第三课笔记)
unzip -v xxx.jar显示jar包下class的目录结构,从其中看到命名极其简单的二进制文件,即可以确定apk是否被混淆
在Jenkins集成中的Archive the artifacts中增加,**/a.txt
a.txt是测试结果保存的文件,正式的测试光靠简单过滤脚本是会出现漏测情况,除非能够统计命名简单的class文件占所有class文件的百分比,且还得有个百分比做标准才行。