🌑

脑洞杂货铺

Unity打包的Apk再解包打包签名

Unity打包的Apk再解包打包签名

  • Unity打包出Apk后 可用无需重新Unity打包 修改调整Apk包中默认的素材。
  • 例如:
    • Unity中StreamingAssets下存放的图片、配置文件等可以再不重新Unity打包的情况下替换素材。
  • 简介
    • 先介绍Apk的基础结构。再将Apk中与Unity对应的文件路径进行介绍。有了这些基础就知道在哪里替换素材了。
    • 接着为了替换素材还要把Apk解包,解包替换素材后,还要再重新打包成Apk,最后重新打包的Apk需要签名后才能安装使用。(这里会介绍Unity默认打包时用到的Unity默认打包证书的相关内容)

Apk结构

  • APK是Android Package的缩写,即Android application package文件或Android安装包。其中包含了应用的二进制代码、资源、配置文件等。APK文件其实就是zip格式,但其扩展名被改为apk,在Windows下将apk扩展名改为zip,用解压软件WinRAR/WinZIP/7-Zip可以直接打开。解压后,你会看到有几个文件和文件夹。一个典型的APK文件通常有下列内容组成:
    • AndroidManifest.xml 程序全局配置文件
    • classes.dex Dalvik字节码
    • resources.arsc 编译后的二进制资源文件
    • META-INF\ 该目录下存放的是签名信息
    • res\ 该目录存放资源文件
    • assets\ 该目录可以存放一些配置文件
  • 下面对这些文件和目录做些基本的注释和介绍:
    • AndroidManifest.xml
      • 该文件是每个apk应用程序都必须包含的文件,它描述了应用程序的名字、版本、权限、引用的库文件等等信息。
    • classes.dex文件
      • classes.dex是java源码编译后生成的java字节码文件。dex是Dalvik VM executes的全称,即Android Dalvik执行程序。利用解析工具可以将其转换成java来加以阅读和理解。
    • resources.arsc
      • 编译后的二进制资源文件。在做主题美化时要常与这个文件打交道。
    • META-INF目录
      • META-INF目录下存放的是签名信息,有三个签名文件,用来保证apk包的完整性和系统的安全。在eclipse编译生成一个apk包时,会对所有要打包的文件做一个校验计算,并把计算结果放在META-INF目录下。这就保证了apk包里的文件不能被随意替换。比如拿到一个apk包后,如果想要替换里面的一幅图片,一段代码, 或一段版权信息,想直接解压缩、替换再重新打包,基本是不可能的。如此一来就给病毒感染和恶意修改增加了难度,有助于保护系统的安全。
    • res目录
      • res目录存放资源文件。包括图片,字符串等等。res下有若干个子目录,主要为drawable,layout,xml。
      • 解包后,几乎所有可能的修改和编辑工作基本都在这里。汉化ROM的主要工作就在这里。汉化ROM实际上就是汉化所有的apk应用程序的字符文件。
    • assets目录
      • assets目录可以存放一些配置文件,这些文件的内容在程序运行过程中可以通过相关的API获得。

Unity与Apk

  • 在Unity中StreamingAssets里的文件会在解压后的assets/目录下存放。
    • 例如:
      • 在StreamingAssets中存放Config/config.txt。
      • 那么在apk解压包中会看到此文件被放到了assets/Config/config.txt
  • 通过对应关系可以在解包后的apk中替换在StreamingAssets中存放的素材。
  • 注意:Android平台的StreamingAssets文件夹下的资源都要用WWW或UnityWebRequest的方式获取,无法直接用System.IO.File的各种方法来读取。
  • 例如读取在StreamingAssets下的文本文件:
    using System.Collections;
    using UnityEngine;
    using UnityEngine.Networking;
    using UnityEngine.UI;
    
    public class LoadRes : MonoBehaviour
    {
      public GameObject configText;
      public void Start()
      {
          StartCoroutine(LoadConfigTextCoroutine());
      }
      // 读取配置文件
      private IEnumerator LoadConfigTextCoroutine()
      {
          string path = Application.streamingAssetsPath + "/Config/config.txt";
          using (UnityWebRequest uwr = UnityWebRequest.Get(path))
          {
              yield return uwr.SendWebRequest();
              // 用 configText 这个 GameObject 来显示获取的文本
              configText.GetComponent<Text>().text = uwr.downloadHandler.text;
          }
      }
    }

Apk解包

  • 上面讲到apk是个zip包,可以解压后看到内容。但是其中的文件时被编译过的,所以为了看到原始的内容,就要用工具来解包,也就是说要反编译apk获取到原始内容。
  • 本文使用 ApkTool 作为工具来解包打包apk。
  • 配置ApkTool
    • 根据官方说明中的install章节 配置环境。(下方bat和jar文件以处理好点击云盘下载,提取码:jb39)
      • Windows:
      • 下载批处理文件 apktool.bat
      • 下载 apktool.jar 的最新版,后改名为 apktool.jar
      • 移动两个文件 (apktool.jar & apktool.bat) 到Windows 路径 (通常是 C://Windows)
      • 如果没有放到 C://Windows 需要在系统的环境变量中添加路径。
      • 尝试在终端中运行 apktool
  • 其他平台参考官方文档。
  • 一条命令解包
    $ apktool d bar.apk -o baz
    // decodes bar.apk to baz folder
    // 在baz文件夹中解包bar.apk
    • 解包对比,上图是直接解压,下图是apktool解包的目录:
      解包对比

Apk打包

  • 一条命令打包
    $ apktool d bar.apk -o baz
    // decodes bar.apk to baz folder
    // 在baz文件夹下打包成bar.apk

Apk签名

  • 一条命令签名
    $ jarsigner.exe -verbose -keystore debug.keystore -signedjar TestApkChangedSigned.apk TestApkChanged.apk androiddebugkey
  • 下面解释一下命令:
    • jarsigner是Java的签名工具
    • -verbose参数表示:显示出签名详细信息
    • -keystore表示使用当前目录中的debug.keystore签名证书文件。
    • -storepass 密钥口令 没写这个参数时,会提示输入口令,正常输入口令即可。
    • -signedjar 后跟三个参数:
      • ThinkDrive_signed.apk表示签名后生成的APK名称,
      • ThinkDrive_temp.apk 表示未签名的APK,
      • androiddebugkey表示debug.keystore的别名
  • Unity中的签名
    • 默认如果不设置直接打包出的apk签名使用的是unity默认提供的签名。
      • 默认签名在 C:\User\用户名.android\debug.keystore 这里。
      • 签名的密码是:android
      • 签名的别名是:androiddebugkey
  • 签名信息
    • 可以用 如下命令查看签名信息:
      $ keytool -list -keystore debug.keystore
    • 也可以在解包后查看签名信息:
      • 找到META-INF下的CERT.RSA(密钥信息文件)
        $ keytool -printcert -file CERT.RSA
      • 注:密钥信息在apktool解包后路径在original/META-INF/中。

参考

— 2021年4月9日