This falls into that series of things where I had to make something work when there wasn’t a pre-built package, so I’m documenting it here in case (1) I ever need to do this again, or (2) someone else can benefit from it. Let’s say you’re looking into a device that runs on Android, and it has a bunch of APKs that you have no clue what to do with… why not use some common tools to quickly process all of those files?
The Disclaimers
Usual disclaimers apply here… in this case I was doing everything on a fully patched (as of the date of this writing) Ubuntu 18.04.2 LTS system. As most of this doesn’t require one to be root, watch those prompt titles to make sure you know who is supposed to be running stuff.
The design goal is to be able to toss a pile of APKs that have been pillaged/looted/tactically acquired into a single directory, then automatically process them all such that we can quickly step from one to the other.
The Tools
I’m not going to reinvent any wheels here, so I’ll be using apktool and Reverse-APK to do the heavy lifting. Let’s get both of them (and their dependencies) installed. First up, the easiest one (apktool). Just use apt-get directly:
root@system:~# apt-get install apktool
Okay, now for something a bit tougher. Reverse-APK uses two tools (smali and baksmali) to do its magic, but there’s no clean package for Ubuntu to get that (there is on Kali, however: smali). Let’s fake that part out. First up, download the latest versions of both from JesusFreke’s download page. As of this writing that’s 2.2.7.
Next, we’ll make a directory to host both of them:
root@system:~# mkdir /usr/share/smali
Copy the two .jar files here:
root@system:~# cp /home/user/Downloads/*smali.jar /usr/share/smali
Of course, we’ll need Java as well for smali/baksmali (and since, you know, Android), so if you don’t have that already add it to the system:
root@system:~# apt-get install openjdk-11-jdk
The Reverse-APK tool expects to call those natively, so we’ll use the helper script approach that JesusFreke specifies and create two files in /usr/local/bin.
root@system:/tmp# cat << 'EOF' > /usr/local/bin/baksmali
> #!/bin/bash
>
> cd /usr/share/smali/ && java -jar baksmali-2.2.7.jar "$@"
> EOF
root@system:/tmp# cat << 'EOF' > /usr/local/bin/smali
> #!/bin/bash
>
> cd /usr/share/smali/ && java -jar smali-2.2.7.jar "$@"
> EOF
Getting close! Now let’s pull down Reverse-APK and install that.
root@system:~# cd /tmp
root@system:/tmp# git clone https://github.com/1N3/ReverseAPK.git
Cloning into 'ReverseAPK'...
remote: Enumerating objects: 60, done.
remote: Total 60 (delta 0), reused 0 (delta 0), pack-reused 60
Unpacking objects: 100% (60/60), done.
root@system:/tmp# cd ReverseAPK/
root@system:/tmp/ReverseAPK# ./install
__________
\______ \ _______ __ ___________ ______ ____
| _// __ \ \/ // __ \_ __ \/ ___// __ \
| | \ ___/\ /\ ___/| | \/\___ \ ___/
|____|_ /\___ >\_/ \___ >__| /____ >\___ >
\/ \/ \/ \/ \/
_____ __________ ____ __.
/ _ \______ \ |/ _|
--=[( by 1N3@CrowdShield )]=-- / /_\ \| ___/ <
--=[( https://crowdshield.com )]=-- / | \ | | | \
\____|__ /____| |____|__ \
\/ \/
Installing reverse-apk...
=========================================================
Reading package lists... Done
Building dependency tree
{etc}
Okay, we’re ready to automate this!
The Automation
I like scripts. In particular, I like Bash scripts because they work pretty much everywhere… so a Bash script it is!
#!/bin/bash
#
# Program : apk-process.sh
# Author : Brian Mork ("Hermit")
# Date : 2019-06-07
# Contact : https://blog.stackattack.net
# Requires : smali/baksmali (https://github.com/JesusFreke/smali)
# apktool (https://github.com/iBotPeaches/Apktool)
# Reverse-APK (https://github.com/1N3/ReverseAPK)
# openjdk-11-jdk
VERSION="1.0"
SUBAPKD=$1
SUBOUTD=$2
PURELS=`which ls`
# Make something pretty
showHeader() {
echo "+--------------------------+"
echo "| apk-process (v${VERSION}) |"
echo "| by: Hermit |"
echo "+--------------------------+"
}
# Show errors in a consistent way, using our pretty header
showError() {
showHeader
echo "ERROR!"
echo $1
exit 1
}
# Check for an installed pre-requisite, show error and exit if not found
checkDep() {
which $1 > /dev/null 2>&1
# If previous returned error, it wasn't found and we should exit
if [ $? -ne 0 ]; then
showError "Missing $1"
fi
}
# Did we get two arguments?
if [ $# -ne 2 ]; then
showError "Syntax: apk-process.sh [apk-directory] [results-directory]"
# Does the specified source directory exist?
elif [ ! -d ${SUBAPKD} ]; then
showError "The specified source APK directory does not exist!"
else
APKDIR=$(cd $PWD/$1 && pwd -P)
fi
# Get the number of files with ".apk" in their name from the source directory
declare -i APKCHK=`find ${APKDIR} -type f -iname '*.apk' -print 2>/dev/null | wc -l`
# If no APK files were found, we have nothing to do
if [ ${APKCHK} -lt 1 ]; then
showError "No APKs were found in ${APKDIR}"
fi
# Checking for required programs
checkDep smali
checkDep baksmali
checkDep reverse-apk
checkDep apktool
# Check if the output directory exists, and make it if not
if [ ! -d ${SUBOUTD} ]; then
mkdir -p ${SUBOUTD}
echo " [+] INFO: Created ${SUBOUTD}"
fi
OUTDIR=$(cd ${PWD}/${SUBOUTD} && pwd -P)
# Check for apktool directory, and create it if it doesn't already exist
if [ ! -d ${OUTDIR}/apktool ]; then
mkdir -p ${OUTDIR}/apktool
echo " [+] INFO: Created apktool directory in ${OUTDIR}"
else
echo " [-] WARNING: The apktool directory already existed in ${OUTDIR}!"
fi
# Check for reverse-apk directory, and create it if it doesn't already exist
if [ ! -d ${OUTDIR}/reverse-apk ]; then
mkdir -p ${OUTDIR}/reverse-apk
echo " [+] INFO: Created reverse-apk directory in ${OUTDIR}"
else
echo " [-] WARNING: The reverse-apk directory already existed in ${OUTDIR}!"
fi
# Looks like we're ready to rock. :)
# First fire off apktool, which helpfully allows us to specify an
# output directory... hint hint reverse-apk!
# Then we'll run reverse-apk, which unfortunately only takes the APK as an input, and stays in whatever
# directory... and uses the relative path to output, so we end up with a dumb situation where we have to
# either update the script itself (not very sustainable) or do the garbage we're going to
# do below with linking to fake it out. :)
for FILE in `${PURELS} ${APKDIR}/*.apk`; do
FILESPLIT=`echo ${FILE} | awk -F'/' '{print NF}'`
BASEFILE=`echo ${FILE} | cut -d '/' -f ${FILESPLIT}`
FOLDER=`echo ${BASEFILE} | cut -d . -f 1`
echo " [+] INFO: Processing ${FILE}"
echo -n " [-] INFO: Processing ${FILE} with apktool... "
apktool d ${FILE} -o ${OUTDIR}/apktool/${FOLDER} >> ${OUTDIR}/apk.log 2>&1
echo "DONE"
echo -n " [-] INFO: Processing ${FILE} with reverse-apk... "
RAPKDIR=${OUTDIR}/reverse-apk/${FOLDER}
mkdir ${RAPKDIR}
cd ${RAPKDIR}
ln -s ${FILE} ${BASEFILE}
reverse-apk ${BASEFILE} >> ../../reverse-apk.log 2>&1
unlink ${BASEFILE}
echo "DONE"
echo " ---------------------------------------------------------"
done
Or grab a copy from my GitHub. 🙂
The #Victory. Good hunting!