📜 ⬆️ ⬇️

Hacking one Android application

Recently, I intensively developed my application for Android, and in the process of protecting the paid version I realized that it was quite difficult to protect the application from hacking. For the sake of sports interest, I decided to try to remove ads from one free application in which the banner is offered to be hidden if you pay money through an In-App Purchase.


In this article I will describe how I managed to remove ads for free and at the end - a few words about how to complicate the task for hackers.

Step 1. Get the “readable” application code.
To get the APK applications from the phone, you need root rights. We pull the application out of the phone using adb (even if for conspiracy, we will have the application greatapp.apk):
adb pull /data/app/greatapp.apk

Habrayuzer overmove told me that root is optional, you can use Astro to backup any application, and it will be copied to / mnt / sdcard.
Habrayuzer MegaDiablo told me that Astro is optional. The list of installed applications and their apk files can be found through the pm utility in the shell, and when the file name is already known, it can be pulled down via adb pull /data/app/app.filename.apk .
')
The APK is a ZIP archive, we classes.dex out the classes.dex file of classes.dex with the compiled code that interests us.
We will use smali / baksmali assembler / disassembler for our dirty business.
java -jar baksmali-1.3.2.jar classes.dex

At the output we get the out directory with a bunch of *.smali files. Each of them corresponds to a .class file. Naturally, I don’t want everything obfuscated for the most, this directory looks like this:


We will try to understand where in this obfuscated heap “it is said” about advertising. At first I just did a search with the text " AdView " (View, displaying ads from the AdMob SDK) for all files. AdView.smali itself was AdView.smali , R$id.smali and some d.smali . AdView.smali not very interesting to look at, I somehow ignored R.$id at first, and went straight to the mysterious d.smali .

Step 2. Go the wrong way.
Here is the a() method in the d.smali file with the first mentioning of AdView (I decided it’s better to take a screenshot, otherwise it’s very sad to read without formatting):


The method does not return anything, so I, without thinking twice, decided to just insert return-void closer to the beginning. When I assembled and launched everything, the application happily crashed. Log from adb logcat :

E/AndroidRuntime(14262): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.greatapp/com.greatapp.GreatApp}: android.view.InflateException: Binary XML file line #22: Error inflating class com.google.ads.AdView

It is clear that our AdView not created as a result of the manipulations. Forget about d.smali .

Step 3. Roll back all changes and look at the previously missed R$id . Here is the line with AdView :
# static fields
.field public static final adView:I = 0x7f080006


Looks like this is a View ID with ads. Find where it is used by searching by value 0x7f080006 . We get only two results: the same R$id and GreatApp.smali . In GreatApp.smali, the text is much more interesting (my comments):


It can be seen that this identifier is used to look for the View (line 588) and literally immediately AdView is removed from the screen (line 595). Apparently deleted if the user paid for the lack of advertising? If you look a little higher, the look clings to line 558 with "keywords":
invoke-static {v7, v8}, Lnet/robotmedia/billing/BillingController;->isPurchased(Landroid/content/Context;Ljava/lang/String;)Z

robotmedia is a third-party (open source) library designed to make it easier to work with in-app billing on Android. Why wasn’t she completely obfuscated? Well, okay, lucky.
It can be seen that the isPurchased() method returns a string, which with the help of Boolean.valueOf() converted into a Boolean object and, finally, into a regular boolean via booleanValue() .
And here is the most interesting, in line 572 we turn into a kind :cond_32 , if the result value == false . Otherwise, the already viewed AdView search and delete AdView .

Step 4. Minimal change, build and run.
Well, it's small - we delete this key line, build the application and immediately install it on the phone:
java -jar ..\smali\smali-1.3.2.jar ..\smali\out -o classes.dex
apkbuilder C:\devel\greatapp\greatapp_cracked.apk -u -z C:\devel\greatapp\greatapp_noclasses.apk -f C:\devel\greatapp\classes.dex
jarsigner -verbose -keystore my-release-key.keystore -storepass testtest -keypass testtest greatapp_cracked.apk alias_name
adb install greatapp_cracked.apk


( greatapp_noclasses.apk is the original APK of the application from which classes.dex is removed, certificates are created using the Android SDK).
And cheers, we run the application, no advertising!

Now about how to complicate the task for lovers of freebies (this is just what I remember from the video about piracy with Google IO 2011, the link below):


I hope it was interesting. Finally, some useful links on the topic:

Source: https://habr.com/ru/post/141522/


All Articles