给smali源添加代码
Add codes to smali sources
我有一个smali代码,相关来源:
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;
const/4 v8, 0x0
invoke-direct {v6, p0, v8}, Lcom/android/commands/locksettings/LockSettingsCmd;-><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
我想编辑上面的smali文件并添加代码到main
函数
所以我在一个新的 java 文件中编写了相同的代码,并使用 javac
将其编译为 class
文件,然后使用 dx.jar
将其转换为 classes.dex
并重新编译 dex
文件并获取要注入的 smali 代码,但每次添加代码时,文件都会崩溃,无法正常工作。
my_code.java:(只是打印即将到来的参数的测试)
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
现在如何将 my_code.smali
注入 original_file.smali
?
在编辑 smali 代码时,您应该小心处理寄存器。 my_code
的主要方法有 5 个寄存器(即 4 个本地和 1 个参数),original_file
的主要方法有 2 个寄存器(即 1 个本地和 1 个参数)。在将 my_code
添加到 original_file
之前,您应该决定需要多少寄存器。在此示例中,5 个寄存器(即 4 个本地寄存器和 1 个参数寄存器)就足够了。
最后的 main
方法(没有 .line
和 .param
指令):
.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
我有一个smali代码,相关来源:
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;
const/4 v8, 0x0
invoke-direct {v6, p0, v8}, Lcom/android/commands/locksettings/LockSettingsCmd;-><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
我想编辑上面的smali文件并添加代码到main
函数
所以我在一个新的 java 文件中编写了相同的代码,并使用 javac
将其编译为 class
文件,然后使用 dx.jar
将其转换为 classes.dex
并重新编译 dex
文件并获取要注入的 smali 代码,但每次添加代码时,文件都会崩溃,无法正常工作。
my_code.java:(只是打印即将到来的参数的测试)
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
现在如何将 my_code.smali
注入 original_file.smali
?
在编辑 smali 代码时,您应该小心处理寄存器。 my_code
的主要方法有 5 个寄存器(即 4 个本地和 1 个参数),original_file
的主要方法有 2 个寄存器(即 1 个本地和 1 个参数)。在将 my_code
添加到 original_file
之前,您应该决定需要多少寄存器。在此示例中,5 个寄存器(即 4 个本地寄存器和 1 个参数寄存器)就足够了。
最后的 main
方法(没有 .line
和 .param
指令):
.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