java中序列化和反序列化的作用,java反射实例化

  java中序列化和反序列化的作用,java反射实例化

  本文已经给大家带来了一些关于java的知识,包括java反射机制的相关问题。动态获取程序信息,动态调用对象的功能称为Java语言的反射机制,希望对你有帮助。

  如何解决写爬虫IP受阻的问题?立即使用。

  每次听到大佬们谈论或者看论坛等途径了解java反序列化漏洞,都会有一个词叫反射机制。Boss利用这个词,给你创造了一个有效载荷。对于我们这些刚学java反序列化的人来说,可能会有点困惑。反正我很迷茫,就赶紧学了一波,不然和大佬的差距越来越大。所以本文主要讨论java反射机制。

  

Java反射机制

   Java的反射机制是指在程序运行状态下,可以构造任意一类对象,知道任意一个对象所属的类,知道任意一个类的成员变量和方法,调用任意一个对象的属性和方法。这种动态获取程序信息,动态调用对象的功能被称为Java语言的反射机制。反思被认为是动态语言的关键。

  我不太会文字,还是操作上图吧。

  非反射机制的例子

  //定义一个animals接口interface animals {

  公共摘要void print();}//定义类来实现animals接口的抽象方法,类Dog实现animals {

  公共作废打印(){

  system . out . println( Dog );

  } }类猫实现动物{

  公共作废打印(){

  system . out . println( Cat );

  } }//构造一个zoo类//之后,如果我们只需要修改zoo类class zoo {

  公共静态动物getInstance(String animals name){

  动物a=空;

  if(‘狗’。等于(动物名)){

  a=新狗();

  }

  if(猫。等于(动物名)){

  a=新猫();

  }

  返回a;

  } }公共类反射{

  公共静态void main(String[] args) {

  //借助zoo类找到对应的类实现接口

  animals a=zoo . getinstance( Cat );

  如果(a!=空)

  a . print();

  }}这个时候要添加动物,就

  添加类,修改动物园,修改主函数的动物类,把上面的改成反射机制。

  //定义一个animals接口interface animals {

  公共摘要void print();}//定义类来实现animals接口的抽象方法,类Dog实现animals {

  公共作废打印(){

  system . out . println( Dog );

  } }类猫实现动物{

  公共作废打印(){

  system . out . println( Cat );

  } }//构造一个zoo类//之后,如果我们只需要修改zoo类class zoo {

  公共静态动物getInstance(字符串类名){

  动物a=空;

  尝试{

  //借助Class.forName找到类名,用newInstance实例化类似new的东西。

  a=(animals)class . for name(class name)。new instance();

  } catch(异常e) {

  e . printstacktrace();

  }

  返回a;

  } }公共类反射{

  公共静态void main(String[] args) {

  //借助zoo类(classname是当前包名加上类名)找到相应的类实现接口

  animals a=zoo . getinstance( com . cc1 . dog );

  如果(a!=空)

  a . print();

  }}这个时候添加动物只需要

  类添加修改主函数的animal类省去了一个步骤,传入的类名可控,任何看似存在的类都可以调整。

  

反射机制方法

  我们用得最多的可能是

  ForName(调用类)getMethod(类下调用方法)invoke(执行)newInstance(实例化对象)类。forname(类名)。getmethod (methodname)。调用(类。forname(类名)。new instance());让我们使用反射机制来弹出计算机(calc)或记事本。

  因为有几台电脑弹出来,这次我就玩记事本。总之,能弹出来真好。

  Runtime.getRuntime()。exec(记事本);

  让我们看看getRuntime函数。

  已知该函数是运行时类获取对象的方式,每次使用都要调整一次,比较麻烦。为了构建一个对象而不调用它一次,它被封装到一个函数中。

  类对象获取方式

  Class.forName(类名获取)zoo.class(已加载类)obj.class(实例)类初始化

  修改zoo类,添加初始块、静态初始块和构造函数。

  动物园类{

  //初始块

  {

  system . out . println( 1 this . getclass());

  }

  //静态初始块

  静态{

  system . out . println( 2 zoo . class);

  }

  公共动物园(){

  system . out . println( 3 this . getclass());

  }

  公共静态动物getInstance(字符串类名){

  动物a=空;

  尝试{

  //借助Class.forName找到类名,用newInstance实例化类似new的东西。

  a=(animals)class . for name(class name)。new instance();

  } catch(异常e) {

  e . printstacktrace();

  }

  返回a;

  }}类初始化执行顺序:静态初始块类实例化执行顺序:静态初始块-初始块-构造器由此得知,类初始化和类实例化不一样

  接下来,添加zoo1类来继承zoo类。

  zoo1类扩展zoo{

  //初始块

  {

  system . out . println( 11 this . getclass());

  }

  //静态初始块

  静态{

  system . out . println( 12 zoo . class);

  }

  公共zoo1() {

  system . out . println( 13 this . getclass());

  }}子类初始化顺序:父类静态初始化块-子类静态初始化块子类实例化顺序:父类静态初始化块-子类静态初始化块-父类初始化块-父类构造器-子类初始化块-子类构造器以上可以得知,当使用Class.forName时,且类静态初始化块可控,可以执行任意代码

  调用内部类

  getMethod

  invoke

  静态方法和动态方法的区别

  最后,让我们合并

  class . forname( Java . lang . runtime )。

  getMethod(exec ,String.class)。

  invoke(class . forname( Java . lang . runtime )。getMethod(getRuntime )。invoke(class . forname( Java . lang . runtime ), notepad );

  

指定构造方法生成实例

   String str= notepad ;process builder Pb=new process builder(str);Pb . start();GetConsturctor(函数可以选择指定接口格式的构造函数(因为构造函数也可以根据参数重载)

  选择之后,我们可以通过newInstance()执行构造函数,传入构造函数的参数。

  ProcessBuilder类有两个构造函数

  公共流程构建器(string … command) (string …可变长度字符串数组string []。class)公共流程构建器(list命令)分别使用构造方法。

  class . forname(" Java . lang . process builder ")。getConstructor(字符串[]。类)。new instance(new String[][]{ { " notepad " } })class . for name(" Java . lang . process builder ")。GetConstructor (list.class)。new instance(arrays . aslist(" notepad "))构造函数实例执行后,可以使用start函数进行强制转换。

  其实肯定行不通。怎么会有这种好事,或者只是反映一下?

  class . forname(" Java . lang . process builder ")。getMethod("start ")。invoke(clazz . get constructor(list . class))。new instance(arrays . aslist(" notepad "));

  这里可能有人会奇怪,为什么我用newstring [] [] {{"Notepad"}}作为Rina的另一个构造函数String…command的参数。不应该是new string[]{“Notepad”},应该是现在用的。

  在这一行的断点处调试。

  我们传递的是一个字符串数组在实例化的时候变成了一个字符串。再看另一个构造函数(列表)。

  这仍然是这条线的一个突破口

  由此可知,List传入时会被当作Object的第一项,而String[]会被当做Object,所以多加一层[]{}

  

执行私有方法

  通过函数getDeclaredConstraint获取私有方法,然后使用setAccessible(true)打破私有方法限制。

  class cls=class . forname( Java . lang . runtime );

  构造函数m=cls . getdeclaredconstructor();

  m . set accessible(true);

  cls.getMethod(exec ,String.class)。invoke(m.newInstance(), notepad );推荐:《java视频教程》是Java反序列化的反射机制的详细内容。请多关注我们的其他相关文章!

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: