Ghidra Decompiler Analysis Engine
Public Types | Public Member Functions | Static Public Member Functions | List of all members
FuncCallSpecs Class Reference

A class for analyzing parameters to a sub-function call. More...

#include <fspec.hh>

Inheritance diagram for FuncCallSpecs:
Inheritance graph
[legend]
Collaboration diagram for FuncCallSpecs:
Collaboration graph
[legend]

Public Types

enum  { offset_unknown = 0xBADBEEF }
 

Public Member Functions

 FuncCallSpecs (PcodeOp *call_op)
 Construct based on CALL or CALLIND. More...
 
void setFuncdata (Funcdata *f)
 Set the Funcdata object associated with the called function.
 
FuncCallSpecsclone (PcodeOp *newop) const
 Clone this given the mirrored p-code CALL. More...
 
void initActiveInput (void)
 Turn on analysis recovering input parameters.
 
bool checkInputJoin (int4 slot1, bool ishislot, Varnode *vn1, Varnode *vn2) const
 Check if adjacent parameter trials can be combined into a single logical parameter. More...
 
void doInputJoin (int4 slot1, bool ishislot)
 Join two parameter trials. More...
 
bool lateRestriction (const FuncProto &restrictedProto, vector< Varnode * > &newinput, Varnode *&newoutput)
 Update this prototype to match a given (more specialized) prototype. More...
 
void deindirect (Funcdata &data, Funcdata *newfd)
 Convert this call site from an indirect to a direct function call. More...
 
void forceSet (Funcdata &data, const FuncProto &fp)
 Force a more restrictive prototype on this call site. More...
 
void insertPcode (Funcdata &data)
 Inject any upon-return p-code at this call site. More...
 
void resolveSpacebaseRelative (Funcdata &data, Varnode *phvn)
 Calculate the stack offset of this call site. More...
 
void abortSpacebaseRelative (Funcdata &data)
 Abort the attempt to recover the relative stack offset for this function. More...
 
void finalInputCheck (void)
 Make final activity check on trials that might have been affected by conditional execution. More...
 
void checkInputTrialUse (Funcdata &data, AliasChecker &aliascheck)
 Mark if input trials are being actively used. More...
 
void checkOutputTrialUse (Funcdata &data, vector< Varnode * > &trialvn)
 Mark if output trials are being actively used. More...
 
void buildInputFromTrials (Funcdata &data)
 Set the final input Varnodes to this CALL based on ParamActive analysis. More...
 
void buildOutputFromTrials (Funcdata &data, vector< Varnode * > &trialvn)
 Set the final output Varnode of this CALL based on ParamActive analysis of trials. More...
 
int4 getInputBytesConsumed (int4 slot) const
 Get the estimated number of bytes within the given parameter that are consumed. More...
 
bool setInputBytesConsumed (int4 slot, int4 val) const
 Set the estimated number of bytes within the given parameter that are consumed. More...
 
void paramshiftModifyStart (void)
 Prepend any extra parameters if a paramshift is required.
 
bool paramshiftModifyStop (Funcdata &data)
 Throw out any paramshift parameters. More...
 
uint4 hasEffectTranslate (const Address &addr, int4 size) const
 Calculate type of side-effect for a given storage location (with caller translation) More...
 
- Public Member Functions inherited from FuncProto
 FuncProto (void)
 Constructor.
 
 ~FuncProto (void)
 Destructor.
 
void copy (const FuncProto &op2)
 Copy another function prototype. More...
 
void copyFlowEffects (const FuncProto &op2)
 Copy properties that affect data-flow.
 
void getPieces (PrototypePieces &pieces) const
 Get the raw pieces of the prototype. More...
 
void setPieces (const PrototypePieces &pieces)
 Set this prototype based on raw pieces. More...
 
void setScope (Scope *s, const Address &startpoint)
 Set a backing symbol Scope for this. More...
 
void setInternal (ProtoModel *m, Datatype *vt)
 Set internal backing storage for this. More...
 
void setModel (ProtoModel *m)
 Set the prototype model for this. More...
 
bool isInputLocked (void) const
 Are input data-types locked.
 
void setInputLock (bool val)
 Toggle the data-type lock on input parameters. More...
 
void setOutputLock (bool val)
 Toggle the data-type lock on the return value. More...
 
