GP-653 added support for user-defined compiler spec extensions

This commit is contained in:
caheckman
2021-04-29 16:17:25 -04:00
committed by ghidra1
parent cce6807470
commit ed82c2cb34
2915 changed files with 333939 additions and 4451 deletions

View File

@@ -18,6 +18,7 @@ package ghidra.dalvik.dex.inject;
import java.io.IOException;
import ghidra.app.plugin.processors.sleigh.PcodeEmit;
import ghidra.app.plugin.processors.sleigh.SleighLanguage;
import ghidra.file.formats.android.dex.analyzer.DexAnalysisState;
import ghidra.file.formats.android.dex.format.*;
import ghidra.file.formats.android.dex.util.DexUtil;
@@ -30,6 +31,8 @@ import ghidra.program.model.listing.Program;
import ghidra.program.model.pcode.PcodeOp;
import ghidra.program.model.pcode.Varnode;
import ghidra.util.Msg;
import ghidra.util.xml.SpecXmlUtils;
import ghidra.xml.*;
/**
* The "uponentry" injection for a DEX method. We simulate DEX's register stack by copying values from
@@ -39,17 +42,21 @@ import ghidra.util.Msg;
public class InjectPayloadDexParameters implements InjectPayload {
public final static int INPUT_REGISTER_START = 0x100;
public final static int REGISTER_START = 0x1000;
private String name;
private String sourceName;
private InjectParameter[] noParams;
private boolean analysisStateRecoverable;
public InjectPayloadDexParameters() {
public InjectPayloadDexParameters(String nm, String srcName) {
name = nm;
sourceName = srcName;
noParams = new InjectParameter[0];
analysisStateRecoverable = true;
}
@Override
public String getName() {
return "dexparameters";
return name;
}
@Override
@@ -57,10 +64,9 @@ public class InjectPayloadDexParameters implements InjectPayload {
return CALLMECHANISM_TYPE;
}
@Override
public String getSource() {
return "dexparameters";
return sourceName;
}
@Override
@@ -78,6 +84,11 @@ public class InjectPayloadDexParameters implements InjectPayload {
return noParams;
}
@Override
public boolean isErrorPlaceholder() {
return false;
}
@Override
public void inject(InjectContext context, PcodeEmit emit) {
// not used
@@ -101,23 +112,27 @@ public class InjectPayloadDexParameters implements InjectPayload {
PcodeOp[] resOps;
Function func = program.getFunctionManager().getFunctionContaining(con.baseAddr);
EncodedMethod encodedMethod = null;
if (func != null)
if (func != null) {
encodedMethod = analysisState.getEncodedMethod(func.getEntryPoint());
if (encodedMethod == null)
}
if (encodedMethod == null) {
return new PcodeOp[0];
}
int paramCount = 0;
if (!encodedMethod.isStatic())
if (!encodedMethod.isStatic()) {
paramCount += 1; // A this pointer at least
}
CodeItem codeItem = encodedMethod.getCodeItem();
int registerIndex = codeItem.getRegistersSize() - codeItem.getIncomingSize();
MethodIDItem methodIDItem = header.getMethods().get( encodedMethod.getMethodIndex() );
MethodIDItem methodIDItem = header.getMethods().get(encodedMethod.getMethodIndex());
int prototypeIndex = methodIDItem.getProtoIndex() & 0xffff;
PrototypesIDItem prototype = header.getPrototypes().get(prototypeIndex);
TypeList parameters = prototype.getParameters();
if (parameters != null)
if (parameters != null) {
paramCount += parameters.getItems().size();
}
AddressSpace registerSpace = program.getAddressFactory().getAddressSpace("register");
resOps = new PcodeOp[ paramCount ];
resOps = new PcodeOp[paramCount];
long fromOffset = INPUT_REGISTER_START; // Base of designated input registers
long toOffset = REGISTER_START + 4 * registerIndex; // Base of registers in method's frame
int i = 0;
@@ -126,16 +141,16 @@ public class InjectPayloadDexParameters implements InjectPayload {
Address toAddr = registerSpace.getAddress(toOffset);
fromOffset += 4;
toOffset += 4;
PcodeOp op = new PcodeOp(con.baseAddr,i,PcodeOp.COPY);
op.setInput(new Varnode(fromAddr,4), 0);
op.setOutput(new Varnode(toAddr,4));
PcodeOp op = new PcodeOp(con.baseAddr, i, PcodeOp.COPY);
op.setInput(new Varnode(fromAddr, 4), 0);
op.setOutput(new Varnode(toAddr, 4));
resOps[i] = op;
i += 1;
}
if (parameters != null) {
for (TypeItem parameterTypeItem : parameters.getItems()) {
String parameterTypeString = DexUtil.convertTypeIndexToString(
header, parameterTypeItem.getType());
String parameterTypeString =
DexUtil.convertTypeIndexToString(header, parameterTypeItem.getType());
int size;
char firstChar = parameterTypeString.charAt(0);
Address fromAddr = registerSpace.getAddress(fromOffset);
@@ -156,4 +171,42 @@ public class InjectPayloadDexParameters implements InjectPayload {
public boolean isFallThru() {
return true;
}
@Override
public boolean isIncidentalCopy() {
return false;
}
@Override
public void saveXml(StringBuilder buffer) {
// Provide a minimal tag so decompiler can call-back
buffer.append("<pcode");
SpecXmlUtils.encodeStringAttribute(buffer, "inject", "uponentry");
SpecXmlUtils.encodeBooleanAttribute(buffer, "dynamic", true);
buffer.append("/>\n");
}
@Override
public void restoreXml(XmlPullParser parser, SleighLanguage language) throws XmlParseException {
XmlElement el = parser.start();
String injectString = el.getAttribute("inject");
if (injectString == null || !injectString.equals("uponentry")) {
throw new XmlParseException("Expecting inject=\"uponentry\" attribute");
}
boolean isDynamic = SpecXmlUtils.decodeBoolean(el.getAttribute("dynamic"));
if (!isDynamic) {
throw new XmlParseException("Expecting dynamic attribute");
}
parser.end(el);
}
@Override
public boolean equals(Object obj) {
return (obj instanceof InjectPayloadDexParameters); // All instances are equal
}
@Override
public int hashCode() {
return 123474219; // All instances are equal
}
}

View File

@@ -15,11 +15,10 @@
*/
package ghidra.dalvik.dex.inject;
import ghidra.app.plugin.processors.sleigh.PcodeEmit;
import ghidra.program.model.address.Address;
import ghidra.program.model.address.AddressSpace;
import ghidra.program.model.lang.InjectContext;
import ghidra.program.model.lang.InjectPayload;
import ghidra.program.model.lang.InjectPayloadCallother;
import ghidra.program.model.listing.Program;
import ghidra.program.model.pcode.PcodeOp;
import ghidra.program.model.pcode.Varnode;
@@ -31,44 +30,10 @@ import ghidra.program.model.pcode.Varnode;
* The registers are moved to the specially designated input registers iv0, iv1, iv2, ...
*
*/
public class InjectPayloadDexRange implements InjectPayload {
public class InjectPayloadDexRange extends InjectPayloadCallother {
public InjectPayloadDexRange() {
}
@Override
public String getName() {
return "dexrange";
}
@Override
public int getType() {
return CALLOTHERFIXUP_TYPE;
}
@Override
public String getSource() {
return "dexrange";
}
@Override
public int getParamShift() {
return 0;
}
@Override
public InjectParameter[] getInput() {
return null; // Not used
}
@Override
public InjectParameter[] getOutput() {
return null; // Not used
}
@Override
public void inject(InjectContext context, PcodeEmit emit) {
// not used
super("dexrange");
}
@Override
@@ -96,10 +61,4 @@ public class InjectPayloadDexRange implements InjectPayload {
}
return resOps;
}
@Override
public boolean isFallThru() {
return true;
}
}

