@CheckForNull Use getUse(ConstantPoolGen cpg, Instruction ins) { if (ins instanceof InvokeInstruction) { InvokeInstruction invoke = (InvokeInstruction) ins; String mName = invoke.getMethodName(cpg); String cName = invoke.getClassName(cpg); if ("setAttribute".equals(mName) && "javax.servlet.http.HttpSession".equals(cName)) { return Use.STORE_INTO_HTTP_SESSION; } if ("writeObject".equals(mName) && ("java.io.ObjectOutput".equals(cName) || "java.io.ObjectOutputStream".equals(cName))) { return Use.PASSED_TO_WRITE_OBJECT; } } return null; } private void analyzeMethod(ClassContext classContext, Method method) throws CFGBuilderException, DataflowAnalysisException {
public boolean matches(Instruction instruction, ConstantPoolGen cpg) { if(instruction != null && instruction instanceof InvokeInstruction) { InvokeInstruction invokeInstruction = (InvokeInstruction) instruction; if (classesNames.size() != 0 && !classesNames.contains(invokeInstruction.getClassName(cpg))) { return false; } else if (methodNames.size() != 0 && !methodNames.contains(invokeInstruction.getMethodName(cpg))) { return false; } else if (argSignatures.size() != 0 && !argSignatures.contains(invokeInstruction.getSignature(cpg))) { return false; } return true; } return false; } }
public MethodDescriptor(InvokeInstruction iins, ConstantPoolGen cpg) { super(ClassName.toSlashedClassName(iins.getClassName(cpg)), iins.getMethodName(cpg), iins.getSignature(cpg), iins instanceof INVOKESTATIC); }
String methodName = inv.getMethodName(cpg); String methodSig = inv.getSignature(cpg); if (inv.getOpcode() == Const.INVOKEVIRTUAL
/** * Determine if given Instruction is a monitor wait. * * @param ins * the Instruction * @param cpg * the ConstantPoolGen for the Instruction * * @return true if the instruction is a monitor wait, false if not */ public static boolean isMonitorWait(Instruction ins, ConstantPoolGen cpg) { if (!(ins instanceof InvokeInstruction)) { return false; } if (ins.getOpcode() == Const.INVOKESTATIC) { return false; } InvokeInstruction inv = (InvokeInstruction) ins; String methodName = inv.getMethodName(cpg); String methodSig = inv.getSignature(cpg); return isMonitorWait(methodName, methodSig); }
/** * Determine if given Instruction is a monitor wait. * * @param ins * the Instruction * @param cpg * the ConstantPoolGen for the Instruction * * @return true if the instruction is a monitor wait, false if not */ public static boolean isMonitorNotify(Instruction ins, ConstantPoolGen cpg) { if (!(ins instanceof InvokeInstruction)) { return false; } if (ins.getOpcode() == Const.INVOKESTATIC) { return false; } InvokeInstruction inv = (InvokeInstruction) ins; String methodName = inv.getMethodName(cpg); String methodSig = inv.getSignature(cpg); return isMonitorNotify(methodName, methodSig); }
/** * Get a MethodDescriptor describing the method called by given * InvokeInstruction. * * @param inv * the InvokeInstruction * @param cpg * ConstantPoolGen of class containing instruction * @return MethodDescriptor describing the called method */ public static MethodDescriptor getCalledMethodDescriptor(InvokeInstruction inv, ConstantPoolGen cpg) { String calledClassName = inv.getClassName(cpg).replace('.', '/'); String calledMethodName = inv.getMethodName(cpg); String calledMethodSig = inv.getSignature(cpg); boolean isStatic = inv.getOpcode() == Const.INVOKESTATIC; return DescriptorFactory.instance().getMethodDescriptor(calledClassName, calledMethodName, calledMethodSig, isStatic); }
/** * Add a method annotation for the method which is called by given * instruction. * * @param cpg * the constant pool for the method containing the call * @param inv * the InvokeInstruction * @return this object */ @Nonnull public BugInstance addCalledMethod(ConstantPoolGen cpg, InvokeInstruction inv) { String className = inv.getClassName(cpg); String methodName = inv.getMethodName(cpg); String methodSig = inv.getSignature(cpg); addMethod(className, methodName, methodSig, inv.getOpcode() == Const.INVOKESTATIC); describe(MethodAnnotation.METHOD_CALLED); return this; }
&& inv.getMethodName(cpg).toLowerCase().indexOf("lock") >= 0) { return; if(inv instanceof INVOKEVIRTUAL && "cast".equals(inv.getMethodName(cpg)) && "java.lang.Class".equals(inv.getClassName(cpg))) {
public MethodDescriptor getInvokedMethod(ConstantPoolGen cpg, InvokeInstruction inv) { String invoked = inv.getClassName(cpg); String methodName = inv.getMethodName(cpg); String methodSig = inv.getSignature(cpg); MethodDescriptor invokedMethod = DescriptorFactory.instance().getMethodDescriptor(ClassName.toSlashedClassName(invoked), methodName, methodSig, inv instanceof INVOKESTATIC); return invokedMethod; }
@Override public InjectionPoint getInjectableParameters(InvokeInstruction ins, ConstantPoolGen cpg, InstructionHandle insHandle) { if (ins instanceof INVOKEINTERFACE) { String methodName = ins.getMethodName(cpg); String className = ins.getReferenceType(cpg).toString(); if (className.equals("javax.servlet.http.HttpServletResponse") || className.equals("javax.servlet.http.HttpServletResponseWrapper")) { if (methodName.equals("sendRedirect")) { InjectionPoint ip = new InjectionPoint(new int[]{0}, UNVALIDATED_REDIRECT_TYPE); //ip.setInjectableMethod(className.concat(".sendRedirect(...)")); ip.setInjectableMethod(ins.getSignature(cpg)); return ip; } else if (methodName.equals("addHeader") || methodName.equals("setHeader")) { LDC ldc = ByteCode.getPrevInstruction(insHandle, LDC.class); if (ldc != null) { Object value = ldc.getValue(cpg); if (value != null && "Location".equalsIgnoreCase((String) value)) { InjectionPoint ip = new InjectionPoint(new int[]{0}, UNVALIDATED_REDIRECT_TYPE); //ip.setInjectableMethod(className + "." + methodName + "(\"Location\", ...)"); ip.setInjectableMethod(ins.getSignature(cpg)); return ip; } } } } } return InjectionPoint.NONE; } }
private boolean isSafeValue(Location location, ConstantPoolGen cpg) throws CFGBuilderException { Instruction prevIns = location.getHandle().getInstruction(); if (prevIns instanceof LDC || prevIns instanceof GETSTATIC) { return true; } if (prevIns instanceof InvokeInstruction) { String methodName = ((InvokeInstruction) prevIns).getMethodName(cpg); if (methodName.startsWith("to") && methodName.endsWith("String") && methodName.length() > 8) { return true; } } if (prevIns instanceof AALOAD) { CFG cfg = classContext.getCFG(method); Location prev = getPreviousLocation(cfg, location, true); if (prev != null) { Location prev2 = getPreviousLocation(cfg, prev, true); if (prev2 != null && prev2.getHandle().getInstruction() instanceof GETSTATIC) { GETSTATIC getStatic = (GETSTATIC) prev2.getHandle().getInstruction(); if ("[Ljava/lang/String;".equals(getStatic.getSignature(cpg))) { return true; } } } } return false; }
private void analyzeMethod(ClassContext classContext, Method method) throws CFGBuilderException, ClassNotFoundException, DataflowAnalysisException { CFG cfg = classContext.getCFG(method); for (Iterator<Location> i = cfg.locationIterator(); i.hasNext();) { Location location = i.next(); Instruction ins = location.getHandle().getInstruction(); if (ins instanceof InvokeInstruction) { if (TARGET_METHOD != null && !((InvokeInstruction) ins).getMethodName(classContext.getConstantPoolGen()).equals(TARGET_METHOD)) { continue; } System.out.println("\n*******************************************************\n"); System.out.println("Method invocation: " + location.getHandle()); System.out.println("\tInvoking: " + SignatureConverter.convertMethodSignature((InvokeInstruction) ins, classContext.getConstantPoolGen())); JavaClassAndMethod proto = Hierarchy.findInvocationLeastUpperBound((InvokeInstruction) ins, classContext.getConstantPoolGen()); if (proto == null) { System.out.println("\tUnknown prototype method"); } else { System.out.println("\tPrototype method: class=" + proto.getJavaClass().getClassName() + ", method=" + proto.getMethod()); } Set<JavaClassAndMethod> calledMethodSet = Hierarchy.resolveMethodCallTargets((InvokeInstruction) ins, classContext.getTypeDataflow(method).getFactAtLocation(location), classContext.getConstantPoolGen()); System.out.println("\tTarget method set: " + calledMethodSet); } } }
@Override public void transferInstruction(InstructionHandle handle, BasicBlock basicBlock, LockSet fact) throws DataflowAnalysisException { Instruction ins = handle.getInstruction(); short opcode = ins.getOpcode(); if (opcode == Const.MONITORENTER || opcode == Const.MONITOREXIT) { ValueNumberFrame frame = vnaDataflow.getFactAtLocation(new Location(handle, basicBlock)); modifyLock(frame, fact, opcode == Const.MONITORENTER ? 1 : -1); } else if (opcode == Const.INVOKEVIRTUAL || opcode == Const.INVOKEINTERFACE) { InvokeInstruction inv = (InvokeInstruction) ins; String name = inv.getMethodName(methodGen.getConstantPool()); String sig = inv.getSignature(methodGen.getConstantPool()); ValueNumberFrame frame = vnaDataflow.getFactAtLocation(new Location(handle, basicBlock)); if ("()V".equals(sig) && ("lock".equals(name) || "lockInterruptibly".equals(name))) { modifyLock(frame, fact, 1); } else if ("()V".equals(sig) && ("unlock".equals(name))) { modifyLock(frame, fact, -1); } } else if ((ins instanceof ReturnInstruction) && isSynchronized && !isStatic) { lockOp(fact, vna.getThisValue().getNumber(), -1); } }
boolean callToAssertionMethod(Location loc) { InstructionHandle h = loc.getHandle(); int firstPos = h.getPosition(); LineNumberTable ln = method.getLineNumberTable(); int firstLine = ln == null ? -1 : ln.getSourceLine(firstPos); while (h != null) { int pos = h.getPosition(); if (ln == null) { if (pos > firstPos + 15) { break; } } else { int line = ln.getSourceLine(pos); if (line != firstLine) { break; } } Instruction i = h.getInstruction(); if (i instanceof InvokeInstruction) { InvokeInstruction ii = (InvokeInstruction) i; String name = ii.getMethodName(classContext.getConstantPoolGen()); if (name.startsWith("check") || name.startsWith("assert")) { return true; } } h = h.getNext(); } return false; }
String methodName = inv.getMethodName(cpg); String methodSig = inv.getSignature(cpg); if (!this.methodName.equals(methodName) || !this.methodSig.equals(methodSig)) {
void initObservedValues() throws DataflowAnalysisException { for(Iterator<Location> iterator = cfg.locationIterator(); iterator.hasNext(); ) { Location location = iterator.next(); Instruction instruction = location.getHandle().getInstruction(); if(instruction instanceof ANEWARRAY || instruction instanceof NEWARRAY || instruction instanceof MULTIANEWARRAY) { int number = vna.getFactAfterLocation(location).getTopValue().getNumber(); TypeFrame typeFrame = ta.getFactAfterLocation(location); if(typeFrame.isValid()) { Type type = typeFrame.getTopValue(); observedValues.put(number, new ValueInfo(number, location, type)); } } else if(instruction instanceof INVOKESPECIAL) { InvokeInstruction inv = (InvokeInstruction) instruction; if (inv.getMethodName(cpg).equals(CONSTRUCTOR_NAME) && noSideEffectMethods.hasNoSideEffect(new MethodDescriptor(inv, cpg))) { int number = vna.getFactAtLocation(location).getStackValue(inv.consumeStack(cpg)-1).getNumber(); TypeFrame typeFrame = ta.getFactAtLocation(location); if(typeFrame.isValid()) { Type type = typeFrame.getStackValue(inv.consumeStack(cpg)-1); observedValues.put(number, new ValueInfo(number, location, type)); } } } } thisValue = vna.getThisValue(); if(thisValue != null) { observedValues.remove(thisValue.getNumber()); } count = observedValues.size(); }
String methodName = inv.getMethodName(cpg); boolean isStatic = inv.getOpcode() == Const.INVOKESTATIC; boolean isCtor = Const.CONSTRUCTOR_NAME.equals(methodName);
private void analyzeMethod(Method m, ClassContext classContext) throws CFGBuilderException, DataflowAnalysisException { MethodGen methodGen = classContext.getMethodGen(m); ConstantPoolGen cpg = classContext.getConstantPoolGen(); CFG cfg = classContext.getCFG(m); if (methodGen == null || methodGen.getInstructionList() == null) { return; //No instruction .. nothing to do } for (Iterator<Location> i = cfg.locationIterator(); i.hasNext(); ) { Location location = i.next(); Instruction inst = location.getHandle().getInstruction(); if (inst instanceof InvokeInstruction) { InvokeInstruction invoke = (InvokeInstruction) inst; String methodName = invoke.getMethodName(cpg); if ("enableDefaultTyping".equals(methodName)) { JavaClass clz = classContext.getJavaClass(); bugReporter.reportBug(new BugInstance(this, DESERIALIZATION_TYPE, HIGH_PRIORITY) .addClass(clz) .addMethod(clz, m) .addCalledMethod(cpg, invoke) .addSourceLine(classContext, m, location) ); } } } }
private void killLoadsOfObjectsPassed(InvokeInstruction ins) { try { XMethod called = Hierarchy2.findExactMethod(ins, methodGen.getConstantPool(), Hierarchy.ANY_METHOD); if (called != null ) { NoSideEffectMethodsDatabase nse = Global.getAnalysisCache().getOptionalDatabase(NoSideEffectMethodsDatabase.class); if(nse != null && !nse.is(called.getMethodDescriptor(), MethodSideEffectStatus.SE, MethodSideEffectStatus.OBJ)) { return; } } FieldSummary fieldSummary = AnalysisContext.currentAnalysisContext().getFieldSummary(); Set<XField> touched = fieldSummary.getFieldsWritten(called); if (!touched.isEmpty()) { getFrame().killLoadsOf(touched); } int passed = getNumWordsConsumed(ins); ValueNumber[] arguments = allocateValueNumberArray(passed); getFrame().killLoadsWithSimilarName(ins.getClassName(cpg), ins.getMethodName(cpg)); getFrame().getTopStackWords(arguments); for (ValueNumber v : arguments) { getFrame().killAllLoadsOf(v); } // Too many false-positives for primitives without transitive FieldSummary analysis, // so currently we simply kill any writable primitive on any method call // TODO: implement transitive FieldSummary getFrame().killAllLoads(true); } catch (DataflowAnalysisException e) { AnalysisContext.logError("Error in killLoadsOfObjectsPassed", e); } }