All pastes #85428 Raw Edit

Unnamed

public text v1 · immutable
·published 2006-07-11 22:47 UTC
rendered paste body
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<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;
	}
}