为什么这是一个无效的 smali 寄存器?

dug*_*gof 5 java android reverse-engineering smali apktool

invoke-static {p0}, Lcom/outfit7/talkingtomcandyrun/Toast;->show(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
Run Code Online (Sandbox Code Playgroud)

但是当我尝试使用 apktool 构建它时,我收到以下消息:

com.outfit7.talkingtomcandyrun\smali\com\bee7\gamewall\dialogs\BannerNotificationDialog.smali[179,106] Invalid register: v25. Must be between v0 and v15, inclusive.

参考这一行:invoke-virtual {v0, v1}, Lcom/bee7/gamewall/dialogs/BannerNotificationDialog;->setContentView(I)V

为什么我收到这个错误?我什至没有v25在代码中看到注册。

编辑:

我用其他一些应用程序尝试过,发现错误总是在最高寄存器上加 1。所以如果方法中的最高寄存器是v17它会说Invalid register: v18.

Jes*_*eke 6

如果您查看操作码的文档invoke-static,您会发现它使用 4 位对每个参数寄存器进行编码,这仅允许它引用寄存器 0-15。

p0是一个参数寄存器,参数寄存器位于方法中“分配”寄存器范围的末尾。

因此,如果该方法有 30 个寄存器 ( .registers 30),并且有 5 个(非长/非双)参数,则该方法的参数将以 v25-v29 形式传入。这些pNN寄存器只是最后这个寄存器范围的别名。所以在本例中,p0是 的别名v25。是等p1的别名。v26

另外,在计算参数数量时,不要忘记包含this非静态方法的隐式参数,它始终是第一个传递的参数。IEp0

在这种情况下,最好的选择是使用invoke-static/range,它接受连续的寄存器范围,并且可以直接引用这些较高的寄存器。

例如

invoke-static/range {p0}, Lcom/outfit7/talkingtomcandyrun/Toast;->show(Landroid/content/Context;)V`
Run Code Online (Sandbox Code Playgroud)

另一种选择是暂时move-object将值p0与较低的寄存器交换,然后再将其交换回来。当然,您需要找到或创建一个未使用的寄存器才能进行交换。