void setModelLock (bool val)
 Toggle the lock on the prototype model for this. More...
 
void setInline (bool val)
 Toggle the in-line setting for functions with this prototype. More...
 
int4 getInjectId (void) const
 Get the injection id associated with this. More...
 
int4 getReturnBytesConsumed (void) const
 Get an estimate of the number of bytes consumed by callers of this prototype. More...
 
bool setReturnBytesConsumed (int4 val)
 Set the number of bytes consumed by callers of this. More...
 
bool isNoReturn (void) const
 Does a function with this prototype never return.
 
void setNoReturn (bool val)
 Toggle the no-return setting for functions with this prototype. More...
 
bool hasThisPointer (void) const
 Is this a prototype for a class method, taking a this pointer.
 
bool isConstructor (void) const
 Is this prototype for a class constructor method.
 
void setConstructor (bool val)
 Toggle whether this prototype is a constructor method. More...
 
bool isDestructor (void) const
 Is this prototype for a class destructor method.
 
void setDestructor (bool val)
 Toggle whether this prototype is a destructor method. More...
 
bool hasInputErrors (void) const
 Has this prototype been marked as having an incorrect input parameter descriptions.
 
bool hasOutputErrors (void) const
 Has this prototype been marked as having an incorrect return value description.
 
void setInputErrors (bool val)
 Toggle the input error setting for this prototype. More...
 
void setOutputErrors (bool val)
 Toggle the output error setting for this prototype. More...
 
void resolveExtraPop (void)
 Assuming this prototype is locked, calculate the extrapop. More...
 
void clearUnlockedInput (void)
 Clear input parameters that have not been locked.
 
void clearUnlockedOutput (void)
 Clear the return value if it has not been locked.
 
void clearInput (void)
 Clear all input parameters regardless of lock.
 
void cancelInjectId (void)
 Turn-off any in-lining for this function.
 
void resolveModel (ParamActive *active)
 If this has a merged model, pick the most likely model (from the merged set) More...
 
void deriveInputMap (ParamActive *active) const
 Given a list of input trials, derive the most likely inputs for this prototype. More...
 
void deriveOutputMap (ParamActive *active) const
 Given a list of output trials, derive the most likely return value for this prototype. More...
 
bool checkInputJoin (const Address &hiaddr, int4 hisz, const Address &loaddr, int4 losz) const
 Check if the given two input storage locations can represent a single logical parameter. More...
 
bool checkInputSplit (const Address &loc, int4 size, int4 splitpoint) const
 Check if it makes sense to split a single storage location into two input parameters. More...
 
void updateInputTypes (Funcdata &data, const vector< Varnode * > &triallist, ParamActive *activeinput)
 Update input parameters based on Varnode trials. More...
 
void updateInputNoTypes (Funcdata &data, const vector< Varnode * > &triallist, ParamActive *activeinput)
 Update input parameters based on Varnode trials, but do not store the data-type. More...
 
void updateOutputTypes (const vector< Varnode * > &triallist)
 Update the return value based on Varnode trials. More...
 
void updateOutputNoTypes (const vector< Varnode * > &triallist, TypeFactory *factory)
 Update the return value based on Varnode trials, but don't store the data-type. More...
 
void updateAllTypes (const vector< string > &namelist, const vector< Datatype * > &typelist, bool dtdtdt)
 Set this entire function prototype based on a list of names and data-types. More...
 
uint4 hasEffect (const Address &addr, int4 size) const
 Calculate the effect this has an a given storage location. More...
 
vector< EffectRecord >::const_iterator effectBegin (void) const
 Get iterator to front of EffectRecord list.
 
vector< EffectRecord >::const_iterator effectEnd (void) const
 Get iterator to end of EffectRecord list.
 
int4 numLikelyTrash (void) const
 Get the number of likely-trash locations. More...
 
const VarnodeDatagetLikelyTrash (int4 i) const
 Get the i-th likely-trash location. More...
 
int4 characterizeAsInputParam (const Address &addr, int4 size) const
 Decide whether a given storage location could be, or could hold, an input parameter. More...
 
bool possibleInputParam (const Address &addr, int4 size) const
 Decide whether a given storage location could be an input parameter. More...
 
bool possibleOutputParam (const Address &addr, int4 size) const
 Decide whether a given storage location could be a return value. More...
 
int4 getMaxInputDelay (void) const
 Return the maximum heritage delay across all possible input parameters. More...
 
int4 getMaxOutputDelay (void) const
 Return the maximum heritage delay across all possible return values. More...
 
bool unjustifiedInputParam (const Address &addr, int4 size, VarnodeData &res) const
 Check if the given storage location looks like an unjustified input parameter. More...
 
OpCode assumedInputExtension (const Address &addr, int4 size, VarnodeData &res) const
 Get the type of extension and containing input parameter for the given storage. More...
 
OpCode assumedOutputExtension (const Address &addr, int4 size, VarnodeData &res) const
 Get the type of extension and containing return value location for the given storage. More...
 
bool getBiggestContainedInputParam (const Address &loc, int4 size, VarnodeData &res) const
 Pass-back the biggest potential input parameter contained within the given range. More...
 
bool isCompatible (const FuncProto &op2) const
 Decide if this can be safely restricted to match another prototype. More...
 
void printRaw (const string &funcname, ostream &s) const
 Print this prototype as a single line of text. More...
 
uint4 getComparableFlags (void) const
 Get the comparable properties of this prototype. More...
 
void saveXml (ostream &s) const
 Save this to an XML stream as a <prototype> tag. More...
 
void restoreXml (const Element *el, Architecture *glb)
 Restore this from an XML stream. More...
 

Static Public Member Functions

static VarnodefindPreexistingWhole (Varnode *vn1, Varnode *vn2)
 Check if given two Varnodes are merged into a whole. More...
 
static FuncCallSpecsgetFspecFromConst (const Address &addr)
 Convert FspecSpace addresses to the underlying FuncCallSpecs object. More...
 
static bool compareByEntryAddress (const FuncCallSpecs *a, const FuncCallSpecs *b)
 Compare FuncCallSpecs by function entry address. More...
 
static void countMatchingCalls (const vector< FuncCallSpecs * > &qlst)
 Calculate the number of times an individual sub-function is called. More...
 

Additional Inherited Members

- Protected Member Functions inherited from FuncProto
void paramShift (int4 paramshift)
 Add parameters to the front of the input parameter list. More...
 
void setParamshiftApplied (bool val)
 Toggle whether a parameter shift has been applied.
 

Detailed Description

A class for analyzing parameters to a sub-function call.

This can be viewed as a function prototype that evolves over the course of analysis. It derives off of FuncProto and includes facilities for analyzing data-flow for parameter information. This is the high-level object managing the examination of data-flow to recover a working prototype (ParamActive), holding a stack-pointer placeholder to facilitate stack analysis, and deciding on the working extrapop for the CALL.

A stack-pointer placeholder is a temporary Varnode in the input operands of the CALL or CALLIND that is defined by a LOAD from the stack-pointer. By examining the pointer, the exact value of the stack-pointer (relative to its incoming value) can be computed at the point of the CALL. The temporary can arise naturally if stack parameters are a possibility, otherwise a placeholder temporary is artificially inserted into the CALL input. At the time heritage of the stack space is computed, the placeholder is examined to read off the active stack-pointer offset for the CALL and the placeholder is removed.

Member Enumeration Documentation

◆ anonymous enum

anonymous enum
Enumerator
offset_unknown 

"Magic" stack offset indicating the offset is unknown

Constructor & Destructor Documentation

◆ FuncCallSpecs()

FuncCallSpecs::FuncCallSpecs ( PcodeOp call_op)

Construct based on CALL or CALLIND.

Parameters
call_opis the representative call site within the data-flow

Member Function Documentation

◆ abortSpacebaseRelative()

void FuncCallSpecs::abortSpacebaseRelative ( Funcdata data)

Abort the attempt to recover the relative stack offset for this function.

Any stack-pointer placeholder is removed.

Parameters
datais the calling function

◆ buildInputFromTrials()

void FuncCallSpecs::buildInputFromTrials ( Funcdata data)

Set the final input Varnodes to this CALL based on ParamActive analysis.

Varnodes that don't look like parameters are removed. Parameters that are unreferenced are filled in. Other Varnode inputs may be truncated or extended. This prototype itself is unchanged.

Parameters
datais the calling function

◆ buildOutputFromTrials()

void FuncCallSpecs::buildOutputFromTrials ( Funcdata data,
vector< Varnode * > &  trialvn 
)

