2013-03-19 110 views
2

我正在調試使用預編譯的jar的程序。我想在某些類中記錄對函數的調用。我們的想法是原來的類文件Xxx.class重命名爲Xxx0.class和定義原始類的名稱爲:如何重命名Java .class文件?

class Xxx extends Xxx0 { 
    void func() { 
     Log.d(...); 
     super.func(); 
    } 
} 

任何想法?

(我曾嘗試反編譯:有在反編譯的代碼奇怪的控制結構,反編譯器可能不會產生正確的代碼對這一計劃)

+0

@Juvanis看起來像是二進制的小數形式[1111111111111111111111111111111111111111111111111111111111111111](http://www.wolframalpha.com/input/?i=+18446744073709551615),還是2^64-1。 – Kapep 2013-03-19 07:13:56

+0

@Juvanis我用來生成我的用戶名是無關緊要的。 – 18446744073709551615 2013-03-19 07:41:09

+0

@Juvanis請留在話題上。雖然它是一個聰明的用戶名,但是stackoverflow不適合脫離主題討論。 – DankMemes 2013-03-20 06:14:07

回答

1

你不能只重命名一個類文件,因爲加載它時不僅使用類的名稱來計算類文件的名稱,而且該類的名稱也存儲在類文件中,並且必須與請求的類匹配。

因此,如果你想重命名一個類,你需要在源代碼中重新編譯。

+0

是的,但由於有反編譯器,有人可以實現一個重命名工具。 – 18446744073709551615 2013-03-19 07:35:40

+0

當然,但我覺得使用JPDA或其他方式來改變活動虛擬機中的功能可能更簡單,也更簡單。 :) – Dolda2000 2013-03-19 07:38:59

+1

嗯,這可能是誇張的,但我想說明,它不會像在類文件中更改名稱一樣簡單;例如,您也必須在常量池中更改對它的所有引用,並且我不知道類的其他格式是否足夠好,以便說明是否還有其他需要更新的符號引用。 – Dolda2000 2013-03-19 07:45:30

0

您無法更改.class文件的名稱,因爲它與java的公共類相關聯(相同)。如果您更改了.class文件的名稱,那麼您仍然需要更改類的名稱,否則會導致錯誤。

一旦它符合(.java到.class)它將轉換爲字節碼,所以如果您更改了類文件的名稱,您將無法直接更改字節碼,但可以將.cl​​ass文件轉換爲.java使用反編譯器(反射),然後將公共類名更改爲您更改的文件名,再次構建並使用它。

您可以獲得很多可用的反編譯器,它們可以很容易地將.class轉換爲.java,並且80%相同。

+1

Java編譯器不會將Java源代碼轉換爲OS本機代碼,它會將其編譯爲與JVM兼容的字節碼。 JVM然後將字節碼轉換爲本地代碼。 – Logan 2013-03-19 07:19:00

+0

是的,它的字節碼本地代碼:)謝謝 – Amol 2013-03-19 09:21:20

1

如果要重命名一個類的螞蟻,你沒有Java源代碼文件,然後執行以下步驟:

我)首先在JD(Java反編譯器)打開該文件,然後保存(Ctrl + S)源文件。
ii)重命名java文件(F2)以及java文件中的類名。
iii)再次編譯java文件(使用任何java編譯器)到.class文件。

這將解決您的問題。
試試這個,讓我知道萬一有任何顧慮。

備註:如果您在使用java解壓縮程序時遇到問題,請嘗試使用其他版本的JD。
Please visit here to download latest JD

+0

不幸的是,因爲那個類jd顯示'// INTERNAL ERROR //'。 – 18446744073709551615 2013-03-19 07:32:05

+0

你用JD打開過類文件嗎?它顯示的是java代碼嗎? – 2013-03-19 07:37:59

+0

不,它顯示'// INTERNAL ERROR //'。如果它顯示java代碼,那就沒有問題了。 – 18446744073709551615 2013-03-19 08:24:10

0

Java類文件不應該根據自己的意願重命名。當您這樣做時,由於錯誤,您編輯的類文件將不會再次可用。這是因爲類文件的名稱對應於您的java類名稱。因此,您只需在eclipse中使用.class查看器,即可複製.class文件中顯示的java代碼。製作另一個.java文件,並使用所需的文件名重命名類名。編譯你的.java文件並找到相應的.class。

現在,您已經成功更名.class。

但是,存在缺點。只要確保將變化反映到受影響的其他課程。

0

我會使用像ASM這樣的字節碼操作庫並更改class visitor中的名稱。

但是,我不確定是否仍需要更新對其他類型的引用,即使您提供了自己的替代方法 - 是否將合成訪問器轉換爲子類型?

如果目的是日誌記錄,那麼比替換類型更少複雜的方法:用AOP或上述的字節碼操作來檢測方法。

0

我確實重命名了類文件,但這是一個漫長而無聊的故事。在我的情況下,這是一個Android應用程序,您可能需要將您的類轉換爲Android應用程序來重複我所做的:)。序列如下:

  1. 反編譯APK apktool。你得到子目錄yourApkName/smali/packageName /你的類的反編譯源。
  2. 將類及其子類複製到一個新文件,例如Stuff.smali成爲Xtuff.smali東西$ Useless.smali成爲Xtuff $ Useless.smali
  3. 在文本編輯器打開這些新文件,我用的gedit。
  4. 將所有出現的完整課程路徑替換爲例如Lfoo/bar/baz/qux/Stuff變成Lfoo/bar/baz/qux/Xtuff;最好看到你正在做的每個替換,但最有可能的是你會替換所有的替換(注意:你替換字符串像Lfoo/bar/baz/qux/Stuff $ Data,但不要替換Lfoo/bar/baz之類的字符串/ qux/StuffData)
  5. 用「Xtuff」替換類名「Stuff」的全部(或不全部)出現;在這種情況下,您很可能會替換並非所有的事件。在這一步你需要了解你在做什麼。使用apktool重建apk,使用-f標誌:apktool b -f AppName AppName.apk
  6. 從該新apk中提取classes.dex(在步驟6獲得);我用了午夜指揮官,它顯示壓縮檔案(包括地塞米松和jar)作爲目錄
  7. 轉換DEX到罐子:~/Downloads/dex2jar-0.0.9.13/d2j-jar2dex.sh classes.jar,你得到的類 - dex2jar.jar
  8. 提取新(重命名)類的Eclipse項目( Xtuff.class,Xtuff $無用等),從頂級重命名類(class Stuff extends Xtuff)派生類,編譯,你會得到新的Stuff.class。 (如果您現在可以進行調試,則可以開始調試並跳過以下步驟。)
  9. 將classes-dex2jar.jar複製到classes-X.jar,將在第9步獲得的類文件(包括嵌套類)添加到classes- X.jar
  10. 轉換類,X.jar到classes.dex
  11. 地方這個新classes.dex原來的APK
  12. 簽署apk:jarsigner -verbose -keystore ./my.keystore ./AppName.apk mykey
  13. 刪除原來的應用程序,安裝APK修改。

很明顯,一個專用工具會使這個長序列更容易執行。

PS此方法當然不適用於生產代碼。

PPS這不是一般情況下的配方:如果你的類包含靜態工廠方法,所需的修改變得更加棘手。