From a677e64aac21734e71895d911a0cd6d2480159f9 Mon Sep 17 00:00:00 2001 From: Adam Date: Sat, 13 Jun 2015 11:01:46 -0400 Subject: [PATCH] Remove unused parameters --- .../java/info/sigterm/deob/ConstantPool.java | 3 + src/main/java/info/sigterm/deob/Deob.java | 94 +++++++++---- src/main/java/info/sigterm/deob/Method.java | 58 +++++++- .../deob/attributes/AttributeType.java | 1 + .../sigterm/deob/attributes/Exceptions.java | 36 +++++ .../deob/attributes/code/Exception.java | 59 +++++--- .../deob/attributes/code/Exceptions.java | 16 --- .../deob/attributes/code/Instruction.java | 130 ++++++++++++++++-- .../deob/attributes/code/Instructions.java | 28 +++- .../instruction/types/InvokeInstruction.java | 6 + .../instruction/types/JumpingInstruction.java | 6 + .../instruction/types/LVTInstruction.java | 5 + .../instruction/types/WideInstruction.java | 2 +- .../attributes/code/instructions/ALoad.java | 22 ++- .../attributes/code/instructions/ALoad_0.java | 6 + .../attributes/code/instructions/ALoad_1.java | 6 + .../attributes/code/instructions/ALoad_2.java | 6 + .../attributes/code/instructions/ALoad_3.java | 8 +- .../code/instructions/ANewArray.java | 4 +- .../attributes/code/instructions/AStore.java | 22 ++- .../code/instructions/AStore_0.java | 6 + .../code/instructions/AStore_1.java | 6 + .../code/instructions/AStore_2.java | 6 + .../code/instructions/AStore_3.java | 6 + .../attributes/code/instructions/BiPush.java | 4 +- .../code/instructions/CheckCast.java | 4 +- .../attributes/code/instructions/DLoad.java | 22 ++- .../attributes/code/instructions/DLoad_0.java | 6 + .../attributes/code/instructions/DLoad_1.java | 6 + .../attributes/code/instructions/DLoad_2.java | 6 + .../attributes/code/instructions/DLoad_3.java | 6 + .../attributes/code/instructions/DStore.java | 22 ++- .../code/instructions/DStore_0.java | 6 + .../code/instructions/DStore_1.java | 6 + .../code/instructions/DStore_2.java | 6 + .../code/instructions/DStore_3.java | 6 + .../attributes/code/instructions/Dup.java | 17 +++ .../attributes/code/instructions/Dup2.java | 6 + .../attributes/code/instructions/Dup2_X1.java | 6 + .../attributes/code/instructions/Dup2_X2.java | 6 + .../attributes/code/instructions/Dup_X1.java | 6 + .../attributes/code/instructions/Dup_X2.java | 6 + .../attributes/code/instructions/FLoad.java | 22 ++- .../attributes/code/instructions/FLoad_0.java | 6 + .../attributes/code/instructions/FLoad_1.java | 6 + .../attributes/code/instructions/FLoad_2.java | 6 + .../attributes/code/instructions/FLoad_3.java | 6 + .../attributes/code/instructions/FStore.java | 22 ++- .../code/instructions/FStore_0.java | 6 + .../code/instructions/FStore_1.java | 6 + .../code/instructions/FStore_2.java | 6 + .../code/instructions/FStore_3.java | 6 + .../code/instructions/GetField.java | 4 +- .../code/instructions/GetStatic.java | 4 +- .../attributes/code/instructions/Goto.java | 26 +++- .../attributes/code/instructions/GotoW.java | 25 +++- .../attributes/code/instructions/IInc.java | 15 +- .../attributes/code/instructions/ILoad.java | 22 ++- .../attributes/code/instructions/ILoad_0.java | 6 + .../attributes/code/instructions/ILoad_1.java | 6 + .../attributes/code/instructions/ILoad_2.java | 6 + .../attributes/code/instructions/ILoad_3.java | 6 + .../attributes/code/instructions/IStore.java | 22 ++- .../code/instructions/IStore_0.java | 6 + .../code/instructions/IStore_1.java | 6 + .../code/instructions/IStore_2.java | 6 + .../code/instructions/IStore_3.java | 6 + .../deob/attributes/code/instructions/If.java | 25 +++- .../attributes/code/instructions/If0.java | 25 +++- .../code/instructions/InstanceOf.java | 4 +- .../code/instructions/InvokeInterface.java | 22 ++- .../code/instructions/InvokeSpecial.java | 22 ++- .../code/instructions/InvokeStatic.java | 22 ++- .../code/instructions/InvokeVirtual.java | 23 +++- .../attributes/code/instructions/LDC.java | 18 ++- .../attributes/code/instructions/LDC2_W.java | 4 +- .../attributes/code/instructions/LDC_W.java | 14 +- .../attributes/code/instructions/LLoad.java | 22 ++- .../attributes/code/instructions/LLoad_0.java | 6 + .../attributes/code/instructions/LLoad_1.java | 6 + .../attributes/code/instructions/LLoad_2.java | 6 + .../attributes/code/instructions/LLoad_3.java | 6 + .../attributes/code/instructions/LStore.java | 22 ++- .../code/instructions/LStore_0.java | 6 + .../code/instructions/LStore_1.java | 6 + .../code/instructions/LStore_2.java | 6 + .../code/instructions/LStore_3.java | 6 + .../code/instructions/LookupSwitch.java | 50 ++++++- .../code/instructions/MultiANewArray.java | 4 +- .../attributes/code/instructions/New.java | 4 +- .../code/instructions/NewArray.java | 4 +- .../code/instructions/PutField.java | 4 +- .../code/instructions/PutStatic.java | 4 +- .../attributes/code/instructions/SiPush.java | 4 +- .../code/instructions/TableSwitch.java | 53 +++++-- .../attributes/code/instructions/Wide.java | 35 ++++- .../sigterm/deob/execution/Execution.java | 5 +- .../info/sigterm/deob/execution/Frame.java | 11 +- .../deob/execution/InstructionContext.java | 11 ++ .../info/sigterm/deob/execution/Stack.java | 4 - .../sigterm/deob/execution/StackContext.java | 14 ++ .../info/sigterm/deob/execution/Type.java | 2 - .../sigterm/deob/pool/InterfaceMethod.java | 8 ++ .../java/info/sigterm/deob/pool/Method.java | 8 ++ .../info/sigterm/deob/pool/NameAndType.java | 8 ++ .../sigterm/deob/signature/Signature.java | 6 + 106 files changed, 1229 insertions(+), 228 deletions(-) create mode 100644 src/main/java/info/sigterm/deob/attributes/Exceptions.java create mode 100644 src/main/java/info/sigterm/deob/attributes/code/instruction/types/InvokeInstruction.java create mode 100644 src/main/java/info/sigterm/deob/attributes/code/instruction/types/JumpingInstruction.java diff --git a/src/main/java/info/sigterm/deob/ConstantPool.java b/src/main/java/info/sigterm/deob/ConstantPool.java index abc61ac1c3..d459048d86 100644 --- a/src/main/java/info/sigterm/deob/ConstantPool.java +++ b/src/main/java/info/sigterm/deob/ConstantPool.java @@ -142,7 +142,10 @@ public class ConstantPool for (PoolEntry e : entries) { if (e.equals(entry)) + { + assert e.getClass() == entry.getClass(); return i; + } i += e.getSlots(); } diff --git a/src/main/java/info/sigterm/deob/Deob.java b/src/main/java/info/sigterm/deob/Deob.java index fd46540e30..681b95ba04 100644 --- a/src/main/java/info/sigterm/deob/Deob.java +++ b/src/main/java/info/sigterm/deob/Deob.java @@ -3,9 +3,12 @@ package info.sigterm.deob; import info.sigterm.deob.execution.Execution; import info.sigterm.deob.execution.Frame; import info.sigterm.deob.pool.NameAndType; +import info.sigterm.deob.signature.Signature; import info.sigterm.deob.attributes.Code; import info.sigterm.deob.attributes.code.Block; +import info.sigterm.deob.attributes.code.Instruction; import info.sigterm.deob.attributes.code.Instructions; + import java.io.ByteArrayOutputStream; import java.io.DataInputStream; import java.io.DataOutputStream; @@ -46,9 +49,10 @@ public class Deob checkCallGraph(group); removeExceptionObfuscation(group); checkBlockGraph(group); - //checkParameters(group); - execute(group); + Execution e = execute(group); + + checkParameters(e, group); JarOutputStream jout = new JarOutputStream(new FileOutputStream(args[1]), new Manifest()); @@ -67,7 +71,7 @@ public class Deob jout.close(); } - private static void execute(ClassGroup group) throws IOException + private static Execution execute(ClassGroup group) throws IOException { Execution e = new Execution(group); @@ -84,6 +88,7 @@ public class Deob } System.out.println("Processed " + count + " methods and " + fcount + " paths"); + return e; } private static void checkCallGraph(ClassGroup group) @@ -99,7 +104,6 @@ public class Deob if (!m.isUsed()) { - System.out.println(cf.getName() + " " + m.getName()); cf.getMethods().removeMethod(m); ++i; } @@ -161,44 +165,82 @@ public class Deob System.out.println("Removed " + i + " unused blocks"); } - private static boolean parameterUsed(int num, List lv) + private static int[] checkParametersOnce(Execution execution, ClassGroup group) { - if (lv.isEmpty()) - return false; + // removing parameters shifts the others around which is annoying. + // if more than one is unused, we'll just remove the one + // and do the others on another pass - // these instructions aren't in order so we can't do this - //LVTInstruction ins = (LVTInstruction) lv.get(0); - //return !ins.store(); - return true; - } - - private static void checkParameters(ClassGroup group) - { int count = 0; + int collide = 0; + int overrides = 0; for (ClassFile cf : group.getClasses()) { - for (Method m : new ArrayList<>(cf.getMethods().getMethods())) + for (Method m : cf.getMethods().getMethods()) { - int start = m.isStatic() ? 0 : 1; + int offset = m.isStatic() ? 0 : 1; NameAndType nat = m.getNameAndType(); - int numParams = start + nat.getNumberOfArgs(); + Signature signature = nat.getDescriptor(); - for (int i = start; i < numParams; ++i) + for (int variableIndex = 0, lvtIndex = offset; + variableIndex < signature.size(); + lvtIndex += signature.getTypeOfArg(variableIndex++).getSlots()) { - List lv = m.findLVTInstructionsForVariable(i); + List lv = m.findLVTInstructionsForVariable(lvtIndex); if (lv == null) continue; + + // XXX instead of checking if the lvt index is never accessed, + // check execution frames and see if it is never read prior to being + // written to, and if so, then remove the parameter, but don't re index + // the lvt table. + if (!lv.isEmpty()) + continue; - if (!parameterUsed(i, lv)) + if (!m.getOverriddenMethods().isEmpty()) { - //m.removeParameter(i); - System.out.println("Not used param " + i + " of " + cf.getName() + " " + m.getName() + " static: " + m.isStatic()); - ++count; + ++overrides; + continue; } + + Signature newSig = new Signature(m.getDescriptor()); + newSig.remove(variableIndex); + + Method otherMethod = cf.getMethods().findMethod(new NameAndType(m.getName(), newSig)); + if (otherMethod != null) + { + // sometimes removing an unused parameter will cause a signature collision with another function, + // just ignore it atm (there seems to be very few) + ++collide; + continue; + } + + m.removeParameter(execution, variableIndex, lvtIndex); + ++count; + break; } } } - System.out.println("Detected " + count + " unused parameters"); + return new int[] { count, collide, overrides }; } -} + + private static void checkParameters(Execution execution, ClassGroup group) + { + int count = 0; + int collide = 0; + int override = 0; + int[] i; + do + { + i = checkParametersOnce(execution, group); + + count += i[0]; + collide = i[1]; // the next pass may be able to reduce the collisions + override = i[2]; + } + while (i[0] > 0); + + System.out.println("Removed " + count + " unused parameters, unable to remove " + collide + " because of signature collisions and " + override + " due to overriding"); + } +} \ No newline at end of file diff --git a/src/main/java/info/sigterm/deob/Method.java b/src/main/java/info/sigterm/deob/Method.java index f04802c622..504e956ae9 100644 --- a/src/main/java/info/sigterm/deob/Method.java +++ b/src/main/java/info/sigterm/deob/Method.java @@ -4,8 +4,12 @@ import info.sigterm.deob.attributes.AttributeType; import info.sigterm.deob.attributes.Attributes; import info.sigterm.deob.attributes.Code; import info.sigterm.deob.attributes.code.Instruction; +import info.sigterm.deob.attributes.code.instruction.types.InvokeInstruction; import info.sigterm.deob.attributes.code.instruction.types.LVTInstruction; import info.sigterm.deob.callgraph.Node; +import info.sigterm.deob.execution.Execution; +import info.sigterm.deob.execution.Frame; +import info.sigterm.deob.execution.InstructionContext; import info.sigterm.deob.pool.NameAndType; import info.sigterm.deob.signature.Signature; @@ -13,7 +17,9 @@ import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.util.ArrayList; +import java.util.HashSet; import java.util.List; +import java.util.Set; public class Method { @@ -56,15 +62,55 @@ public class Method assert callsFrom.isEmpty(); } - protected void removeParameter(int i) + protected void removeParameter(Execution execution, int paramIndex, int lvtIndex) { - // If this is a non static method parameter 0 is this - if (!this.isStatic()) - --i; + Set done = new HashSet<>(); + for (Node n : callsFrom) + { + // find everywhere that calls this + // remove parameter from stack + Method caller = n.from; + + // find frames on the caller + for (Frame f : execution.processedFrames) + if (f.getMethod() == caller) + for (InstructionContext ins : f.getInstructions()) + if (ins.getInstruction() == n.ins) // this instruction invokes the function we're removing a parameter from + { + if (done.contains(ins.getInstruction())) + continue; + + int pops = arguments.size() - paramIndex - 1; // index from top of stack of parameter + ins.removeStack(pops); // remove parameter from stack + + InvokeInstruction iins = (InvokeInstruction) ins.getInstruction(); + iins.removeParameter(paramIndex); // remove parameter from instruction + + done.add(ins.getInstruction()); + } + } - arguments.remove(i); + // adjust lvt indexes to get rid of idx in the method + for (Instruction ins : new ArrayList<>(getCode().getInstructions().getInstructions())) + { + if (ins instanceof LVTInstruction) + { + LVTInstruction lins = (LVTInstruction) ins; + + int i = lins.getVariableIndex(); + assert i != lvtIndex; // current unused variable detection just looks for no accesses + + // reassign + if (i > lvtIndex) + { + Instruction newIns = lins.setVariableIndex(--i); + if (newIns != ins) + ins.replace(newIns); + } + } + } - // XXX now remove from code. + arguments.remove(paramIndex); } public Methods getMethods() diff --git a/src/main/java/info/sigterm/deob/attributes/AttributeType.java b/src/main/java/info/sigterm/deob/attributes/AttributeType.java index bbbe0c7414..3c631396f6 100644 --- a/src/main/java/info/sigterm/deob/attributes/AttributeType.java +++ b/src/main/java/info/sigterm/deob/attributes/AttributeType.java @@ -4,6 +4,7 @@ public enum AttributeType { CONSTANT_VALUE("ConstantValue", ConstantValue.class), CODE("Code", Code.class), + EXCEPTIONS("Exceptions", Exceptions.class), UNKNOWN(null, Unknown.class); private String name; diff --git a/src/main/java/info/sigterm/deob/attributes/Exceptions.java b/src/main/java/info/sigterm/deob/attributes/Exceptions.java new file mode 100644 index 0000000000..3fefddfe3a --- /dev/null +++ b/src/main/java/info/sigterm/deob/attributes/Exceptions.java @@ -0,0 +1,36 @@ +package info.sigterm.deob.attributes; + +import info.sigterm.deob.pool.Class; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +public class Exceptions extends Attribute +{ + private List classes = new ArrayList<>(); + + public Exceptions(Attributes attributes) throws IOException + { + super(attributes, AttributeType.EXCEPTIONS); + + DataInputStream is = attributes.getStream(); + + int count = is.readUnsignedShort(); + for (int i = 0; i < count; ++i) + { + Class clazz = attributes.getClassFile().getPool().getClass(is.readUnsignedShort()); + classes.add(clazz); + } + } + + @Override + public void writeAttr(DataOutputStream out) throws IOException + { + out.writeShort(classes.size()); + for (Class c : classes) + out.writeShort(this.getAttributes().getClassFile().getPool().make(c)); + } +} diff --git a/src/main/java/info/sigterm/deob/attributes/code/Exception.java b/src/main/java/info/sigterm/deob/attributes/code/Exception.java index fc32d054d2..ee15dac05e 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/Exception.java +++ b/src/main/java/info/sigterm/deob/attributes/code/Exception.java @@ -11,9 +11,7 @@ public class Exception { private Exceptions exceptions; - private int startPc; - private int endPc; - private int handlerPc; + private Instruction start, end, handler; private Class catchType; public Exception(Exceptions exceptions) throws IOException @@ -23,28 +21,35 @@ public class Exception DataInputStream is = exceptions.getCode().getAttributes().getStream(); ConstantPool pool = exceptions.getCode().getAttributes().getClassFile().getPool(); - startPc = is.readUnsignedShort(); - endPc = is.readUnsignedShort(); - handlerPc = is.readUnsignedShort(); + int startPc = is.readUnsignedShort(); + int endPc = is.readUnsignedShort(); + int handlerPc = is.readUnsignedShort(); catchType = pool.getClass(is.readUnsignedShort()); - Instruction ins = exceptions.getCode().getInstructions().findInstruction(handlerPc); - ins.exce.add(this); + Instructions instructions = exceptions.getCode().getInstructions(); + start = instructions.findInstruction(startPc); + end = instructions.findInstruction(endPc); + handler = instructions.findInstruction(handlerPc); + + assert start != null; + assert end != null; + assert handler != null; + + handler.exce.add(this); } protected void remove() { - Instruction ins = exceptions.getCode().getInstructions().findInstruction(handlerPc); - ins.exce.remove(this); + handler.exce.remove(this); } public void write(DataOutputStream out) throws IOException { ConstantPool pool = exceptions.getCode().getAttributes().getClassFile().getPool(); - out.writeShort(startPc); - out.writeShort(endPc); - out.writeShort(handlerPc); + out.writeShort(start.getPc()); + out.writeShort(end.getPc()); + out.writeShort(handler.getPc()); out.writeShort(catchType == null ? 0 : pool.make(catchType)); } @@ -53,19 +58,35 @@ public class Exception return exceptions; } - public int getStartPc() + public Instruction getStart() { - return startPc; + return start; } - public int getEndPc() + public Instruction getEnd() { - return endPc; + return end; } - public int getHandlerPc() + public Instruction getHandler() { - return handlerPc; + return handler; + } + + public void replace(Instruction oldi, Instruction newi) + { + if (start == oldi) + start = newi; + + if (end == oldi) + end = newi; + + if (handler == oldi) + { + handler.exce.remove(this); + handler = newi; + handler.exce.add(this); + } } public Class getCatchType() diff --git a/src/main/java/info/sigterm/deob/attributes/code/Exceptions.java b/src/main/java/info/sigterm/deob/attributes/code/Exceptions.java index e3ba6bb0d1..807fde2e97 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/Exceptions.java +++ b/src/main/java/info/sigterm/deob/attributes/code/Exceptions.java @@ -47,20 +47,4 @@ public class Exceptions { return exceptions; } - - public List getHandlersForPc(int pc) - { - List matches = new ArrayList<>(); - - for (Exception e : exceptions) - { - if (pc >= e.getStartPc() && pc < e.getEndPc()) - { - /* possible match */ - matches.add(e); - } - } - - return matches; - } } \ No newline at end of file diff --git a/src/main/java/info/sigterm/deob/attributes/code/Instruction.java b/src/main/java/info/sigterm/deob/attributes/code/Instruction.java index fffe6d34c7..679bc33172 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/Instruction.java +++ b/src/main/java/info/sigterm/deob/attributes/code/Instruction.java @@ -36,11 +36,113 @@ public abstract class Instruction i.from.remove(this); jump.clear(); - assert from.isEmpty(); + Exceptions exceptions = instructions.getCode().getExceptions(); + for (Exception e : exceptions.getExceptions()) + { + assert this != e.getStart(); + assert this != e.getEnd(); + assert this != e.getHandler(); + } + + assert from.isEmpty(); // because this is empty no jumping instructions point here assert exce.isEmpty(); } - public void write(DataOutputStream out, int pc) throws IOException + public void replace(Instruction other) + { + List ins = instructions.getInstructions(); + + assert this != other; + assert ins.contains(this); + assert !ins.contains(other); + + // XXX this corrupts the block graph. we shouldn't keep it around once we are done using it, + // too much stuff to keep updated. + this.block = null; + + // XXX instructions which hold references to instructions ! + for (Instruction i : ins) + { + i.replace(this, other); + } + + // update instructions which jump here to jump to the new instruction + for (Instruction i : from) + { + assert i.jump.contains(this); + assert !i.jump.contains(other); + + i.jump.remove(this); + i.jump.add(other); + } + from.clear(); + + // move jumps over + for (Instruction i : jump) + { + assert i.from.contains(this); + assert !i.from.contains(other); + + i.from.remove(this); + i.from.add(other); + } + other.jump = new ArrayList<>(this.jump); + jump.clear(); + + Exceptions exceptions = instructions.getCode().getExceptions(); + for (Exception e : exceptions.getExceptions()) + { + e.replace(this, other); + } + assert exce.isEmpty(); + + // replace ins + int index = ins.indexOf(this); + ins.remove(this); + ins.add(index, other); + } + + public boolean removeStack() + { + block = null; + + // update instructions which jump here to jump to the next instruction + List ins = instructions.getInstructions(); + Instruction next = ins.get(ins.indexOf(this) + 1); + assert next != null; + + for (Instruction i : ins) + { + i.replace(this, next); + } + + for (Instruction i : from) + { + assert i.jump.contains(this); + + i.jump.remove(this); + + i.jump.add(next); + next.from.add(i); + } + from.clear(); + + this.getInstructions().remove(this); // calls remove() + + return true; + } + + // resolve jumps + public void resolve() + { + } + + // initialize constant pool to see if instruction u/g is required + public void prime() + { + } + + public void write(DataOutputStream out) throws IOException { out.writeByte(type.getCode()); } @@ -64,6 +166,11 @@ public abstract class Instruction { return pc; } + + public void setPc(int pc) + { + this.pc = pc; + } public int getLength() { @@ -75,18 +182,13 @@ public abstract class Instruction return type.getName() + " at pc " + frame.getPc() + " in " + frame.getMethod().getName() + " " + frame.getMethod().getDescriptor() + " class " + frame.getMethod().getCode().getAttributes().getClassFile().getName(); } - protected void addJump(int offset) + protected void addJump(Instruction to) { - Instruction other = instructions.findInstruction(pc + offset); - assert other != null; - assert other != this; + assert to != null; + assert to != this; - this.jump.add(other); - other.from.add(this); - } - - public void buildJumpGraph() - { + this.jump.add(to); + to.from.add(this); } public void buildInstructionGraph() @@ -104,4 +206,8 @@ public abstract class Instruction { return false; } + + public void replace(Instruction oldi, Instruction newi) + { + } } diff --git a/src/main/java/info/sigterm/deob/attributes/code/Instructions.java b/src/main/java/info/sigterm/deob/attributes/code/Instructions.java index ef7164a4e4..75ae825a1f 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/Instructions.java +++ b/src/main/java/info/sigterm/deob/attributes/code/Instructions.java @@ -1,6 +1,8 @@ package info.sigterm.deob.attributes.code; import info.sigterm.deob.attributes.Code; +import info.sigterm.deob.attributes.code.instruction.types.JumpingInstruction; +import info.sigterm.deob.attributes.code.instructions.LDC; import java.io.ByteArrayOutputStream; import java.io.DataInputStream; @@ -47,6 +49,9 @@ public class Instructions } assert pc == length; + + for (Instruction i : instructions) + i.resolve(); buildJumpGraph(); buildBlocks(); @@ -102,13 +107,25 @@ public class Instructions public void write(DataOutputStream out) throws IOException { - ByteArrayOutputStream b = new ByteArrayOutputStream(); - DataOutputStream o = new DataOutputStream(b); + // generate pool indexes + for (Instruction i : new ArrayList<>(instructions)) + i.prime(); + + // rebuild pc int pc = 0; for (Instruction i : instructions) { - i.write(o, pc); - pc = o.size(); + i.setPc(pc); + pc += i.getLength(); + } + + ByteArrayOutputStream b = new ByteArrayOutputStream(); + DataOutputStream o = new DataOutputStream(b); + for (Instruction i : instructions) + { + assert o.size() == i.getPc(); + i.write(o); + assert o.size() == i.getPc() + i.getLength(); } byte[] ba = b.toByteArray(); out.writeInt(ba.length); @@ -118,7 +135,8 @@ public class Instructions private void buildJumpGraph() { for (Instruction i : instructions) - i.buildJumpGraph(); + if (i instanceof JumpingInstruction) + ((JumpingInstruction) i).buildJumpGraph(); } public void buildInstructionGraph() diff --git a/src/main/java/info/sigterm/deob/attributes/code/instruction/types/InvokeInstruction.java b/src/main/java/info/sigterm/deob/attributes/code/instruction/types/InvokeInstruction.java new file mode 100644 index 0000000000..9bc46f5fa7 --- /dev/null +++ b/src/main/java/info/sigterm/deob/attributes/code/instruction/types/InvokeInstruction.java @@ -0,0 +1,6 @@ +package info.sigterm.deob.attributes.code.instruction.types; + +public interface InvokeInstruction +{ + public void removeParameter(int idx); +} diff --git a/src/main/java/info/sigterm/deob/attributes/code/instruction/types/JumpingInstruction.java b/src/main/java/info/sigterm/deob/attributes/code/instruction/types/JumpingInstruction.java new file mode 100644 index 0000000000..03bd521bcd --- /dev/null +++ b/src/main/java/info/sigterm/deob/attributes/code/instruction/types/JumpingInstruction.java @@ -0,0 +1,6 @@ +package info.sigterm.deob.attributes.code.instruction.types; + +public interface JumpingInstruction +{ + public void buildJumpGraph(); +} diff --git a/src/main/java/info/sigterm/deob/attributes/code/instruction/types/LVTInstruction.java b/src/main/java/info/sigterm/deob/attributes/code/instruction/types/LVTInstruction.java index 147f922cd9..21a2be4953 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instruction/types/LVTInstruction.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instruction/types/LVTInstruction.java @@ -1,7 +1,12 @@ package info.sigterm.deob.attributes.code.instruction.types; +import info.sigterm.deob.attributes.code.Instruction; + public interface LVTInstruction { public int getVariableIndex(); + + public Instruction setVariableIndex(int idx); + public boolean store(); } diff --git a/src/main/java/info/sigterm/deob/attributes/code/instruction/types/WideInstruction.java b/src/main/java/info/sigterm/deob/attributes/code/instruction/types/WideInstruction.java index 1cfa1daa96..441947ad39 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instruction/types/WideInstruction.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instruction/types/WideInstruction.java @@ -5,5 +5,5 @@ import java.io.IOException; public interface WideInstruction { - public void writeWide(DataOutputStream out, int pc) throws IOException; + public void writeWide(DataOutputStream out) throws IOException; } diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/ALoad.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/ALoad.java index b38809d8d7..4a43daab98 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/ALoad.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/ALoad.java @@ -19,6 +19,13 @@ import java.io.IOException; public class ALoad extends Instruction implements LVTInstruction, WideInstruction { private int index; + + public ALoad(Instructions instructions, int index) + { + super(instructions, InstructionType.ALOAD, 0); + this.index = index; + ++length; + } public ALoad(Instructions instructions, InstructionType type, int pc) throws IOException { @@ -39,9 +46,9 @@ public class ALoad extends Instruction implements LVTInstruction, WideInstructio } @Override - public void write(DataOutputStream out, int pc) throws IOException + public void write(DataOutputStream out) throws IOException { - super.write(out, pc); + super.write(out); out.writeByte(index); } @@ -74,9 +81,16 @@ public class ALoad extends Instruction implements LVTInstruction, WideInstructio } @Override - public void writeWide(DataOutputStream out, int pc) throws IOException + public void writeWide(DataOutputStream out) throws IOException { - super.write(out, pc); + super.write(out); out.writeShort(index); } + + @Override + public Instruction setVariableIndex(int idx) + { + index = idx; + return this; + } } diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/ALoad_0.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/ALoad_0.java index 07f9da9c84..be10643fb5 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/ALoad_0.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/ALoad_0.java @@ -47,4 +47,10 @@ public class ALoad_0 extends Instruction implements LVTInstruction { return false; } + + @Override + public Instruction setVariableIndex(int idx) + { + return new ALoad(this.getInstructions(), idx); + } } diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/ALoad_1.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/ALoad_1.java index c139668572..d9fadd0186 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/ALoad_1.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/ALoad_1.java @@ -47,4 +47,10 @@ public class ALoad_1 extends Instruction implements LVTInstruction { return false; } + + @Override + public Instruction setVariableIndex(int idx) + { + return new ALoad(this.getInstructions(), idx); + } } diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/ALoad_2.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/ALoad_2.java index 51e31397c7..918f4edc92 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/ALoad_2.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/ALoad_2.java @@ -41,6 +41,12 @@ public class ALoad_2 extends Instruction implements LVTInstruction { return 2; } + + @Override + public Instruction setVariableIndex(int idx) + { + return new ALoad(this.getInstructions(), idx); + } @Override public boolean store() diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/ALoad_3.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/ALoad_3.java index 7d381c6130..cac03591ef 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/ALoad_3.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/ALoad_3.java @@ -39,7 +39,13 @@ public class ALoad_3 extends Instruction implements LVTInstruction @Override public int getVariableIndex() { - return 0; + return 3; + } + + @Override + public Instruction setVariableIndex(int idx) + { + return new ALoad(this.getInstructions(), idx); } @Override diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/ANewArray.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/ANewArray.java index b710f29e3f..68073069d2 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/ANewArray.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/ANewArray.java @@ -28,9 +28,9 @@ public class ANewArray extends Instruction } @Override - public void write(DataOutputStream out, int pc) throws IOException + public void write(DataOutputStream out) throws IOException { - super.write(out, pc); + super.write(out); out.writeShort(this.getPool().make(clazz)); } diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/AStore.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/AStore.java index 99fca89183..7d519581c8 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/AStore.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/AStore.java @@ -19,6 +19,13 @@ import java.io.IOException; public class AStore extends Instruction implements LVTInstruction, WideInstruction { private int index; + + public AStore(Instructions instructions, int index) + { + super(instructions, InstructionType.ASTORE, 0); + this.index = index; + ++length; + } public AStore(Instructions instructions, InstructionType type, int pc) throws IOException { @@ -39,9 +46,9 @@ public class AStore extends Instruction implements LVTInstruction, WideInstructi } @Override - public void write(DataOutputStream out, int pc) throws IOException + public void write(DataOutputStream out) throws IOException { - super.write(out, pc); + super.write(out); out.writeByte(index); } @@ -73,9 +80,16 @@ public class AStore extends Instruction implements LVTInstruction, WideInstructi } @Override - public void writeWide(DataOutputStream out, int pc) throws IOException + public void writeWide(DataOutputStream out) throws IOException { - super.write(out, pc); + super.write(out); out.writeShort(index); } + + @Override + public Instruction setVariableIndex(int idx) + { + index = idx; + return this; + } } diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/AStore_0.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/AStore_0.java index 462a9d2900..7281600e8a 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/AStore_0.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/AStore_0.java @@ -40,6 +40,12 @@ public class AStore_0 extends Instruction implements LVTInstruction { return 0; } + + @Override + public Instruction setVariableIndex(int idx) + { + return new AStore(this.getInstructions(), idx); + } @Override public boolean store() diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/AStore_1.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/AStore_1.java index 0f6a54d2bf..415fa60152 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/AStore_1.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/AStore_1.java @@ -40,6 +40,12 @@ public class AStore_1 extends Instruction implements LVTInstruction { return 1; } + + @Override + public Instruction setVariableIndex(int idx) + { + return new AStore(this.getInstructions(), idx); + } @Override public boolean store() diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/AStore_2.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/AStore_2.java index 0ad866c3ed..76678313bc 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/AStore_2.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/AStore_2.java @@ -40,6 +40,12 @@ public class AStore_2 extends Instruction implements LVTInstruction { return 2; } + + @Override + public Instruction setVariableIndex(int idx) + { + return new AStore(this.getInstructions(), idx); + } @Override public boolean store() diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/AStore_3.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/AStore_3.java index a3d441dfc8..c03e7cdfec 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/AStore_3.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/AStore_3.java @@ -40,6 +40,12 @@ public class AStore_3 extends Instruction implements LVTInstruction { return 3; } + + @Override + public Instruction setVariableIndex(int idx) + { + return new AStore(this.getInstructions(), idx); + } @Override public boolean store() diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/BiPush.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/BiPush.java index 4129794ee7..a0c9b78dfc 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/BiPush.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/BiPush.java @@ -26,9 +26,9 @@ public class BiPush extends Instruction } @Override - public void write(DataOutputStream out, int pc) throws IOException + public void write(DataOutputStream out) throws IOException { - super.write(out, pc); + super.write(out); out.writeByte(b); } diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/CheckCast.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/CheckCast.java index da692d7d58..477a315269 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/CheckCast.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/CheckCast.java @@ -28,9 +28,9 @@ public class CheckCast extends Instruction } @Override - public void write(DataOutputStream out, int pc) throws IOException + public void write(DataOutputStream out) throws IOException { - super.write(out, pc); + super.write(out); out.writeShort(this.getPool().make(clazz)); } diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/DLoad.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/DLoad.java index 419ee80754..c99fce8262 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/DLoad.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/DLoad.java @@ -20,6 +20,13 @@ import java.io.IOException; public class DLoad extends Instruction implements LVTInstruction, WideInstruction { private int index; + + public DLoad(Instructions instructions, int index) + { + super(instructions, InstructionType.DLOAD, 0); + this.index = index; + ++length; + } public DLoad(Instructions instructions, InstructionType type, int pc) throws IOException { @@ -40,9 +47,9 @@ public class DLoad extends Instruction implements LVTInstruction, WideInstructio } @Override - public void write(DataOutputStream out, int pc) throws IOException + public void write(DataOutputStream out) throws IOException { - super.write(out, pc); + super.write(out); out.writeByte(index); } @@ -76,9 +83,16 @@ public class DLoad extends Instruction implements LVTInstruction, WideInstructio } @Override - public void writeWide(DataOutputStream out, int pc) throws IOException + public void writeWide(DataOutputStream out) throws IOException { - super.write(out, pc); + super.write(out); out.writeShort(index); } + + @Override + public Instruction setVariableIndex(int idx) + { + index = idx; + return this; + } } diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/DLoad_0.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/DLoad_0.java index 33593a0d59..e83c702871 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/DLoad_0.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/DLoad_0.java @@ -43,6 +43,12 @@ public class DLoad_0 extends Instruction implements LVTInstruction { return 0; } + + @Override + public Instruction setVariableIndex(int idx) + { + return new DLoad(this.getInstructions(), idx); + } @Override public boolean store() diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/DLoad_1.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/DLoad_1.java index 42ca7097e1..87856ed32e 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/DLoad_1.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/DLoad_1.java @@ -43,6 +43,12 @@ public class DLoad_1 extends Instruction implements LVTInstruction { return 1; } + + @Override + public Instruction setVariableIndex(int idx) + { + return new DLoad(this.getInstructions(), idx); + } @Override public boolean store() diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/DLoad_2.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/DLoad_2.java index 9efc403d08..db9ce992d6 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/DLoad_2.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/DLoad_2.java @@ -43,6 +43,12 @@ public class DLoad_2 extends Instruction implements LVTInstruction { return 2; } + + @Override + public Instruction setVariableIndex(int idx) + { + return new DLoad(this.getInstructions(), idx); + } @Override public boolean store() diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/DLoad_3.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/DLoad_3.java index 5b39f1216a..971f986997 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/DLoad_3.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/DLoad_3.java @@ -43,6 +43,12 @@ public class DLoad_3 extends Instruction implements LVTInstruction { return 3; } + + @Override + public Instruction setVariableIndex(int idx) + { + return new DLoad(this.getInstructions(), idx); + } @Override public boolean store() diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/DStore.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/DStore.java index 2df87f27e9..9396bcf85c 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/DStore.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/DStore.java @@ -19,6 +19,13 @@ import java.io.IOException; public class DStore extends Instruction implements LVTInstruction, WideInstruction { private int index; + + public DStore(Instructions instructions, int index) + { + super(instructions, InstructionType.DSTORE, 0); + this.index = index; + ++length; + } public DStore(Instructions instructions, InstructionType type, int pc) throws IOException { @@ -39,9 +46,9 @@ public class DStore extends Instruction implements LVTInstruction, WideInstructi } @Override - public void write(DataOutputStream out, int pc) throws IOException + public void write(DataOutputStream out) throws IOException { - super.write(out, pc); + super.write(out); out.writeByte(index); } @@ -73,9 +80,16 @@ public class DStore extends Instruction implements LVTInstruction, WideInstructi } @Override - public void writeWide(DataOutputStream out, int pc) throws IOException + public void writeWide(DataOutputStream out) throws IOException { - super.write(out, pc); + super.write(out); out.writeShort(index); } + + @Override + public Instruction setVariableIndex(int idx) + { + index = idx; + return this; + } } diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/DStore_0.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/DStore_0.java index cc60085a63..403f662962 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/DStore_0.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/DStore_0.java @@ -40,6 +40,12 @@ public class DStore_0 extends Instruction implements LVTInstruction { return 0; } + + @Override + public Instruction setVariableIndex(int idx) + { + return new DStore(this.getInstructions(), idx); + } @Override public boolean store() diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/DStore_1.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/DStore_1.java index 8d1df5db8d..01a1dbb7fa 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/DStore_1.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/DStore_1.java @@ -40,6 +40,12 @@ public class DStore_1 extends Instruction implements LVTInstruction { return 1; } + + @Override + public Instruction setVariableIndex(int idx) + { + return new DStore(this.getInstructions(), idx); + } @Override public boolean store() diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/DStore_2.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/DStore_2.java index 20017aa674..37f159d914 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/DStore_2.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/DStore_2.java @@ -40,6 +40,12 @@ public class DStore_2 extends Instruction implements LVTInstruction { return 2; } + + @Override + public Instruction setVariableIndex(int idx) + { + return new DStore(this.getInstructions(), idx); + } @Override public boolean store() diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/DStore_3.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/DStore_3.java index bb65131a01..9ad2155d8e 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/DStore_3.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/DStore_3.java @@ -40,6 +40,12 @@ public class DStore_3 extends Instruction implements LVTInstruction { return 3; } + + @Override + public Instruction setVariableIndex(int idx) + { + return new DStore(this.getInstructions(), idx); + } @Override public boolean store() diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/Dup.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/Dup.java index f70a5dc688..45326cbdce 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/Dup.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/Dup.java @@ -34,4 +34,21 @@ public class Dup extends Instruction frame.addInstructionContext(ins); } + + @Override + public boolean removeStack() + { + // removing something from the stack this pushed at index 'idx' + // idx = 0 is top of the stack, goes up. + // + // the stack is relative to post-execute of this instruction + + // for dup, to remove one of the things pushed by it you simply + // remove the dup instruction + super.removeStack(); + // do not continue as the other branch still uses what we left + // usually this is for new dup invokespecial and we end up with + // an unused new/invokesepcial + return false; + } } diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/Dup2.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/Dup2.java index b382735b27..5ddfcc68b8 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/Dup2.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/Dup2.java @@ -53,4 +53,10 @@ public class Dup2 extends Instruction frame.addInstructionContext(ins); } + + @Override + public boolean removeStack() + { + throw new UnsupportedOperationException(); + } } diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/Dup2_X1.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/Dup2_X1.java index b58e5146fa..efd46e9d86 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/Dup2_X1.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/Dup2_X1.java @@ -58,4 +58,10 @@ public class Dup2_X1 extends Instruction frame.addInstructionContext(ins); } + + @Override + public boolean removeStack() + { + throw new UnsupportedOperationException(); + } } diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/Dup2_X2.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/Dup2_X2.java index 993f3e4534..4a55dc775d 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/Dup2_X2.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/Dup2_X2.java @@ -69,4 +69,10 @@ public class Dup2_X2 extends Instruction frame.addInstructionContext(ins); } + + @Override + public boolean removeStack() + { + throw new UnsupportedOperationException(); + } } diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/Dup_X1.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/Dup_X1.java index 5301fa6199..1d44145264 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/Dup_X1.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/Dup_X1.java @@ -39,4 +39,10 @@ public class Dup_X1 extends Instruction frame.addInstructionContext(ins); } + + @Override + public boolean removeStack() + { + throw new UnsupportedOperationException(); + } } diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/Dup_X2.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/Dup_X2.java index daa35dde8c..dab36ff57d 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/Dup_X2.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/Dup_X2.java @@ -51,4 +51,10 @@ public class Dup_X2 extends Instruction frame.addInstructionContext(ins); } + + @Override + public boolean removeStack() + { + throw new UnsupportedOperationException(); + } } diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/FLoad.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/FLoad.java index 5161adcaa9..e253f5c939 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/FLoad.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/FLoad.java @@ -20,6 +20,13 @@ import java.io.IOException; public class FLoad extends Instruction implements LVTInstruction, WideInstruction { private int index; + + public FLoad(Instructions instructions, int index) + { + super(instructions, InstructionType.FLOAD, 0); + this.index = index; + ++length; + } public FLoad(Instructions instructions, InstructionType type, int pc) throws IOException { @@ -40,9 +47,9 @@ public class FLoad extends Instruction implements LVTInstruction, WideInstructio } @Override - public void write(DataOutputStream out, int pc) throws IOException + public void write(DataOutputStream out) throws IOException { - super.write(out, pc); + super.write(out); out.writeByte(index); } @@ -76,9 +83,16 @@ public class FLoad extends Instruction implements LVTInstruction, WideInstructio } @Override - public void writeWide(DataOutputStream out, int pc) throws IOException + public void writeWide(DataOutputStream out) throws IOException { - super.write(out, pc); + super.write(out); out.writeShort(index); } + + @Override + public Instruction setVariableIndex(int idx) + { + index = idx; + return this; + } } diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/FLoad_0.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/FLoad_0.java index c22edac57b..0f0b0d1d41 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/FLoad_0.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/FLoad_0.java @@ -43,6 +43,12 @@ public class FLoad_0 extends Instruction implements LVTInstruction { return 0; } + + @Override + public Instruction setVariableIndex(int idx) + { + return new FLoad(this.getInstructions(), idx); + } @Override public boolean store() diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/FLoad_1.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/FLoad_1.java index b0c1aa12c4..901edf8a13 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/FLoad_1.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/FLoad_1.java @@ -43,6 +43,12 @@ public class FLoad_1 extends Instruction implements LVTInstruction { return 1; } + + @Override + public Instruction setVariableIndex(int idx) + { + return new FLoad(this.getInstructions(), idx); + } @Override public boolean store() diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/FLoad_2.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/FLoad_2.java index 792b2a8a0b..db9872d7a0 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/FLoad_2.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/FLoad_2.java @@ -43,6 +43,12 @@ public class FLoad_2 extends Instruction implements LVTInstruction { return 2; } + + @Override + public Instruction setVariableIndex(int idx) + { + return new FLoad(this.getInstructions(), idx); + } @Override public boolean store() diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/FLoad_3.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/FLoad_3.java index 2707fc5cfb..b3fd6d725e 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/FLoad_3.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/FLoad_3.java @@ -43,6 +43,12 @@ public class FLoad_3 extends Instruction implements LVTInstruction { return 3; } + + @Override + public Instruction setVariableIndex(int idx) + { + return new FLoad(this.getInstructions(), idx); + } @Override public boolean store() diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/FStore.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/FStore.java index ae4b8f530e..31439fe0fb 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/FStore.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/FStore.java @@ -19,6 +19,13 @@ import java.io.IOException; public class FStore extends Instruction implements LVTInstruction, WideInstruction { private int index; + + public FStore(Instructions instructions, int index) + { + super(instructions, InstructionType.FSTORE, 0); + this.index = index; + ++length; + } public FStore(Instructions instructions, InstructionType type, int pc) throws IOException { @@ -39,9 +46,9 @@ public class FStore extends Instruction implements LVTInstruction, WideInstructi } @Override - public void write(DataOutputStream out, int pc) throws IOException + public void write(DataOutputStream out) throws IOException { - super.write(out, pc); + super.write(out); out.writeByte(index); } @@ -73,9 +80,16 @@ public class FStore extends Instruction implements LVTInstruction, WideInstructi } @Override - public void writeWide(DataOutputStream out, int pc) throws IOException + public void writeWide(DataOutputStream out) throws IOException { - super.write(out, pc); + super.write(out); out.writeShort(index); } + + @Override + public Instruction setVariableIndex(int idx) + { + index = idx; + return this; + } } diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/FStore_0.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/FStore_0.java index 1dbbe94577..94c8616da6 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/FStore_0.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/FStore_0.java @@ -40,6 +40,12 @@ public class FStore_0 extends Instruction implements LVTInstruction { return 0; } + + @Override + public Instruction setVariableIndex(int idx) + { + return new FStore(this.getInstructions(), idx); + } @Override public boolean store() diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/FStore_1.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/FStore_1.java index 8d234b2dcf..c25b24c79a 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/FStore_1.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/FStore_1.java @@ -40,6 +40,12 @@ public class FStore_1 extends Instruction implements LVTInstruction { return 1; } + + @Override + public Instruction setVariableIndex(int idx) + { + return new FStore(this.getInstructions(), idx); + } @Override public boolean store() diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/FStore_2.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/FStore_2.java index 1205a8b29c..65787860ae 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/FStore_2.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/FStore_2.java @@ -40,6 +40,12 @@ public class FStore_2 extends Instruction implements LVTInstruction { return 2; } + + @Override + public Instruction setVariableIndex(int idx) + { + return new FStore(this.getInstructions(), idx); + } @Override public boolean store() diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/FStore_3.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/FStore_3.java index 60a0a3a5a5..2dfb153440 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/FStore_3.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/FStore_3.java @@ -40,6 +40,12 @@ public class FStore_3 extends Instruction implements LVTInstruction { return 3; } + + @Override + public Instruction setVariableIndex(int idx) + { + return new FStore(this.getInstructions(), idx); + } @Override public boolean store() diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/GetField.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/GetField.java index 1c8562ed71..b98ceff926 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/GetField.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/GetField.java @@ -27,9 +27,9 @@ public class GetField extends Instruction } @Override - public void write(DataOutputStream out, int pc) throws IOException + public void write(DataOutputStream out) throws IOException { - super.write(out, pc); + super.write(out); out.writeShort(this.getPool().make(field)); } diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/GetStatic.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/GetStatic.java index 6cc3feb7a6..c67d09d0cc 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/GetStatic.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/GetStatic.java @@ -31,9 +31,9 @@ public class GetStatic extends Instruction } @Override - public void write(DataOutputStream out, int pc) throws IOException + public void write(DataOutputStream out) throws IOException { - super.write(out, pc); + super.write(out); out.writeShort(this.getPool().make(field)); } diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/Goto.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/Goto.java index 4b8e516757..969b083793 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/Goto.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/Goto.java @@ -3,14 +3,16 @@ package info.sigterm.deob.attributes.code.instructions; import info.sigterm.deob.attributes.code.Instruction; import info.sigterm.deob.attributes.code.InstructionType; import info.sigterm.deob.attributes.code.Instructions; +import info.sigterm.deob.attributes.code.instruction.types.JumpingInstruction; import info.sigterm.deob.execution.Frame; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; -public class Goto extends Instruction +public class Goto extends Instruction implements JumpingInstruction { + private Instruction to; private short offset; public Goto(Instructions instructions, InstructionType type, int pc) throws IOException @@ -23,16 +25,25 @@ public class Goto extends Instruction } @Override - public void write(DataOutputStream out, int pc) throws IOException + public void resolve() { - super.write(out, pc); + to = this.getInstructions().findInstruction(this.getPc() + offset); + } + + @Override + public void write(DataOutputStream out) throws IOException + { + super.write(out); + int offset = to.getPc() - this.getPc(); + assert offset <= Short.MAX_VALUE; + assert offset >= Short.MIN_VALUE; out.writeShort(offset); } @Override public void buildJumpGraph() { - this.addJump(offset); + this.addJump(to); } @Override @@ -46,4 +57,11 @@ public class Goto extends Instruction { return true; } + + @Override + public void replace(Instruction oldi, Instruction newi) + { + if (to == oldi) + to = newi; + } } diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/GotoW.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/GotoW.java index 32dd337b6a..25db691fa0 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/GotoW.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/GotoW.java @@ -3,14 +3,16 @@ package info.sigterm.deob.attributes.code.instructions; import info.sigterm.deob.attributes.code.Instruction; import info.sigterm.deob.attributes.code.InstructionType; import info.sigterm.deob.attributes.code.Instructions; +import info.sigterm.deob.attributes.code.instruction.types.JumpingInstruction; import info.sigterm.deob.execution.Frame; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; -public class GotoW extends Instruction +public class GotoW extends Instruction implements JumpingInstruction { + private Instruction to; private int offset; public GotoW(Instructions instructions, InstructionType type, int pc) throws IOException @@ -23,16 +25,22 @@ public class GotoW extends Instruction } @Override - public void write(DataOutputStream out, int pc) throws IOException + public void resolve() { - super.write(out, pc); - out.writeInt(offset); + to = this.getInstructions().findInstruction(this.getPc() + offset); + } + + @Override + public void write(DataOutputStream out) throws IOException + { + super.write(out); + out.writeInt(to.getPc() - this.getPc()); } @Override public void buildJumpGraph() { - this.addJump(offset); + this.addJump(to); } @Override @@ -46,4 +54,11 @@ public class GotoW extends Instruction { return true; } + + @Override + public void replace(Instruction oldi, Instruction newi) + { + if (to == oldi) + to = newi; + } } diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/IInc.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/IInc.java index 983449ced4..63ad066607 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/IInc.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/IInc.java @@ -41,9 +41,9 @@ public class IInc extends Instruction implements LVTInstruction, WideInstruction } @Override - public void write(DataOutputStream out, int pc) throws IOException + public void write(DataOutputStream out) throws IOException { - super.write(out, pc); + super.write(out); out.writeByte(index); out.writeByte(inc); } @@ -77,10 +77,17 @@ public class IInc extends Instruction implements LVTInstruction, WideInstruction } @Override - public void writeWide(DataOutputStream out, int pc) throws IOException + public void writeWide(DataOutputStream out) throws IOException { - super.write(out, pc); + super.write(out); out.writeShort(index); out.writeShort(inc); } + + @Override + public Instruction setVariableIndex(int idx) + { + index = (short) idx; + return this; + } } diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/ILoad.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/ILoad.java index 2c1c6226bc..f3bb7caeb2 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/ILoad.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/ILoad.java @@ -20,6 +20,13 @@ import java.io.IOException; public class ILoad extends Instruction implements LVTInstruction, WideInstruction { private int index; + + public ILoad(Instructions instructions, int index) + { + super(instructions, InstructionType.ILOAD, 0); + this.index = index; + ++length; + } public ILoad(Instructions instructions, InstructionType type, int pc) throws IOException { @@ -40,9 +47,9 @@ public class ILoad extends Instruction implements LVTInstruction, WideInstructio } @Override - public void write(DataOutputStream out, int pc) throws IOException + public void write(DataOutputStream out) throws IOException { - super.write(out, pc); + super.write(out); out.writeByte(index); } @@ -76,9 +83,16 @@ public class ILoad extends Instruction implements LVTInstruction, WideInstructio } @Override - public void writeWide(DataOutputStream out, int pc) throws IOException + public void writeWide(DataOutputStream out) throws IOException { - super.write(out, pc); + super.write(out); out.writeShort(index); } + + @Override + public Instruction setVariableIndex(int idx) + { + index = idx; + return this; + } } diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/ILoad_0.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/ILoad_0.java index b6c2b6f2a3..b2a7e04efd 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/ILoad_0.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/ILoad_0.java @@ -43,6 +43,12 @@ public class ILoad_0 extends Instruction implements LVTInstruction { return 0; } + + @Override + public Instruction setVariableIndex(int idx) + { + return new ILoad(this.getInstructions(), idx); + } @Override public boolean store() diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/ILoad_1.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/ILoad_1.java index 4e8559e372..4100491c9a 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/ILoad_1.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/ILoad_1.java @@ -43,6 +43,12 @@ public class ILoad_1 extends Instruction implements LVTInstruction { return 1; } + + @Override + public Instruction setVariableIndex(int idx) + { + return new ILoad(this.getInstructions(), idx); + } @Override public boolean store() diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/ILoad_2.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/ILoad_2.java index b378259eda..a693fdd71f 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/ILoad_2.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/ILoad_2.java @@ -43,6 +43,12 @@ public class ILoad_2 extends Instruction implements LVTInstruction { return 2; } + + @Override + public Instruction setVariableIndex(int idx) + { + return new ILoad(this.getInstructions(), idx); + } @Override public boolean store() diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/ILoad_3.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/ILoad_3.java index 979119d666..34c25b000b 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/ILoad_3.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/ILoad_3.java @@ -43,6 +43,12 @@ public class ILoad_3 extends Instruction implements LVTInstruction { return 3; } + + @Override + public Instruction setVariableIndex(int idx) + { + return new ILoad(this.getInstructions(), idx); + } @Override public boolean store() diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/IStore.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/IStore.java index be448835cb..505e5fea8f 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/IStore.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/IStore.java @@ -20,6 +20,13 @@ import java.io.IOException; public class IStore extends Instruction implements LVTInstruction, WideInstruction { private int index; + + public IStore(Instructions instructions, int index) + { + super(instructions, InstructionType.ISTORE, 0); + this.index = index; + ++length; + } public IStore(Instructions instructions, InstructionType type, int pc) throws IOException { @@ -40,9 +47,9 @@ public class IStore extends Instruction implements LVTInstruction, WideInstructi } @Override - public void write(DataOutputStream out, int pc) throws IOException + public void write(DataOutputStream out) throws IOException { - super.write(out, pc); + super.write(out); out.writeByte(index); } @@ -75,9 +82,16 @@ public class IStore extends Instruction implements LVTInstruction, WideInstructi } @Override - public void writeWide(DataOutputStream out, int pc) throws IOException + public void writeWide(DataOutputStream out) throws IOException { - super.write(out, pc); + super.write(out); out.writeShort(index); } + + @Override + public Instruction setVariableIndex(int idx) + { + index = idx; + return this; + } } diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/IStore_0.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/IStore_0.java index 22067b7351..776a34ded0 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/IStore_0.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/IStore_0.java @@ -42,6 +42,12 @@ public class IStore_0 extends Instruction implements LVTInstruction { return 0; } + + @Override + public Instruction setVariableIndex(int idx) + { + return new IStore(this.getInstructions(), idx); + } @Override public boolean store() diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/IStore_1.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/IStore_1.java index 16e24cf225..809e905b81 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/IStore_1.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/IStore_1.java @@ -42,6 +42,12 @@ public class IStore_1 extends Instruction implements LVTInstruction { return 1; } + + @Override + public Instruction setVariableIndex(int idx) + { + return new IStore(this.getInstructions(), idx); + } @Override public boolean store() diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/IStore_2.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/IStore_2.java index b4ddb8b434..3d9d5fa203 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/IStore_2.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/IStore_2.java @@ -42,6 +42,12 @@ public class IStore_2 extends Instruction implements LVTInstruction { return 2; } + + @Override + public Instruction setVariableIndex(int idx) + { + return new IStore(this.getInstructions(), idx); + } @Override public boolean store() diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/IStore_3.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/IStore_3.java index f8556c4a05..67e63c7df7 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/IStore_3.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/IStore_3.java @@ -42,6 +42,12 @@ public class IStore_3 extends Instruction implements LVTInstruction { return 3; } + + @Override + public Instruction setVariableIndex(int idx) + { + return new IStore(this.getInstructions(), idx); + } @Override public boolean store() diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/If.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/If.java index 21227ad1fe..3258c1fcf3 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/If.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/If.java @@ -3,6 +3,7 @@ package info.sigterm.deob.attributes.code.instructions; import info.sigterm.deob.attributes.code.Instruction; import info.sigterm.deob.attributes.code.InstructionType; import info.sigterm.deob.attributes.code.Instructions; +import info.sigterm.deob.attributes.code.instruction.types.JumpingInstruction; import info.sigterm.deob.execution.Frame; import info.sigterm.deob.execution.InstructionContext; import info.sigterm.deob.execution.Stack; @@ -12,8 +13,9 @@ import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; -public class If extends Instruction +public class If extends Instruction implements JumpingInstruction { + private Instruction to; private short offset; public If(Instructions instructions, InstructionType type, int pc) throws IOException @@ -26,16 +28,22 @@ public class If extends Instruction } @Override - public void write(DataOutputStream out, int pc) throws IOException + public void resolve() { - super.write(out, pc); - out.writeShort(offset); + to = this.getInstructions().findInstruction(this.getPc() + offset); + } + + @Override + public void write(DataOutputStream out) throws IOException + { + super.write(out); + out.writeShort(to.getPc() - this.getPc()); } @Override public void buildJumpGraph() { - this.addJump(offset); + this.addJump(to); } @Override @@ -52,4 +60,11 @@ public class If extends Instruction Frame other = frame.dup(); other.jump(offset); } + + @Override + public void replace(Instruction oldi, Instruction newi) + { + if (to == oldi) + to = newi; + } } diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/If0.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/If0.java index 5573c07229..a88ca3177b 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/If0.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/If0.java @@ -3,6 +3,7 @@ package info.sigterm.deob.attributes.code.instructions; import info.sigterm.deob.attributes.code.Instruction; import info.sigterm.deob.attributes.code.InstructionType; import info.sigterm.deob.attributes.code.Instructions; +import info.sigterm.deob.attributes.code.instruction.types.JumpingInstruction; import info.sigterm.deob.execution.Frame; import info.sigterm.deob.execution.InstructionContext; import info.sigterm.deob.execution.Stack; @@ -12,8 +13,9 @@ import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; -public class If0 extends Instruction +public class If0 extends Instruction implements JumpingInstruction { + private Instruction to; private short offset; public If0(Instructions instructions, InstructionType type, int pc) throws IOException @@ -26,16 +28,22 @@ public class If0 extends Instruction } @Override - public void write(DataOutputStream out, int pc) throws IOException + public void resolve() { - super.write(out, pc); - out.writeShort(offset); + to = this.getInstructions().findInstruction(this.getPc() + offset); + } + + @Override + public void write(DataOutputStream out) throws IOException + { + super.write(out); + out.writeShort(to.getPc() - this.getPc()); } @Override public void buildJumpGraph() { - this.addJump(offset); + this.addJump(to); } @Override @@ -51,4 +59,11 @@ public class If0 extends Instruction Frame other = frame.dup(); other.jump(offset); } + + @Override + public void replace(Instruction oldi, Instruction newi) + { + if (to == oldi) + to = newi; + } } diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/InstanceOf.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/InstanceOf.java index c2321b7c28..6628f33cf1 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/InstanceOf.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/InstanceOf.java @@ -27,9 +27,9 @@ public class InstanceOf extends Instruction } @Override - public void write(DataOutputStream out, int pc) throws IOException + public void write(DataOutputStream out) throws IOException { - super.write(out, pc); + super.write(out); out.writeShort(this.getPool().make(clazz)); } diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/InvokeInterface.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/InvokeInterface.java index e8e703e166..3607f591bd 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/InvokeInterface.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/InvokeInterface.java @@ -4,19 +4,22 @@ import info.sigterm.deob.ClassFile; import info.sigterm.deob.attributes.code.Instruction; import info.sigterm.deob.attributes.code.InstructionType; import info.sigterm.deob.attributes.code.Instructions; +import info.sigterm.deob.attributes.code.instruction.types.InvokeInstruction; import info.sigterm.deob.execution.Frame; import info.sigterm.deob.execution.InstructionContext; import info.sigterm.deob.execution.Stack; import info.sigterm.deob.execution.StackContext; import info.sigterm.deob.execution.Type; import info.sigterm.deob.pool.InterfaceMethod; +import info.sigterm.deob.pool.Method; import info.sigterm.deob.pool.NameAndType; +import info.sigterm.deob.signature.Signature; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; -public class InvokeInterface extends Instruction +public class InvokeInterface extends Instruction implements InvokeInstruction { private InterfaceMethod method; private int count; @@ -33,9 +36,9 @@ public class InvokeInterface extends Instruction } @Override - public void write(DataOutputStream out, int pc) throws IOException + public void write(DataOutputStream out) throws IOException { - super.write(out, pc); + super.write(out); out.writeShort(this.getPool().make(method)); out.writeByte(count); out.writeByte(0); @@ -83,4 +86,17 @@ public class InvokeInterface extends Instruction frame.addInstructionContext(ins); } + @Override + public void removeParameter(int idx) + { + info.sigterm.deob.pool.Class clazz = method.getClassEntry(); + NameAndType nat = method.getNameAndType(); + + // create new signature + Signature sig = new Signature(nat.getDescriptor()); + sig.remove(idx); + + // create new method pool object + method = new InterfaceMethod(method.getPool(), clazz, new NameAndType(nat.getPool(), nat.getName(), sig)); + } } diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/InvokeSpecial.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/InvokeSpecial.java index d9f7a371f8..83cefef645 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/InvokeSpecial.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/InvokeSpecial.java @@ -4,6 +4,7 @@ import info.sigterm.deob.ClassFile; import info.sigterm.deob.attributes.code.Instruction; import info.sigterm.deob.attributes.code.InstructionType; import info.sigterm.deob.attributes.code.Instructions; +import info.sigterm.deob.attributes.code.instruction.types.InvokeInstruction; import info.sigterm.deob.execution.Frame; import info.sigterm.deob.execution.InstructionContext; import info.sigterm.deob.execution.Stack; @@ -11,12 +12,13 @@ import info.sigterm.deob.execution.StackContext; import info.sigterm.deob.execution.Type; import info.sigterm.deob.pool.Method; import info.sigterm.deob.pool.NameAndType; +import info.sigterm.deob.signature.Signature; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; -public class InvokeSpecial extends Instruction +public class InvokeSpecial extends Instruction implements InvokeInstruction { private Method method; @@ -30,9 +32,9 @@ public class InvokeSpecial extends Instruction } @Override - public void write(DataOutputStream out, int pc) throws IOException + public void write(DataOutputStream out) throws IOException { - super.write(out, pc); + super.write(out); out.writeShort(this.getPool().make(method)); } @@ -84,4 +86,18 @@ public class InvokeSpecial extends Instruction { return "invokespecial " + method.getNameAndType().getDescriptor() + " on " + method.getClassEntry().getName(); } + + @Override + public void removeParameter(int idx) + { + info.sigterm.deob.pool.Class clazz = method.getClassEntry(); + NameAndType nat = method.getNameAndType(); + + // create new signature + Signature sig = new Signature(nat.getDescriptor()); + sig.remove(idx); + + // create new method pool object + method = new Method(method.getPool(), clazz, new NameAndType(nat.getPool(), nat.getName(), sig)); + } } diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/InvokeStatic.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/InvokeStatic.java index 26fad339c7..476e7a5430 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/InvokeStatic.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/InvokeStatic.java @@ -4,6 +4,7 @@ import info.sigterm.deob.ClassFile; import info.sigterm.deob.attributes.code.Instruction; import info.sigterm.deob.attributes.code.InstructionType; import info.sigterm.deob.attributes.code.Instructions; +import info.sigterm.deob.attributes.code.instruction.types.InvokeInstruction; import info.sigterm.deob.execution.Frame; import info.sigterm.deob.execution.InstructionContext; import info.sigterm.deob.execution.Stack; @@ -11,12 +12,13 @@ import info.sigterm.deob.execution.StackContext; import info.sigterm.deob.execution.Type; import info.sigterm.deob.pool.Method; import info.sigterm.deob.pool.NameAndType; +import info.sigterm.deob.signature.Signature; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; -public class InvokeStatic extends Instruction +public class InvokeStatic extends Instruction implements InvokeInstruction { private Method method; @@ -30,9 +32,9 @@ public class InvokeStatic extends Instruction } @Override - public void write(DataOutputStream out, int pc) throws IOException + public void write(DataOutputStream out) throws IOException { - super.write(out, pc); + super.write(out); out.writeShort(this.getPool().make(method)); } @@ -81,4 +83,18 @@ public class InvokeStatic extends Instruction { return "invokestatic " + method.getNameAndType().getDescriptor() + " on " + method.getClassEntry().getName() + " return value " + method.getNameAndType().getDescriptor().getReturnValue(); } + + @Override + public void removeParameter(int idx) + { + info.sigterm.deob.pool.Class clazz = method.getClassEntry(); + NameAndType nat = method.getNameAndType(); + + // create new signature + Signature sig = new Signature(nat.getDescriptor()); + sig.remove(idx); + + // create new method pool object + method = new Method(method.getPool(), clazz, new NameAndType(nat.getPool(), nat.getName(), sig)); + } } diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/InvokeVirtual.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/InvokeVirtual.java index b5a0f16e83..50395df8ac 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/InvokeVirtual.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/InvokeVirtual.java @@ -4,6 +4,7 @@ import info.sigterm.deob.ClassFile; import info.sigterm.deob.attributes.code.Instruction; import info.sigterm.deob.attributes.code.InstructionType; import info.sigterm.deob.attributes.code.Instructions; +import info.sigterm.deob.attributes.code.instruction.types.InvokeInstruction; import info.sigterm.deob.execution.Frame; import info.sigterm.deob.execution.InstructionContext; import info.sigterm.deob.execution.Stack; @@ -11,12 +12,13 @@ import info.sigterm.deob.execution.StackContext; import info.sigterm.deob.execution.Type; import info.sigterm.deob.pool.Method; import info.sigterm.deob.pool.NameAndType; +import info.sigterm.deob.signature.Signature; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; -public class InvokeVirtual extends Instruction +public class InvokeVirtual extends Instruction implements InvokeInstruction { private Method method; @@ -30,9 +32,9 @@ public class InvokeVirtual extends Instruction } @Override - public void write(DataOutputStream out, int pc) throws IOException + public void write(DataOutputStream out) throws IOException { - super.write(out, pc); + super.write(out); out.writeShort(this.getPool().make(method)); } @@ -79,5 +81,18 @@ public class InvokeVirtual extends Instruction frame.addInstructionContext(ins); } - + + @Override + public void removeParameter(int idx) + { + info.sigterm.deob.pool.Class clazz = method.getClassEntry(); + NameAndType nat = method.getNameAndType(); + + // create new signature + Signature sig = new Signature(nat.getDescriptor()); + sig.remove(idx); + + // create new method pool object + method = new Method(method.getPool(), clazz, new NameAndType(nat.getPool(), nat.getName(), sig)); + } } diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/LDC.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/LDC.java index 4a9b4a425b..f737c83175 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/LDC.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/LDC.java @@ -27,10 +27,22 @@ public class LDC extends Instruction } @Override - public void write(DataOutputStream out, int pc) throws IOException + public void prime() { - super.write(out, pc); - out.writeByte(this.getPool().make(value)); + int index = this.getPool().make(value); + if (index > 0xFF) + { + // new index might require changing this to an ldc_w + this.replace(new LDC_W(this.getInstructions(), value)); + } + } + + @Override + public void write(DataOutputStream out) throws IOException + { + super.write(out); + int index = this.getPool().make(value); + out.writeByte(index); } @Override diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/LDC2_W.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/LDC2_W.java index d13ccd2d9f..ae2507eafe 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/LDC2_W.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/LDC2_W.java @@ -27,9 +27,9 @@ public class LDC2_W extends Instruction } @Override - public void write(DataOutputStream out, int pc) throws IOException + public void write(DataOutputStream out) throws IOException { - super.write(out, pc); + super.write(out); out.writeShort(this.getPool().make(value)); } diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/LDC_W.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/LDC_W.java index 5e3cda458a..15a03c9d7d 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/LDC_W.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/LDC_W.java @@ -26,10 +26,18 @@ public class LDC_W extends Instruction length += 2; } - @Override - public void write(DataOutputStream out, int pc) throws IOException + public LDC_W(Instructions instructions, PoolEntry value) { - super.write(out, pc); + super(instructions, InstructionType.LDC_W, 0); + + this.value = value; + length += 2; + } + + @Override + public void write(DataOutputStream out) throws IOException + { + super.write(out); out.writeShort(this.getPool().make(value)); } diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/LLoad.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/LLoad.java index a995228aff..6389a45517 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/LLoad.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/LLoad.java @@ -20,6 +20,13 @@ import java.io.IOException; public class LLoad extends Instruction implements LVTInstruction, WideInstruction { private int index; + + public LLoad(Instructions instructions, int index) + { + super(instructions, InstructionType.LLOAD, 0); + this.index = index; + ++length; + } public LLoad(Instructions instructions, InstructionType type, int pc) throws IOException { @@ -40,9 +47,9 @@ public class LLoad extends Instruction implements LVTInstruction, WideInstructio } @Override - public void write(DataOutputStream out, int pc) throws IOException + public void write(DataOutputStream out) throws IOException { - super.write(out, pc); + super.write(out); out.writeByte(index); } @@ -76,9 +83,16 @@ public class LLoad extends Instruction implements LVTInstruction, WideInstructio } @Override - public void writeWide(DataOutputStream out, int pc) throws IOException + public void writeWide(DataOutputStream out) throws IOException { - super.write(out, pc); + super.write(out); out.writeShort(index); } + + @Override + public Instruction setVariableIndex(int idx) + { + index = idx; + return this; + } } diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/LLoad_0.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/LLoad_0.java index 69b0fcb4dd..7429611b5b 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/LLoad_0.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/LLoad_0.java @@ -43,6 +43,12 @@ public class LLoad_0 extends Instruction implements LVTInstruction { return 0; } + + @Override + public Instruction setVariableIndex(int idx) + { + return new LLoad(this.getInstructions(), idx); + } @Override public boolean store() diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/LLoad_1.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/LLoad_1.java index 2b69904839..69b7944e86 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/LLoad_1.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/LLoad_1.java @@ -43,6 +43,12 @@ public class LLoad_1 extends Instruction implements LVTInstruction { return 1; } + + @Override + public Instruction setVariableIndex(int idx) + { + return new LLoad(this.getInstructions(), idx); + } @Override public boolean store() diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/LLoad_2.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/LLoad_2.java index 0916dd9c65..982b9e659c 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/LLoad_2.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/LLoad_2.java @@ -43,6 +43,12 @@ public class LLoad_2 extends Instruction implements LVTInstruction { return 2; } + + @Override + public Instruction setVariableIndex(int idx) + { + return new LLoad(this.getInstructions(), idx); + } @Override public boolean store() diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/LLoad_3.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/LLoad_3.java index 329275c529..73437c2354 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/LLoad_3.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/LLoad_3.java @@ -43,6 +43,12 @@ public class LLoad_3 extends Instruction implements LVTInstruction { return 3; } + + @Override + public Instruction setVariableIndex(int idx) + { + return new LLoad(this.getInstructions(), idx); + } @Override public boolean store() diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/LStore.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/LStore.java index b27fb0d844..74976494d8 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/LStore.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/LStore.java @@ -21,6 +21,13 @@ public class LStore extends Instruction implements LVTInstruction, WideInstructi { private int index; + public LStore(Instructions instructions, int index) + { + super(instructions, InstructionType.LSTORE, 0); + this.index = index; + ++length; + } + public LStore(Instructions instructions, InstructionType type, int pc) throws IOException { super(instructions, type, pc); @@ -40,9 +47,9 @@ public class LStore extends Instruction implements LVTInstruction, WideInstructi } @Override - public void write(DataOutputStream out, int pc) throws IOException + public void write(DataOutputStream out) throws IOException { - super.write(out, pc); + super.write(out); out.writeByte(index); } @@ -75,9 +82,16 @@ public class LStore extends Instruction implements LVTInstruction, WideInstructi } @Override - public void writeWide(DataOutputStream out, int pc) throws IOException + public void writeWide(DataOutputStream out) throws IOException { - super.write(out, pc); + super.write(out); out.writeShort(index); } + + @Override + public Instruction setVariableIndex(int idx) + { + index = idx; + return this; + } } diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/LStore_0.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/LStore_0.java index ae7195a602..23ea6d0d76 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/LStore_0.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/LStore_0.java @@ -42,6 +42,12 @@ public class LStore_0 extends Instruction implements LVTInstruction { return 0; } + + @Override + public Instruction setVariableIndex(int idx) + { + return new LStore(this.getInstructions(), idx); + } @Override public boolean store() diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/LStore_1.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/LStore_1.java index b9e18c24c7..0d52b293a7 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/LStore_1.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/LStore_1.java @@ -42,6 +42,12 @@ public class LStore_1 extends Instruction implements LVTInstruction { return 1; } + + @Override + public Instruction setVariableIndex(int idx) + { + return new LStore(this.getInstructions(), idx); + } @Override public boolean store() diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/LStore_2.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/LStore_2.java index 98ea09416d..d972b203d7 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/LStore_2.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/LStore_2.java @@ -42,6 +42,12 @@ public class LStore_2 extends Instruction implements LVTInstruction { return 2; } + + @Override + public Instruction setVariableIndex(int idx) + { + return new LStore(this.getInstructions(), idx); + } @Override public boolean store() diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/LStore_3.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/LStore_3.java index 69e108a980..4b0342a0ad 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/LStore_3.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/LStore_3.java @@ -42,6 +42,12 @@ public class LStore_3 extends Instruction implements LVTInstruction { return 3; } + + @Override + public Instruction setVariableIndex(int idx) + { + return new LStore(this.getInstructions(), idx); + } @Override public boolean store() diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/LookupSwitch.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/LookupSwitch.java index 8c773cf25d..b1accd1171 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/LookupSwitch.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/LookupSwitch.java @@ -3,6 +3,7 @@ package info.sigterm.deob.attributes.code.instructions; import info.sigterm.deob.attributes.code.Instruction; import info.sigterm.deob.attributes.code.InstructionType; import info.sigterm.deob.attributes.code.Instructions; +import info.sigterm.deob.attributes.code.instruction.types.JumpingInstruction; import info.sigterm.deob.execution.Frame; import info.sigterm.deob.execution.InstructionContext; import info.sigterm.deob.execution.Stack; @@ -11,9 +12,14 @@ import info.sigterm.deob.execution.StackContext; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; +import java.util.ArrayList; +import java.util.List; -public class LookupSwitch extends Instruction +public class LookupSwitch extends Instruction implements JumpingInstruction { + private List branchi = new ArrayList<>(); + private Instruction defi; + private int def; private int count; private int[] match; @@ -45,30 +51,49 @@ public class LookupSwitch extends Instruction } @Override - public void write(DataOutputStream out, int pc) throws IOException + public void setPc(int pc) { - super.write(out, pc); + super.setPc(pc); int tableSkip = 4 - (pc + 1) % 4; if (tableSkip == 4) tableSkip = 0; + + length = 1 + tableSkip + 8 + (count * 8); + } + + @Override + public void resolve() + { + for (int i : branch) + branchi.add(this.getInstructions().findInstruction(this.getPc() + i)); + defi = this.getInstructions().findInstruction(this.getPc() + def); + } + + @Override + public void write(DataOutputStream out) throws IOException + { + super.write(out); + + int tableSkip = 4 - (this.getPc() + 1) % 4; + if (tableSkip == 4) tableSkip = 0; if (tableSkip > 0) out.write(new byte[tableSkip]); - out.writeInt(def); + out.writeInt(defi.getPc() - this.getPc()); out.writeInt(count); for (int i = 0; i < count; ++i) { out.writeInt(match[i]); - out.writeInt(branch[i]); + out.writeInt(branchi.get(i).getPc() - this.getPc()); } } @Override public void buildJumpGraph() { - for (int i : branch) + for (Instruction i : branchi) this.addJump(i); - this.addJump(def); + this.addJump(defi); } @Override @@ -96,4 +121,15 @@ public class LookupSwitch extends Instruction { return true; } + + @Override + public void replace(Instruction oldi, Instruction newi) + { + if (defi == oldi) + defi = newi; + + for (int i = 0; i < branchi.size(); ++i) + if (branchi.get(i) == oldi) + branchi.set(i, newi); + } } diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/MultiANewArray.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/MultiANewArray.java index 3f592004f6..c767d22703 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/MultiANewArray.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/MultiANewArray.java @@ -30,9 +30,9 @@ public class MultiANewArray extends Instruction } @Override - public void write(DataOutputStream out, int pc) throws IOException + public void write(DataOutputStream out) throws IOException { - super.write(out, pc); + super.write(out); out.writeShort(this.getPool().make(clazz)); out.writeByte(dimensions); } diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/New.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/New.java index 7eb0a5a34a..dcd50aa928 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/New.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/New.java @@ -28,9 +28,9 @@ public class New extends Instruction } @Override - public void write(DataOutputStream out, int pc) throws IOException + public void write(DataOutputStream out) throws IOException { - super.write(out, pc); + super.write(out); out.writeShort(this.getPool().make(clazz)); } diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/NewArray.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/NewArray.java index 1c1612a016..516a04e15e 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/NewArray.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/NewArray.java @@ -27,9 +27,9 @@ public class NewArray extends Instruction } @Override - public void write(DataOutputStream out, int pc) throws IOException + public void write(DataOutputStream out) throws IOException { - super.write(out, pc); + super.write(out); out.writeByte(type); } diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/PutField.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/PutField.java index 95ca83c6a2..1be5b06eea 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/PutField.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/PutField.java @@ -26,9 +26,9 @@ public class PutField extends Instruction } @Override - public void write(DataOutputStream out, int pc) throws IOException + public void write(DataOutputStream out) throws IOException { - super.write(out, pc); + super.write(out); out.writeShort(this.getPool().make(field)); } diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/PutStatic.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/PutStatic.java index a39d010379..1bf14b7a61 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/PutStatic.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/PutStatic.java @@ -26,9 +26,9 @@ public class PutStatic extends Instruction } @Override - public void write(DataOutputStream out, int pc) throws IOException + public void write(DataOutputStream out) throws IOException { - super.write(out, pc); + super.write(out); out.writeShort(this.getPool().make(field)); } diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/SiPush.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/SiPush.java index a61d975d5c..14bf41f141 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/SiPush.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/SiPush.java @@ -26,9 +26,9 @@ public class SiPush extends Instruction } @Override - public void write(DataOutputStream out, int pc) throws IOException + public void write(DataOutputStream out) throws IOException { - super.write(out, pc); + super.write(out); out.writeShort(s); } diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/TableSwitch.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/TableSwitch.java index 86b64ad6ed..051e92d84e 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/TableSwitch.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/TableSwitch.java @@ -3,6 +3,7 @@ package info.sigterm.deob.attributes.code.instructions; import info.sigterm.deob.attributes.code.Instruction; import info.sigterm.deob.attributes.code.InstructionType; import info.sigterm.deob.attributes.code.Instructions; +import info.sigterm.deob.attributes.code.instruction.types.JumpingInstruction; import info.sigterm.deob.execution.Frame; import info.sigterm.deob.execution.InstructionContext; import info.sigterm.deob.execution.Stack; @@ -11,9 +12,14 @@ import info.sigterm.deob.execution.StackContext; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; +import java.util.ArrayList; +import java.util.List; -public class TableSwitch extends Instruction +public class TableSwitch extends Instruction implements JumpingInstruction { + private List branchi = new ArrayList<>(); + private Instruction defi; + private int def; private int low; private int high; @@ -42,29 +48,49 @@ public class TableSwitch extends Instruction length += tableSkip + 12 + (count * 4); } + // changing the pc changes the instruction length due to padding @Override - public void write(DataOutputStream out, int pc) throws IOException + public void setPc(int pc) { - super.write(out, pc); + super.setPc(pc); int tableSkip = 4 - (pc + 1) % 4; if (tableSkip == 4) tableSkip = 0; + + length = 1 + tableSkip + 12 + (jumps.length * 4); + } + + @Override + public void resolve() + { + for (int i : jumps) + branchi.add(this.getInstructions().findInstruction(this.getPc() + i)); + defi = this.getInstructions().findInstruction(this.getPc() + def); + } + + @Override + public void write(DataOutputStream out) throws IOException + { + super.write(out); + + int tableSkip = 4 - (this.getPc() + 1) % 4; + if (tableSkip == 4) tableSkip = 0; if (tableSkip > 0) out.write(new byte[tableSkip]); - out.writeInt(def); + out.writeInt(defi.getPc() - this.getPc()); out.writeInt(low); out.writeInt(high); - for (int i = 0; i < high - low + 1; ++i) - out.writeInt(jumps[i]); + for (Instruction i : branchi) + out.writeInt(i.getPc() - this.getPc()); } @Override public void buildJumpGraph() { - for (int i : jumps) + for (Instruction i : branchi) this.addJump(i); - this.addJump(def); + this.addJump(defi); } @Override @@ -92,4 +118,15 @@ public class TableSwitch extends Instruction { return true; } + + @Override + public void replace(Instruction oldi, Instruction newi) + { + if (defi == oldi) + defi = newi; + + for (int i = 0; i < branchi.size(); ++i) + if (branchi.get(i) == oldi) + branchi.set(i, newi); + } } diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/Wide.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/Wide.java index 8b18fc393c..38f5791e3c 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/Wide.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/Wide.java @@ -3,6 +3,7 @@ package info.sigterm.deob.attributes.code.instructions; import info.sigterm.deob.attributes.code.Instruction; import info.sigterm.deob.attributes.code.InstructionType; import info.sigterm.deob.attributes.code.Instructions; +import info.sigterm.deob.attributes.code.instruction.types.LVTInstruction; import info.sigterm.deob.attributes.code.instruction.types.WideInstruction; import info.sigterm.deob.execution.Frame; @@ -11,7 +12,7 @@ import java.io.DataOutputStream; import java.io.IOException; import java.lang.reflect.Constructor; -public class Wide extends Instruction +public class Wide extends Instruction implements LVTInstruction { private Instruction ins; @@ -27,7 +28,7 @@ public class Wide extends Instruction try { Constructor con = op.getInstructionClass().getConstructor(Instructions.class, InstructionType.class, Instruction.class, int.class); - ins = con.newInstance(instructions, type, this, pc); + ins = con.newInstance(instructions, op, this, pc); length += ins.getLength(); } catch (Exception ex) @@ -37,12 +38,12 @@ public class Wide extends Instruction } @Override - public void write(DataOutputStream out, int pc) throws IOException + public void write(DataOutputStream out) throws IOException { - super.write(out, pc); + super.write(out); WideInstruction w = (WideInstruction) ins; - w.writeWide(out, pc); + w.writeWide(out); } @Override @@ -51,4 +52,28 @@ public class Wide extends Instruction ins.execute(e); } + @Override + public void replace(Instruction oldi, Instruction newi) + { + assert oldi != ins; + } + + @Override + public int getVariableIndex() + { + return ((LVTInstruction) ins).getVariableIndex(); + } + + @Override + public Instruction setVariableIndex(int idx) + { + ins = ((LVTInstruction) ins).setVariableIndex(idx); + return this; + } + + @Override + public boolean store() + { + return ((LVTInstruction) ins).store(); + } } diff --git a/src/main/java/info/sigterm/deob/execution/Execution.java b/src/main/java/info/sigterm/deob/execution/Execution.java index c6687b7af4..e937cefa74 100644 --- a/src/main/java/info/sigterm/deob/execution/Execution.java +++ b/src/main/java/info/sigterm/deob/execution/Execution.java @@ -7,7 +7,8 @@ import java.util.List; public class Execution { private ClassGroup group; - public List frames = new ArrayList<>(); + public List frames = new ArrayList<>(), + processedFrames = new ArrayList<>(); public Execution(ClassGroup group) { @@ -21,9 +22,9 @@ public class Execution while (!frames.isEmpty()) { Frame frame = frames.remove(0); - System.out.println("Executing frame " + frame); ++fcount; frame.execute(); + processedFrames.add(frame); } return fcount; diff --git a/src/main/java/info/sigterm/deob/execution/Frame.java b/src/main/java/info/sigterm/deob/execution/Frame.java index 9d1a21e442..a2dd4c427e 100644 --- a/src/main/java/info/sigterm/deob/execution/Frame.java +++ b/src/main/java/info/sigterm/deob/execution/Frame.java @@ -103,6 +103,11 @@ public class Frame instructions.add(i); } + public List getInstructions() + { + return instructions; + } + public void execute() { Instructions ins = method.getCode().getInstructions(); @@ -121,7 +126,6 @@ public class Frame try { i.execute(this); - System.out.println(i.getDesc(this)); } catch (Throwable ex) { @@ -185,9 +189,4 @@ public class Frame doJump(from, to); this.pc = pc; } - - public Collection getExceptionHandlers() - { - return method.getCode().getExceptions().getHandlersForPc(this.pc); - } } diff --git a/src/main/java/info/sigterm/deob/execution/InstructionContext.java b/src/main/java/info/sigterm/deob/execution/InstructionContext.java index e2b22effd7..dab1a17968 100644 --- a/src/main/java/info/sigterm/deob/execution/InstructionContext.java +++ b/src/main/java/info/sigterm/deob/execution/InstructionContext.java @@ -39,4 +39,15 @@ public class InstructionContext { return pops; } + + public void removeStack(int idx) + { + // idx 0 is top of the stack, 1 is one under + // stack contexts are added to 'pops' in the order that they are popped from the stack, + // so just remove at index idx + StackContext ctx = pops.remove(idx); + + // start recursively removing + ctx.removeStack(); + } } diff --git a/src/main/java/info/sigterm/deob/execution/Stack.java b/src/main/java/info/sigterm/deob/execution/Stack.java index cb9188c1bd..bf4167d528 100644 --- a/src/main/java/info/sigterm/deob/execution/Stack.java +++ b/src/main/java/info/sigterm/deob/execution/Stack.java @@ -40,7 +40,6 @@ public class Stack assert !i.getType().type.equals("V"); - System.out.println("PUSH context " + i.getType().type + " from + " + i.getIns().getInstruction()); stack[size] = i; ++size; } @@ -50,9 +49,6 @@ public class Stack if (size <= 0) throw new RuntimeException("Stack underflow"); - System.out.println("POP"); - if (size == 1) - System.out.println("STACK SIZE IS NOW ZERO"); return stack[--size]; } diff --git a/src/main/java/info/sigterm/deob/execution/StackContext.java b/src/main/java/info/sigterm/deob/execution/StackContext.java index 14f5815a84..62dbe18773 100644 --- a/src/main/java/info/sigterm/deob/execution/StackContext.java +++ b/src/main/java/info/sigterm/deob/execution/StackContext.java @@ -32,4 +32,18 @@ public class StackContext { return type; } + + // remove this object from the stack + public void removeStack() + { + // remove the instruction which pushed this + if (!ic.getInstruction().removeStack()) + // dup will return false as the other objects on the stack below this are necessary + // for the other branch. + return; + + // remove from the stack things this instruction read + for (StackContext ctx : ic.getPops()) + ctx.removeStack(); + } } diff --git a/src/main/java/info/sigterm/deob/execution/Type.java b/src/main/java/info/sigterm/deob/execution/Type.java index 4c3d8630f2..6eae8cf4b2 100644 --- a/src/main/java/info/sigterm/deob/execution/Type.java +++ b/src/main/java/info/sigterm/deob/execution/Type.java @@ -13,11 +13,9 @@ public class Type public Type(info.sigterm.deob.signature.Type t) { - String before = t.getType(); type = asmTypeToClass(t.getType()); for (int i = 0; i < t.getArrayDims(); ++i) type = type + "[]"; - System.out.println(before + " -> " + type); } public Type toStackType() diff --git a/src/main/java/info/sigterm/deob/pool/InterfaceMethod.java b/src/main/java/info/sigterm/deob/pool/InterfaceMethod.java index 56f9097422..1937cab8e6 100644 --- a/src/main/java/info/sigterm/deob/pool/InterfaceMethod.java +++ b/src/main/java/info/sigterm/deob/pool/InterfaceMethod.java @@ -11,6 +11,14 @@ public class InterfaceMethod extends PoolEntry private int classIndex, natIndex; private Class clazz; private NameAndType nat; + + public InterfaceMethod(ConstantPool pool, Class clazz, NameAndType nat) + { + super(pool, ConstantType.INTERFACE_METHOD_REF); + + this.clazz = clazz; + this.nat = nat; + } public InterfaceMethod(ConstantPool pool) throws IOException { diff --git a/src/main/java/info/sigterm/deob/pool/Method.java b/src/main/java/info/sigterm/deob/pool/Method.java index 85dc65b5a4..a7a15fe85c 100644 --- a/src/main/java/info/sigterm/deob/pool/Method.java +++ b/src/main/java/info/sigterm/deob/pool/Method.java @@ -11,6 +11,14 @@ public class Method extends PoolEntry private int classIndex, natIndex; private Class clazz; private NameAndType nat; + + public Method(ConstantPool pool, Class clazz, NameAndType nat) + { + super(pool, ConstantType.METHODREF); + + this.clazz = clazz; + this.nat = nat; + } public Method(ConstantPool pool) throws IOException { diff --git a/src/main/java/info/sigterm/deob/pool/NameAndType.java b/src/main/java/info/sigterm/deob/pool/NameAndType.java index 5e8e88c1f8..580969287c 100644 --- a/src/main/java/info/sigterm/deob/pool/NameAndType.java +++ b/src/main/java/info/sigterm/deob/pool/NameAndType.java @@ -28,6 +28,14 @@ public class NameAndType extends PoolEntry descriptorIndex = is.readUnsignedShort(); } + public NameAndType(ConstantPool pool, java.lang.String name, Signature sig) + { + super(pool, ConstantType.NAME_AND_TYPE); + + this.name = name; + this.signature = sig; + } + public NameAndType(java.lang.String name, Signature type) { super(null, ConstantType.NAME_AND_TYPE); diff --git a/src/main/java/info/sigterm/deob/signature/Signature.java b/src/main/java/info/sigterm/deob/signature/Signature.java index 34dd5bfb00..18ce0dbe0d 100644 --- a/src/main/java/info/sigterm/deob/signature/Signature.java +++ b/src/main/java/info/sigterm/deob/signature/Signature.java @@ -31,6 +31,12 @@ public class Signature rv = new Type(ret); } + public Signature(Signature other) + { + rv = other.rv; + arguments.addAll(other.arguments); + } + @Override public boolean equals(Object other) {