From 500037fc45e67af1d811a9fe72febd010efee467 Mon Sep 17 00:00:00 2001 From: Adam Date: Fri, 3 Jul 2015 18:54:54 -0400 Subject: [PATCH] Cleanup, prepare to detect more ob'd fields. --- .../ModularArithmeticDeobfuscation.java | 107 +++++++++++------- 1 file changed, 66 insertions(+), 41 deletions(-) diff --git a/src/main/java/info/sigterm/deob/deobfuscators/ModularArithmeticDeobfuscation.java b/src/main/java/info/sigterm/deob/deobfuscators/ModularArithmeticDeobfuscation.java index b28483c42d..92a56b47eb 100644 --- a/src/main/java/info/sigterm/deob/deobfuscators/ModularArithmeticDeobfuscation.java +++ b/src/main/java/info/sigterm/deob/deobfuscators/ModularArithmeticDeobfuscation.java @@ -31,6 +31,7 @@ import info.sigterm.deob.execution.StackContext; public class ModularArithmeticDeobfuscation { + /* private static String getMethodDesc(Method m) { return m.getMethods().getClassFile().getName() + "." + m.getName() + m.getNameAndType().getDescriptor().toString(); @@ -51,14 +52,18 @@ public class ModularArithmeticDeobfuscation } } } - } + }*/ - private static Field convertFieldFromPool(ClassGroup group, info.sigterm.deob.pool.Field field) + private Set obfuscatedFields; + private Map constants = new HashMap<>(); // getters + private Map setterConstants = new HashMap<>(); + + private Field convertFieldFromPool(ClassGroup group, info.sigterm.deob.pool.Field field) { return group.findClass(field.getClassEntry().getName()).findField(field.getNameAndType()); } - private static List checkDown(InstructionContext context) + private List checkDown(InstructionContext context) { List fields = new ArrayList<>(); @@ -78,7 +83,7 @@ public class ModularArithmeticDeobfuscation return fields; } - private static List checkUp(InstructionContext context) + private List checkUp(InstructionContext context) { List fields = new ArrayList<>(); @@ -102,7 +107,7 @@ public class ModularArithmeticDeobfuscation } /* check there are no other fields */ - private static boolean checkFields(ClassGroup group, Set obFields, info.sigterm.deob.pool.Field imulField, InstructionContext context) + private boolean checkFields(ClassGroup group, Set obFields, info.sigterm.deob.pool.Field imulField, InstructionContext context) { List fields = new ArrayList<>(); fields.addAll(checkUp(context)); @@ -127,7 +132,7 @@ public class ModularArithmeticDeobfuscation return true; } - private static Set getObfuscatedFields(Execution execution, ClassGroup group) + private Set getObfuscatedFields(Execution execution, ClassGroup group) { Set fields = new HashSet<>(); @@ -135,45 +140,42 @@ public class ModularArithmeticDeobfuscation { for (InstructionContext ctx : frame.getInstructions()) { - if (!(ctx.getInstruction() instanceof IMul)) - continue; - - Instruction one = ctx.getPops().get(0).getPushed().getInstruction(); - Instruction two = ctx.getPops().get(1).getPushed().getInstruction(); - - PushConstantInstruction pc = null; - GetFieldInstruction gf = null; - if (one instanceof PushConstantInstruction && two instanceof GetFieldInstruction) - { - pc = (PushConstantInstruction) one; - gf = (GetFieldInstruction) two; + if (ctx.getInstruction() instanceof IMul) + { + Instruction one = ctx.getPops().get(0).getPushed().getInstruction(); + Instruction two = ctx.getPops().get(1).getPushed().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; + + // get Field from pool Field + info.sigterm.deob.pool.Field field = gf.getField(); + Field f = group.findClass(field.getClassEntry().getName()).findField(field.getNameAndType()); + + assert f != null; + + fields.add(f); } - else if (two instanceof PushConstantInstruction && one instanceof GetFieldInstruction) - { - pc = (PushConstantInstruction) two; - gf = (GetFieldInstruction) one; - } - - if (pc == null) - continue; - - // get Field from pool Field - info.sigterm.deob.pool.Field field = gf.getField(); - Field f = group.findClass(field.getClassEntry().getName()).findField(field.getNameAndType()); - - assert f != null; - - fields.add(f); } } return fields; } - private static Set obfuscatedFields; - private static Map constants = new HashMap<>(); // getters - - private static void detectSetters(Execution execution, ClassGroup group, InstructionContext ctx) + private void detectSetters(Execution execution, ClassGroup group, InstructionContext ctx) { if (!(ctx.getInstruction() instanceof SetFieldInstruction)) return; @@ -206,10 +208,32 @@ public class ModularArithmeticDeobfuscation if (!checkFields(group, obfuscatedFields, sf.getField(), value.getPushed())) return; - System.out.println("Setter " + sf.getField().getClassEntry().getName() + "." + sf.getField().getNameAndType().getName() + " -> " + pc.getConstant().toString()); + //System.out.println("Setter " + sf.getField().getClassEntry().getName() + "." + sf.getField().getNameAndType().getName() + " -> " + pc.getConstant().toString()); + + int constant = Integer.parseInt(pc.getConstant().toString()); + try + { + modInverse(constant); + } + catch (ArithmeticException ex) + { + System.err.println("Constant " + constant + " passed setter logic tests but is not inversable"); + //printWhatCalls(execution, frame.getMethod(), 0); + return; // if the constant isn't inversable then it can't be the right one + } + + Field field = convertFieldFromPool(group, sf.getField()); + + Integer old = setterConstants.get(field); + int newi = constant; + + if (old != null && (int) old != newi) + System.err.println("Setter For " + sf.getField().getNameAndType().getName() + " in " + sf.getField().getClassEntry().getName() + " constant " + pc.getConstant().toString() + " mismatch on " + old); + + setterConstants.put(field, newi); } - private static void detectGetters(Execution execution, ClassGroup group, InstructionContext ctx) + private void detectGetters(Execution execution, ClassGroup group, InstructionContext ctx) { if (!(ctx.getInstruction() instanceof IMul)) return; @@ -286,6 +310,7 @@ public class ModularArithmeticDeobfuscation detectSetters(execution, group, ctx); } } + System.out.println("Found " + constants.size() + " constants"); for (Entry entry : constants.entrySet()) { @@ -324,7 +349,7 @@ public class ModularArithmeticDeobfuscation private static long modInverse(long val) { - return modInverse(BigInteger.valueOf(val), 64).intValue(); + return modInverse(BigInteger.valueOf(val), 64).longValue(); } public void run(ClassGroup group)