DexPatcher / dexpatcher-gradle

Modify Android applications at source-level in Android Studio
https://dexpatcher.github.io/
GNU General Public License v3.0
83 stars 17 forks source link

Package name clashes with class name #17

Closed mRokita closed 6 years ago

mRokita commented 7 years ago

How can I modify a member of such package? I'm trying to edit com.somedomain.a.a but there's also a class named com.somedomain.a.

Btw, DexPatcher is a great tool, thank you for developing it :-)

Lanchon commented 7 years ago

hi, thanks!

How can I modify a member of such package?

so... obfuscated code. please clarify the problem. this is what i understand:

questions: 1) is the above correct? if so, this is a javac shortcoming (or maybe a Java language limitation). 2) do you want to edit all static methods in class class xxx.a.a? or do you need to edit some instance methods too? 3) do you need to target (eg edit) class xxx.a at all?

thanks!

mRokita commented 7 years ago
  1. Yes, it is :-)
  2. I'm not able to check it at the moment, but I'm pretty sure that I have to edit some instance methods too.
  3. I don't have to edit xxx.a, it's just a class with some static variables.
mRokita commented 7 years ago

Yes, all the methods I want to edit are instance methods.

Lanchon commented 7 years ago

if you DON'T have to edit instance methods, you can define any other class and @DexEdit(target="xxx.a.a", onlyEditMembers=true) it.

however if you have to edit instance methods, it might or might not work. the this reference in your defined class will be of a different type than in xxx.a.a, and that may cause issues, depending on what you need to do with this. in the general case, it wont work and fail at runtime.

the other solution is this: 1) make 2 copies of your project. 2) in one copy delete the 'patched' subproject. in the other delete the 'source' subproject. so you now have 2 separate projects for source and patched. 3) build the source and make a copy of the apk library (name.apk.aar) produced by the project. 4) make the patched project not depend on ':source' (which doesnt exist anymore), and instead import the apk library into the patched project manually. you can use Android Studio UI to import the .apk.aar file as if it were any regular android library, or just place the file somewhere in the patched project and make build.gradle depend on the file. 5) now edit the .apk.aar file:

Lanchon commented 7 years ago

if you look at https://github.com/DexPatcher/dexpatcher-tool/issues/14 you will find this item that would help with your case a lot:

rewrite here means alter all declarations and code in the class, replacing one type with the other. this sounds hard to do but it is not so.

mRokita commented 7 years ago

thank you, I've tried the easy approach with @DexEdit. Unfortunately, it doesn't work - the app crashes throwing java.lang.ClassNotFoundException: Didn't find class "xxx.MainActivity" I will try to create 2 separate projects for source and patched.

mRokita commented 7 years ago

There is no classes.zip, just classes.jar with no java files :(

mRokita commented 7 years ago

Nevermind, found it.

mRokita commented 7 years ago

Okay, if somebody else will ever have this problem: The trick with 2 separate projects works. I wasn't able to hack in-app purchases in that app though - the code was too obscure to make it work :/ But still, I'm happy I learnt something new :-)

Lanchon commented 6 years ago

FYI, there are two roadplan items that fix this:

1) from the roadplan: "In the Gradle plugins, add an option to inhibit the import of the source symbols. This option can be enabled to make sure that every symbol referenced in the patch is also declared in the patch. If they are declared using @DexCheck, then all symbols will be checked at patch time. This is more developer work but makes the patch fail at patch time if applied against a new version of the app that is missing a symbol (instead of producing a patched app that will fail at runtime with link errors)." inhibiting the import of the source symbols and using @DexCheck or even @DexIgnore on patch-defined symbols fixes this issue.

2) Not written down in the roadplan yet, but it involves a future mechanism in the Gradle plugins to handle obfuscated code in general. This mechanism does not yet exist because it requires an extension in dex2jar or a new tool altogether (or two). I worked on bringing dex2jar to Android Oreo already, so this is not too far fetched.

Lanchon commented 6 years ago

item 1) is now implemented in dexpatcher-gradle v0.4.5.

Lanchon commented 6 years ago

and now you can also use cross-class edits in dexpatcher-tool v1.5.0.

thanks!

mRokita commented 6 years ago

awesome! :)