From bf03c607310e796403dad2d6352e4bd78b8fcc97 Mon Sep 17 00:00:00 2001 From: Adam Date: Fri, 12 Feb 2016 14:56:32 -0500 Subject: [PATCH] Map fields from ifs --- .../deob/attributes/code/instructions/If.java | 54 +++++++++++++++++-- .../attributes/code/instructions/If0.java | 53 ++++++++++++++++-- .../code/instructions/IfACmpEq.java | 5 +- .../code/instructions/IfACmpNe.java | 5 +- .../attributes/code/instructions/IfCmpGe.java | 5 +- .../attributes/code/instructions/IfCmpGt.java | 5 +- .../attributes/code/instructions/IfCmpLe.java | 5 +- .../attributes/code/instructions/IfCmpLt.java | 5 +- .../attributes/code/instructions/IfEq.java | 5 +- .../attributes/code/instructions/IfGe.java | 13 +++++ .../attributes/code/instructions/IfGt.java | 5 +- .../code/instructions/IfICmpEq.java | 5 +- .../code/instructions/IfICmpNe.java | 5 +- .../attributes/code/instructions/IfLe.java | 5 +- .../attributes/code/instructions/IfLt.java | 5 +- .../attributes/code/instructions/IfNe.java | 5 +- .../code/instructions/IfNonNull.java | 5 +- .../attributes/code/instructions/IfNull.java | 5 +- .../deobfuscators/rename/MapStaticTest.java | 20 +++---- 19 files changed, 184 insertions(+), 31 deletions(-) diff --git a/src/main/java/net/runelite/deob/attributes/code/instructions/If.java b/src/main/java/net/runelite/deob/attributes/code/instructions/If.java index a4586beb88..1a1cb89ba9 100644 --- a/src/main/java/net/runelite/deob/attributes/code/instructions/If.java +++ b/src/main/java/net/runelite/deob/attributes/code/instructions/If.java @@ -15,7 +15,10 @@ import java.io.DataOutputStream; import java.io.IOException; import java.util.Arrays; import java.util.List; +import net.runelite.deob.Field; +import net.runelite.deob.attributes.code.instruction.types.GetFieldInstruction; import net.runelite.deob.attributes.code.instruction.types.MappableInstruction; +import net.runelite.deob.deobfuscators.rename.MappingExecutorUtil; import net.runelite.deob.deobfuscators.rename.ParallelExecutorMapping; import net.runelite.deob.execution.Execution; @@ -110,6 +113,8 @@ public abstract class If extends Instruction implements JumpingInstruction, Comp branch1.other = branch2; branch2.other = branch1; + + this.mapArguments(mapping, ctx, other); } protected void mapOtherBranch(ParallelExecutorMapping mapping, InstructionContext ctx, InstructionContext other) @@ -147,12 +152,55 @@ public abstract class If extends Instruction implements JumpingInstruction, Comp // // e2.frames.remove(i2); // e2.frames.add(i2, f2); + + this.mapArguments(mapping, ctx, other); } - @Override - public boolean isSame(InstructionContext thisIc, InstructionContext otherIc) + private void mapArguments(ParallelExecutorMapping mapping, InstructionContext ctx, InstructionContext other) { - return thisIc.getInstruction().getClass() == otherIc.getInstruction().getClass(); + Field f1 = getComparedField(ctx), f2 = getComparedField(other); + + if (f1 == null || f2 == null) + return; + + assert f1.getType().equals(f2.getType()); + + mapping.map(f1, f2); + } + + private Field getComparedField(InstructionContext ctx) + { + GetFieldInstruction gfi = null; + + for (StackContext sctx : ctx.getPops()) + { + InstructionContext base = MappingExecutorUtil.resolve(sctx.getPushed(), sctx); + + if (base.getInstruction() instanceof GetFieldInstruction) + { + if (gfi != null) + return null; + + gfi = (GetFieldInstruction) base.getInstruction(); + } + } + + if (gfi == null) + return null; + + return gfi.getMyField(); + } + + protected boolean isSameField(InstructionContext thisIc, InstructionContext otherIc) + { + Field f1 = getComparedField(thisIc), f2 = getComparedField(otherIc); + if ((f1 != null) != (f2 != null)) + return false; + + if (f1 == null || f2 == null) + return true; + + return f1.getType().equals(f2.getType()); } @Override diff --git a/src/main/java/net/runelite/deob/attributes/code/instructions/If0.java b/src/main/java/net/runelite/deob/attributes/code/instructions/If0.java index 7f6f4a5c42..e796c1ffb1 100644 --- a/src/main/java/net/runelite/deob/attributes/code/instructions/If0.java +++ b/src/main/java/net/runelite/deob/attributes/code/instructions/If0.java @@ -15,7 +15,10 @@ import java.io.DataOutputStream; import java.io.IOException; import java.util.Arrays; import java.util.List; +import net.runelite.deob.Field; +import net.runelite.deob.attributes.code.instruction.types.GetFieldInstruction; import net.runelite.deob.attributes.code.instruction.types.MappableInstruction; +import net.runelite.deob.deobfuscators.rename.MappingExecutorUtil; import net.runelite.deob.deobfuscators.rename.ParallelExecutorMapping; import net.runelite.deob.execution.Execution; @@ -112,6 +115,8 @@ public abstract class If0 extends Instruction implements JumpingInstruction, Com branch1.other = branch2; branch2.other = branch1; + + this.mapArguments(mapping, ctx, other); } // duplicated from If @@ -150,12 +155,54 @@ public abstract class If0 extends Instruction implements JumpingInstruction, Com // // e2.frames.remove(i2); // e2.frames.add(i2, f2); + + this.mapArguments(mapping, ctx, other); } - @Override - public boolean isSame(InstructionContext thisIc, InstructionContext otherIc) + private void mapArguments(ParallelExecutorMapping mapping, InstructionContext ctx, InstructionContext other) { - return thisIc.getInstruction().getClass() == otherIc.getInstruction().getClass(); + Field f1 = getComparedField(ctx), f2 = getComparedField(other); + if (f1 == null || f2 == null) + return; + + assert f1.getType().equals(f2.getType()); + + mapping.map(f1, f2); + } + + private Field getComparedField(InstructionContext ctx) + { + GetFieldInstruction gfi = null; + + for (StackContext sctx : ctx.getPops()) + { + InstructionContext base = MappingExecutorUtil.resolve(sctx.getPushed(), sctx); + + if (base.getInstruction() instanceof GetFieldInstruction) + { + if (gfi != null) + return null; + + gfi = (GetFieldInstruction) base.getInstruction(); + } + } + + if (gfi == null) + return null; + + return gfi.getMyField(); + } + + protected boolean isSameField(InstructionContext thisIc, InstructionContext otherIc) + { + Field f1 = getComparedField(thisIc), f2 = getComparedField(otherIc); + if ((f1 != null) != (f2 != null)) + return false; + + if (f1 == null || f2 == null) + return true; + + return f1.getType().equals(f2.getType()); } @Override diff --git a/src/main/java/net/runelite/deob/attributes/code/instructions/IfACmpEq.java b/src/main/java/net/runelite/deob/attributes/code/instructions/IfACmpEq.java index 811d758c9b..6c97ea9b0e 100644 --- a/src/main/java/net/runelite/deob/attributes/code/instructions/IfACmpEq.java +++ b/src/main/java/net/runelite/deob/attributes/code/instructions/IfACmpEq.java @@ -16,7 +16,10 @@ public class IfACmpEq extends If @Override public boolean isSame(InstructionContext thisIc, InstructionContext otherIc) { - if (super.isSame(thisIc, otherIc)) + if (!this.isSameField(thisIc, otherIc)) + return false; + + if (thisIc.getInstruction().getClass() == otherIc.getInstruction().getClass()) return true; if (otherIc.getInstruction() instanceof IfNull || otherIc.getInstruction() instanceof IfNonNull) diff --git a/src/main/java/net/runelite/deob/attributes/code/instructions/IfACmpNe.java b/src/main/java/net/runelite/deob/attributes/code/instructions/IfACmpNe.java index 00ec4f698a..c5f18ae69d 100644 --- a/src/main/java/net/runelite/deob/attributes/code/instructions/IfACmpNe.java +++ b/src/main/java/net/runelite/deob/attributes/code/instructions/IfACmpNe.java @@ -16,7 +16,10 @@ public class IfACmpNe extends If @Override public boolean isSame(InstructionContext thisIc, InstructionContext otherIc) { - if (super.isSame(thisIc, otherIc)) + if (!this.isSameField(thisIc, otherIc)) + return false; + + if (thisIc.getInstruction().getClass() == otherIc.getInstruction().getClass()) return true; if (otherIc.getInstruction() instanceof IfNonNull || otherIc.getInstruction() instanceof IfNull) diff --git a/src/main/java/net/runelite/deob/attributes/code/instructions/IfCmpGe.java b/src/main/java/net/runelite/deob/attributes/code/instructions/IfCmpGe.java index 9abde94be5..5ec56b27bc 100644 --- a/src/main/java/net/runelite/deob/attributes/code/instructions/IfCmpGe.java +++ b/src/main/java/net/runelite/deob/attributes/code/instructions/IfCmpGe.java @@ -15,7 +15,10 @@ public class IfCmpGe extends If @Override public boolean isSame(InstructionContext thisIc, InstructionContext otherIc) { - if (super.isSame(thisIc, otherIc)) + if (!this.isSameField(thisIc, otherIc)) + return false; + + if (thisIc.getInstruction().getClass() == otherIc.getInstruction().getClass()) return true; if (otherIc.getInstruction() instanceof IfCmpLt) diff --git a/src/main/java/net/runelite/deob/attributes/code/instructions/IfCmpGt.java b/src/main/java/net/runelite/deob/attributes/code/instructions/IfCmpGt.java index 096c7222a3..73ceec4fdd 100644 --- a/src/main/java/net/runelite/deob/attributes/code/instructions/IfCmpGt.java +++ b/src/main/java/net/runelite/deob/attributes/code/instructions/IfCmpGt.java @@ -17,7 +17,10 @@ public class IfCmpGt extends If @Override public boolean isSame(InstructionContext thisIc, InstructionContext otherIc) { - if (super.isSame(thisIc, otherIc)) + if (!this.isSameField(thisIc, otherIc)) + return false; + + if (thisIc.getInstruction().getClass() == otherIc.getInstruction().getClass()) return true; if (otherIc.getInstruction() instanceof IfCmpLe) diff --git a/src/main/java/net/runelite/deob/attributes/code/instructions/IfCmpLe.java b/src/main/java/net/runelite/deob/attributes/code/instructions/IfCmpLe.java index 785a9c11ac..f113893263 100644 --- a/src/main/java/net/runelite/deob/attributes/code/instructions/IfCmpLe.java +++ b/src/main/java/net/runelite/deob/attributes/code/instructions/IfCmpLe.java @@ -15,7 +15,10 @@ public class IfCmpLe extends If @Override public boolean isSame(InstructionContext thisIc, InstructionContext otherIc) { - if (super.isSame(thisIc, otherIc)) + if (!this.isSameField(thisIc, otherIc)) + return false; + + if (thisIc.getInstruction().getClass() == otherIc.getInstruction().getClass()) return true; if (otherIc.getInstruction() instanceof IfCmpGt) diff --git a/src/main/java/net/runelite/deob/attributes/code/instructions/IfCmpLt.java b/src/main/java/net/runelite/deob/attributes/code/instructions/IfCmpLt.java index 710d302393..81f7d678e5 100644 --- a/src/main/java/net/runelite/deob/attributes/code/instructions/IfCmpLt.java +++ b/src/main/java/net/runelite/deob/attributes/code/instructions/IfCmpLt.java @@ -15,7 +15,10 @@ public class IfCmpLt extends If @Override public boolean isSame(InstructionContext thisIc, InstructionContext otherIc) { - if (super.isSame(thisIc, otherIc)) + if (!this.isSameField(thisIc, otherIc)) + return false; + + if (thisIc.getInstruction().getClass() == otherIc.getInstruction().getClass()) return true; if (otherIc.getInstruction() instanceof IfCmpGe) diff --git a/src/main/java/net/runelite/deob/attributes/code/instructions/IfEq.java b/src/main/java/net/runelite/deob/attributes/code/instructions/IfEq.java index 3dd9c408a7..50417ddc80 100644 --- a/src/main/java/net/runelite/deob/attributes/code/instructions/IfEq.java +++ b/src/main/java/net/runelite/deob/attributes/code/instructions/IfEq.java @@ -18,7 +18,10 @@ public class IfEq extends If0 @Override public boolean isSame(InstructionContext thisIc, InstructionContext otherIc) { - if (super.isSame(thisIc, otherIc)) + if (!this.isSameField(thisIc, otherIc)) + return false; + + if (thisIc.getInstruction().getClass() == otherIc.getInstruction().getClass()) return true; if (otherIc.getInstruction() instanceof IfNe) diff --git a/src/main/java/net/runelite/deob/attributes/code/instructions/IfGe.java b/src/main/java/net/runelite/deob/attributes/code/instructions/IfGe.java index 386ae5d722..ba98d70e80 100644 --- a/src/main/java/net/runelite/deob/attributes/code/instructions/IfGe.java +++ b/src/main/java/net/runelite/deob/attributes/code/instructions/IfGe.java @@ -2,6 +2,7 @@ package net.runelite.deob.attributes.code.instructions; import net.runelite.deob.attributes.code.InstructionType; import net.runelite.deob.attributes.code.Instructions; +import net.runelite.deob.execution.InstructionContext; public class IfGe extends If0 { @@ -10,4 +11,16 @@ public class IfGe extends If0 super(instructions, type, pc); } + @Override + public boolean isSame(InstructionContext thisIc, InstructionContext otherIc) + { + if (!this.isSameField(thisIc, otherIc)) + return false; + + if (thisIc.getInstruction().getClass() == otherIc.getInstruction().getClass()) + return true; + + return false; + } + } diff --git a/src/main/java/net/runelite/deob/attributes/code/instructions/IfGt.java b/src/main/java/net/runelite/deob/attributes/code/instructions/IfGt.java index 219ef625ec..2b1eb3a6ea 100644 --- a/src/main/java/net/runelite/deob/attributes/code/instructions/IfGt.java +++ b/src/main/java/net/runelite/deob/attributes/code/instructions/IfGt.java @@ -15,7 +15,10 @@ public class IfGt extends If0 @Override public boolean isSame(InstructionContext thisIc, InstructionContext otherIc) { - if (super.isSame(thisIc, otherIc)) + if (!this.isSameField(thisIc, otherIc)) + return false; + + if (thisIc.getInstruction().getClass() == otherIc.getInstruction().getClass()) return true; if (otherIc.getInstruction() instanceof IfLe) diff --git a/src/main/java/net/runelite/deob/attributes/code/instructions/IfICmpEq.java b/src/main/java/net/runelite/deob/attributes/code/instructions/IfICmpEq.java index 7f5f94a8c8..a2e4b0d833 100644 --- a/src/main/java/net/runelite/deob/attributes/code/instructions/IfICmpEq.java +++ b/src/main/java/net/runelite/deob/attributes/code/instructions/IfICmpEq.java @@ -41,7 +41,10 @@ public class IfICmpEq extends If @Override public boolean isSame(InstructionContext thisIc, InstructionContext otherIc) { - if (super.isSame(thisIc, otherIc)) + if (!this.isSameField(thisIc, otherIc)) + return false; + + if (thisIc.getInstruction().getClass() == otherIc.getInstruction().getClass()) return true; // check for other being ifeq and this has a constant 0 diff --git a/src/main/java/net/runelite/deob/attributes/code/instructions/IfICmpNe.java b/src/main/java/net/runelite/deob/attributes/code/instructions/IfICmpNe.java index 8b30138d88..e08542d63b 100644 --- a/src/main/java/net/runelite/deob/attributes/code/instructions/IfICmpNe.java +++ b/src/main/java/net/runelite/deob/attributes/code/instructions/IfICmpNe.java @@ -31,7 +31,10 @@ public class IfICmpNe extends If @Override public boolean isSame(InstructionContext thisIc, InstructionContext otherIc) { - if (super.isSame(thisIc, otherIc)) + if (!this.isSameField(thisIc, otherIc)) + return false; + + if (thisIc.getInstruction().getClass() == otherIc.getInstruction().getClass()) return true; // check for other being ifne and this has a constant 0 diff --git a/src/main/java/net/runelite/deob/attributes/code/instructions/IfLe.java b/src/main/java/net/runelite/deob/attributes/code/instructions/IfLe.java index d250cfaf97..72cec50406 100644 --- a/src/main/java/net/runelite/deob/attributes/code/instructions/IfLe.java +++ b/src/main/java/net/runelite/deob/attributes/code/instructions/IfLe.java @@ -15,7 +15,10 @@ public class IfLe extends If0 @Override public boolean isSame(InstructionContext thisIc, InstructionContext otherIc) { - if (super.isSame(thisIc, otherIc)) + if (!this.isSameField(thisIc, otherIc)) + return false; + + if (thisIc.getInstruction().getClass() == otherIc.getInstruction().getClass()) return true; if (otherIc.getInstruction() instanceof IfGt) diff --git a/src/main/java/net/runelite/deob/attributes/code/instructions/IfLt.java b/src/main/java/net/runelite/deob/attributes/code/instructions/IfLt.java index ebb6536798..748f60f146 100644 --- a/src/main/java/net/runelite/deob/attributes/code/instructions/IfLt.java +++ b/src/main/java/net/runelite/deob/attributes/code/instructions/IfLt.java @@ -15,7 +15,10 @@ public class IfLt extends If0 @Override public boolean isSame(InstructionContext thisIc, InstructionContext otherIc) { - if (super.isSame(thisIc, otherIc)) + if (!this.isSameField(thisIc, otherIc)) + return false; + + if (thisIc.getInstruction().getClass() == otherIc.getInstruction().getClass()) return true; if (otherIc.getInstruction() instanceof IfGe) diff --git a/src/main/java/net/runelite/deob/attributes/code/instructions/IfNe.java b/src/main/java/net/runelite/deob/attributes/code/instructions/IfNe.java index a68dfe5481..4fa5cf426c 100644 --- a/src/main/java/net/runelite/deob/attributes/code/instructions/IfNe.java +++ b/src/main/java/net/runelite/deob/attributes/code/instructions/IfNe.java @@ -18,7 +18,10 @@ public class IfNe extends If0 @Override public boolean isSame(InstructionContext thisIc, InstructionContext otherIc) { - if (super.isSame(thisIc, otherIc)) + if (!this.isSameField(thisIc, otherIc)) + return false; + + if (thisIc.getInstruction().getClass() == otherIc.getInstruction().getClass()) return true; if (otherIc.getInstruction() instanceof IfICmpNe || otherIc.getInstruction() instanceof IfICmpEq) diff --git a/src/main/java/net/runelite/deob/attributes/code/instructions/IfNonNull.java b/src/main/java/net/runelite/deob/attributes/code/instructions/IfNonNull.java index 0b0b807086..eef12892ca 100644 --- a/src/main/java/net/runelite/deob/attributes/code/instructions/IfNonNull.java +++ b/src/main/java/net/runelite/deob/attributes/code/instructions/IfNonNull.java @@ -16,7 +16,10 @@ public class IfNonNull extends If0 @Override public boolean isSame(InstructionContext thisIc, InstructionContext otherIc) { - if (super.isSame(thisIc, otherIc)) + if (!this.isSameField(thisIc, otherIc)) + return false; + + if (thisIc.getInstruction().getClass() == otherIc.getInstruction().getClass()) return true; if (otherIc.getInstruction() instanceof IfACmpNe) diff --git a/src/main/java/net/runelite/deob/attributes/code/instructions/IfNull.java b/src/main/java/net/runelite/deob/attributes/code/instructions/IfNull.java index 748fd5835f..872af41796 100644 --- a/src/main/java/net/runelite/deob/attributes/code/instructions/IfNull.java +++ b/src/main/java/net/runelite/deob/attributes/code/instructions/IfNull.java @@ -16,7 +16,10 @@ public class IfNull extends If0 @Override public boolean isSame(InstructionContext thisIc, InstructionContext otherIc) { - if (super.isSame(thisIc, otherIc)) + if (!this.isSameField(thisIc, otherIc)) + return false; + + if (thisIc.getInstruction().getClass() == otherIc.getInstruction().getClass()) return true; if (otherIc.getInstruction() instanceof IfACmpEq || otherIc.getInstruction() instanceof IfACmpNe) diff --git a/src/test/java/net/runelite/deob/deobfuscators/rename/MapStaticTest.java b/src/test/java/net/runelite/deob/deobfuscators/rename/MapStaticTest.java index cf4cdfffd8..adc9405a94 100644 --- a/src/test/java/net/runelite/deob/deobfuscators/rename/MapStaticTest.java +++ b/src/test/java/net/runelite/deob/deobfuscators/rename/MapStaticTest.java @@ -245,16 +245,16 @@ public class MapStaticTest System.out.println("GROUP 2 " + sg2); - for (Method m : group1.findClass("client").getMethods().getMethods()) - { - if (!finalm.getMap().containsKey(m)) - System.out.println("missing " + m); - } - for (Field m : group1.findClass("client").getFields().getFields()) - { - if (!finalm.getMap().containsKey(m)) - System.out.println("missing " + m); - } +// for (Method m : group1.findClass("client").getMethods().getMethods()) +// { +// if (!finalm.getMap().containsKey(m)) +// System.out.println("missing " + m); +// } +// for (Field m : group1.findClass("client").getFields().getFields()) +// { +// if (!finalm.getMap().containsKey(m)) +// System.out.println("missing " + m); +// } } //@Test