APK解包与修改

概述

这是我2018年时,在第一家公司时的需求时,开始研究的。
当需要修改apk内的文件,以此切换不同的渠道。所以需要解包和打包的操作。甚至是还考虑过出包含玩家信息的推广包,所以最后连服务器分包的功能都给做出来了。

不过万变不离其宗,掌握好基础的解包和打包就可以了。

工具

工欲善其事必先利其器,解包与二次打包,我们需要使用以下三种工具:

  1. Apktool
  2. JDK
  3. 压缩解压缩工具

ApkTool用于解包与打包。

JDK在我们重新打包之后的签名环节需要使用到。

由于APK就是个压缩包,所以我们也可以使用解压缩工具进行解压来实现解包。不过使用这种方法无法解密Manifest,需要查看或者修改Manifest还需要使用Apktool来进行实现。

使用压缩解压缩工具修改包内文件

如上一章所说,我们可以使用解压再压缩的方式,对包内添加文件,或者修改我们自身创建的文件。

但是,我们在压缩成新的apk之后,需要对apk进行签名。在文章最后的部分中我们会提到。

Windows压缩解压环境布置

Windows不像Linux系统,会提供压缩与解压命令。如果我们需要使用命令行工具来实现分包,就需要准备Windows的压缩解压环境。

如果你是Linux系统或者Mac系统,则可以跳过这一步。

访问http://stahlworks.com/dev/index.php?tool=zipunzip
可以下载zip与unzip的程序。放到C:/windows目录下,即可在命令行中调用压缩加压指令。

# 压缩
zip -r fileName.apk ./*

# 解压
unzip -o -d /path fileName.apk

当然,你也可以在命令行中调用第三方压缩工具来实现这一目的。

命令行数组

如果想要生成一批apk,他们中需要修改的位置都是相同的,只有修改的内容不同。第一时间我们会想到字符串数组。

但是在命令行中是没有数组的,有的文章采用本地文件逐行读取的方法来实现。但我们也可以使用下面的方法来对数组进行模拟:

@echo off
set a[0]=1 
set a[1]=2 
set a[2]=3 
echo The first element of the array is %a[0]% 
echo The second element of the array is %a[1]% 
echo The third element of the array is %a[2]%

注意事项

我们对apk直接解压的操作,实际上没有完成解包的过程,只是一种投机取巧的方式。
如果我们没有删除签名相关内容,会在我们二次打包之后,签名时弹出报错:
jarsigner: java.lang.SecurityException:SHA1 digest error for META-INF/CERT.RSA

因此,我们需要在完成自己所需修改之外,还得删除包内的META-INF目录。

参考:https://stackoverflow.com/questions/37513084/jarsigner-java-lang-securityexceptionsha1-digest-error-for-meta-inf-cert-rsa-a

完整工具

@echo off
setlocal enabledelayedexpansion
rem 拖入apk并获取其路径和文件名
echo 请拖入需要处理的apk
set /p input=
set apkUrl=
for /f "delims=" %%i in ('dir /b %input%') do (set apkUrl=!apkUrl!%%i)
set fileName=%apkUrl:.apk=%
rem 解包并删除签名
if exist output rmdir /s/q output
md output
cd output
md %fileName%
unzip -o -d %fileName% %input%
rmdir /s/q %fileName%\META-INF
rem 修改文件打包并签名
for  do (
[这里填写修改操作]
cd !fileName!
zip -r [your file name].apk ./*
cd..
jarsigner -verbose -keystore [keystore path] -signedjar [out apk name].apk [current apk name].apk [alias name] -storepass [password]
)
pause

使用apktool进行解包与打包

如果你需要查看或者修改Manifest文件,甚至修改java代码,则需要使用apktool进行解包。

以前会有一个叫做Smali2JavaUI的项目,可以直接解包apk,并将smali文件转换成了java代码。但是由于年久失修,已经无法适用于新版的安卓应用了。因此,这里就不再提及。

安装与使用

Apktool是一个jar文件,官网是https://ibotpeaches.github.io/Apktool/
可以参考它的文档进行使用。

但是下载之后你会发现,如果直接使用命令行调用的它的命令,会单独开一个新的窗口,后面的命令行的代码不会顺利执行。
实际上它的命令其实是执行了同目录下的一个bat脚本文件,而且是加了参数的。
所以,在使用apktool时候,我比较推荐直接调用jar包,以解包为例:


java -jar -Duser.language=zh_cn -Dfile.encoding=UTF-8 apktool.jar d [file name] -o [decode path]

如果是直接下载的jar包可以不用管这一步。

我们常用的命令其实就是解包和打包:


apktool d xxx.apk
apktool b xxx

完整工具

#coding=utf-8
 
import os,os.path
from shutil import rmtree
 
def decode_apk(filename, decode_folder):
    if os.path.exists(decode_folder):
        rmtree(decode_folder)
        print "删除已存在的文件夹"+decode_folder
    print "开始解包"+filename+"->"+decode_folder
    apktool_command = "java -jar -Duser.language=zh_cn -Dfile.encoding=UTF8 apktool.jar d " + filename + " -o " + decode_folder
    os.system(apktool_command)
    print "解包成功"+filename+"->"+decode_folder
def build_apk(folder, apk_out):
    if os.access(apk_out,os.R_OK):
        print "删除已存在的"+apk_out
        os.remove(apk_out)
    print "打包中"+apk_out
    apktool_command = "java -jar -Duser.language=zh_cn -Dfile.encoding=UTF8 apktool.jar b " + folder + " -o " + apk_out
    os.system(apktool_command)
    print "打包成功"+apk_out
    

脚本需要和apktool.jar在同一目录下,否则命令中需要指定路径。

签名

二次打包之后的Apk,需要再次签名才能够使用。

签名文件保证

如果你有keystore文件,则可以直接使用。如果是jks文件,可以经过p12文件中转,再转换成keystore文件:


keytool -importkeystore -srckeystore xxx.jks -srcstoretype JKS -deststoretype PKCS12 -destkeystore xxx.p12

keytool -v -importkeystore -srckeystore xxx.p12 -srcstoretype PKCS12 -destkeystore xxx.keystore -deststoretype JKS

如果没有keystore文件,可以使用keytool重新生成。这个工具应该是集成在JDK中的:

keytool -genkeypair -alias serverkey -keypass 111111 -storepass 111111 -dname "C=CN,ST=GD,L=SZ,O=haha,OU=dev,CN=haha.com" -keyalg RSA -keysize 2048 -validity 3650 -keystore server.keystore

可以以借助Android Studio进行生成。

对apk签名

签名需要使用jarsigner工具:

jarsigner -verbose -keystore [keystore path] -signedjar [out apk name].apk [current apk name].apk [alias name] -storepass [password]

签名结束之后,也可以进行验证:

jarsigner -verify [out apk name].apk
  • 33
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值