Merge remote-tracking branch 'origin/GP-1881_Dan_editableReprColumn--SQUASHED'

This commit is contained in:
Ryan Kurtz 2022-05-06 23:26:26 -04:00
commit f249abfac0
12 changed files with 314 additions and 28 deletions

View file

@ -44,7 +44,21 @@ public class PatchStep implements Step {
protected String sleigh;
protected int hashCode;
public static String generateSleigh(Language language, Address address, byte[] data,
/**
* Generate a single line of Sleigh
*
* <p>
* Note that when length is greater than 8, this will generate constants which are too large for
* the Java implementation of Sleigh. Use {@link #generateSleigh(Language, Address, byte[])}
* instead to write the variable in chunks.
*
* @param language the target language
* @param address the (start) address of the variable
* @param data the bytes to write to the variable
* @param length the length of the variable
* @return the Sleigh code
*/
public static String generateSleighLine(Language language, Address address, byte[] data,
int length) {
BigInteger value = Utils.bytesToBigInteger(data, length, language.isBigEndian(), false);
if (address.isMemoryAddress()) {
@ -67,8 +81,34 @@ public class PatchStep implements Step {
return String.format("%s=0x%s", register, value.toString(16));
}
public static String generateSleigh(Language language, Address address, byte[] data) {
return generateSleigh(language, address, data, data.length);
/**
* Generate a single line of Sleigh
*
* @see #generateSleighLine(Language, Address, byte[], int)
*/
public static String generateSleighLine(Language language, Address address, byte[] data) {
return generateSleighLine(language, address, data, data.length);
}
/**
* Generate multiple lines of Sleigh, all to set a single variable
*
* @param language the target language
* @param address the (start) address of the variable
* @param data the bytes to write to the variable
* @return the lines of Sleigh code
*/
public static List<String> generateSleigh(Language language, Address address, byte[] data) {
List<String> result = new ArrayList<>();
generateSleigh(result, language, address, data);
return result;
}
protected static void generateSleigh(List<String> result, Language language, Address address,
byte[] data) {
SemisparseByteArray array = new SemisparseByteArray(); // TODO: Seems heavy-handed
array.putData(address.getOffset(), data);
generateSleigh(result, language, address.getAddressSpace(), array);
}
protected static List<String> generateSleigh(Language language,
@ -102,7 +142,7 @@ public class PatchStep implements Step {
Address min = chunk.getMinAddress();
int length = (int) chunk.getLength();
array.getData(min.getOffset(), data, 0, length);
result.add(generateSleigh(language, min, data, length));
result.add(generateSleighLine(language, min, data, length));
}
}
}

View file

@ -494,6 +494,7 @@ public class TraceSchedule implements Comparable<TraceSchedule> {
/**
* Returns the equivalent of executing this schedule then performing a given patch
*
* @param thread the thread context for the patch; cannot be null
* @param sleigh a single line of sleigh, excluding the terminating semicolon.
* @return the resulting schedule
*/
@ -509,4 +510,27 @@ public class TraceSchedule implements Comparable<TraceSchedule> {
ticks.coalescePatches(thread.getTrace().getBaseLanguage());
return new TraceSchedule(snap, ticks, new Sequence());
}
/**
* Returns the equivalent of executing this schedule then performing the given patches
*
* @param thread the thread context for the patch; cannot be null
* @param sleigh the lines of sleigh, excluding the terminating semicolons.
* @return the resulting schedule
*/
public TraceSchedule patched(TraceThread thread, List<String> sleigh) {
if (!this.pSteps.isNop()) {
Sequence pTicks = this.pSteps.clone();
for (String line : sleigh) {
pTicks.advance(new PatchStep(thread.getKey(), line));
}
pTicks.coalescePatches(thread.getTrace().getBaseLanguage());
return new TraceSchedule(snap, steps.clone(), pTicks);
}
Sequence ticks = this.steps.clone();
for (String line : sleigh) {
ticks.advance(new PatchStep(thread.getKey(), line));
}
return new TraceSchedule(snap, ticks, new Sequence());
}
}

View file

@ -15,12 +15,14 @@
*/
package ghidra.trace.util;
import java.math.BigInteger;
import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.function.BiConsumer;
import org.apache.commons.lang3.ArrayUtils;
import ghidra.pcode.utils.Utils;
import ghidra.program.model.address.*;
import ghidra.program.model.data.*;
import ghidra.program.model.lang.Register;
@ -122,6 +124,23 @@ public enum TraceRegisterUtils {
return addr.toString();
}
public static RegisterValue encodeValueRepresentationHackPointer(Register register,
TraceData data, String representation) throws DataTypeEncodeException {
DataType dataType = data.getBaseDataType();
if (data.getValueClass() != Address.class) {
byte[] bytes =
dataType.encodeRepresentation(representation, data, data, data.getLength());
BigInteger value = Utils.bytesToBigInteger(bytes, register.getMinimumByteSize(),
register.isBigEndian(), false);
return new RegisterValue(register, value);
}
Address addr = data.getTrace().getBaseAddressFactory().getAddress(representation);
if (addr == null) {
throw new DataTypeEncodeException("Invalid address", representation, dataType);
}
return new RegisterValue(register, addr.getOffsetAsBigInteger());
}
public static RegisterValue combineWithTraceBaseRegisterValue(RegisterValue rv, long snap,
TraceMemoryRegisterSpace regs, boolean requireKnown) {
Register reg = rv.getRegister();