View File

@@ -23,35 +23,32 @@ import ghidra.program.model.listing.Program;
public class PcodeInjectLibraryDex extends PcodeInjectLibrary {
private InjectPayloadDexParameters paramPayload = null;
private InjectPayloadDexRange rangePayload = null;
public PcodeInjectLibraryDex(SleighLanguage l) {
super(l);
}
@Override
public InjectPayload getPayload(int type, String name, Program program,
String context) {
if (type == InjectPayload.CALLMECHANISM_TYPE) {
if (paramPayload == null) {
paramPayload = new InjectPayloadDexParameters();
}
return paramPayload;
}
else if (type == InjectPayload.CALLOTHERFIXUP_TYPE && name.equals("moveRangeToIV")) {
if (rangePayload == null) {
rangePayload = new InjectPayloadDexRange();
}
return rangePayload;
}
public PcodeInjectLibraryDex(PcodeInjectLibraryDex op2) {
super(op2);
}
return super.getPayload(type, name, program, context);
@Override
public PcodeInjectLibrary clone() {
return new PcodeInjectLibraryDex(this);
}
@Override
public InjectPayload allocateInject(String sourceName, String name, int tp) {
if (tp == InjectPayload.CALLMECHANISM_TYPE) {
return new InjectPayloadDexParameters(name, sourceName);
}
else if (tp == InjectPayload.CALLOTHERFIXUP_TYPE && name.equals("moveRangeToIV")) {
return new InjectPayloadDexRange();
}
return super.allocateInject(sourceName, name, tp);
}
@Override
public ConstantPool getConstantPool(Program program) throws IOException {
return new ConstantPoolDex(program);
}
}