Beispiel #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);
 }
Beispiel #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);
 }
Beispiel #3
0
  public int countIndirectBranches() {
    int res = 0;
    for (Map.Entry<AbsoluteAddress, Instruction> entry : assemblyMap.entrySet()) {
      Instruction instr = entry.getValue();

      if (instr instanceof BranchInstruction) {
        BranchInstruction branch = (BranchInstruction) instr;
        if (branch.isIndirect()) {
          // if branch target is not a memory operand pointing into a static data area of the binary
          // (imports)
          if (branch.getBranchDestination() instanceof MemoryOperand) {
            MemoryOperand memOp = (MemoryOperand) branch.getBranchDestination();
            // Import calls have only displacement
            if (memOp.getBase() == null && memOp.getIndex() == null) {
              AbsoluteAddress disp = new AbsoluteAddress(memOp.getDisplacement());
              // Check whether displacement points into import table
              ExecutableImage module = getModule(disp);
              if (module instanceof PEModule
                  && ((PEModule) module).getImportTable().containsKey(disp)) continue;
            }
          }
          res++;
          // logger.verbose(entry.getKey() + "\t" + getInstructionString(entry.getKey()));
        }
      }
    }
    return res;
  }
Beispiel #4
0
 /**
  * Returns the address of the given procedure within the given library. Procedures present within
  * the analyzed modules are given precedence over stub functions.
  *
  * @param library
  * @param procedure
  * @return the virtual address of the procedure
  */
 public AbsoluteAddress getProcAddress(String library, String procedure) {
   ExportedSymbol expSymbol = exportedSymbols.get(procedure);
   if (expSymbol != null) {
     return expSymbol.getAddress();
   } else {
     return stubLibrary.resolveSymbol(library, procedure);
   }
 }
Beispiel #5
0
  /** Resolves symbols between the loaded modules. */
  private void resolveSymbols() {
    Iterator<UnresolvedSymbol> sIter = unresolvedSymbols.iterator();
    while (sIter.hasNext()) {
      UnresolvedSymbol unresolvedSymbol = sIter.next();
      ExportedSymbol symbol = exportedSymbols.get(removeDecoration(unresolvedSymbol.getName()));

      if (symbol != null) {
        logger.debug("Resolving symbol " + unresolvedSymbol.getName());
        unresolvedSymbol.resolve(symbol.getAddress());
        sIter.remove();
      }
    }
  }
Beispiel #6
0
  public LinkedList<BranchInstruction> getIndirectBranches() {
    LinkedList<BranchInstruction> indirectBranches = new LinkedList<BranchInstruction>();
    for (Map.Entry<AbsoluteAddress, Instruction> entry : assemblyMap.entrySet()) {
      Instruction instr = entry.getValue();

      if (instr instanceof BranchInstruction) {
        BranchInstruction branch = (BranchInstruction) instr;
        if (branch.isIndirect()) {
          indirectBranches.add(branch);
        }
      }
    }
    return indirectBranches;
  }
Beispiel #7
0
  /**
   * Gets the assembly instruction at the specified virtual address.
   *
   * @param address a virtual address
   * @return the assembly instruction at the specified address
   */
  public final Instruction getInstruction(AbsoluteAddress address) {

    Instruction instr = assemblyMap.get(address);
    if (instr != null) {
      return instr;
    } else {
      // No real instructions in prologue/epilogue
      if (harness.contains(address) || isStub(address)) return null;

      ExecutableImage module = getModule(address);

      long fp = -1;
      if (module == null) {
        logger.error("No module for address " + address + ". Cannot disassemble instruction!");
      } else {
        fp = module.getFilePointer(address);
        // Also check whether fp is out of the int range, since the X86Disassembler actually
        // performs this cast in its implementation.
        if (fp < 0 || (int) fp < 0) {
          logger.error("Requested instruction outside of file area: " + address);
        } else {
          if (!module.isCodeArea(address)) {
            logger.error("Requested instruction outside code section: " + address);
            return null;
          }
          instr = module.getDisassembler().decodeInstruction(fp);
          if (instr == null) {
            logger.error("Instruction could not be disassembled at: " + address);
          }
        }
      }

      if (instr != null) putInstruction(address, instr);
      return instr;
    }
  }
Beispiel #8
0
  /**
   * Loads a secondary (library or stub) module for analysis. Automatically determines the correct
   * file type.
   *
   * @param moduleFile the file to load
   * @return the ExecutableImage class for the loaded module
   * @throws IOException
   * @throws BinaryParseException
   */
  public ExecutableImage loadModule(File moduleFile) throws IOException, BinaryParseException {
    // First try to load it as a PE file, then object file, ELF and finally raw binary code
    // The right thing to do would be some smart IDing of the file type, but
    // this exception chaining works for now...
    ExecutableImage module = null;
    try {
      module = new PEModule(moduleFile, getArchitecture());
      targetOS = TargetOS.WINDOWS;
    } catch (BinaryParseException e) {
      try {
        module = new ObjectFile(moduleFile, getArchitecture());
      } catch (BinaryParseException e2) {
        try {
          module = new ELFModule(moduleFile, getArchitecture());
          targetOS = TargetOS.LINUX;
        } catch (BinaryParseException e3) {
          module = new RawModule(moduleFile, getArchitecture());
        }
      }
    }

    for (ExecutableImage existingModule : modules) {
      if (existingModule.getMaxAddress().getValue() >= module.getMinAddress().getValue()
          && existingModule.getMinAddress().getValue() <= module.getMaxAddress().getValue()) {
        throw new RuntimeException("Virtual addresses of modules overlap!");
      }
    }

    modules.add(module);
    unresolvedSymbols.addAll(module.getUnresolvedSymbols());
    for (ExportedSymbol symbol : module.getExportedSymbols()) {
      exportedSymbols.put(removeDecoration(symbol.getName()), symbol);
    }
    resolveSymbols();
    return module;
  }
Beispiel #9
0
 public Collection<ExportedSymbol> getSymbols() {
   return exportedSymbols.values();
 }
Beispiel #10
0
 /**
  * Stores an assembly instruction at the given address, overwriting any existing instruction.
  *
  * @param addr the virtual address to save the instruction at
  * @param instr the assembly instruction
  * @return true if there was no instruction stored for that address before, false otherwise.
  */
 public final boolean putInstruction(AbsoluteAddress addr, Instruction instr) {
   // logger.info(addr + " " + instr.toString(addr.getValue(), new DummySymbolFinder()));
   return assemblyMap.put(addr, instr) == null;
 }
Beispiel #11
0
 public final int getInstructionCount() {
   return assemblyMap.size();
 }
Beispiel #12
0
 public final int getStatementCount() {
   return statementMap.size();
 }
Beispiel #13
0
 public boolean containsLabel(RTLLabel label) {
   return statementMap.containsKey(label);
 }