mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-03 09:49:23 +02:00
GP-4287: Format. Revise. Certify.
This commit is contained in:
parent
43131199cf
commit
e645d74a5f
10 changed files with 160 additions and 101 deletions
|
@ -2,5 +2,5 @@
|
||||||
##MODULE IP: FAMFAMFAM Icons - CC 2.5
|
##MODULE IP: FAMFAMFAM Icons - CC 2.5
|
||||||
##MODULE IP: Oxygen Icons - LGPL 3.0
|
##MODULE IP: Oxygen Icons - LGPL 3.0
|
||||||
Module.manifest||GHIDRA||||END|
|
Module.manifest||GHIDRA||||END|
|
||||||
src/main/help/help/TOC_Source.xml||GHIDRA||reviewed||END|
|
src/main/help/help/TOC_Source.xml||GHIDRA||||END|
|
||||||
src/main/help/help/topics/WildcardAssemblerModule/Wildcard_Assembler.html||GHIDRA||||END|
|
src/main/help/help/topics/WildcardAssemblerModule/Wildcard_Assembler.html||GHIDRA||||END|
|
||||||
|
|
|
@ -29,35 +29,28 @@
|
||||||
// See the "WildSleighAssemblerInfo" script for a simpler use of the WildSleighAssembler.
|
// See the "WildSleighAssemblerInfo" script for a simpler use of the WildSleighAssembler.
|
||||||
// @category Examples
|
// @category Examples
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import ghidra.app.plugin.assembler.AssemblySelector;
|
import ghidra.app.plugin.assembler.AssemblySelector;
|
||||||
import ghidra.app.plugin.assembler.sleigh.parse.AssemblyParseResult;
|
import ghidra.app.plugin.assembler.sleigh.parse.AssemblyParseResult;
|
||||||
import ghidra.app.plugin.assembler.sleigh.sem.AssemblyPatternBlock;
|
import ghidra.app.plugin.assembler.sleigh.sem.*;
|
||||||
import ghidra.app.plugin.assembler.sleigh.sem.AssemblyResolution;
|
|
||||||
import ghidra.app.plugin.assembler.sleigh.sem.AssemblyResolutionResults;
|
|
||||||
import ghidra.app.plugin.processors.sleigh.SleighLanguage;
|
import ghidra.app.plugin.processors.sleigh.SleighLanguage;
|
||||||
import ghidra.app.script.GhidraScript;
|
import ghidra.app.script.GhidraScript;
|
||||||
import ghidra.asm.wild.WildOperandInfo;
|
import ghidra.asm.wild.*;
|
||||||
import ghidra.asm.wild.WildSleighAssembler;
|
|
||||||
import ghidra.asm.wild.WildSleighAssemblerBuilder;
|
|
||||||
import ghidra.asm.wild.sem.WildAssemblyResolvedPatterns;
|
import ghidra.asm.wild.sem.WildAssemblyResolvedPatterns;
|
||||||
import ghidra.program.model.mem.*;
|
import ghidra.program.model.address.Address;
|
||||||
import ghidra.program.model.address.*;
|
import ghidra.program.model.mem.Memory;
|
||||||
|
import ghidra.program.model.mem.MemoryAccessException;
|
||||||
|
|
||||||
public class FindInstructionWithWildcard extends GhidraScript {
|
public class FindInstructionWithWildcard extends GhidraScript {
|
||||||
|
|
||||||
|
@Override
|
||||||
public void run() throws Exception {
|
public void run() throws Exception {
|
||||||
|
|
||||||
var instruction = askString("Instruction to search",
|
var instruction = askString("Instruction to search", """
|
||||||
"Instruction to search for with wildcard (example is for x86_64, adjust if you are using a different architecture):",
|
Instruction to search for with wildcard (example is for x86_64, adjust if you are \
|
||||||
"XOR R13D,`Q1/R1(2|3)D`");
|
using a different architecture): \
|
||||||
|
XOR R13D,`Q1/R1(2|3)D`""");
|
||||||
var allValidResults = getAllResolvedPatterns(instruction);
|
var allValidResults = getAllResolvedPatterns(instruction);
|
||||||
|
|
||||||
var encodings = getMapOfUniqueInstructionEncodings(allValidResults);
|
var encodings = getMapOfUniqueInstructionEncodings(allValidResults);
|
||||||
|
@ -175,8 +168,7 @@ public class FindInstructionWithWildcard extends GhidraScript {
|
||||||
* Returns true of the given value shares the same {@code maskedInstruction} and wildcard(s)
|
* Returns true of the given value shares the same {@code maskedInstruction} and wildcard(s)
|
||||||
* as this instance.
|
* as this instance.
|
||||||
*
|
*
|
||||||
* @param other
|
* @param other Value to compare against
|
||||||
* Value to compare against
|
|
||||||
* @return True if both values share the same maskedInstruction and wildcard(s)
|
* @return True if both values share the same maskedInstruction and wildcard(s)
|
||||||
*/
|
*/
|
||||||
boolean sameBaseEncoding(ReducedWildcardAssemblyResolvedPattern other) {
|
boolean sameBaseEncoding(ReducedWildcardAssemblyResolvedPattern other) {
|
||||||
|
@ -194,7 +186,7 @@ public class FindInstructionWithWildcard extends GhidraScript {
|
||||||
// Check all of other's WildOperandInfo
|
// Check all of other's WildOperandInfo
|
||||||
for (WildOperandInfo otherInfo : other.parent.getOperandInfo()) {
|
for (WildOperandInfo otherInfo : other.parent.getOperandInfo()) {
|
||||||
// Check if we have matching wildcards (names), expressions, and locations.
|
// Check if we have matching wildcards (names), expressions, and locations.
|
||||||
// Notice that we're *NOT* checking choice here, as we expect those to be different.
|
// We're *NOT* checking choice here, as we expect those to be different.
|
||||||
if (info.wildcard().equals(otherInfo.wildcard()) &&
|
if (info.wildcard().equals(otherInfo.wildcard()) &&
|
||||||
info.expression().equals(otherInfo.expression()) &&
|
info.expression().equals(otherInfo.expression()) &&
|
||||||
info.location().equals(otherInfo.location())) {
|
info.location().equals(otherInfo.location())) {
|
||||||
|
@ -222,10 +214,8 @@ public class FindInstructionWithWildcard extends GhidraScript {
|
||||||
* Does not currently print wildcard information about the search results, but this could be
|
* Does not currently print wildcard information about the search results, but this could be
|
||||||
* added.
|
* added.
|
||||||
*
|
*
|
||||||
* @param encodings
|
* @param encodings Map of encodings to that encoding's possible WildOperandInfo values.
|
||||||
* HashMap of encodings to that encoding's possible WildOperandInfo values.
|
* @throws MemoryAccessException If we find bytes but can't read them
|
||||||
* @throws MemoryAccessException
|
|
||||||
* If we find bytes but can't read them
|
|
||||||
*/
|
*/
|
||||||
private void searchMemoryForEncodings(
|
private void searchMemoryForEncodings(
|
||||||
Map<AssemblyPatternBlock, Set<WildOperandInfo>> encodings,
|
Map<AssemblyPatternBlock, Set<WildOperandInfo>> encodings,
|
||||||
|
@ -274,12 +264,11 @@ public class FindInstructionWithWildcard extends GhidraScript {
|
||||||
* NOTE: This is certainly not the highest performance way to do this, but it is reasonably
|
* NOTE: This is certainly not the highest performance way to do this, but it is reasonably
|
||||||
* simple and shows what is possible.
|
* simple and shows what is possible.
|
||||||
*
|
*
|
||||||
* @param matchAddress
|
* @param matchAddress The address where our search hit occurred
|
||||||
* The address where our search hit occurred
|
* @param matchData The bytes found at matchAddress. Must include the entire matching
|
||||||
* @param matchData
|
* instruction!
|
||||||
* The bytes found at matchAddress. Must include the entire matching instruction!
|
* @param allValidResolvedPatterns All resolved patterns which were searched from (used to find
|
||||||
* @param allValidResolvedPatterns
|
* wildcard information)
|
||||||
* All resolved patterns which were searched from (used to find wildcard information)
|
|
||||||
*/
|
*/
|
||||||
private void printSearchHitInfo(Address matchAddress, byte[] matchData,
|
private void printSearchHitInfo(Address matchAddress, byte[] matchData,
|
||||||
List<WildAssemblyResolvedPatterns> allValidResolvedPatterns) {
|
List<WildAssemblyResolvedPatterns> allValidResolvedPatterns) {
|
||||||
|
@ -321,8 +310,7 @@ public class FindInstructionWithWildcard extends GhidraScript {
|
||||||
* Return all items from {@code results} which are instances of
|
* Return all items from {@code results} which are instances of
|
||||||
* {@link WildAssemblyResolvedPatterns}
|
* {@link WildAssemblyResolvedPatterns}
|
||||||
*
|
*
|
||||||
* @param results
|
* @param results The results to return {@link WildAssemblyResolvePatterns} from
|
||||||
* The results to return {@link WildAssemblyResolvePatterns} from
|
|
||||||
* @return All {@link WildAssemblyResolvedPatterns} which were found in the input
|
* @return All {@link WildAssemblyResolvedPatterns} which were found in the input
|
||||||
*/
|
*/
|
||||||
private List<WildAssemblyResolvedPatterns> getValidResults(AssemblyResolutionResults results) {
|
private List<WildAssemblyResolvedPatterns> getValidResults(AssemblyResolutionResults results) {
|
||||||
|
|
|
@ -24,7 +24,6 @@
|
||||||
// See the "FindInstructionWithWildcard" script for another example of using the WildSleighAssembler
|
// See the "FindInstructionWithWildcard" script for another example of using the WildSleighAssembler
|
||||||
// @category Examples
|
// @category Examples
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
@ -34,16 +33,17 @@ import ghidra.app.plugin.assembler.sleigh.parse.AssemblyParseResult;
|
||||||
import ghidra.app.plugin.assembler.sleigh.sem.AssemblyResolution;
|
import ghidra.app.plugin.assembler.sleigh.sem.AssemblyResolution;
|
||||||
import ghidra.app.plugin.processors.sleigh.SleighLanguage;
|
import ghidra.app.plugin.processors.sleigh.SleighLanguage;
|
||||||
import ghidra.app.script.GhidraScript;
|
import ghidra.app.script.GhidraScript;
|
||||||
import ghidra.asm.wild.WildOperandInfo;
|
import ghidra.asm.wild.*;
|
||||||
import ghidra.asm.wild.WildSleighAssembler;
|
|
||||||
import ghidra.asm.wild.WildSleighAssemblerBuilder;
|
|
||||||
import ghidra.asm.wild.sem.WildAssemblyResolvedPatterns;
|
import ghidra.asm.wild.sem.WildAssemblyResolvedPatterns;
|
||||||
|
|
||||||
public class WildSleighAssemblerInfo extends GhidraScript {
|
public class WildSleighAssemblerInfo extends GhidraScript {
|
||||||
|
|
||||||
List<String> sampleInstructions =
|
List<String> sampleInstructions = List.of(
|
||||||
Arrays.asList("MOV EAX,`Q1`", "MOV RDI,qword ptr [`Q1` + -0x30]", "Custom");
|
"MOV EAX,`Q1`",
|
||||||
|
"MOV RDI,qword ptr [`Q1` + -0x30]",
|
||||||
|
"Custom");
|
||||||
|
|
||||||
|
@Override
|
||||||
public void run() throws Exception {
|
public void run() throws Exception {
|
||||||
|
|
||||||
String instruction = askChoice("Instruction to assemble", "Assemble this instruction:",
|
String instruction = askChoice("Instruction to assemble", "Assemble this instruction:",
|
||||||
|
@ -61,8 +61,8 @@ public class WildSleighAssemblerInfo extends GhidraScript {
|
||||||
/**
|
/**
|
||||||
* Use a {@link WildSleighAssembler} to assemble the given {@code wildcardedInstruction}
|
* Use a {@link WildSleighAssembler} to assemble the given {@code wildcardedInstruction}
|
||||||
*
|
*
|
||||||
* @param wildcardedInstruction
|
* @param wildcardedInstruction String of the instruction to assemble, possibly including a
|
||||||
* String of the instruction to assemble, possibly including a wildcard
|
* wildcard
|
||||||
* @return All AssemblyParseResult produced from the given input
|
* @return All AssemblyParseResult produced from the given input
|
||||||
*/
|
*/
|
||||||
private List<AssemblyResolution> getAllAssemblyResolutions(
|
private List<AssemblyResolution> getAllAssemblyResolutions(
|
||||||
|
@ -74,10 +74,10 @@ public class WildSleighAssemblerInfo extends GhidraScript {
|
||||||
// correct architecture.
|
// correct architecture.
|
||||||
if (sampleInstructions.contains(wildcardedInstruction) &&
|
if (sampleInstructions.contains(wildcardedInstruction) &&
|
||||||
!language.getLanguageID().toString().equals("x86:LE:64:default")) {
|
!language.getLanguageID().toString().equals("x86:LE:64:default")) {
|
||||||
popup(
|
popup("""
|
||||||
"The current program is not a \"x86:LE:64:default\" binary that the example was " +
|
The current program is not a \"x86:LE:64:default\" binary that the example was \
|
||||||
"designed for. This script will continue and try anyway, but the results might " +
|
designed for. This script will continue and try anyway, but the results might \
|
||||||
"not be as expected. Retry with a custom instruction in your architecture!");
|
not be as expected. Retry with a custom instruction in your architecture!""");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a WildSleighAssembler that we'll use to assemble our wildcard-included instruction
|
// Create a WildSleighAssembler that we'll use to assemble our wildcard-included instruction
|
||||||
|
@ -123,9 +123,8 @@ public class WildSleighAssemblerInfo extends GhidraScript {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (errorCount > 0) {
|
if (errorCount > 0) {
|
||||||
println(
|
println("Additionally, " + errorCount +
|
||||||
"Additionally " + errorCount +
|
" non-WildAssemblyResolvedPatterns were not printed");
|
||||||
" non-WildAssemblyResolvedPatterns were not printed");
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -134,8 +133,7 @@ public class WildSleighAssemblerInfo extends GhidraScript {
|
||||||
* Print information about a single {@link WildAssemblyResolvedPatterns}, including information
|
* Print information about a single {@link WildAssemblyResolvedPatterns}, including information
|
||||||
* about each of its wildcards.
|
* about each of its wildcards.
|
||||||
*
|
*
|
||||||
* @param x
|
* @param x The value to print information about.
|
||||||
* The value to print information about.
|
|
||||||
*/
|
*/
|
||||||
private void printWildAssemblyResolvedPatterns(WildAssemblyResolvedPatterns x) {
|
private void printWildAssemblyResolvedPatterns(WildAssemblyResolvedPatterns x) {
|
||||||
println("Instruction bits (including wildcard values): " + x.getInstruction());
|
println("Instruction bits (including wildcard values): " + x.getInstruction());
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
<HTML>
|
<HTML>
|
||||||
<HEAD>
|
<HEAD>
|
||||||
|
<META name="generator" content=
|
||||||
|
"HTML Tidy for Java (vers. 2009-12-01), see jtidy.sourceforge.net">
|
||||||
<META http-equiv="Content-Language" content="en-us">
|
<META http-equiv="Content-Language" content="en-us">
|
||||||
<META http-equiv="Content-Type" content="text/html; charset=windows-1252">
|
<META http-equiv="Content-Type" content="text/html; charset=windows-1252">
|
||||||
|
|
||||||
|
@ -13,84 +15,93 @@
|
||||||
<H1><A name="Wildcard_Assembler_Module"></A>Wildcard Assembler Module</H1>
|
<H1><A name="Wildcard_Assembler_Module"></A>Wildcard Assembler Module</H1>
|
||||||
|
|
||||||
<BLOCKQUOTE>
|
<BLOCKQUOTE>
|
||||||
|
<P><B>This feature is currently only available as an API for Ghidra scripts and plugins. For
|
||||||
|
an example of how to use the API, see the FindInstructionWithWildcard and
|
||||||
|
WildSleighAssemblerInfo scripts in the Script Manager.</B></P>
|
||||||
|
|
||||||
<P><B>This feature is currently only available as an API for Ghidra
|
<P>The <I>Wildcard Assembler</I> extends Ghidra's assembler to enable assembling instructions
|
||||||
scripts and plugins. For an example of how to use the API, see the
|
with specific tokens replaced with wildcards.</P>
|
||||||
FindInstructionWithWildcard and WildSleighAssemblerInfo scripts in the
|
|
||||||
Script Manager.</B></P>
|
|
||||||
|
|
||||||
<P>The <I>Wildcard Assembler</I> extends Ghidra's assembler to enable
|
<P>This assembler will return metadata for each wildcard in an assembled instruction. This
|
||||||
assembling instructions with specific tokens replaced with wildcards.</P>
|
metadata includes details of which specific bits of an assembled instruction are used to
|
||||||
|
derive the value of the wildcarded token and the expression used to derive the value.</P>
|
||||||
<p>This assembler will return metadata for each wildcard in an assembled
|
|
||||||
instruction. This metadata includes details of which specific bits of an
|
|
||||||
assembled instruction are used to derive the value of the wildcarded token
|
|
||||||
and the expression used to derive the value.</p>
|
|
||||||
|
|
||||||
<H2>Wildcard Syntax</H2>
|
<H2>Wildcard Syntax</H2>
|
||||||
|
|
||||||
<P>Wildcards in instructions are specified by replacing the
|
<P>Wildcards in instructions are specified by replacing the to-be-wildcarded token with a
|
||||||
to-be-wildcarded token with a wildcard name surrounded by backticks (e.g.
|
wildcard name surrounded by backticks (e.g. <CODE>`Q1`</CODE> where Q1 is an arbitrary
|
||||||
<CODE>`Q1`</CODE> where Q1 is an arbitrary wildcard name) and passing the
|
wildcard name) and passing the entire instruction to the Wildcard Assembler.</P>
|
||||||
entire instruction to the Wildcard Assembler.</P>
|
|
||||||
|
|
||||||
<P>By default, the Wildcard Assembler will return metadata about all
|
<P>By default, the Wildcard Assembler will return metadata about all possible values that a
|
||||||
possible values that a wildcarded token could take and all the encodings
|
wildcarded token could take and all the encodings of all these values. This behavior can be
|
||||||
of all these values. This behavior can be limited by filtering the
|
limited by filtering the wildcard by appending specific syntax after the wildcard name:</P>
|
||||||
wildcard by appending specific syntax after the wildcard name:</P>
|
|
||||||
|
|
||||||
<UL>
|
<UL>
|
||||||
<LI><B>Numeric Filter:</B>
|
<LI>
|
||||||
|
<B>Numeric Filter:</B>
|
||||||
|
|
||||||
<UL>
|
<UL>
|
||||||
<LI>Appending <CODE>[..]</CODE> will constrain the wildcarded token
|
<LI>Appending <CODE>[..]</CODE> e.g., <CODE>MOV RAX, `Q1[..]`</CODE>, will constrain
|
||||||
to only numeric values (and not registers or other strings).</LI>
|
the wildcarded token to only numeric values (and not registers or other strings).</LI>
|
||||||
<LI>Appending <CODE>[0x0..0x100]</CODE> (where 0x0 and 0x100 are
|
|
||||||
arbitrary hexadecimal values with the smaller number first) will
|
<LI>Appending <CODE>[0x0..0x100]</CODE> (where 0x0 and 0x100 are arbitrary hexadecimal
|
||||||
constrain the wildcarded token to only numeric values between the
|
values with the smaller number first) will constrain the wildcarded token to only
|
||||||
two given values. This can be used to ensure that the returned
|
numeric values between the two given values. This can be used to ensure that the
|
||||||
encodings can hold values of a desired size. Multiple non-contiguous
|
returned encodings can hold values of a desired size. Multiple non-contiguous ranges
|
||||||
ranges can be specified by separating them with commas (e.g.
|
can be specified by separating them with commas (e.g.
|
||||||
<CODE>[0x0..0x5,0x1000-0x4000]</CODE>)</LI>
|
<CODE>[0x0..0x5,0x1000..0x4000]</CODE>)</LI>
|
||||||
</UL>
|
</UL>
|
||||||
</LI>
|
</LI>
|
||||||
<LI><B>Regex Filter:</B>
|
|
||||||
<UL>
|
<LI>
|
||||||
<LI>Appending <CODE>/ABCD</CODE> where ABCD is an arbitrary
|
<B>Regex Filter:</B>
|
||||||
regular expression will constrain the wildcarded token to only be
|
|
||||||
string tokens matching the given regular expression. This is most
|
<UL>
|
||||||
likely used for filtering register names; for example appending
|
<LI>Appending <CODE>/ABCD</CODE> where ABCD is an arbitrary regular expression will
|
||||||
<CODE>/(sp)|(lr)</CODE> to a wildcard in a register position in
|
constrain the wildcarded token to only be string tokens matching the given regular
|
||||||
ARM assembly will limit the wildcard results to only encodings
|
expression. This is most likely used for filtering register names; for example
|
||||||
using the <CODE>sp</CODE> or <CODE>lr</CODE> registers in that
|
appending <CODE>/(sp)|(lr)</CODE> to a wildcard in a register position in ARM assembly
|
||||||
position.</LI>
|
will limit the wildcard results to only encodings using the <CODE>sp</CODE> or
|
||||||
</UL>
|
<CODE>lr</CODE> registers in that position.</LI>
|
||||||
</LI>
|
</UL>
|
||||||
|
</LI>
|
||||||
</UL>
|
</UL>
|
||||||
|
|
||||||
<P>Normally a wildcard will only match a single token. To allow a single
|
<P>Normally a wildcard will only match a single token. For example, in a x86:LE:32:default
|
||||||
wildcard to match multiple related tokens: precede the wildcard name with a
|
binary:</P>
|
||||||
<CODE>!</CODE> character. For example, in a x86:LE:32:default binary:</P>
|
|
||||||
<BLOCKQUOTE>
|
<BLOCKQUOTE>
|
||||||
<DL>
|
<DL>
|
||||||
<DT>No wildcard:</DT>
|
<DT>No wildcard:</DT>
|
||||||
|
|
||||||
<DD><CODE>MOVSD.REP ES:EDI,ESI</CODE></DD>
|
<DD><CODE>MOVSD.REP ES:EDI,ESI</CODE></DD>
|
||||||
|
|
||||||
<DT>Single token:</DT>
|
<DT>Single token:</DT>
|
||||||
|
|
||||||
<DD><CODE>MOVSD.REP `Q1`:EDI,ESI</CODE></DD>
|
<DD><CODE>MOVSD.REP `Q1`:EDI,ESI</CODE></DD>
|
||||||
|
|
||||||
<DT>Single token:</DT>
|
<DT>Single token:</DT>
|
||||||
|
|
||||||
<DD><CODE>MOVSD.REP ES:`Q2`,ESI</CODE></DD>
|
<DD><CODE>MOVSD.REP ES:`Q2`,ESI</CODE></DD>
|
||||||
|
</DL>
|
||||||
|
</BLOCKQUOTE>
|
||||||
|
|
||||||
|
<P>To allow a single wildcard to match multiple related tokens: precede the wildcard name
|
||||||
|
with a <CODE>!</CODE> character:</P>
|
||||||
|
|
||||||
|
<BLOCKQUOTE>
|
||||||
|
<DL>
|
||||||
|
<DT>Multi-token:</DT>
|
||||||
|
|
||||||
|
<DD><CODE>MOVSD.REP `!Q4`,ESI</CODE></DD>
|
||||||
|
|
||||||
<DT>Single token (Does <I>NOT</I> assemble):</DT>
|
<DT>Single token (Does <I>NOT</I> assemble):</DT>
|
||||||
<DD><CODE>MOVSD.REP `Q3`,ESI</CODE></DD>
|
|
||||||
|
|
||||||
<DT>Multi-token:</DT>
|
<DD><CODE>MOVSD.REP `Q3`,ESI</CODE></DD>
|
||||||
<DD><CODE>MOVSD.REP `!Q4`,ESI</CODE></DD>
|
|
||||||
</DL>
|
</DL>
|
||||||
</BLOCKQUOTE>
|
</BLOCKQUOTE>
|
||||||
|
|
||||||
<P class="providedbyplugin">Provided by: <I>Wildcard Assembler Module</I></P>
|
<P class="providedbyplugin">Provided by: <I>Wildcard Assembler Module</I></P>
|
||||||
|
|
||||||
</BLOCKQUOTE>
|
</BLOCKQUOTE>
|
||||||
</BODY>
|
</BODY>
|
||||||
</HTML>
|
</HTML>
|
||||||
|
|
|
@ -21,9 +21,25 @@ import ghidra.app.plugin.assembler.sleigh.sem.AssemblyConstructorSemantic;
|
||||||
import ghidra.app.plugin.assembler.sleigh.sem.AssemblyPatternBlock;
|
import ghidra.app.plugin.assembler.sleigh.sem.AssemblyPatternBlock;
|
||||||
import ghidra.app.plugin.processors.sleigh.expression.PatternExpression;
|
import ghidra.app.plugin.processors.sleigh.expression.PatternExpression;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Information about an operand that was matched to a wildcard
|
||||||
|
*
|
||||||
|
* @param wildcard the name of the wildcard that matched the operand
|
||||||
|
* @param path the hierarchy of Sleigh constructors leading to the operand
|
||||||
|
* @param location the bit pattern giving the location of the operand's field(s) in the machine
|
||||||
|
* instruction
|
||||||
|
* @param expression the expression describing how to encode the operand in the field(s)
|
||||||
|
* @param choice if applicable, the value encoded in the result containing this information
|
||||||
|
*/
|
||||||
public record WildOperandInfo(String wildcard, List<AssemblyConstructorSemantic> path,
|
public record WildOperandInfo(String wildcard, List<AssemblyConstructorSemantic> path,
|
||||||
AssemblyPatternBlock location, PatternExpression expression, Object choice) {
|
AssemblyPatternBlock location, PatternExpression expression, Object choice) {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy this wildcard info, but with an increased shift amount
|
||||||
|
*
|
||||||
|
* @param amt the number of bits to shift (right)
|
||||||
|
* @return the copy
|
||||||
|
*/
|
||||||
public WildOperandInfo shift(int amt) {
|
public WildOperandInfo shift(int amt) {
|
||||||
return new WildOperandInfo(wildcard, path, location.shift(amt), expression, choice);
|
return new WildOperandInfo(wildcard, path, location.shift(amt), expression, choice);
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,12 @@ import ghidra.asm.wild.sem.WildAssemblyTreeResolver;
|
||||||
import ghidra.program.model.address.Address;
|
import ghidra.program.model.address.Address;
|
||||||
import ghidra.program.model.listing.Program;
|
import ghidra.program.model.listing.Program;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An assembler implementation that allows for wildcard operands
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* Construct these using {@link WildSleighAssemblerBuilder}.
|
||||||
|
*/
|
||||||
public class WildSleighAssembler extends AbstractSleighAssembler<WildAssemblyResolvedPatterns> {
|
public class WildSleighAssembler extends AbstractSleighAssembler<WildAssemblyResolvedPatterns> {
|
||||||
|
|
||||||
protected WildSleighAssembler(
|
protected WildSleighAssembler(
|
||||||
|
|
|
@ -19,6 +19,7 @@ import java.util.*;
|
||||||
|
|
||||||
import ghidra.app.plugin.assembler.AssemblySelector;
|
import ghidra.app.plugin.assembler.AssemblySelector;
|
||||||
import ghidra.app.plugin.assembler.sleigh.AbstractSleighAssemblerBuilder;
|
import ghidra.app.plugin.assembler.sleigh.AbstractSleighAssemblerBuilder;
|
||||||
|
import ghidra.app.plugin.assembler.sleigh.SleighAssemblerBuilder;
|
||||||
import ghidra.app.plugin.assembler.sleigh.grammars.AssemblyGrammar;
|
import ghidra.app.plugin.assembler.sleigh.grammars.AssemblyGrammar;
|
||||||
import ghidra.app.plugin.assembler.sleigh.grammars.AssemblySentential;
|
import ghidra.app.plugin.assembler.sleigh.grammars.AssemblySentential;
|
||||||
import ghidra.app.plugin.assembler.sleigh.sem.AbstractAssemblyResolutionFactory;
|
import ghidra.app.plugin.assembler.sleigh.sem.AbstractAssemblyResolutionFactory;
|
||||||
|
@ -33,11 +34,32 @@ import ghidra.asm.wild.sem.WildAssemblyResolvedPatterns;
|
||||||
import ghidra.asm.wild.symbol.*;
|
import ghidra.asm.wild.symbol.*;
|
||||||
import ghidra.program.model.listing.Program;
|
import ghidra.program.model.listing.Program;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The builder for wildcard-enabled assemblers.
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* Ideally, only one of these is created and cached per language, to save on the cost of building
|
||||||
|
* the assembler. However, if heap space needs to be freed up, then the builder must be disposed.
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* This is based on the same abstract class as {@link SleighAssemblerBuilder}. See its documentation
|
||||||
|
* for more information.
|
||||||
|
*/
|
||||||
public class WildSleighAssemblerBuilder
|
public class WildSleighAssemblerBuilder
|
||||||
extends AbstractSleighAssemblerBuilder<WildAssemblyResolvedPatterns, WildSleighAssembler> {
|
extends AbstractSleighAssemblerBuilder<WildAssemblyResolvedPatterns, WildSleighAssembler> {
|
||||||
|
|
||||||
protected final Map<AssemblySymbol, AssemblyNonTerminal> wildNTs = new HashMap<>();
|
protected final Map<AssemblySymbol, AssemblyNonTerminal> wildNTs = new HashMap<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct a builder for the given language
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* Once a builder is prepared for the given language, it can be used to build an assembler for
|
||||||
|
* any number of programs using that same language. Clients should take advantage of this to
|
||||||
|
* avoid re-incurring the steep cost of constructing an assembler for the same language.
|
||||||
|
*
|
||||||
|
* @param lang the language
|
||||||
|
*/
|
||||||
public WildSleighAssemblerBuilder(SleighLanguage lang) {
|
public WildSleighAssemblerBuilder(SleighLanguage lang) {
|
||||||
super(lang);
|
super(lang);
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,6 @@ import java.util.stream.Stream;
|
||||||
import ghidra.app.plugin.assembler.sleigh.sem.*;
|
import ghidra.app.plugin.assembler.sleigh.sem.*;
|
||||||
import ghidra.app.plugin.processors.sleigh.symbol.OperandSymbol;
|
import ghidra.app.plugin.processors.sleigh.symbol.OperandSymbol;
|
||||||
import ghidra.asm.wild.tree.WildAssemblyParseToken;
|
import ghidra.asm.wild.tree.WildAssemblyParseToken;
|
||||||
import ghidra.asm.wild.tree.WildAssemblyParseToken.RegexWildcard;
|
|
||||||
|
|
||||||
public class WildAssemblyFixedNumericStateGenerator
|
public class WildAssemblyFixedNumericStateGenerator
|
||||||
extends AbstractAssemblyStateGenerator<WildAssemblyParseToken> {
|
extends AbstractAssemblyStateGenerator<WildAssemblyParseToken> {
|
||||||
|
|
|
@ -22,10 +22,28 @@ import ghidra.app.plugin.assembler.sleigh.sem.*;
|
||||||
import ghidra.app.plugin.processors.sleigh.expression.PatternExpression;
|
import ghidra.app.plugin.processors.sleigh.expression.PatternExpression;
|
||||||
import ghidra.asm.wild.WildOperandInfo;
|
import ghidra.asm.wild.WildOperandInfo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The result of assembling an instruction with the wildcard assembler
|
||||||
|
*/
|
||||||
public interface WildAssemblyResolvedPatterns extends AssemblyResolvedPatterns {
|
public interface WildAssemblyResolvedPatterns extends AssemblyResolvedPatterns {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The information for wildcarded operands in this instruction
|
||||||
|
*
|
||||||
|
* @return the set of information
|
||||||
|
*/
|
||||||
Set<WildOperandInfo> getOperandInfo();
|
Set<WildOperandInfo> getOperandInfo();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a copy of this result with added wilcard information
|
||||||
|
*
|
||||||
|
* @param wildcard see {@link WildOperandInfo}
|
||||||
|
* @param path see {@link WildOperandInfo}
|
||||||
|
* @param location see {@link WildOperandInfo}
|
||||||
|
* @param expression see {@link WildOperandInfo}
|
||||||
|
* @param choice see {@link WildOperandInfo}
|
||||||
|
* @return the copy
|
||||||
|
*/
|
||||||
WildAssemblyResolvedPatterns withWildInfo(String wildcard,
|
WildAssemblyResolvedPatterns withWildInfo(String wildcard,
|
||||||
List<AssemblyConstructorSemantic> path, AssemblyPatternBlock location,
|
List<AssemblyConstructorSemantic> path, AssemblyPatternBlock location,
|
||||||
PatternExpression expression, Object choice);
|
PatternExpression expression, Object choice);
|
||||||
|
|
|
@ -157,6 +157,7 @@ public class AssemblyPatternBlock implements Comparable<AssemblyPatternBlock> {
|
||||||
* Convert a block from a disjoint pattern into an assembly pattern block
|
* Convert a block from a disjoint pattern into an assembly pattern block
|
||||||
*
|
*
|
||||||
* @param pat the pattern to convert
|
* @param pat the pattern to convert
|
||||||
|
* @param minLen the minimum byte length of the block
|
||||||
* @param context true to select the context block, false to select the instruction block
|
* @param context true to select the context block, false to select the instruction block
|
||||||
* @return the converted pattern block
|
* @return the converted pattern block
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue