APKファイルを使用してAndroidアプリケーションのソースコードを変更する

たまたま、更新後にAndroidスマートフォンで使用するコミックブックおよびマンガリーダーアプリケーションで、コミックブックの各章の最後に広告が表示されるようになりました。 このアプリケーションは、数年前にGoogle Playで利用できました(私が購入した有料版)が、「著作権侵害」により削除され、その後、アンダーグラウンドになり、開発者のWebサイトを通じて配布され始めました。 残念ながら、AndroidとiOSでこのアプリケーションに代わる価値のある選択肢は見つかりませんでしたが、特に広告なしのバージョンをすでに購入していたので、広告を見たくありませんでした。 何らかの理由で、開発者自身がそれを無効にすることはできませんでしたが、そのような機会を追加する要求に応答しませんでした。 したがって、それを無効にする別の方法を探す必要がありました。 最初に思いついたのは、AndroidアプリケーションがJavaで記述されていることです。つまり、作成者がアプリケーションを難読化せず、逆コンパイルを試みることができる可能性が高いことを意味します。 少し考えた後、私は働き始めました。



最初に、 アプリケーション自体のapkファイルがダウンロードされました。 その後、インターネットで短い検索を行ったところ、 http://www.decompileandroid.com/というサイトに移動しました。 これを使用すると、アプリケーションとともにapkファイルをダウンロードし、出力でソースコードのセットを取得できます。 残念ながら、Javaクラスへの逆コンパイルは完全に理想的ではないため、IDE(アプリケーション)でアプリケーションプロジェクトを完全に復元することはできませんでしたが、これによりプロジェクトの構造を分析し、その動作を理解することができました。 分析後、 BaseReaderFragment.javaクラスでplaceAdViewIfNeededremoveAdViewIfNeededの 2つの有望なメソッドが見つかりました。



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; }
      
      







コードを読んだ後に思いついた最も簡単なことは、余分なものをすべて削除し、リターンコールのみを残すことでした。



しかし、すでに述べたように、javaクラスで何かを変更しても、最終的にIDEでアプリケーションをコンパイルすることはできませんでした。 したがって、私は代替手段を探す必要がありました。 逆コンパイル処理中に作成されたsmaliファイルは、必要な変更を行った後、変更されたアプリケーションを再アセンブルすることもできます。 悲しいかな、上記のサイトでは、ソースコードの受信のみが許可されており、新しいソースコードの収集は許可されていません。 だから私は自分でそれをする方法を探さなければなりませんでした。

ApkToolsユーティリティが見つかりました。これにより、apkファイルの逆コンパイルとコンパイルが可能になりました。 さらに、aapt.exeユーティリティが必要でした。これは、android-sdk \ build-tools \ 20.0.0フォルダにあるAndroidの標準SDKから取得しました。



Windowsからユーティリティを呼び出すために、apktool.batスクリプトが作成されました。



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







アプリケーションを逆コンパイルするために、次のコマンドが実行されました。



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







その後、 BaseReaderFragment.smaliファイルが受信したソースで見つかり、必要なメソッドが次のように変更されました。



 .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
      
      







次は、ソースからapkファイルをビルドする番です。



これを行うには、次のコマンドを使用します。



 apktool b <AppSourceDir>
      
      







しかし、それだけではありません。 アプリケーションをインストールするには、デジタル署名が必要でした。 これを行う最も簡単な方法は、アプリケーションおよびデジタル証明書に署名するためのユーティリティを含むアーカイブをダウンロードすることです。



アーカイブを解凍し、コマンドを実行します:



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







結果のapkファイルを携帯電話にダウンロードして、変更されたアプリケーションを確認できます。 しかし、変更をテストする過程で、広告は表示されなくなりましたが、それらを表示するためのページ自体が作成されていることがわかりました。 アプリケーションコードが再度分析され、 BaseSeamlessReaderFragmentクラスが見つかりappendPagesメソッドがその中に見つかりました。



以下の行が明らかでした:



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





マンガの章にあるページに加えて、広告を表示するパラメーターを備えた追加のページを作成します。 この行を削除して結果を確認することにしました。 繰り返しますが、同様のsmaliファイル( BaseSeamlessReaderFragment $ 4 )を見て、行を削除します。



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







繰り返しますが、ソースからapkファイルを作成し、アプリケーションに署名します。 アプリケーションをインストールしてテストした後、最終的に広告画面が消えました。これが最終的な目標でした。



この例は、必要に応じて、既存のAndroidアプリケーションを非常に簡単かつ迅速に変更して不足している機能を追加したり、その逆を行ったりして、ソースにアクセスできない状況で望ましくない機能を削除できることを示しています。 同じような状況にあり、我慢したくない人たちを助け、問題の解決策を見つけてくれることを願っています。



All Articles