1. 程式人生 > >安卓app原始碼的獲取

安卓app原始碼的獲取

反編譯有一種方式是

  1. 把dex檔案從apk解壓出來,得到classes.dex
  2. 然後用dex2jar把dex檔案轉換成jar檔案: dex2jar.bat classes.dex
  3. 再把生成的classes.jar檔案放到JD-GUI中即可

仍然報錯

dex2jar .\classes.dex -> .\classes-dex2jar.jar
com.googlecode.d2j.DexException: not support version.
        at com.googlecode.d2j.reader.DexFileReader.<init>(DexFileReader.java:151)
        at com.googlecode.d2j.reader.DexFileReader.<init>(DexFileReader.java:211)
        at com.googlecode.dex2jar.tools.Dex2jarCmd.doCommandLine(Dex2jarCmd.java:104)
        at com.googlecode.dex2jar.tools.BaseCmd.doMain(BaseCmd.java:288)
        at com.googlecode.dex2jar.tools.Dex2jarCmd.main(Dex2jarCmd.java:32)

提示not support version,版本不支援?(看到這條資訊我還以為要下載最新版本的dex2jar,結果仍然不行)

此時想到乾脆編譯下dex2jar的相關檔案看看為什麼報錯 開啟dex2jar-2.0\lib目錄,因為是reader.DexFileReader.<init> 處報錯,所以應該是DexFileReader初始化報錯吧,應該是dex-reader-2.0.jardex-reader-api-2.0.jar把這兩個jar包扔到jdgui裡面,很快便找到DexFileReader,並在構造方法裡面,並找到相關原始碼

public DexFileReader(ByteBuffer in)
  {
    in.position(0);
    in = in.asReadOnlyBuffer().order(ByteOrder.LITTLE_ENDIAN);
    int magic = in.getInt() & 0xFFFFFF;
    if (magic != 7890276)
    {
      if (magic == 7955812) {
        throw new DexException("Not support odex");
      }
      throw new DexException("not support magic.");
    }
    int version = in.getInt() & 0xFFFFFF;
    if ((version != 3486512) && (version != 3552048)) {//這裡主動丟擲異常
      throw new DexException("not support version.");
    }
    ....
}

可以猜測這在讀取第一個字元時通過比較version 值主動丟擲異常了 顯然version不等於3486512和3552048是罪魁禍首,它們是什麼呢,上下搜尋可以看到一個定義的常量:

  private static final int MAGIC_035 = 3486512;
  private static final int MAGIC_036 = 3552048;

額,MAGIC_035MAGIC_036,網上查了一下,說是dex頭部校驗

老版本的magic version是035 優化的dex檔案,magic version是036 報錯居然說不等於這兩個,是什麼情況???

用notpad++開啟classes.dex檔案,在頭部看到如下情況

dex頭部

第二行竟然是037!!!!嗯,我有一個大膽的想法: 把037,改成036,儲存,再用dex2jar 成功!!!再用jd-gui開啟jar檔案也能順利反編譯

遺留思考:

  1. magic version是dex校驗的話,為什麼gts的apk為是037一個不合法的值?難道這個apk比較特殊?(實際驗證這個apk安裝不上)
  2. 為什麼讀到的int值3552048,而通過notepad++顯示是036?(猜測與字元編碼有關)