androidreverse-engineeringsmaliapktool

Two questions regarding peculiar smali classes reversed from an apk using apktool


I asked this question on smali github, but this might be a way better place to ask it again.

I have observed two cases of weird code decompilation which I wanted to ask about. The code is decompiled apk using apktool 2.4.1 on Windows 10 and both questions have to do with figuring out if this is legal in smali language and how to deal with this logically and programmatically (with a parser).

  1. The first issue is having multiple same field definitions in a single smali class. I have the following situation:
.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
...

If you observe the first three instance fields, all three have the same name 'a'. They also have different types. Initially, I was thinking that this might be the case of hiding the members from superclasses, but the superclass of this one is plain Object.

How would this be interpreted?

  1. The second issue is having the character '-' as the first character in the name of a method. The code in question is this one:
...
# 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
...

The method name in question here is '-deprecated_javaName'. Is this a legal name, considering '-' character? I've searched on Google and found only one place that this name is mentioned, and this is in the following code: https://jar-download.com/artifacts/com.squareup.okhttp3/okhttp/4.2.2/source-code/okhttp3/CipherSuite.kt

If you take a look, it seems this is deprecated and renamed Kotlin function:

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

I'm parsing smali with a custom antlr script, which sets function names to always start with a letter and fails on this character.

If anyone can shed some light on what is going on with these two smali peculiarities and how to properly handle their parsing I would greatly appreciate it.


Solution

    1. A dex file has a single table of every field that is referenced in the dex file, and then any references to any given field are via an index into that table. The field_id_item structure is an entry in that table that holds a single field reference. As you can see, all field_id_items include both the name AND type of the field being referenced. So it's perfectly cromulent to have multiple fields in the same class with the same name, but with different types. Since a field reference always includes both the name and type, there is no ambiguity as to which field is being referred to.

    2. The allowed syntax of a member name in the dex format is defined here. This definition is broader than what java allows, so it's entirely possible to have a valid dex member name that is an invalid name in java. -deprecated_javaName is a perfectly cromulent dex member name :)