Program specific, user-defined, cspec extensions

Documentation for spec extensions

Handle extensions with parse errors
Export button for spec extensions
Pop-up dialog for parse errors in user-defined specification extensions
GP-653 corrected some minor issues and established new ProgramDB version
make incremental initialization constructor for AddressSized private
Make AddressSized fields private
More adjustments to AddressSized
Review fixes for BasicCompilerSpec
Take restoreXml out of DataOrganization interface
Remove restoreXml from BitFieldPacking interface
More review fixes
Prevent callotherfixup extension with non-existent target
Suggested export name
More documentation for SpecExtension
Support for undo/redo with spec extensions
Documentation for ConstructTpl
Split out ProgramCompilerSpec and other changes for review
Changes after next round of reviews
This commit is contained in:
caheckman 2021-02-02 13:07:54 -05:00 committed by ghidra1
parent 27fbe7278d
commit a5d4ca3cab
108 changed files with 7997 additions and 1997 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);
}
}

View file

@ -27,11 +27,6 @@ public class InjectGetField extends InjectPayloadJava {
super(sourceName, language, uniqBase);
}
@Override
public String getName() {
return PcodeInjectLibraryJava.GETFIELD;
}
@Override
public PcodeOp[] getPcode(Program program, InjectContext con) {
AbstractConstantPoolInfoJava[] constantPool = getConstantPool(program);

View file

@ -27,11 +27,6 @@ public class InjectGetStatic extends InjectPayloadJava {
super(sourceName, language, uniqBase);
}
@Override
public String getName() {
return PcodeInjectLibraryJava.GETSTATIC;
}
@Override
public PcodeOp[] getPcode(Program program, InjectContext con) {
AbstractConstantPoolInfoJava[] constantPool = getConstantPool(program);

View file

@ -27,11 +27,6 @@ public class InjectInvokeDynamic extends InjectPayloadJava {
super(sourceName, language, uniqBase);
}
@Override
public String getName() {
return PcodeInjectLibraryJava.INVOKE_DYNAMIC;
}
@Override
public PcodeOp[] getPcode(Program program, InjectContext con) {
AbstractConstantPoolInfoJava[] constantPool = getConstantPool(program);

View file

@ -27,11 +27,6 @@ public class InjectInvokeInterface extends InjectPayloadJava {
super(sourceName, language, uniqBase);
}
@Override
public String getName() {
return PcodeInjectLibraryJava.INVOKE_INTERFACE;
}
@Override
public PcodeOp[] getPcode(Program program, InjectContext con) {
AbstractConstantPoolInfoJava[] constantPool = getConstantPool(program);

View file

@ -27,11 +27,6 @@ public class InjectInvokeSpecial extends InjectPayloadJava {
super(sourceName, language, uniqBase);
}
@Override
public String getName() {
return PcodeInjectLibraryJava.INVOKE_SPECIAL;
}
@Override
public PcodeOp[] getPcode(Program program, InjectContext con) {
AbstractConstantPoolInfoJava[] constantPool = getConstantPool(program);

View file

@ -27,11 +27,6 @@ public class InjectInvokeStatic extends InjectPayloadJava {
super(sourceName, language, uniqBase);
}
@Override
public String getName() {
return PcodeInjectLibraryJava.INVOKE_STATIC;
}
@Override
public PcodeOp[] getPcode(Program program, InjectContext con) {
AbstractConstantPoolInfoJava[] constantPool = getConstantPool(program);

View file

@ -27,11 +27,6 @@ public class InjectInvokeVirtual extends InjectPayloadJava {
super(sourceName, language, uniqBase);
}
@Override
public String getName() {
return PcodeInjectLibraryJava.INVOKE_VIRTUAL;
}
@Override
public PcodeOp[] getPcode(Program program, InjectContext con) {
AbstractConstantPoolInfoJava[] constantPool = getConstantPool(program);

View file

@ -27,11 +27,6 @@ public class InjectLdc extends InjectPayloadJava {
super(sourceName, language, uniqBase);
}
@Override
public String getName() {
return PcodeInjectLibraryJava.LDC;
}
@Override
public PcodeOp[] getPcode(Program program, InjectContext con) {
AbstractConstantPoolInfoJava[] constantPool = getConstantPool(program);

View file

@ -27,11 +27,6 @@ public class InjectMultiANewArray extends InjectPayloadJava {
super(sourceName, language, uniqBase);
}
@Override
public String getName() {
return PcodeInjectLibraryJava.MULTIANEWARRAY;
}
@Override
public PcodeOp[] getPcode(Program program, InjectContext con) {
AbstractConstantPoolInfoJava[] constantPool = getConstantPool(program);

View file

@ -17,29 +17,26 @@ package ghidra.app.util.pcodeInject;
import java.io.IOException;
import ghidra.app.plugin.processors.sleigh.PcodeEmit;
import ghidra.app.plugin.processors.sleigh.SleighLanguage;
import ghidra.javaclass.format.ClassFileAnalysisState;
import ghidra.javaclass.format.ClassFileJava;
import ghidra.javaclass.format.constantpool.AbstractConstantPoolInfoJava;
import ghidra.program.model.lang.InjectContext;
import ghidra.program.model.lang.InjectPayload;
import ghidra.program.model.lang.InjectPayloadCallother;
import ghidra.program.model.listing.Program;
/**
* Subclasses of this class are used to generate pcode to inject for modeling
* java bytecode in pcode.
* Subclasses of this class are used to generate p-code to inject for modeling
* java bytecode in p-code. Each is attached to CALLOTHER p-code op.
*
*/
public abstract class InjectPayloadJava implements InjectPayload {
public abstract class InjectPayloadJava extends InjectPayloadCallother {
protected SleighLanguage language;
protected long uniqueBase;
private String sourceName;
public InjectPayloadJava(String sourceName, SleighLanguage language, long uniqBase) {
super(sourceName);
this.language = language;
this.sourceName = sourceName;
this.uniqueBase = uniqBase;
}
@ -54,39 +51,4 @@ public abstract class InjectPayloadJava implements InjectPayload {
ClassFileJava classFile = analysisState.getClassFile();
return classFile.getConstantPool();
}
@Override
public int getType() {
return InjectPayload.CALLOTHERFIXUP_TYPE;
}
@Override
public String getSource() {
return sourceName;
}
@Override
public int getParamShift() {
return 0;
}
@Override
public void inject(InjectContext context, PcodeEmit emit) {
// Not used
}
@Override
public boolean isFallThru() {
return true;
}
@Override
public InjectParameter[] getInput() {
return null;
}
@Override
public InjectParameter[] getOutput() {
return null;
}
}

View file

@ -31,9 +31,13 @@ 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.*;
public class InjectPayloadJavaParameters implements InjectPayload {
private String name;
private String sourceName;
private InjectParameter[] noParams;
private boolean analysisStateRecoverable;
private AddressSpace constantSpace;
@ -46,7 +50,10 @@ public class InjectPayloadJavaParameters implements InjectPayload {
private Varnode eight;
private Varnode LVA;
public InjectPayloadJavaParameters(SleighLanguage language, long uniqBase) {
public InjectPayloadJavaParameters(String nm, String srcName, SleighLanguage language,
long uniqBase) {
name = nm;
sourceName = srcName;
noParams = new InjectParameter[0];
analysisStateRecoverable = true;
constantSpace = language.getAddressFactory().getConstantSpace();
@ -70,7 +77,7 @@ public class InjectPayloadJavaParameters implements InjectPayload {
@Override
public String getName() {
return "javaparameters";
return name;
}
@Override
@ -80,7 +87,7 @@ public class InjectPayloadJavaParameters implements InjectPayload {
@Override
public String getSource() {
return "javaparameters";
return sourceName;
}
@Override
@ -98,6 +105,11 @@ public class InjectPayloadJavaParameters implements InjectPayload {
return noParams;
}
@Override
public boolean isErrorPlaceholder() {
return false;
}
@Override
public void inject(InjectContext context, PcodeEmit emit) {
//not used
@ -119,29 +131,30 @@ public class InjectPayloadJavaParameters implements InjectPayload {
}
ClassFileJava classFile = analysisState.getClassFile();
MethodInfoJava methodInfo = analysisState.getMethodInfo(con.baseAddr);
if (methodInfo == null){
if (methodInfo == null) {
return new PcodeOp[0];
}
int descriptorIndex = methodInfo.getDescriptorIndex();
ConstantPoolUtf8Info descriptorInfo = (ConstantPoolUtf8Info)(classFile.getConstantPool()[descriptorIndex]);
ConstantPoolUtf8Info descriptorInfo =
(ConstantPoolUtf8Info) (classFile.getConstantPool()[descriptorIndex]);
String descriptor = descriptorInfo.getString();
List<JavaComputationalCategory> paramCategories = new ArrayList<>();
if (!methodInfo.isStatic()){
if (!methodInfo.isStatic()) {
paramCategories.add(JavaComputationalCategory.CAT_1);//for the this pointer
}
paramCategories.addAll(DescriptorDecoder.getParameterCategories(descriptor));
int numOps = paramCategories.size();
if (paramCategories.size() == 0){
if (paramCategories.size() == 0) {
//no this pointer, no parameters: nothing to do
return new PcodeOp[0];
}
PcodeOp[] resOps = new PcodeOp[1 + 3*numOps];
PcodeOp[] resOps = new PcodeOp[1 + 3 * numOps];
int seqNum = 0;
//initialize LVA to contain 0
PcodeOp copy = new PcodeOp(con.baseAddr,seqNum, PcodeOp.COPY);
PcodeOp copy = new PcodeOp(con.baseAddr, seqNum, PcodeOp.COPY);
copy.setInput(zero, 0);
copy.setOutput(LVA);
resOps[seqNum++] = copy;
@ -149,8 +162,8 @@ public class InjectPayloadJavaParameters implements InjectPayload {
Varnode tempLocation = null;
Varnode increment = null;
for (JavaComputationalCategory cat : paramCategories){
if (cat.equals(JavaComputationalCategory.CAT_1)){
for (JavaComputationalCategory cat : paramCategories) {
if (cat.equals(JavaComputationalCategory.CAT_1)) {
tempLocation = temp4;
increment = four;
}
@ -167,16 +180,16 @@ public class InjectPayloadJavaParameters implements InjectPayload {
//copy temporary to LVA
PcodeOp store = new PcodeOp(con.baseAddr, seqNum, PcodeOp.STORE);
store.setInput(new Varnode(constantSpace.getAddress(lvaID), 4), 0);
store.setInput(LVA,1);
store.setInput(LVA, 1);
store.setInput(tempLocation, 2);
resOps[seqNum++] = store;
resOps[seqNum++] = store;
//increment LVA reg
PcodeOp add = new PcodeOp(con.baseAddr, seqNum, PcodeOp.INT_ADD);
add.setInput(LVA, 0);
add.setInput(increment, 1);
add.setOutput(LVA);
resOps[seqNum++] = add;
}
resOps[seqNum++] = add;
}
return resOps;
}
@ -184,4 +197,42 @@ public class InjectPayloadJavaParameters 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 InjectPayloadJavaParameters); // All instances are equal
}
@Override
public int hashCode() {
return 123474217; // All instances are equal
}
}

View file

@ -27,11 +27,6 @@ public class InjectPutField extends InjectPayloadJava {
super(sourceName, language, uniqBase);
}
@Override
public String getName() {
return PcodeInjectLibraryJava.PUTFIELD;
}
@Override
public PcodeOp[] getPcode(Program program, InjectContext con) {
AbstractConstantPoolInfoJava[] constantPool = getConstantPool(program);

View file

@ -27,11 +27,6 @@ public class InjectPutStatic extends InjectPayloadJava {
super(sourceName, language, uniqBase);
}
@Override
public String getName() {
return PcodeInjectLibraryJava.PUTSTATIC;
}
@Override
public PcodeOp[] getPcode(Program program, InjectContext con) {
AbstractConstantPoolInfoJava[] constantPool = getConstantPool(program);

View file

@ -116,56 +116,60 @@ public class PcodeInjectLibraryJava extends PcodeInjectLibrary {
public static final int REFERENCE_SIZE = 4;
private Map<String, InjectPayloadJava> implementedOps;
private InjectPayloadJavaParameters paramPayload;
public PcodeInjectLibraryJava(SleighLanguage l) {
super(l);
long offset = l.getUniqueBase();
implementedOps = new HashMap<>();
implementedOps.put(GETFIELD, new InjectGetField(SOURCENAME, l, offset));
offset += 0x100;
implementedOps.put(GETSTATIC, new InjectGetStatic(SOURCENAME, l, offset));
offset += 0x100;
implementedOps.put(INVOKE_DYNAMIC, new InjectInvokeDynamic(SOURCENAME, l, offset));
offset += 0x100;
implementedOps.put(INVOKE_INTERFACE, new InjectInvokeInterface(SOURCENAME, l, offset));
offset += 0x100;
implementedOps.put(INVOKE_SPECIAL, new InjectInvokeSpecial(SOURCENAME, l, offset));
offset += 0x100;
implementedOps.put(INVOKE_STATIC, new InjectInvokeStatic(SOURCENAME, l, offset));
offset += 0x100;
implementedOps.put(INVOKE_VIRTUAL, new InjectInvokeVirtual(SOURCENAME, l, offset));
offset += 0x100;
InjectPayloadJava ldcInject = new InjectLdc(SOURCENAME, l, offset);
offset += 0x100;
implementedOps.put(LDC, ldcInject);
implementedOps.put(LDC2_W, ldcInject);
implementedOps.put(LDC_W, ldcInject);
implementedOps.put(MULTIANEWARRAY, new InjectMultiANewArray(SOURCENAME, l, offset));
offset += 0x100;
implementedOps.put(PUTFIELD, new InjectPutField(SOURCENAME, l, offset));
offset += 0x100;
implementedOps.put(PUTSTATIC, new InjectPutStatic(SOURCENAME, l, offset));
offset += 0x100;
implementedOps.put(GETFIELD, new InjectGetField(SOURCENAME, l, uniqueBase));
uniqueBase += 0x100;
implementedOps.put(GETSTATIC, new InjectGetStatic(SOURCENAME, l, uniqueBase));
uniqueBase += 0x100;
implementedOps.put(INVOKE_DYNAMIC, new InjectInvokeDynamic(SOURCENAME, l, uniqueBase));
uniqueBase += 0x100;
implementedOps.put(INVOKE_INTERFACE, new InjectInvokeInterface(SOURCENAME, l, uniqueBase));
uniqueBase += 0x100;
implementedOps.put(INVOKE_SPECIAL, new InjectInvokeSpecial(SOURCENAME, l, uniqueBase));
uniqueBase += 0x100;
implementedOps.put(INVOKE_STATIC, new InjectInvokeStatic(SOURCENAME, l, uniqueBase));
uniqueBase += 0x100;
implementedOps.put(INVOKE_VIRTUAL, new InjectInvokeVirtual(SOURCENAME, l, uniqueBase));
uniqueBase += 0x100;
implementedOps.put(LDC, new InjectLdc(SOURCENAME, l, uniqueBase));
uniqueBase += 0x100;
implementedOps.put(LDC2_W, new InjectLdc(SOURCENAME, l, uniqueBase));
uniqueBase += 0x100;
implementedOps.put(LDC_W, new InjectLdc(SOURCENAME, l, uniqueBase));
uniqueBase += 0x100;
implementedOps.put(MULTIANEWARRAY, new InjectMultiANewArray(SOURCENAME, l, uniqueBase));
uniqueBase += 0x100;
implementedOps.put(PUTFIELD, new InjectPutField(SOURCENAME, l, uniqueBase));
uniqueBase += 0x100;
implementedOps.put(PUTSTATIC, new InjectPutStatic(SOURCENAME, l, uniqueBase));
uniqueBase += 0x100;
}
paramPayload = new InjectPayloadJavaParameters(l, offset);
public PcodeInjectLibraryJava(PcodeInjectLibraryJava op2) {
super(op2);
implementedOps = op2.implementedOps; // Immutable
}
@Override
/**
* This method is called by DecompileCallback.getPcodeInject.
*/
public InjectPayload getPayload(int type, String name, Program program, String context) {
if (type == InjectPayload.CALLMECHANISM_TYPE) {
return paramPayload;
}
public PcodeInjectLibrary clone() {
return new PcodeInjectLibraryJava(this);
}
InjectPayloadJava payload = implementedOps.get(name);
if (payload == null) {
return super.getPayload(type, name, program, context);
@Override
public InjectPayload allocateInject(String sourceName, String name, int tp) {
if (tp == InjectPayload.CALLMECHANISM_TYPE) {
return new InjectPayloadJavaParameters(name, sourceName, language, tp);
}
return payload;
if (tp == InjectPayload.CALLOTHERFIXUP_TYPE) {
InjectPayloadJava payload = implementedOps.get(name);
if (payload != null) {
return payload;
}
}
return super.allocateInject(sourceName, name, tp);
}
@Override

View file

@ -36,10 +36,10 @@ import ghidra.javaclass.flags.MethodsInfoAccessFlags;
import ghidra.javaclass.format.*;
import ghidra.javaclass.format.attributes.*;
import ghidra.javaclass.format.constantpool.*;
import ghidra.program.database.ProgramCompilerSpec;
import ghidra.program.model.address.Address;
import ghidra.program.model.address.AddressSetView;
import ghidra.program.model.data.*;
import ghidra.program.model.lang.BasicCompilerSpec;
import ghidra.program.model.listing.*;
import ghidra.program.model.listing.Function.FunctionUpdateType;
import ghidra.program.model.mem.MemoryAccessException;
@ -138,7 +138,7 @@ public class JavaAnalyzer extends AbstractJavaAnalyzer implements AnalysisWorker
disassembleMethods(program, classFile, monitor);
processInstructions(program, constantPoolData, classFile, monitor);
recordJavaVersionInfo(program, classFile);
BasicCompilerSpec.enableJavaLanguageDecompilation(program);
ProgramCompilerSpec.enableJavaLanguageDecompilation(program);
return true;
}