Set the final output Varnode of this CALL based on ParamActive analysis of trials.

If it exists, the active output trial is moved to be the output Varnode of this CALL. If there are two active trials, they are merged as a single output of the CALL. Any INDIRECT ops that were holding the active trials are removed. This prototype itself is unchanged.

Parameters
datais the calling function
trialvnis the list of Varnodes associated with trials

◆ checkInputJoin()

bool FuncCallSpecs::checkInputJoin ( int4  slot1,
bool  ishislot,
Varnode vn1,
Varnode vn2 
) const

Check if adjacent parameter trials can be combined into a single logical parameter.

A slot must be provided indicating the trial and the only following it.

Parameters
slot1is the first trial slot
ishislotis true if the first slot will be the most significant piece
vn1is the Varnode corresponding to the first trial
vn2is the Varnode corresponding to the second trial
Returns
true if the trials can be combined

◆ checkInputTrialUse()

void FuncCallSpecs::checkInputTrialUse ( Funcdata data,
AliasChecker aliascheck 
)

Mark if input trials are being actively used.

Run through each input trial and try to make a determination if the trial is active or not, meaning basically that a write has occurred on the trial with no intervening reads between the write and the call.

Parameters
datais the calling function
aliascheckholds local aliasing information about the function

◆ checkOutputTrialUse()

void FuncCallSpecs::checkOutputTrialUse ( Funcdata data,
vector< Varnode * > &  trialvn 
)

Mark if output trials are being actively used.

Run through each output trial and try to make a determination if the trial is active or not, meaning basically that the first occurrence of a trial after the call is a read.

Parameters
datais the calling function
trialvnwill hold Varnodes corresponding to the trials

◆ clone()

FuncCallSpecs * FuncCallSpecs::clone ( PcodeOp newop) const

Clone this given the mirrored p-code CALL.

Parameters
newopreplaces the CALL or CALLIND op in the clone
Returns
the cloned FuncCallSpecs

◆ compareByEntryAddress()

static bool FuncCallSpecs::compareByEntryAddress ( const FuncCallSpecs a,
const FuncCallSpecs b 
)
inlinestatic

Compare FuncCallSpecs by function entry address.

Parameters
ais the first FuncCallSpecs to compare
bis the second to compare
Returns
true if the first should be ordered before the second

◆ countMatchingCalls()

void FuncCallSpecs::countMatchingCalls ( const vector< FuncCallSpecs * > &  qlst)
static

Calculate the number of times an individual sub-function is called.

Provided a list of all call sites for a calling function, tally the number of calls to the same sub-function. Update the matchCallCount field of each FuncCallSpecs

Parameters
qlstis the list of call sites (FuncCallSpecs) for the calling function

◆ deindirect()

void FuncCallSpecs::deindirect ( Funcdata data,
Funcdata newfd 
)

Convert this call site from an indirect to a direct function call.

This call site must be a CALLIND, and the function that it is actually calling must be provided. The method makes a determination if the current state of data-flow allows converting to the prototype of the new function without dropping information due to inaccurate dead-code elimination. If conversion is safe, it is performed immediately. Otherwise a restart directive issued to force decompilation to restart from scratch (now with the direct function in hand)

Parameters
datais the calling function
newfdis the Funcdata object that we know is the destination of this CALLIND

◆ doInputJoin()

void FuncCallSpecs::doInputJoin ( int4  slot1,
bool  ishislot 
)

Join two parameter trials.

We assume checkInputJoin() has returned true. Perform the join, replacing the given adjacent trials with a single merged parameter.

Parameters
slot1is the trial slot of the first trial
ishislotis true if the first slot will be the most significant piece

◆ finalInputCheck()

void FuncCallSpecs::finalInputCheck ( void  )

Make final activity check on trials that might have been affected by conditional execution.

The activity level a trial may change once conditional execution has been analyzed. This routine (re)checks trials that might be affected by this, which may then be converted to not used.

◆ findPreexistingWhole()

Varnode * FuncCallSpecs::findPreexistingWhole ( Varnode vn1,
Varnode vn2 
)
static

Check if given two Varnodes are merged into a whole.

If the Varnodes are merged immediately into a common whole and aren't used for anything else, return the whole Varnode.

