Skip to content

Commit

Permalink
Add operand keywords in BinExport exporter
Browse files Browse the repository at this point in the history
PiperOrigin-RevId: 667998113
Change-Id: I5b16e54170cc64016d544432ec068a11bf7db664
  • Loading branch information
Lin Chen authored and copybara-github committed Aug 27, 2024
1 parent 7a1534a commit 757381f
Showing 1 changed file with 73 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@

package com.google.security.binexport;

import static java.util.stream.Collectors.joining;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
Expand All @@ -28,6 +30,7 @@
import ghidra.program.model.block.CodeBlock;
import ghidra.program.model.block.CodeBlockReference;
import ghidra.program.model.data.StringDataInstance;
import ghidra.program.model.lang.OperandType;
import ghidra.program.model.lang.Register;
import ghidra.program.model.listing.CodeUnit;
import ghidra.program.model.listing.CodeUnitFormat;
Expand Down Expand Up @@ -61,6 +64,7 @@
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Optional;
Expand Down Expand Up @@ -165,6 +169,12 @@ private void buildMetaInformation() {
"tword ptr ", 10,
"xmmword ptr ", 16);

static final ImmutableSet<String> OPERAND_SHIFT_SYMBOLS =
ImmutableSet.of("asr", "lsl", "lsr", "ror", "rrx");
static final ImmutableSet<String> OPERAND_CONDITION_SYMBOLS =
ImmutableSet.of(
"eq", "ne", "cs", "hs", "cc", "lo", "mi", "pl", "vs", "vc", "hi", "ls", "ge", "lt", "gt",
"le", "al");
// Ghidra separates operands of an instruction already for us.
// The separators and brackets don't and are difficult to represent any semantically meanings.
// Instead, it only helps to determine the priorities of expression tree nodes.
Expand Down Expand Up @@ -259,6 +269,7 @@ private Optional<Integer> addCommentedExpression(
private void buildOperandExpressions(
Integer startOffset,
Integer endOffset,
Integer operandType,
ImmutableList<? extends Object> operandList,
ImmutableList<? extends Object> operandMarkupList,
Integer parentId,
Expand All @@ -273,6 +284,58 @@ private void buildOperandExpressions(
if (parentId != null) {
exprBuilder.setParentIndex(parentId);
}

// Find shift keywords
var operandSubstring =
operandMarkupList.subList(startOffset, endOffset).stream()
.map(Object::toString)
.collect(joining(""))
.toLowerCase(Locale.getDefault());

for (var symbol : OPERAND_SHIFT_SYMBOLS) {
if (!operandSubstring.startsWith(symbol)) {
continue;
}
var expr = exprBuilder.setType(BinExport2.Expression.Type.OPERATOR).setSymbol(symbol).build();
var nextParentId = getOrAddExpression(expr);
opExprIndices.add(nextParentId);
buildOperandExpressions(
startOffset + symbol.length(),
endOffset,
operandType,
operandList,
operandMarkupList,
nextParentId,
opExprIndices,
addComment,
comments);
return;
}

// Find Condition keywords
if (OperandType.isFlag(operandType)) {
for (var symbol : OPERAND_CONDITION_SYMBOLS) {
if (!operandSubstring.startsWith(symbol)) {
continue;
}
var expr =
exprBuilder.setType(BinExport2.Expression.Type.OPERATOR).setSymbol(symbol).build();
var nextParentId = getOrAddExpression(expr);
opExprIndices.add(nextParentId);
buildOperandExpressions(
startOffset + symbol.length(),
endOffset,
operandType,
operandList,
operandMarkupList,
nextParentId,
opExprIndices,
addComment,
comments);
return;
}
}

// Find first non-enclosing separator
var openClosure = 0;
for (var i = startOffset; i < endOffset; i++) {
Expand Down Expand Up @@ -300,6 +363,7 @@ private void buildOperandExpressions(
buildOperandExpressions(
startOffset,
i,
operandType,
operandList,
operandMarkupList,
separatorId,
Expand All @@ -309,6 +373,7 @@ private void buildOperandExpressions(
buildOperandExpressions(
i + 1,
endOffset,
operandType,
operandList,
operandMarkupList,
separatorId,
Expand All @@ -334,6 +399,7 @@ private void buildOperandExpressions(
buildOperandExpressions(
startOffset,
endOffset - 1,
operandType,
operandList,
operandMarkupList,
nextParentId,
Expand Down Expand Up @@ -375,6 +441,7 @@ private void buildOperandExpressions(
buildOperandExpressions(
startOffset + 1,
j,
operandType,
operandList,
operandMarkupList,
nextParentId,
Expand All @@ -384,6 +451,7 @@ private void buildOperandExpressions(
buildOperandExpressions(
j + 1,
endOffset,
operandType,
operandList,
operandMarkupList,
parentId,
Expand Down Expand Up @@ -464,6 +532,7 @@ private void buildOperandExpressions(
buildOperandExpressions(
startOffset + 1,
endOffset,
operandType,
operandList,
operandMarkupList,
nextParentId,
Expand All @@ -484,6 +553,7 @@ private ImmutableList<Integer> buildInstructionOperands(
Boolean addComment = operandMarkupList.size() == operandList.size();

Integer parentId = null;
Integer startOffset = 0;
var opExprIndices = new ArrayList<Integer>();

// Add size prefix if applicable
Expand All @@ -500,14 +570,13 @@ private ImmutableList<Integer> buildInstructionOperands(
.build();
parentId = getOrAddExpression(expr);
opExprIndices.add(parentId);
operandMarkupList =
operandMarkupList.subList(entry.getKey().length(), operandMarkupList.size());
operandList = operandList.subList(entry.getKey().length(), operandList.size());
startOffset += entry.getKey().length();
break;
}
buildOperandExpressions(
0,
startOffset,
operandMarkupList.size(),
instr.getOperandType(i),
operandList,
operandMarkupList,
parentId,
Expand Down

0 comments on commit 757381f

Please sign in to comment.