Shell脚本 | 健壮性测试之空指针检查详解程序员

通过 “adb shell am start” 遍历安卓应用所有的 Activity,可以检查是否存在空指针的情况。

以下为梳理后的测试流程:

  1. 通过 apktool 反编译 apk(输入参数 apk 路径)
  2. 得到反编译后的 AndroidManifest.xml 文件
  3. 通过 FindActivity.py 得到 Activity_List(activity 列表)
  4. 删除 Activity_List 中含有 “loader.a.ActivityN1/loader.a.ActivityP0/loader.a.ActivityP1/loader.a.ActivityP2” 的 activity(部分 App 反编译后的 activity 列表中有类似名字的无意义 activity,可以删除)
  5. 运行 NullPointer.py,输出 log 在指定文件夹
  6. 手动分析 log

写了个脚本将以上步骤串了起来。

运行方式:

  • sh +x check_nullpointer.sh

前提条件:

  • MacBook
  • python
  • apktool
  • aapt

运行示例:
Shell脚本 | 健壮性测试之空指针检查详解程序员

脚本如下:
check_nullpointer.sh

#!/usr/bin/env bash 
# 如果有反编译后的文件夹存在,先清空当前环境 
if [[ -d "apkFile" ]]; then 
    rm -r AC_list_filter Activity_List apkFile log.txt all_log.txt 
fi 
# 当前路径 
WORKSPACE=`pwd` 
# apk地址 
echo "Please enter the apk file address:" 
read apk_address 
# 通过aapt获取包名 
pkg_name=$(aapt dump badging ${apk_address} | grep package: | sed 's/ //g' | tr -d $'/r' | cut -d"'" -f2) 
# 通过apktool反编译,反编译后的文件输出到apkFile文件夹 
apktool d ${apk_address} -o apkFile 
# 获取安卓manifest文件 
ANDROID_MANIFEST=${WORKSPACE}/apkFile/AndroidManifest.xml 
# 通过FindActivity.py获取Activity列表 
python FindActivity.py ${ANDROID_MANIFEST} 
# 删除包含"loader.a.ActivityN1/loader.a.ActivityP0/loader.a.ActivityP1/loader.a.ActivityP2"的Activity 
sed '/loader.a.ActivityN1/d;/loader.a.ActivityP0/d;/loader.a.ActivityP1/d;/loader.a.ActivityP2/d' Activity_List > AC_list_filter 
# 运行NullPointer.py,遍历启动activity,输出log在指定文件夹 
echo "Starting..." 
python NullPointer.py ${pkg_name} 
# 全部log 
adb logcat -d -v threadtime > ${WORKSPACE}/all_log.txt 
# error log 
adb logcat -d -v long "AndroidRuntime:E" "*:S" > ${WORKSPACE}/log.txt 
echo "log文件:${WORKSPACE}/log.txt"

FindActivity.py

import xml.dom.minidom as minidom 
import sys 
def find_activities(filePath): 
    xml = minidom.parse(filePath) 
    root = xml.getElementsByTagName('manifest') 
    appNode = None 
    for node in root[0]._get_childNodes(): 
        if(node._get_localName() == "application"): 
            appNode = node 
            break 
    content = '' 
    for item in appNode._get_childNodes(): 
        if(item._get_localName() == 'activity'): 
            content = content + item.getAttribute("android:name") + '/n' 
 
    fs = open("Activity_List", 'w') 
    fs.write(content) 
    fs.close() 
if __name__ == '__main__': 
    filePath = sys.argv[1] 
    find_activities(filePath)

NullPointer.py

#!/usr/bin/env python 
# -*- coding: utf-8 -*-  
import os 
import sys 
import time 
import threading 
# 当前路径 
PATH = sys.path[0] 
# 应用包名 
PKG_NAME = sys.argv[1] 
# 先判断设备是否连接 
os.popen("adb wait-for-device") 
# 遍历文件获得activities 的值 
def CheckNullPoint(): 
    f = open(PATH + "/" + "AC_list_filter", "r") 
    for line in f.readlines(): 
        os.popen('adb shell am start -n %s/%s' % (PKG_NAME, line)) 
        # print("adb shell am start -n %s/%s" % (PKG_NAME, line)) 
    time.sleep(3) 
    f.close() 
# back键退出应用 
def quit_app(): 
    os.popen('adb shell input keyevent 4') 
# 清空log 
def clear_log(): 
    os.popen('adb logcat -c') 
clear_log() 
CheckNullPoint() 
print "Success" 
# back键退出应用 
for i in range(10): 
    quit_app()

欢迎关注微信公众号”测试开发Stack”

原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/6377.html

(0)
上一篇 2021年7月16日
下一篇 2021年7月16日

相关推荐

发表回复

登录后才能评论