APK に classes.dex を統合するには?(deodex)
大体のファームウェアでは、CRB Android Kitchen を使えばできますが、有料だし、なんなら正常に deodex 出来ないものもあります。
今回の記事では、smali と baksmali を使用しますが、検索してすぐ出てくるような記事とはやり方が異なります。
それで出来たらこの記事書く意味無いので...
では、解説していきます。
前提
- JDK17 及び Linux
Windows でも PowerShell を使えばできますが、再現が面倒なので書きません。 -
smali と baksmali
https://bitbucket.org/JesusFreke/smali/downloads/ -
dex2jar
https://github.com/pxb1988/dex2jar
コマンド化して直接実行できるようにしたください。
今回使用するファームウェアは、MTK製の Android 9 です。
知る人ぞ知る、TAB-A05-BA1 です(笑)
解説
フレームワーク
classes.dex化したい人は、APKの手順を参照してください。
まず、framework フォルダ内を全てコピーします。
そして、oatフォルダ内にある全てのアーキテクチャを確認します。
アーキテクチャ毎に順番に smali 化します。
例えば、oat の中が、arm と arm64 の場合、
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
これを、arm
と arm64
の両方で行う。
これで output_smali フォルダが作成され、各クラスの中に .smali が作成されるはずです。
ただ、さすがに smali 形式では可読性が壊滅的にゴミなので、これを class 化します。
cd output_smali/
rm -rf java javax dalvik junit
cd ..
smali a output_smali/ -o classes.dex -a 28
更に、jadx や decompiler.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 にあるアーキテクチャのOATとARTをコピーします。
アーキテクチャが複数ある場合は順番に行ってください。
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