この記事では、Androidのリバースエンジニアリングアプリケーションについてお話します。 このプロセスはwinアプリケーションのプロセスとは多少異なります。LogCatとバイトコードではなく、デバッガーとアセンブラーはありません。 ご想像のとおり、アプリケーションを破壊、またはより単純に「クワッキング」を目的としてアプリケーションを調査します。
ブリーフィング
実験ウサギとして、私はプログラム「Multi Mount SD-Card」を選択しました。 その本質は、システムとユーザーへの同時アクセスでデバイスのフラッシュドライブをマウントすることです。 実際には、デフォルトでは、Androidは現在マウントされているドライブにアクセスできません。 Eclairユーザーの場合、これはそれほど重要ではありませんが、カードにインストールされたプログラムがマウントされたときにクラッシュすると、
開始するには、何かを壊すための配布パッケージが必要です。 しかし、どこで入手できますか? 結局のところ、このためにはあなたがそれを購入する必要があります。 さて、またはすでに購入した人から物toいする。 そのような人は、購入したapkを親切に共有しているw3bsit3-dns.comフォーラムから寄せられたものです 。
それで、 配布キットがあり 、すでにプログラムをインストールし、実行しています...そしてbam! ライセンスの購入を提案するウィンドウが表示されます 。 検証はインターネットを経由するため、切断しようとしますが、解決しません。 アプリケーションの購入者にはキーとログインが与えられません。これにより、hardware_idやgoogleアカウントなどへのバインドについて通知されます。 そのため、いくつかのハッキングオプションがあります。プログラムを故意に正しい検証情報でハードコーディングするか、ライセンスの有効性を検証するすべてのセクションをコードから切り取ります。 私はそれがより好きなので、私は2番目のオプションを選びました。
ツールキット
仕事にはツールが必要です。 私は途中でそれらについて話したかったのですが、それでも私の考えを変えて、事前にすべてについて書くことに決めました。 実際、今日は次のツールのリストが必要です。
はじめに
開始する前に、Androidアプリケーションの小さな構造について説明します。 各アプリケーションには、zipで圧縮されたapk拡張子のファイルがあります。 アプリケーションリソース、AndroidManifest.xmlおよびclasses.dexが含まれています。 後者は何ですか? これは、dalvik仮想マシン専用にコンパイルされたプログラムバイトコードです。 Javaでクリーンなソースコードを取得することは不可能ですが、 dalvikオペコード(仮想マシンのコマンドセット、大まかに言うと、これはローカルアセンブラー)を取得できます。 また、dexファイルをjarに変換し、それを逆コンパイルして、Javaで多少読み取り可能なコードを取得できます。 これからやること。
逆コンパイル
Apkマネージャーユーティリティを使用して、apkですべての操作を実行します。 これは、apkで動作する一連のライブラリの一種の統合フロントエンドです。 デバイスのドライバーをインストールする必要があり、 USBデバッグモードがオンになっていることを思い出させてください。 始めましょう。
- multimount.apkをapk_manager \ place-apk-here-for-moddingフォルダーにコピーし、Script.batを実行します。 すべてが正常な場合、緑色のテキストのコンソールが表示されます。
- APKを逆コンパイルする必要があります。 同じ名前のアイテム9を選択します。その後、コンソールを閉じません。
- アーカイバーでmultimount.apkを開き、classes.dexファイルをdex2jarフォルダーにコピーしてから、dex2jar.batにドラッグします。 Total Commanderでは、ドラッグアンドドロップは機能しません。
- 表示されるclasses.dex.dex2jar.jarは、jd-guiを使用して開かれます。 ウィンドウはまだ閉じられていません。後で必要になります。
分析の開始
アプリケーションに関する初期情報については、そのマニフェストを見てみましょう。 これから、主なアクティビティが設定であることを理解できます。 そのため、アプリケーションを購入するためのコードはどこかにあります。 また、一番下に奇妙な行があります:
<uses-permission android:name = "com.android.vending.CHECK_LICENSE" />
これは何? Googleが示唆しているように、この行は、アプリケーションがLVL 、つまりAndroidライセンスマネージャーを使用していることを示唆しています。 まあ、それは良いことです。ドキュメントがあるからです。 これを読んで、このLVLがライセンスを管理するだけでなく、難読化コードを公開することを理解できます。これにより、作業が大幅に複雑になります。
それでは、コードの分析に直接進みましょう。 jd-guiに切り替えてツリーを展開し、3つの名前空間を確認します。1つ目は広告に関連するもの、2つ目はLVLクラスのセット、3つ目は必要なものです。
そこに行き、難読化の結果を確認します。 MultiMountSDCardConfigureを開き、コードをすばやく確認します。 ハッシュのある長い行がすぐに目を引きます。 これはbase64公開キーです。 そしてその周りには、ライセンスをチェックする他の行があります。 それらを切り取る必要があります。
- com。 アンドロイド 販売しています。 ライセンス 。 h localh = new com。 アンドロイド 販売しています。 ライセンス 。 h ( arrayOfByte、str4、str3 ) ;
- v localv = new v ( これ 、localh ) ;
- m localm1 = new m ( これ 、localv、 「MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAg1 ...」 ) ;
- f = localm1 ;
- m localm2 = f ;
- j localj = e ;
- localm2。 a ( localj ) ;
apk_manager \ projects \ multimount.apk \ smali \ com \ rafoid \ multimountsdcard \ widget \ MultiMountSDCardConfigure.smaliを開き、バイトコードを確認します。 さらに読む前に、まずコマンドのリストを確認することをお勧めします。 これらの行を見つけてコメントアウトする必要があります。 ここにあります:
- ...
- #iput-object v1、p0、Lcom / rafoid / multimountsdcard / widget / MultiMountSDCardConfigure;-> e:Lcom / android / vending / Licensing / j;
- #新しいインスタンスv1、Lcom / android / vending /ライセンス/ m;
- #新しいインスタンスv2、Lcom / android / vending /ライセンス/ v;
- #新しいインスタンスv3、Lcom / android / vending /ライセンス/ h;
- #sget-object v4、Lcom / rafoid / multimountsdcard / widget / MultiMountSDCardConfigure;-> d:[B
- #invoke-virtual {p0}、Lcom / rafoid / multimountsdcard / widget / MultiMountSDCardConfigure;-> getPackageName()Ljava / lang / String;
- #move-result-object v5
- #invoke-direct {v3、v4、v5、v0}、Lcom / android / vending / licenseing / h;-> <init>([BLjava / lang / String; Ljava / lang / String;)V
- #invoke-direct {v2、p0、v3}、Lcom / android / vending / licenseing / v;-> <init>(Landroid / content / Context; Lcom / android / vending / Licensing / n;)V
- #const-string v0、 "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCg ..."
- #invoke-direct {v1、p0、v2、v0}、Lcom / android / vending / licenseing / m;-> <init>(Landroid / content / Context; Lcom / android / vending / Licensing / k; Ljava / lang /ストリング;)V
- #iput-object v1、p0、Lcom / rafoid / multimountsdcard / widget / MultiMountSDCardConfigure;-> f:Lcom / android / vending / Licensing / m;
- #iget-object v0、p0、Lcom / rafoid / multimountsdcard / widget / MultiMountSDCardConfigure;-> f:Lcom / android / vending / Licensing / m;
- #iget-object v1、p0、Lcom / rafoid / multimountsdcard / widget / MultiMountSDCardConfigure;-> e:Lcom / android / vending / Licensing / j;
- #invoke-virtual {v0、v1}、Lcom / android / vending / licenseing / m;-> a(Lcom / android / vending / Licensing / j;)V
- ...
短くして保存します。 すべてが使用できるようです。 コンパイルしてインストールするだけです。
コンパイルとインストール
これを行うには、すでにおなじみのApkマネージャーを使用します。
- コンソールウィンドウをまだ閉じていない場合は、コンソールウィンドウに切り替えて項目14を選択します。 スクリプト自体がコンパイルされ、署名され、デバイスにapkがインストールされます。
- アプリケーションを起動すると、何も買えないようになりましたが、確認プロセスのウィンドウがハングして閉じません。
再分析
ここで、不要なダイアログを示すコードを検出して削除する必要があります。 jd-guiに切り替えて、次の行を少し高めに見つけます。
- rogressDialog localProgressDialog = ProgressDialog.show(this、str1、str2、1、0);
- b = localProgressDialog;
次に、MultiMountSDCardConfigure.smaliでそれらを見つける必要があります。 ここにあります:
- ...
- #invoke-static {p0、v0、v1、v6、v7}、Landroid / app / ProgressDialog;-> show(Landroid / content / Context; Ljava / lang / CharSequence; Ljava / lang / CharSequence; ZZ)Landroid / app / ProgressDialog;
- #移動結果オブジェクトv0
- #iput-object v0、p0、Lcom / rafoid / multimountsdcard / widget / MultiMountSDCardConfigure;-> b:Landroid / app / ProgressDialog;
- ...
コミット、保存、コンパイル、インストール、実行します。 やった! すべてが機能します。 しかし、短いテストの後、すべてが機能するわけではないこと、つまり自動マウント機能があることを理解しています。 jd-guiに切り替えて、MultiMountSDCardWidget $ UpdateServiceを開き、次の湾曲したコードを確認します。
- if(MultiMountSDCardWidget.b.booleanValue());
- int j;
- for(int i = 0 ;; j = 1)
- {
- ブールlocalBoolean = Boolean.valueOf(i);
- RemoteViews localRemoteViews = MultiMountSDCardWidget.a(this、localBoolean);
- クラスlocalClass = MultiMountSDCardWidget.a;
- ComponentName localComponentName = new ComponentName(this、localClass);
- AppWidgetManager.getInstance(this).updateAppWidget(localComponentName、localRemoteViews);
- 帰る
- }
このサービスは自動マウントを担当します。 冒頭に何らかのチェックがあり、その結果、このマウントが実行されます。 このコードは、メインアクティビティの変数bをチェックします。これは、宣言をコメントアウトした同じ変数で、ダイアログを削除します。 このテストでも同じことを行います-地獄にコメントします。
今回は、MultiMountSDCardWidget $ UpdateService.smaliを開き、次の行を閉じます。
- ...
- .method public onStart(Landroid / content / Intent; I)V
- .locals 3
- #sget-object v0、Lcom / rafoid / multimountsdcard / widget / MultiMountSDCardWidget;-> b:Ljava / lang / Boolean;
- #invoke-virtual {v0}、Ljava / lang / Boolean;-> booleanValue()Z
- #move-result v0
- #if-eqz v0 ,: cond_0
- const / 4 v0、0x0
- :goto_0
- invoke-static {v0}、Ljava / lang / Boolean;-> valueOf(Z)Ljava / lang / Boolean;
- 移動結果オブジェクトv0
- invoke-static {p0、v0}、Lcom / rafoid / multimountsdcard / widget / MultiMountSDCardWidget;-> a(Landroid / content / Context; Ljava / lang / Boolean;)Landroid / widget / RemoteViews;
- 移動結果オブジェクトv0
- 新しいインスタンスv1、Landroid / content / ComponentName;
- sget-object v2、Lcom / rafoid / multimountsdcard / widget / MultiMountSDCardWidget;-> a:Ljava / lang / Class;
- invoke-direct {v1、p0、v2}、Landroid / content / ComponentName;-> <init>(Landroid / content / Context; Ljava / lang / Class;)V
- invoke-static {p0}、Landroid / appwidget / AppWidgetManager;-> getInstance(Landroid / content / Context;)Landroid / appwidget / AppWidgetManager;
- 移動結果オブジェクトv2
- invoke-virtual {v2、v1、v0}、Landroid / appwidget / AppWidgetManager;-> updateAppWidget(Landroid / content / ComponentName; Landroid / widget / RemoteViews;)V
- リターンボイド
- #:cond_0
- const / 4 v0、0x1
- goto:goto_0
- .endメソッド
- ...
私たちはこの便利なプログラムの購入で30ルーブルを節約したことを開始し、喜んでいます。
注釈
このプロセスは完全にWindowsについて説明されていますが、必要なライブラリはすべてクロスプラットフォームであるため、Linuxで簡単に繰り返すことができます。
記事を書いた後、私はこのハッキング方法に出会いましたが、私が理解しているように、それはLVLの初期バージョンに関連しています。
すべての情報は情報提供のみを目的として提供されています。 また、ソフトウェア保護を改善するための開発者向け。