AE APIs - SVF-tools/Software-Security-Analysis GitHub Wiki

Essential API Documentation for Labs and Assignments

Lab-Exercise-3

API Introduction
getNodeID("variable") Retrieves the node ID of the specified variable.
IntervalValue(lower, upper) Creates an interval value.
AbstractValue::getInterval() Retrieves the interval value of the abstract state.
AbstractValue::join_with(value) Merges the current value with another value.
getMemObjAddress("variable") Retrieves the memory object address of the specified variable.
AddressValue(getMemObjAddress("variable")) Creates an address value initialized to the memory object address of the specified variable.
AEState::widening(state) Performs widening on the given state.
AEState::narrowing(state) Performs narrowing on the given state.
AEState::joinWith(state) Merges the current state with another state.
AbstractValue::meet_with(value) Performs an intersection operation between the current value and another value.
getGepObjAddress("variable", offset) Retrieves the GEP (GetElementPtr) object address of the specified variable with the given offset.
AEState::loadValue(varId) Loads the abstract value from the variable ID's address.
AEState::storeValue(varId, val) Stores the abstract value at the variable ID's address.
AEState::printAbstractState() Prints the abstract trace for debugging purposes.

AEState::widening(state)

  • Perform widening on the current state with another state.

    For example,

    void exampleWidening() {
        AEState as1, as2;
        NodeID a = getNodeID("a");
        as1[a] = IntervalValue(1, 5); // as1: a in [1, 5]
        as2[a] = IntervalValue(3, 10); // as2: a in [3, 10]
        AEState widenedState = as1.widening(as2); // widenedState: a in [1, +inf]
    }
    

    Input: state (an AEState)

    Output: Widened state (an AEState)


AEState::loadValue(varId) and AEState::storeValue(varId, val)

  • Load and store values associated with a variable ID.

    For example,

    void exampleLoadValue() {
        AEState as;
        NodeID a = getNodeID("a");
        NodeID p = getNodeID("p");
        NodeID malloc = getNodeID("malloc");
        as[p] = AddressValue(getMemObjAddress("malloc"));
        as.storeValue(p, IntervalValue(42, 42)); // Store 42 at address p
    
        AbstractValue loadedValue = as.loadValue(p);
    
        std::cout << loadedValue.toString() << std::endl;
    }
    

    Input: varId (a NodeID), val (an AbstractValue)

    Output: Loaded value (an AbstractValue, can be Interval Value or Address Value)


AEState::printAbstractState()

  • Print the abstract trace for debugging purposes.

    For example,

    void examplePrintAbstractState() {
        AEState as;
        NodeID a = getNodeID("a");
        NodeID b = getNodeID("b");
    
        as[a] = IntervalValue(1, 5); // a in [1, 5]
        as[b] = IntervalValue(3, 7); // b in [3, 7]
    
        as.printAbstractState(); // Print the abstract trace for debugging
    }
    

    Input: None

    Output: None (prints the abstract trace)

-----------Var and Value-----------
Var2(b)             :  Value: [3, 7]
Var1(a)             :  Value: [1, 5]
-----------------------------------------

Assignment-3

