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