use of net.runelite.asm.Method in project runelite by runelite.
the class IsaacCipherFinder method find.
public void find() {
Method highest = null;
int count = 0;
for (ClassFile cf : group.getClasses()) {
for (Method m : cf.getMethods()) {
Code code = m.getCode();
int i = find(m, code);
if (i > count) {
count = i;
highest = m;
}
}
}
assert highest != null;
isaacCipher = highest.getClassFile();
// find nextInt
for (Method method : isaacCipher.getMethods()) {
if (method.getDescriptor().size() == 0 && method.getDescriptor().getReturnValue().equals(Type.INT)) {
getNext = method;
}
}
logger.debug("Found cipher {}, getNext {}", isaacCipher, getNext);
}
use of net.runelite.asm.Method in project runelite by runelite.
the class EnumDeobfuscator method makeEnum.
private void makeEnum(ClassFile cf) {
// make class an enum
cf.setEnum();
// enums super class is java/lang/Enum
assert cf.getParentClass().getName().equals("java/lang/Object");
cf.setSuperName("java/lang/Enum");
// all static fields of the type of the class become enum members
for (Field field : cf.getFields()) {
if (field.isStatic() && field.getType().equals(new Type("L" + cf.getName() + ";"))) {
field.setEnum();
}
}
for (Method method : cf.getMethods()) {
if (!method.getName().equals("<init>")) {
continue;
}
// Add string as first argument, which is the field name,
// and ordinal as second argument
Signature signature = new Signature.Builder().setReturnType(method.getDescriptor().getReturnValue()).addArgument(Type.STRING).addArgument(Type.INT).addArguments(method.getDescriptor().getArguments()).build();
method.setDescriptor(signature);
// Remove instructions up to invokespecial
Instructions ins = method.getCode().getInstructions();
Instruction i;
do {
i = ins.getInstructions().get(0);
ins.remove(i);
} while (i.getType() != InstructionType.INVOKESPECIAL);
// load this
ins.addInstruction(0, new ALoad(ins, 0));
// load constant name
ins.addInstruction(1, new ALoad(ins, 1));
// ordinal
ins.addInstruction(2, new ILoad(ins, 2));
// invoke enum constructor
ins.addInstruction(3, new InvokeSpecial(ins, ENUM_INIT));
// Shift all indexes after this up +2 because of the new String and int argument
for (int j = 4; j < ins.getInstructions().size(); ++j) {
i = ins.getInstructions().get(j);
if (i instanceof LVTInstruction) {
LVTInstruction lvt = ((LVTInstruction) i);
int idx = lvt.getVariableIndex();
if (idx != 0) {
lvt.setVariableIndex(idx + 2);
}
}
}
}
// Order of fields being set in clinit, which is the order
// the enum fields are actually in
List<Field> order = new ArrayList<>();
for (Method method : cf.getMethods()) {
if (!method.getName().equals("<clinit>")) {
continue;
}
Instructions ins = method.getCode().getInstructions();
int count = 0;
// sometimes there is new new invokespecial invokespecial putfield
// for eg enum member field30(1, 2, String.class, new class5());
boolean seenDup = false;
for (int j = 0; j < ins.getInstructions().size(); ++j) {
Instruction i = ins.getInstructions().get(j);
if (i.getType() == InstructionType.DUP && !seenDup) {
// XXX this should actually be the field name, but it seems to have no effect on fernflower
ins.addInstruction(j + 1, new LDC(ins, "runelite"));
ins.addInstruction(j + 2, new LDC(ins, count++));
seenDup = true;
} else if (i.getType() == InstructionType.INVOKESPECIAL) {
Instruction next = ins.getInstructions().get(j + 1);
// check if this is the invokespecial on the enum, putstatic comes next
if (next.getType() == InstructionType.PUTSTATIC) {
InvokeSpecial is = (InvokeSpecial) i;
PutStatic ps = (PutStatic) next;
net.runelite.asm.pool.Method pmethod = new net.runelite.asm.pool.Method(is.getMethod().getClazz(), is.getMethod().getName(), new Signature.Builder().setReturnType(is.getMethod().getType().getReturnValue()).addArgument(Type.STRING).addArgument(Type.INT).addArguments(is.getMethod().getType().getArguments()).build());
is.setMethod(pmethod);
Field field = ps.getMyField();
assert field != null;
order.add(field);
seenDup = false;
}
}
}
}
// Enum fields must be first. Also they are in order in clinit.
// Sort fields
Collections.sort(cf.getFields(), (f1, f2) -> {
int idx1 = order.indexOf(f1);
int idx2 = order.indexOf(f2);
if (idx1 == -1) {
idx1 = Integer.MAX_VALUE;
}
if (idx2 == -1) {
idx2 = Integer.MAX_VALUE;
}
return Integer.compare(idx1, idx2);
});
}
use of net.runelite.asm.Method in project runelite by runelite.
the class Execution method getInitialMethods.
public List<Method> getInitialMethods() {
List<Method> methods = new ArrayList<>();
// required when looking up methods
group.buildClassGraph();
// lookup methods
group.lookup();
for (ClassFile cf : group.getClasses()) {
boolean extendsApplet = extendsApplet(cf);
for (Method m : cf.getMethods()) {
if (!Deob.isObfuscated(m.getName()) && !m.getName().equals("<init>")) {
if (m.getCode() == null) {
methods.add(m);
continue;
}
// I guess this method name is overriding a jre interface (init, run, ?).
methods.add(m);
logger.debug("Adding initial method {}", m);
}
if (m.getName().equals("<init>") && extendsApplet) {
methods.add(m);
}
}
}
return methods;
}
use of net.runelite.asm.Method in project runelite by runelite.
the class Stack method push.
public void push(StackContext i) {
if (size == stack.length) {
Method m = i.getPushed().getInstruction().getInstructions().getCode().getMethod();
System.err.println("stack overflow in " + m.getClassFile().getName() + " method " + m.getName());
for (int c = 0; c < stack.length; ++c) printStack(stack[c], 0);
throw new RuntimeException("Stack overflow");
}
assert !i.getType().equals(Type.VOID);
stack[size] = i;
++size;
}
use of net.runelite.asm.Method in project runelite by runelite.
the class VirtualMethods method findMethodUp.
private static void findMethodUp(List<Method> methods, Set<ClassFile> visited, ClassFile cf, String name, Signature type) {
if (cf == null || visited.contains(cf))
return;
// can do diamond inheritance with interfaces
visited.add(cf);
Method m = cf.findMethod(name, type);
if (m != null && !m.isStatic())
methods.add(m);
for (ClassFile child : cf.getChildren()) findMethodUp(methods, visited, child, name, type);
}
Aggregations