Esempio n. 1
0
  private boolean isNativeCodeSequence(
      NativeCodeSequence nativeCodeSequence, CodeInstruction codeInstruction, CodeBlock codeBlock) {
    int address = codeInstruction.getAddress();
    int numOpcodes = nativeCodeSequence.getNumOpcodes();

    // Can this NativeCodeSequence only match a whole CodeBlock?
    if (nativeCodeSequence.isWholeCodeBlock()) {
      // Match only a whole CodeBlock: same StartAddress, same Length
      if (codeBlock.getStartAddress() != address) {
        return false;
      }

      if (codeBlock.getLength() != numOpcodes) {
        return false;
      }
    }

    IMemoryReader codeBlockReader = MemoryReader.getMemoryReader(address, 4);
    for (int i = 0; i < numOpcodes; i++) {
      int opcode = codeBlockReader.readNext();
      if (!nativeCodeSequence.isMatching(i, opcode)) {
        return false;
      }
    }

    return true;
  }
Esempio n. 2
0
  private void addNativeCodeSequence(NativeCodeSequence nativeCodeSequence) {
    if (nativeCodeSequence.getNumOpcodes() > 0) {
      int firstOpcodeMask = nativeCodeSequence.getFirstOpcodeMask();
      if (firstOpcodeMask == defaultOpcodeMask) {
        // First opcode has not mask: fast lookup allowed
        int firstOpcode = nativeCodeSequence.getFirstOpcode();

        if (!nativeCodeSequencesByFirstOpcode.containsKey(firstOpcode)) {
          nativeCodeSequencesByFirstOpcode.put(firstOpcode, new LinkedList<NativeCodeSequence>());
        }
        nativeCodeSequencesByFirstOpcode.get(firstOpcode).add(nativeCodeSequence);
      } else {
        // First opcode has not mask: only slow lookup possible
        nativeCodeSequenceWithMaskInFirstOpcode.add(nativeCodeSequence);
      }
    }
  }
Esempio n. 3
0
  private void loadNativeCodeOpcodes(
      NativeCodeSequence nativeCodeSequence, String codeInstructions) {
    BufferedReader reader = new BufferedReader(new StringReader(codeInstructions));
    if (reader == null) {
      return;
    }

    Pattern codeInstructionPattern =
        Pattern.compile("\\s*((\\w+)\\s*:?\\s*)?\\[(\\p{XDigit}+)(/(\\p{XDigit}+))?\\].*");
    final int labelGroup = 2;
    final int opcodeGroup = 3;
    final int opcodeMaskGroup = 5;

    try {
      while (true) {
        String line = reader.readLine();
        if (line == null) {
          break;
        }

        line = line.trim();
        if (line.length() > 0) {
          try {
            Matcher codeInstructionMatcher = codeInstructionPattern.matcher(line);
            int opcode = 0;
            int mask = defaultOpcodeMask;
            String label = null;
            if (codeInstructionMatcher.matches()) {
              opcode = Utilities.parseAddress(codeInstructionMatcher.group(opcodeGroup));
              String opcodeMaskString = codeInstructionMatcher.group(opcodeMaskGroup);
              if (opcodeMaskString != null) {
                mask = Utilities.parseAddress(opcodeMaskString);
              }
              label = codeInstructionMatcher.group(labelGroup);
            } else {
              opcode = Utilities.parseAddress(line.trim());
            }

            nativeCodeSequence.addOpcode(opcode, mask, label);
          } catch (NumberFormatException e) {
            Compiler.log.error(e);
          }
        }
      }
    } catch (IOException e) {
      Compiler.log.error(e);
    }
  }
Esempio n. 4
0
  private void loadBeforeCodeInstructions(
      NativeCodeSequence nativeCodeSequence, String codeInstructions) {
    BufferedReader reader = new BufferedReader(new StringReader(codeInstructions));
    if (reader == null) {
      return;
    }

    Pattern codeInstructionPattern = Pattern.compile("\\s*(\\w+\\s*:?\\s*)?\\[(\\p{XDigit}+)\\].*");
    final int opcodeGroup = 2;
    final int address = 0;

    try {
      while (true) {
        String line = reader.readLine();
        if (line == null) {
          break;
        }

        line = line.trim();
        if (line.length() > 0) {
          try {
            Matcher codeInstructionMatcher = codeInstructionPattern.matcher(line);
            int opcode = 0;
            if (codeInstructionMatcher.matches()) {
              opcode = Utilities.parseAddress(codeInstructionMatcher.group(opcodeGroup));
            } else {
              opcode = Utilities.parseAddress(line.trim());
            }

            Common.Instruction insn = Decoder.instruction(opcode);
            CodeInstruction codeInstruction =
                new CodeInstruction(address, opcode, insn, false, false, 0);

            nativeCodeSequence.addBeforeCodeInstruction(codeInstruction);
          } catch (NumberFormatException e) {
            Compiler.log.error(e);
          }
        }
      }
    } catch (IOException e) {
      Compiler.log.error(e);
    }
  }
