use of soot.ValueBox in project soot by Sable.
the class DexDefUseAnalysis method initialize.
protected void initialize() {
int lastLocalNumber = 0;
for (Local l : body.getLocals()) {
localToNumber.put(l, lastLocalNumber++);
}
localToDefsBits = new BitSet[body.getLocalCount()];
localToUsesBits = new BitSet[body.getLocalCount()];
unitList = new ArrayList<>(body.getUnits());
for (int i = 0; i < unitList.size(); i++) {
Unit u = unitList.get(i);
// Record the definitions
if (u instanceof DefinitionStmt) {
Value val = ((DefinitionStmt) u).getLeftOp();
if (val instanceof Local) {
final int localIdx = localToNumber.get(val);
BitSet bs = localToDefsBits[localIdx];
if (bs == null) {
bs = new BitSet();
localToDefsBits[localIdx] = bs;
}
bs.set(i);
}
}
// Record the uses
for (ValueBox vb : u.getUseBoxes()) {
Value val = vb.getValue();
if (val instanceof Local) {
final int localIdx = localToNumber.get(val);
BitSet bs = localToUsesBits[localIdx];
if (bs == null) {
bs = new BitSet();
localToUsesBits[localIdx] = bs;
}
bs.set(i);
}
}
}
}
use of soot.ValueBox in project soot by Sable.
the class ShortcutIfGenerator method inASTStatementSequenceNode.
public void inASTStatementSequenceNode(ASTStatementSequenceNode node) {
for (AugmentedStmt as : node.getStatements()) {
Stmt s = as.get_Stmt();
if (!(s instanceof DefinitionStmt))
continue;
DefinitionStmt ds = (DefinitionStmt) s;
ValueBox rightBox = ds.getRightOpBox();
Value right = rightBox.getValue();
/*
* Going to match int i = (int) z where z is a boolean
* or int i= z i.e. without the cast
*/
// right type should contain the expected type on the left
// in the case of the cast this is the cast type else just get the left type
Type rightType = null;
ValueBox OpBox = null;
if (right instanceof CastExpr) {
rightType = ((CastExpr) right).getCastType();
OpBox = ((CastExpr) right).getOpBox();
} else {
rightType = ds.getLeftOp().getType();
OpBox = rightBox;
}
if (!(rightType instanceof IntType)) {
continue;
}
Value Op = OpBox.getValue();
if (!(Op.getType() instanceof BooleanType)) {
continue;
}
// ready for the switch
ImmediateBox trueBox = new ImmediateBox(IntConstant.v(1));
ImmediateBox falseBox = new ImmediateBox(IntConstant.v(0));
DShortcutIf shortcut = new DShortcutIf(OpBox, trueBox, falseBox);
if (DEBUG)
System.out.println("created: " + shortcut);
rightBox.setValue(shortcut);
}
}
use of soot.ValueBox in project soot by Sable.
the class BuildIntermediateAppClasses method internalTransform.
protected void internalTransform(String phaseName, Map<String, String> options) {
if (output) {
out.println("Building Intermediate Classes...");
}
BodyBuilder.retrieveAllBodies();
// iterate through application classes, build intermediate classes
Iterator<SootClass> it = Scene.v().getApplicationClasses().snapshotIterator();
while (it.hasNext()) {
List<SootMethod> initMethodsToRewrite = new ArrayList<>();
Map<String, SootMethod> methodsToAdd = new HashMap<>();
SootClass sc = it.next();
SootClass originalSuperclass = sc.getSuperclass();
if (output) {
out.println("Processing " + sc.getName() + " with super " + originalSuperclass.getName());
}
Iterator<SootMethod> methodIterator = sc.methodIterator();
while (methodIterator.hasNext()) {
SootMethod method = methodIterator.next();
if (!method.isConcrete()) {
continue;
}
try {
method.getActiveBody();
} catch (Exception e) {
if (method.retrieveActiveBody() == null)
throw new RuntimeException(method.getSignature() + " has no body. This was not expected dude.");
}
String subSig = method.getSubSignature();
if (subSig.equals("void main(java.lang.String[])") && method.isPublic() && method.isStatic()) {
// skip the main method - it needs to be named 'main'
continue;
} else if (subSig.indexOf("init>(") > 0) {
if (subSig.startsWith("void <init>(")) {
initMethodsToRewrite.add(method);
}
// skip constructors, just add for rewriting at the end
continue;
} else {
Scene.v().releaseActiveHierarchy();
findAccessibleInSuperClassesBySubSig(sc, subSig).ifPresent(m -> methodsToAdd.put(subSig, m));
}
}
if (methodsToAdd.size() > 0) {
final String fullName = ClassRenamer.v().getNewName(ClassRenamer.getPackageName(sc.getName()), null);
if (output) {
out.println("\tBuilding " + fullName);
}
// make non-final soot class
SootClass mediatingClass = new SootClass(fullName, sc.getModifiers() & (~Modifier.FINAL));
Main.IntermediateAppClasses.add(mediatingClass);
mediatingClass.setSuperclass(originalSuperclass);
Scene.v().addClass(mediatingClass);
mediatingClass.setApplicationClass();
mediatingClass.setInScene(true);
ThisRef thisRef = new ThisRef(mediatingClass.getType());
for (String subSig : methodsToAdd.keySet()) {
SootMethod originalSuperclassMethod = methodsToAdd.get(subSig);
List<Type> paramTypes = originalSuperclassMethod.getParameterTypes();
Type returnType = originalSuperclassMethod.getReturnType();
List<SootClass> exceptions = originalSuperclassMethod.getExceptions();
int modifiers = originalSuperclassMethod.getModifiers() & ~Modifier.ABSTRACT & ~Modifier.NATIVE;
SootMethod newMethod;
{
// build new junk method to call original method
String newMethodName = MethodRenamer.v().getNewName();
newMethod = Scene.v().makeSootMethod(newMethodName, paramTypes, returnType, modifiers, exceptions);
mediatingClass.addMethod(newMethod);
Body body = Jimple.v().newBody(newMethod);
newMethod.setActiveBody(body);
Chain<Local> locals = body.getLocals();
PatchingChain<Unit> units = body.getUnits();
BodyBuilder.buildThisLocal(units, thisRef, locals);
BodyBuilder.buildParameterLocals(units, locals, paramTypes);
if (returnType instanceof VoidType) {
units.add(Jimple.v().newReturnVoidStmt());
} else if (returnType instanceof PrimType) {
units.add(Jimple.v().newReturnStmt(IntConstant.v(0)));
} else {
units.add(Jimple.v().newReturnStmt(NullConstant.v()));
}
newmethods++;
}
// end build new junk method to call original method
{
// build copy of old method
newMethod = Scene.v().makeSootMethod(originalSuperclassMethod.getName(), paramTypes, returnType, modifiers, exceptions);
mediatingClass.addMethod(newMethod);
Body body = Jimple.v().newBody(newMethod);
newMethod.setActiveBody(body);
Chain<Local> locals = body.getLocals();
PatchingChain<Unit> units = body.getUnits();
Local ths = BodyBuilder.buildThisLocal(units, thisRef, locals);
List<Local> args = BodyBuilder.buildParameterLocals(units, locals, paramTypes);
SootMethodRef superclassMethodRef = originalSuperclassMethod.makeRef();
if (returnType instanceof VoidType) {
units.add(Jimple.v().newInvokeStmt(Jimple.v().newSpecialInvokeExpr(ths, superclassMethodRef, args)));
units.add(Jimple.v().newReturnVoidStmt());
} else {
Local loc = Jimple.v().newLocal("retValue", returnType);
body.getLocals().add(loc);
units.add(Jimple.v().newAssignStmt(loc, Jimple.v().newSpecialInvokeExpr(ths, superclassMethodRef, args)));
units.add(Jimple.v().newReturnStmt(loc));
}
newmethods++;
}
// end build copy of old method
}
sc.setSuperclass(mediatingClass);
// rewrite class init methods to call the proper superclass inits
int i = initMethodsToRewrite.size();
while (i-- > 0) {
SootMethod im = initMethodsToRewrite.remove(i);
Body b = im.getActiveBody();
Local thisLocal = b.getThisLocal();
Iterator<Unit> uIt = b.getUnits().snapshotIterator();
while (uIt.hasNext()) {
for (ValueBox valueBox : uIt.next().getUseBoxes()) {
Value v = valueBox.getValue();
if (v instanceof SpecialInvokeExpr) {
SpecialInvokeExpr sie = (SpecialInvokeExpr) v;
SootMethodRef smr = sie.getMethodRef();
if (sie.getBase().equivTo(thisLocal) && smr.declaringClass().getName().equals(originalSuperclass.getName()) && smr.getSubSignature().getString().startsWith("void " + constructorName)) {
SootMethod newSuperInit;
if (!mediatingClass.declaresMethod(constructorName, smr.parameterTypes())) {
List<Type> paramTypes = smr.parameterTypes();
newSuperInit = Scene.v().makeSootMethod(constructorName, paramTypes, smr.returnType());
mediatingClass.addMethod(newSuperInit);
JimpleBody body = Jimple.v().newBody(newSuperInit);
newSuperInit.setActiveBody(body);
PatchingChain<Unit> initUnits = body.getUnits();
Collection<Local> locals = body.getLocals();
Local ths = BodyBuilder.buildThisLocal(initUnits, thisRef, locals);
List<Local> args = BodyBuilder.buildParameterLocals(initUnits, locals, paramTypes);
initUnits.add(Jimple.v().newInvokeStmt(Jimple.v().newSpecialInvokeExpr(ths, smr, args)));
initUnits.add(Jimple.v().newReturnVoidStmt());
} else {
newSuperInit = mediatingClass.getMethod(constructorName, smr.parameterTypes());
}
sie.setMethodRef(newSuperInit.makeRef());
}
}
}
}
}
// end of rewrite class init methods to call the proper superclass inits
}
}
newclasses = Main.IntermediateAppClasses.size();
Scene.v().releaseActiveHierarchy();
Scene.v().getActiveHierarchy();
Scene.v().setFastHierarchy(new FastHierarchy());
}
use of soot.ValueBox in project soot by Sable.
the class CollectConstants method internalTransform.
protected void internalTransform(String phaseName, Map<String, String> options) {
if (output) {
out.println("Collecting Constant Data");
}
BodyBuilder.retrieveAllNames();
Chain<SootClass> appClasses = Scene.v().getApplicationClasses();
for (SootClass sc : appClasses) {
for (SootMethod m : sc.getMethods()) {
if (!m.hasActiveBody() || m.getName().contains(SootMethod.staticInitializerName)) {
continue;
}
for (ValueBox useBox : m.getActiveBody().getUseBoxes()) {
Value v = useBox.getValue();
if (v instanceof Constant) {
Constant constant = (Constant) v;
Type type = constant.getType();
List<Constant> constants = typesToValues.computeIfAbsent(type, t -> new ArrayList<>());
if (!constants.contains(constant)) {
this.constants++;
constants.add(constant);
}
}
}
}
}
int count = 0;
String name = "newConstantJbcoName";
SootClass[] classes = appClasses.toArray(new SootClass[appClasses.size()]);
for (Type type : typesToValues.keySet()) {
if (type instanceof NullType) {
// type = RefType.v("java.lang.Object");
continue;
}
for (Constant constant : typesToValues.get(type)) {
name += "_";
SootClass randomClass;
do {
randomClass = classes[Rand.getInt(classes.length)];
} while (!isSuitableClassToAddFieldConstant(randomClass, constant));
SootField newField = Scene.v().makeSootField(FieldRenamer.getNewName(), type, Modifier.STATIC ^ Modifier.PUBLIC);
randomClass.addField(newField);
FieldRenamer.sootFieldsRenamed.add(newField);
FieldRenamer.addOldAndNewName(name, newField.getName());
constantsToFields.put(constant, newField);
addInitializingValue(randomClass, newField, constant);
FieldRenamer.addOldAndNewName("addedConstant" + count++, newField.getName());
}
}
updatedConstants += count;
}
use of soot.ValueBox in project soot by Sable.
the class FieldRenamer method internalTransform.
protected void internalTransform(String phaseName, Map<String, String> options) {
if (output) {
if (rename_fields) {
out.println("Transforming Field Names and Adding Opaque Predicates...");
} else {
out.println("Adding Opaques...");
}
}
RefType boolRef = Scene.v().getRefType(booleanClassName);
BodyBuilder.retrieveAllBodies();
BodyBuilder.retrieveAllNames();
for (SootClass sc : Scene.v().getApplicationClasses()) {
String className = sc.getName();
if (className.contains(".")) {
className = className.substring(className.lastIndexOf(".") + 1, className.length());
}
oldToNewFieldNames.put(className, className);
if (rename_fields) {
if (output) {
out.println("\tClassName: " + className);
}
// rename all the fields in the class
for (SootField f : sc.getFields()) {
int weight = soot.jbco.Main.getWeight(phaseName, f.getName());
if (weight > 0) {
renameField(className, f);
}
}
}
// skip interfaces - they can only hold final fields
if (sc.isInterface()) {
continue;
}
// add one opaq predicate for true and one for false to each class
String bool = "opPred1";
Type t = Rand.getInt() % 2 == 0 ? BooleanType.v() : boolRef;
while (oldToNewFieldNames.containsKey(bool)) {
bool += "_";
}
SootField f = Scene.v().makeSootField(bool, t, Modifier.PUBLIC | Modifier.STATIC);
renameField(className, f);
opaquePreds1ByClass.put(sc, f);
sc.addField(f);
setBooleanTo(sc, f, true);
bool = "opPred2";
t = t == BooleanType.v() ? boolRef : BooleanType.v();
while (oldToNewFieldNames.containsKey(bool)) {
bool += "_";
}
f = Scene.v().makeSootField(bool, t, Modifier.PUBLIC | Modifier.STATIC);
renameField(className, f);
opaquePreds2ByClass.put(sc, f);
sc.addField(f);
if (t == boolRef) {
setBooleanTo(sc, f, false);
}
}
buildOpaquePairings();
if (!rename_fields) {
return;
}
if (output) {
out.println("\r\tUpdating field references in bytecode");
}
for (SootClass sc : Scene.v().getApplicationClasses()) {
for (SootMethod m : sc.getMethods()) {
if (!m.isConcrete()) {
continue;
}
if (!m.hasActiveBody()) {
m.retrieveActiveBody();
}
for (Unit unit : m.getActiveBody().getUnits()) {
for (ValueBox box : unit.getUseAndDefBoxes()) {
Value value = box.getValue();
if (value instanceof FieldRef) {
FieldRef fieldRef = (FieldRef) value;
SootFieldRef sootFieldRef = fieldRef.getFieldRef();
if (sootFieldRef.declaringClass().isLibraryClass()) {
continue;
}
String oldName = sootFieldRef.name();
String fullName = sootFieldRef.declaringClass().getName() + '.' + oldName;
String newName = oldToNewFieldNames.get(oldName);
if (newName == null || namesToNotRename.contains(fullName)) {
continue;
}
if (newName.equals(oldName)) {
System.out.println("Strange.. Should not find a field with the same old and new name.");
}
sootFieldRef = Scene.v().makeFieldRef(sootFieldRef.declaringClass(), newName, sootFieldRef.type(), sootFieldRef.isStatic());
fieldRef.setFieldRef(sootFieldRef);
try {
sootFieldRef.resolve();
} catch (Exception e) {
System.err.println("********ERROR Updating " + sootFieldRef.name() + " to " + newName);
System.err.println("Fields of " + sootFieldRef.declaringClass().getName() + ": " + sootFieldRef.declaringClass().getFields());
throw new RuntimeException(e);
}
}
}
}
}
}
}
Aggregations