Skip to content

Instantly share code, notes, and snippets.

@DayS
Created May 9, 2019 11:50
Show Gist options
  • Save DayS/1c7bcf7ee943381f44138a7773af893f to your computer and use it in GitHub Desktop.
Save DayS/1c7bcf7ee943381f44138a7773af893f to your computer and use it in GitHub Desktop.
apk-debuggable
#!/bin/sh
function usage(){
printf "Make APK debuggable.\n"
printf "Usage: $0 [options]\n"
printf "\t-f,--file <path> : Direct path to an APK to make debuggable\n"
printf "\t-i,--id <package_name> : Identifier of an APK to pull from device\n"
}
if [ $# -eq 0 ]; then
usage
fi
# Declare alias for sed to make it compatible in both Mac and Unix OS
darwin=false;
case "`uname`" in
Darwin*) darwin=true ;;
esac
if "$darwin"; then
alias sed_regexp="sed -E"
else
alias sed_regexp="sed -r -e"
fi
# Retrieve zipalign binary from Android SDK
if [ -z "$ANDROID_HOME" ]; then
echo "You must set a ANDROID_HOME environment variable referencing Android SDK folder"
exit 1;
fi
ANDROID_BUILD_TOOLS_VERSION=`ls $ANDROID_HOME/build-tools | tail -1`
ZIPALING_PATH="$ANDROID_HOME/build-tools/$ANDROID_BUILD_TOOLS_VERSION/zipalign"
function pullFromDevice() {
APK_ID="$1"
echo ">> Search an APK on device matching id $APK_ID"
APK_MATCHES=`adb shell pm list packages -f | grep "$APK_ID"`
if [ `echo "$APK_MATCHES" | wc -l` -gt 1 ]; then
echo "Too many results:"
echo "$APK_MATCHES"
exit 1;
fi
APK_DEVICE_PATH=`echo "$APK_MATCHES" | sed_regexp 's/^package:(.+\.apk).*/\1/'`
APK_DEVICE_ID=`echo "$APK_MATCHES" | sed_regexp 's/.*=([^=]+)$/\1/'`
echo ">>> Found APK $APK_DEVICE_ID at $APK_DEVICE_PATH"
APK_LOCAL_PATH="$APK_DEVICE_ID.apk"
echo ">> Pulling APK to $APK_LOCAL_PATH"
adb pull "$APK_DEVICE_PATH" "$APK_LOCAL_PATH"
if [ $? -ne 0 ]; then
echo "ERROR while pulling APK"
exit 1
fi
}
function makeDebuggable() {
APK_INPUT_PATH="$1"
APK_RECOMPILED_PATH=`echo "$APK_INPUT_PATH" | sed 's/\.apk/.debuggable.apk/'`
APK_ALIGNED_PATH=`echo "$APK_RECOMPILED_PATH" | sed 's/\.apk/.aligned.apk/'`
APK_DECOMPILE_PATH="$APK_INPUT_PATH.out"
echo ">> Decompiling APK from $APK_INPUT_PATH"
apktool d -f -o "$APK_DECOMPILE_PATH" "$APK_INPUT_PATH"
if [ $? -ne 0 ]; then
echo "ERROR while decompiling APK"
exit 1
fi
allowUserCertificates "$APK_DECOMPILE_PATH"
echo ">> Recompiling APK to $APK_RECOMPILED_PATH"
apktool b --debug --no-crunch -o "$APK_RECOMPILED_PATH" "$APK_DECOMPILE_PATH"
if [ $? -ne 0 ]; then
echo "ERROR while recompiling APK"
echo "Try again after running : apktool empty-framework-dir --force"
exit 1
fi
echo ">> Signing APK"
CERT_PATH="$APK_DECOMPILE_PATH/resign.keystore"
CERT_ALIAS="alias_name"
CERT_PASS="recompiled"
if [ ! -f "$CERT_PATH" ]; then
echo ">>> Generating certificate"
keytool -genkey -v -keystore "$CERT_PATH" -alias "$CERT_ALIAS" -keyalg RSA -keysize 2048 -validity 10000 -dname "CN=Unknown, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown" -storepass "$CERT_PASS" -keypass "$CERT_PASS"
if [ $? -ne 0 ]; then
echo "ERROR while generating certificate"
exit 1
fi
fi
echo ">>> Signing APK with certificate"
jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore "$CERT_PATH" -storepass "$CERT_PASS" -keypass "$CERT_PASS" "$APK_RECOMPILED_PATH" "$CERT_ALIAS"
echo ">>> Aligning APK"
$ZIPALING_PATH -f -v 4 "$APK_RECOMPILED_PATH" "$APK_ALIGNED_PATH"
if [ $? -ne 0 ]; then
echo "ERROR while aligning APK"
exit 1
fi
rm -f "$APK_RECOMPILED_PATH"
echo ">> Done. Install apk with : adb install -f $APK_ALIGNED_PATH"
}
function allowUserCertificates() {
APK_DECOMPILED_PATH="$1"
MANIFEST_FILE="$APK_DECOMPILED_PATH/AndroidManifest.xml"
echo ">> Allowing User's SSL certificates"
mkdir -p "$APK_DECOMPILED_PATH/res/xml"
EXISTING_NETWORK_SECURITY_CONFIG=`grep -E 'android:networkSecurityConfig="@xml/([a-zA-Z0-9_]+)"' -o "$MANIFEST_FILE" | sed -E 's#.*@xml/([a-zA-Z0-9_]+).*#\1#'`
if [ ! -z "$EXISTING_NETWORK_SECURITY_CONFIG" ]; then
NETWORK_SECURITY_CONFIG_FILE="$APK_DECOMPILED_PATH/res/xml/$EXISTING_NETWORK_SECURITY_CONFIG.xml"
echo ">>> Found existing and used network security file : $NETWORK_SECURITY_CONFIG_FILE"
EXISTING_DEBUG_NODE=`grep "<debug-overrides>" "$NETWORK_SECURITY_CONFIG_FILE"`
if [ ! -z "$EXISTING_DEBUG_NODE" ]; then
echo ">>> Found debug-overrides XML tag"
# Because we're making a replacement on multiline, we can't use 'sed' command
mv "$NETWORK_SECURITY_CONFIG_FILE" "$NETWORK_SECURITY_CONFIG_FILE.bck"
cat "$NETWORK_SECURITY_CONFIG_FILE.bck" | tr -d '\n' | sed_regexp -e $'s#(</trust-anchors>[\s\t]*</debug-overrides>)#<certificates src="user" />\\1#' > "$NETWORK_SECURITY_CONFIG_FILE"
rm "$NETWORK_SECURITY_CONFIG_FILE.bck"
else
sed_regexp -i '' -e 's#(</network-security-config>)#<debug-overrides><trust-anchors><certificates src=\"user\" /></trust-anchors></debug-overrides>\1#' "$NETWORK_SECURITY_CONFIG_FILE"
fi
else
NETWORK_SECURITY_CONFIG_FILE="$APK_DECOMPILED_PATH/res/xml/network_security_config.xml"
echo ">>> Creating network security file : $NETWORK_SECURITY_CONFIG_FILE"
echo "<network-security-config>
<debug-overrides><trust-anchors><certificates src=\"user\" /></trust-anchors></debug-overrides>
</network-security-config>" > "$NETWORK_SECURITY_CONFIG_FILE"
sed_regexp -i '' -e 's#(<application)#\1 android:networkSecurityConfig="@xml/network_security_config"#' "$MANIFEST_FILE"
fi
}
while [[ "$#" -gt 0 ]]; do case $1 in
-f|--file)
makeDebuggable $2
shift;;
-i|--id)
pullFromDevice $2
makeDebuggable $APK_LOCAL_PATH
shift;;
*) "Echo unknown parameter $1"; exit 1;;
esac; shift; done
exit 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment