JesusFreke / smali

smali/baksmali
6.29k stars 1.07k forks source link

[Question] Usage for incremental changes? #802

Closed Col-E closed 3 years ago

Col-E commented 3 years ago

I'm looking to integrate apk/dex read/write support in a later version my bytecode editor. The general design of this integration I'm hoping to achieve is similar to ASM's tree api. You would read the classes from a dex file into some structure that contains all the information independently of the dex file (So rather than pointing to offsets the values are all local to each class instance). Once a user updates these classes they can generate a new classes.dex from the collection of classes.

This would also allow them to easily rename/add/remove/modify classes from the collection since they do not have to be concerned with the integrity of a backing dex file. A new one will be generated in the end. This will also enable incremental changes in the sense that to edit one class the user only needs to disassemble the one class and no other ones.

I've looked over the wiki and skimmed old issues and don't see much that fits well into this use-case. The ClassDef model also seems to be designed to be read-only in all of its implementations.

Is this sort of usage with dexlib2/smali possible? If so, could you give me some pointers on how to approach this?

JesusFreke commented 3 years ago

dexlib2 generally works with generic interfaces for all of the various concepts in a dex file. Most of the concrete implementations of those interfaces are not modifiable, but there's no reason you can't create a modifiable instance. And there are a few places in dexlib2 that use modifiable implementations. See, e.g. MutableMethodImplementation, and more generally DexRewriter.

Col-E commented 3 years ago

So if I created my own MutableClassDef as a copy of each DexBackedClassDef then interned them into a DexPool after modification that'd be all I need to do?

JesusFreke commented 3 years ago

You'd probably need mutable versions of all of the basic interfaces, but yeah. You don't even really need to deal with a DexPool, if you use DexFileFactory.writeTo(), which just accepts a generic DexFile, which can be your mutable implementation. It will handle interning all the various things into their respective pools, etc.

Col-E commented 3 years ago

Awesome! Thanks for the help and the great library 😄

MuntashirAkon commented 1 year ago

if you use DexFileFactory.writeTo(), which just accepts a generic DexFile, which can be your mutable implementation. It will handle interning all the various things into their respective pools, etc.

My idea is also similar to @Col-E's. In my case, if a class was modified or created, I created a ClassDef out of it and then created a DexPool and added all the unmodified classes along with the newly generated class in in it to generate a dex file. However, if DexFile can be made mutable, this repeated work can be prevented. But is this even possible? I mean is there a way to make DexBuffer mutable? This might sound stupid but this is a legitimate question to ask since I don't know dex specification.