修改apk植入動態信息總結

需求背景

作爲遊戲的發行平臺,在遊戲客戶端對接SDK後需要進行不同渠道的分發。(一些小發行沒有自己的渠道,靠自己的經驗選擇一些第三方的渠道進行推送,如媒介通過軟文鏈接、xx渠道合作等)那這個時候發行需要收集一些渠道相關的數據信息,給推廣提供數據依據。爲了區分不同渠道,發行拿到遊戲 apk 後,需要針對各個不同的渠道給apk進行標記,標記apk 就涉及到動態修改apk

【這裏記錄下參考的兩篇文章及實現思路原理】

實現方案

技術點前提:

  • 理解apk 本質上是一個 zip 的歸檔文件

技術要點:

  • 修改apk後,apk文件格式不能損壞、且能正常的被Android安裝、文件驗證通過

參考1:美團Android自動化之旅—生成渠道包

這篇文章中可借鑑二種方案

  • 1、使用 apk-tool 解壓apk 修改 AndroidMainfest.xml 的 meta-data
  • 2、直接修改過apk 在 META-INF 添加空文件,已文件名作爲渠道標記

參考2:一種動態爲apk寫入信息的方案
方案參考:

  • 3、理解zip 的歸檔文件組織的規則,並利用zip 的 comment 區域加入自定義的struct 用來標記自己想要的信息

對比上面的所有方案,方案1:需要apk tool 解析反編譯修改,這導致需要重新簽證 apk 、且執行速度比 方案2、3 都比較慢。方案3 對比2 可能擴展性、安全性更好(能夠自定義自己的數據結構)所有本人的選擇了方案3.

額外說明下:如果對接過騰訊MSDK的可以看到,WGPlatform其中有一接口爲,獲得對應的渠道號:(開發這個需求自然想到以前對接MSDK的獲得渠道接口)

public static String WGGetChannelId()

通過 JD-GUI 反編譯分析可以看到如下代碼:

  public static String WGGetChannelId() {
    return "" + WGPfManager.getInstance().getChannelId();
  }
private String getConfigChannelId() {
    String channel = "";

    Activity act = WeGame.getInstance().getActivity();
    String apkSelfFilePath = act.getPackageCodePath();
    try
    {
      String comment = ApkExternalInfoTool.readChannelId(new File(apkSelfFilePath));
      Logger.d("Comment: " + comment);
      channel = comment;
      if (!CommonUtil.ckIsEmpty(channel))
        return channel;
    }
    catch (IOException e) {
      e.printStackTrace();
      Logger.d("Read apk file for channelId Error");
    }

    channel = readChannelFromIni();
    if (!CommonUtil.ckIsEmpty(channel)) {
      return channel;
    }

    channel = "00000000";
    return channel;
  }

繼續分析可以看到,MSDK 也是利用zip 的 Comment (zip的文件顯示概要)區域進行加入特定信息實現的。

ZIP 文件格學習

wiki 地址:Zip (file format)

zip格式圖概述:

這裏寫圖片描述

這裏有意思的一個點記錄下:

The name “zip” (meaning “move at high speed”) was suggested by Katz’s friend, Robert Mahoney. They wanted to imply that their product would be faster than ARC and other compression formats of the time

zip 的意思 move at high speed 。爲什麼?可以看這的例子

For example, we may start with a .ZIP file that contains files A, B and C. File B is then deleted and C updated. This may be achieved by just appending a new file C to the end of the original ZIP file and adding a new central directory that only lists file A and the new file C. When ZIP was first designed, transferring files by floppy disk was common, yet writing to disks was very time consuming. If you had a large zip file, possibly spanning multiple disks, and only needed to update a few files, rather than reading and re-writing all the files, it would be substantially faster to just read the old central directory, append the new files then append an updated central directory.

新浪博客一篇文章 zip文件格式說明能較說明理解。

這裏用到的重點是 End of central directory record 這裏有 2 兩個字節表示的 comment 內容端的長度。

代碼實現

這裏也只是貼一下github 上一個實現的代碼,可以借鑑實現。
MultiChannelPackageTool

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章