(ART/DVM) 在 :try_end 指令之前插入一条指令会导致 VerifyError

问题描述

我已经使用 smali/baksmali 有一段时间了,我在合理的程度上理解这些说明。最近,我遇到了一个非常奇怪的错误。 在对齐的 try-catch 块之后插入指令会在运行时导致类型验证错误。 我对可能的原因做了一些假设,包括假设 ART 不接受期望可移动结果的调用,但事实并非如此。我还尝试插入 sput 指令来检查它是否可以工作,但没有。但是对于我见过的某些方法,在同一位置插入的 put 指令效果很好,这让我相信这是一个对齐问题。但我不知道这是基于什么规则。

根据我的理解,当寄存器的类型可能通过分支到不同的条件或 goto 语句而改变时,会发生冲突类型错误。但在这种情况下,我似乎无法弄清楚保证这种情况发生的跳跃位置。

以这个方法为例

.method private static zzd(Ljava/lang/String;)I
    .locals 7

    const/4 v0,0x0

    const/4 v1,0x2

    const/4 v2,0x3

    const/4 v3,0x1

    :try_start_0
    const-string v4,"[.-]"

    .line 19
    invoke-static {v4},Lcom/a/b/c/d/zzax;->zza(Ljava/lang/String;)Lcom/a/b/c/d/zzax;

    move-result-object v4

    invoke-virtual {v4,p0},Lcom/a/b/c/d/zzax;->zza(Ljava/lang/CharSequence;)Ljava/util/List;

    move-result-object v4

    .line 20
    invoke-interface {v4},Ljava/util/List;->size()I

    move-result v5

    if-ne v5,v3,:cond_0

    .line 21
    invoke-static {p0},Ljava/lang/Integer;->parseInt(Ljava/lang/String;)I

    move-result p0

    return p0

    .line 22
    :cond_0
    invoke-interface {v4},Ljava/util/List;->size()I

    move-result v5

    if-lt v5,v2,:cond_1

    .line 23
    invoke-interface {v4,v0},Ljava/util/List;->get(I)Ljava/lang/Object;

    move-result-object v5

    check-cast v5,Ljava/lang/String;

    invoke-static {v5},Ljava/lang/Integer;->parseInt(Ljava/lang/String;)I

    move-result v5

    const v6,0xf4240

    mul-int v5,v5,v6

    .line 24
    invoke-interface {v4,v3},Ljava/util/List;->get(I)Ljava/lang/Object;

    move-result-object v6

    check-cast v6,Ljava/lang/String;

    invoke-static {v6},Ljava/lang/Integer;->parseInt(Ljava/lang/String;)I

    move-result v6

    mul-int/lit16 v6,v6,0x3e8

    add-int/2addr v5,v6

    .line 25
    invoke-interface {v4,v1},Ljava/util/List;->get(I)Ljava/lang/Object;

    move-result-object v4

    check-cast v4,Ljava/lang/String;

    invoke-static {v4},Ljava/lang/Integer;->parseInt(Ljava/lang/String;)I

    move-result p0

    # Inserting any instruction here causes a type p0 to become a conflicted type

    :try_end_0
    .catch Ljava/lang/IllegalArgumentException; {:try_start_0 .. :try_end_0} :catch_0

    add-int/2addr v5,p0

    return v5

    :catch_0
    move-exception v4

    const-string v5,"LibraryVersionContainer"

    .line 29
    invoke-static {v5,v2},Landroid/util/Log;->isLoggable(Ljava/lang/String;I)Z

    move-result v2

    if-eqz v2,:cond_1

    new-array v1,v1,[Ljava/lang/Object;

    # Trying to insert the value of p0 into the object array causes the VerifyError

    aput-object p0,v0

    aput-object v4,v3

    const-string p0,"Version code parsing failed for: %s with exception %s."

    .line 31
    invoke-static {p0,Ljava/lang/String;->format(Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/String;

    move-result-object p0

    .line 32
    invoke-static {v5,Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I

    :cond_1
    const/4 p0,-0x1

    return p0
.end method

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)