2012-09-28 8 views
11

Ich reverse-Engineering einige Android-APKs, um einige Instrumente für Funktionstests hinzuzufügen. Ich möchte wissen, ein smali wie folgt festgelegt, wie kann ich so etwas wieÄndern von .Smali-Dateien

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

zu jeder Methode in den .smali Dateien hinzufügen.

.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 

Antwort

28

Der eigentliche Code zum Aufrufen von Log.e() ist ziemlich einfach. Es würde etwas wie gehören:

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 

Allerdings müssen Sie vorsichtig sein, was registriert Sie verwenden. Sie möchten ein Register nicht überlisten, das einen Wert hat, der später verwendet wird.

So haben Sie 2 Möglichkeiten:

  1. Finden „sicher“ nicht verwendeten Register und diejenigen verwenden (kann tückisch sein)
  2. die Registerzählung des Verfahrens erhöhen, und verwenden Sie die neu Register erstellt

Für Nummer 2 ist das einzige Problem, dass die neuen Register nicht am Ende des Registerbereichs liegen - sie befinden sich tatsächlich kurz vor der Registrierung des Parameters.

Nehmen wir zum Beispiel eine Methode, die insgesamt 5 Register hat (.registers 5), von denen 3 Parameterregister sind. Sie haben also v0 und v1, die Nicht-Parameter-Register sind, und p0-p2, die die 3-Parameter-Register sind und Aliase für v2-v4 sind.

Wenn Sie zwei weitere Register hinzufügen müssen, stossen Sie auf .registers 7. Die Parameterregister bleiben am Ende des Registerbereichs, so dass p0-p2 nun nach v4-v6 umbenannt wird und v2 und v3 die neuen Register sind, die sicher zu verwenden sind.

+0

Dies erklärt, warum meine Bemühungen würden manchmal aus unerklärlichen Gründen zu einem Absturz führen. Vielen Dank! –

+1

Dies ist eine großartige, knappe Antwort, aber ich denke, es gibt einen kleinen Tippfehler am Ende der Aufruf-Statik und es braucht ein; nach Ljava/lang/Throwable – GeekyDeaks

+0

Das ist behoben, danke. – JesusFreke

10

Ein Kommentar zu Registern, der für einen Kommentar zu JesusFrekes Antwort zu groß war. Es ist erwähnenswert, dass, wenn Sie .local Direktiven anstelle von .register Direktiven haben, das Nummernschema wird anders sein. Grob gesagt, beziehen sich die Richtlinien auf die folgende Weise:

.registers = .locals + NUMBER_OF_PARAMETERS 

Wenn Sie also eine Funktion haben, die 4 Parameter und verwendet 3 weitere Register, die Richtlinien, die bis sind .registers 7 oder .locals 3 zeigen konnte.

Und Sie werden das Register Setup erhalten wie folgt:

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

Quelle: https://github.com/JesusFreke/smali/wiki/Registers

3

Eine der einfacheren Möglichkeiten smali Code hinzuzufügen, ist die Java-Code in einem Test android app zu schreiben. Demontieren Sie mit apktool. Sehen Sie sich die Smali-Dateien an, um den Smali-Code zu identifizieren und ihn für das Injizieren in andere Apps zu verwenden, die Sie demontiert haben.

herunterladen apktool hier: http://ibotpeaches.github.io/Apktool/