目录
JSP免杀马
随着Java框架的进化和程序员的内卷,使用PHP
编写的系统越来少,使用Java
编写的系统越来越多。JSP
马的使用越来越多,但是就目前来看,各大厂商对JSP
马的查杀效果还是不尽人意。这里简单通过Java
的反射机制和ClassLoader
技术尝试绕过杀毒软件。
先介绍这几个常见的Java概念。
Java反射
概念
Java的反射(reflection)机制是指在程序的运行状态中,可以构造任意一个类的对象,可以了解任意一个对象所属的类,可以了解任意一个类的成员变量和方法,可以调用任意一个对象的属性和方法。这种动态获取程序信息以及动态调用对象的功能称为Java语言的反射机制。反射被视为动态语言的关键。——《JAVA反射机制》百度百科
要想了解Java
反射,首先要了解到.java
文件是无法直接执行的,需要将其编译成.class
字节码文件,然后借助借助Java
虚拟机也就是jvm
进行执行。
通过Java
语言中的反射机制可以直接操作字节码文件。
要操作一个类的字节码,需要首先获取,有以下三种方式获取java.lang.Class
实例:
//1
Class.forName(“完整类名带包名”)
//2
对象.getClass()
//3
任何类型.class
这三种获取方式没有使用上的区别。
下面我们通过一个实例来使用一下Java
的反射机制。
实例
创建Reflect类:
public class Reflect {
private static Reflect reflect = new Reflect();
public Reflect() {
}
public static Reflect getReflect() {
return reflect;
}
public void print(int a, int b) {
System.out.println(a + b);
}
}
利用反射的方式调用函数:
import java.lang.reflect.Method;
public class testClass {
public static void main(String[] args) throws Throwable {
//正常方式
Reflect reflect = new Reflect();
reflect.print(1, 2);
//部分反射
//通过运行时的对象调用getClass();
Class<?> aClass = Class.forName("reflection.Reflect");
//getMethod(方法名,参数类型)
//getMethod第一个参数是方法名,第二个参数是该方法的参数类型
//因为存在同方法名不同参数这种情况
//所以只有同时指定方法名和参数类型才能唯一确定一个方法
Method method = aClass.getMethod("print", int.class, int.class);
//相当于reflect.print(1, 2);方法的反射操作是用method对象来进行方法调用
//和reflect.print调用的效果完全相同
//使用reflect调用m1获得的对象所声明的公开方法即print,并将int类型的1,2作为参数传入
method.invoke(reflect, 1, 2);
//全部反射
Class.forName("reflection.Reflect")
.getMethod("print", int.class, int.class)
.invoke(Class.forName("reflection.Reflect")
.getMethod("getReflect")
.invoke(Class.forName("reflection.Reflect")), 1, 2);
//如需获取实例化,也可以使用newInstance()
Object instance = aClass.newInstance();
System.out.println("instance = " + instance);
}
}
执行结果如下:
3
3
3
instance = reflection.Reflect@28d93b30
ClassLoader加载机制
ClassLoader
具体作用是将.class
文件加载到jvm
虚拟机中,程序就可以正确运行了。但是,jvm
启动的时候,并不会一次性加载所有的.class
文件,而是根据需要去动态加载。
Java
语言自带有三个类加载器:
-
**Bootstrap ClassLoade**
为最顶层的加载类,主要加载核心类库,%JRE_HOME%\\lib
下的rt.jar
、resources.jar
、charsets.jar
和class
等。 -
**Extention ClassLoader**
为扩展的类加载器,加载目录%JRE_HOME%\\lib\\ext
目录下的jar
包和class
文件。 -
**Appclass Loader**
也称为**SystemAppClass**
为加载当前应用的classpath
的所有类。
BootstrapClassLoader
、ExtClassLoader
、AppClassLoader
是通过查阅相应的环境属性sun.boot.class.path
、java.ext.dirs
和java.