Last active
May 2, 2018 02:48
-
-
Save hypersoft/47569b31a2b764641dafb2d5cb643092 to your computer and use it in GitHub Desktop.
Virtual: MicroMachine
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.hypersoft.systems.usa.bleeding.edge; | |
import java.io.ByteArrayInputStream; | |
import java.io.ByteArrayOutputStream; | |
import java.io.IOException; | |
import java.io.ObjectInputStream; | |
import java.io.ObjectOutputStream; | |
import java.io.Serializable; | |
import java.util.Map; | |
import java.util.concurrent.ConcurrentHashMap; | |
/** | |
* Created by Triston-Jerard: Taylor ([email protected]) on 5/1/18. | |
*/ | |
/** | |
* Micro-Machine: eXecutor (mmx) | |
* | |
* Features: thread-synchronized-memory-unit, sub-procedures, modules and functions with | |
* machine-unit-exception-trap; and machine-serialization in a wide-open-can-o-runtime-whoop-ass. | |
* | |
* Perks: not tested, free-to-use-license with author's-attribution and copy-rights-notice. | |
* Bonuses: object-(serializer and builder); written in a quick-and-dirty-sit-down-session; | |
* no warranty, only 3 machine exceptions to master. | |
* | |
* Purposes: anti-reverse-engineering-agent, code-obfuscation-agent, networked-executable-code-push, | |
* linear-test-suite-director (much needed by "J-Unit"), etc... | |
* | |
* For best security: compile this class, stash the .class (file) bytecode somewhere and load it up with a | |
* Classloader. Optional, but very useful to keep eyes out of this sensitive (panties-down) area. | |
* | |
* Simple usage: Create a new instance or class extending Micro-Machine. Add runnables (modules), | |
* Subs (sub-procedures) and Functions to the MicroMachine, then invoke sub or call with your target | |
* names. Each target can run functions and routines within the machine, or other machines they | |
* may have access to. MicroMachine is also a runnable, which means it can be added to other machines, | |
* but can only run as a module during the code-adding-phase. To use the machine as a runnable, | |
* you must override the boot method and provide your startup-code. | |
* | |
* Author: Triston-Jerard: Taylor ([email protected]) | |
* | |
*/ | |
public abstract class MicroMachine implements Serializable, Runnable { | |
private static final long serialVersionUID = 7740289738932459369L; // change this if you change MicroMachine from within this file | |
public Map<Object, Object> memory = new ConcurrentHashMap<>(); // shared-memory: Unit.mmx.memory | |
public Map<String, Unit> umap = new ConcurrentHashMap(); // name-service-map | |
/** | |
* Fill this in with your implementation. | |
*/ | |
public abstract void onException(Exception e); | |
/** | |
* Fill this in with your implementation. | |
*/ | |
public abstract void boot(); | |
@Override public void run() {try { boot(); } catch (Exception e) {onException(e);}} // don't bother with this | |
public static abstract class Unit implements Runnable { | |
public MicroMachine mmx; final public String name; | |
abstract public void run(); | |
public Unit(String name) { this.name = name; } | |
@Override public String toString() {return name;} | |
} | |
public static abstract class Sub extends Unit { public Sub(String name) {super(name);}} | |
public static abstract class Function extends Unit { | |
final public void run(){} | |
public Function(String name) {super(name);} | |
abstract <ANY> ANY invoke(Object... parameters); | |
} | |
public void addAll(Runnable... unit) {for(Runnable r:unit) add(r);} | |
public void add(Runnable unit) { if (unit instanceof Unit) { | |
Unit u = (Unit) unit; | |
if (umap.containsKey(u.name)) throw new RuntimeException("Adding unit: "+unit+"; aborted: name-space-clashes"); | |
u.mmx = this; umap.put(u.name, u); return; | |
} else try {unit.run();} catch (Exception e) {onException(e);} // run-runnable: instantly as support module | |
} | |
public <ANY> ANY call(String name, Object... parameters) { Object o = umap.get(name); | |
if (!(o instanceof Function)) throw new IllegalArgumentException("Invoke unit: "+name+"; aborted: non-invokable-reference"); | |
try { return ((Function)o).invoke(parameters);} catch (Exception e) {onException(e);} return null; | |
} | |
public void sub(String name) { Object o = umap.get(name); | |
if (!(o instanceof Sub)) throw new IllegalArgumentException("Go to subroutine-unit: "+name+"; aborted: non-subroutine-reference"); | |
try {((Sub)o).run();} catch (Exception e) {onException(e);}; return; | |
} | |
public static byte[] serialize(Serializable object) throws IOException { | |
ByteArrayOutputStream bAOS = new ByteArrayOutputStream(); | |
ObjectOutputStream oos = new ObjectOutputStream(bAOS); oos.writeObject(object); oos.close(); | |
return bAOS.toByteArray(); | |
} | |
public static <ANY> ANY build(byte[] data) throws IOException, ClassNotFoundException { | |
ByteArrayInputStream bAIS = new ByteArrayInputStream(data); | |
ObjectInputStream ois = new ObjectInputStream(bAIS); | |
Object object = null; try {object = ois.readObject();} catch (ClassNotFoundException e){ois.close(); throw e;} | |
ois.close(); return (ANY) object; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment