Unverified Commit 8d8e0efd by Melvin Klimke Committed by GitHub

Handle unimplemented pcode (#106)

parent f86b10a6
...@@ -16,7 +16,7 @@ use crate::prelude::*; ...@@ -16,7 +16,7 @@ use crate::prelude::*;
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Hash, Clone)] #[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Hash, Clone)]
pub struct Call { pub struct Call {
pub target: Label, pub target: Option<Label>,
#[serde(rename = "return")] #[serde(rename = "return")]
pub return_: Option<Label>, pub return_: Option<Label>,
pub call_string: Option<String>, pub call_string: Option<String>,
...@@ -85,14 +85,14 @@ impl From<Jmp> for IrJmp { ...@@ -85,14 +85,14 @@ impl From<Jmp> for IrJmp {
CALL => { CALL => {
let call = jmp.call.unwrap(); let call = jmp.call.unwrap();
IrJmp::Call { IrJmp::Call {
target: unwrap_label_direct(call.target), target: unwrap_label_direct(call.target.unwrap()),
return_: call.return_.map(unwrap_label_direct), return_: call.return_.map(unwrap_label_direct),
} }
} }
CALLIND => { CALLIND => {
let call = jmp.call.unwrap(); let call = jmp.call.unwrap();
IrJmp::CallInd { IrJmp::CallInd {
target: unwrap_label_indirect(call.target).into(), target: unwrap_label_indirect(call.target.unwrap()).into(),
return_: call.return_.map(unwrap_label_direct), return_: call.return_.map(unwrap_label_direct),
} }
} }
......
...@@ -319,7 +319,7 @@ public class PcodeExtractor extends GhidraScript { ...@@ -319,7 +319,7 @@ public class PcodeExtractor extends GhidraScript {
for(int pcodeIndex = 0; pcodeIndex < numberOfPcodeOps; pcodeIndex++) { for(int pcodeIndex = 0; pcodeIndex < numberOfPcodeOps; pcodeIndex++) {
PcodeOp pcodeOp = PcodeBlockData.ops[pcodeIndex]; PcodeOp pcodeOp = PcodeBlockData.ops[pcodeIndex];
String mnemonic = pcodeOp.getMnemonic(); String mnemonic = pcodeOp.getMnemonic();
if (this.jumps.contains(mnemonic)) { if (this.jumps.contains(mnemonic) || pcodeOp.getOpcode() == PcodeOp.UNIMPLEMENTED) {
intraInstructionJumpOccured = processJump(pcodeOp, mnemonic, numberOfPcodeOps, pcodeIndex, intraInstructionJumpOccured); intraInstructionJumpOccured = processJump(pcodeOp, mnemonic, numberOfPcodeOps, pcodeIndex, intraInstructionJumpOccured);
} else { } else {
PcodeBlockData.temporaryDefStorage.add(createDefTerm(pcodeIndex, pcodeOp)); PcodeBlockData.temporaryDefStorage.add(createDefTerm(pcodeIndex, pcodeOp));
...@@ -591,7 +591,7 @@ public class PcodeExtractor extends GhidraScript { ...@@ -591,7 +591,7 @@ public class PcodeExtractor extends GhidraScript {
*/ */
protected void redirectCallReturn(Term<Blk> currentBlock, PcodeOp pcodeOp) { protected void redirectCallReturn(Term<Blk> currentBlock, PcodeOp pcodeOp) {
Tid jmpTid = new Tid(String.format("instr_%s_%s_r", PcodeBlockData.instruction.getAddress().toString(), 0), PcodeBlockData.instruction.getAddress().toString()); Tid jmpTid = new Tid(String.format("instr_%s_%s_r", PcodeBlockData.instruction.getAddress().toString(), 0), PcodeBlockData.instruction.getAddress().toString());
Term<Jmp> ret = new Term<Jmp>(jmpTid, new Jmp(ExecutionType.JmpType.RETURN, pcodeOp.getMnemonic(), createLabel(pcodeOp.getMnemonic(), pcodeOp, null), 0)); Term<Jmp> ret = new Term<Jmp>(jmpTid, new Jmp(ExecutionType.JmpType.RETURN, pcodeOp.getMnemonic(), createLabel(pcodeOp, null), 0));
currentBlock.getTerm().addJmp(ret); currentBlock.getTerm().addJmp(ret);
} }
...@@ -883,12 +883,17 @@ public class PcodeExtractor extends GhidraScript { ...@@ -883,12 +883,17 @@ public class PcodeExtractor extends GhidraScript {
protected Term<Jmp> createJmpTerm(int pCodeCount, PcodeOp pcodeOp, String mnemonic) { protected Term<Jmp> createJmpTerm(int pCodeCount, PcodeOp pcodeOp, String mnemonic) {
Address instrAddr = PcodeBlockData.instruction.getAddress(); Address instrAddr = PcodeBlockData.instruction.getAddress();
Tid jmpTid = new Tid(String.format("instr_%s_%s", instrAddr.toString(), pCodeCount), instrAddr.toString()); Tid jmpTid = new Tid(String.format("instr_%s_%s", instrAddr.toString(), pCodeCount), instrAddr.toString());
if (mnemonic.equals("CBRANCH")) { if (pcodeOp.getOpcode() == PcodeOp.CBRANCH) {
return new Term<Jmp>(jmpTid, new Jmp(ExecutionType.JmpType.GOTO, mnemonic, createLabel(mnemonic, pcodeOp, null), createVariable(pcodeOp.getInput(1)), pCodeCount)); return new Term<Jmp>(jmpTid, new Jmp(ExecutionType.JmpType.GOTO, mnemonic, createLabel(pcodeOp, null), createVariable(pcodeOp.getInput(1)), pCodeCount));
} else if (mnemonic.equals("BRANCH") || mnemonic.equals("BRANCHIND")) { }
return new Term<Jmp>(jmpTid, new Jmp(ExecutionType.JmpType.GOTO, mnemonic, createLabel(mnemonic, pcodeOp, null), pCodeCount)); if (pcodeOp.getOpcode() == PcodeOp.BRANCH || pcodeOp.getOpcode() == PcodeOp.BRANCHIND) {
} else if (mnemonic.equals("RETURN")) { return new Term<Jmp>(jmpTid, new Jmp(ExecutionType.JmpType.GOTO, mnemonic, createLabel(pcodeOp, null), pCodeCount));
return new Term<Jmp>(jmpTid, new Jmp(ExecutionType.JmpType.RETURN, mnemonic, createLabel(mnemonic, pcodeOp, null), pCodeCount)); }
if (pcodeOp.getOpcode() == PcodeOp.RETURN) {
return new Term<Jmp>(jmpTid, new Jmp(ExecutionType.JmpType.RETURN, mnemonic, createLabel(pcodeOp, null), pCodeCount));
}
if (pcodeOp.getOpcode() == PcodeOp.UNIMPLEMENTED) {
mnemonic = "CALLOTHER";
} }
Term<Jmp> call = new Term<Jmp>(jmpTid, new Jmp(ExecutionType.JmpType.CALL, mnemonic, createCall(mnemonic, pcodeOp), pCodeCount)); Term<Jmp> call = new Term<Jmp>(jmpTid, new Jmp(ExecutionType.JmpType.CALL, mnemonic, createCall(mnemonic, pcodeOp), pCodeCount));
...@@ -994,7 +999,6 @@ public class PcodeExtractor extends GhidraScript { ...@@ -994,7 +999,6 @@ public class PcodeExtractor extends GhidraScript {
/** /**
* @param mnemonic: Pcode instruction mnemonic
* @param pcodeOp: Pcode instruction * @param pcodeOp: Pcode instruction
* @param fallThrough: fallThrough address of branch/call * @param fallThrough: fallThrough address of branch/call
* @return: new Label * @return: new Label
...@@ -1002,20 +1006,21 @@ public class PcodeExtractor extends GhidraScript { ...@@ -1002,20 +1006,21 @@ public class PcodeExtractor extends GhidraScript {
* Create a Label based on the branch instruction. For indirect branches and calls, it consists of a Variable, for calls of a sub TID * Create a Label based on the branch instruction. For indirect branches and calls, it consists of a Variable, for calls of a sub TID
* and for branches of a blk TID. * and for branches of a blk TID.
*/ */
protected Label createLabel(String mnemonic, PcodeOp pcodeOp, Address fallThrough) { protected Label createLabel(PcodeOp pcodeOp, Address fallThrough) {
Label jumpLabel; Label jumpLabel;
if (fallThrough == null) { if (fallThrough == null) {
switch(mnemonic) { switch(pcodeOp.getOpcode()) {
case "CALL": case PcodeOp.CALL:
case "CALLIND": case PcodeOp.CALLIND:
jumpLabel = handleLabelsForCalls(pcodeOp); jumpLabel = handleLabelsForCalls(pcodeOp);
break; break;
case "BRANCHIND": case PcodeOp.BRANCHIND:
case "RETURN": case PcodeOp.RETURN:
jumpLabel = new Label((Variable) createVariable(pcodeOp.getInput(0))); jumpLabel = new Label((Variable) createVariable(pcodeOp.getInput(0)));
break; break;
case "CALLOTHER": case PcodeOp.CALLOTHER:
jumpLabel = new Label((Tid) new Tid(String.format("sub_%s", pcodeOp.getInput(0).getAddress().toString()), pcodeOp.getInput(0).getAddress().toString())); case PcodeOp.UNIMPLEMENTED:
jumpLabel = null;
break; break;
default: default:
jumpLabel = new Label((Tid) new Tid(String.format("blk_%s", pcodeOp.getInput(0).getAddress().toString()), pcodeOp.getInput(0).getAddress().toString())); jumpLabel = new Label((Tid) new Tid(String.format("blk_%s", pcodeOp.getInput(0).getAddress().toString()), pcodeOp.getInput(0).getAddress().toString()));
...@@ -1138,11 +1143,16 @@ public class PcodeExtractor extends GhidraScript { ...@@ -1138,11 +1143,16 @@ public class PcodeExtractor extends GhidraScript {
* Creates a Call object, using a target and return Label. * Creates a Call object, using a target and return Label.
*/ */
protected Call createCall(String mnemonic, PcodeOp pcodeOp) { protected Call createCall(String mnemonic, PcodeOp pcodeOp) {
if(mnemonic.equals("CALLOTHER")) { String callString = null;
String callString = ghidraProgram.getLanguage().getUserDefinedOpName((int) pcodeOp.getInput(0).getOffset()); if(pcodeOp.getOpcode() == PcodeOp.CALLOTHER) {
return new Call(createLabel(mnemonic, pcodeOp, null), createLabel(mnemonic, pcodeOp, PcodeBlockData.instruction.getFallThrough()), callString); callString = ghidraProgram.getLanguage().getUserDefinedOpName((int) pcodeOp.getInput(0).getOffset());
return new Call(null, createLabel(pcodeOp, PcodeBlockData.instruction.getFallThrough()), callString);
}
if(pcodeOp.getOpcode() == PcodeOp.UNIMPLEMENTED) {
callString = "unimplemented";
return new Call(null, createLabel(pcodeOp, PcodeBlockData.instruction.getFallThrough()), callString);
} }
return new Call(createLabel(mnemonic, pcodeOp, null), createLabel(mnemonic, pcodeOp, PcodeBlockData.instruction.getFallThrough())); return new Call(createLabel(pcodeOp, null), createLabel(pcodeOp, PcodeBlockData.instruction.getFallThrough()));
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment