如何从已编译的 Java class/jar 文件中删除方法?

How to remove a method from a compiled Java class/jar file?

我有一个 JAR 文件并且有一个静态文件 class,我无法反编译它,它被弄乱了。里面有一个方法,那个returns一个class,那是不存在的。不知道如何,但我得到 NoClassDefFoundError。即使我没有使用该方法,它仍然会崩溃。所以我需要以某种方式删除它,它应该可以正常工作。我知道可以使用 Reflection 或 Javassist,但不知道如何使用。

请注意,这显然不是产品发布,只是一些白帽黑客攻击。

我认为你错了:如果那个方法永远不会被调用,那么 JVM 很可能不会 尝试加载那个 class。

你看,class 加载的全部意义在于 lazy;当您加载 class X,并且 X 需要 Y、Z ... 时,仅当执行某些需要加载 Y、Z 的代码时才加载 Y 和 Z。

换句话说:NoClassDefFound 错误实际上告诉您 某事(可能是您 JAR 中某处的静态初始化)正在调用该方法。

因此,解决方案不是 "cut out" 那个方法(那只会导致另一个异常,例如 MethodNotFound!)。相反,您应该尝试创建一个 dummy class 以完全不 运行 进入该异常。或者:您的 JAR 至少缺少一个依赖项。您可以尝试 解决 该依赖关系 - 也许您可以在某处找到 class,或者,您 "build" 您自己的版本(第二个想法可能是很难 正确)。

GhostCat 已经解释了为什么您的问题不是删除方法。但我想我应该回答原来的问题,以防其他人想知道。

从类文件中删除方法的最佳方法是使用 Krakatau 对其进行反汇编,从 .j 文件中删除所需的方法,然后重新组合。此方法允许您编辑任何类文件,无论多么奇怪。 (如果您发现 Krakatau 反汇编程序无法处理的任何有效类文件,请提交错误)。

反汇编时,可能还想通过-roundtrip选项。这不是正确性所必需的,但它可以防止重新排列常量池,从而减少生成的类文件的二进制差异。另一方面,-roundtrip 也使得在 .j 文件中找到所需的方法变得更加困难。