decompiler  1.0.0
Public Member Functions | Private Member Functions | Private Attributes | List of all members
ghidra::EmulateSnippet Class Reference

Emulate a snippet of PcodeOps out of a functional context. More...

#include <emulateutil.hh>

Inheritance diagram for ghidra::EmulateSnippet:
ghidra::Emulate

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.
 
ArchitecturegetArch (void) const
 Get the underlying Architecture.
 
void resetMemory (void)
 Reset the emulation snippet. More...
 
PcodeEmitbuildEmitter (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

Architectureglb
 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.
 
PcodeOpRawcurrentOp
 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.
 
OpBehaviorcurrentBehave
 Behavior of the next op to execute.
 

Detailed Description

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.

Member Function Documentation

◆ buildEmitter()

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.

Parameters
instis the opcode to behavior map the emitter will use
uniqReserveis the starting offset within the unique address space for any temporary registers
Returns
the newly constructed emitter

Referenced by ghidra::ExecutablePcode::build().

◆ checkForLegalCode()

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.

  • Branches must use p-code relative addressing.
  • Snippets can only read/write from temporary registers
  • Snippets cannot use BRANCHIND, CALL, CALLIND, CALLOTHER, STORE, SEGMENTOP, CPOOLREF, NEW, MULTIEQUAL, or INDIRECT
Returns
true if the current snippet is legal

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().

◆ executeBranch()

void ghidra::EmulateSnippet::executeBranch ( void  )
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.

◆ executeCbranch()

bool ghidra::EmulateSnippet::executeCbranch ( void  )
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.

Returns
the boolean state indicated by the condition

Implements ghidra::Emulate.

References ghidra::EmulatePcodeOp::currentOp, and ghidra::EmulatePcodeOp::getVarnodeValue().

◆ getLoadImageValue()

uintb ghidra::EmulateSnippet::getLoadImageValue ( AddrSpace spc,
uintb  offset,
int4  sz 
) const
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.

Parameters
spcis the address space to pull the value from
offsetis the starting address offset (from within the space) to pull the value from
szis the number of bytes to pull from memory
Returns
indicated bytes arranged as a constant value

References ghidra::calc_mask(), ghidra::EmulatePcodeOp::glb, ghidra::AddrSpace::isBigEndian(), ghidra::Architecture::loader, and ghidra::LoadImage::loadFill().

◆ getTempValue()

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.

Parameters
offsetis the offset of the temporary register to retrieve
Returns
the calculated value or 0 if the register was never written

Referenced by ghidra::ExecutablePcode::evaluate().

◆ getVarnodeValue()

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.

Parameters
vnis the Varnode to read
Returns
the retrieved value

References ghidra::EmulatePcodeOp::getLoadImageValue(), ghidra::AddrSpace::getType(), ghidra::IPTR_CONSTANT, ghidra::IPTR_INTERNAL, ghidra::VarnodeData::offset, ghidra::VarnodeData::size, and ghidra::VarnodeData::space.

◆ resetMemory()

void ghidra::EmulateSnippet::resetMemory ( void  )
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().

◆ setCurrentOp()

void ghidra::EmulateSnippet::setCurrentOp ( int4  i)
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.

Parameters
iis the index

References ghidra::Emulate::currentBehave, and ghidra::PcodeOpRaw::getBehavior().

◆ setVarnodeValue()

void ghidra::EmulateSnippet::setVarnodeValue ( uintb  offset,
uintb  val 
)
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.

Parameters
offsetis the temporary storage offset
valis the value to put into the machine state

References ghidra::EmulatePcodeOp::getVarnodeValue().

Referenced by ghidra::ExecutablePcode::evaluate().


The documentation for this class was generated from the following files: