Android 增加Smali中的本地寄存器并使用新寄存器
嗨,我想了解如何在smali虚拟方法中正确增加寄存器。以便注入将使用新寄存器的代码 作为参考,我已经阅读了以下内容: 这是我的java代码:Android 增加Smali中的本地寄存器并使用新寄存器,android,logcat,smali,Android,Logcat,Smali,嗨,我想了解如何在smali虚拟方法中正确增加寄存器。以便注入将使用新寄存器的代码 作为参考,我已经阅读了以下内容: 这是我的java代码: public void toastMsg(字符串消息){ Toast Toast=Toast.makeText(this,msg,Toast.LENGTH\u LONG); toast.setGravity(Gravity.CENTER,0,0); toast.show(); } 在斯马里,它看起来像这样 .method public toastMsg(
public void toastMsg(字符串消息){
Toast Toast=Toast.makeText(this,msg,Toast.LENGTH\u LONG);
toast.setGravity(Gravity.CENTER,0,0);
toast.show();
}
在斯马里,它看起来像这样
.method public toastMsg(Ljava/lang/String;)V
.locals 2
const/4 v0, 0x1
.line 26
invoke-static {p0, p1, v0}, Landroid/widget/Toast;->makeText(Landroid/content/Context;Ljava/lang/CharSequence;I)Landroid/widget/Toast;
move-result-object p1
const/4 v0, 0x0
const/16 v1, 0x11
.line 27
invoke-virtual {p1, v1, v0, v0}, Landroid/widget/Toast;->setGravity(III)V
.line 28
invoke-virtual {p1}, Landroid/widget/Toast;->show()V
return-void
.end method
v0 - free local register
v1 - free local register
v2 => p0 (this)
v3 => p1 (the string parameter - our msg)
.method public toastMsg(Ljava/lang/String;)V
.locals 3 <--- increased here by 1
const/4 v0, 0x1
.line 25
invoke-static {p0, p1, v0}, Landroid/widget/Toast;->makeText(Landroid/content/Context;Ljava/lang/CharSequence;I)Landroid/widget/Toast;
move-result-object p1
const/4 v0, 0x0
const/16 v1, 0x11
.line 26
invoke-virtual {p1, v1, v0, v0}, Landroid/widget/Toast;->setGravity(III)V
.line 27
invoke-virtual {p1}, Landroid/widget/Toast;->show()V
# PATCH here useing the new regiser
const-string v2, "MYAWESOMELOG"
invoke-static {v2, p1}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I
# END PATCH
return-void
.end method
v0 - 0x1
v1 - free local register
v2 - "MYAWESOMELOG"
v3 => p0 (this)
v4 => p1 (android/widget/Toast)
现在据我所知,上述toastMsg方法的smali片段总共包含4个寄存器
.locals=2+1表示对象(this),1表示toastMsg方法的参数(String msg)
所以我的寄存器是这样的
.method public toastMsg(Ljava/lang/String;)V
.locals 2
const/4 v0, 0x1
.line 26
invoke-static {p0, p1, v0}, Landroid/widget/Toast;->makeText(Landroid/content/Context;Ljava/lang/CharSequence;I)Landroid/widget/Toast;
move-result-object p1
const/4 v0, 0x0
const/16 v1, 0x11
.line 27
invoke-virtual {p1, v1, v0, v0}, Landroid/widget/Toast;->setGravity(III)V
.line 28
invoke-virtual {p1}, Landroid/widget/Toast;->show()V
return-void
.end method
v0 - free local register
v1 - free local register
v2 => p0 (this)
v3 => p1 (the string parameter - our msg)
.method public toastMsg(Ljava/lang/String;)V
.locals 3 <--- increased here by 1
const/4 v0, 0x1
.line 25
invoke-static {p0, p1, v0}, Landroid/widget/Toast;->makeText(Landroid/content/Context;Ljava/lang/CharSequence;I)Landroid/widget/Toast;
move-result-object p1
const/4 v0, 0x0
const/16 v1, 0x11
.line 26
invoke-virtual {p1, v1, v0, v0}, Landroid/widget/Toast;->setGravity(III)V
.line 27
invoke-virtual {p1}, Landroid/widget/Toast;->show()V
# PATCH here useing the new regiser
const-string v2, "MYAWESOMELOG"
invoke-static {v2, p1}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I
# END PATCH
return-void
.end method
v0 - 0x1
v1 - free local register
v2 - "MYAWESOMELOG"
v3 => p0 (this)
v4 => p1 (android/widget/Toast)
现在让我们假设我想注入下面的logcat行,但我没有任何免费的本地寄存器
const-string v3, "MYAWESOMELOG"
invoke-static {v3, p1}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I
注入logcat代码当然会阻塞v3寄存器,但p1的值会丢失,因为v3==p1
我想向.locals中添加一个额外的寄存器,以便它可以容纳字符串。而且什么都不碰。假设基于引用,我可以简单地增加.locals
变量上的数字,它应该会给我更多的本地寄存器来使用
因此,如果.3
这个方法中的寄存器现在看起来应该是这样的
v0 - free local register
v1 - free local register
v2 - new free local register ?
v3 => p0 (this)
v4 => p1 (the string parameter - our msg)
因此,如果我理解正确,本地寄存器v2现在应该是全新的,可以免费使用
因此,下面的logcat smali代码我希望可以使用新的寄存器v2来存储标记,并且仍然保留字符串参数(p1)
因此,修改后的代码现在看起来是这样的
.method public toastMsg(Ljava/lang/String;)V
.locals 2
const/4 v0, 0x1
.line 26
invoke-static {p0, p1, v0}, Landroid/widget/Toast;->makeText(Landroid/content/Context;Ljava/lang/CharSequence;I)Landroid/widget/Toast;
move-result-object p1
const/4 v0, 0x0
const/16 v1, 0x11
.line 27
invoke-virtual {p1, v1, v0, v0}, Landroid/widget/Toast;->setGravity(III)V
.line 28
invoke-virtual {p1}, Landroid/widget/Toast;->show()V
return-void
.end method
v0 - free local register
v1 - free local register
v2 => p0 (this)
v3 => p1 (the string parameter - our msg)
.method public toastMsg(Ljava/lang/String;)V
.locals 3 <--- increased here by 1
const/4 v0, 0x1
.line 25
invoke-static {p0, p1, v0}, Landroid/widget/Toast;->makeText(Landroid/content/Context;Ljava/lang/CharSequence;I)Landroid/widget/Toast;
move-result-object p1
const/4 v0, 0x0
const/16 v1, 0x11
.line 26
invoke-virtual {p1, v1, v0, v0}, Landroid/widget/Toast;->setGravity(III)V
.line 27
invoke-virtual {p1}, Landroid/widget/Toast;->show()V
# PATCH here useing the new regiser
const-string v2, "MYAWESOMELOG"
invoke-static {v2, p1}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I
# END PATCH
return-void
.end method
v0 - 0x1
v1 - free local register
v2 - "MYAWESOMELOG"
v3 => p0 (this)
v4 => p1 (android/widget/Toast)
java.lang.VerifyError:验证程序拒绝类
com.example.androidtest.MainActivity:void com.example.androidtest.MainActivity.toastMsg(java.lang.String)未能
验证:void com.example.androidtest.MainActivity.toastMsg(java.lang.String):
[0x10]寄存器v4的类型引用为:android.widget.Toast,但预期的精确引用为:java.lang.String
(声明'com.example.androidtest.MainActivity'出现在
/data/app/com.example.androidtest-m1NPS9_tJaTgZLY7-1Ev6w==/base.apk)
我似乎把寄存器弄乱了,但我不太明白问题出在哪里。将.locals
增加1应该会给我一个额外的寄存器,并且还会自动向下移动参数引用,因此v4应该指向p1,并且是一个字符串,但它指向的是android.widget.Toast
那么,我是否不能在方法中增加.locals
变量并使用新的寄存器?我是否必须声明新的寄存器并以另一种方式初始化它
奇怪的是,似乎已经有一些问题指向了答案,我实际上应该能够增加寄存器
const-string v3, "MYAWESOMELOG"
invoke-static {v3, p1}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I
我非常确信该文件没有使用-p/--no-parameter registers选项进行分解。我只是使用了apktool d中的默认值
这个答案还说我应该能够做到这一点
所以问题是,当我增加
.locals
变量时,为什么没有新的寄存器v2,或者如果有,为什么寄存器没有下移?或者如果所有这些都是正确的,那么可能我没有使用正确的寄存器,也没有在正确的位置注入补丁?问题在于此指令
invoke-static {v2, p1}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I
您将p1作为第二个参数传递,但p1仍然包含toast对象。该方法要求第二个参数使用string对象,而不是toast对象。问题正是JesusFreke所描述的,但我也在错误的位置修补了代码。我试图调用Log方法,但未能理解在函数结束时,
p1
的类型已从String更改为android/widget/Toast
下面使用新寄存器v2工作
.method public toastMsg(Ljava/lang/String;)V
.locals 3
const/4 v0, 0x1
.line 26
# PATCH HERE
const-string v2, "MYAWESOMELOG"
invoke-static {v2, p1}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I
# END PATH
invoke-static {p0, p1, v0}, Landroid/widget/Toast;->makeText(Landroid/content/Context;Ljava/lang/CharSequence;I)Landroid/widget/Toast;
move-result-object p1
const/4 v0, 0x0
const/16 v1, 0x11
.line 27
invoke-virtual {p1, v1, v0, v0}, Landroid/widget/Toast;->setGravity(III)V
.line 28
invoke-virtual {p1}, Landroid/widget/Toast;->show()V
return-void
.end method
下面是一个更深入的解释:
增加.locals
与正常情况一样,在toastMsg方法调用的开始处是这样的
v0 - free local register
v1 - free local register
v2 - free local register
v3 => p0 (this)
v4 => p1 (the string parameter - our msg)
然而,下面几行现在改变了寄存器中的值,观察v4==p1
在执行这些行之前,v4(p1)指向字符串对象(我们的参数msg)
代码段中的移动结果对象p1
之后,寄存器中的值现在如下所示
.method public toastMsg(Ljava/lang/String;)V
.locals 2
const/4 v0, 0x1
.line 26
invoke-static {p0, p1, v0}, Landroid/widget/Toast;->makeText(Landroid/content/Context;Ljava/lang/CharSequence;I)Landroid/widget/Toast;
move-result-object p1
const/4 v0, 0x0
const/16 v1, 0x11
.line 27
invoke-virtual {p1, v1, v0, v0}, Landroid/widget/Toast;->setGravity(III)V
.line 28
invoke-virtual {p1}, Landroid/widget/Toast;->show()V
return-void
.end method
v0 - free local register
v1 - free local register
v2 => p0 (this)
v3 => p1 (the string parameter - our msg)
.method public toastMsg(Ljava/lang/String;)V
.locals 3 <--- increased here by 1
const/4 v0, 0x1
.line 25
invoke-static {p0, p1, v0}, Landroid/widget/Toast;->makeText(Landroid/content/Context;Ljava/lang/CharSequence;I)Landroid/widget/Toast;
move-result-object p1
const/4 v0, 0x0
const/16 v1, 0x11
.line 26
invoke-virtual {p1, v1, v0, v0}, Landroid/widget/Toast;->setGravity(III)V
.line 27
invoke-virtual {p1}, Landroid/widget/Toast;->show()V
# PATCH here useing the new regiser
const-string v2, "MYAWESOMELOG"
invoke-static {v2, p1}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I
# END PATCH
return-void
.end method
v0 - 0x1
v1 - free local register
v2 - "MYAWESOMELOG"
v3 => p0 (this)
v4 => p1 (android/widget/Toast)
我们不再拥有传递到toastMsg方法的原始字符串值
如果我想使用原始的
p1
值,我必须在移动结果对象p1
行之前使用它。或者,我可以再次增加局部变量,并在函数开头复制/存储p1
的结果 好问题:)