mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-04 18:29:37 +02:00
GP-2834: Add Unwind Stack action, hovers for dynamic variable values.
This commit is contained in:
parent
01dfe6cab5
commit
df9a1e2756
105 changed files with 12292 additions and 482 deletions
|
@ -82,12 +82,54 @@ public class AssemblyBuffer {
|
|||
return emit(asm.assembleLine(getNext(), line));
|
||||
}
|
||||
|
||||
/**
|
||||
* Assemble a line and patch into the buffer
|
||||
*
|
||||
* <p>
|
||||
* This will not grow the buffer, so the instruction being patched must already exist in the
|
||||
* buffer. The typical use case is to fix up a reference:
|
||||
*
|
||||
* <pre>
|
||||
* AssemblyBuffer buf = new AssemblyBuffer(asm, entry);
|
||||
* // ...
|
||||
* Address jumpCheck = buf.getNext();
|
||||
* buf.assemble("JMP 0x" + buf.getNext()); // Template must accommodate expected jump distance
|
||||
* // ...
|
||||
* Address labelCheck = buf.getNext();
|
||||
* buf.assemble(jumpCheck, "JMP 0x" + labelCheck);
|
||||
* buf.assemble("CMP ECX, 0");
|
||||
* // ...
|
||||
* </pre>
|
||||
*
|
||||
* <p>
|
||||
* This does not check that the patched instruction matches length with the new instruction. In
|
||||
* fact, the buffer does not remember instruction boundaries at all. If verification is needed,
|
||||
* the caller should check the lengths of the returned byte arrays for the template and the
|
||||
* patch.
|
||||
*
|
||||
* @param at the address of the instruction to patch
|
||||
* @param line the line
|
||||
* @return the resulting bytes for the assembled instruction
|
||||
* @throws AssemblySyntaxException if the instruction cannot be parsed
|
||||
* @throws AssemblySemanticException if the instruction cannot be encoded
|
||||
* @throws IOException if the buffer cannot be written
|
||||
*/
|
||||
public byte[] assemble(Address at, String line)
|
||||
throws AssemblySyntaxException, AssemblySemanticException, IOException {
|
||||
byte[] full = baos.toByteArray();
|
||||
byte[] bytes = asm.assembleLine(at, line);
|
||||
System.arraycopy(bytes, 0, full, (int) at.subtract(entry), bytes.length);
|
||||
baos.reset();
|
||||
baos.write(full);
|
||||
return bytes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Append arbitrary bytes to the buffer
|
||||
*
|
||||
* @param bytes the bytes to append
|
||||
* @return bytes
|
||||
* @throws IOException if the bufgfer cannot be written
|
||||
* @throws IOException if the buffer cannot be written
|
||||
*/
|
||||
public byte[] emit(byte[] bytes) throws IOException {
|
||||
baos.write(bytes);
|
||||
|
|
|
@ -82,6 +82,7 @@ public class AssemblySelector {
|
|||
*/
|
||||
public Collection<AssemblyParseResult> filterParse(Collection<AssemblyParseResult> parse)
|
||||
throws AssemblySyntaxException {
|
||||
syntaxErrors.clear();
|
||||
boolean gotOne = false;
|
||||
for (AssemblyParseResult pr : parse) {
|
||||
if (pr.isError()) {
|
||||
|
@ -97,6 +98,26 @@ public class AssemblySelector {
|
|||
return parse;
|
||||
}
|
||||
|
||||
protected List<AssemblyResolvedPatterns> filterCompatibleAndSort(AssemblyResolutionResults rr,
|
||||
AssemblyPatternBlock ctx) throws AssemblySemanticException {
|
||||
semanticErrors.clear();
|
||||
List<AssemblyResolvedPatterns> sorted = new ArrayList<>();
|
||||
// Select only non-erroneous results whose contexts are compatible.
|
||||
for (AssemblyResolution ar : rr) {
|
||||
if (ar.isError()) {
|
||||
semanticErrors.add((AssemblyResolvedError) ar);
|
||||
continue;
|
||||
}
|
||||
AssemblyResolvedPatterns rc = (AssemblyResolvedPatterns) ar;
|
||||
sorted.add(rc);
|
||||
}
|
||||
if (sorted.isEmpty()) {
|
||||
throw new AssemblySemanticException(semanticErrors);
|
||||
}
|
||||
sorted.sort(compareBySizeThenBits);
|
||||
return sorted;
|
||||
}
|
||||
|
||||
/**
|
||||
* Select an instruction from the possible results.
|
||||
*
|
||||
|
@ -117,21 +138,7 @@ public class AssemblySelector {
|
|||
*/
|
||||
public AssemblyResolvedPatterns select(AssemblyResolutionResults rr,
|
||||
AssemblyPatternBlock ctx) throws AssemblySemanticException {
|
||||
List<AssemblyResolvedPatterns> sorted = new ArrayList<>();
|
||||
// Select only non-erroneous results whose contexts are compatible.
|
||||
for (AssemblyResolution ar : rr) {
|
||||
if (ar.isError()) {
|
||||
semanticErrors.add((AssemblyResolvedError) ar);
|
||||
continue;
|
||||
}
|
||||
AssemblyResolvedPatterns rc = (AssemblyResolvedPatterns) ar;
|
||||
sorted.add(rc);
|
||||
}
|
||||
if (sorted.isEmpty()) {
|
||||
throw new AssemblySemanticException(semanticErrors);
|
||||
}
|
||||
// Sort them
|
||||
sorted.sort(compareBySizeThenBits);
|
||||
List<AssemblyResolvedPatterns> sorted = filterCompatibleAndSort(rr, ctx);
|
||||
|
||||
// Pick just the first
|
||||
AssemblyResolvedPatterns res = sorted.get(0);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue