Last active
August 19, 2024 07:36
-
-
Save aveuiller/2ccbd7b8a7b229107843fb3f9ac45d64 to your computer and use it in GitHub Desktop.
Extract the Android .odex files and package a new android.jar with the retrieved classes
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
## | |
# Usage: | |
# ./convert.sh /path/to/framework /path/to/out $apiVersion $arch | |
# | |
# $arch is mandatory only in case of an ART system and defines the boot folder to use (arm, x86, x86_64). | |
## | |
frameworkDir=$1 | |
# Final output directory | |
if [ -z $2 ]; | |
then | |
outDir=out | |
else | |
outDir=$2 | |
fi | |
[[ -d $outDir ]] || mkdir -p $outDir | |
# Target API Version, | |
# useful to detect Dalvik/ART platforms | |
if [ -z $3 ]; | |
then | |
apiVersion=15 | |
else | |
apiVersion=$3 | |
fi | |
# Target architecture, | |
# which is needed for ART build | |
if [ -z $4 ]; | |
then | |
arch="x86" | |
else | |
arch=$4 | |
fi; | |
## | |
# Convert *.odex file to smali code, | |
# then build *.dex file back from it. | |
# | |
# The baksmali method we are using will limit us to API 23+ for ART systems | |
# and 20- for Dalvik systems | |
# | |
# There is a no-go zone for API 21 and 22 | |
# See: https://github.com/JesusFreke/smali/issues/392 | |
## | |
function odex2dex { | |
# Inputs | |
odexDir=$1 | |
outputDir=$2 | |
## Workspace dependencies | |
smali="smali.jar" | |
baksmali="baksmali.jar" | |
[[ -f $smali ]] || curl -L https://bitbucket.org/JesusFreke/smali/downloads/smali-2.2.0.jar -o $smali | |
[[ -f $baksmali ]] || curl -L https://bitbucket.org/JesusFreke/smali/downloads/baksmali-2.2.0.jar -o $baksmali | |
if [ $apiVersion -ge 21 ]; then | |
baksmaliCP="boot.oat" | |
frameworkWorkDir="$frameworkDir/$arch" | |
else | |
baksmaliCP=":core.jar:bouncycastle.jar:ext.jar:framework.jar:android.policy.jar:services.jar:core-junit.jar" | |
frameworkWorkDir=$frameworkDir | |
fi | |
# Actual process | |
[[ -d $frameworkWorkDir ]] || $(echo "Boot classpath directory $frameworkWorkDir not found!" && exit 1) | |
for file in $(ls $odexDir/*.odex) | |
do | |
fileName=$(basename $file) | |
libName=${fileName%.*} # Remove the trailing extension | |
libSmali="$outputDir/$libName-smali" | |
dexFile="$outputDir/$libName.dex" | |
echo "Transforming odex lib: $libName (smali: $libSmali - dex: $dexFile)" | |
echo "[DEBUG] cp: $baksmaliCP" | |
# Exctract odex files | |
java -jar $baksmali deodex -a $apiVersion -c $baksmaliCP -d $frameworkWorkDir -o $libSmali $file | |
# Convert the smali files to simple dex files | |
java -jar $smali assemble -a $apiVersion -o $dexFile $libSmali | |
done; | |
} | |
## | |
# Takes decompressed .dex files from $1 | |
# and assemble corresponding .class jar files in $2. | |
## | |
function dex2jar { | |
# Inputs | |
dexDir=$1 | |
outputDir=$2 | |
## Workspace dependencies | |
d2jZip="d2j-2.0.zip" | |
d2jDir="dex2jar" | |
d2jBin="$d2jDir/dex2jar-2.0" | |
d2j="$d2jBin/d2j-dex2jar.sh" | |
chmod +x $d2jBin/*.sh | |
[[ -f $d2j ]] || $(curl -L https://github.com/pxb1988/dex2jar/releases/download/2.0/dex-tools-2.0.zip -o $d2jZip \ | |
&& unzip $d2jZip -d $d2jDir) | |
rm $d2jZip | |
for file in $(ls $dexDir/*.dex); | |
do | |
fileName=$(basename $file) | |
libName=${fileName%.*} # Remove the trailing extension | |
jarFile=$outputDir/$libName.jar | |
echo "Converting dex $file to jar: $jarFile" | |
./$d2j --force -o $jarFile $file | |
done | |
} | |
## | |
# Unzip every .jar file from the $1 dir | |
# and creates a single jar file in the $2 dir. | |
## | |
function bundleAndroidJar { | |
jarInput=$1 | |
outputDir=$2 | |
jarContent="$outputDir/unzippedJars" | |
[[ -d $jarContent ]] || mkdir $jarContent | |
for file in $(ls $jarInput/*.jar) | |
do | |
echo "Adding $file to final jar" | |
unzip -o $file -d $jarContent | |
done; | |
output=android-$apiVersion-custom.jar | |
cd $jarContent && jar cf $output * && cd - | |
mv $jarContent/$output $outputDir | |
} | |
## Defining common work directories | |
# Contains the extracted dex files for each previous jar | |
tmpDex="$outDir/dex2jar-output" | |
[[ -d $tmpDex ]] || mkdir $tmpDex | |
# Contains every final framework jars | |
jarDir="$outDir/jars" | |
[[ -d $jarDir ]] || mkdir $jarDir | |
if [ $apiVersion -ge 21 ]; | |
then | |
## If using ART instead of Dalvik, the framework directory should look like: | |
# framework -- *.jar (stubs) | |
# ├── oat -- API 23+ (!) | |
# │ └── $arch -- *.odex | |
# └── $arch -- boot*.{oat,art} (framework implementation) | |
## | |
echo "Disassembling post Lollipop version, using oat2dex tool" | |
# Currently using v2.2b4 | |
oat2Dex="oat2Dex.jar" | |
[[ -f $oat2Dex ]] || curl -L https://github.com/testwhat/SmaliEx/releases/download/snapshot-s/oat2dex.jar -o $oat2Dex | |
# Contains the raw results of oat2dex | |
tmpO2D="$outDir/oat2dex-output" | |
[[ -d $tmpO2D ]] || mkdir $tmpO2D | |
## There seems to be a bug with oat2Dex no copying all jars | |
bootJar="$tmpO2D/boot-jar-original" | |
[[ -d $bootJar ]] || mkdir $bootJar | |
cp $frameworkDir/*.jar $bootJar | |
# | |
java -jar $oat2Dex -o $tmpO2D devfw $frameworkDir | |
cp $tmpO2D/framework-odex/*.odex $tmpDex | |
cp $tmpO2D/framework-jar-original/*.jar $tmpDex | |
cp $tmpO2D/odex/*.dex $tmpDex | |
cp $tmpO2D/boot-jar-original/*.jar $tmpDex | |
else | |
## If using Dalvik, the framework directory should look like: | |
# framework -- *.{jar,odex} | |
## | |
echo "Disassembling Dalvik image, using baksmali" | |
# This script is assuming that every | |
# *.jar, and *.odex files are in the same folder. | |
## TODO: `find | cp` ? | |
cp $frameworkDir/{*.odex,*.jar} $tmpDex | |
fi; | |
echo "Transforming framework to a single jar (api: $apiVersion, framework: $frameworkDir)" | |
odex2jar $tmpDex $jarDir | |
dex2jar $tmpDex $jarDir | |
bundleAndroidJar $jarDir $outDir |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Updated Links (cURL/wGet compatible):
May 5th 2020: originals
https://repo1.maven.org/maven2/org/smali/smali/2.4.0/smali-2.4.0.jar
https://repo1.maven.org/maven2/org/smali/baksmali/2.4.0/baksmali-2.4.0.jar
https://repo1.maven.org/maven2/org/smali/dexlib2/2.4.0/dexlib2-2.4.0.jar
https://repo1.maven.org/maven2/org/smali/util/2.4.0/util-2.4.0.jar
or
June 4th 2018: oat2dex (v0.90) with modified smali/baksmali (2.2.3-ea9d5c42) to support-multi-dex
https://github.com/testwhat/SmaliEx/releases/download/snapshot/oat2dex.jar
https://github.com/testwhat/SmaliEx/releases/download/snapshot/baksmali.jar
https://github.com/testwhat/SmaliEx/releases/download/snapshot/smali.jar
or
This fork I've just made,
based-on oat2dex 0.90,
but using smali and baksmali latest dirty v2.4.0 source.
It has fat-jar which includes all dependencies, and docs (if that's important for some people).
https://github.com/eladkarako/SmaliEx-DirtyMod/releases
Elad Karako / September 2020.