14

機能テスト用のインストルメンテーションを追加するために、いくつかのandroidapkをリバースエンジニアリングしました。次のようなスマリを与えられて知りたいのですが、どうすれば次のようなものを追加できますか

Log.e(TAG, "some descritpion", e);

.smaliファイルの各メソッドに。

.class public Ld;
.super Landroid/view/View;
.source "SourceFile"


# instance fields
.field a:Z

.field b:Lcom/rovio/ka3d/App;


# direct methods
.method public constructor <init>(Lcom/rovio/ka3d/App;)V
    .locals 2
    .parameter

    .prologue
    const/4 v1, 0x1

    .line 317
    invoke-direct {p0, p1}, Landroid/view/View;-><init>(Landroid/content/Context;)V

    .line 313
    const/4 v0, 0x0

    iput-boolean v0, p0, Ld;->a:Z

    .line 314
    const/4 v0, 0x0

    iput-object v0, p0, Ld;->b:Lcom/rovio/ka3d/App;

    .line 318
    iput-object p1, p0, Ld;->b:Lcom/rovio/ka3d/App;

    .line 319
    invoke-virtual {p0, v1}, Ld;->setFocusable(Z)V

    .line 320
    invoke-virtual {p0, v1}, Ld;->setFocusableInTouchMode(Z)V

    .line 321
    return-void
.end method


# virtual methods
.method public a(Z)V
    .locals 4
    .parameter

    .prologue
    const/4 v3, 0x0

    .line 325
    invoke-virtual {p0}, Ld;->getContext()Landroid/content/Context;

    move-result-object v0

    const-string v1, "input_method"

    invoke-virtual {v0, v1}, Landroid/content/Context;->getSystemService(Ljava/lang/String;)Ljava/lang/Object;

    move-result-object v0

    check-cast v0, Landroid/view/inputmethod/InputMethodManager;

    .line 326
    invoke-virtual {p0}, Ld;->getWindowToken()Landroid/os/IBinder;

    move-result-object v1

    invoke-virtual {v0, v1, v3}, Landroid/view/inputmethod/InputMethodManager;->hideSoftInputFromWindow(Landroid/os/IBinder;I)Z

    .line 327
    if-eqz p1, :cond_0

    .line 329
    invoke-virtual {p0}, Ld;->getWindowToken()Landroid/os/IBinder;

    move-result-object v1

    const/4 v2, 0x2

    invoke-virtual {v0, v1, v2, v3}, Landroid/view/inputmethod/InputMethodManager;->toggleSoftInputFromWindow(Landroid/os/IBinder;II)V

    .line 330
    invoke-virtual {p0}, Ld;->requestFocus()Z

    .line 333
    :cond_0
    iput-boolean p1, p0, Ld;->a:Z

    .line 334
    return-void
.end method

.method public onCreateInputConnection(Landroid/view/inputmethod/EditorInfo;)Landroid/view/inputmethod/InputConnection;
    .locals 3
    .parameter

    .prologue
    .line 343
    new-instance v0, La;

    iget-object v1, p0, Ld;->b:Lcom/rovio/ka3d/App;

    const/4 v2, 0x0

    invoke-direct {v0, v1, p0, v2}, La;-><init>(Lcom/rovio/ka3d/App;Landroid/view/View;Z)V

    .line 345
    const/4 v1, 0x0

    iput-object v1, p1, Landroid/view/inputmethod/EditorInfo;->actionLabel:Ljava/lang/CharSequence;

    .line 350
    const v1, 0x80090

    iput v1, p1, Landroid/view/inputmethod/EditorInfo;->inputType:I

    .line 351
    const/high16 v1, 0x1000

    iput v1, p1, Landroid/view/inputmethod/EditorInfo;->imeOptions:I

    .line 352
    return-object v0
.end method
4

4 に答える 4

34

Log.e() を呼び出す実際のコードはかなり単純です。次のようなものが含まれます。

