square/moshi

Decompiled code still shows annotated name

KAPLANDROID opened this issue · 1 comments

Hi, I am trying to enable code obfuscation in my android project. I am using moshi for json operations. I am having a problem with release apk/aab file. When I use a decompiler the @JsonClass(generateAdapter = true) annotated files are almost stays non-obfuscated in terms of reducing code readability. I can easily read the class name and also variable names. I attach original and obfuscated sample class code below. There is also an adapter class generated by moshi lib that also shows the readable class content. I used to be using Gson lib before and I was not having similar issues with it. I didn't add any moshi related lines to my proguard-rules.pro file. I am also sure that I didn't add any rules to proguard-rules.pro file related to keeping this annotated files. I checked moshi's proguard file and these rules might be a reason for this issue. Am I missing a configuration update?

Gradle file


    buildTypes {
        release {
            minifyEnabled true
            shrinkResources true
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }

Original class


    import com.decompiletest.enum.EyeColor
    import com.squareup.moshi.Json
    import com.squareup.moshi.JsonClass
    
    @JsonClass(generateAdapter = true)
    data class MPerson(
        @Json(name = "name") val name: String,
        @Json(name = "lucy_number") val luckyNumber: Int,
        @Json(name = "eye_color") val eyeColor: EyeColor,
    )

Obfuscated version



    import p002a1.C1300j;
    import p002a1.C1303m;
    import p026f1.C0403d;
    import p099y0.C1202a;
    
    @C1303m(generateAdapter = true)
    /* renamed from: com.decompiletest.moshis.MPerson */
    public final class MPerson {
    
        /* renamed from: a */
        public final String f759a;
    
        /* renamed from: b */
        public final int f760b;
    
        /* renamed from: c */
        public final C1202a f3861c;
    
        public MPerson(@C1300j(name = "name") String str, @C1300j(name = "lucy_number") int i, @C1300j(name = "eye_color") C1202a aVar) {
            C0403d.m3330r(str, "name");
            C0403d.m3330r(aVar, "eyeColor");
            this.f759a = str;
            this.f760b = i;
            this.f3861c = aVar;
        }
    
        public final MPerson copy(@C1300j(name = "name") String str, @C1300j(name = "lucy_number") int i, @C1300j(name = "eye_color") C1202a aVar) {
            C0403d.m3330r(str, "name");
            C0403d.m3330r(aVar, "eyeColor");
            return new MPerson(str, i, aVar);
        }
    
        public final boolean equals(Object obj) {
            if (this == obj) {
                return true;
            }
            if (!(obj instanceof MPerson)) {
                return false;
            }
            MPerson mPerson = (MPerson) obj;
            return C0403d.m3322d(this.f759a, mPerson.f759a) && this.f760b == mPerson.f760b && this.f3861c == mPerson.f3861c;
        }
    
        public final int hashCode() {
            int hashCode = Integer.hashCode(this.f760b);
            return this.f3861c.hashCode() + ((hashCode + (this.f759a.hashCode() * 31)) * 31);
        }
    
        public final String toString() {
            return "MPerson(name=" + this.f759a + ", luckyNumber=" + this.f760b + ", eyeColor=" + this.f3861c + ")";
        }
    }

This is working as intended. Code gen generates proguard rules on the fly to conditionally keep class names and primary constructors in order to reflectively instantiate them at runtime.