Shell腳本 | 健壯性測試之空指針檢查

經過 "adb shell am start" 遍歷安卓應用全部的 Activity,能夠檢查是否存在空指針的狀況。node

如下爲梳理後的測試流程:python

  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

寫了個腳本將以上步驟串了起來。android

運行方式:shell

  • sh +x check_nullpointer.sh

前提條件:bash

  • MacBook
  • python
  • apktool
  • aapt

運行示例:
微信

腳本以下:
check_nullpointer.shapp

#!/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.pydom

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"ui

相關文章
相關標籤/搜索