您的位置:首页 > 移动开发

Remote CMD to Java App

2015-11-26 22:16 267 查看
package org.test.remotecmd;

public class JavaClassExecuter {

public static String execute(byte[] classByte) {
HackSystem.clearBuffer();
ClassModifier cm = new ClassModifier(classByte);
byte[] modiBytes = cm.modifyUTF8Constant("java/lang/System",
"org/test/remotecmd/HackSystem");
HotSwapClassloader loader = new HotSwapClassloader();
Class<?> clazz = loader.loadByte(modiBytes);

try {
Method method = clazz.getMethod("main",
new Class[] { String.class });
method.invoke(null, (Object[]) new String[] { null });
} catch (Throwable e) {
e.printStackTrace(HackSystem.out);
}
return HackSystem.getBufferString();

}
}

public class HotSwapClassloader extends ClassLoader {

public HotSwapClassloader() {
super(HotSwapClassloader.class.getClassLoader());
}

public Class<?> loadByte(byte[] classByte) {
return defineClass(null, classByte, 0, classByte.length);
}
}

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 len) {
System.arraycopy(src, srcPos, dest, destPos, len);
}

public static int indentityHashCode(Object x) {
return System.identityHashCode(x);
}

// 下面所有的方法都与java.lang.System的名称一样,因版面原因,省略了其他方法
}

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[] origBytes, int offset, int len,
byte[] replaceBytes) {
byte[] newBytes = new byte[origBytes.length
+ (replaceBytes.length - len)];
System.arraycopy(origBytes, 0, newBytes, 0, offset);
System.arraycopy(replaceBytes, 0, newBytes, offset, replaceBytes.length);
System.arraycopy(origBytes, offset + len, newBytes, offset
+ replaceBytes.length, origBytes.length - offset - len);

return newBytes;
}
}

public class ClassModifier {

/**
* Class文件中常量池的起始偏移
*/
private static final int CONSTANT_POOL_INDEX = 8;

/**
* CONSTANT_Utf8_info常量的tag标志
*/
private static final int CONSTANT_Utf8_info = 1;

/**
* 常量池中11种常量所占的长度,CONSTANT_Utf8_info型常量除外,因为它不是定长的
*/
private static final int[] CONSTANT_ITEM_LEN = { -1, -1, 5, -1, 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;
}

public byte[] modifyUTF8Constant(String oldStr, String newStr) {
int cpc = getConstantPoolCount();
int offset = CONSTANT_POOL_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_LEN[tag];
}
}
return classByte;
}

public int getConstantPoolCount() {
return ByteUtils.bytes2Int(classByte, CONSTANT_POOL_INDEX, u2);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: