more arith deob

This commit is contained in:
Adam
2015-07-02 17:07:57 -04:00
parent e5a8ff8268
commit 7b0776d1ec
9 changed files with 107 additions and 12 deletions

View File

@@ -5,6 +5,7 @@ import info.sigterm.deob.deobfuscators.Jumps;
import info.sigterm.deob.deobfuscators.ModularArithmeticDeobfuscation;
import info.sigterm.deob.deobfuscators.RuntimeExceptions;
import info.sigterm.deob.deobfuscators.UnusedBlocks;
import info.sigterm.deob.deobfuscators.UnusedFields;
import info.sigterm.deob.deobfuscators.UnusedMethods;
import info.sigterm.deob.deobfuscators.UnusedParameters;
import info.sigterm.deob.execution.Execution;
@@ -59,6 +60,8 @@ public class Deob
// remove jump obfuscation
new Jumps().run(group);
new UnusedFields().run(group);
new ModularArithmeticDeobfuscation().run(group);
saveJar(group, args[1]);

View File

@@ -0,0 +1,6 @@
package info.sigterm.deob.attributes.code.instruction.types;
public interface ComparisonInstruction
{
}

View File

@@ -0,0 +1,8 @@
package info.sigterm.deob.attributes.code.instruction.types;
import info.sigterm.deob.pool.Field;
public interface FieldInstruction
{
public Field getField();
}

View File

@@ -1,8 +1,5 @@
package info.sigterm.deob.attributes.code.instruction.types;
import info.sigterm.deob.pool.Field;
public interface GetFieldInstruction
public interface GetFieldInstruction extends FieldInstruction
{
public Field getField();
}

View File

@@ -1,8 +1,5 @@
package info.sigterm.deob.attributes.code.instruction.types;
import info.sigterm.deob.pool.Field;
public interface SetFieldInstruction
public interface SetFieldInstruction extends FieldInstruction
{
public Field getField();
}

View File

@@ -3,6 +3,7 @@ package info.sigterm.deob.attributes.code.instructions;
import info.sigterm.deob.attributes.code.Instruction;
import info.sigterm.deob.attributes.code.InstructionType;
import info.sigterm.deob.attributes.code.Instructions;
import info.sigterm.deob.attributes.code.instruction.types.ComparisonInstruction;
import info.sigterm.deob.attributes.code.instruction.types.JumpingInstruction;
import info.sigterm.deob.execution.Frame;
import info.sigterm.deob.execution.InstructionContext;
@@ -13,7 +14,7 @@ import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
public class If extends Instruction implements JumpingInstruction
public class If extends Instruction implements JumpingInstruction, ComparisonInstruction
{
private Instruction to;
private short offset;

View File

@@ -3,6 +3,7 @@ package info.sigterm.deob.attributes.code.instructions;
import info.sigterm.deob.attributes.code.Instruction;
import info.sigterm.deob.attributes.code.InstructionType;
import info.sigterm.deob.attributes.code.Instructions;
import info.sigterm.deob.attributes.code.instruction.types.ComparisonInstruction;
import info.sigterm.deob.attributes.code.instruction.types.JumpingInstruction;
import info.sigterm.deob.execution.Frame;
import info.sigterm.deob.execution.InstructionContext;
@@ -13,7 +14,7 @@ import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
public class If0 extends Instruction implements JumpingInstruction
public class If0 extends Instruction implements JumpingInstruction, ComparisonInstruction
{
private Instruction to;
private short offset;

View File

@@ -13,6 +13,7 @@ import info.sigterm.deob.Method;
import info.sigterm.deob.attributes.Code;
import info.sigterm.deob.attributes.code.Instruction;
import info.sigterm.deob.attributes.code.Instructions;
import info.sigterm.deob.attributes.code.instruction.types.ComparisonInstruction;
import info.sigterm.deob.attributes.code.instruction.types.GetFieldInstruction;
import info.sigterm.deob.attributes.code.instruction.types.InvokeInstruction;
import info.sigterm.deob.attributes.code.instruction.types.LVTInstruction;
@@ -48,7 +49,7 @@ public class ModularArithmeticDeobfuscation
}
}
// check for popping instruction to be a LVT get
// lvt = field * constant
private static boolean checkLVTGet(InstructionContext popCtx)
{
if (!(popCtx.getInstruction() instanceof LVTInstruction))
@@ -70,10 +71,32 @@ public class ModularArithmeticDeobfuscation
return true;
}
// lvt comparison field * constant
private static boolean checkCompare(InstructionContext popCtx)
{
if (!(popCtx.getInstruction() instanceof ComparisonInstruction))
return false;
// make sure comparison is against lvt
List<StackContext> pops = popCtx.getPops(); // things popCtx popped
for (StackContext ctx : pops) // one of these is the imul
{
InstructionContext pushCtx = ctx.getPushed(); // instruction which pushed this here
if (pushCtx.getInstruction() instanceof LVTInstruction)
{
LVTInstruction lvt = (LVTInstruction) pushCtx.getInstruction();
return !lvt.store(); // check its a get
}
}
return false;
}
private static boolean checkRules(InstructionContext popCtx)
{
return checkLVTGet(popCtx)
|| checkInvoke(popCtx);
|| checkInvoke(popCtx)
|| checkCompare(popCtx);
}
/* try to identify:

View File

@@ -0,0 +1,59 @@
package info.sigterm.deob.deobfuscators;
import java.util.ArrayList;
import info.sigterm.deob.ClassFile;
import info.sigterm.deob.ClassGroup;
import info.sigterm.deob.Field;
import info.sigterm.deob.Method;
import info.sigterm.deob.attributes.Code;
import info.sigterm.deob.attributes.code.Instruction;
import info.sigterm.deob.attributes.code.instruction.types.FieldInstruction;
public class UnusedFields
{
private static boolean isUnused(ClassGroup group, Field field)
{
for (ClassFile cf : group.getClasses())
for (Method m : cf.getMethods().getMethods())
{
Code code = m.getCode();
if (code == null)
continue;
for (Instruction ins : code.getInstructions().getInstructions())
{
if (ins instanceof FieldInstruction)
{
FieldInstruction fi = (FieldInstruction) ins;
info.sigterm.deob.pool.Field ff = fi.getField();
if (ff.getClassEntry().getName().equals(field.getFields().getClassFile().getName()))
{
if (ff.getNameAndType().getName().equals(field.getName()))
{
return false;
}
}
}
}
}
return true;
}
public void run(ClassGroup group)
{
int count = 0;
for (ClassFile cf : group.getClasses())
for (Field f : new ArrayList<>(cf.getFields().getFields()))
{
if (isUnused(group, f))
{
cf.getFields().getFields().remove(f);
++count;
}
}
System.out.println("Removed " + count + " unused fields");
}
}