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的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。