Skip to content

Instantly share code, notes, and snippets.

@benbek
Forked from sebfisch/replace-classes-in-apk.sh
Last active January 29, 2019 15:08
Show Gist options
  • Save benbek/60c85f47d69530f214962342e3667542 to your computer and use it in GitHub Desktop.
Save benbek/60c85f47d69530f214962342e3667542 to your computer and use it in GitHub Desktop.
Replaces classes in Android Package Files
#!/bin/sh
# Replaces classes in Android Package Files
# (c) Sebastian Fischer, CC-BY
# Enhanced by Ben Bek
# Can be used to rebuild an App with a modified version of a used library.
exists()
{
command -v "$1" >/dev/null 2>&1
}
if !([ -n "$1" ] && [ -n "$2" ] && [ -n "$3" ] && [ -n "$4" ]); then
echo "Usage: $0 <path to SomeApp.apk> <path to classes.jar> <replaced package path, for example: com/example> <path to private key.jks>"
exit 1
fi
set -e # exit on first error
if ! exists d2j-dex2jar; then
echo "Could not find d2j-dex2jar; please run 'brew install dex2jar'."
exit 1
elif ! exists dx; then
echo "Could not find dx executable; please make sure Android Build Tools are in the path."
exit 1
elif ! exists apksigner; then
echo "Could not find apksigner executable; please make sure Android Build Tools are in the path."
exit 1
fi
APK=$1
JAR=$2
PKG=$3
CLASSESJAR_FILE=classes.jar
echo "De-dexing..."
unzip $APK classes*.dex # extract original classes
for dexfile in classes*.dex; do
filename=${dexfile%.dex}
d2j-dex2jar -f -o ${filename}.jar ${filename}.dex # and convert them to .jar
done
filecount=$(ls -1q classes*.dex | wc -l)
if [ $filecount -eq 1 ]; then
echo "Found one dex file."
else
echo "Found ${filecount} dex files."
for j in *.jar; do
if jar -tvf "$j" | grep -sq $PKG/; then
CLASSESJAR_FILE="$j"
fi
done
fi
rm classes*.dex
unzip $JAR $PKG/* # extract alternative classes
zip -d $CLASSESJAR_FILE "$PKG/*"
jar uvf $CLASSESJAR_FILE $PKG # and replace originals
rm -rf $PKG
echo "Dexing..."
if [ $filecount -eq 1 ]; then # not multidex
d2j-jar2dex -f -o classes.dex $CLASSESJAR_FILE # convert back to .dex
else
dx -JXmx4096M --dex --no-strict --output=temp.zip --multi-dex classes*.jar
unzip temp.zip classes*.dex
rm temp.zip
fi
rm classes*.jar
jar uvf $APK classes*.dex # replace .dex in .apk
rm classes*.dex
mv $APK unsigned.apk
echo "Signing, please enter the password for $4..."
apksigner sign --ks $4 --out $APK unsigned.apk # sign modified .apk
if [ $APK != "unsigned.apk" ]; then
rm unsigned.apk
fi
echo "All done. The signed APK has been written to \x1B[4m$APK\x1B[0m."
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment