Thinking on modinverse

This commit is contained in:
Adam
2015-06-23 19:29:32 -04:00
parent 815b2e2931
commit 85fc94dd57
13 changed files with 219 additions and 5 deletions

View File

@@ -2,6 +2,7 @@ package info.sigterm.deob;
import info.sigterm.deob.deobfuscators.IllegalStateExceptions;
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.UnusedMethods;
@@ -57,6 +58,8 @@ public class Deob
// remove jump obfuscation
new Jumps().run(group);
new ModularArithmeticDeobfuscation().run(group);
saveJar(group, args[1]);

View File

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

View File

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

View File

@@ -3,17 +3,19 @@ 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.GetFieldInstruction;
import info.sigterm.deob.execution.Frame;
import info.sigterm.deob.execution.InstructionContext;
import info.sigterm.deob.execution.Stack;
import info.sigterm.deob.execution.StackContext;
import info.sigterm.deob.execution.Type;
import info.sigterm.deob.pool.Field;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
public class GetField extends Instruction
public class GetField extends Instruction implements GetFieldInstruction
{
private Field field;
@@ -47,4 +49,10 @@ public class GetField extends Instruction
frame.addInstructionContext(ins);
}
@Override
public Field getField()
{
return field;
}
}

View File

@@ -4,6 +4,7 @@ import info.sigterm.deob.ClassFile;
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.GetFieldInstruction;
import info.sigterm.deob.execution.Frame;
import info.sigterm.deob.execution.InstructionContext;
import info.sigterm.deob.execution.Stack;
@@ -17,7 +18,7 @@ import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
public class GetStatic extends Instruction
public class GetStatic extends Instruction implements GetFieldInstruction
{
private Field field;
@@ -65,4 +66,10 @@ public class GetStatic extends Instruction
f.addReference(this);
}
@Override
public Field getField()
{
return field;
}
}

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.PushConstantInstruction;
import info.sigterm.deob.execution.Frame;
import info.sigterm.deob.execution.InstructionContext;
import info.sigterm.deob.execution.Stack;
@@ -13,7 +14,7 @@ import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
public class LDC extends Instruction
public class LDC extends Instruction implements PushConstantInstruction
{
private PoolEntry value;
@@ -56,4 +57,10 @@ public class LDC extends Instruction
frame.addInstructionContext(ins);
}
@Override
public PoolEntry getConstant()
{
return value;
}
}

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.PushConstantInstruction;
import info.sigterm.deob.execution.Frame;
import info.sigterm.deob.execution.InstructionContext;
import info.sigterm.deob.execution.Stack;
@@ -13,7 +14,7 @@ import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
public class LDC2_W extends Instruction
public class LDC2_W extends Instruction implements PushConstantInstruction
{
private PoolEntry value;
@@ -44,4 +45,10 @@ public class LDC2_W extends Instruction
frame.addInstructionContext(ins);
}
@Override
public PoolEntry getConstant()
{
return value;
}
}

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.PushConstantInstruction;
import info.sigterm.deob.execution.Frame;
import info.sigterm.deob.execution.InstructionContext;
import info.sigterm.deob.execution.Stack;
@@ -13,7 +14,7 @@ import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
public class LDC_W extends Instruction
public class LDC_W extends Instruction implements PushConstantInstruction
{
private PoolEntry value;
@@ -59,4 +60,10 @@ public class LDC_W extends Instruction
{
return "ldc_w " + value;
}
@Override
public PoolEntry getConstant()
{
return value;
}
}

View File

@@ -0,0 +1,135 @@
package info.sigterm.deob.deobfuscators;
import java.math.BigInteger;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import info.sigterm.deob.ClassFile;
import info.sigterm.deob.ClassGroup;
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.GetFieldInstruction;
import info.sigterm.deob.attributes.code.instruction.types.PushConstantInstruction;
import info.sigterm.deob.attributes.code.instructions.IMul;
import info.sigterm.deob.execution.Execution;
import info.sigterm.deob.execution.Frame;
import info.sigterm.deob.execution.InstructionContext;
import info.sigterm.deob.execution.StackContext;
import info.sigterm.deob.pool.Field;
public class ModularArithmeticDeobfuscation
{
/* try to identify:
*
lvt = field * constant
getfield dy/e I
ldc 1512989863
imul
istore_1
or
field * constant compare+conditional jump
getstatic client/c I
ldc -2061786953
imul
bipush 30
if_icmpeq LABEL0x86
or
(constant * field) - lvt
ldc 1512989863
getstatic client/cq Ldy;
getfield dy/e I
imul
iload_1
isub
field * constant where result is:
stored in lvt
compared with something
any other operation with lvt
*/
private void run(Execution execution, ClassGroup group)
{
Map<Field, Integer> constants = new HashMap<>();
for (Frame frame : execution.processedFrames)
{
for (InstructionContext ctx : frame.getInstructions())
{
// I think it is easier to detect the getters instead of the setters,
// and then calculate the setters.
if (!(ctx.getInstruction() instanceof IMul))
continue;
// check for push constant and for get field instruction
Instruction one = ctx.getPops().get(0).getIns().getInstruction();
Instruction two = ctx.getPops().get(1).getIns().getInstruction();
PushConstantInstruction pc = null;
GetFieldInstruction gf = null;
if (one instanceof PushConstantInstruction && two instanceof GetFieldInstruction)
{
pc = (PushConstantInstruction) one;
gf = (GetFieldInstruction) two;
}
else if (two instanceof PushConstantInstruction && one instanceof GetFieldInstruction)
{
pc = (PushConstantInstruction) two;
gf = (GetFieldInstruction) one;
}
if (pc == null)
continue;
try
{
int constant = Integer.parseInt(pc.getConstant().toString());
modInverse(constant);
}
catch (ArithmeticException ex)
{
continue;
}
Integer old = constants.get(gf.getField());
int newi = Integer.parseInt(pc.getConstant().toString());
if (old != null && (int) old != newi)
System.out.println("For " + gf.getField().getNameAndType().getName() + " in " + gf.getField().getClassEntry().getName() + " constant " + pc.getConstant().toString() + " mismatch on " + old);
constants.put(gf.getField(), newi);
// see what the result is used for?
}
}
}
private static BigInteger modInverse(BigInteger val, int bits)
{
BigInteger shift = BigInteger.ONE.shiftLeft(bits);
return val.modInverse(shift);
}
private static int modInverse(int val)
{
return modInverse(BigInteger.valueOf(val), 32).intValue();
}
private static long modInverse(long val)
{
return modInverse(BigInteger.valueOf(val), 64).intValue();
}
public void run(ClassGroup group)
{
Execution execution = new Execution(group);
execution.run();
run(execution, group);
}
}

View File

@@ -41,6 +41,12 @@ public class Class extends PoolEntry
Class c = (Class) other;
return name.equals(c.name);
}
@Override
public int hashCode()
{
return name.hashCode();
}
public java.lang.String getName()
{

View File

@@ -45,6 +45,12 @@ public class Field extends PoolEntry
Field f = (Field) other;
return clazz.equals(f.clazz) && nat.equals(f.nat);
}
@Override
public int hashCode()
{
return clazz.hashCode() ^ nat.hashCode();
}
public Class getClassEntry()
{

View File

@@ -36,6 +36,12 @@ public class Integer extends PoolEntry
Integer i = (Integer) other;
return value == i.value;
}
@Override
public java.lang.String toString()
{
return "" + value;
}
@Override
public Type getTypeClass()

View File

@@ -75,6 +75,12 @@ public class NameAndType extends PoolEntry
NameAndType nat = (NameAndType) other;
return name.equals(nat.name) && Objects.equals(signature, nat.signature) && Objects.equals(type, nat.type);
}
@Override
public int hashCode()
{
return name.hashCode();
}
public java.lang.String getName()
{