const-string v0, "MyTag"
const-string v1, "Something to print"
# assuming you have an exception in v2...
invoke-static {v0, v1, v2}, Landroid/util/Log;->e(Ljava/lang/String;Ljava/lang/String;Ljava/lang/Throwable;)I

ただし、使用するレジスタには注意が必要です。後で使用する値を持つレジスタを上書きしたくありません。

したがって、2 つのオプションがあります。

  1. 「安全な」未使用のレジスタを見つけて、それらを使用します (注意が必要な場合があります)。
  2. メソッドのレジスタ数を増やし、新しく作成したレジスタを使用する

番号 2 の場合、唯一の問題は、新しいレジスタがレジスタ範囲の最後ではなく、実際にはパラメータ レジスタの直前にあるということです。

たとえば、合計 5 つのレジスタ ( .registers 5) があり、そのうち 3 つがパラメータ レジスタであるメソッドを考えてみましょう。したがって、非パラメーター レジスターである v0 と v1 と、3 つのパラメーター レジスターであり、v2-v4 のエイリアスである p0-p2 があります。

さらに 2 つのレジスタを追加する必要がある場合は、最大で.registers 7. パラメータ レジスタはレジスタ範囲の最後にあるため、p0 ~ p2 は v4 ~ v6 にエイリアスされ、v2 と v3 は安全に使用できる新しいレジスタです。

于 2012-09-28T23:37:03.873 に答える
13

JesusFreke の回答へのコメントには大きすぎるレジスタに関するコメント。.localディレクティブの代わりにディレクティブがある場合.register、番号スキームが異なることに注意してください。大まかに言えば、ディレクティブは次のように関連しています。

.registers = .locals + NUMBER_OF_PARAMETERS

したがって、4 つのパラメーターを持ち、さらに 3 つのレジスターを使用する関数がある場合、表示されるディレクティブは.registers 7または.locals 3です。

そして、次のようにレジスタをセットアップします。

v0
v1
v2
v3 <==> p0
v4 <==> p1
v5 <==> p2
v6 <==> p3

ソース: https://github.com/JesusFreke/smali/wiki/Registers

于 2012-10-26T16:24:11.210 に答える
4

小さなコードを追加する簡単な方法の 1 つは、テスト用の Android アプリに Java コードを記述することです。apktool を使用して逆アセンブルします。smali ファイルを調べて smali コードを特定し、逆アセンブルした他のアプリに挿入するために使用します。

ここから apktool をダウンロードしてください: http://ibotpeaches.github.io/Apktool/

于 2013-08-02T12:06:52.183 に答える
1

私が常に使用しており、FileWritter.javaそのような目的のためにクラスを作成した別のオプションは、お気に入りの IDEA ( Intellij/Android Studio ) を開いて、正しい IDEA 用のJava2Smaliプラグインをダウンロードし、プラグインを実行することです。

要するに :

  • AndroidStudio/Intellijを開きます
  • ファイル/設定に移動します
  • 検索バーをタップして、「プラグイン」を検索します
  • プラグイン UI に到達したら、そこにある [ MarketPlace ] タブにいることを確認してください。
  • java2smaliを検索してインストールし、IDEA を再起動します。

ここにjava2smaliプラグインへのリンクがあります

使い方?

  • Java でコードを記述します (Kotlin ではなく Java で記述することをお勧めします。これを smali に逆コンパイルしようとすると、逆コンパイルしたアプリがサポートしていない可能性がある Kotlin->Java から余分なコードが取得されるためです。 Java で記述されているか、Kotlin ライブラリが含まれていない可能性があります)
  • smali に変換したいコードを書いたら、 Build/Compile To Smai をクリックします。
  • コンパイルされた Smali コードに自動的にリダイレクトされます (その Smali コードは、プロジェクトで元の Java コードの隣に生成されます)。
  • この時点から、必要なことは何でも実行できます。コンパイルされた Smali ファイル内を調べて、目的のコードが呼び出される行を見つけるか、必要に応じて Smali ファイル全体を実装することができます。

================================================== ====================== 乾杯!

于 2021-02-23T23:38:29.637 に答える