我正在调试一个使用预编译jar的程序。我想记录对某个类中的函数的调用。我们的想法是将原始类文件Xxx.class重命名为Xxx0.class,并将原始类名定义为:
class Xxx extends Xxx0 {
void func() {
Log.d(...);
super.func();
}
}
有什么想法吗?
(我确实尝试过反编译器:反编译代码中有奇怪的控制结构,反编译程序可能无法为此程序生成正确的代码。)
答案 0 :(得分:1)
您不能只重命名一个类文件,因为在加载类文件时,不仅要使用类的名称来计算类文件的名称,而且类的名称也存储在类文件中,并且必须与要求的类匹配。
因此,如果要重命名一个类,则需要在源代码中重命名并重新编译。
答案 1 :(得分:1)
如果要重命名类ant,则没有源java文件,请执行以下步骤:
i)首先在jd(java反编译器)中打开文件,然后保存(Ctrl + S)源文件。
ii)重命名java文件(F2)以及java文件中的类名
iii)再次编译java文件(使用任何java编译器)到.class文件。
这将解决您的问题
试试这件事,如果有任何疑虑,请告诉我。
注意:如果您遇到java decomplier问题,请尝试使用其他版本的JD。
Please visit here to download latest JD
答案 2 :(得分:0)
您无法更改.class文件的名称,因为它与java的公共类链接(相同)。如果您更改了.class文件的名称,那么您需要更改类的名称,否则会导致错误。
一旦它符合(.java到.class)它就会转换为字节码,所以如果你改变了类文件的名字,你就无法直接更改字节码,但你可以再次使用.class文件转换为.java反编译器(反射),然后将公共类名称更改为更改的文件名,再次构建并使用它。
你可以获得许多反编译器,它们可以轻松地将.class转换为.java,并且80%相同。
答案 3 :(得分:0)
不应该根据自己的意愿重命名Java类文件。执行此操作时,由于错误,您编辑的类文件将永远不会再次使用。这是因为类文件的名称对应于您的java类名。
有了这个,你需要做的就是在eclipse中使用.class查看器,复制.class文件中显示的java代码。制作另一个.java文件,并使用所需的文件名重命名类名。编译.java文件并找到相应的.class。
现在,您已经成功重命名了.class。
然而,存在缺点。只需确保将更改反映到受影响的其他类。
答案 4 :(得分:0)
我会使用像ASM这样的字节码操作库,并更改class visitor中的名称。
但是,我不确定您是否仍需要更新其他类型的引用,即使您提供了自己的替代方案 - 合成访问器是否转换为子类型?
如果目的是记录,则替换类型的方法较少:使用AOP或上述字节码操作来检测方法。
答案 5 :(得分:0)
我确实重命名了这个类文件,但这是一个冗长乏味的故事。在我的例子中,这是一个Android应用程序,您可能需要将您的类转换为Android应用程序以重复我所做的:)。顺序是:
apktool b -f AppName AppName.apk
~/Downloads/dex2jar-0.0.9.13/d2j-jar2dex.sh classes.jar
,你得到的是class-dex2jar.jar class Stuff extends Xtuff
)派生类,编译,得到新的东西。类。 (如果您现在可以调试,则可以开始调试并跳过以下步骤。)jarsigner -verbose -keystore ./my.keystore ./AppName.apk mykey
很明显,专用工具可以使这个长序列更容易执行。
PS此方法当然不适用于生产代码。
PPS这不是一般情况的配方:如果你的类包含一个静态工厂方法,那么所需的修改会变得更加棘手。
答案 6 :(得分:0)
这是面向方面编程的经典任务。例如,请参阅Aspect Oriented Android Development – Tool Integration。