modarith test

This commit is contained in:
Adam
2016-03-26 10:43:26 -04:00
parent fd8af8732d
commit 4485681a28
3 changed files with 107 additions and 48 deletions

View File

@@ -37,6 +37,7 @@ public class ModArith implements Deobfuscator
{ {
private ClassGroup group; private ClassGroup group;
private Execution execution; private Execution execution;
private Set<Field> obfuscatedFields = new HashSet<>();
private MultiValueMap<Field, Number> constantGetters = new MultiValueMap<>(), private MultiValueMap<Field, Number> constantGetters = new MultiValueMap<>(),
constantSetters = new MultiValueMap<>(); constantSetters = new MultiValueMap<>();
private List<Pair> pairs = new ArrayList<>(); private List<Pair> pairs = new ArrayList<>();
@@ -67,11 +68,12 @@ public class ModArith implements Deobfuscator
return l; return l;
} }
private boolean isFieldObfuscated(Execution e, Field field) private void findObfuscatedFields()
{ {
// find a direct big*field with no other fields involved // find a direct big*field with no other fields involved
obfuscatedFields.clear();
for (Frame f : e.processedFrames) for (Frame f : execution.processedFrames)
{ {
outer: outer:
for (InstructionContext ctx : f.getInstructions()) for (InstructionContext ctx : f.getInstructions())
@@ -80,48 +82,45 @@ public class ModArith implements Deobfuscator
{ {
SetFieldInstruction sfi = (SetFieldInstruction) ctx.getInstruction(); SetFieldInstruction sfi = (SetFieldInstruction) ctx.getInstruction();
if (sfi.getMyField() == field) InstructionContext pushedsfi = ctx.getPops().get(0).getPushed();
if (pushedsfi.getInstruction() instanceof LDC_W || pushedsfi.getInstruction() instanceof LDC2_W)
{ {
InstructionContext pushedsfi = ctx.getPops().get(0).getPushed(); PushConstantInstruction ldc = (PushConstantInstruction) pushedsfi.getInstruction();
if (pushedsfi.getInstruction() instanceof LDC_W || pushedsfi.getInstruction() instanceof LDC2_W) if (ldc.getConstant().getObject() instanceof Integer || ldc.getConstant().getObject() instanceof Long)
{ {
PushConstantInstruction ldc = (PushConstantInstruction) pushedsfi.getInstruction(); Number it = (Number) ldc.getConstant().getObject();
if (ldc.getConstant().getObject() instanceof Integer || ldc.getConstant().getObject() instanceof Long) if (DMath.isBig(it))
{ // field = constant
Number it = (Number) ldc.getConstant().getObject(); this.obfuscatedFields.add(sfi.getMyField());
if (DMath.isBig(it))
// field = constant
return true;
}
} }
else if (pushedsfi.getInstruction() instanceof IMul || pushedsfi.getInstruction() instanceof LMul) }
else if (pushedsfi.getInstruction() instanceof IMul || pushedsfi.getInstruction() instanceof LMul)
{
Instruction one = pushedsfi.getPops().get(0).getPushed().getInstruction();
Instruction two = pushedsfi.getPops().get(1).getPushed().getInstruction();
PushConstantInstruction pci = null;
Instruction other = null;
if (one instanceof LDC_W || one instanceof LDC2_W)
{ {
Instruction one = pushedsfi.getPops().get(0).getPushed().getInstruction(); pci = (PushConstantInstruction) one;
Instruction two = pushedsfi.getPops().get(1).getPushed().getInstruction(); other = two;
}
PushConstantInstruction pci = null; else if (two instanceof LDC_W || two instanceof LDC2_W)
Instruction other = null; {
if (one instanceof LDC_W || one instanceof LDC2_W) pci = (PushConstantInstruction) two;
other = one;
}
if (pci != null
&& !(other instanceof GetFieldInstruction))
{
if (pci.getConstant().getObject() instanceof Integer || pci.getConstant().getObject() instanceof Long)
{ {
pci = (PushConstantInstruction) one; Number i = (Number) pci.getConstant().getObject();
other = two; if (DMath.isBig(i))
} // field = constant * not other field
else if (two instanceof LDC_W || two instanceof LDC2_W) this.obfuscatedFields.add(sfi.getMyField());
{
pci = (PushConstantInstruction) two;
other = one;
}
if (pci != null
&& !(other instanceof GetFieldInstruction))
{
if (pci.getConstant().getObject() instanceof Integer || pci.getConstant().getObject() instanceof Long)
{
Number i = (Number) pci.getConstant().getObject();
if (DMath.isBig(i))
// field = constant * not other field
return true;
}
} }
} }
} }
@@ -152,7 +151,7 @@ public class ModArith implements Deobfuscator
continue; continue;
} }
if (other.getMyField() != null && other.getMyField() != field) if (other.getMyField() != null)
continue; continue;
if (!(pc.getConstant().getObject() instanceof Integer) && !(pc.getConstant().getObject() instanceof Long)) if (!(pc.getConstant().getObject() instanceof Integer) && !(pc.getConstant().getObject() instanceof Long))
@@ -164,8 +163,8 @@ public class ModArith implements Deobfuscator
try try
{ {
MultiplicationExpression expr = MultiplicationDeobfuscator.parseExpression(e, ctx, ctx.getInstruction().getClass()); MultiplicationExpression expr = MultiplicationDeobfuscator.parseExpression(execution, ctx, ctx.getInstruction().getClass());
if (expr.hasFieldOtherThan(field)) if (expr.hasFieldOtherThan(other.getMyField()))
continue; continue;
} }
catch (IllegalStateException ex) catch (IllegalStateException ex)
@@ -178,15 +177,13 @@ public class ModArith implements Deobfuscator
{ {
SetFieldInstruction sfi = (SetFieldInstruction) popped.getInstruction(); SetFieldInstruction sfi = (SetFieldInstruction) popped.getInstruction();
if (sfi.getMyField() != null && sfi.getMyField() != field) if (sfi.getMyField() != null)
continue; continue;
} }
return true; this.obfuscatedFields.add(other.getMyField());
} }
} }
return false;
} }
static class AssociatedConstant static class AssociatedConstant
@@ -537,7 +534,7 @@ public class ModArith implements Deobfuscator
removeDupes(noOther); removeDupes(noOther);
removeDupes(other); removeDupes(other);
if (!isFieldObfuscated(execution, f)) if (!this.obfuscatedFields.contains(f))
continue; continue;
// guess with constants not associated with other fields // guess with constants not associated with other fields
@@ -648,6 +645,7 @@ public class ModArith implements Deobfuscator
execution.populateInitialMethods(); execution.populateInitialMethods();
execution.run(); execution.run();
findObfuscatedFields();
findUses(); findUses();
findUses2(); findUses2();
reduce2(); reduce2();

