use of com.google.security.zynamics.reil.OperandSize in project binnavi by google.
the class Helpers method writeMulResult.
public static ArrayList<ReilInstruction> writeMulResult(final ITranslationEnvironment environment, final long offset, final String result, final OperandSize size) {
final ArrayList<ReilInstruction> instructions = new ArrayList<ReilInstruction>();
final OperandSize archSize = environment.getArchitectureSize();
if (size == OperandSize.BYTE) {
// Store the result in AX
final String maskedEax = environment.getNextVariableString();
instructions.add(ReilHelpers.createAnd(offset, archSize, "eax", archSize, "4294901760", archSize, maskedEax));
instructions.add(ReilHelpers.createOr(offset + 1, OperandSize.WORD, result, archSize, maskedEax, archSize, "eax"));
return instructions;
} else if (size == OperandSize.WORD) {
// Store the result in DX:AX
final String maskResNeg = "4294901760";
final String maskedEax = environment.getNextVariableString();
final String maskedResult = environment.getNextVariableString();
final String maskedEdx = environment.getNextVariableString();
final String shiftedResult = environment.getNextVariableString();
// Store the lower half in AX
instructions.add(ReilHelpers.createAnd(offset, OperandSize.DWORD, "eax", OperandSize.DWORD, maskResNeg, OperandSize.DWORD, maskedEax));
instructions.add(ReilHelpers.createAnd(offset + 1, OperandSize.DWORD, result, OperandSize.DWORD, "65535", OperandSize.DWORD, maskedResult));
instructions.add(ReilHelpers.createOr(offset + 2, OperandSize.DWORD, maskedEax, OperandSize.DWORD, maskedResult, OperandSize.DWORD, "eax"));
// Store the upper half in DX
instructions.add(ReilHelpers.createAnd(offset + 3, OperandSize.DWORD, "edx", OperandSize.DWORD, maskResNeg, OperandSize.DWORD, maskedEdx));
instructions.add(ReilHelpers.createBsh(offset + 4, OperandSize.DWORD, result, OperandSize.DWORD, "-16", OperandSize.DWORD, shiftedResult));
instructions.add(ReilHelpers.createOr(offset + 5, OperandSize.DWORD, maskedEdx, OperandSize.DWORD, shiftedResult, OperandSize.DWORD, "edx"));
return instructions;
} else if (size == OperandSize.DWORD) {
// Store the result in EDX:EAX
instructions.add(ReilHelpers.createAnd(offset, OperandSize.QWORD, result, OperandSize.DWORD, "4294967295", OperandSize.DWORD, "eax"));
instructions.add(ReilHelpers.createBsh(offset + 1, OperandSize.QWORD, result, OperandSize.QWORD, "-32", OperandSize.DWORD, "edx"));
return instructions;
} else {
assert false;
return instructions;
}
}
use of com.google.security.zynamics.reil.OperandSize in project binnavi by google.
the class Helpers method loadFirstDivOperand.
public static TranslationResult loadFirstDivOperand(final ITranslationEnvironment environment, final long offset, final OperandSize size) {
final ArrayList<ReilInstruction> instructions = new ArrayList<ReilInstruction>();
final OperandSize archSize = environment.getArchitectureSize();
if (size == OperandSize.BYTE) {
final String dividend = environment.getNextVariableString();
instructions.add(ReilHelpers.createAnd(offset, archSize, "eax", OperandSize.BYTE, "255", OperandSize.BYTE, dividend));
return new TranslationResult(dividend, OperandSize.BYTE, TranslationResultType.REGISTER, null, instructions, offset);
} else if (size == OperandSize.WORD) {
final String extractedAx = environment.getNextVariableString();
final String extractedDx = environment.getNextVariableString();
final String shiftedDx = environment.getNextVariableString();
final String dividend = environment.getNextVariableString();
instructions.add(ReilHelpers.createAnd(offset, archSize, "eax", OperandSize.WORD, "65535", size, extractedAx));
instructions.add(ReilHelpers.createAnd(offset + 1, archSize, "edx", OperandSize.WORD, "65535", size, extractedDx));
instructions.add(ReilHelpers.createBsh(offset + 2, OperandSize.WORD, extractedDx, OperandSize.WORD, "16", OperandSize.DWORD, shiftedDx));
instructions.add(ReilHelpers.createOr(offset + 3, OperandSize.WORD, extractedAx, OperandSize.DWORD, shiftedDx, OperandSize.DWORD, dividend));
return new TranslationResult(dividend, OperandSize.DWORD, TranslationResultType.REGISTER, null, instructions, offset);
} else if (size == OperandSize.DWORD) {
final String shiftedEdx = environment.getNextVariableString();
final String dividend = environment.getNextVariableString();
instructions.add(ReilHelpers.createBsh(offset, OperandSize.DWORD, "edx", OperandSize.DWORD, "32", OperandSize.QWORD, shiftedEdx));
instructions.add(ReilHelpers.createOr(offset + 1, OperandSize.DWORD, "eax", OperandSize.QWORD, shiftedEdx, OperandSize.QWORD, dividend));
return new TranslationResult(dividend, OperandSize.QWORD, TranslationResultType.REGISTER, null, instructions, offset);
} else {
assert false;
return null;
}
}
use of com.google.security.zynamics.reil.OperandSize in project binnavi by google.
the class Helpers method generatePushAllRegisters.
/**
* Pushes all registers onto the stack (in correct order for pusha/pushaw)
*
* @param environment A valid translation environment
* @param baseOffset The next unused REIL offset
* @param size The size of the registers to push (either WORD or DWORD)
* @param instructions A list of REIL instructions where the new REIL code is added
*
* @throws IllegalArgumentException Thrown if any of the arguments are invalid
*/
public static void generatePushAllRegisters(final ITranslationEnvironment environment, final long baseOffset, final OperandSize size, final List<ReilInstruction> instructions) throws IllegalArgumentException {
Preconditions.checkNotNull(environment, "Error: Argument environment can't be null");
Preconditions.checkNotNull(size, "Error: Argument size can't be null");
Preconditions.checkNotNull(instructions, "Error: Argument instructions can't be null");
Preconditions.checkArgument((size == OperandSize.WORD) || (size == OperandSize.DWORD), "Error: Invalid size argument");
long offset = baseOffset;
final OperandSize archSize = environment.getArchitectureSize();
final String tempEsp = environment.getNextVariableString();
instructions.add(ReilHelpers.createStr(offset, archSize, "esp", archSize, tempEsp));
generateRegisterPush(environment, offset + 1, "eax", size, instructions);
offset = baseOffset + instructions.size();
generateRegisterPush(environment, offset, "ebx", size, instructions);
offset = baseOffset + instructions.size();
generateRegisterPush(environment, offset, "ecx", size, instructions);
offset = baseOffset + instructions.size();
generateRegisterPush(environment, offset, "edx", size, instructions);
offset = baseOffset + instructions.size();
generateRegisterPush(environment, offset, tempEsp, size, instructions);
offset = baseOffset + instructions.size();
generateRegisterPush(environment, offset, "ebp", size, instructions);
offset = baseOffset + instructions.size();
generateRegisterPush(environment, offset, "esi", size, instructions);
offset = baseOffset + instructions.size();
generateRegisterPush(environment, offset, "edi", size, instructions);
offset = baseOffset + instructions.size();
}
use of com.google.security.zynamics.reil.OperandSize in project binnavi by google.
the class Helpers method loadOperand.
/**
* Generates code that loads an x86 operand.
*
* This is done by first recursively calling loadOperand for all children of
* the current node, and then processing the current node in the operand tree.
*
* @param environment A valid translation environment.
* @param baseOffset Offset of the first instruction to translate.
* @param expression The operand tree node to translate next
* @param segmentOverride If any segment override was seen in the tree so far,
* it should be passed down the recursion
* @param size The size of the operand.
* @param loadOperand TODO(thomasdullien) The purpose of this argument is unknown.
*
* @return The result of the translation.
*
* @throws InternalTranslationException Thrown if an internal problem occurs
*/
private static TranslationResult loadOperand(final ITranslationEnvironment environment, final Long baseOffset, final IOperandTreeNode expression, final IOperandTreeNode segmentOverride, OperandSize size, final boolean loadOperand) throws InternalTranslationException {
// Obtain the string that describes the current node in the operand tree.
final String currentNodeValue = expression.getValue();
// Obtain the number of children of the current node. This will be needed
// in several places for different purposes, so we get it now.
final int numberOfChildren = expression.getChildren().size();
// reset the current operand size accordingly.
if (TranslationHelpers.isSizeExpression(expression)) {
size = OperandSize.sizeStringToValue(currentNodeValue);
}
// Now process all children of the current node and gather the results of
// the translation of the child nodes.
// Make a copy of baseOffset
Long newBaseOffset = baseOffset.longValue();
// so we can have reference semantics. It
// gets modified inside translateChildrenOfNode
// below.
final OperandSize childrenSize = isMemoryAccess(currentNodeValue) ? environment.getArchitectureSize() : size;
final List<TranslationResult> partialResults = translateChildrenOfNode(environment, expression, childrenSize, loadOperand, newBaseOffset);
switch(numberOfChildren) {
case 0:
return processLeafNode(environment, newBaseOffset, expression, size, loadOperand);
case 1:
// - Memory access nodes.
if (OperandSize.isSizeString(currentNodeValue)) {
// translateChildrenOfNode. Just return the translation.
return partialResults.get(0);
} else if (isSegmentExpression(currentNodeValue)) {
// translateChildrenOfNode. Just return the translation.
return partialResults.get(0);
} else if (isMemoryAccess(currentNodeValue)) {
return processSimpleMemoryAccess(environment, segmentOverride, size, loadOperand, partialResults.get(0));
} else {
throw new InternalTranslationException("Error: Unknown node type with one child during address operand translation");
}
default:
// always dealing with a compound memory dereference.
return processInOperandArithmetic(partialResults, environment, newBaseOffset, expression);
}
}
use of com.google.security.zynamics.reil.OperandSize in project binnavi by google.
the class Helpers method processInOperandArithmetic.
/**
* Deals with complicated arithmetic within operands, such as [ebx+ecx*2+2]
*
* @param partialResults The list of translations for the subtrees of the operand
* @param environment The translation environment to track temp registers etc.
* @param baseOffset The base address of this instruction.
* @param expression The current node in the tree to process.
* @return The result of the translation for the operand arithmetic.
* @throws InternalTranslationException
*/
private static TranslationResult processInOperandArithmetic(List<TranslationResult> partialResults, ITranslationEnvironment environment, long baseOffset, IOperandTreeNode expression) throws InternalTranslationException {
final String value = expression.getValue();
final OperandSize archSize = environment.getArchitectureSize();
final OperandSize nextSize = TranslationHelpers.getNextSize(archSize);
// This result will be filled with the merged results from partialResults.
TranslationResult finalResult = new TranslationResult("NEEDS_REPLACEMENT", archSize, TranslationResultType.REGISTER, "", new ArrayList<ReilInstruction>(), baseOffset);
if (value.equals("+") || (value.equals("*"))) {
// Join all the instructions from all partial results into a new list.
ArrayList<ReilInstruction> allInstructions = new ArrayList<>();
for (TranslationResult result : partialResults) {
allInstructions.addAll(result.getInstructions());
}
finalResult.updateBaseAndReil(baseOffset, allInstructions);
String source1 = partialResults.get(0).getRegister();
String source2 = partialResults.get(1).getRegister();
String currentTemporary = environment.getNextVariableString();
// to not reuse the temporaries here in the future.
for (int index = 2; index <= partialResults.size(); index++) {
addPlusOrTimesInOperandArithmetic(environment, value, source1, source2, currentTemporary, finalResult);
if (index < partialResults.size()) {
source1 = partialResults.get(index).getRegister();
source2 = currentTemporary;
}
}
// Add an AND to mask off extra bits in the address calculation.
final String truncationMask = String.valueOf(TranslationHelpers.getAllBitsMask(archSize));
finalResult.addInstruction(ReilHelpers.createAnd(0, nextSize, currentTemporary, nextSize, truncationMask, archSize, currentTemporary));
finalResult.updateResult(currentTemporary, archSize, "", TranslationResultType.REGISTER);
} else if (value.equals(":")) {
throw new InternalTranslationException("Error: Don't know how to deal with 1234:ABCD1234 (segment:address) operands.");
}
return finalResult;
}
Aggregations