rendered paste bodypackage 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<FieldID> fieldSet;
private ArrayList<FieldID> 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<FieldID>();
}
potentialControlFields.add(new FieldID(cnat.getName(cp), cnat.getSignature(cp), cfr.getClass(cp)));
}
}
if(DEBUG) {
System.out.println("potentials = " + potentialControlFields);
}
for(Iterator<ClassGen> 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<InstructionHandle[]> 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>();
}
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;
}
}