API Introduction
SVFUtil::isa<CallICFGNode>(stmt) Checks if the given statement is a call ICFG node.
SVFUtil::dyn_cast<GepStmt>(stmt) Dynamically casts the given statement to a GepStmt type.
AbstractExecution::getAbsStateFromTrace(node) Retrieves the abstract state of the given ICFG node.
GepStmt::getLHSVarID() Retrieves the left-hand side variable ID of the GepStmt.
GepStmt::getRHSVarID() Retrieves the right-hand side variable ID of the GepStmt.
AEState::getAddrs() Retrieves the address values in the abstract state.
AEState::getInternalID(addr) Retrieves the internal ID of the given address.
SVFUtil::cast<GepObjVar>(node) Statically casts the given node to a GepObjVar type.
svfir->getGNode(id) Retrieves the SVFVar with the given ID.
svfir->getBaseObj(id)->getByteSizeOfObj() Retrieves the byte size of the base object.
Options::WidenDelay() Retrieves the value of the widen delay option.
AEState::widening(state) Performs widening on the given state.
AEState::narrowing(state) Performs narrowing on the given state.
handleSingletonWTO(wto) Handles a singleton WTO (Weak Topological Order) which includes an ICFGNode.
handleWTOComponents(components) Handles WTO components (a series of singleton WTO nodes or cycles)
mergeStatesFromPredecessors(node, state) Merges states from predecessor ICFGNodes.
CopyStmt::getLHSVarID() Retrieves the left-hand side variable ID of the copy statement.
CopyStmt::getRHSVarID() Retrieves the right-hand side variable ID of the copy statement.
BinaryOPStmt::getOpVarID(index) Retrieves the operand variable ID of the binary operation statement.
BinaryOPStmt::getResID() Retrieves the result variable ID of the binary operation statement.
BinaryOPStmt::getOpcode() Retrieves the opcode of the binary operation statement.
AEState::loadValue(varId) Loads the abstract value of the given variable ID.
AEState::storeValue(varId, val) Stores the abstract value at the given variable ID.
LoadStmt::getRHSVarID() Retrieves the right-hand side variable ID of the load statement.
LoadStmt::getLHSVarID() Retrieves the left-hand side variable ID of the load statement.
IntervalValue::getIntNumeral() Returns the integer representation of the interval value (lower and upper bounds are the same)
AEState::getByteOffset(gep) Retrieves the byte offset of the GEP statement.
AEState::getElementIndex(gep) Retrieves the element index of the GEP statement.
AEState::getGepObjAddrs(varID, offset) Retrieves the address of the GEP object.
AEState::printAbstractState() Prints the abstract trace for debugging purposes.
AbstractExecution::runOnModule(icfg) Runs the abstract execution on the given ICFG module.
AbstractExecution::handleSingletonWTO(node) Handles a singleton WTO node in the control flow graph.
AbstractExecution::handleCycleWTO(cycle) Handles a WTO cycle in the control flow graph.
AbstractExecution::handleGlobalNode() Handles global variables and initializations.
AbstractExecution::analyse() The driver function to conduct the overall analysis of the program.
AbstractExecution::updateAbsState(stmt) Updates the abstract state for each type of SVF statement.
AbstractExecution::reportBufOverflow(node) Reports a buffer overflow for a given ICFG node.
AbstractExecution::handleStubFunctions(call) Handles stub functions for verifying abstract interpretation results.
AbstractExecution::handleCallSite(callnode) Handles a call site in the control flow graph.
AbstractExecution::updateGepObjOffsetFromBase(gepAddrs, objAddrs, offset) Updates the GEP object offset from the base.
AbstractExecution::getAccessOffset(objId, gep) Returns the accessing offset of an object at a GepStmt.
AbstractExecution::ensureAllAssertsValidated() Ensures all assertions are validated.
AbstractExecution::initWTO() Marks recursive functions in the call graph.
AbstractExecutionHelper::printReport() Prints the buffer overflow report.
AbstractExecutionHelper::addToGepObjOffsetFromBase(obj, offset) Adds the offset to the GEP object from the base.
AbstractExecutionHelper::hasGepObjOffsetFromBase(obj) Checks if the GEP object has an offset from the base.
AbstractExecutionHelper::getGepObjOffsetFromBase(obj) Retrieves the offset of the GEP object from the base.

AEState::getInternalID(addr)

  • Retrieve the internal ID associated with a given address.

    For example,

    // Assuming 'addr' is a valid address object
    int internalID = AEState::getInternalID(addr);
    std::cout << "Internal ID: " << internalID << std::endl;

    Input: addr (an address object starting with 0x7f****), e.g. 0x7f0005

    Output: Internal ID associated with addr (remove the mask of 0x7f0000), e.g. 5 (0x7f0005 remove the mask)


bufOverflowHelper.addToGepObjOffsetFromBase(objVar, offset)

  • Add an offset to the GEP object offset from the base object.

    For example,

    // Assuming 'GepObjVar' is a valid Gep object variable and 'offset' is an integer
    bufOverflowHelper.addToGepObjOffsetFromBase(gepObjVar, offset);

    Input: gepObjVar (a gep object variable), offset (an Interval Value)

    Output: None (operation performed)


