Java Integers’ forget easily

For this challenge, we are given an apk ‘EzDroid.apk’. As with any apk I analyze, I always like to run apktool d EzDroid.apk, unzip using your favorite tool and attempt to decompile back to Java.

The next thing I also do when analyzing APK’s is to examine the AndroidManifest.xml file.


The file is an essential file for any APK. It provides sort of a blueprint for the application. Understanding this file can aid you greatly in analyzing Android applications. In this challenge, the AndroidManifest.xml is rather small and simple. With only one Activity being the Main and the Launcher we can focus on that specific Activity.

Android activities can have a few entry points for which it can execute different code depending on the action. This is known as the


Once again this challenge only has one entry point; onCreate(). A quick look at the application’s code we can see strings such as:

These quickly lead me to believe the app is doing some checking. Let’s focus on the first string and reverse some code. We can see that the string is presented only if the function checkers() returns True. It then calls the buh() function. Diving into the checkers() function, we quickly notice a few interesting strings that are often used to check against emulators. In this case, the code is checking the phone’s product:

Checks for its model:

Lastly checks for the phone’s SimOperatorName & NetworkOperatorName

Remember that after this checkers() call if it returns true it will present the string “You chose poor execution tactics…” it then calls the buh() function. This little function simple kills our application:

To summarize we need to find a way to not have the application exit. There are several ways to do this. Some more simple, some more practical and some a bit more difficult. I am going to take the route of modifying the APK’s code. Taking this route also allows us for several ways to accomplish what we want. I am going to simply modify the smali code in the checkers() function to always return False.

If you used apktool to decompile the application, then you can go ahead modify the smali code. Looking at smali code takes practice just like anything else, I will try to walk you through it. Open the following file with your preferred editor:

vi EzDroid/smali/com/labyrenth/manykeys/manykeys/onoes.smali

Locate the function checkers() by searching for it. These first few lines should be enough to accomplish what we want.

I highlighted the variable we are interested in, v3. We can see that in line 42 the code is initializing this variable to a Boolean. This is the variable used to set and return the value for each check. If you remember from the decompiled Java code we count four checks. I said I was going to modify the code to return False. Therefore, I need to change the assignment four times. Simple change the following lines: 95, 118, 141 and 151.

from: const/4 v3, 0x1

to: const/4 v3, 0x0

Save the file. Before we package the APK let’s go back to the code and see if we need to make any other changes.

Remember we identify a string: “You\’re in an emulator…”. In this case the code is checking the phone’s Product and testing if it contains ‘sdk’ if True it displays the text, sleeps and then kills the application process. Once again, a few different ways to bypass this, since we are already modifying the smali code let’s do the same. Let’s open the file: Note:the filename. Java Classes with dollar signs

vi EzDroid/smali/com/labyrenth/manykeys/manykeys/EZMain\$1.smali

Search for ‘sdk’ and we should fall into line 141. We just change the string to something more fun:

from: const-string v3, “sdk”

to: const-string v3, “fun”

All right at this point we can repackaged the APK. This requires a few things. First, we use apktool to package it up. Then we need to re-sign all the files. Lastly use zipalign to realign the files. There is a lot of magic that goes under the hood for all these three steps that we won’t cover. If you are new to APK analysis I encourage you to read up on it. For today I will just show the magic jazz hands.

Repacking the using apktool we can run the following command:

apktool b EzDroid -o ./newA.apk

This will take the directory ‘EzDroid’ and create a new apk file with the name ‘newA.apk’. To resign the APK you need generate a key. Using keytool we can run; remember your password.

keytool -genkey -v -keystore ctfkey.keystore -alias ctfandroidKey -keyalg RSA -keysize 2048 -validity 20000.

Once we have the key we can resign the created ‘newA.apk’ file.

jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore ./ctfkey.keystore -storepass MyPassword newA.apk ctfandroidKey

Lastly we can run zipalign. If you have installed the Android sdk in your machine or VM you can find this tool under the build-tools directory. For example, in my Windows VM is located under:

