├── README.md ├── apkinfo.sh ├── rebuild.sh └── decompile.sh /README.md: -------------------------------------------------------------------------------- 1 | # APK shell 工具 2 | 3 | * [apkinfo.sh](apkinfo.sh) 查看apk包名、版本和签名信息,依赖aapt和jdk 4 | ``` 5 | ./apkinfo.sh xxx.apk 6 | ``` 7 | 8 | * [decompile.sh](decompile.sh) 快速反编译apk和生成jar,依赖apktool,dex2jar 9 | ``` 10 | ./decompile.sh xxx.apk j #最后的j表示同时使用dex2jar生成jar文件 11 | ``` 12 | 13 | * [rebuild.sh](rebuild.sh) 快速重新打包并签名,需要配置keystore,依赖apktool和jarsigner 14 | ``` 15 | ./rebuild.sh xxx.apk 16 | ``` 17 | 18 | 19 | 在osx上能正常运行。 20 | -------------------------------------------------------------------------------- /apkinfo.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | #需要借助aapt查看包名等信息,aapt命令在android sdk/build-tools/xxx-version/aapt 4 | #最好将这个文件夹加入到环境变量 5 | 6 | 7 | tmpdir=".temp_for_certificate" 8 | mkdir $tmpdir 9 | cd $tmpdir 10 | count=0 11 | while [ -n "$1" ] 12 | do 13 | count=$[$count+1] 14 | 15 | cd ../ 16 | curPath=$1 17 | if [[ $curPath =~ ^//* ]]; then 18 | curPath=$1 19 | else 20 | curPath=`pwd`"/"$1 21 | fi 22 | cd $tmpdir 23 | 24 | echo $curPath 25 | 26 | echo "(#$count) "`basename "$curPath"`":" 27 | echo "" 28 | aapt dump badging $curPath | grep versionCode # 输出apk版本信息 29 | echo "" 30 | path=`jar tf "$curPath" | grep RSA` #查找apk中RSA文件 31 | jar xf $curPath $path #把RSA文件解压出来 32 | keytool -printcert -file $path #查看指纹证书 33 | rm -r $path #删除之前解压的文件 34 | echo "--------------------------------------------" 35 | 36 | shift 37 | done 38 | cd .. 39 | rm -r $tmpdir -------------------------------------------------------------------------------- /rebuild.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #最后生成的签名apk在传入传入文件夹的dist/xxx_rebuild_signed.apk 3 | 4 | #apktool 根目录,可选配置,如果环境变量中有apktool可以不用配置 5 | apktool_path=~/tools/android/apktool 6 | 7 | #keystore 目录,必须配置,用于签名文件 8 | key_store=~/tools/android/demo.keystore 9 | key_store_pwd="123456" 10 | key_alias="mytestkey" 11 | key_alias_pwd="123456" 12 | 13 | 14 | # 判断apktool,优先使用手动配置的,如果没有就提取环境变量中的 15 | if [ ! -x ${apktool_path} ]; then 16 | apktool_path=$(command -v apktool) 17 | if [ ! -x ${apktool_path} ];then 18 | echo '没有找到apktool ! 需要先配置' 19 | exit 1 20 | else 21 | echo '使用环境变量中的apktool' 22 | fi 23 | fi 24 | 25 | # 判断签名文件是否存在 26 | if [ ! -f ${key_store} ];then 27 | echo "keystore 签名文件不存在!" 28 | exit 1 29 | fi 30 | 31 | if [ $# -lt 1 ]; then 32 | echo "输入要重新编译的文件夹路径" 33 | exit 1 34 | fi 35 | 36 | build_dir=$1 37 | 38 | unsign_apk_dir=$build_dir"/dist" #生成未签名 apk 的文件夹路径 39 | 40 | echo "删除 build、dist文件夹" 41 | rm -rf $build_dir"/build" 42 | rm -rf $build_dir"/dist" 43 | 44 | echo "assamble apk" 45 | $apktool_path b $build_dir 46 | 47 | cd $unsign_apk_dir 48 | 49 | find . -type f -name *.apk -print | 50 | 51 | while read myline 52 | do 53 | 54 | compress "$myline" 55 | 56 | unsign_apk_filename=`basename "$myline"` #未签名apk 文件名 57 | 58 | unsign_apk=$unsign_apk_dir"/"$unsign_apk_filename #未签名apk路径 59 | 60 | sign_apk_file=$unsign_apk_dir"/"${unsign_apk_filename%.*}"_rebuild_signed.apk" #签名后生成apk的路径 61 | 62 | #echo "${unsign_apk_filename%.*}" #截取文件名,不要后缀的 63 | 64 | echo "开始签名apk" 65 | 66 | #签名 apk 67 | jarsigner -keystore $key_store -storepass $key_store_pwd -keypass $key_alias_pwd -digestalg SHA1 -sigalg sha1withrsa -signedjar $sign_apk_file $unsign_apk $key_alias 68 | 69 | jarsigner -verify $sign_apk_file #验证签名 70 | 71 | echo "signed apk file: $sign_apk_file" 72 | 73 | #用finder打开文件夹,可选 74 | open $unsign_apk_dir 75 | 76 | done 77 | 78 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /decompile.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 用法 $:./decompile.sh [apk(路径,必须)] -[j(加此参数同时会将dex反编译为jar,可选)] 3 | 4 | #反编译之后文件保存的路径,必须配置 5 | decompile_save_path=~/tools/apk_decompile 6 | #apktool 根目录,可选配置,如果环境变量中有apktool可以不用配置 7 | apktool_path=~/tools/apk 8 | #dex2jar 根目录,可选配置,但是如果使用了j参数则必须配置 9 | dex2jar_path=~/tools/android/dex2jar-2.0 10 | 11 | if [ $# -lt 1 ]; then 12 | echo "至少需要apk文件路径" 13 | exit 1 14 | fi 15 | 16 | if [[ $1 = "h" ]]; then 17 | 18 | echo "第一个参数apk文件路径" 19 | echo "j (可选,同时会将dex反编译为jar)" 20 | exit 0 21 | fi 22 | 23 | 24 | # 判断apktool,优先使用手动配置的,如果没有就提取环境变量中的 25 | if [ ! -x ${apktool_path} ]; then 26 | apktool_path=$(command -v apktool) 27 | if [ ! -x ${apktool_path} ];then 28 | echo '没有找到apktool ! 需要先配置' 29 | exit 1 30 | else 31 | echo '使用环境变量中的apktool' 32 | fi 33 | fi 34 | 35 | curPath=$1 36 | if [[ $curPath =~ ^//* ]]; then 37 | curPath=$1 38 | else 39 | curPath=`pwd`"/"$1 40 | fi 41 | 42 | #检测文件是否存在 43 | if [ ! -f ${curPath} ];then 44 | echo "apk文件不存在" 45 | exit 1 46 | fi 47 | echo "文件验证通过,开始反编译..." 48 | apk=`basename $curPath` #通过路径获取apk文件名 49 | apk=${apk%.*} #截取.apk前的文件名 50 | 51 | 52 | d_dir=$decompile_save_path"/"$apk #反编译之后的路径 已apk文件名区分 53 | if [ -e $d_dir ]; then 54 | echo "删除旧文件..." 55 | rm -rf $d_dir 56 | fi 57 | mkdir $d_dir 58 | #cd $apktool_path 59 | #echo `./apktool if framework-res.apk` 60 | $apktool_path d -f $curPath -o $d_dir #执行apktool的反编译 61 | 62 | #下面开始将用dex2jar 反编译dex文件 63 | if [[ $2 = "j" ]]; then 64 | echo "开始反编译classes.dex文件..." 65 | cd $d_dir 66 | cls=classes.dex 67 | unzip $curPath $cls -d $d_dir #解压apk中的dex文件到工作目录 68 | 69 | cp -f $cls $dex2jar_path 70 | cd $dex2jar_path 71 | 72 | ./d2j-dex2jar.sh --force $cls #开始dex反编译为jar 73 | mv -f $dex2jar_path"/classes-dex2jar.jar" $d_dir 74 | 75 | fi 76 | 77 | echo "反编译 $apk.apk 成功!" 78 | echo "文件保存在 $d_dir" 79 | 80 | # mac osx open finder 81 | open $d_dir 82 | --------------------------------------------------------------------------------