Esempio n. 5
0
  private void setParameter(
      NativeCodeSequence nativeCodeSequence, int parameter, String valueString) {
    if (valueString == null || valueString.length() <= 0) {
      nativeCodeSequence.setParameter(parameter, 0, false);
      return;
    }

    for (int i = 0; i < Common.gprNames.length; i++) {
      if (Common.gprNames[i].equals(valueString)) {
        nativeCodeSequence.setParameter(parameter, i, false);
        return;
      }
    }

    for (int i = 0; i < Common.fprNames.length; i++) {
      if (Common.fprNames[i].equals(valueString)) {
        nativeCodeSequence.setParameter(parameter, i, false);
        return;
      }
    }

    if (valueString.startsWith("@")) {
      String label = valueString.substring(1);
      int labelIndex = nativeCodeSequence.getLabelIndex(label);
      if (labelIndex >= 0) {
        nativeCodeSequence.setParameter(parameter, labelIndex, true);
        return;
      }
    }

    try {
      int value;
      if (valueString.startsWith("0x")) {
        value = Integer.parseInt(valueString.substring(2), 16);
      } else {
        value = Integer.parseInt(valueString);
      }
      nativeCodeSequence.setParameter(parameter, value, false);
    } catch (NumberFormatException e) {
      Compiler.log.error(e);
    }
  }
Esempio n. 6
0
  private void loadNativeCodeSequence(Element element) {
    String name = element.getAttribute("name");
    String className = getContent(element.getElementsByTagName("Class"));

    Class<INativeCodeSequence> nativeCodeSequenceClass = getNativeCodeSequenceClass(className);
    if (nativeCodeSequenceClass == null) {
      return;
    }

    NativeCodeSequence nativeCodeSequence = new NativeCodeSequence(name, nativeCodeSequenceClass);

    String isReturningString = getContent(element.getElementsByTagName("IsReturning"));
    if (isReturningString != null) {
      nativeCodeSequence.setReturning(Boolean.parseBoolean(isReturningString));
    }

    String wholeCodeBlockString = getContent(element.getElementsByTagName("WholeCodeBlock"));
    if (wholeCodeBlockString != null) {
      nativeCodeSequence.setWholeCodeBlock(Boolean.parseBoolean(wholeCodeBlockString));
    }

    String methodName = getContent(element.getElementsByTagName("Method"));
    if (methodName != null) {
      nativeCodeSequence.setMethodName(methodName);
    }

    String isHookString = getContent(element.getElementsByTagName("IsHook"));
    if (isHookString != null) {
      nativeCodeSequence.setHook(Boolean.parseBoolean(isHookString));
    }

    String isMethodRetuningString = getContent(element.getElementsByTagName("IsMethodReturning"));
    if (isMethodRetuningString != null) {
      nativeCodeSequence.setMethodReturning(Boolean.parseBoolean(isMethodRetuningString));
    }

    String codeInstructions = getContent(element.getElementsByTagName("CodeInstructions"));
    loadNativeCodeOpcodes(nativeCodeSequence, codeInstructions);

    // The "Parameters" and "BranchInstruction" have to be parsed after "CodeInstructions"
    // because they are using them (e.g. instruction labels)
    String parametersList = getContent(element.getElementsByTagName("Parameters"));
    if (parametersList != null) {
      String[] parameters = parametersList.split(" *, *");
      for (int parameter = 0; parameters != null && parameter < parameters.length; parameter++) {
        setParameter(nativeCodeSequence, parameter, parameters[parameter].trim());
      }
    }

    String branchInstructionLabel = getContent(element.getElementsByTagName("BranchInstruction"));
    if (branchInstructionLabel != null) {
      if (branchInstructionLabel.startsWith("@")) {
        branchInstructionLabel = branchInstructionLabel.substring(1);
      }
      int branchInstructionOffset = nativeCodeSequence.getLabelIndex(branchInstructionLabel.trim());
      if (branchInstructionOffset >= 0) {
        nativeCodeSequence.setBranchInstruction(branchInstructionOffset);
      } else {
        Compiler.log.error(
            String.format("BranchInstruction: label '%s' not found", branchInstructionLabel));
      }
    }

    String beforeCodeInstructions =
        getContent(element.getElementsByTagName("BeforeCodeInstructions"));
    if (beforeCodeInstructions != null) {
      loadBeforeCodeInstructions(nativeCodeSequence, beforeCodeInstructions);
    }

    addNativeCodeSequence(nativeCodeSequence);
  }