View File

@@ -0,0 +1,61 @@
package net.runelite.deob.deobfuscators;
import java.io.File;
import java.io.IOException;
import net.runelite.asm.ClassGroup;
import net.runelite.deob.deobfuscators.arithmetic.ModArith;
import net.runelite.deob.deobfuscators.arithmetic.MultiplicationDeobfuscator;
import net.runelite.deob.deobfuscators.arithmetic.MultiplyOneDeobfuscator;
import net.runelite.deob.deobfuscators.arithmetic.MultiplyZeroDeobfuscator;
import net.runelite.deob.util.JarUtil;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
public class ModArithTest
{
private static final File GAMEPACK = new File("d:/rs/07/adamin.jar");
@Rule
public TemporaryFolder folder = new TemporaryFolder();
private ClassGroup group;
@Before
public void before() throws IOException
{
group = JarUtil.loadJar(GAMEPACK);
}
@After
public void after() throws IOException
{
JarUtil.saveJar(group, folder.newFile());
}
@Test
public void testRun()
{
ModArith mod = new ModArith();
mod.run(group);
int last = -1, cur;
while ((cur = mod.runOnce()) > 0)
{
new MultiplicationDeobfuscator().run(group);
new MultiplyOneDeobfuscator().run(group);
new MultiplyZeroDeobfuscator().run(group);
if (last == cur)
break;
last = cur;
}
mod.annotateEncryption();
}
}

View File

@@ -71,7 +71,7 @@ class TestClass2
} }
} }
public class ModArithTest public class SimpleModArithTest
{ {
private void checkConstants(ClassFile cf) private void checkConstants(ClassFile cf)
{ {