Make method inliner copy instead of move ins. I don't think the way it inlined exceptions before was correct. I had to make it not inline funcs with exception handlers
This commit is contained in:
@@ -30,6 +30,8 @@ import net.runelite.deob.deobfuscators.arithmetic.MultiplyOneDeobfuscator;
|
||||
import net.runelite.deob.deobfuscators.arithmetic.MultiplyZeroDeobfuscator;
|
||||
import net.runelite.deob.execution.Execution;
|
||||
|
||||
// XXX something to detect final fields and evaluate them
|
||||
|
||||
public class Deob
|
||||
{
|
||||
public static void main(String[] args) throws IOException
|
||||
@@ -73,7 +75,7 @@ public class Deob
|
||||
// run(group, new UnusedMethods());
|
||||
|
||||
run(group, new MethodInliner());
|
||||
// now remove unused methods?
|
||||
run(group, new UnusedMethods()); // inliner might leave unused methods
|
||||
|
||||
// // broken because rename was removed
|
||||
// //run(group, new MethodMover());
|
||||
|
||||
@@ -8,7 +8,7 @@ import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
public class Exception
|
||||
public class Exception implements Cloneable
|
||||
{
|
||||
private Exceptions exceptions;
|
||||
|
||||
@@ -36,6 +36,19 @@ public class Exception
|
||||
assert handler != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Exception clone()
|
||||
{
|
||||
try
|
||||
{
|
||||
return (Exception) super.clone();
|
||||
}
|
||||
catch (CloneNotSupportedException ex)
|
||||
{
|
||||
throw new RuntimeException();
|
||||
}
|
||||
}
|
||||
|
||||
public void write(DataOutputStream out) throws IOException
|
||||
{
|
||||
ConstantPool pool = exceptions.getCode().getAttributes().getClassFile().getPool();
|
||||
|
||||
@@ -9,9 +9,8 @@ import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import net.runelite.deob.util.NameMappings;
|
||||
|
||||
public abstract class Instruction
|
||||
public abstract class Instruction implements Cloneable
|
||||
{
|
||||
private Instructions instructions;
|
||||
public Block block;
|
||||
@@ -30,6 +29,19 @@ public abstract class Instruction
|
||||
this.pc = pc;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Instruction clone()
|
||||
{
|
||||
try
|
||||
{
|
||||
return (Instruction) super.clone();
|
||||
}
|
||||
catch (CloneNotSupportedException ex)
|
||||
{
|
||||
throw new RuntimeException();
|
||||
}
|
||||
}
|
||||
|
||||
public void load(DataInputStream is) throws IOException
|
||||
{
|
||||
}
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
package net.runelite.deob.attributes.code;
|
||||
|
||||
import net.runelite.deob.ClassFile;
|
||||
import net.runelite.deob.Field;
|
||||
import net.runelite.deob.Method;
|
||||
import net.runelite.deob.attributes.Code;
|
||||
import net.runelite.deob.attributes.code.instruction.types.JumpingInstruction;
|
||||
import net.runelite.deob.block.Block;
|
||||
@@ -14,7 +11,7 @@ import java.io.IOException;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import net.runelite.deob.util.NameMappings;
|
||||
import net.runelite.deob.attributes.code.instructions.Goto;
|
||||
|
||||
public class Instructions
|
||||
{
|
||||
@@ -182,6 +179,8 @@ public class Instructions
|
||||
public void write(DataOutputStream out) throws IOException
|
||||
{
|
||||
// trnaslate instructions to specific
|
||||
this.buildJumpGraph();
|
||||
|
||||
for (Instruction i : new ArrayList<>(instructions))
|
||||
{
|
||||
Instruction specific = i.makeSpecific();
|
||||
@@ -271,10 +270,13 @@ public class Instructions
|
||||
|
||||
int i = instructions.indexOf(oldi);
|
||||
instructions.remove(oldi);
|
||||
oldi.setInstructions(null);
|
||||
instructions.add(i, newi);
|
||||
|
||||
for (Instruction ins : oldi.from)
|
||||
{
|
||||
assert ins.getInstructions() == this;
|
||||
assert this.getInstructions().contains(ins);
|
||||
assert ins.jump.contains(oldi);
|
||||
|
||||
ins.jump.remove(oldi);
|
||||
@@ -286,7 +288,5 @@ public class Instructions
|
||||
|
||||
for (net.runelite.deob.attributes.code.Exception e : code.getExceptions().getExceptions())
|
||||
e.replace(oldi, newi);
|
||||
|
||||
oldi.setInstructions(null);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,14 @@ public class Wide extends Instruction implements LVTInstruction
|
||||
super(instructions, type, pc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Instruction clone()
|
||||
{
|
||||
Wide wide = (Wide) super.clone();
|
||||
wide.ins = ins.clone();
|
||||
return wide;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load(DataInputStream is) throws IOException
|
||||
{
|
||||
|
||||
@@ -21,10 +21,9 @@ import net.runelite.deob.attributes.code.instructions.NOP;
|
||||
import net.runelite.deob.signature.Signature;
|
||||
import net.runelite.deob.signature.Type;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.Map.Entry;
|
||||
import net.runelite.deob.attributes.code.Exceptions;
|
||||
|
||||
public class MethodInliner implements Deobfuscator
|
||||
@@ -84,7 +83,10 @@ public class MethodInliner implements Deobfuscator
|
||||
Method invokedMethod = invokedMethods.get(0);
|
||||
Integer count = calls.get(invokedMethod);
|
||||
|
||||
if (count == null || invokedMethod.getCode().getInstructions().getInstructions().size() > 30)
|
||||
// this can't inline functions with exception handlers because throwing exceptions clears the stack
|
||||
if (count == null
|
||||
|| !invokedMethod.getCode().getExceptions().getExceptions().isEmpty()
|
||||
|| invokedMethod.getCode().getInstructions().getInstructions().size() > 30) // XXX magic
|
||||
continue;
|
||||
// if (count == null || count != 1)
|
||||
// continue; // only inline methods called once
|
||||
@@ -94,7 +96,7 @@ public class MethodInliner implements Deobfuscator
|
||||
|
||||
int invokeIdx = ins.getInstructions().indexOf(i);
|
||||
assert invokeIdx != -1;
|
||||
assert ins.getInstructions().get(invokeIdx).getInstructions() == ins.getInstructions();
|
||||
assert ins.getInstructions().get(invokeIdx).getInstructions() == ins;
|
||||
|
||||
int lvtIndex = code.getMaxLocals(),
|
||||
//startLvtIndex = lvtIndex,
|
||||
@@ -167,7 +169,6 @@ public class MethodInliner implements Deobfuscator
|
||||
code.setMaxStack(maxStack);
|
||||
|
||||
inline(m, i, invokedMethod, lvtIndex, firstParamStore);
|
||||
moveExceptions(m, invokedMethod);
|
||||
++inlineCount;
|
||||
break;
|
||||
}
|
||||
@@ -220,9 +221,43 @@ public class MethodInliner implements Deobfuscator
|
||||
|
||||
methodInstructions.remove(invokeIns);
|
||||
|
||||
Map<Instruction, Instruction> insMap = new HashMap<>();
|
||||
for (Instruction i : invokeMethodInstructions.getInstructions())
|
||||
{
|
||||
// move instructions over.
|
||||
Instruction i2 = i.clone();
|
||||
i2.setInstructions(null);
|
||||
insMap.put(i, i2);
|
||||
}
|
||||
|
||||
for (Instruction i : insMap.values())
|
||||
{
|
||||
for (Entry<Instruction, Instruction> e : insMap.entrySet())
|
||||
{
|
||||
i.replace(e.getKey(), e.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
Exceptions fromExceptions = invokeMethod.getCode().getExceptions();
|
||||
Exceptions toExceptions = method.getCode().getExceptions();
|
||||
|
||||
for (net.runelite.deob.attributes.code.Exception e : fromExceptions.getExceptions())
|
||||
{
|
||||
e = e.clone();
|
||||
e.setExceptions(toExceptions);
|
||||
|
||||
for (Entry<Instruction, Instruction> en : insMap.entrySet())
|
||||
{
|
||||
e.replace(en.getKey(), en.getValue());
|
||||
}
|
||||
|
||||
toExceptions.add(e);
|
||||
}
|
||||
|
||||
for (Instruction i : invokeMethodInstructions.getInstructions())
|
||||
{
|
||||
Instruction orig = i;
|
||||
i = insMap.get(i);
|
||||
// copy instructions over.
|
||||
|
||||
if (i instanceof ReturnInstruction)
|
||||
{
|
||||
@@ -231,23 +266,16 @@ public class MethodInliner implements Deobfuscator
|
||||
// instead of return, jump to next instruction after the invoke
|
||||
Instruction oldI = i;
|
||||
i = new Goto(methodInstructions, nextInstruction);
|
||||
assert nextInstruction.getInstructions() == methodInstructions;
|
||||
assert methodInstructions.getInstructions().contains(nextInstruction);
|
||||
|
||||
assert oldI != nextInstruction;
|
||||
i.jump.add(nextInstruction);
|
||||
nextInstruction.from.add(i);
|
||||
|
||||
assert oldI.jump.isEmpty();
|
||||
//i.jump.addAll(oldI.jump);
|
||||
i.from.addAll(oldI.from);
|
||||
|
||||
for (Instruction i2 : oldI.from)
|
||||
for (Instruction i2 : insMap.values())
|
||||
i2.replace(oldI, i);
|
||||
|
||||
oldI.from.clear();
|
||||
|
||||
for (net.runelite.deob.attributes.code.Exception e : invokeMethodCode.getExceptions().getExceptions())
|
||||
for (net.runelite.deob.attributes.code.Exception e : toExceptions.getExceptions())
|
||||
e.replace(oldI, i);
|
||||
|
||||
insMap.put(orig, i);
|
||||
}
|
||||
|
||||
if (i instanceof LVTInstruction)
|
||||
@@ -261,40 +289,20 @@ public class MethodInliner implements Deobfuscator
|
||||
|
||||
if (oldI != i)
|
||||
{
|
||||
assert oldI.jump.isEmpty();
|
||||
//i.jump.addAll(oldI.jump);
|
||||
i.from.addAll(oldI.from);
|
||||
|
||||
for (Instruction i2 : oldI.from)
|
||||
for (Instruction i2 : insMap.values())
|
||||
i2.replace(oldI, i);
|
||||
|
||||
oldI.from.clear();
|
||||
|
||||
for (net.runelite.deob.attributes.code.Exception e : invokeMethodCode.getExceptions().getExceptions())
|
||||
for (net.runelite.deob.attributes.code.Exception e : toExceptions.getExceptions())
|
||||
e.replace(oldI, i);
|
||||
|
||||
insMap.put(orig, i);
|
||||
}
|
||||
}
|
||||
|
||||
methodInstructions.getInstructions().add(idx++, i);
|
||||
assert !methodInstructions.getInstructions().contains(i);
|
||||
i.setInstructions(methodInstructions);
|
||||
methodInstructions.getInstructions().add(idx++, i);
|
||||
}
|
||||
|
||||
// old method goes away
|
||||
//invokeMethodInstructions.getInstructions().clear();
|
||||
//removeMethods.add(invokeMethod);
|
||||
}
|
||||
|
||||
private void moveExceptions(Method to, Method from)
|
||||
{
|
||||
Exceptions exceptions = from.getCode().getExceptions();
|
||||
Exceptions toExceptions = to.getCode().getExceptions();
|
||||
|
||||
for (net.runelite.deob.attributes.code.Exception e : exceptions.getExceptions())
|
||||
{
|
||||
e.setExceptions(toExceptions);
|
||||
toExceptions.add(e);
|
||||
}
|
||||
exceptions.getExceptions().clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user