Created
February 10, 2017 22:21
-
-
Save DenWav/e36396ba78ef6063848761913b65079e to your computer and use it in GitHub Desktop.
This file contains hidden or 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.demonwav.stupid; | |
import java.lang.reflect.Field; | |
import java.lang.reflect.Method; | |
import java.lang.reflect.Modifier; | |
public class Main { | |
public static final Object object = new Object() { | |
private final Object one = "one"; | |
private final Object two = "two"; | |
private final Object three = "three"; | |
private final Object four = "four"; | |
private final Object five = "five"; | |
private final Object six = "six"; | |
private final Object seven = "seven"; | |
private final Object eight = "eight"; | |
private final Object nine = "nine"; | |
private final Object ten = "ten"; | |
private void printFields() throws Throwable { | |
forMethod( | |
getField(Class.forName("java.lang.System"), "out"), | |
"println", Class.forName("java.lang.String") | |
).call( | |
one + ", " + | |
two + ", " + | |
three + ", " + | |
four + ", " + | |
five + ", " + | |
six + ", " + | |
seven + ", " + | |
eight + ", " + | |
nine + ", " + | |
ten | |
); | |
} | |
}; | |
public static void main(String[] args) throws Throwable { | |
final Class<?> scannerClass = Class.forName("java.util.Scanner"); | |
final Class<?> classArray = Class.forName("java.lang.reflect.Array"); | |
final Object classArrayObject = forMethod( | |
classArray, | |
"newInstance", | |
Class.forName("java.lang.Class"), | |
int.class | |
).call(Class.forName("java.lang.Class"), 1); | |
final Object classArrayClass = forMethod(classArrayObject, "getClass").call(); | |
forMethod( | |
Class.forName("java.lang.reflect.Array"), | |
"set", | |
Class.forName("java.lang.Object"), | |
int.class, | |
Class.forName("java.lang.Object") | |
).call(classArrayObject, 0, Class.forName("java.io.InputStream")); | |
final Object constructor = forMethod((Object) scannerClass, "getConstructor", (Class<?>) classArrayClass).call(classArrayObject); | |
final Class<?> array = Class.forName("java.lang.reflect.Array"); | |
final Object arrayObject = forMethod( | |
array, | |
"newInstance", | |
Class.forName("java.lang.Class"), | |
int.class | |
).call(Class.forName("java.lang.Object"), 1); | |
final Object arrayClass = forMethod(arrayObject, "getClass").call(); | |
forMethod( | |
Class.forName("java.lang.reflect.Array"), | |
"set", | |
Class.forName("java.lang.Object"), | |
int.class, | |
Class.forName("java.lang.Object") | |
).call(arrayObject, 0, getField(Class.forName("java.lang.System"), "in")); | |
forMethod(constructor, "newInstance", (Class<?>) arrayClass).call(arrayObject); | |
final Object scanner = forMethod(constructor, "newInstance", (Class<?>) arrayClass).call(arrayObject); | |
while (true) { | |
forMethod(getField(Class.forName("java.lang.System"), "out"), "print", Class.forName("java.lang.String")) | |
.call("(S)et field / (G)et field / (C)all method / (Q)uit: "); | |
final Object line = forMethod(scanner, "nextLine").call(); | |
forMethod(getField(Class.forName("java.lang.System"), "out"), "println").call(); | |
final Object lowerCase = forMethod(line, "toLowerCase").call(); | |
if (lowerCase.equals("q")) { | |
forMethod(forMethod(Class.forName("java.lang.Runtime"), "getRuntime").call(), "exit", int.class).call(0); | |
} else if (lowerCase.equals("s")) { | |
forMethod(getField(Class.forName("java.lang.System"), "out"), "print", Class.forName("java.lang.String")) | |
.call("<fieldName>,<value>: "); | |
final Object nextLine = forMethod(scanner, "nextLine").call(); | |
forMethod(getField(Class.forName("java.lang.System"), "out"), "println").call(); | |
final Object split = forMethod(nextLine, "split", Class.forName("java.lang.String")).call(","); | |
final Object first = forMethod( | |
Class.forName("java.lang.reflect.Array"), | |
"get", | |
Class.forName("java.lang.Object"), | |
int.class | |
).call(split, 0); | |
final Object second = forMethod( | |
Class.forName("java.lang.reflect.Array"), | |
"get", | |
Class.forName("java.lang.Object"), | |
int.class | |
).call(split, 1); | |
setField(object, (String) first, second); | |
} else if (lowerCase.equals("g")) { | |
forMethod(getField(Class.forName("java.lang.System"), "out"), "print", Class.forName("java.lang.String")) | |
.call("<fieldName>: "); | |
final Object nextLine = forMethod(scanner, "nextLine").call(); | |
forMethod(getField(Class.forName("java.lang.System"), "out"), "println").call(); | |
final Object field = getField(object, (String) nextLine); | |
forMethod(getField(Class.forName("java.lang.System"), "out"), "println", Class.forName("java.lang.String")) | |
.call(field); | |
} else if (lowerCase.equals("c")) { | |
forMethod(getField(Class.forName("java.lang.System"), "out"), "print", Class.forName("java.lang.String")) | |
.call("<methodName>: "); | |
final Object nextLine = forMethod(scanner, "nextLine").call(); | |
forMethod(getField(Class.forName("java.lang.System"), "out"), "println").call(); | |
forMethod(object, (String) nextLine).call(); | |
} | |
} | |
} | |
//**************************************************************************************** | |
// Framework | |
//**************************************************************************************** | |
public static class MethodCaller { | |
private final Class<?> aClass; | |
private final Object object; | |
private final String method; | |
private final Class<?>[] types; | |
public MethodCaller(Class<?> aClass, Object object, String method, Class<?>[] types) throws Throwable { | |
this.aClass = aClass; | |
this.object = object; | |
this.method = method; | |
this.types = types; | |
} | |
public Object call(Object... params) throws Throwable { | |
Method method; | |
try { | |
method = aClass.getDeclaredMethod(this.method, types); | |
} catch (NoSuchMethodException e) { | |
method = aClass.getMethod(this.method, types); | |
} | |
method.setAccessible(true); | |
return method.invoke(object, params); | |
} | |
} | |
public static MethodCaller forMethod(Class<?> aClass, String method, Class<?>... types) throws Throwable { | |
return new MethodCaller(aClass, null, method, types); | |
} | |
public static MethodCaller forMethod(Object object, String method, Class<?>... types) throws Throwable { | |
final Class<?> aClass = object.getClass(); | |
return new MethodCaller(aClass, object, method, types); | |
} | |
public static Object getField(Class<?> aClass, String fieldName) throws Throwable { | |
Field field; | |
try { | |
field = aClass.getDeclaredField(fieldName); | |
} catch (NoSuchFieldException e) { | |
field = aClass.getField(fieldName); | |
} | |
field.setAccessible(true); | |
return field.get(null); | |
} | |
public static Object getField(Object object, String fieldName) throws Throwable { | |
final Class<?> aClass = object.getClass(); | |
Field field; | |
try { | |
field = aClass.getDeclaredField(fieldName); | |
} catch (NoSuchFieldException e) { | |
field = aClass.getField(fieldName); | |
} | |
field.setAccessible(true); | |
return field.get(object); | |
} | |
public static Object setField(Class<?> aClass, String fieldName, Object value) throws Throwable { | |
Field field; | |
try { | |
field = aClass.getDeclaredField(fieldName); | |
} catch (NoSuchFieldException e) { | |
field = aClass.getField(fieldName); | |
} | |
field.setAccessible(true); | |
if (Modifier.isFinal(field.getModifiers())) { | |
final Field modifiers = field.getClass().getDeclaredField("modifiers"); | |
modifiers.setAccessible(true); | |
modifiers.setInt(field, field.getModifiers() & ~Modifier.FINAL); | |
} | |
final Object oldVal = getField(aClass, fieldName); | |
field.set(null, value); | |
return oldVal; | |
} | |
public static Object setField(Object object, String fieldName, Object value) throws Throwable { | |
final Class<?> aClass = object.getClass(); | |
Field field; | |
try { | |
field = aClass.getDeclaredField(fieldName); | |
} catch (NoSuchFieldException e) { | |
field = aClass.getField(fieldName); | |
} | |
field.setAccessible(true); | |
if (Modifier.isFinal(field.getModifiers())) { | |
final Field modifiers = field.getClass().getDeclaredField("modifiers"); | |
modifiers.setAccessible(true); | |
modifiers.setInt(field, field.getModifiers() & ~Modifier.FINAL); | |
} | |
final Object oldVal = getField(object, fieldName); | |
field.set(object, value); | |
return oldVal; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment