package org.saev.deob.trans.pred; import org.saev.deob.Application; import org.saev.deob.util.FieldID; import java.util.*; import org.apache.bcel.classfile.*; import org.apache.bcel.generic.*; import org.apache.bcel.util.*; public class PotentialFieldControlFinder implements ControlFinder { private static final boolean DEBUG = false; private Set fieldSet; private ArrayList potentialControlFields; private FieldID mainField = null; public PotentialFieldControlFinder(Application app) { ClassGen mainClass = app.getMainClass(); if(mainClass == null) { throw new RuntimeException("error: could not find main class"); } ConstantPoolGen pool = mainClass.getConstantPool(); for(int i = 0; i < pool.getSize(); i++) { Constant c = pool.getConstant(i); ConstantPool cp = pool.getConstantPool(); if(!(c instanceof ConstantFieldref)) { continue; } ConstantFieldref cfr = (ConstantFieldref)c; ConstantNameAndType cnat = (ConstantNameAndType) pool.getConstant(cfr.getNameAndTypeIndex()); if(cnat.getSignature(cp).equals("Z") && !cfr.getClass(cp).equals(mainClass.getClassName())) { if(potentialControlFields == null) { potentialControlFields = new ArrayList(); } potentialControlFields.add(new FieldID(cnat.getName(cp), cnat.getSignature(cp), cfr.getClass(cp))); } } if(DEBUG) { System.out.println("potentials = " + potentialControlFields); } for(Iterator classIt = app.getClasses().iterator(); classIt.hasNext(); ) { ClassGen cgen = classIt.next(); Method[] methods = cgen.getMethods(); final String className = cgen.getClassName(); final ConstantPoolGen cpg = cgen.getConstantPool(); for(int i = 0; i < methods.length; i++) { MethodGen mg = new MethodGen(methods[i], className, cpg); InstructionList il = mg.getInstructionList(); try { Iterator matchIt = new InstructionFinder(il).search("GETSTATIC IFEQ ((IINC ILOAD) | (ILOAD IFEQ ICONST GOTO ICONST)) PUTSTATIC", new InstructionFinder.CodeConstraint() { public boolean checkCode(InstructionHandle[] match) { for(int i = 0; i < match.length; i++) { if(!(match[i].getInstruction() instanceof FieldInstruction)) continue; FieldInstruction fi = (FieldInstruction) match[i].getInstruction(); FieldID fid = new FieldID(fi.getName(cpg), fi.getSignature(cpg), fi.getClassName(cpg)); if(potentialControlFields.contains(fid)) { mainField = fid; if(DEBUG) { System.out.println("main field = " + mainField); } return true; } } return false; } }); while(matchIt.hasNext()) { InstructionHandle[] match = matchIt.next(); FieldInstruction fi = (FieldInstruction) match[match.length - 1].getInstruction(); if(fieldSet == null) { fieldSet = new HashSet(); } FieldID fid = new FieldID(fi.getName(cpg), fi.getSignature(cpg), fi.getClassName(cpg)); fieldSet.add(fid); if(DEBUG) { System.out.println("field = " + fid); } } } catch (NullPointerException npe) {} } } if(mainField == null) { throw new RuntimeException("could not find control field"); } } public boolean containsField(FieldID fid) { return fieldSet.contains(fid); } public FieldID getControlField() { return mainField; } }