decompiler
1.0.0
|
Emulate a snippet of PcodeOps out of a functional context. More...
#include <emulateutil.hh>
Public Member Functions | |
EmulateSnippet (Architecture *g) | |
Constructor. | |
virtual | ~EmulateSnippet (void) |
Destructor. | |
virtual void | setExecuteAddress (const Address &addr) |
Set the address of the next instruction to emulate. | |
virtual Address | getExecuteAddress (void) const |
Get the address of the current instruction being executed. | |
Architecture * | getArch (void) const |
Get the underlying Architecture. | |
void | resetMemory (void) |
Reset the emulation snippet. More... | |
PcodeEmit * | buildEmitter (const vector< OpBehavior *> &inst, uintb uniqReserve) |
Provide the caller with an emitter for building the p-code snippet. More... | |
bool | checkForLegalCode (void) const |
Check for p-code that is deemed illegal for a snippet. More... | |
void | setCurrentOp (int4 i) |
Set the current executing p-code op by index. More... | |
void | setVarnodeValue (uintb offset, uintb val) |
Set a temporary register value in the machine state. More... | |
uintb | getVarnodeValue (VarnodeData *vn) const |
Retrieve the value of a Varnode from the current machine state. More... | |
uintb | getTempValue (uintb offset) const |
Retrieve a temporary register value directly. More... | |
Public Member Functions inherited from ghidra::Emulate | |
Emulate (void) | |
generic emulator constructor | |
void | setHalt (bool val) |
Set the halt state of the emulator. More... | |
bool | getHalt (void) const |
Get the halt state of the emulator. More... | |
void | executeCurrentOp (void) |
Do a single pcode op step. More... | |
Private Member Functions | |
uintb | getLoadImageValue (AddrSpace *spc, uintb offset, int4 sz) const |
Pull a value from the load-image given a specific address. More... | |
virtual void | executeUnary (void) |
Execute a unary arithmetic/logical operation. | |
virtual void | executeBinary (void) |
Execute a binary arithmetic/logical operation. | |
virtual void | executeLoad (void) |
Standard behavior for a p-code LOAD. | |
virtual void | executeStore (void) |
Standard behavior for a p-code STORE. | |
virtual void | executeBranch (void) |
Standard behavior for a BRANCH. More... | |
virtual bool | executeCbranch (void) |
Check if the conditional of a CBRANCH is true. More... | |
virtual void | executeBranchind (void) |
Standard behavior for a BRANCHIND. | |
virtual void | executeCall (void) |
Standard behavior for a p-code CALL. | |
virtual void | executeCallind (void) |
Standard behavior for a CALLIND. | |
virtual void | executeCallother (void) |
Standard behavior for a user-defined p-code op. | |
virtual void | executeMultiequal (void) |
Standard behavior for a MULTIEQUAL (phi-node) | |
virtual void | executeIndirect (void) |
Standard behavior for an INDIRECT op. | |
virtual void | executeSegmentOp (void) |
Behavior for a SEGMENTOP. | |
virtual void | executeCpoolRef (void) |
Standard behavior for a CPOOLREF (constant pool reference) op. | |
virtual void | executeNew (void) |
Standard behavior for (low-level) NEW op. | |
virtual void | fallthruOp (void) |
Standard p-code fall-thru semantics. | |
Private Attributes | |
Architecture * | glb |
The underlying Architecture for the program being emulated. | |
vector< PcodeOpRaw * > | opList |
Sequence of p-code ops to be executed. | |
vector< VarnodeData * > | varList |
Varnodes allocated for ops. | |
map< uintb, uintb > | tempValues |
Values stored in temporary registers. | |
PcodeOpRaw * | currentOp |
Current p-code op being executed. | |
int4 | pos |
Index of current p-code op being executed. | |
Additional Inherited Members | |
Protected Attributes inherited from ghidra::Emulate | |
bool | emu_halted |
Set to true if the emulator is halted. | |
OpBehavior * | currentBehave |
Behavior of the next op to execute. | |
Emulate a snippet of PcodeOps out of a functional context.
Emulation is performed on a short sequence (snippet) of PcodeOpRaw objects. Control-flow emulation is limited to this snippet; BRANCH and CBRANCH operations can happen using p-code relative branching. Executing BRANCHIND, CALL, CALLIND, CALLOTHER, STORE, MULTIEQUAL, INDIRECT, SEGMENTOP, CPOOLOP, and NEW ops is treated as illegal and an exception is thrown. Expressions can only use temporary registers or read from the LoadImage.
The set of PcodeOpRaw objects in the snippet is provided by emitting p-code to the object returned by buildEmitter(). This is designed for one-time initialization of this class, which can be repeatedly used by calling resetMemory() between executions.
PcodeEmit * ghidra::EmulateSnippet::buildEmitter | ( | const vector< OpBehavior *> & | inst, |
uintb | uniqReserve | ||
) |
Provide the caller with an emitter for building the p-code snippet.
Any p-code produced by the PcodeEmit, when triggered by the caller, becomes part of the snippet that will get emulated by this. The caller should free the PcodeEmit object immediately after use.
inst | is the opcode to behavior map the emitter will use |
uniqReserve | is the starting offset within the unique address space for any temporary registers |
Referenced by ghidra::ExecutablePcode::build().
bool ghidra::EmulateSnippet::checkForLegalCode | ( | void | ) | const |
Check for p-code that is deemed illegal for a snippet.
This method facilitates enforcement of the formal rules for snippet code.
References ghidra::CPUI_BRANCH, ghidra::CPUI_BRANCHIND, ghidra::CPUI_CALL, ghidra::CPUI_CALLIND, ghidra::CPUI_CALLOTHER, ghidra::CPUI_CPOOLREF, ghidra::CPUI_INDIRECT, ghidra::CPUI_MULTIEQUAL, ghidra::CPUI_NEW, ghidra::CPUI_SEGMENTOP, ghidra::CPUI_STORE, ghidra::PcodeOpRaw::getInput(), ghidra::PcodeOpRaw::getOpcode(), ghidra::PcodeOpRaw::getOutput(), ghidra::AddrSpace::getType(), ghidra::IPTR_CONSTANT, ghidra::IPTR_INTERNAL, ghidra::IPTR_PROCESSOR, ghidra::PcodeOpRaw::numInput(), and ghidra::VarnodeData::space.
Referenced by ghidra::ExecutablePcode::build().
|
privatevirtual |
Standard behavior for a BRANCH.
This routine performs a standard p-code BRANCH operation on the memory state. This same routine is used for CBRANCH operations if the condition has evaluated to true.
Implements ghidra::Emulate.
References ghidra::EmulatePcodeOp::currentOp, ghidra::Emulate::emu_halted, ghidra::AddrSpace::getType(), ghidra::IPTR_CONSTANT, ghidra::VarnodeData::offset, ghidra::EmulatePcodeOp::setCurrentOp(), and ghidra::VarnodeData::space.
|
privatevirtual |
Check if the conditional of a CBRANCH is true.
This routine only checks if the condition for a p-code CBRANCH is true. It does not perform the actual branch.
Implements ghidra::Emulate.
References ghidra::EmulatePcodeOp::currentOp, and ghidra::EmulatePcodeOp::getVarnodeValue().
|
private |
Pull a value from the load-image given a specific address.
A contiguous chunk of memory is pulled from the load-image and returned as a constant value, respecting the endianess of the address space.
spc | is the address space to pull the value from |
offset | is the starting address offset (from within the space) to pull the value from |
sz | is the number of bytes to pull from memory |
References ghidra::calc_mask(), ghidra::EmulatePcodeOp::glb, ghidra::AddrSpace::isBigEndian(), ghidra::Architecture::loader, and ghidra::LoadImage::loadFill().
uintb ghidra::EmulateSnippet::getTempValue | ( | uintb | offset | ) | const |
Retrieve a temporary register value directly.
This allows the user to obtain the final value of the snippet calculation, without having to have the Varnode object in hand.
offset | is the offset of the temporary register to retrieve |
Referenced by ghidra::ExecutablePcode::evaluate().
uintb ghidra::EmulateSnippet::getVarnodeValue | ( | VarnodeData * | vn | ) | const |
Retrieve the value of a Varnode from the current machine state.
If the Varnode is a temporary registers, the storage offset is used to look up the value from the machine state cache. If the Varnode represents a RAM location, the value is pulled directly out of the load-image. If the value does not exist, a "Read before write" exception is thrown.
vn | is the Varnode to read |
References ghidra::EmulatePcodeOp::getLoadImageValue(), ghidra::AddrSpace::getType(), ghidra::IPTR_CONSTANT, ghidra::IPTR_INTERNAL, ghidra::VarnodeData::offset, ghidra::VarnodeData::size, and ghidra::VarnodeData::space.
|
inline |
Reset the emulation snippet.
Reset the memory state, and set the first p-code op as current.
References ghidra::Emulate::emu_halted, and ghidra::EmulatePcodeOp::setCurrentOp().
Referenced by ghidra::ExecutablePcode::evaluate().
|
inline |
Set the current executing p-code op by index.
The i-th p-code op in the snippet sequence is set as the currently executing op.
i | is the index |
References ghidra::Emulate::currentBehave, and ghidra::PcodeOpRaw::getBehavior().
|
inline |
Set a temporary register value in the machine state.
The temporary Varnode's storage offset is used as key into the machine state map.
offset | is the temporary storage offset |
val | is the value to put into the machine state |
References ghidra::EmulatePcodeOp::getVarnodeValue().
Referenced by ghidra::ExecutablePcode::evaluate().