关于使用 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 类的两个问题的主要内容,如果未能解决你的问题,请参考以下文章