Java 为什么这是一个无效的smali寄存器?
我注入了这段代码Java 为什么这是一个无效的smali寄存器?,java,android,reverse-engineering,smali,apktool,Java,Android,Reverse Engineering,Smali,Apktool,我注入了这段代码invoke static{p0},Lcom/ought7/talkingtomcandyrun/Toast;->在反编译的应用程序中显示(Landroid/content/Context;)V 像这样: .line 70 move-object/from16 v0, p0 iget-object v0, v0, Lcom/bee7/gamewall/dialogs/BannerNotificationDialog;->sharedPreferencesN
invoke static{p0},Lcom/ought7/talkingtomcandyrun/Toast;->在反编译的应用程序中显示(Landroid/content/Context;)V
像这样:
.line 70
move-object/from16 v0, p0
iget-object v0, v0, Lcom/bee7/gamewall/dialogs/BannerNotificationDialog;->sharedPreferencesNotificationsHelper:Lcom/bee7/sdk/common/util/SharedPreferencesNotificationsHelper;
move-object/from16 v21, v0
sget v22, Lcom/bee7/gamewall/BannerNotification;->NUMBER_OF_REWARD_BANNER_NOTIFICATIONS_LAYOUTS:I
invoke-virtual/range {v21 .. v22}, Lcom/bee7/sdk/common/util/SharedPreferencesNotificationsHelper;->getNextRewardNotificationLayout(I)I
.line 76
sget v21, Lcom/bee7/gamewall/R$layout;->gamewall_banner_notification_reward_0:I
move-object/from16 v0, p0
move/from16 v1, v21
invoke-virtual {v0, v1}, Lcom/bee7/gamewall/dialogs/BannerNotificationDialog;->setContentView(I)V
invoke-static {p0}, Lcom/outfit7/talkingtomcandyrun/Toast;->show(Landroid/content/Context;)V
.line 77
const/16 v21, 0x1
move/from16 v0, v21
move-object/from16 v1, p0
iput v0, v1, Lcom/bee7/gamewall/dialogs/BannerNotificationDialog;->numberOfOffersInBannerNotification:I
但当我尝试使用apktool构建它时,我收到了以下消息:
com.ought7.talkingtomcandyrun\smali\com\bee7\gamewall\dialogs\BannerNotificationDialog.smali[179106]无效寄存器:v25。必须介于v0和v15之间(含v0和v15)。
参考这一行:invoke virtual{v0,v1},Lcom/bee7/gamewall/dialogs/BannerNotificationDialog;->setContentView(I)V
为什么我会犯这个错误?我甚至没有在代码中看到registerv25
编辑:
我在其他一些应用程序中尝试了它,并注意到该错误总是将1添加到最高寄存器。因此,如果方法中的最高寄存器是
v17
,它会说无效寄存器:v18
如果您查看调用静态操作码的文档,您将看到它使用4位编码每个参数寄存器,这只允许它引用寄存器0-15
p0
是一个参数寄存器,参数寄存器位于方法中“已分配”寄存器范围的末尾
因此,如果该方法有30个寄存器(.registers 30
),并且有5个(非长/非双精度)参数,那么该方法的参数将作为v25-v29传入。pNN
寄存器只是末尾这一系列寄存器的别名。因此在本例中,p0
是v25
的别名p1
是v26
等的别名
另外,在计算参数数量时,不要忘记为非静态方法包含隐式this
参数,它始终是第一个传递的参数。i、 e.p0
在这种情况下,最好使用invoke static/range,它接受一个连续的寄存器范围,并可以直接引用这些更高的寄存器
e、 g
另一个选项是使用move object
临时将p0
中的值与较低的寄存器交换,然后再交换回来。当然,为了进行交换,您需要找到或创建一个未使用的寄存器。它在我反编译的其他应用程序中运行良好。在我看来,move object
在这种情况下可能不起作用。至少对我来说不是这样。它应该使用move object/16
版本。move object和move object/16之间的唯一区别是,源寄存器的move object限制为v0-v255。移动对象/16可参考整个v0-v65535范围。假设您会根据需要选择正确的移动对象变量。嗯,这很奇怪,因为在我的例子中,p0是v18寄存器,所以当我使用简单的移动对象时,应用程序没有编译。但从你的回答中,我了解到它在非/16版本中应该工作得很好?这里确实没有足够的上下文来回答你的问题。我建议你根据自己的具体情况提出一个实际问题。
invoke-static/range {p0}, Lcom/outfit7/talkingtomcandyrun/Toast;->show(Landroid/content/Context;)V`