skylot / jadx

Dex to Java decompiler
Apache License 2.0
41.96k stars 4.9k forks source link

[core] Missing field access assignment #2340

Closed eybisi closed 3 weeks ago

eybisi commented 3 weeks ago

Issue details

dProtect uses somewhat unconvential field access which results in incorrect decompilation.

Instead of normal field access instruction order where sput instruction is at the end after array filled with data:

# direct methods
.method static constructor <clinit>()V
    .locals 4

    const v0, 0x1
    new-array v0, v0, [J
    const/4 v1, 0x0
    const-wide/32 v2, 0x4c78b648
    aput-wide v2, v0, v1
    sput-object v0, Lorg/abc/obfusactiontests/MainActivity;->myArr:[J
    return-void
    nop

.end method

it first moves field into newly generated array register like following:

# direct methods
.method static constructor <clinit>()V
    .locals 4

    const v0, 0x1
    new-array v0, v0, [J
    sput-object v0, Lorg/abc/obfusactiontests/MainActivity;->myArr:[J
    const/4 v1, 0x0
    const-wide/32 v2, 0x4c78b648
    aput-wide v2, v0, v1
    return-void
    nop

.end method

And we get following decompilation which is not complete:

    static {
        myArr = r0;
        long[] jArr = {1282979400};
    }

Instead of:

private static long[] myArr = {1282979400};

I've attached sample for these cases, where app-debug1.zip is a normal access and app-debug2.zip is a dProtect way. Samples also prints myArr via System.out, and both are the same at the runtime.

Also another small issue with arrays, If an array created with bigger size than filled data for example:

# direct methods
.method static constructor <clinit>()V
    .locals 4

    const v0, 0x4
    new-array v0, v0, [J
    const/4 v1, 0x0
    const-wide/32 v2, 0x4c78b648
    aput-wide v2, v0, v1
    sput-object v0, Lorg/abc/obfusactiontests/MainActivity;->myArr:[J
    return-void
    nop

.end method

Jadx decompiles this to following:

private static long[] myArr = {1282979400};

Instead of :

private static long[] myArr = {1282979400,0,0,0};

Jadx produces same output for the cases where length is 1 or 4.

We can fill rest of the array with default element of the array type.

Relevant log output or stacktrace

No response

Provide sample and class/method full name

app-debug2.zip app-debug1.zip

Jadx version

dev

skylot commented 3 weeks ago

Fixed. @eybisi thank you for report :+1: