• Arthas之实例操作


    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. 实例方法调用

    调用实例 getNotesetNote 方法

    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. 总结

    欢迎感兴趣的朋友关注我的订阅号“小院不小”,或点击下方二维码关注。我将多年开发中遇到的难点,以及一些有意思的功能,体会都会一一发布到我的订阅号中
    订阅号

  • 相关阅读:
    Linux学习笔记---编辑器Vim
    等保备案主体是谁?在当地网安进行备案是吗?
    数组容器装水问题解法
    软件测试面试题之自动化测试题大合集(上)
    VMLogin防关联指纹浏览器与传统浏览器的主要区别
    Java高级编程—注解
    跟模型和中间层聊聊:什么是最好的AI原生应用?
    大数据hadoop_HDFS概述(1)
    IPv4报文头部
    解决Linux提示:/lib64/libc.so.6: version GLIBC_2.XX‘ not found
  • 原文地址:https://www.cnblogs.com/yfrs/p/arthas_instance.html