Parameters
vn1is the first given Varnode
vn2is the second given Varnode
Returns
the combined Varnode or NULL

◆ forceSet()

void FuncCallSpecs::forceSet ( Funcdata data,
const FuncProto fp 
)

Force a more restrictive prototype on this call site.

A new prototype must be given, typically recovered from a function pointer data-type that has been propagated to this call site. The method makes a determination if the current state of data-flow allows converting to the new prototype without dropping information due to inaccurate dead-code elimination. If conversion is safe, it is performed immediately. Otherwise a restart directive issued to force decompilation to restart from scratch (now with the new prototype in hand)

Parameters
datais the calling function
fpis the new (more restrictive) function prototype

◆ getFspecFromConst()

static FuncCallSpecs* FuncCallSpecs::getFspecFromConst ( const Address addr)
inlinestatic

Convert FspecSpace addresses to the underlying FuncCallSpecs object.

Parameters
addris the given fspec address
Returns
the FuncCallSpecs object

◆ getInputBytesConsumed()

int4 FuncCallSpecs::getInputBytesConsumed ( int4  slot) const

Get the estimated number of bytes within the given parameter that are consumed.

As a function is decompiled, there may hints about how many of the bytes, within the storage location used to pass the parameter, are used by this sub-function. A non-zero value means that that many least significant bytes of the storage location are used. A value of zero means all bytes are presumed used.

Parameters
slotis the slot of the given input parameter
Returns
the number of bytes used (or 0)

◆ hasEffectTranslate()

uint4 FuncCallSpecs::hasEffectTranslate ( const Address addr,
int4  size 
) const

Calculate type of side-effect for a given storage location (with caller translation)

Stack locations should be provided from the caller's perspective. They are automatically translated to the callee's perspective before making the underlying query.

Parameters
addris the starting address of the storage location
sizeis the number of bytes in the storage
Returns
the effect type

◆ insertPcode()

void FuncCallSpecs::insertPcode ( Funcdata data)

Inject any upon-return p-code at this call site.

This function prototype may trigger injection of p-code immediately after the CALL or CALLIND to mimic a portion of the callee that decompilation of the caller otherwise wouldn't see.

Parameters
datais the calling function

◆ lateRestriction()

bool FuncCallSpecs::lateRestriction ( const FuncProto restrictedProto,
vector< Varnode * > &  newinput,
Varnode *&  newoutput 
)

Update this prototype to match a given (more specialized) prototype.

This method assumes that this prototype is in some intermediate state during the parameter recovery process and that a new definitive (locked) prototype is discovered for this call site. This method checks to see if this can be updated to match the new prototype without missing any data-flow. If so, this is updated, and new input and output Varnodes for the CALL are passed back.

Parameters
restrictedProtois the new definitive function prototype
newinputwill hold the new list of input Varnodes for the CALL
newoutputwill hold the new output Varnode or NULL
Returns
true if this can be fully converted

◆ paramshiftModifyStop()

bool FuncCallSpecs::paramshiftModifyStop ( Funcdata data)

Throw out any paramshift parameters.

Parameters
datais the calling function
Returns
true if a change was made

◆ resolveSpacebaseRelative()

void FuncCallSpecs::resolveSpacebaseRelative ( Funcdata data,
Varnode phvn 
)

Calculate the stack offset of this call site.

The given Varnode must be the input to the CALL in the placeholder slot and must be defined by a COPY from a Varnode in the stack space. Calculate the offset of the stack-pointer at the point of this CALL, relative to the incoming stack-pointer value. This can be obtained either be looking at a stack parameter, or if there is no stack parameter, the stack-pointer placeholder can be used. If the placeholder has no other purpose, remove it.

Parameters
datais the calling function
phvnis the Varnode in the placeholder slot for this CALL

◆ setInputBytesConsumed()

bool FuncCallSpecs::setInputBytesConsumed ( int4  slot,
int4  val 
) const

Set the estimated number of bytes within the given parameter that are consumed.

This provides a hint to the dead code consume algorithm, while examining the calling function, about how the given parameter within the subfunction is used. A non-zero value means that that many least significant bytes of the storage location are used. A value of zero means all bytes are presumed used.

Parameters
slotis the slot of the given input parameter
valis the number of bytes consumed (or 0)
Returns
true if there was a change in the estimate

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