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

为什么我会犯这个错误?我甚至没有在代码中看到register
v25

编辑:


我在其他一些应用程序中尝试了它,并注意到该错误总是将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`