Add codes to smali sources

John :

I have a smali code with the related source:

original_file.java:

package com.android.commands.locksettings;

import android.os.ResultReceiver;
import android.os.ServiceManager;
import android.os.ShellCallback;

import com.android.internal.os.BaseCommand;
import com.android.internal.widget.ILockSettings;

import java.io.FileDescriptor;
import java.io.PrintStream;

public final class LockSettingsCmd extends BaseCommand {

    private static final String USAGE =
            "usage: locksettings set-pattern [--old OLD_CREDENTIAL] NEW_PATTERN\n" +
            "       locksettings set-pin [--old OLD_CREDENTIAL] NEW_PIN\n" +
            "       locksettings set-password [--old OLD_CREDENTIAL] NEW_PASSWORD\n" +
            "       locksettings clear [--old OLD_CREDENTIAL]\n" +
            "\n" +
            "locksettings set-pattern: sets a pattern\n" +
            "    A pattern is specified by a non-separated list of numbers that index the cell\n" +
            "    on the pattern in a 1-based manner in left to right and top to bottom order,\n" +
            "    i.e. the top-left cell is indexed with 1, whereas the bottom-right cell\n" +
            "    is indexed with 9. Example: 1234\n" +
            "\n" +
            "locksettings set-pin: sets a PIN\n" +
            "\n" +
            "locksettings set-password: sets a password\n" +
            "\n" +
            "locksettings clear: clears the unlock credential\n";

    public static void main(String[] args) {
        (new LockSettingsCmd()).run(args);
    }

    @Override
    public void onShowUsage(PrintStream out) {
        out.println(USAGE);
    }

    @Override
    public void onRun() throws Exception {
        ILockSettings lockSettings = ILockSettings.Stub.asInterface(
                ServiceManager.getService("lock_settings"));
        lockSettings.asBinder().shellCommand(FileDescriptor.in, FileDescriptor.out,
                FileDescriptor.err, getRawArgs(), new ShellCallback(), new ResultReceiver(null) {});
    }
}

original_file.smali:

.class public final Lcom/android/commands/locksettings/LockSettingsCmd;
.super Lcom/android/internal/os/BaseCommand;
.source "LockSettingsCmd.java"


# static fields
.field private static final USAGE:Ljava/lang/String; = "usage: locksettings set-pattern [--old OLD_CREDENTIAL] NEW_PATTERN\n       locksettings set-pin [--old OLD_CREDENTIAL] NEW_PIN\n       locksettings set-password [--old OLD_CREDENTIAL] NEW_PASSWORD\n       locksettings clear [--old OLD_CREDENTIAL]\n\nlocksettings set-pattern: sets a pattern\n    A pattern is specified by a non-separated list of numbers that index the cell\n    on the pattern in a 1-based manner in left to right and top to bottom order,\n    i.e. the top-left cell is indexed with 1, whereas the bottom-right cell\n    is indexed with 9. Example: 1234\n\nlocksettings set-pin: sets a PIN\n\nlocksettings set-password: sets a password\n\nlocksettings clear: clears the unlock credential\n"


# direct methods
.method public constructor <init>()V
    .registers 1

    .prologue
    .line 29
    invoke-direct {p0}, Lcom/android/internal/os/BaseCommand;-><init>()V

    return-void
.end method

