1

我想将以下方法调用“send()”添加到 smali 方法中:

invoke-direct {p0}, X->send()V

send() 是当前类的方法。X 是当前类名的通配符。现在我有两个未解决的问题:

  1. 为什么invoke-direct需要注册p0?我认为这是一个参数。

  2. 我是否考虑了 p0 寄存器?如果我只是保留它,是否有可能这个附加代码会使整个应用程序无法编译?如果是这样,我如何找出必须使用哪个寄存器?

我想将此方法调用添加到任意方法。我不知道方法结构,也无法预测任何寄存器的使用情况。因此我需要确切地知道上面代码中的 p0 是否可以改变以及在什么条件下改变。

我提供一个简单的例子来强调我的意图:

假设我们有这种方法,它只读取保存在智能手机上的联系人:

.method private getContacts()Ljava/util/ArrayList;
.locals 12
.annotation system Ldalvik/annotation/Signature;
value = {
"()",
"Ljava/util/ArrayList",
"<",
"Ljava/lang/String;",
">;"
}
.end annotation
.prologue
const/4 v2, 0x0
.line 43
new-instance v7, Ljava/util/ArrayList;
invoke-direct {v7}, Ljava/util/ArrayList;-><init>()V
.line 44
.local v7, "contacts":Ljava/util/ArrayList;, "Ljava/util/ArrayList<Ljava/lang/String;>;"
invoke-virtual {p0}, Lorg/puellen/contacts/MainActivity;->getContentResolver()Landroid/content/ContentResolver;
move-result-object v0
sget-object v1, Landroid/provider/ContactsContract$Contacts;->CONTENT_URI:Landroid/net/Uri;
move-object v3, v2
move-object v4, v2
move-object v5, v2
...

我编写了一个解析器,它自动从 .apk 文件中提取此代码。现在我想通过添加上层方法调用来扩展方法功能。

在这种情况下,我可以简单地在开头添加调用。唯一的区别出现在第 13 行(见评论)

.method private getContacts()Ljava/util/ArrayList;
.locals 12
.annotation system Ldalvik/annotation/Signature;
value = {
"()",
"Ljava/util/ArrayList",
"<",
"Ljava/lang/String;",
">;"
}
.end annotation
.prologue
invoke-direct {p0}, Lorg/my_package/custom_class/MainActivity;->send()V # added method call
const/4 v2, 0x0
.line 43
new-instance v7, Ljava/util/ArrayList;
invoke-direct {v7}, Ljava/util/ArrayList;-><init>()V
.line 44
.local v7, "contacts":Ljava/util/ArrayList;, "Ljava/util/ArrayList<Ljava/lang/String;>;"
invoke-virtual {p0}, Lorg/puellen/contacts/MainActivity;->getContentResolver()Landroid/content/ContentResolver;
move-result-object v0
sget-object v1, Landroid/provider/ContactsContract$Contacts;->CONTENT_URI:Landroid/net/Uri;
move-object v3, v2
move-object v4, v2
move-object v5, v2

直到知道我只是在.prologue之后添加方法调用。但我确信这种行为并不总是有效。有没有“完美”的地方来添加电话?我可以总是在“invoke-direct”中使用p0吗?或者我如何找出可以使用的寄存器?


问题:我可以总是在“invoke-direct”中使用p0吗?或者我如何找出可以使用的寄存器?

答案:“非静态方法的第一个参数始终是调用该方法的对象。” (链接见第一条评论中的打击)。由于我的方法不是静态的,我可以始终使用 p0

现在我只需要知道在哪里放置方法调用。

4

0 回答 0