use of soot.Body in project soot by Sable.
the class CFGViewer method internalTransform.
// particular
// methods to print, this is a map
// from method name to the class
// name declaring the method.
protected void internalTransform(Body b, String phaseName, Map<String, String> options) {
initialize(options);
SootMethod meth = b.getMethod();
if ((methodsToPrint == null) || (meth.getDeclaringClass().getName() == methodsToPrint.get(meth.getName()))) {
Body body = ir.getBody((JimpleBody) b);
print_cfg(body);
}
}
use of soot.Body in project soot by Sable.
the class DexMethod method createMethodSource.
protected MethodSource createMethodSource(final Method method) {
return new MethodSource() {
@Override
public Body getBody(SootMethod m, String phaseName) {
Body b = Jimple.v().newBody(m);
try {
// add the body of this code item
DexBody dexBody = new DexBody(dexFile, method, declaringClass.getType());
dexBody.jimplify(b, m);
} catch (InvalidDalvikBytecodeException e) {
String msg = "Warning: Invalid bytecode in method " + m + ": " + e;
logger.debug("" + msg);
Util.emptyBody(b);
Util.addExceptionAfterUnit(b, "java.lang.RuntimeException", b.getUnits().getLast(), "Soot has detected that this method contains invalid Dalvik bytecode which would have throw an exception at runtime. [" + msg + "]");
TypeAssigner.v().transform(b);
}
m.setActiveBody(b);
return m.getActiveBody();
}
};
}
use of soot.Body in project soot by Sable.
the class RemoveEmptyBodyDefaultConstructor method checkAndRemoveDefault.
public static void checkAndRemoveDefault(SootClass s) {
debug("\n\nRemoveEmptyBodyDefaultConstructor----" + s.getName());
List methods = s.getMethods();
Iterator it = methods.iterator();
List<SootMethod> constructors = new ArrayList<SootMethod>();
while (it.hasNext()) {
SootMethod method = (SootMethod) it.next();
debug("method name is" + method.getName());
if (method.getName().indexOf("<init>") > -1) {
// constructor add to constructor list
constructors.add(method);
}
}
if (constructors.size() != 1) {
// cant do anything since there are more than one constructors
debug("class has more than one constructors cant do anything");
return;
}
// only one constructor check its default (no arguments)
SootMethod constructor = constructors.get(0);
if (constructor.getParameterCount() != 0) {
// can only deal with default constructors
debug("constructor is not the default constructor");
return;
}
debug("Check that the body is empty....and call to super contains no arguments and delete");
if (!constructor.hasActiveBody()) {
debug("No active body found for the default constructor");
return;
}
Body body = constructor.getActiveBody();
Chain units = ((DavaBody) body).getUnits();
if (units.size() != 1) {
debug(" DavaBody AST does not have single root");
return;
}
ASTNode AST = (ASTNode) units.getFirst();
if (!(AST instanceof ASTMethodNode))
throw new RuntimeException("Starting node of DavaBody AST is not an ASTMethodNode");
ASTMethodNode methodNode = (ASTMethodNode) AST;
debug("got methodnode check body is empty and super has nothing in it");
List<Object> subBodies = methodNode.get_SubBodies();
if (subBodies.size() != 1) {
debug("Method node does not have one subBody!!!");
return;
}
List methodBody = (List) subBodies.get(0);
if (methodBody.size() != 0) {
debug("Method body size is greater than 1 so cant do nothing");
return;
}
debug("Method body is empty...check super call is empty");
if (((DavaBody) body).get_ConstructorExpr().getArgCount() != 0) {
debug("call to super not empty");
return;
}
debug("REMOVE METHOD");
s.removeMethod(constructor);
}
use of soot.Body in project soot by Sable.
the class DexPrinter method toMethodImplementation.
private MethodImplementation toMethodImplementation(SootMethod m) {
if (m.isAbstract() || m.isNative()) {
return null;
}
Body activeBody = m.retrieveActiveBody();
// when installing the app
if (m.getName().contains("<") || m.getName().equals(">"))
if (!m.getName().equals("<init>") && !m.getName().equals("<clinit>"))
throw new RuntimeException("Invalid method name: " + m.getName());
// Switch statements may not be empty in dex, so we have to fix this
// first
EmptySwitchEliminator.v().transform(activeBody);
// Dalvik requires synchronized methods to have explicit monitor calls,
// so we insert them here. See
// http://milk.com/kodebase/dalvik-docs-mirror/docs/debugger.html
// We cannot place this upon the developer since it is only required
// for Dalvik, but not for other targets.
SynchronizedMethodTransformer.v().transform(activeBody);
// Tries may not start or end at units which have no corresponding
// Dalvik
// instructions such as IdentityStmts. We reduce the traps to start at
// the
// first "real" instruction. We could also use a TrapTigthener, but that
// would be too expensive for what we need here.
FastDexTrapTightener.v().transform(activeBody);
// Look for sequences of array element assignments that we can collapse
// into bulk initializations
DexArrayInitDetector initDetector = new DexArrayInitDetector();
initDetector.constructArrayInitializations(activeBody);
initDetector.fixTraps(activeBody);
// Split the tries since Dalvik does not supported nested try/catch
// blocks
TrapSplitter.v().transform(activeBody);
// word count of incoming parameters
int inWords = SootToDexUtils.getDexWords(m.getParameterTypes());
if (!m.isStatic()) {
// extra word for "this"
inWords++;
}
// word count of max outgoing parameters
Collection<Unit> units = activeBody.getUnits();
// register count = parameters + additional registers, depending on the
// dex instructions generated (e.g. locals used and constants loaded)
StmtVisitor stmtV = new StmtVisitor(m, initDetector);
Chain<Trap> traps = activeBody.getTraps();
Set<Unit> trapReferences = new HashSet<Unit>(traps.size() * 3);
for (Trap t : activeBody.getTraps()) {
trapReferences.add(t.getBeginUnit());
trapReferences.add(t.getEndUnit());
trapReferences.add(t.getHandlerUnit());
}
toInstructions(units, stmtV, trapReferences);
int registerCount = stmtV.getRegisterCount();
if (inWords > registerCount) {
/*
* as the Dalvik VM moves the parameters into the last registers, the "in" word
* count must be at least equal to the register count. a smaller register count
* could occur if soot generated the method body, see e.g. the handling of
* phantom refs in SootMethodRefImpl.resolve(StringBuffer): the body has no
* locals for the ParameterRefs, it just throws an error.
*
* we satisfy the verifier by just increasing the register count, since calling
* phantom refs will lead to an error anyway.
*/
registerCount = inWords;
}
MethodImplementationBuilder builder = new MethodImplementationBuilder(registerCount);
LabelAssigner labelAssinger = new LabelAssigner(builder);
List<BuilderInstruction> instructions = stmtV.getRealInsns(labelAssinger);
fixLongJumps(instructions, labelAssinger, stmtV);
Map<Local, Integer> seenRegisters = new HashMap<Local, Integer>();
Map<Instruction, LocalRegisterAssignmentInformation> instructionRegisterMap = stmtV.getInstructionRegisterMap();
if (Options.v().write_local_annotations()) {
for (LocalRegisterAssignmentInformation assignment : stmtV.getParameterInstructionsList()) {
// (at least not if it exists with exactly this name)
if (assignment.getLocal().getName().equals("this"))
continue;
addRegisterAssignmentDebugInfo(assignment, seenRegisters, builder);
}
}
for (BuilderInstruction ins : instructions) {
Stmt origStmt = stmtV.getStmtForInstruction(ins);
// If this is a switch payload, we need to place the label
if (stmtV.getInstructionPayloadMap().containsKey(ins))
builder.addLabel(labelAssinger.getLabelName(stmtV.getInstructionPayloadMap().get(ins)));
if (origStmt != null) {
// Do we need a label here because this a trap handler?
if (trapReferences.contains(origStmt))
labelAssinger.getOrCreateLabel(origStmt);
// Add the label if the statement has one
String labelName = labelAssinger.getLabelName(origStmt);
if (labelName != null && !builder.getLabel(labelName).isPlaced())
builder.addLabel(labelName);
// Add the tags
if (stmtV.getStmtForInstruction(ins) != null) {
List<Tag> tags = origStmt.getTags();
for (Tag t : tags) {
if (t instanceof LineNumberTag) {
LineNumberTag lnt = (LineNumberTag) t;
builder.addLineNumber(lnt.getLineNumber());
} else if (t instanceof SourceFileTag) {
SourceFileTag sft = (SourceFileTag) t;
builder.addSetSourceFile(new ImmutableStringReference(sft.getSourceFile()));
}
}
}
}
builder.addInstruction(ins);
LocalRegisterAssignmentInformation registerAssignmentTag = instructionRegisterMap.get(ins);
if (registerAssignmentTag != null) {
// Add start local debugging information: Register -> Local
// assignment
addRegisterAssignmentDebugInfo(registerAssignmentTag, seenRegisters, builder);
}
}
for (int registersLeft : seenRegisters.values()) builder.addEndLocal(registersLeft);
toTries(activeBody.getTraps(), stmtV, builder, labelAssinger);
// Make sure that all labels have been placed by now
for (Label lbl : labelAssinger.getAllLabels()) if (!lbl.isPlaced())
throw new RuntimeException("Label not placed: " + lbl);
return builder.getMethodImplementation();
}
use of soot.Body in project soot by Sable.
the class TemplatePrinter method printTo.
private void printTo(SootClass c) {
String templateClassName = c.getName().replace('.', '_') + "_Maker";
// imports
println("import java.util.*;");
println("import soot.*;");
println("import soot.jimple.*;");
println("import soot.util.*;");
println("");
// open class
print("public class ");
print(templateClassName);
println(" {");
println("private static Local localByName(Body b, String name) {");
println(" for(Local l: b.getLocals()) {");
println(" if(l.getName().equals(name))");
println(" return l;");
println(" }");
println(" throw new IllegalArgumentException(\"No such local: \"+name);");
println("}");
// open main method
indent();
println("public void create() {");
indent();
println("SootClass c = new SootClass(\"" + c.getName() + "\");");
println("c.setApplicationClass();");
// todo modifiers, extends etc.
println("Scene.v().addClass(c);");
for (int i = 0; i < c.getMethodCount(); i++) {
println("createMethod" + i + "(c);");
}
// close main method
closeMethod();
int i = 0;
for (SootMethod m : c.getMethods()) {
newMethod("createMethod" + i);
// TODO modifiers, types
println("SootMethod m = new SootMethod(\"" + m.getName() + "\",null,null);");
println("Body b = Jimple.v().newBody(m);");
println("m.setActiveBody(b);");
if (!m.hasActiveBody())
continue;
Body b = m.getActiveBody();
println("Chain<Local> locals = b.getLocals();");
for (Local l : b.getLocals()) {
// TODO properly treat primitive types
println("locals.add(Jimple.v().newLocal(\"" + l.getName() + "\", RefType.v(\"" + l.getType() + "\")));");
}
println("Chain<Unit> units = b.getUnits();");
StmtTemplatePrinter sw = new StmtTemplatePrinter(this, b.getUnits());
for (Unit u : b.getUnits()) {
u.apply(sw);
}
// TODO print traps
closeMethod();
i++;
}
// close class
println("}");
}
Aggregations