use of net.runelite.asm.attributes.code.Instruction in project runelite by runelite.
the class MenuActionDeobfuscator method insert.
private void insert(Method method, List<Comparison> comparisons) {
Instructions instructions = method.getCode().getInstructions();
List<Instruction> ins = instructions.getInstructions();
// replace all if(var == constant) with a jump to the false branch
// then, insert before the first jump the ifs to jump to the old
// true branch
//
// this is probably actually lookupswitch but it isn't mappable
// currently...
int min = -1;
for (Comparison comp : comparisons) {
if (min == -1) {
min = ins.indexOf(comp.lvt);
} else {
min = Math.min(min, ins.indexOf(comp.lvt));
}
if (comp.cmp.getType() == InstructionType.IF_ICMPEQ) {
If cmp = (If) comp.cmp;
// remove
instructions.remove(comp.ldc);
instructions.remove((Instruction) comp.lvt);
instructions.remove(comp.cmp);
comp.next = cmp.getJumps().get(0);
} else if (comp.cmp.getType() == InstructionType.IF_ICMPNE) {
// replace with goto dest
If cmp = (If) comp.cmp;
int idx = ins.indexOf(cmp);
assert idx != -1;
comp.next = instructions.createLabelFor(ins.get(idx + 1));
instructions.remove(comp.ldc);
instructions.remove((Instruction) comp.lvt);
instructions.replace(comp.cmp, new Goto(instructions, cmp.getJumps().get(0)));
} else {
throw new IllegalStateException();
}
}
assert min != -1;
// sort comparisons - but if they jump to the same address, they are equal..
List<Comparison> sortedComparisons = new ArrayList<>(comparisons);
Collections.sort(sortedComparisons, (c1, c2) -> compare(comparisons, c1, c2));
// reinsert jumps
for (int i = 0; i < sortedComparisons.size(); ++i) {
Comparison comp = sortedComparisons.get(i);
Instruction lvt = (Instruction) comp.lvt;
lvt.setInstructions(instructions);
comp.ldc.setInstructions(instructions);
instructions.addInstruction(min++, lvt);
instructions.addInstruction(min++, comp.ldc);
// use if_icmpeq if what follows also jumps to the same location
boolean multiple = i + 1 < sortedComparisons.size() && sortedComparisons.get(i + 1).next == comp.next;
if (multiple) {
instructions.addInstruction(min++, new IfICmpEq(instructions, comp.next));
} else {
// fernflower decompiles a series of if_icmpeq as chains of not equal expressions
Label label = instructions.createLabelFor(ins.get(min));
instructions.addInstruction(min++, new IfICmpNe(instructions, label));
instructions.addInstruction(min++, new Goto(instructions, comp.next));
// go past label
++min;
}
}
}
use of net.runelite.asm.attributes.code.Instruction in project runelite by runelite.
the class PacketHandler method findReorderableReads.
public void findReorderableReads() {
for (PacketRead pr : reads) {
// InstructionContext invokeCtx = pr.getInvokeCtx();
List<Instruction> instructions = pr.getInvoke().getInstructions().getInstructions();
// look for an lvt store immediately after
int invokeIdx = instructions.indexOf(pr.getInvoke());
assert invokeIdx != -1;
Instruction next = instructions.get(invokeIdx + 1);
if (next instanceof LVTInstruction) {
LVTInstruction lvt = (LVTInstruction) next;
if (lvt.store()) {
logger.info("Found lvt store {} for {}", next, pr.getInvoke());
pr.setStore(next);
}
}
}
}
use of net.runelite.asm.attributes.code.Instruction in project runelite by runelite.
the class PacketHandler method getAfterRead.
public Instruction getAfterRead() {
if (reads.isEmpty()) {
return null;
}
PacketRead last = reads.get(reads.size() - 1);
if (last.getStore() == null) {
return null;
}
List<Instruction> ins = method.getCode().getInstructions().getInstructions();
int idx = ins.indexOf(last.getStore());
if (idx == -1) {
// can be a read in not this function
return null;
}
return ins.get(idx + 1);
}
use of net.runelite.asm.attributes.code.Instruction in project runelite by runelite.
the class HandlerFinder method removeDuplicates.
private void removeDuplicates(PacketHandlers handlers) {
// remove handlers which have multiple opcodes
Multimap<Instruction, PacketHandler> i2h = HashMultimap.create();
for (PacketHandler handler : handlers.getHandlers()) {
i2h.put(handler.getStart(), handler);
}
for (Instruction i : i2h.keySet()) {
int sz = i2h.get(i).size();
if (sz == 1) {
continue;
}
// this is part of if (opcode == 1 || opcode == 2 || ...) func();
for (PacketHandler ph : i2h.get(i)) {
handlers.getHandlers().remove(ph);
logger.debug("Removed duplicate handler {}", ph);
}
}
}
use of net.runelite.asm.attributes.code.Instruction in project runelite by runelite.
the class CastNullTest method testRun.
@Test
public void testRun() {
ClassGroup group = ClassGroupFactory.generateGroup();
Code code = group.findClass("test").findMethod("func").getCode();
Instructions ins = code.getInstructions();
code.setMaxStack(3);
CheckCast checkCast = new CheckCast(ins);
checkCast.setType(new Type("test"));
Instruction[] instructions = { new LDC(ins, 2), new AConstNull(ins), checkCast, new LDC(ins, 2), new IAdd(ins), new Return(ins, InstructionType.IRETURN) };
for (Instruction i : instructions) {
ins.addInstruction(i);
}
Assert.assertEquals(6, ins.getInstructions().size());
CastNull lvt = new CastNull();
lvt.run(group);
Assert.assertEquals(5, ins.getInstructions().size());
Optional<Instruction> o = ins.getInstructions().stream().filter(i -> i instanceof CheckCast).findAny();
Assert.assertFalse(o.isPresent());
}
Aggregations