Skip to content

Instantly share code, notes, and snippets.

@aveuiller
Last active May 12, 2024 14:38
Show Gist options
  • Save aveuiller/2ccbd7b8a7b229107843fb3f9ac45d64 to your computer and use it in GitHub Desktop.
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
#!/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
Copy link

ghost commented Sep 12, 2020

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment