Arthas之實例操作
1. 靜態類屬性操作
獲取public靜態屬性
ognl -c 7cd84586 '@com.system.framework.ArtahsDemoClassLoader@pubTestPrex'
ognl -c 7cd84586 "@com.system.framework.ArtahsDemoClassLoader@pubfinalTestPrex"
輸出各式 @Type[屬性值],內容如下
@String[static public]
...
@String[final static public]
獲取private靜態屬性
ognl -c 7cd84586 '@com.system.framework.ArtahsDemoClassLoader@privTestPrex'
ognl -c 7cd84586 '@com.system.framework.ArtahsDemoClassLoader@privFnalTestPrex'
@String[static private]
...
@String[final static private]
修改public靜態屬性,被final修飾,不能被修改
// author:herbert qq:464884492 date:20220331 測試代碼想修改FINAL修飾符,結果沒有成功
@Test
public void testModifyFinal() throws Exception {
Field finalField = this.getClass().getDeclaredField("privFnalTestPrex");
finalField.setAccessible(true);
System.out.println("==========初始值==========");
System.out.println(finalField.get(null));
Field modiField = Field.class.getDeclaredField("modifiers");
modiField.setAccessible(true);
modiField.setInt(finalField, finalField.getModifiers() & ~Modifier.FINAL);
finalField.set(null, "修改后FInal");
System.out.println("==========修改值==========");
System.out.println(privFnalTestPrex);
}
靜態變量賦值,不能通過=直接賦值,需要采用反射的方式設置值
ognl '#c=@com.system.framework.ArtahsDemoClassLoader@class,#f=#c.getDeclaredField("pubTestPrex"),#f.set(#c,"modify static public ")'
修改private靜態屬性,需要在反射時調用方法setAccessible
,使private特殊轉化為public
ognl '#c=@com.system.framework.ArtahsDemoClassLoader@class,#f=#c.getDeclaredField("privTestPrex"),#f.setAccessible(true),#f.set(#c,"modify static private ")'
2. 靜態類方法調用
靜態方法調用和靜態屬性一樣,格式為@class@method(args)
無參數調用
ognl -c 7cd84586 '@com.system.framework.ArtahsDemoClassLoader@setPublicStaticMethod()'
ognl -c 7cd84586 '@com.system.framework.ArtahsDemoClassLoader@modfiyPrivateStaticFiled()'
...
======第5次輸出======
源文件初始輸出==>static public/static private/testRefect--1/final static public/final static private
源文件初始輸出==>static public/static private/testRefect--2/final static public/final static private
======第6次輸出======
源文件初始輸出==>modify by method static public/static private/testRefect--1/final static public/final static private
源文件初始輸出==>modify by method static public/static private/testRefect--2/final static public/final static private
...
======第11次輸出======
源文件初始輸出==>modify by method static public/static private/testRefect--1/final static public/final static private
源文件初始輸出==>modify by method static public/static private/testRefect--2/final static public/final static private
======第12次輸出======
源文件初始輸出==>modify by method static public/modify by method static private/testRefect--1/final static public/final static private
源文件初始輸出==>modify by method static public/modify by method static private/testRefect--2/final static public/final static private
...
// author:herbert qq:464884492 date:20220331
有參數調用
ognl -c 7cd84586 '@com.system.framework.ArtahsDemoClassLoader@getPublicStaticMethod("input params")'
...
ognl -c 7cd84586 '@com.system.framework.ArtahsDemoClassLoader@getStaticPrivateMethod("input params")'
@String[input params <==> public static method return string]
...
@String[input params <==> private static method return string]
從以上的測試結果來說,靜態方法不管是public還是private都可以直接調用。
3. 獲取非靜態類實例
查看某個類實例,無 --limit 參數默認10個
vmtool -c 3e2e18f2 -a getInstances --className *EncryptClass
vmtool -c 3e2e18f2 -a getInstances --className *EncryptClass --express 'instances.length'
vmtool -c 3e2e18f2 -a getInstances --className *EncryptClass --express 'instances[0]'
@EncryptClass[][
@EncryptClass[com.system.framework.EncryptClass@3c573d32],
@EncryptClass[com.system.framework.EncryptClass@68390fae],
]
...
@Integer[2]
...
@EncryptClass[
note=@String[testRefect--1],
]
經過上邊測試發現,一個類存在多個classloader加載時,需要指定classloader。但從返回結果看,返回了所有classloader加載的實例
4. 實例方法調用
調用實例 getNote
和 setNote
方法
vmtool -c 3e2e18f2 -a getInstances --className *EncryptClass --express '#val=instances[0],#val.getNote()'
vmtool -c 3e2e18f2 -a getInstances --className *EncryptClass --express '#val=instances[0],#val.setNote("modify by instance"+#val.getNote())'
@String[testRefect--1]
======第7次輸出======
源文件初始輸出==>static public/static private/testRefect--1/final static public/final static private
源文件初始輸出==>static public/static private/testRefect--2/final static public/final static private
======第8次輸出======
源文件初始輸出==>static public/static private/modify by instancetestRefect--1/final static public/final static private
源文件初始輸出==>static public/static private/testRefect--2/final static public/final static private
從控制台輸出結果,對比第7次和8次輸出,我們可以發現第一個loader加載的class實例已經成功修改了
5. 實例屬性操作
獲取或者修改第一個實例 note 屬性
vmtool -c 3e2e18f2 -a getInstances --className *EncryptClass --express '#val=instances[1].note'
vmtool -c 3e2e18f2 -a getInstances --className *EncryptClass --express '#val=instances[1],#val.note="modify by instance"+#val.note'
@String[testRefect--2]
...
======第121次輸出======
源文件初始輸出==>static public/static private/modify by instancetestRefect--1/final static public/final static private
源文件初始輸出==>static public/static private/testRefect--2/final static public/final static private
======第122次輸出======
源文件初始輸出==>static public/static private/modify by instancetestRefect--1/final static public/final static private
源文件初始輸出==>static public/static private/modify by instancetestRefect--2/final static public/final static private
從控制台輸出結果,對比第121次和122次輸出,我們可以發現第二個loader加載的class實例已經成功修改了
6. 條件操作
返回的對象集合,可以做二次篩選投影操作,也可以帶條件查詢符合的數據
vmtool -c 3e2e18f2 -a getInstances --className *EncryptClass --express '#val=instances'
vmtool -c 3e2e18f2 -a getInstances --className *EncryptClass --express '#val=instances.{note}'
vmtool -c 3e2e18f2 -a getInstances --className *EncryptClass --express '#val=instances.{#this.note}'
vmtool -c 3e2e18f2 -a getInstances --className *EncryptClass --express '#val=instances.{? #this.note.indexOf("1")>0}.{note}'
@EncryptClass[][
@EncryptClass[com.system.framework.EncryptClass@52790e67],
@EncryptClass[com.system.framework.EncryptClass@822cf83],
]
...
@ArrayList[
@String[modify by instancetestRefect--1],
@String[modify by instancetestRefect--2],
]
...
@ArrayList[
@String[modify by instancetestRefect--1],
@String[modify by instancetestRefect--2],
]
...
@ArrayList[
@String[modify by instancetestRefect--1],
]
7. 總結
歡迎感興趣的朋友關注我的訂閱號“小院不小”,或點擊下方二維碼關注。我將多年開發中遇到的難點,以及一些有意思的功能,體會都會一一發布到我的訂閱號中