Skip to content

A powerful memory management library. Perform illegal, unsafe and incredibly dangerous operations on your JVM's native memory with no restrictions.

Notifications You must be signed in to change notification settings

Moderocky/Overlord

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

11 Commits
 
 
 
 
 
 
 
 

Repository files navigation

Overlord

Opus #1

A powerful memory management library.

Perform illegal, unsafe and incredibly dangerous operations on your JVM's native memory with no restrictions.

You can also pretend this is C, and manage memory directly! :)

Features:

  • Create objects without using their constructor.
  • Edit objects in heap memory.
  • Assign and manage memory outside of the heap.
  • Store objects and data outside of the heap.
  • Edit intrinsic parts of an object, such as headers, klass pointers, mark words, etc.
  • Transform objects to an incompatible type at runtime.
  • Cast objects to incompatible types.
  • Create shallow and deep perfect clones of objects.
  • Construct objects using the constructor from a completely unrelated class.
  • Trace where methods are called.
  • Use real objects to provide the implementation for native methods.
  • Load classes at runtime, both hidden and explicitly.
  • Create pointers to objects in memory.
  • Rewrite the behaviour of a method at runtime for reflective access.
  • Break encapsulation and open jdk.internal classes for access.
  • Silence those pesky "illegal reflection" warnings.

Maven Information

<repository>
    <id>pan-repo</id>
    <name>Pandaemonium Repository</name>
    <url>https://gitlab.com/api/v4/projects/18568066/packages/maven</url>
</repository>
<dependency>
    <groupId>mx.kenzie</groupId>
    <artifactId>overlord</artifactId>
    <version>1.0.1</version>
    <scope>compile</scope>
</dependency>

Examples

Shallow-clone an object (creates a NEW instance, but any non-primitive field will be a reference to the original.)

final MyObject original = new MyObject();
final MyObject clone = Overlord.shallowClone(source);

assert original.objectField == clone.objectField;

Deep-clone an object (creates a NEW instance, any non-primitive non-constant field will be recursively deep-cloned from the original.)

final MyObject original = new MyObject();
final MyObject clone = Overlord.deepClone(source);

assert original.objectField != clone.objectField;

With the following class structure:

static class NativeImplClass {
    public native String getWord();
    public native void setWord(String word);
    public native int getNumber();
    public native void setNumber(int number);
}

static class RealClass {
    int number = 10;
    String word = "hello";

    protected String getWord() { return word; }
    protected void setWord(String word) { this.word = word; }
    protected int getNumber() { return number; }
    protected void setNumber(int number) { this.number = number; }
}

You can use NativeImplClass as a blind implementation in the following:

final RealClass original = new RealClass();
final NativeImplClass cast = Overlord.transform(original, NativeImplClass.class); // Transforms 'original' to an instance of NativeImplClass
// the 'cast' variable is strongly-typed and so valid hereafter
Overlord.transform(original, RealClass.class); // Transforms 'original' back to its true class
// Now any methods called will be executed on RealClass

cast.setNumber(10); // The compiler will execute this public method from NativeImplClass
                    // The JVM will *actually* execute the protected getNumber method from RealClass

Swapping a constructor:

static class Class2 {
    public final int number;
    public final String name;

    public Class2(String string) {
        number = 10;
        name = string;
    }

}

static class Class1 {
    public final int number;
    public final String name;

    public Class1(String string) {
        number = 5;
        name = string + " <- thing";
    }

}

Any fields set in the copy constructor will either target the object's fields or be ignored silently.

final Class1 class1 = Overlord.createSwapConstructor(Class1.class, Class2.class, "hello");

assert class1.number == 10;
assert class1.name.equalsIgnoreCase("hello");

Creating an empty object:

final Class1 obj = Overlord.createEmpty(Class1.class);

Replacing method behaviour for reflection access:

{
    Method method = Blob.class.getMethod("myMethod");
    Overlord.setReflectiveBehaviour(method, (obj, args) -> "please don't use reflection on me!");
}


Method method = Blob.class.getMethod("myMethod");

// method.invoke(new Blob()) == "please don't use reflection on me!"
// new Blob().myMethod() == whatever the original was

assert !method.invoke(new Blob()).equals(new Blob().myMethod());

See RewriteBehaviourTest.class for more examples.

About

A powerful memory management library. Perform illegal, unsafe and incredibly dangerous operations on your JVM's native memory with no restrictions.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages