关于使用 apktool 从 apk 反转的特殊 smali 类的两个问题

Posted

技术标签:

【中文标题】关于使用 apktool 从 apk 反转的特殊 smali 类的两个问题【英文标题】:Two questions regarding peculiar smali classes reversed from an apk using apktool 【发布时间】:2020-12-22 23:17:24 【问题描述】:

我在 smali github 上问过这个问题,但这可能是一个更好的地方再问一次。

我观察到了两个我想询问的奇怪的代码反编译案例。该代码是在 Windows 10 上使用 apktool 2.4.1 对 apk 进行反编译的,这两个问题都与确定这在 smali 语言中是否合法以及如何以逻辑和编程方式(使用解析器)进行处理有关。

    第一个问题是在一个 smali 类中有多个相同的字段定义。我有以下情况:
.class public final Likev2/network/sdk/network/tools/***BuilderHelper;
.super Ljava/lang/Object;


# annotations
.annotation system Ldalvik/annotation/MemberClasses;
    value = 
        Likev2/network/sdk/network/tools/***BuilderHelper$a;
    
.end annotation


# instance fields
.field public a:Landroid/net/***Service$Builder;

.field public final a:Landroid/net/***Service;

.field public a:Likev2/network/sdk/network/tools/***BuilderHelper$a;

.field public b:Likev2/network/sdk/network/tools/***BuilderHelper$a;


# direct methods
.method public constructor <init>(Landroid/net/***Service;)V
    .locals 0

    if-eqz p1, :cond_0

    invoke-direct p0, Ljava/lang/Object;-><init>()V
...

如果您观察前三个实例字段,则所有三个都具有相同的名称“a”。它们也有不同的类型。最初,我认为这可能是对超类隐藏成员的情况,但是这个超类的超类是普通的 Object。

这将如何解释?

    第二个问题是将字符“-”作为方法名称中的第一个字符。有问题的代码是这样的:
...
# virtual methods
.method public final -deprecated_javaName()Ljava/lang/String;
    .locals 1

    .line 1
    iget-object v0, p0, Lb0/m0;->javaName:Ljava/lang/String;

    return-object v0
.end method
...

这里有问题的方法名称是“-deprecated_javaName”。考虑到“-”字符,这是一个合法名称吗?我在谷歌上搜索,发现只有一个地方提到了这个名字,这是在下面的代码中:https://jar-download.com/artifacts/com.squareup.okhttp3/okhttp/4.2.2/source-code/okhttp3/CipherSuite.kt

如果你看一下,似乎这是不推荐使用并重命名的 Kotlin 函数:

...
@JvmName("-deprecated_javaName")
  @Deprecated(
      message = "moved to val",
      replaceWith = ReplaceWith(expression = "javaName"),
      level = DeprecationLevel.ERROR)
  fun javaName(): String = javaName
...

我正在使用自定义 antlr 脚本解析 smali,该脚本将函数名称设置为始终以字母开头并且在此字符上失败。

如果有人能阐明这两个 smali 特性发生了什么以及如何正确处理它们的解析,我将不胜感激。

【问题讨论】:

【参考方案1】:

    dex 文件有一个包含 dex 文件中引用的每个字段的单个表,然后对任何给定字段的任何引用都是通过该表的索引。 field_id_item 结构是该表中包含单个字段引用的条目。如您所见,所有field_id_items 都包含被引用字段的名称​​AND 类型。因此,在同一个类中拥有多个名称相同但类型不同的字段是完全合适的。由于字段引用始终包含名称和类型,因此对于引用哪个字段没有歧义。

    dex 格式的成员名称的允许语法定义为here。这个定义比 java 允许的更广泛,所以完全有可能有一个有效的 dex 成员名称,它在 java 中是一个无效的名称。 -deprecated_javaName 是一个完美的 dex 成员名称 :)

【讨论】:

非常感谢您的详细回答。我不知道我是如何错过您发送链接的词法信息的。我想我必须重新实现一些东西。谢谢!

以上是关于关于使用 apktool 从 apk 反转的特殊 smali 类的两个问题的主要内容,如果未能解决你的问题,请参考以下文章

请问apktool怎么使用?

我想获取APK文件中的图片,怎么使用apktool工具

在我的 android 项目中使用 apktool jar 文件?

使用apktool解包和打包apk

apktool 没有生成 apk 文件

Ubuntu使用ApkTool进行APK反编译