bufOverflowHelper.hasGepObjOffsetFromBase(objVar)

  • Check if there is a GEP object offset from the base object.

    For example,

    // Assuming 'objVar' is a valid object variable
    bool hasOffset = bufOverflowHelper.hasGepObjOffsetFromBase(gepObjVar);

    Input: gepObjVar (a gep object variable)

    Output: Boolean indicating if there is a GEP object offset from the base


bufOverflowHelper.getGepObjOffsetFromBase(objVar)

  • Retrieve the GEP object offset from the base object.

    For example,

    // Assuming 'objVar' is a valid object variable
    IntervalValue accessOffset = _bufOverflowHelper.getGepObjOffsetFromBase(objVar);
    std::cout << "GEP object offset from base: " << accessOffset.toString() << std::endl;

    Input: gepObjVar (a gep object variable)

    Output: Interval value representing the GEP object offset from the base


svfir->getBaseObj(id)->getByteSizeOfObj()

  • Get the byte size of a base object given its ID.

    For example,

    // Assuming 'id' is a valid object ID
    u32_t byteSize = svfir->getBaseObj(id)->getByteSizeOfObj();
    std::cout << "Byte size of base object: " << byteSize << std::endl;

    Input: id (an object ID)

    Output: Unsigned integer representing the byte size of the base object


AEState::getByteOffset(gep)

  • Retrieve the byte offset (has lower and upper bound) for a given GEP instruction.

    For example,

    // Assuming 'gep' is a valid GEP instruction
    IntervalValue byteOffset = as.getByteOffset(gep);
    std::cout << "Byte offset: " << byteOffset.toString() << std::endl;

    Input: gep (a GEP instruction)

    Output: IntervalValue representing the byte offset


AEState::getGepObjAddrs(varID, offset)

  • Get the addresses of GEP objects given a variable ID and an offset.

    For example,

    // Assuming 'varID' is a valid variable ID and 'offset' is an integer
    auto gepObjAddrs = as.getGepObjAddrs(varID, offset);
    std::cout << "GEP object addresses: ";
    for (const auto& addr : gepObjAddrs) {
        std::cout << "0x" << std::hex << addr << ", ";
    }
    std::cout << std::endl;

    Input: varID (a variable ID), offset (an Interval Value)

    Output: List of addresses of GEP objects


AbstractExecution::updateGepObjOffsetFromBase(gepAddrs, objAddrs, offset)

  • Update the GEP object offset from the base object.

    For example,

    // Assuming 'gepAddrs' and 'objAddrs' are valid address lists and 'offset' is an integer
    AbstractExecution::updateGepObjOffsetFromBase(gepAddrs, objAddrs, offset);

    Input: gepAddrs (list of GEP addresses), objAddrs (list of object addresses), offset (an IntervalValue)

    Output: None (operation performed). For example, for $gepObj = getelementptr $obj, 20. gepAddrs is the addresses of $gepObj, objAddrsis the addresses of $obj, 20 is the offset (if it is concrete value, the lower bound and the upper bound are both equal to 20.)


AbstractExecution::getAccessOffset(objId, gep)

  • Retrieve the access offset for a given object ID and GEP instruction.

    For example,

    // Assuming 'objId' is a valid object ID and 'gep' is a valid GEP instruction
    IntervalValue accessOffset = AbstractExecution::getAccessOffset(objId, gep);
    std::cout << "Access offset: " << accessOffset.toString() << std::endl;

    Input: objId (an object ID), gep (a GEP instruction)

    Output: IntervalValue representing the access offset


AEState::printAbstractState()

  • Print the abstract trace of the execution.

    For example,

    // Assuming `AEState` is an Abstract Trace
    AEState& as = getAbsStateFromTrace(icfgNode);
    as.printAbstractState();

    Input: None

    Output: Prints the abstract trace to the standard output, e.g.

-----------Var and Value-----------
Var4                 Value: [5, 5]
Var2                 Value: [5, 5]
Var1                 Value: {0x7f000005}
0x7f000005           Value: [5, 5]
——————————————---------------------

⚠️ **GitHub.com Fallback** ⚠️