class oopDesc {
volatile markWord _mark;
union _metadata {
Klass* _klass; // 正常指针
narrowKlass _compressed_klass; // 压缩指针
} _metadata;
};
oopDesc是每一个java对象头部都有的结构,_metadata这个联合体保存的就是java对象的类型,所以通过更改_metadata可以控制java对象的行为。
oopDesc is part of the metadata of a Java object. Field _klass (or _compressed_klass depending on the environment) stores the type of the object. Change it can spoof the JVM of the object's type. For example
Unsafe unsafe = getUnsafe(); Object o = new Object(); unsafe.putInt(o,8L,unsafe.getInt(new ArrayList<>(),8L)); System.out.println(o.getClass());
should print "class java.util.ArrayList".
**Sorry but I can't figure out how to nextline inside <code> block in this wiki
Unfortunately, changing an object's klass metadata is an undefined behaviour which will corrupt the gc state that it can easily crash JVM. I personally don't recommend anyone to use it.