Apktool回编时Invalid register. Must be between v0 and v15, inclusive..的解决办法

一般我们在自定义修改apk时,难免会对smali代码进行增减删改,再回编的时候可能会遇到如下错误:

Invalid register: vx. Must be between v0 and v15, inclusive.

shakaApktool的中文提示为:

无效寄存器: v20. 必须在 v0 到 v15(含) 之间

其中vx>15,导致回编译错误。

错误原因可能有以下几种情况:

1.引用了不存在的方法参数。

参数个数很容易识别,但是一定要注意传入的方法参数是从p0,还是从p1开始的。根据smali规则,static方法参数从p0开始计数。

所以如果我们引用了不存在的参数,在回编时就会报RT错误。比如一个传入4个参数的static方法,我们修改时却引用到了p4,就会报错。

实例:http://www.52pojie.cn/thread-421963-1-1.html

2.使用vx>15的方式传参调用方法。

根据smali语法,在使用invoke-、iget-等非range形式调用方法,当传参vx>15时就会报RT错误,如下几种情况:

const-string v16, "b57ba656b518a6b145b9a77fabcddcf1f24ed757"
const-string v17, "logging"
invoke-static {v17, v16} ,Landroid/util/Log;->i(Ljava/lang/String;Ljava/lang/String;)I
const-string v20, "1111111"
invoke-static {v20}, LFineT;->printStr00(Ljava/lang/String;)V
这时候需要调整调用方法为 /range 就ok了:

const-string v20, "1111111"
invoke-static/range {v20}, LFineT;->printStr00(Ljava/lang/String;)V
const-string v20, "b57ba656b518a6b145b9a77fabcddcf1f24ed757"
const-string v21, "logging"
invoke-static/range {v20..v21} ,Landroid/util/Log;->i(Ljava/lang/String;Ljava/lang/String;)I
或者先将其 move 到vx

const-string v0, "KKKKSend"  
move-object/from16 v1, v27    
invoke-static {v0, v1}, Landroid/util/Log;->e(Ljava/lang/String;Ljava/lang/String;)I
示例讨论: http://bbs.pediy.com/showthread.php?t=179791

3.当.local>15时,修改代码中使用了p0,p1等传参。

当.local>15时,修改时引用了传入参数,如p0,p1,p2..时,会包RT错误,如下我想插入一段弹出AlertDialog框的代码:

.method public onCreate(Landroid/os/Bundle;)V
    .locals 20
    .param p1, "savedInstanceState"    # Landroid/os/Bundle;

    .prologue
    #插入开始#
    new-instance v1,Landroid/app/AlertDialog$Builder;
    invoke-direct {v1,p0}, Landroid/app/AlertDialog$Builder;->(Landroid/content/Context;)V
    const-string v2,"tip!!!"
    invoke-virtual {v1,v2}, Landroid/app/AlertDialog$Builder;->setTitle(Ljava/lang/CharSequence;)Landroid/app/AlertDialog$Builder;
    const-string v2,"1234567thisisadilog"
    invoke-virtual {v1,v2},Landroid/app/AlertDialog$Builder;->setMessage(Ljava/lang/CharSequence;)Landroid/app/AlertDialog$Builder;
    invoke-virtual {v1},Landroid/app/AlertDialog$Builder;->create()Landroid/app/AlertDialog;
    move-result-object v2
    invoke-virtual {v2},Landroid/app/AlertDialog;->show()V
    #插入结束#
    invoke-super/range {p0 .. p1}, Lcom/yuchengtech/mobile/commonUtils/BaseFragmentActivity;->onCreate(Landroid/os/Bundle;)V

    .line 129
    sput-object p0, Lcom/yuchengtech/mobile/JZYHMainActivity;->ctx:Lcom/yuchengtech/mobile/JZYHMainActivity;
...
插入的代码中,在.local>15的情况下,使用invoke-非range形式引用了this对应的p0,这时回编就会报错。

修改方法为,将p0对象move给v0,引用v0:

    move-object/from16 v0, p0
    new-instance v1,Landroid/app/AlertDialog$Builder;
    invoke-direct {v1,v0}, Landroid/app/AlertDialog$Builder;->(Landroid/content/Context;)V


你可能感兴趣的:(Android安全)