https://kotlinlang.org logo
#reflect
Title
# reflect
i

int02h

01/10/2020, 11:59 AM
Hi! Did I understand it right that kotlin-reflect extracts information about class (for example member names) from its
@Metadata
annotation? Because I can extract class member original names even if ProGuard/R8 has obfusacted the class. Does it make reverse engineering easier because bytecode of the class contains information about its members in
@Metadata
annotation?
d

diesieben07

01/10/2020, 12:01 PM
Yes,
@Metadata
contains detailed information about the class. You can test what exactly is contained using https://github.com/JetBrains/kotlin/blob/master/libraries/kotlinx-metadata/jvm/ReadMe.md
i

int02h

01/10/2020, 12:04 PM
The library you pointed is working with .class files but I mean reflection working at runtime. Does reflection use the same mechanism?
d

diesieben07

01/10/2020, 12:04 PM
Yes, reflection also reads data from the metadata descriptor.
i

int02h

01/10/2020, 12:07 PM
Does it break the idea of code obfuscation? Because possible attacker can extract all information about class. For instance with the library from above.
d

diesieben07

01/10/2020, 12:08 PM
You would have to instruct your obfuscator to remove @Metadata.
i

int02h

01/10/2020, 12:14 PM
But what if using some library like Moshi or another that works with reflection? For example
primaryConstructor
property of
KClass
returns
null
if
@Metadata
is shrinked by ProGuard/R8. So Moshi will not work in that conditions.
d

diesieben07

01/10/2020, 12:21 PM
That is true.
primaryConstructor
will work after obfuscation, because constructors cannot be renamed. But other reflective operations will fail anyways, because the names in
@Metadata
do not match the actual names of your members anymore.
i

int02h

01/10/2020, 12:36 PM
primaryConstructor
returns
null
because flag indicating primary constructor is also inside
@Metadata
annotation. But if I try to get class properties with, for example,
declaredMemberProperties
the I get properties with their original names even if ProGuard/R8 turned and
@Metadata
is preserved.
d

diesieben07

01/10/2020, 12:39 PM
Yes, you will get them, but accessing them (e.g. calling
get()
) is probably not going to work, because it cant find the actual field/method to access
i

int02h

01/10/2020, 12:45 PM
Yes, you’re right. Just checked it out in test project.
But it’s quite confusing
d

diesieben07

01/10/2020, 12:47 PM
Obfuscation has many problems, you have to be aware of them. Reflection is always a problematic area
i

int02h

01/10/2020, 12:49 PM
So it seems that I need to
-keep
all class members without any obfuscation to get it work properly.
d

diesieben07

01/10/2020, 12:59 PM
It depends on what you want to achieve exactly.
i

int02h

01/10/2020, 1:01 PM
I am working on library like Moshi but not for JSON. So I need to serialize/deserialize instances to/from some representation. My library does it in runtime via reflection. So if I keep
@Metadata
annotation but allow R8 to rename class members it won’t work because of reason you’ve described above (https://kotlinlang.slack.com/archives/C0AVAB92L/p1578659941007300?thread_ts=1578657597.005400&cid=C0AVAB92L)
d

diesieben07

01/10/2020, 1:02 PM
Yes, if you use reflection at runtime you do need to keep those members.
i

int02h

01/10/2020, 1:03 PM
To be more precise - not only keep members but their names too
d

diesieben07

01/10/2020, 1:03 PM
Yes, that's what I meant, sorry
i

int02h

01/10/2020, 1:04 PM
Thank you for fast and complete responses. I figured out what I want.
t

Tim Van Den Broecke

01/16/2020, 10:40 AM
@int02h the latest ProGuard beta has extended support for processing Kotlin metadata so that you don't need to keep classes/members that you want to reflect on anymore: https://www.guardsquare.com/en/products/proguard/proguard-manual-kotlin-beta maybe that's useful for your case?
i

int02h

01/16/2020, 12:31 PM
@Tim Van Den Broecke looks exciting. But I develop for Android and thus I use R8 instead of ProGuard actually. R8 seems to be completely compatible with ProGuard but this feature is in beta right now so I’m not sure when it become available in R8. But thank you. I will keep my eye on the updates of ProGuard/R8.
49 Views