public void transform() { if (clazz.isPhantom()) return; // build ancestor // List<SootClass> ancestors = Scene.v().getActiveHierarchy().getSuperclassesOf(clazz); List<SootClass> ancestors = new LinkedList<SootClass>(); // fill in ancestor list without using Soot.Hierarchy SootClass curAncestor = clazz; while (curAncestor.hasSuperclass()) { ancestors.add(curAncestor.getSuperclass()); curAncestor = curAncestor.getSuperclass(); } for (SootClass ancestor : ancestors) { if (ancestor.isPhantom()) continue; cloneReachableNonHiddenAncestorMethods(ancestor); } // modify ancestors fields for (SootClass ancestor : ancestors) { if (ancestor.isPhantom()) continue; SootUtils.makeFieldsVisible(ancestor); } cloneHiddenAncestorMethodsAndFixInvokeSpecial(); }
public static HashSet<SootMethod> getAllImplementations(SootMethod method) { Chain appClasses = Scene.v().getApplicationClasses(); HashSet<SootClass> implementingClasses = new HashSet<SootClass>(1); HashSet<SootMethod> overridingMethods = new HashSet<SootMethod>(1); SootClass t = method.getDeclaringClass(); if ( /*t.isAbstract() || */ t.isPhantom() || t.isPhantomClass()) { boolean b1 = t.isAbstract(); boolean be = t.isPhantom(); boolean b3 = t.isPhantomClass(); try { throw new Exception("Need to implement for Plantom Classes"); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } if (t.isAbstract()) { for (Object object : appClasses) { SootClass clazz = (SootClass) object; SootClass superClass = clazz.getSuperclass(); { if (superClass.getName().equals(t.toString())) { implementingClasses.add(clazz); SootMethod m2 = clazz.getMethod( method.getName(), method.getParameterTypes(), method.getReturnType()); overridingMethods.add(m2); } } } } if (t.isInterface()) { for (Object object : appClasses) { SootClass clazz = (SootClass) object; Chain<SootClass> interfaces = clazz.getInterfaces(); for (SootClass sootClass : interfaces) { if (sootClass.getName().equals(t.toString())) { implementingClasses.add(clazz); SootMethod m2 = clazz.getMethod( method.getName(), method.getParameterTypes(), method.getReturnType()); overridingMethods.add(m2); } } } } return overridingMethods; }
public static SootClass mockSootClass(String clsName) { SootClass sc = null; if (Scene.v().containsClass(clsName)) { sc = Scene.v().getSootClass(clsName); if (sc.isPhantom()) { // sc.setPhantom(false); sc.setApplicationClass(); sc.setInScene(true); try { for (Field field : sc.getClass().getFields()) { if (field.getName().equals("isPhantom")) { field.setAccessible(true); field.setBoolean(sc, false); } } } catch (Exception e) { e.printStackTrace(); } } } else { sc = new SootClass(clsName); sc.setSuperclass(Scene.v().getSootClass("java.lang.Object")); sc.setPhantom(false); sc.setApplicationClass(); sc.setInScene(true); } mockConstructor(sc); return sc; }
protected void internalTransform(String phaseName, Map options) { if (Options.v().verbose()) G.v().out.println("Transforming all classes in the Scene to Shimple..."); // *** FIXME: Add debug output to indicate which class/method is being shimplified. // *** FIXME: Is ShimpleTransformer the right solution? The call graph may deem // some classes unreachable. Iterator classesIt = Scene.v().getClasses().iterator(); while (classesIt.hasNext()) { SootClass sClass = (SootClass) classesIt.next(); if (sClass.isPhantom()) continue; Iterator methodsIt = sClass.getMethods().iterator(); while (methodsIt.hasNext()) { SootMethod method = (SootMethod) methodsIt.next(); if (!method.isConcrete()) continue; if (method.hasActiveBody()) { Body body = method.getActiveBody(); ShimpleBody sBody = null; if (body instanceof ShimpleBody) { sBody = (ShimpleBody) body; if (!sBody.isSSA()) sBody.rebuild(); } else { sBody = Shimple.v().newBody(body); } method.setActiveBody(sBody); } else { MethodSource ms = new ShimpleMethodSource(method.getSource()); method.setSource(ms); } } } }
private StructureConstant createClassInfoErrorStruct() { /* * Check that clazz can be loaded, i.e. that the superclass * and interfaces of the class exist and are accessible to the * class. Also check that any exception the class uses in catch * clauses exist and is accessible to the class. If the class * cannot be loaded we override the ClassInfoHeader struct * produced by the ClassCompiler for the class with one which * tells the code in bc.c to throw an appropriate exception * whenever clazz is accessed. */ int errorType = ClassCompiler.CI_ERROR_TYPE_NONE; String errorMessage = null; if (!sootClass.isInterface() && sootClass.hasSuperclass()) { // Check superclass SootClass superclazz = sootClass.getSuperclass(); if (superclazz.isPhantom()) { errorType = ClassCompiler.CI_ERROR_TYPE_NO_CLASS_DEF_FOUND; errorMessage = superclazz.getName(); } else if (!checkClassAccessible(superclazz, sootClass)) { errorType = ClassCompiler.CI_ERROR_TYPE_ILLEGAL_ACCESS; errorMessage = String.format(ILLEGAL_ACCESS_ERROR_CLASS, superclazz, sootClass); } else if (superclazz.isInterface()) { errorType = ClassCompiler.CI_ERROR_TYPE_INCOMPATIBLE_CLASS_CHANGE; errorMessage = String.format("class %s has interface %s as super class", sootClass, superclazz); } // No need to check for ClassCircularityError. Soot doesn't handle // such problems so the compilation will fail earlier. } if (errorType == ClassCompiler.CI_ERROR_TYPE_NONE) { // Check interfaces for (SootClass interfaze : sootClass.getInterfaces()) { if (interfaze.isPhantom()) { errorType = ClassCompiler.CI_ERROR_TYPE_NO_CLASS_DEF_FOUND; errorMessage = interfaze.getName(); break; } else if (!checkClassAccessible(interfaze, sootClass)) { errorType = ClassCompiler.CI_ERROR_TYPE_ILLEGAL_ACCESS; errorMessage = String.format(ILLEGAL_ACCESS_ERROR_CLASS, interfaze, sootClass); break; } else if (!interfaze.isInterface()) { errorType = ClassCompiler.CI_ERROR_TYPE_INCOMPATIBLE_CLASS_CHANGE; errorMessage = String.format( "class %s tries to implement class %s as interface", sootClass, interfaze); break; } } } if (errorType == ClassCompiler.CI_ERROR_TYPE_NONE) { // Check exceptions used in catch clauses. I cannot find any info in // the VM spec specifying that this has to be done when the class is loaded. // However, this is how it's done in other VMs so we do it too. for (String exName : catches) { Clazz ex = config.getClazzes().load(exName); if (ex == null || ex.getSootClass().isPhantom()) { errorType = ClassCompiler.CI_ERROR_TYPE_NO_CLASS_DEF_FOUND; errorMessage = exName; break; } else if (!checkClassAccessible(ex.getSootClass(), sootClass)) { errorType = ClassCompiler.CI_ERROR_TYPE_ILLEGAL_ACCESS; errorMessage = String.format(ILLEGAL_ACCESS_ERROR_CLASS, ex, sootClass); break; } } } if (errorType == ClassCompiler.CI_ERROR_TYPE_NONE) { return null; } // Create a ClassInfoError struct StructureConstantBuilder error = new StructureConstantBuilder(); error.add(new NullConstant(I8_PTR)); // Points to the runtime Class struct error.add(new IntegerConstant(ClassCompiler.CI_ERROR)); error.add(getString(getInternalName(sootClass))); error.add(new IntegerConstant(errorType)); error.add(getString(errorMessage)); return error.build(); }