いくつかのAndroid apksをリバースエンジニアリングして、機能テスト用のインストルメンテーションを追加しました。次のようなスマリを指定して、次のようなものを追加する方法を知りたいです。
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
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つのオプションがあります。
2番目の場合、唯一の落とし穴は、新しいレジスタがレジスタ範囲の最後にないことです。実際には、パラメータレジスタの直前にあります。
たとえば、合計5つのレジスタ(.registers 5
)があり、そのうち3つがパラメータレジスタであるメソッドを考えてみましょう。したがって、非パラメータレジスタであるv0とv1、および3つのパラメータレジスタであり、v2-v4のエイリアスであるp0-p2があります。
さらに2つのレジスタを追加する必要がある場合は、それを.registers 7
に増やします。パラメータレジスタはレジスタ範囲の最後に留まるため、p0-p2はv4-v6にエイリアスされ、v2とv3は安全に使用できる新しいレジスタです。
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
Smaliコードを追加する簡単な方法の1つは、テストでJavaコードを書くことですAndroidアプリ。apktoolを使用して逆アセンブルします。smaliファイルを見てください。 smaliコードを特定し、逆アセンブルした他のアプリに挿入するために使用します。
ここからapktoolをダウンロードしてください: http://ibotpeaches.github.io/Apktool/