C:\\Program Files (x86)\\Android\\android-sdk\\build-tools\\23.0.2\\zipalign.exe

We then simply run:

C:\\Program Files (x86)\\Android\\android-sdk\\build-tools\\23.0.2>zipalign.exe -v 4

Our APK is ready to be installed in our emulator. One other thing I like to before running the application is execute logcat. Sometimes it gives you good information. I usually always run it like so:

adb.exe logcat -v long *:v > C:\\Users\\Me\\mylog.out

Running the application we are presented with the several math problems. I hope you paid attention in 1^st^ grade.

It seems that app doesn’t care if you passed 1^st^ grade. Inputting any value gives the next problem. When you get to the last problem the application crashes. Good thing you ran logcat…right? If you didn’t you might want to, it will help. My log file is about 50k lines, yours may vary, either way scroll all the way to the bottom and beginning to scroll up. You should run into this error: The log is truncated.

[ 05-24 13:58:47.054 2418: 2418 E/AndroidRuntime ]


Process: com.labyrenth.manykeys.manykeys, PID: 2418

java.lang.NumberFormatException: Invalid long:

at java.lang.Long.invalidLong(

at java.lang.Long.parse(

at java.lang.Long.parseLong(

at java.lang.Long.parseLong(

at com.labyrenth.manykeys.manykeys.onoes.lastCheck(

at com.labyrenth.manykeys.manykeys.EZMain.checks(

at com.labyrenth.manykeys.manykeys.EZMain.access$000(

at com.labyrenth.manykeys.manykeys.EZMain$1.onClick(

This stack trace is fairly simple, the app fails with an invalid long integer and appears to be at the function lastCheck(). Let’s go examine the code.

Awesome! More math! Also, interestingly the long int used in the function gets decoded to:

`>>> "72657031616365746831732121".decode('hex')

> 'rep1aceth1s!!'`

If you are like me and always looking for the fastest solution you would solve the equation above and input some ridiculously floating number. Which would crash the application. Not that easy! Darn!

What we need to do is understand this algebraic expression better. The equation in the problem that needs to be solved can be broken down to x(-37)-42=17206538691. In Algebra we learned to solve for ‘x’ that we need to isolate it, so we do and get (17206538691/-37)-42 = x. The solution to this is irreducible and leads to some questions as well as the wrong answer for this challenge. Therefore, let’s do some searching on the Internet in hopes of finding what is going on here. After a few searches, we come across the page: This explains the problem almost exactly and with further research we understand that this is a modular multiplicative inverse and can be solved quite simply using some standard formulas, these are explained better here: Module Multplicative. Basically, in order to solve the equation we calculate ax+b=c, while multiplying both sides by the modular inverse of -37. Since the mod is 2^64 in this case, we calculate it by raising it to the 2^63-1 power. A full solution script is attached.

At this point we figured the right long int to use in our application. We replace and rebuilt our apk. Install it, run it and answer the math questions. Did you forget to run logcat again? If so shame on you. If you did open the file and again start from the end, scrolling up:

`[ 05-24 17:48:34.970 1483: 1543 W/AudioTrack ]

AUDIO_OUTPUT_FLAG_FAST denied by client

> [ 05-24 17:48:37.542 2718: 2718 I/System.out ]
> Part 2: 2start_
> [ 05-24 17:48:37.542 2718: 2718 I/System.out ]
> One last check...
> [ 05-24 17:48:37.542 2718: 2718 I/System.out ]
> Final Part: hard2defeat}
> [ 05-24 17:48:37.542 1483: 1543 W/AudioTrack ]
> AUDIO_OUTPUT_FLAG_FAST denied by client
> [ 05-24 17:48:37.542 2718: 2718 I/System.out ] `

Look at this we have ‘Final Part’ and ‘Part 2’… Let’s find Part 1:

`[ 05-24 17:47:38.996 2718: 2718 I/System.out ]

Part1: PAN{ez_droid_`

That looks like a key to me: PAN{ez_droid_2start_hard2defeat}