Example #1
0
 /**
  * Get the statement at a specific label. If there is no statement stored, attempts to disassemble
  * the instruction at the label's virtual address. If the address is outside of the file area,
  * logs an error and returns a Halt statement by default.
  *
  * @param label The label for which to get the statement
  * @return The statement object at label.
  */
 public final RTLStatement getStatement(RTLLabel label) {
   if (!statementMap.containsKey(label)) {
     AbsoluteAddress address = label.getAddress();
     Instruction instr = getInstruction(address);
     // If we did not get an instruction, add an artificial Halt for recovery
     if (instr == null) {
       RTLHalt halt = new RTLHalt();
       halt.setLabel(label);
       putStatement(halt);
       logger.error("ERROR: Replacing unknown instruction with HALT.");
       if (Options.debug.getValue())
         throw new DisassemblyException("Disassembly failed at " + address);
     } else {
       try {
         StatementSequence seq = arch.getRTLEquivalent(address, instr);
         for (RTLStatement s : seq) {
           putStatement(s);
         }
       } catch (Exception e) {
         logger.error("Error during translation of instruction to IL");
         e.printStackTrace();
         RTLStatement skip = new RTLSkip();
         skip.setLabel(label);
         skip.setNextLabel(new RTLLabel(new AbsoluteAddress(address.getValue() + 1)));
         putStatement(skip);
       }
       assert statementMap.containsKey(label) : "Disassembly did not produce label: " + label;
     }
   }
   return statementMap.get(label);
 }
