关于使用 apktool 从 apk 反转的特殊 smali 类 的两个问题
Two questions regarding peculiar smali classes reversed from an apk using apktool
我在 smali github 上问过这个问题,但这可能是一个更好的地方再问一次。
观察到两起奇怪的代码反编译案例,想请教一下。该代码是在 Windows 10 上使用 apktool 2.4.1 反编译的 apk,这两个问题都与确定这在 smali 语言中是否合法以及如何以逻辑和编程方式(使用解析器)处理此问题有关。
- 第一个问题是在单个 smali 中有多个相同的字段定义 class。我有以下情况:
.class public final Likev2/network/sdk/network/tools/VpnBuilderHelper;
.super Ljava/lang/Object;
# annotations
.annotation system Ldalvik/annotation/MemberClasses;
value = {
Likev2/network/sdk/network/tools/VpnBuilderHelper$a;
}
.end annotation
# instance fields
.field public a:Landroid/net/VpnService$Builder;
.field public final a:Landroid/net/VpnService;
.field public a:Likev2/network/sdk/network/tools/VpnBuilderHelper$a;
.field public b:Likev2/network/sdk/network/tools/VpnBuilderHelper$a;
# direct methods
.method public constructor <init>(Landroid/net/VpnService;)V
.locals 0
if-eqz p1, :cond_0
invoke-direct {p0}, Ljava/lang/Object;-><init>()V
...
如果您观察前三个实例字段,所有三个都具有相同的名称 'a'。它们也有不同的类型。最初,我在想这可能是对 superclasses 隐藏成员的情况,但是这个的 superclass 是普通的 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”。考虑到“-”字符,这是合法名称吗?我在 Google 上搜索过,只发现一个地方提到了这个名字,这是在下面的代码中: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 的特点以及如何正确处理它们的解析,我将不胜感激。
一个 dex 文件在 dex 文件中引用的每个字段都有一个 table,然后对任何给定字段的任何引用都是通过索引到 table. field_id_item 结构是 table 中的一个条目,它包含一个字段引用。如您所见,所有 field_id_items
都包含所引用字段的名称 和 类型。因此,在同一个 class 中具有相同名称但具有不同类型的多个字段是完美的。由于字段引用始终包括名称和类型,因此对于引用哪个字段没有歧义。
定义了 dex 格式成员名称允许的语法 here。这个定义比 java 允许的范围更广,所以完全有可能有一个有效的 dex 成员名称是 java 中的一个无效名称。 -deprecated_javaName
是一个完美的 cromulent dex 成员名称:)
我在 smali github 上问过这个问题,但这可能是一个更好的地方再问一次。
观察到两起奇怪的代码反编译案例,想请教一下。该代码是在 Windows 10 上使用 apktool 2.4.1 反编译的 apk,这两个问题都与确定这在 smali 语言中是否合法以及如何以逻辑和编程方式(使用解析器)处理此问题有关。
- 第一个问题是在单个 smali 中有多个相同的字段定义 class。我有以下情况:
.class public final Likev2/network/sdk/network/tools/VpnBuilderHelper;
.super Ljava/lang/Object;
# annotations
.annotation system Ldalvik/annotation/MemberClasses;
value = {
Likev2/network/sdk/network/tools/VpnBuilderHelper$a;
}
.end annotation
# instance fields
.field public a:Landroid/net/VpnService$Builder;
.field public final a:Landroid/net/VpnService;
.field public a:Likev2/network/sdk/network/tools/VpnBuilderHelper$a;
.field public b:Likev2/network/sdk/network/tools/VpnBuilderHelper$a;
# direct methods
.method public constructor <init>(Landroid/net/VpnService;)V
.locals 0
if-eqz p1, :cond_0
invoke-direct {p0}, Ljava/lang/Object;-><init>()V
...
如果您观察前三个实例字段,所有三个都具有相同的名称 'a'。它们也有不同的类型。最初,我在想这可能是对 superclasses 隐藏成员的情况,但是这个的 superclass 是普通的 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”。考虑到“-”字符,这是合法名称吗?我在 Google 上搜索过,只发现一个地方提到了这个名字,这是在下面的代码中: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 的特点以及如何正确处理它们的解析,我将不胜感激。
一个 dex 文件在 dex 文件中引用的每个字段都有一个 table,然后对任何给定字段的任何引用都是通过索引到 table. field_id_item 结构是 table 中的一个条目,它包含一个字段引用。如您所见,所有
field_id_items
都包含所引用字段的名称 和 类型。因此,在同一个 class 中具有相同名称但具有不同类型的多个字段是完美的。由于字段引用始终包括名称和类型,因此对于引用哪个字段没有歧义。定义了 dex 格式成员名称允许的语法 here。这个定义比 java 允许的范围更广,所以完全有可能有一个有效的 dex 成员名称是 java 中的一个无效名称。
-deprecated_javaName
是一个完美的 cromulent dex 成员名称:)