📦

APK に classes.dex を統合するには?(deodex)

に公開

大体のファームウェアでは、CRB Android Kitchen を使えばできますが、有料だし、なんなら正常に deodex 出来ないものもあります。

今回の記事では、smalibaksmali を使用しますが、検索してすぐ出てくるような記事とはやり方が異なります。
それで出来たらこの記事書く意味無いので...

では、解説していきます。


前提

コマンド化して直接実行できるようにしたください。

今回使用するファームウェアは、MTK製の Android 9 です。
知る人ぞ知る、TAB-A05-BA1 です(笑)

解説

フレームワーク

classes.dex化したい人は、APKの手順を参照してください。

まず、framework フォルダ内を全てコピーします。
そして、oatフォルダ内にある全てのアーキテクチャを確認します。
アーキテクチャ毎に順番に smali 化します。

例えば、oat の中が、armarm64 の場合、

cd [FRAMEWORK]
mkdir -p output_smali/

find oat/arm64/ -name "*.odex" -exec sh -c '
    file="$1"
    echo "Processing $file"
    baksmali deodex "$file" -o "output_smali" -d ./arm64
' sh {} \;

find ./arm64/ -maxdepth 1 -name "*.oat" -print0 | while IFS= read -r -d $'\0' oat_file; do
    echo "Processing $oat_file"
    baksmali deodex "$oat_file" -o "output_smali" -d ./arm64
done

これを、armarm64 の両方で行う。
これで output_smali フォルダが作成され、各クラスの中に .smali が作成されるはずです。

ただ、さすがに smali 形式では可読性が壊滅的にゴミなので、これを class 化します。

cd output_smali/
rm -rf java javax dalvik junit
cd ..
smali a output_smali/ -o classes.dex -a 28

更に、jadxdecompiler.com 等でデコンパイル出来るようにしたいので、1つのファイルにまとめます。

zip framework.jar -r classes.dex

これで framework.zip (vdex除く) が出来ます。

ここからはVDEXです。

VDEX

mkdir -p cdex_arm
mkdir -p cdex_arm64

find oat/arm/*.vdex -exec vdexExtractor -i {} -o cdex_arm \;
find oat/arm64/*.vdex -exec vdexExtractor -i {} -o cdex_arm64 \;
find cdex_arm* -name "*.dex" -exec compact_dex_converter {} \;
mkdir -p temp_jar_files
mkdir -p all_classes
mkdir -p final_output

find cdex_arm*/ -name "*.cdex.new" -print0 | while IFS= read -r -d $'\0' dex_file; do
    relative_path=${dex_file//\//_}
    output_jar="./temp_jar_files/${relative_path%.cdex.new}.jar"

    echo "Converting $dex_file to $output_jar"
    dex2jar -f "$dex_file" -o "$output_jar"
    if [ $? -ne 0 ]; then
        echo "Error converting $dex_file"
    fi
done

find ./temp_jar_files/ -name "*.jar" -print0 | while IFS= read -r -d $'\0' jar_file; do
    echo "Extracting $jar_file into ./all_classes/"
    unzip -qo "$jar_file" -d ./all_classes/
done

echo "Creating final combined JAR: ./final_output/combined_framework.jar"
(cd ./all_classes && zip -qr ../final_output/combined_framework.jar .)

rm -rf ./temp_jar_files
rm -rf ./all_classes

APK

APKの場合もほぼ同じです。

Launcher3/
├── Launcher3.apk
└── oat
    └── arm64
        └── Launcher3.odex

このような構造の場合、APK と ODEX を framework にコピーします。
そして、framework にあるアーキテクチャのOATARTをコピーします。
アーキテクチャが複数ある場合は順番に行ってください。

cp -f [APK] [FRAMEWORK]
cp -f [ODEX] [FRAMEWORK]
cd [FRAMEWORK]
cp -f arm64/* .

smali 化します

baksmali x [ODEX]

class 化します

cd out
find -type f -name "*.smali" | while read -r file; do
  smali a $file
  dex2jar out.dex
  unzip -o -qq out-dex2jar.jar
  rm -f out.dex out-dex2jar.jar
done
find -name "*.smali" -exec rm -f {} \;

zip にします

zip classes -r *

ここから手順が異なります。
Android SDK の build-tools に含まれる dx, zipalign, apksigner コマンドを使用します。

dx --dex --output=classes.dex classes.zip

APKに含めたい場合は、

zip [APK] classes.dex
zipalign -pvf 4 [APK] [APK-Aligned]
apksigner --cert [PUBKEY] --key [PRIVKEY] [APK-Aligned]

apksigner の使い方は人によって異なるので各自で署名してください。

Discussion