📜 ⬆️ ⬇️

Modifying the source code of an android application using an apk file

It so happened that the app for reading comics and manga, which I use on my android-smartphone, after the update began to show ads at the end of each chapter of the comic. This application was available a couple of years ago on Google Play (the paid version of which was bought by me), but was removed due to “copyright infringement”, after which it went underground and became distributed through the developer’s website. Alas, I haven’t found any worthy alternatives to this application on android and iOS, but I didn’t have much desire to watch ads, especially since I already bought the version without ads. The developer himself for some reason did not make it possible to disable it, and did not respond to requests for adding such an opportunity. Therefore it was necessary to look for alternative methods for its disconnection. The first thing that came to mind is that android applications are written in java, which means there is a possibility that the author did not obfuscate his application and can try to decompile it. A little thought, I got to work.

To start, the apk-file of the application itself was downloaded. Then a brief internet search brought me to http://www.decompileandroid.com/ . With it, you could download the apk-file with the application and get a set of sources at the output. Alas, decompiling into java-classes is not quite perfect and therefore I did not succeed in completely restoring the application project itself in IDE (Idea), but this allowed us to analyze the structure of the project itself and figure out how it works. After analyzing, two promising methods were found in the BaseReaderFragment.java class - placeAdViewIfNeeded and removeAdViewIfNeeded .

Method code placeAdViewIfNeeded:
')
if (adViewPlaced || adView == null) { return; } else { viewgroup.setVisibility(0); android.widget.RelativeLayout.LayoutParams layoutparams = new android.widget.RelativeLayout.LayoutParams(-2, -2); layoutparams.addRule(13, -1); viewgroup.addView(adView, layoutparams); adViewPlaced = true; AdsHelper.requestNewAd(adView); return; } 


The simplest thing that came to mind after reading the code is to remove all unnecessary, and leave only the call return;

But, as already mentioned, even if I changed something in the java class, I could not eventually compile the application into the IDE. So I had to look for an alternative. It turned out that the smali files that are created during the decompilation process also allow, after making the necessary changes, to reassemble the modified application. Alas, the site that was listed above, allowed only to receive the source code, but not to collect new ones. So I had to look for ways to do it myself.
The ApkTools utility was found, which allowed to decompile and compile apk-files. In addition, I needed the aapt.exe utility, which was taken by me from the standard SDK for android in the android-sdk \ build-tools \ 20.0.0 folder.

For the convenience of calling the utility from under windows, an apktool.bat script was created:

 @echo off set PATH=%CD%;%PATH%; java -jar "%~dp0\apktool.jar" %1 %2 %3 %4 %5 %6 %7 %8 %9 


To decompile the application, the following commands were executed:

 apktool if <appName>.apk apktool d <appName>.apk 


After that, the BaseReaderFragment.smali file was found in the received sources, and the methods we needed were changed as follows:

 .method protected placeAdViewIfNeeded(Landroid/view/ViewGroup;)V .locals 3 .param p1, "layoutAds" # Landroid/view/ViewGroup; .prologue const/4 v2, -0x2 return-void .end method .method protected removeAdViewIfNeeded(Landroid/view/ViewGroup;)V .locals 1 .param p1, "layoutAds" # Landroid/view/ViewGroup; .prologue .line 149 const/16 v0, 0x8 return-void .end method 


Next came the turn of the assembly of the apk-file from source.

You can do this with the following command:

 apktool b <AppSourceDir> 


But that is not all. In order for the application to be installed, it had to be digitally signed. The easiest way to do this is to download the archive in which there is a utility for signing applications and digital certificates for it.

Unpack the archive, execute the command:

 java -jar signapk.jar certificate.pem key.pk8 <path-of-the-folder-contaning-the-apk>.apk <path-of-the-new-signed-apk>.apk 


The resulting apk-file can be downloaded to your phone to check our modified application. However, in the process of testing the changes, it turned out that the ads are no longer shown, but the page itself is created for their display, which is not very pleasant. The application code was analyzed again, the BaseSeamlessReaderFragment class was found , and the appendPages method was found in it.

It was clear that the line:

 addPage(new MangaPage(i - 1, null, chapteritem, true), false); 

creates an additional page, in addition to those in the manga chapter, with the parameter responsible for displaying ads. It was decided to delete this line and see the result. Look in the same smali-file ( BaseSeamlessReaderFragment $ 4 ) again and delete the line:

 invoke-virtual {v6, v7, v10}, Lorg/mangawatcher/android/fragments/BaseSeamlessReaderFragment;->addPage(Lorg/mangawatcher/android/fragments/BaseSeamlessReaderFragment$MangaPage;Z)V 


Again we build the apk-file from source and sign our application. After installing and testing the application, the advertising screen finally disappeared, which was the ultimate goal.

This example shows that, if necessary, you can easily and quickly modify existing android applications to add the missing functionality or, on the contrary, remove some unwanted features in situations where there is no access to the sources. I hope he will help people who are in a similar situation and do not want to put up with it, to find a solution to the problem.

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


All Articles