Saturday, March 21, 2015

Reverse Engineering Closed Source Android Apps Part 1(Smali Intro)

The Intro

  In my recent studies in reverse engineering android apps I have taken to learning the smali assembler/disassembler.  It is my opinion that smali is a powerful tool and learning its syntax and usage will open many doors for you in the world of reverse engineering Android applications.  Through scraping the internet I found it very difficult to find an article covering the process of disassembling, modify, rebuilding and signing apks.  In this post I hope to cover the basics and give anyone who is interested the knowledge needed to start tinkering with android apps.


The Setup:

  There are a few tool you will need to get you started.  Sadly I am writing this guide on a windows machine so my instructions will be based on that operating system.  If anyone needs help setting up an environment on a Linux machine, shoot me an email and I would be glad to help.

Android SDK

- In my practice lab I use the android SDK to write the apps that I would use in my testing.  I highly recommend the android developer studio.  It is based on IntelliJ and call me a fan boy all you want but, I love every IDE to come out of JetBrains. This also come with the Android debug bridge which will come in very handy if you plan to spend a lot of time tinkering with Android.

http://developer.android.com/sdk/index.html

Java

- You will need to have the Java JDK installed.  The two specific tools we will need are 'jarsigner' and 'keytool'.  These tools will be very important as a non signed apk will not install on your phone making it very hard to test your changes.  The process of generating a keystore and signing your apk will be described below.  You will also want to add <jdk_home>/bin directory to your environment variables so that you don't have to specify the entire path in terminal whenever you want to use keytool or jarsigner.
- You will also need to have the JRE installed. You more than likely already have the JDK but if not download and install it.

http://www.oracle.com/technetwork/java/javase/downloads/index.html

Apktool

- Apktool is what we will use for decoding and building our apks.  The link below has very good instructions for installing.  I will go over the basic usage later on in this post.  For now follow the steps to download and install and verify it runs.  Apktool is what is going to generate our smali code for us.  We can then modify the smali code and rebuild the apk.  Apktool also allows for step by step debugging.  It is open source under the Apache license and very easy to setup and use.



Lets Get Started

  The first thing we will need to start tinkering is an apk.  If you are already an Android developer, skip this paragraph.  For my first smali experience I used a simple "Hello World" app.  This is very fast and easy to obtain all you have to do is start android studio and select File->New Project. This will bring up the new project prompt. Give your project a name, click next a few times and then hit finish.  When creating take note of the location of your project on disk.  You will need to know this location at a later point in time.




  Once you have this setup you just need to select Run->Run 'app' (Shift + F10). When prompted to choose a device you can just close this dialog. This will create your apk file in <project dir>app\build\outputs\apk (Example: C:\Smali\app\build\outputs\apk). In that directory you will see a file called 'app-debug.apk'. This starter hello world app is what we will use for part one of this series.

  Now that you have your apk we are going to use the decode feature of apktool in order to get our editable smali code.  Open up your terminal and navigate to the directory containing your apk. Issue the following command to decode your apk:

apktool d <apk name> 

Example: apktool d app-debug.apk

Your output should look similar to the picture below:



  If you go back to the directory containing your apk you will now see a new directory has been created. The name of the directory will match the name of your apk and contains our smali code. Open that folder with your favorite editor, I personally am a huge fan of sublime text but whatever your comfortable with will work. In this post I am going to tell you the location of the files you are looking for. When you are tinkering you may not know this information ahead of time, make sure to take advantage of the search all function in whatever tool you use to edit text files. I feel this is the best way to learn where everything is located. For instance in this example I know I want to change the text "Hello World" in my app to say something else. I could use my global search in sublime text to search for the string 'hello world'. This would return the name and location of the string in the files it resides.  



Now that we know that the value for our text field is located in the file:

 <apk location>/app-debug\res\values\strings.xml

ExamplC:\Users\atari\code\Tinker\app\build\outputs\apk\app-debug\res\values\strings.xml 

You can open that File and you will see something that looks like the image below.


  Lets have a little fun with this text. Change the string 'Hello World!'  sitting in between the <string> tags in the 'strings.xml' file shown above to whatever suits your fancy. Now that we have changed that pesky message to something more fun we are going to rebuild our package. We will accomplish this just as easily as decoding.  In a terminal if you are not already in the directory containing your apk and the folder with your smali code(the same folder we were in for decoding). Now run the following command to build a new apk using your modified code:

apktool b <decoded folder name> -o <new apk name>.apk

Example: apktool b app-debug -o tinker.apk

  Inside of the directory you just ran the command from, you will now see a new apk by the name you provided after the '-o' in the previous command.  In my case tinker.apk.  This is the part where every guide I read when first learning smali would give you the impression that you are done.  This is not the case.  Android requires that all apps be signed in order to install them.  If you want to see it for yourself, you can put this apk on your phone using your USB cable or using the android debug bridge and attempt to install.  You will receive a message saying the install failed.  In order to test our changes we must sign the apk ourselves.  We can accomplish this using tools included in your JDK.  If it is not already there  you are going to want to add <JAVA_HOME>\bin to your path environment variable.  This is going to save you from having to type the full path to the tools we are about to use.  First up is keytool.  We will use the following command to generate a new private RSA key to use for signing our apk:

keytool -genkey -v -keystore <keystore name>.keystore -alias keystore_alias -keyalg RSA -keysize 2048  -validity 10000

Example: keytool -genkey -v -keystore tinker.keystore -alias tinker_key -keyalg RSA -keysize 2048  -validity 10000

  Set a password for your key and enter all of the requested information.  The output of the commands should look something like the picture below:


  You should have run this command from a terminal thats current working directory is where your apk resides. You will now have a new file by whatever name you specified in the above command in with your apk.  In my example we would now have tinker.keystore in the directory we ran our command from.  Now that we have the key created we need to use it to sign our apk.  We can accomplish this with the following task:

jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore <keystore name>.keystore <apk name>.apk keystore_alias

Example: jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore tinker.keystore tinker.apk tinker_key

  You will be prompted for the password you set while generating your key.  You should get an output that looks something like the image below:


  If you would like to verify the signature jarsigner provides you with this functionality as well.   The following command will verify that your apk was properly signed:

jarsigner -verify -verbose -certs my_application.apk

Example: jarsigner -verify -verbose -certs tinker.apk

  You will get a warning that your signature is from a certificate chain that is not verified.  This is fine it states this because you are not a verified certificate authority.  You should get output something along the lines of the message below:


  Now its time to see how closely you followed directions.  Plug your phone into your box and copy over your newly signed apk.  Open up your favorite Android file manager and browse to the location you copied the apk too.  Open the apk and allow it to install.  If all goes well you should get a message stating the app was successfully installed.  Open up your newly installed app and take a look at your message.


  This brings us to the end of part one.  Tomorrow I am going to work on part two and I hope to get it out by the end of the day. Now that we know how to convert out apk to smali code, in tomorrows post we will go over smali syntax and dig much deeper down the wormhole.  I will add some new functionality to our app and we will dig much deeper into Smali code modification.  I hope everyone enjoyed reading feel free to shoot me and email or comment.  Happy tinkering!

  If you want to know more about me my contact info can be found at atarimaster.us


5 comments: