1、HotSwapClassLoader的实现
public class HotSwapClassLoader extends ClassLoader{
public HotSwapClassLoader(){
super(HotSwapClassLoader.class.getClassLoader());
}
@SuppressWarnings("rawtypes")
public Class loadByte(byte[] classByte){
return defineClass(null,classByte,0,classByte.length);
}
}
2、ClassModifier的实现
public class ClassModifier {
private static final int CONSTANT_POOL_COUNT_INDEX=8;
private static final int CONSTANT_Utf8_info=1;
private static final int[] CONSTANT_ITEM_LENGTH={-1,-1,-1,5,5,9,9,3,3,5,5,5,5};
private static final int u1=1;
private static final int u2=2;
private byte[] classByte;
public ClassModifier(byte[] classByte){
this.classByte=classByte;
}
/**
* 修改常量池中CONSTANT_Utf8_info常量的内容
* @param oldStr修改前中字符串
* @param newStr修改后中字符串
* @return 修改结果
*/
public byte[] modifyUTF8Constant(String oldStr,String newStr){
int cpc=getConstantPoolCount();
int offset=CONSTANT_POOL_COUNT_INDEX+u2;
for(int i=0;i<cpc;i++){
int tag=ByteUtils.bytes2Int(classByte, offset, u1);
if(tag==CONSTANT_Utf8_info){
int len=ByteUtils.bytes2Int(classByte, offset+u1, u2);
offset+=(u1+u2);
String str=ByteUtils.bytes2String(classByte, offset, len);
if(str.equalsIgnoreCase(oldStr)){
byte[] strBytes=ByteUtils.string2Bytes(newStr);
byte[] strLen=ByteUtils.int2Bytes(newStr.length(), u2);
classByte=ByteUtils.bytesReplace(classByte, offset-u2, u2, strLen);
classByte=ByteUtils.bytesReplace(classByte, offset, len, strBytes);
return classByte;
}else{
offset+=len;
}
}else{
offset+=CONSTANT_ITEM_LENGTH[tag];
}
}
return classByte;
}
/**
*
* @return
*/
private int getConstantPoolCount() {
return ByteUtils.bytes2Int(classByte,CONSTANT_POOL_COUNT_INDEX, u2);
}
}
3、ByteUtils的实现
public class ByteUtils {
public static int bytes2Int(byte[] b,int start,int len){
int sum=0;
int end=start+len;
for(int i=start;i<end;i++){
int n=((int)b[i])&0xff;
n<<=(--len)*8;
sum=n+sum;
}
return sum;
}
public static byte[] int2Bytes(int value,int len){
byte[] b=new byte[len];
for(int i=0;i<len;i++){
b[len-i-1]=(byte)((value>>8*i)&0xff);
}
return b;
}
public static String bytes2String(byte[] b,int start,int len){
return new String(b,start,len);
}
public static byte[] string2Bytes(String str){
return str.getBytes();
}
public static byte[] bytesReplace(byte[] originalBytes,int offset,int len,byte[] replaceBytes){
byte[] newBytes=new byte[originalBytes.length+(replaceBytes.length-len)];
System.arraycopy(originalBytes, 0, newBytes, 0, offset);
System.arraycopy(replaceBytes, 0, newBytes, offset, replaceBytes.length);
System.arraycopy(originalBytes, offset+len, newBytes, offset+replaceBytes.length, originalBytes.length-offset-len);
return newBytes;
}
}
4HackSystem的实现
public class HackSystem {
public final static InputStream in=System.in;
private static ByteArrayOutputStream buffer=new ByteArrayOutputStream();
public final static PrintStream out=new PrintStream(buffer);
public final static PrintStream err=out;
public static String getBufferString(){
return buffer.toString();
}
public static void clearBuffer(){
buffer.reset();
}
public static void setSecurityManager(final SecurityManager s){
System.setSecurityManager(s);
}
public static SecurityManager getSecurityManager(){
return System.getSecurityManager();
}
public static long currentTimeMills(){
return System.currentTimeMillis();
}
public static void arrayCopy(Object src,int srcPos,Object dest,int destPos,int length){
System.arraycopy(src, srcPos, dest, destPos, length);
}
public static int identityHashCode(Object x){
return System.identityHashCode(x);
}
public static void setIn(InputStream in) {
System.setIn(in);
}
public static void setOut(PrintStream out) {
System.setOut(out);
}
public static Console console() {
return System.console();
}
public static Channel inheritedChannel() throws IOException {
return System.inheritedChannel();
}
public static long nanoTime(){
return System.nanoTime();
};
public static Properties getProperties() {
return System.getProperties();
}
public static void setProperties(Properties props) {
System.setProperties(props);
}
public static String getProperty(String key) {
return System.getProperty(key);
}
public static String getProperty(String key, String def) {
return System.getProperty(key, def);
}
public static String setProperty(String key, String value) {
return System.setProperty(key, value);
}
public static String clearProperty(String key) {
return System.clearProperty(key);
}
public static String getenv(String name) {
return System.getenv(name);
}
public static java.util.Map<String,String> getenv() {
return System.getenv();
}
public static void exit(int status) {
System.exit(status);
}
public static void gc() {
System.gc();
}
public static void runFinalization() {
System.runFinalization();
}
public static void load(String filename) {
System.load(filename);
}
public static void loadLibrary(String libname) {
System.loadLibrary(libname);
}
public static String mapLibraryName(String libname){
return System.mapLibraryName(libname);
};
}
5JavaClassExecuter的实现
public class JavaClassExecuter {
@SuppressWarnings({ "unused", "rawtypes", "unchecked" })
public static String execute(byte[] classByte){
HackSystem.clearBuffer();
ClassModifier cm=new ClassModifier(classByte);
byte[] modiBytes=cm.modifyUTF8Constant("java/lang/System", "test/HackSystem");
HotSwapClassLoader loader=new HotSwapClassLoader();
Class clazz=loader.loadByte(modiBytes);
try{
Method method=clazz.getMethod("main", new Class[]{String[].class});
method.invoke(null, new String[]{null});
}catch(Throwable e){
e.printStackTrace(HackSystem.out);
}
return HackSystem.getBufferString();
}
}
6、Jsp页面
<%
InputStream is=new FileInputStream("");
byte[] b=new byte[is.available()];
is.read(b);
is.close();
out.println("<textarea style='width:1000;height=800'>");
out.println(JavaClassExecuter.execute(b));
out.println("</textarea>");
%>