.method public static main([Ljava/lang/String;)V
    .registers 2
    .param p0, "args"    # [Ljava/lang/String;

    .prologue
    .line 50
    new-instance v0, Lcom/android/commands/locksettings/LockSettingsCmd;

    invoke-direct {v0}, Lcom/android/commands/locksettings/LockSettingsCmd;-><init>()V

    invoke-virtual {v0, p0}, Lcom/android/commands/locksettings/LockSettingsCmd;->run([Ljava/lang/String;)V

    const/4 v0, 0x0

    invoke-virtual {v0, p0}, Ljava/io/PrintStream;->println(Ljava/lang/Object;)V

    .line 51
    return-void
.end method


# virtual methods
.method public onRun()V
    .registers 10
    .annotation system Ldalvik/annotation/Throws;
        value = {
            Ljava/lang/Exception;
        }
    .end annotation

    .prologue
    .line 61
    const-string/jumbo v0, "lock_settings"

    invoke-static {v0}, Landroid/os/ServiceManager;->getService(Ljava/lang/String;)Landroid/os/IBinder;

    move-result-object v0

    .line 60
    invoke-static {v0}, Lcom/android/internal/widget/ILockSettings$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/widget/ILockSettings;

    move-result-object v7

    .line 62
    .local v7, "lockSettings":Lcom/android/internal/widget/ILockSettings;
    invoke-interface {v7}, Lcom/android/internal/widget/ILockSettings;->asBinder()Landroid/os/IBinder;

    move-result-object v0

    sget-object v1, Ljava/io/FileDescriptor;->in:Ljava/io/FileDescriptor;

    sget-object v2, Ljava/io/FileDescriptor;->out:Ljava/io/FileDescriptor;

    .line 63
    sget-object v3, Ljava/io/FileDescriptor;->err:Ljava/io/FileDescriptor;

    invoke-virtual {p0}, Lcom/android/commands/locksettings/LockSettingsCmd;->getRawArgs()[Ljava/lang/String;

    move-result-object v4

    new-instance v5, Landroid/os/ShellCallback;

    invoke-direct {v5}, Landroid/os/ShellCallback;-><init>()V

    new-instance v6, Lcom/android/commands/locksettings/LockSettingsCmd$1;

    const/4 v8, 0x0

    invoke-direct {v6, p0, v8}, Lcom/android/commands/locksettings/LockSettingsCmd$1;-><init>(Lcom/android/commands/locksettings/LockSettingsCmd;Landroid/os/Handler;)V

    .line 62
    invoke-interface/range {v0 .. v6}, Landroid/os/IBinder;->shellCommand(Ljava/io/FileDescriptor;Ljava/io/FileDescriptor;Ljava/io/FileDescriptor;[Ljava/lang/String;Landroid/os/ShellCallback;Landroid/os/ResultReceiver;)V

    .line 64
    return-void
.end method

.method public onShowUsage(Ljava/io/PrintStream;)V
    .registers 3
    .param p1, "out"    # Ljava/io/PrintStream;

    .prologue
    .line 55
    const-string/jumbo v0, "usage: locksettings set-pattern [--old OLD_CREDENTIAL] NEW_PATTERN\n       locksettings set-pin [--old OLD_CREDENTIAL] NEW_PIN\n       locksettings set-password [--old OLD_CREDENTIAL] NEW_PASSWORD\n       locksettings clear [--old OLD_CREDENTIAL]\n\nlocksettings set-pattern: sets a pattern\n    A pattern is specified by a non-separated list of numbers that index the cell\n    on the pattern in a 1-based manner in left to right and top to bottom order,\n    i.e. the top-left cell is indexed with 1, whereas the bottom-right cell\n    is indexed with 9. Example: 1234\n\nlocksettings set-pin: sets a PIN\n\nlocksettings set-password: sets a password\n\nlocksettings clear: clears the unlock credential\n"

    invoke-virtual {p1, v0}, Ljava/io/PrintStream;->println(Ljava/lang/String;)V

    .line 56
    return-void
.end method

I want to edit the above smali file and add codes to main function So I wrote the same codes in a new java file and compiled it to class file using javac then using dx.jar convert it to classes.dex and redecompiled the dex file and get the smali code to inject but on each time a add the code the file crached and never work.

my_code.java: (just a test to print the coming args)

  public static void main(String[] args) {
        for(String s : args){
            System.out.println(s);
        }
    }

    @Override
    public void onShowUsage(PrintStream out) {
        out.println(USAGE);
    }

my_code.smali:

.method public static main([Ljava/lang/String;)V
    .registers 5

    .prologue
    .line 50
    array-length v1, p0

    const/4 v0, 0x0

    :goto_2
    if-ge v0, v1, :cond_e

    aget-object v2, p0, v0

    .line 51
    sget-object v3, Ljava/lang/System;->out:Ljava/io/PrintStream;

    invoke-virtual {v3, v2}, Ljava/io/PrintStream;->println(Ljava/lang/String;)V

    .line 50
    add-int/lit8 v0, v0, 0x1

    goto :goto_2

    .line 54
    :cond_e
    return-void
.end method

Now how can i inject the my_code.smali to original_file.smali ?

frogatto :

When you're editing smali code you should carefully take care of registers. my_code's main method has 5 registers (i.e. 4 local and 1 param) and original_file's main method has 2 registers (i.e. 1 local and 1 param). Before adding the my_code to original_file, you should decide how may registers you would need. In this example, 5 registers (i.e. 4 local and 1 param) is enough.

The final main method (without .line and .param directives):

.method public static main([Ljava/lang/String;)V
    .registers 5

    .prologue
    array-length v1, p0

    const/4 v0, 0x0

    :goto_2
    if-ge v0, v1, :cond_e

    aget-object v2, p0, v0

    sget-object v3, Ljava/lang/System;->out:Ljava/io/PrintStream;

    invoke-virtual {v3, v2}, Ljava/io/PrintStream;->println(Ljava/lang/String;)V

    add-int/lit8 v0, v0, 0x1

    goto :goto_2

    :cond_e
    new-instance v0, Lcom/android/commands/locksettings/LockSettingsCmd;

    invoke-direct {v0}, Lcom/android/commands/locksettings/LockSettingsCmd;-><init>()V

    invoke-virtual {v0, p0}, Lcom/android/commands/locksettings/LockSettingsCmd;->run([Ljava/lang/String;)V

    const/4 v0, 0x0

    invoke-virtual {v0, p0}, Ljava/io/PrintStream;->println(Ljava/lang/Object;)V

    return-void
.end method

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=159183&siteId=1