zoukankan      html  css  js  c++  java
  • mac下自己实现re-sign.jar对apk进行重签名

      利用Robotinum对给的apk文件进行自动化测试,在不知道源码的情况下,只有apk文件如何进行自动化测试呢?

      首先需要对apk文件进行重签名,并获得该apk文件的包名和程序入口的类名。

      最开始网上说用re-sign.jar这个jar包,但是我用mac电脑实验了很多次都不行,一直提示JAVA_HOME环境变量没有设置,可是我已经设置了,echo $PATH输出也能看到JAVA_HOME,不过在Windows系统上实验是好的,可惜我是mac电脑,实验了好几个小时都不行,特别是在真心实意的请教测试的小姑娘帮忙,但是小姑娘不鸟我的情况下,于是一怒之下就自己实现了re-sign.jar的功能。

      通过在Windows上看到的情况,re-sign.jar做了哪些事呢?首先是对已有的apk进行重签名,然后是获得该apk文件的包名和程序入口的类名,为了获得apk文件的包名和入口类名我们需要用到apktool这个工具,因为有些apk是做了混淆的,需要反编译才能得到清晰的AndroidManifest.xml文件。我们知道apk的包名是有这样的标示的: package="xxxxxx",而程序入口类名就是<activity > </activity>标签中包含<xxx.action.MAIN>和<category.LAUCNCH>的部分。这样通过解析Manifest.xml文件,就能获得包名和入口类名了。

      注意:其中需要配置JAVA环境变量,Android环境变量,还需要将apktool所在目录加入到环境变量。该shell脚本需要与apk在同级目录下

      开始动手写shell 脚本。

    #!/bin/bash

    # Program :
    # re-sign to specialy apk
    # History :
    # 2015.9.4 evilking First release

    echo ===============================
    echo 1.将此.sh文件放置您需要签名的apk同级目录下
    echo 2.传入FILE_NAME参数,并设置为需要签名的apk文件名
    echo 3.设置ANDROID_TOOLS_PATH 环境变量 为sdk下的tools路径
    echo 4.设置JDK/bin 环境变量
    echo 5.需要将/Users/你的用户名/.android/debug.keystore复制到apk同级目录下
    echo 5.此脚本是基于JDK1.6来签名的,如果之前的apk不是用此版本签名可能会出血“无法对jar进行签名”的情况,用ZIP工具打开,找到下面的目录META-INF,删除目录
    echo 6.如果出现未提供-tsa或-tsacert的警告,签名指令后加上-tsa https://timestamp.geotrust.com/tsa
    echo ===============================

    #获得当前路径
    Cur_Dir=$(pwd)

    #需要签名的apk文件名
    FILE_NAME=$1

    #验证该apk文件是否存在
    if [ ! -e ${FILE_NAME}.apk ];then
      echo "error: not fount ${FILE_NAME}.apk file"
      exit 1
    fi

    #查看指定apk的签名信息
    echo 查看指定apk的签名信息
    jarsigner -verify -verbose -certs ${Cur_Dir}/${FILE_NAME}.apk | tail -n 10

    #删除掉apk中的签名信息
    echo =================================
    echo 开始删掉apk中的签名信息
    mv ${FILE_NAME}.apk ${FILE_NAME}.zip

    #从zip包中直接删除META-INF文件夹
    zip -d ${FILE_NAME}.zip META-INF/*

    mv ${FILE_NAME}.zip ${FILE_NAME}.apk

    echo 删除META-INF完成
    echo =================================
    #将原来的apk修改回来

    #再次查看_unsign.apk签名信息
    echo =================================
    echo 再次查看_unsign.apk的签名信息
    jarsigner -verify -verbose -certs ${FILE_NAME}.apk | tail -n 10

    #对apk包重新签名
    echo =================================
    echo 对.apk包重新签名

    #检测debug.keystore是否在本目录下
    if [ ! -e debug.keystore ];then
      echo "warning:re-sign need username/.android/debug.keystore file"
      read -p "input your uname : " uname
      cp /Users/${uname}/.android/debug.keystore ./debug.keystore
    fi

    jarsigner -digestalg SHA1 -sigalg MD5withRSA -keystore debug.keystore -storepass android -keypass android ${FILE_NAME}.apk androiddebugkey -tsa https://timestamp.geotrust.com/tsa


    echo ==================================
    echo =========签名成功......开始简化......

    zipalign 4 ${FILE_NAME}.apk ${FILE_NAME}_sign.apk
    echo ============简化签名完成============

    #查看重新签名的apk信息
    echo ===================================
    echo ======查看重新签名后的apk信息==========
    jarsigner -verify -verbose -certs ${FILE_NAME}_sign.apk | tail -n 10

    rm ${FILE_NAME}.apk

    #下面部分是提取该应用的包名和程序入口类名
    echo =======================================
    echo ================开始提取包名=============

    apktool d ${FILE_NAME}_sign.apk &>/dev/null

    echo =============提取包名=================

    package_name=$(egrep "package=".*"" ${FILE_NAME}_sign/AndroidManifest.xml | sed 's/.*package=//g')
    echo "package=$package_name"

    #获取程序入口
    echo =============获取程序入口================
    declare -i last_line
    last_line=$(grep -n "action.MAIN" ${FILE_NAME}_sign/AndroidManifest.xml | cut -d ':' -f 1)

    declare -i first_line
    first_line=$(cat ${FILE_NAME}_sign/AndroidManifest.xml | head -n ${last_line} | egrep -n "<activity" | cut -d ':' -f 1 | tail -n 1)

    echo "程序入口类为:"
    entry_class=$(head -n $last_line ${FILE_NAME}_sign/AndroidManifest.xml | tail -n +$first_line | sed 's/.*android:name="//g' | cut -d """ -f 1 |   head -n 1)
    if [ "$(echo $entry_class | cut -d "." -f 1)" == "" ];then
      echo "$(echo $package_name | sed 's/"//g')$entry_class"
    else
      echo "$entry_class"
    fi

    rm -r ${FILE_NAME}_sign/
    echo ===================结束=============

       整整花了一天的时间,不过值了,久违的成就感啊。

      参考博文:http://blog.csdn.net/h5q8n2e7/article/details/47837653

      

  • 相关阅读:
    LeetCode OJ:Divide Two Integers(两数相除)
    LeetCode OJ:Sqrt(x)(平方根)
    LeetCode OJ:Excel Sheet Column Number(表格列数)
    LeetCode OJ:Compare Version Numbers(比较版本字符串)
    LeetCode OJ:Valid Parentheses(有效括号)
    LeetCode OJ:Longest Common Prefix(最长公共前缀)
    LeetCode OJ:Linked List Cycle II(循环链表II)
    LeetCode OJ:Permutations II(排列II)
    LeetCode OJ:Permutations(排列)
    MongoDB复制二:复制集的管理
  • 原文地址:https://www.cnblogs.com/evilKing/p/4782140.html
Copyright © 2011-2022 走看看