专栏名称: 渗透测试网络安全
致力于分享成员技术研究成果、漏洞新闻、安全招聘以及其他安全相关内容,非营利组织,商业广告免谈
目录
相关文章推荐
51好读  ›  专栏  ›  渗透测试网络安全

浅析JAVA javassist技术

渗透测试网络安全  · 公众号  ·  · 2022-07-07 22:25

正文

请到「今天看啥」查看全文


浅析javassist


0x01  javassist是什么?

网上copy~: Javassist是可以动态编辑Java字节码的类库。它可以在Java程序运行时定义一个新的类,并加载到JVM中;还可以在JVM加载时修改一个类文件。Javassist使用户不必关心字节码相关的规范也是可以编辑类文件的。


0x02 javassist介绍

1.ClassPool

ClassPool:一个基于哈希表(Hashtable)实现的CtClass对象容器,其中键名是类名称,值是表示该类的CtClass对象

常用方法

static ClassPool  getDefault()  返回默认的类池。ClassPath  insertClassPath(java.lang.String pathname)    在搜索路径的开头插入目录或jar(或zip)文件。ClassPath  insertClassPath(ClassPath cp)    ClassPath在搜索路径的开头插入一个对象。java.lang.ClassLoader  getClassLoader()    获取类加载器toClass(),getAnnotations()在 CtClassCtClass  get(java.lang.String classname)    从源中读取类文件,并返回对CtClass 表示该类文件的对象的引用。ClassPath  appendClassPath(ClassPath cp)  ClassPath对象附加到搜索路径的末尾。CtClass  makeClass(java.lang.String classname)  创建一个新的public


2.CtClass

CtClass表示类,一个CtClass(编译时类)对象可以处理一个class文件,这些CtClass对象可以从ClassPoold的一些方法获得。

void  setSuperclass(CtClass clazz)  更改超类,除非此对象表示接口。java.lang.Class>  toClass(java.lang.invoke.MethodHandles.Lookup lookup)    将此类转换为java.lang.Class对象。byte[]  toBytecode()    将该类转换为类文件。void  writeFile()    将由此CtClass 对象表示的类文件写入当前目录。void  writeFile(java.lang.String directoryName)    将由此CtClass 对象表示的类文件写入本地磁盘。CtConstructor  makeClassInitializer()    制作一个空的类初始化程序(静态构造函数)。

3.CtMethod

CtMethod:表示类中的方法。

void  setBody(java.lang.String src)    设置构造函数主体。void  setBody(CtConstructor src, ClassMap map)    从另一个构造函数复制一个构造函数主体。CtMethod  toMethod(java.lang.String name, CtClass declaring)    复制此构造函数并将其转换为方法。

4.CtConstructor

CtConstructor的实例表示一个构造函数。它可能代表一个静态构造函数(类初始化器)。

具体不做过多介绍,参考连接

https://blog.csdn.net/weixin_39876592/article/details/111256182


0x03 javassist简单使用

1.创建类玩法

        ClassPool cp = ClassPool.getDefault();//获取类池        CtClass ctClass = cp.makeClass("org.example.ClassLoaders.Met32");//创建一个类        ctClass.writeFile("src/main/java");//写入


    2.向存在的类植入代码

    在下面代码中,本人首先准备了一个现有的类User,并给User中的say方法植入代码

    User:

    public class User {
    public void say(){
    System.out.println("User say");
    }
    }
    ClassPool cp = ClassPool.getDefault();CtClass ct2 = cp.get("org.example.ClassLoaders.User");//现有类的路径CtMethod ctMethod = ct2.getDeclaredMethod("say");//获取User类的say方法ctMethod.insertBefore("Runtime.getRuntime().exec(\"calc\");");//植入代码Class clazz = ct2.toClass();User user = (User) clazz.newInstance();user.say();

    可以看见User中的say方法,成功被植入,这就类似于aop


    3. 实现set和get方法

    ClassPool cp = ClassPool.getDefault();
    CtClass ctClass = cp.makeClass("org.example.ClassLoaders.Hello");//Field就是设置属性CtField ctField = new CtField(CtClass.intType,"value",ctClass);//参数1 类型 参数2 名称 参数3 CtClassctField.setModifiers(Modifier.PRIVATE);//设置访问修饰符ctClass.addField(ctField);
    /*CtMethod(...)源代码:public CtMethod(CtClass returnType,//这个方法的返回值类型, String mname, //(method name)方法的名字是什么 CtClass[] parameters, //方法传入的参数类型是什么 CtClass declaring //添加到哪个类中 ) {....} */CtMethod ctMethod = new CtMethod(CtClass.voidType,"setValue",new CtClass[]{CtClass.intType},ctClass);ctMethod.setModifiers(Modifier.PUBLIC);ctMethod.setBody("this.value = $1;");ctMethod.insertBefore("System.out.println(\"Before....\");");ctMethod.insertAfter("System.out.println(\"After....\");");ctClass.addMethod(ctMethod);
    CtMethod getValue = new CtMethod(CtClass.intType,"getValue",new CtClass[]{},ctClass);getValue.setModifiers(Modifier.PUBLIC);getValue.setBody("return this.value;");ctClass.addMethod(getValue);


    4.toClass and toBytecode


    其实比较通用的还是获取类的byte或者获取class。

            ClassPool cp = ClassPool.getDefault();        CtClass ctClass = cp.get("org.example.ClassLoaders.User");        byte[] bytes = ctClass.toBytecode();//获取byte        String str = Arrays.toString(bytes);        System.out.println(str);
    Class cls = ctClass.toClass();//获取class User user = (User) cls.newInstance(); user.say();





11111
微信搜索关注 "安全族" 长期致力于安全研究


下方扫一下扫,即可关注












请到「今天看啥」查看全文