GP-3735 Additional isPointer checks for CALL,CALLIND, and COPY (RETURN)

This commit is contained in:
caheckman 2023-08-10 22:36:44 +00:00
parent 339130a6a1
commit 1fdfb96d57
2 changed files with 41 additions and 5 deletions

View file

@ -1023,6 +1023,28 @@ AddrSpace *ActionConstantPtr::selectInferSpace(Varnode *vn,PcodeOp *op,const vec
return resSpace; return resSpace;
} }
/// \brief Check if we need to try to infer a constant pointer from the input of the given COPY
///
/// In general, we do want try, but there is a special case where the COPY feeds into a RETURN and
/// the function does \e not return a pointer. We also consider the \b infer_pointers boolean.
/// \param op is the given COPY op
/// \param data is the function
/// \return \b true if we should try to infer
bool ActionConstantPtr::checkCopy(PcodeOp *op,Funcdata &data)
{
Varnode *vn = op->getOut();
PcodeOp *retOp = vn->loneDescend();
if (retOp != (PcodeOp *)0 && retOp->code() == CPUI_RETURN && data.getFuncProto().isOutputLocked()) {
type_metatype meta = data.getFuncProto().getOutput()->getType()->getMetatype();
if (meta != TYPE_PTR && meta != TYPE_UNKNOWN) {
return false; // Do NOT infer, we know the constant can't be pointer
}
return true; // Try to infer, regardless of infer_pointers config, because we KNOW it is a pointer
}
return data.getArch()->infer_pointers;
}
/// \brief Determine if given Varnode might be a pointer constant. /// \brief Determine if given Varnode might be a pointer constant.
/// ///
/// If it is a pointer, return the symbol it points to, or NULL otherwise. If it is determined /// If it is a pointer, return the symbol it points to, or NULL otherwise. If it is determined
@ -1054,23 +1076,36 @@ SymbolEntry *ActionConstantPtr::isPointer(AddrSpace *spc,Varnode *vn,PcodeOp *op
// Check if the constant is involved in a potential pointer expression // Check if the constant is involved in a potential pointer expression
// as the base // as the base
switch(op->code()) { switch(op->code()) {
case CPUI_RETURN:
case CPUI_CALL: case CPUI_CALL:
case CPUI_CALLIND: case CPUI_CALLIND:
// A constant parameter or return value could be a pointer {
if (!glb->infer_pointers)
return (SymbolEntry *)0;
if (slot==0) if (slot==0)
return (SymbolEntry *)0; return (SymbolEntry *)0;
// A constant parameter could be a pointer
FuncCallSpecs *fc = data.getCallSpecs(op);
if (fc != (FuncCallSpecs *)0 && fc->isInputLocked() && fc->numParams() > slot-1) {
type_metatype meta = fc->getParam(slot-1)->getType()->getMetatype();
if (meta != TYPE_PTR && meta != TYPE_UNKNOWN) {
return (SymbolEntry *)0; // Definitely not passing a pointer
}
}
else if (!glb->infer_pointers)
return (SymbolEntry *)0;
break;
}
case CPUI_COPY:
if (!checkCopy(op, data))
return (SymbolEntry *)0;
break; break;
case CPUI_PIECE: case CPUI_PIECE:
// Pointers get concatenated in structures // Pointers get concatenated in structures
case CPUI_COPY:
case CPUI_INT_EQUAL: case CPUI_INT_EQUAL:
case CPUI_INT_NOTEQUAL: case CPUI_INT_NOTEQUAL:
case CPUI_INT_LESS: case CPUI_INT_LESS:
case CPUI_INT_LESSEQUAL: case CPUI_INT_LESSEQUAL:
// A comparison with a constant could be a pointer // A comparison with a constant could be a pointer
if (!glb->infer_pointers)
return (SymbolEntry *)0;
break; break;
case CPUI_INT_ADD: case CPUI_INT_ADD:
outvn = op->getOut(); outvn = op->getOut();

View file

@ -189,6 +189,7 @@ class ActionConstantPtr : public Action {
int4 localcount; ///< Number of passes made for this function int4 localcount; ///< Number of passes made for this function
static AddrSpace *searchForSpaceAttribute(Varnode *vn,PcodeOp *op); static AddrSpace *searchForSpaceAttribute(Varnode *vn,PcodeOp *op);
static AddrSpace *selectInferSpace(Varnode *vn,PcodeOp *op,const vector<AddrSpace *> &spaceList); static AddrSpace *selectInferSpace(Varnode *vn,PcodeOp *op,const vector<AddrSpace *> &spaceList);
static bool checkCopy(PcodeOp *op,Funcdata &data);
static SymbolEntry *isPointer(AddrSpace *spc,Varnode *vn,PcodeOp *op,int4 slot, static SymbolEntry *isPointer(AddrSpace *spc,Varnode *vn,PcodeOp *op,int4 slot,
Address &rampoint,uintb &fullEncoding,Funcdata &data); Address &rampoint,uintb &fullEncoding,Funcdata &data);
public: public: