JesusFreke / smali

smali/baksmali
6.29k stars 1.07k forks source link

dexlib2: method reference count available? #785

Closed auermich93 closed 3 years ago

auermich93 commented 3 years ago

Hi, I am curious whether dexlib2 can provide me access to the number of method references a given class or at least the dex file has? Otherwise I am running into the risk that a dex file exceeds the maximal number of method references when adding additional methods. I could catch the exception of DexFileFactory.writeDexFile() but that's not the elegant way.

I know about the extension 'multidexlib2', which can excactly handle this use case, but I would like to avoid additional dependencies. Btw, it would be nice to see the features of multidexlib2 merged into dexlib2 in the near future. :)

Thank you JF!

Lanchon commented 3 years ago

its more complex than that. it has a rollback mechanism. take a look at multidexlib2

Lanchon commented 3 years ago

i mean take a look at how multidexlib2 handles this

auermich93 commented 3 years ago

Yeah, it seems to be not that simple. I guess I have three options:

1) Use apkanalyzer from the Android SDK to get the number of method references before the instrumentation and keep track of additionally inserted method references and split the dex file accordingly. 2) Try to explore the number of method references within dexlib2. However, I need some help for this. Basically, I need a concrete definition of a method reference. I would assume one has to iterate over the classes, count the number of methods contained in these classes (are unused method counted as well?) and inspect the method invocations and add them as well. Are duplicates counted as well? Do I miss any method references? Can someone resolve all method references of the Android framework itself? 3) Split a dex file into multiple dex files based on some heuristic, e.g. every 50 classes come into an individual dex file. Just for clarity, are there any restrictions regarding dex files or the classes contained within dex files? For instance, is there an upper limit of dex files? Is there some sort of 'main' dex file? Can I arbitrarily split classes (ClassDef instances) into dex files or need certain classes be grouped together? Is there some performance issue with too many dex files?

JesusFreke commented 3 years ago

To get the number of method references, see, e.g. DexBackedDexFile.getMethodSection().size()

auermich93 commented 3 years ago

Yeah, thanks, but the 'methodCount' variable is never updated as far as I can see. This means I have to track newly inserted method references on my own.

JesusFreke commented 3 years ago

Yes, DexBackedDexFile is not a mutable structure - it's a "view" of an existing dex file on disk (or in memory).

When building your own dex file, see e.g. DexBuilder.methodSection.getItemCount()

auermich93 commented 3 years ago

I am sorry, but this method is not public. I guess dexBuilder.getMethodReferences().size(); refers to the same thing.

Lanchon commented 3 years ago

this is what u want: https://github.com/DexPatcher/multidexlib2/blob/fb02b58c45c405ff537b7c4b20e20f4f245a3c36/src/main/java/lanchon/multidexlib2/DexIO.java#L141

Lanchon commented 3 years ago

mdexlib2 will do it better and faster than u if it does what you need. but if u insist on doing it yourself, then copy what mdexlib2 does

auermich93 commented 3 years ago

@Lanchon: OK, I will have a look at your library. It seems that reading directly from an APK file is not possible? This means I have to run 'apktool d -s' and specify the output directory as input file to the method MultiDexIO.readMultiDexContainer()?

Lanchon commented 3 years ago

i dont remember. i suspect you can. but you CANT write directly to a zip, it has to be a dir.

auermich93 commented 3 years ago

I think we can close this here. The original question was covered. Thank you!