modarith test
This commit is contained in:
@@ -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();
|
||||||
|
|||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -71,7 +71,7 @@ class TestClass2
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ModArithTest
|
public class SimpleModArithTest
|
||||||
{
|
{
|
||||||
private void checkConstants(ClassFile cf)
|
private void checkConstants(ClassFile cf)
|
||||||
{
|
{
|
||||||
Reference in New Issue
Block a user