2011-08-25 66 views
1

如何才能找到正在運行的java程序在內存中存儲正在運行的字節碼?我很欣賞這可能會或可能不會令人難以忍受。尋找字節碼

+1

字節代碼存儲在.class文件。你具體是什麼意思? – AlexR

+0

當程序運行時它從磁盤加載到內存中,不是嗎?如何找到存儲在這個'.class'文件中的字節碼? – providence

+0

看來你並不是在問你的「真實」問題。你想解決什麼問題?如果你想攔截類加載,可能會有更好更簡單的解決方案。 – AlexR

回答

2

看的源代碼的本機函數java.lang.ClassLoader.defineClass1(String, byte[], int, int, ProtectionDomain, String, boolean)

這是一個VM specfic,所以沒有通用的解決方案。

如果您想查看字節碼,只需將該類加載爲資源(例如getClass().getClassLoader().getResourceAsStream('java/lang/String.class'))並使用類似ASM或類似工具分析該流。

如果您想在運行時修改字節碼:祝您好運。虛擬機已經針對這種攻擊進行了強化,所以即使你能夠獲得內存位置,也有可能發生這種變化。

請注意,調試器不會修改內存,它們使用特殊的類加載器(或內置的類加載器的功能)在IDE中更改源代碼時有人要求類時返回不同的結果。但是這是有限的。例如,一個虛擬機在類加載一次後不能更改方法的數量和/或參數。

+0

嗯..我不需要這個在我自己以外的任何機器上工作,真的。有沒有一個JVM,我可以叉/擴展來允許這個? – providence

+0

當然:http://openjdk.java.net/ –

1

您可以嘗試使用調試器運行jvm,然後在加載類後立即在分配的內存中搜索字節代碼模式,該模式可以在加載的類文件中找到。

jvm可能決定及時編譯字節碼,然後它可能決定釋放爲字節碼分配的內存(因爲它不再需要)。所以你可能會也可能不會在內存中找到字節碼。

+0

是否可以採用相同的方法開發調試工具以在調試模式之外訪問這些內容? – providence

1

當JVM讀取字節碼時,它會多次處理它,直到它最終生成本地代碼(它可能會執行多次)。嘗試查找某處是存儲字節碼並更改它可能不會做任何事情,因爲它可能不直接使用字節代碼(甚至不保留它)

如果您想要更改字節代碼,建議您在加載之前檢查它,或者使用Instrumentation旨在改變字節碼,並在這種情況發生時觸發正確的行爲。

字節碼實際上是用,也不能保證它意味着什麼真機(這是你所看到的「C」級)

+0

數據+數據結構(可以說是一個數組)的字節碼錶示如何傳遞到正在運行的程序中?這些表示是否可以在運行時從外部生成並從外部傳入? – providence

+0

@providence:對此 –

+0

@providence打開一個新問題,執行此操作的方法是按照我的建議進行更改。你採取的方法極不可能工作。 JVM在運行時會執行大量的優化,並且代碼的概念遠比您所認爲的更流暢。 –