mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2024-11-21 19:42:14 +00:00
Merge remote-tracking branch 'origin/GP-4889_Dan_detectPcPatches' into
patch (Closes #6867)
This commit is contained in:
commit
2b7a497235
@ -82,6 +82,10 @@ public class PatchStep implements Step {
|
|||||||
/**
|
/**
|
||||||
* Generate a single line of Sleigh
|
* Generate a single line of Sleigh
|
||||||
*
|
*
|
||||||
|
* @param language the target language
|
||||||
|
* @param address the (start) address of the variable
|
||||||
|
* @param data the bytes to write to the variable
|
||||||
|
* @return the Sleigh code
|
||||||
* @see #generateSleighLine(Language, Address, byte[], int)
|
* @see #generateSleighLine(Language, Address, byte[], int)
|
||||||
*/
|
*/
|
||||||
public static String generateSleighLine(Language language, Address address, byte[] data) {
|
public static String generateSleighLine(Language language, Address address, byte[] data) {
|
||||||
@ -169,10 +173,18 @@ public class PatchStep implements Step {
|
|||||||
if (register == null) {
|
if (register == null) {
|
||||||
throw new IllegalArgumentException("Could not find a register for " + min);
|
throw new IllegalArgumentException("Could not find a register for " + min);
|
||||||
}
|
}
|
||||||
|
if (register.getBaseRegister().isProgramCounter()) {
|
||||||
|
register = register.getBaseRegister();
|
||||||
|
}
|
||||||
int length = register.getNumBytes();
|
int length = register.getNumBytes();
|
||||||
array.getData(min.getOffset(), data, 0, length);
|
array.getData(register.getOffset(), data, 0, length);
|
||||||
BigInteger value = Utils.bytesToBigInteger(data, length, language.isBigEndian(), false);
|
BigInteger value = Utils.bytesToBigInteger(data, length, language.isBigEndian(), false);
|
||||||
result.add(String.format("%s=0x%s", register, value.toString(16)));
|
if (register.isProgramCounter()) {
|
||||||
|
result.add(String.format("goto 0x%s", value.toString(16)));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
result.add(String.format("%s=0x%s", register, value.toString(16)));
|
||||||
|
}
|
||||||
remains.remove(spanOfRegister(register));
|
remains.remove(spanOfRegister(register));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -371,20 +383,26 @@ public class PatchStep implements Step {
|
|||||||
// SemisparseArray is a bit overkill, no?
|
// SemisparseArray is a bit overkill, no?
|
||||||
Map<AddressSpace, SemisparseByteArray> result = new TreeMap<>();
|
Map<AddressSpace, SemisparseByteArray> result = new TreeMap<>();
|
||||||
for (PcodeOp op : prog.getCode()) {
|
for (PcodeOp op : prog.getCode()) {
|
||||||
// Only accept patches in form [mem/reg] = [constant]
|
// Only accept patches in form [mem/reg] = [constant], or goto [constant]
|
||||||
switch (op.getOpcode()) {
|
switch (op.getOpcode()) {
|
||||||
case PcodeOp.COPY:
|
case PcodeOp.COPY -> {
|
||||||
if (!getPatchCopyOp(language, result, op)) {
|
if (!getPatchCopyOp(language, result, op)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
break;
|
}
|
||||||
case PcodeOp.STORE:
|
case PcodeOp.STORE -> {
|
||||||
if (!getPatchStoreOp(language, result, op)) {
|
if (!getPatchStoreOp(language, result, op)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
break;
|
}
|
||||||
default:
|
case PcodeOp.BRANCH -> {
|
||||||
|
if (!getPatchBranchOp(language, result, op)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
default -> {
|
||||||
return null;
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
@ -410,8 +428,7 @@ public class PatchStep implements Step {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected boolean getPatchStoreOp(Language language,
|
protected boolean getPatchStoreOp(Language language,
|
||||||
Map<AddressSpace, SemisparseByteArray> result,
|
Map<AddressSpace, SemisparseByteArray> result, PcodeOp op) {
|
||||||
PcodeOp op) {
|
|
||||||
Varnode vnSpace = op.getInput(0);
|
Varnode vnSpace = op.getInput(0);
|
||||||
if (!vnSpace.isConstant()) {
|
if (!vnSpace.isConstant()) {
|
||||||
return false;
|
return false;
|
||||||
@ -432,4 +449,17 @@ public class PatchStep implements Step {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected boolean getPatchBranchOp(Language language,
|
||||||
|
Map<AddressSpace, SemisparseByteArray> result, PcodeOp op) {
|
||||||
|
Address target = op.getInput(0).getAddress();
|
||||||
|
if (target.getAddressSpace() != language.getDefaultSpace()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Register pc = language.getProgramCounter();
|
||||||
|
SemisparseByteArray array =
|
||||||
|
result.computeIfAbsent(pc.getAddressSpace(), as -> new SemisparseByteArray());
|
||||||
|
array.putData(pc.getOffset(),
|
||||||
|
Utils.longToBytes(target.getOffset(), pc.getNumBytes(), language.isBigEndian()));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user