Convert APK to source code automatically with lazyX

A python script to automate the use of dex2jar tool along with cfr in order to decompile apk files instantly.

Date and Time of last update Sun 29 Mar 2020
  

If you play around with reversing APK files you might have been in the situation repeating the same process over and over. This was the case while attempting to reverse an apk and in the process of using the famous dex2jar along with CFR to decompile the java classes an idea came up. Why not just script this into Python so we can have the result immediately. Upon searching for it the apkx tool came up but it has not been updated with the latest libraries for some time now so lets make something simple and straight forward ourselves.

This resulted in the creation of something named lazyX and can be found in Github here!

We are using dex2jar and CFR and the only parameter to supply to our script is the apk. Also we made it in such a way that if we want to update the dex2jar or the CFR it is an easy task to do. We download the dex2jar from here and we unzip it so we have a directory with the tool inside. We also download the jar of CFR and put it besides the directory of dex2jar. The final structure we end up should be similar to the following in our repo here.

The actual code of the tool is presented bellow although it is pretty self explanatory with some basic understanding of Python.

#!/usr/bin/python

import os
import sys
import subprocess
import zipfile
import argparse


'''
lazyX is a small tool to automate the extraction, conversion of dex files
to jar files and decompiling of class files using dex2jar and cfr!
Adjust the following two lines to the directory of the dex2jar
and the Jar file of the cfr you have downloaded
'''
name_of_the_DEX2JAR_directory = "dex-tools-2.1-SNAPSHOT"
name_of_the_cfr_jar = "cfr-0.149.jar"



cwd = os.path.dirname(os.path.realpath(__file__))
dexDir = cwd  + "/" + name_of_the_DEX2JAR_directory
cfrDir = cwd + "/" + name_of_the_cfr_jar
FNULL = open(os.devnull, 'w')


'''
Call the dex2jar on a dex file
'''
def dex2jar(dexDir, xpath, infile, outfile):
	subprocess.call(['sh', dexDir + "/d2j-dex2jar.sh", xpath + '/' + infile, '-o', xpath + '/' + outfile, '-f'])

'''
Call cfr the jar file generated by dex2jar
'''
def cfr(dexDir, xpath, srcpath, jar):
	subprocess.call(['java','-Xms512m', '-Xmx1024m', '-jar', cfrDir, xpath + '/' + jar, '--outputdir', srcpath, '--silent', 'true', '--caseinsensitivefs', 'true'], stdout=FNULL)

parser = argparse.ArgumentParser(description='Crack open an apk the lazy way.')
parser.add_argument('apkfile', help='your apk')
args = parser.parse_args()
if not args.apkfile.endswith((".apk")):
	print("File is not an apk")
	sys.exit(0)

xpath = os.path.splitext(os.path.basename(args.apkfile))[0]
srcpath = xpath + "/src"


'''
Extract the apk
'''
try:
	zip_ref = zipfile.ZipFile(args.apkfile, 'r')
	zip_ref.extractall(xpath)
	zip_ref.close()
except IOError as e:
	print("Error extracting apk: " + str(e))
	sys.exit(0)


'''
Iterate over all the extracted files to find dex files
'''
for root, dirs, files in os.walk(xpath):
	for file in files:
		if file.endswith((".dex")):
			jar = os.path.splitext(file)[0] + ".jar"

			try:
				print("dex2jar ----> Converting...")
				dex2jar(dexDir, xpath, file, jar)
			except Exception as e:
				print('Something went wrong while DEX2JAR was converting! : '+ str(e))
				next
			try:
				print("cfr ----> Decompiling...")

				cfr(dexDir, xpath, srcpath, jar)
			except Exception as e:
				print('Something went wrong while CFR was decompiling! : ' + str(e))

print("Completed!")


In order to use it you can simply add it to your path executing the following command from within the downloaded directory of the repo sudo mv dex-tools-2.1-SNAPSHOT lazyX cfr-0.149.jar /usr/local/bin && sudo chmod +x /usr/local/bin/lazyX.

This allows us to run the following on an example.apk.

$ lazyX example.apk
dex2jar ----> Converting...
dex2jar example/classes.dex -> example/classes.jar
cfr ----> Decompiling...
Completed!

The above will create a folder named example and it would extract in there the contents of the apk. Dex2jar will convert the dex files found into jar files and another directory will be created in example/src that will contain the decompiled source code that cfr creates.


Finally if you would like to update the versions of dex2jar and CFR simply download the new versions and put them in the same directory as lazyX. Do not forget to update the two parameters in the head of the script with the names of of the directory of the dex2jar tool and the jar file of cfr. Similar to the following:

name_of_the_DEX2JAR_directory = "dex-tools-2.1-SNAPSHOT"
name_of_the_cfr_jar = "cfr-0.149.jar"


Conclusion

This is a very handy script that automates the reverse engineering process of an apk by instantly providing the jar files and the decompiled source code. If you would like to tweak the parameters passed on the dex2jar and cfr feel free to do so by altering the functions dex2jar and cfr in the script respectively.