Best practice: how to obfuscate a plugin with Zelix KlassMaster

Hi,

we can now easily find advice and sample projects that integrates the ProGuard obfuscator, even if this is no longer considered as an obfuscator (for good reasons) by ProGuard itself ^_^.

Unfortunately, I found nothing about Zelix KlassMaster. The JetBrains documentation says it’s used by the IDE, so you have a great experience with this tool.
I think providing a sample plugin project would be awesome.
I know this is a recurring and old issue, but there is still no documentation, code sample, or best practices. Some help would he appreciated. I think this would be very beneficial to developers of paid plugins.
Thx

For info, I started to replace ProGuard by ZKM in my paid plugins, mostly because ProGuard is completely useless against malicious users.
So, I can’t share private code, but I cloned the intellij platform plugin template and I added a basic support for ZKM. It:

  • is integrated into the build.gradle.kts, I’m not using the ZKM Gradle plugin. There is no specific reason for that, except that it was relatively easy to migrate from ProGuard
  • is compatible with Gradle’s configuration cache, which should be enabled (forced?) in Gradle 10
  • obfuscates and trim bytecode
  • rewrites the MANIFST.MF file because I don’t want to give any hint to malicious users

I also commented out obfuscateReferences because it needs additional configuration, otherwise it does nothing.

The repository, and the relevant commit: basic ZKM support · jonathanlermitage/intellij-platform-plugin-template-zelix-klassmaster@91155a2 · GitHub

I’m preparing a guest blog post and I may submit it very soon. In this post, I will also explain how to configure obfuscateReferences, share metrics, etc :wink:

For now, what can I say about ZKM?
It really obfuscates the bytecode. Unfortunately:

  • I migrated from ProGuard. Crack developers clearly know what to crack, and I had to develop new protections. It may have been different if I started with ZKM.
  • Crack developers can “trace” relevant API usages, especially JetBrains APIs, so the bytecode can be obfuscated or not, this is not a problem for them. They know what to override via ASM or network redirectors.

While that, it seems that my new protections are a bit more efficient. I will say if they have been cracked too. They used to be cracked within a day, but since I migrate to ZKM it seems more difficult for crack developers. They still target JetBrains APIs, but not my new protections.

So, I can’t really say if this is good against cracks. At least, it should be very useful if you want to protect your business logic. Malicious users won’t be able to clone your plugin.
Finally, there is no noticeable impact on performance, and I do the heavy stuff asynchronously.

Does obfuscateFlow=aggressive work for you with kotlin coroutines ? I’m always getting Inconsistent stack heights and need to switch to light.

The plugin template uses Kotlin, but my private projects use Java. So, I did not test with coroutines. BTW, most of the obfuscate config comes from Obfuscate the plugin | JetBrains Marketplace Documentation, so it should work.
I imagine other plugin developers or JetBrains staff know how to sort this out. You could also ask Zelix this question; they reply quickly.