java远程执行调试类

package com.dfb.dong.loader;
/**
 * 為了多次載入執行類而加入的加载器
 * 把defineClass方法开放出来,只有外部显式调用的时候才会使用到loadByte方法
 * 由虚拟机调用时,仍然按照原有的双亲委派规则使用loadClass方法进行类加载
 * @author zhoudong
 *
 */
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);
	}
}


package com.dfb.dong.modifier;

import com.dfb.dong.util.ByteUtils;

/**
 * 修改Class文件,暂时只提供修改常量池常量的功能
 * @author zhoudong
 *
 */
public class ClassModifier {

	/**
	 * Class文件中常量池的起始偏移
	 */
	private static final int CONSTANT_POOL_COUNT_INDEX = 8;
	/**
	 * CONSTANT_Uff8_info常量的tag标志
	 */
	private static final int CONSTANT_Utf8_info = 1;
	/**
	 * 常量池中11中常量所占的长度,CONSTATN_UTF8_INFO型常量除外,因为它不是定长的
	 */
	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_Uft8_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);//常量池数量值占两个字节,从class文件的第八位到第十位为常量池数量位置
	}
}

package com.dfb.dong.system;

import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.PrintStream;

/**
 * 为JavaClass劫持java.lang.System提供支持
 * 除了out和err外,其余的都直接转发给System处理
 * @author zhoudong
 *
 */
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 currentTimeMillis()
	{
		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);
	}
	/**
	 * 下面所有的方法都与java.lang.System的名称一样
	 * 实现都是字节转调System的对应方法
	 */
}

package com.dfb.dong.util;
/**
 * Bytes 数组处理工具
 * @author zhoudong
 *
 */
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;
	}
}

package com.dfb.dong.executer;

import java.lang.reflect.Method;

import com.dfb.dong.loader.HotSwapClassLoader;
import com.dfb.dong.modifier.ClassModifier;
import com.dfb.dong.system.HackSystem;

/**
 * JavaClass执行工具
 * @author zhoudong
 *
 */
public class JavaClassExecuter {

	/**
	 * 执行外部传过来的代表一个Java类的byte数组
	 * 将输入类的byte数组中代表java.lang.System的CONSTANT_Uft8_info常量修改为劫持后的HackSystem类
	 * 执行方法为该类的static main(String [] atgs)方法,输出结果为该类向System.out/err输出的信息
	 * 
	 * @param classByte 代表一个java类的byte数组
	 * @return 执行结果
	 */
	public static String excute(byte [] classByte)
	{
		HackSystem.clearBuffer();
		ClassModifier cm = new ClassModifier(classByte);
		byte[] modiBytes = cm.modifyUTF8Constant("java/lang/System", "com/dfb/dong/system/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();
	}
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值