Example #2
0
 /**
  * Stores a statement in the program. If a statement already exists with the same label, it is
  * replaced.
  *
  * @param stmt The statement to be stored. Has to contain a proper label.
  */
 public final void putStatement(RTLStatement stmt) {
   RTLStatement existing = statementMap.get(stmt.getLabel());
   if (existing != null) {
     if (existing.equals(stmt)) return;
     logger.debug("Replacing statement at " + stmt.getLabel());
   }
   statementMap.put(stmt.getLabel(), stmt);
 }
  /*
   * @see org.jakstab.analysis.ConfigurableProgramAnalysis#post(org.jakstab.analysis.AbstractState, org.jakstab.analysis.StateTransformer, org.jakstab.analysis.Precision)
   */
  @Override
  public Set<AbstractState> post(final AbstractState state, CFAEdge cfaEdge, Precision precision) {

    final RTLStatement statement = (RTLStatement) cfaEdge.getTransformer();
    final ValuationState iState = (ValuationState) state;

    return Collections.singleton(
        statement.accept(
            new DefaultStatementVisitor<AbstractState>() {

              @Override
              protected AbstractState visitDefault(RTLStatement stmt) {
                return state;
              }

              @Override
              public AbstractState visit(RTLVariableAssignment stmt) {
                ValuationState post = new ValuationState(iState);
                Writable lhs = stmt.getLeftHandSide();
                RTLExpression rhs = stmt.getRightHandSide();
                AbstractDomainElement evaledRhs = iState.abstractEval(rhs);

                // Check for stackpointer alignment assignments (workaround for gcc compiled files)
                RTLVariable sp = Program.getProgram().getArchitecture().stackPointer();
                if (lhs.equals(sp) && rhs instanceof RTLOperation) {
                  RTLOperation op = (RTLOperation) rhs;
                  if (op.getOperator().equals(Operator.AND)
                      && op.getOperands()[0].equals(sp)
                      && op.getOperands()[1] instanceof RTLNumber) {
                    evaledRhs = iState.getVariableValue(sp);
                    logger.warn("Ignoring stackpointer alignment at " + stmt.getAddress());
                  }
                }

                post.setVariableValue((RTLVariable) lhs, evaledRhs);

                return post;
              }

              @Override
              public AbstractState visit(RTLMemoryAssignment stmt) {
                ValuationState post = new ValuationState(iState);
                RTLMemoryLocation m = stmt.getLeftHandSide();
                RTLExpression rhs = stmt.getRightHandSide();
                AbstractDomainElement evaledRhs = iState.abstractEval(rhs);
                AbstractDomainElement evaledAddress = iState.abstractEval(m.getAddress());
                post.setMemoryValue(evaledAddress, m.getBitWidth(), evaledRhs);
                return post;
              }

              @Override
              public AbstractState visit(RTLAssume stmt) {

                ValuationState post = new ValuationState(iState);

                RTLExpression assumption = stmt.getAssumption();

                // TODO: implement assume

                if (assumption instanceof RTLOperation) {
                  RTLOperation op = (RTLOperation) assumption;
                  switch (op.getOperator()) {
                    case UNSIGNED_LESS_OR_EQUAL:
                      RTLExpression lhs = op.getOperands()[0];
                      RTLExpression rhs = op.getOperands()[1];
                      IntervalElement evaledLhs = (IntervalElement) iState.abstractEval(lhs);
                      IntervalElement evaledRhs = (IntervalElement) iState.abstractEval(rhs);

                      if (evaledRhs.getLeft() >= 0) {
                        IntervalElement uLessInt =
                            new IntervalElement(
                                evaledRhs.getRegion(),
                                0,
                                evaledRhs.getRight(),
                                1,
                                evaledLhs.getBitWidth());
                        // TODO: Implement meet for interval elements for optimal result
                        // uLessInt = uLessInt.meet(evaledLhs);
                        // if uLessInt.isBot() return Collections.emptySet();
                        // cheap but sound solution for now: only use new interval if it has less
                        // elements
                        if (uLessInt.size() < evaledLhs.size()) {
                          if (lhs instanceof RTLVariable) {
                            post.setVariableValue((RTLVariable) lhs, uLessInt);
                          } else if (lhs instanceof RTLMemoryLocation) {
                            RTLMemoryLocation m = (RTLMemoryLocation) lhs;
                            AbstractDomainElement evaledAddress =
                                iState.abstractEval(m.getAddress());
                            post.setMemoryValue(evaledAddress, m.getBitWidth(), uLessInt);
                          }
                        }
                      }
                      break;
                    default: // nothing
                  }
                }

                return post;
              }

              @Override
              public AbstractState visit(RTLAlloc stmt) {
                ValuationState post = new ValuationState(iState);
                Writable lhs = stmt.getPointer();

                MemoryRegion newRegion;
                if (stmt.getAllocationName() != null) {
                  newRegion = MemoryRegion.create(stmt.getAllocationName());
                } else {
                  // TODO: Detect whether this allocation is unique to allow strong updates
                  newRegion = MemoryRegion.createAsSummary("alloc" + stmt.getLabel());
                }

                IntervalElement basePointer =
                    new IntervalElement(newRegion, ExpressionFactory.createNumber(0, 32));

                if (lhs instanceof RTLVariable) {
                  post.setVariableValue((RTLVariable) lhs, basePointer);
                } else {
                  RTLMemoryLocation m = (RTLMemoryLocation) lhs;
                  AbstractDomainElement evaledAddress = iState.abstractEval(m.getAddress());
                  post.setMemoryValue(evaledAddress, m.getBitWidth(), basePointer);
                }

                return post;
              }

              @Override
              public AbstractState visit(RTLHavoc stmt) {
                ValuationState post = new ValuationState(iState);

                // Only create a single state with the havoc range, since this analysis
                // is not path sensitive
                post.setVariableValue(
                    stmt.getVariable(),
                    // new IntervalElement(ExpressionFactory.getInstance().createNumber(0,
                    // stmt.getVariable().getBitWidth()),
                    // (RTLNumber)stmt.getMaximum()));
                    new IntervalElement(
                        MemoryRegion.GLOBAL,
                        0,
                        ((RTLNumber) stmt.getMaximum()).longValue(),
                        1,
                        stmt.getVariable().getBitWidth()));

                return post;
              }

              @Override
              public AbstractState visit(RTLUnknownProcedureCall stmt) {
                ValuationState post = new ValuationState(iState);
                for (RTLVariable var : stmt.getDefinedVariables()) {
                  post.setVariableValue(var, IntervalElement.getTop(var.getBitWidth()));
                }
                post.setMemoryValue(
                    IntervalElement.getTop(
                        Program.getProgram().getArchitecture().getAddressBitWidth()),
                    32,
                    IntervalElement.getTop(32));
                return post;
              }
            }));
  }