Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/204.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何重命名Java.class文件?_Java_Android_Decompiling - Fatal编程技术网

如何重命名Java.class文件?

如何重命名Java.class文件?,java,android,decompiling,Java,Android,Decompiling,我正在调试一个使用预编译jar的程序。我想记录对某个类中函数的调用。其思想是将原始类文件Xxx.class重命名为Xxx0.class,并将原始类名定义为: class Xxx extends Xxx0 { void func() { Log.d(...); super.func(); } } 有什么想法吗 (我确实尝试过反编译器:反编译代码中有奇怪的控制结构,反编译器可能无法为该程序生成正确的代码。)你不能只重命名类文件,因为加载类文件时不仅要

我正在调试一个使用预编译jar的程序。我想记录对某个类中函数的调用。其思想是将原始类文件Xxx.class重命名为Xxx0.class,并将原始类名定义为:

class Xxx extends Xxx0 {
    void func() {
        Log.d(...);
        super.func();
    }
}
有什么想法吗


(我确实尝试过反编译器:反编译代码中有奇怪的控制结构,反编译器可能无法为该程序生成正确的代码。)

你不能只重命名类文件,因为加载类文件时不仅要使用类的名称来计算类文件的名称,但是类的名称也存储在类文件中,并且必须与请求的类匹配


因此,如果您想重命名一个类,您需要在源代码中这样做并重新编译。

您无法更改.class文件的名称,因为它与java的公共类链接(相同)。但是,如果您更改了.class文件的名称,则还需要更改该类的名称,否则会导致错误

一旦编译完成(.java to.class),它将转换为字节码,因此如果更改了类文件的名称,则无法直接更改字节码,但可以使用反编译器(反射)将.class文件再次转换为.java,然后将公共类名更改为更改后的文件名,再次构建并使用它


您可以获得许多可用的反编译器,它们可以轻松地将.class转换为.java,并且80%相同。

如果您想重命名一个类,但没有源java文件,请执行以下步骤:

i)首先在jd(java反编译器)中打开文件,然后保存(Ctrl+S)源文件。
ii)重命名java文件(F2)以及java文件内的类名。
iii)再次将java文件(使用任何java编译器)编译为.class文件。

这将解决您的问题。
试试这个,如果有任何问题,请告诉我。

注意:如果您在java反编译中遇到问题,请尝试使用另一版本的JD。

Java类文件不应随意重命名。执行此操作时,由于出现错误,您编辑的类文件将不再可用。这是因为类文件的名称与java类名相对应

这样,您只需在eclipse中使用.class查看器,复制.class文件中显示的java代码。创建另一个.java文件,并使用所需的文件名重命名类名。编译.java文件并找到相应的.class

现在,您已经成功重命名了.class


然而,也有缺点。只需确保将更改反映到其他受影响的类。

我将使用类似的字节码操纵库,并在中更改名称

但是,我不确定您是否仍然需要更新对其他类型中类型的引用,即使您提供了自己的替代方法-合成访问器是否转换为子类型


如果目的是日志记录,那么有比替换类型更复杂的方法:如上所述使用或字节码操作检测方法。

我确实重命名了类文件,但这是一个漫长而乏味的故事。在我的例子中,这是一个Android应用程序,您可能需要将类转换为Android应用程序以重复我所做的:)。顺序是:

  • 使用apktool反编译apk。您将获得子目录yourapname/smali/packageName/,其中包含类的反编译源代码
  • 将类及其子类复制到一个新文件中,例如Stuff.smali变为Xtuff.smali,Stuff$untible.smali变为Xtuff$untible.smali
  • 在文本编辑器中打开这些新文件,我使用了gedit
  • 替换所有出现的完整类路径,例如Lfoo/bar/baz/qux/Stuff变为Lfoo/bar/baz/qux/Xtuff;最好查看您正在进行的每个替换,但最有可能的是您将替换所有替换(注意:您确实替换了像Lfoo/bar/baz/qux/Stuff$Data这样的字符串,但没有替换像Lfoo/bar/baz/qux/StuffData这样的字符串)
  • 用“Xtuff”替换所有(或不是所有)出现的类名“Stuff”;在这种情况下,您很可能不会替换所有实例。在这一步中,您需要了解自己正在做什么
  • (保存原始apk并)使用apktool重建apk,使用-f标志:
    apktool b-f AppName AppName.apk
  • 从新的apk中提取classes.dex(在步骤6获得);我使用了Midnight Commander,它将压缩的档案(包括dex和jar)显示为目录
  • 将dex转换为jar:
    ~/Downloads/dex2jar-0.0.9.13/d2j-jar2dex.sh classes.jar
    ,您将得到classes-dex2jar.jar
  • 将新的(重命名的)类提取到Eclipse项目中(Xtuff.class、Xtuff$unavailable等),从顶级重命名类派生类(
    class-Stuff-extensed-Xtuff
    ),编译,就得到了新的Stuff.class。(如果现在可以调试,则可以开始调试并跳过以下步骤。)
  • 将classes-dex2jar.jar复制到classes-X.jar,将步骤9中获得的类文件(包括嵌套类)添加到classes-X.jar
  • 将classes-X.jar转换为classes.dex
  • 将此新的classes.dex放置到原始apk
  • 签署apk:
    jarsigner-verbose-keystore./my.keystore./AppName.apk mykey
  • 删除原始应用程序,安装修改后的apk
  • 很明显,一个专用的工具将使这个长序列更容易执行

    当然,这种方法不适用于生产代码


    PPS这不是一个通用的案例配方:如果您的类包含静态工厂方法,那么所需的修改将变得更加棘手。

    这是面向方面编程的经典任务。例如,请参阅。

    @Juvanis看起来像是二进制的十进制形式,或者是2^64-1。@Juvanis我用来生成用户名的内容与此无关。@Juvanis请继续讨论。虽然它是一个聪明的用户