octarine-noise / simpledeobf

simple deobfuscator for Minecraft mods
MIT License
82 stars 13 forks source link

Force public option doesn't change invokespecial on private methods to invokevirtual #7

Open Barteks2x opened 6 years ago

Barteks2x commented 6 years ago

This is what actually causes #3. See: https://github.com/MinecraftForge/MinecraftForge/blob/c20a5e8805f64097430cf0722011f20862a8df9c/src/main/java/net/minecraftforge/fml/common/asm/transformers/AccessTransformer.java#L230-L294

I found it while making my own (far more convinient) pile of hacks to make optifine work in dev.

octarine-noise commented 6 years ago

Oh, nice. Thanks for the heads-up! On the 1 year anniversary of this issue as well :)

So, if I understand correctly, with the bytecode thing fixed in Forge, it Just Works now? I don't need to do anything with simpledeobf? Also, if it's not a trade secret, how did you hack Optifine in? I'm all for convenience.

Barteks2x commented 6 years ago

This is my awful not yet cleaned up pile of hacks to make it work https://gist.github.com/Barteks2x/38125abcac5cd069f2b23cd63468392b

It just needs to be named something like aa_FileName.jar and has to contain tweaker entry in manifest.

And you do need to modify simple deobf to also contain the same fix fml has. The fml code handles normal access tranaformers. You don't handle overriding newly public method. Javac emits invokespecial insn for private methods. This needs to be changed to invokevirtual when you make them public.

octarine-noise commented 6 years ago

Right, of course. It's been too long since I worked with this stuff.

So basically instead of deobfuscating each version of Optifine externally, you have a deobfuscator tweaker doing it on the fly at boot time. Much more convenient indeed. I'm a bit perplexed by the property pointing to the mapping file. Do you set this yourself in the buildscript/runconf? Or is this a feature of the ForgeGradle bootstrapper?

Barteks2x commented 6 years ago

It's a feature of forge gradle. You can see it being set in GradleStartCommon.

There are a few nonobvious parts of my code.

First is loading optifine transformer class from tweaker static initializer. This is done so that OptiFine will see obfuscated MC jar I inject into classpath. Otherwise it won't be loaded with launch class loader and it won't work.

Second non obvious part is creating new optifine transformer instance and then hacking it with reflection. Turns out that loading this with launchclassloader breaks the constructor, but optifine helpfully catches the exception and ignores it. From there it's just a matter of setting the null fields myself with reflection.

Everything else is mostly obvious or a leftover from some dead end I reached.