AE CPP APIs - SVF-tools/Software-Security-Analysis GitHub Wiki
| 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. |
-
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)
-
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)
-
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]
-----------------------------------------
Note on naming: SVF master no longer has a separate
AbstractStateManager/AEStateclass. The dense per-ICFGNodetrace and the GEP / load / store / pointer helpers now live onSVF::AbstractInterpretation. Assignment-3'sAbstractExecutionholds a pointer to that instance under the field namesvfStateMgr(seeAssignment_3.h), so the wiki usessvfStateMgr->...below where the old wiki saidAEState::.... The per-nodeSVF::AbstractStatevalue object is still returned bygetAbsStateFromTrace(node)and is what you callwidening/narrowing/joinWithon.
| API | Introduction |
|---|---|
SVFUtil::isa<CallICFGNode>(stmt->getICFGNode()) |
Checks if the statement's containing ICFG node is a call 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 from the trace (returns an AbstractState&). |
GepStmt::getLHSVarID() |
Retrieves the left-hand side variable ID of the GepStmt (inherited from AssignStmt). |
GepStmt::getRHSVarID() |
Retrieves the right-hand side variable ID of the GepStmt (inherited from AssignStmt). |
as[id].getAddrs() |
Retrieves the AddressValue of variable id from an AbstractState as (as[id] returns an AbstractValue, on which getAddrs() lives). |
as.getIDFromAddr(addr) |
Retrieves the internal ID of the given virtual address (method on AbstractState). |
svfir->getBaseObject(id)->getByteSizeOfObj() |
Retrieves the byte size of the base object. |
Options::WidenDelay() |
Retrieves the value of the widen delay option. |
as.widening(other) |
Performs widening on the current AbstractState with another AbstractState. |
as.narrowing(other) |
Performs narrowing on the current AbstractState with another AbstractState. |
as.joinWith(other) / as.meetWith(other)
|
Join / meet the current AbstractState with another (in-place). |
AbstractExecution::handleICFGNode(ICFGNode*) |
Handles a singleton WTO (Weak Topological Order) which includes an ICFGNode (defined in Assignment-3's AbstractExecution). |
AbstractExecution::handleICFGCycle(ICFGCycleWTO*) |
Handles WTO cycles, which includes a set of ICFGNodes. |
ICFGCycleWTO::head()->getICFGNode() |
Get the cycle head ICFGNode. |
AbstractExecution::mergeStatesFromPredecessors(node, as) |
Merges states from predecessor ICFGNodes into as (defined on Assignment-3's AbstractExecution). |
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. |
CallPE::getResID() |
Retrieves the formal-parameter variable ID for a phi-like call parameter statement. |
CallPE::getOpVarNum() |
Retrieves the number of actual-parameter operands in a phi-like CallPE. |
CallPE::getOpVarID(index) |
Retrieves the actual-parameter variable ID at index. |
CallPE::getOpCallICFGNode(index) |
Retrieves the call site corresponding to the actual-parameter operand at index. |
svfStateMgr->loadValue(pointer, node) |
Loads the abstract value pointed to by pointer (a ValVar*) at node. Returns an AbstractValue. Replaces the old AEState::loadValue(varId). |
svfStateMgr->storeValue(pointer, val, node) |
Stores val (an AbstractValue) through the pointer at node. Replaces the old AEState::storeValue(varId, val). |
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. |
svfStateMgr->getGepByteOffset(gep) |
Retrieves the byte offset of the GEP statement. Returns an IntervalValue. Replaces the old AEState::getByteOffset(gep). |
svfStateMgr->getGepElementIndex(gep) |
Retrieves the element index of the GEP statement. Replaces the old AEState::getElementIndex(gep). |
svfStateMgr->getGepObjAddrs(pointer, offset) |
Retrieves the addresses of GEP objects (pointer is a ValVar*, offset is an IntervalValue). Replaces the old AEState::getGepObjAddrs(varID, offset). |
AbstractExecution::reportBufOverflow(node) |
Reports a buffer overflow for a given ICFG node (Assignment-3 only). |
AbstractExecution::updateGepObjOffsetFromBase(as, gepAddrs, objAddrs, offset) |
Updates the GEP object offset from the base on AbstractState as. |
AbstractExecution::getAccessOffset(objId, gep) |
Returns the accessing offset of an object at a GepStmt. |
AbstractExecution::updateStateOnExtCall(extCallNode) |
Handles external calls, checking for buffer overflows, and updates abstract states using memcpy-like APIs via AbsExtAPI::handleMemcpy. |
utils->handleMemcpy(dst, src, len, start_idx, extCallNode) |
Simulates a memcpy operation: copies len bytes from the source variable src (a ValVar*) to the destination variable dst (a ValVar*), starting at offset start_idx, at the CallICFGNode extCallNode. The function automatically determines the element size (for arrays or pointers) and performs element-wise copying, updating the abstract state accordingly. Only objects present in the abstract state are copied. (utils is the AbsExtAPI* member of AbstractExecution.) |
utils->getStrlen(strValue, extCallNode) |
Computes a null-terminated string length from the abstract state managed by svfStateMgr. |
bufOverflowHelper.addToGepObjOffsetFromBase(gepObjVar, offset) |
Adds an offset to the GEP object offset from the base object (on Assignment-3's AbstractExecutionHelper). |
bufOverflowHelper.hasGepObjOffsetFromBase(gepObjVar) |
Checks if there is a GEP object offset from the base object. |
bufOverflowHelper.getGepObjOffsetFromBase(gepObjVar) |
Retrieves the GEP object offset from the base object. |
as.printAbstractState() |
Prints the abstract state of the execution (method on AbstractState). |
-
CallPEis phi-like in current SVF: the result is the formal parameter, and each operand is one actual parameter from a specific call site.For example,
void AbstractExecution::updateStateOnCall(const CallPE* callPE) { AbstractState& as = getAbsStateFromTrace(callPE->getICFGNode()); NodeID formal = callPE->getResID(); AbstractValue joined; for (u32_t i = 0; i < callPE->getOpVarNum(); ++i) { const ICFGNode* callSite = callPE->getOpCallICFGNode(i); NodeID actual = callPE->getOpVarID(i); if (postAbsTrace().count(callSite)) joined.join_with(postAbsTrace()[callSite][actual]); } as[formal] = joined; }
-
Retrieve the internal ID associated with a given virtual address.
For example,
// Assuming 'addr' is a valid virtual address (0x7f******) AbstractState& as = getAbsStateFromTrace(node); int internalID = as.getIDFromAddr(addr); std::cout << "Internal ID: " << internalID << std::endl;
Input:
addr(an address object starting with 0x7f****), e.g. 0x7f0005Output: Internal ID associated with
addr(remove the mask of 0x7f0000), e.g. 5 (0x7f0005 remove the mask)
-
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)
-
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
-
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
-
Get the byte size of a base object given its ID.
For example,
// Assuming 'id' is a valid object ID u32_t byteSize = svfir->getBaseObject(id)->getByteSizeOfObj(); std::cout << "Byte size of base object: " << byteSize << std::endl;
Input:
id(an object ID, either GepObj or BaseObj)Output: Unsigned integer representing the byte size of the base object
-
Retrieve the byte offset (has lower and upper bound) for a given GEP statement. Note: this method now lives on
AbstractInterpretation(accessed viasvfStateMgr->...in Assignment-3), not onAbstractState— the oldAEState::getByteOffset/AbstractStateManagerAPI was removed when the denseAbstractInterpretationwas folded in.For example,
// Assuming 'gep' is a valid GepStmt* IntervalValue byteOffset = svfStateMgr->getGepByteOffset(gep); std::cout << "Byte offset: " << byteOffset.toString() << std::endl;
Input:
gep(aGepStmt*)Output:
IntervalValuerepresenting the byte offset
-
Get the addresses of GEP objects given a
ValVar*pointer and an offset.For example,
// Assuming 'pointer' is a ValVar* and 'offset' is an IntervalValue AddressValue gepObjAddrs = svfStateMgr->getGepObjAddrs(pointer, offset); std::cout << "GEP object addresses: "; for (const auto& addr : gepObjAddrs) { std::cout << "0x" << std::hex << addr << ", "; } std::cout << std::endl;
Input:
pointer(aValVar*),offset(anIntervalValue)Output:
AddressValuecontaining the addresses of GEP objects
-
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.)
-
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
-
Simulates a memcpy operation against the abstract state held by the owning
AbstractInterpretation: copieslenbytes from the source variablesrcto the destination variabledst, starting at offsetstart_idx. The function automatically determines the element size (for arrays or pointers) and performs element-wise copying, updating the abstract state accordingly. Only objects present in the abstract state are copied. The currentAbstractStateis no longer passed in explicitly —handleMemcpyreads/writes it via the owningAbstractInterpretationusingextCallNode.For example
// dst is a ValVar*, whose underlying type can be Array or Pointer. // src is a ValVar*, whose underlying type can be Array or Pointer. // len is an IntervalValue; we copy the lower bound bytes. // start_idx is the starting position. // extCallNode is the CallICFGNode at which the external memcpy-like call occurs. // e.g. in source code, char dst[10] = {'a','a','a','a','a','a','a','a','a','a'}; // char src[5] = {'1', '2', '3', '4', '\0'}; // we call handleMemcpy(dst, src, [5, 5], 2, extCallNode); // AbstractState should be updated as `dst = {'a', 'a', '1', '2', '3', '4','\0', 'a','a','a'}` // in which dst[2] = '1', dst[3] = '2', dst[4] = '3', dst[5] = '4', dst[6] = '\0', and no change occurs in other indices. utils->handleMemcpy(SVFUtil::cast<ValVar>(dst), SVFUtil::cast<ValVar>(src), len, start_idx, extCallNode);
-
Computes the length of a null-terminated string starting at
strValueusing the abstract state associated withextCallNode.For example,
IntervalValue len = utils->getStrlen(SVFUtil::cast<ValVar>(extCallNode->getArgument(1)), extCallNode);Input:
strValue(aValVar*),extCallNode(the call ICFG node)Output:
IntervalValuerepresenting the string length
-
Print the abstract state at an ICFG node.
For example,
AbstractState& as = getAbsStateFromTrace(icfgNode); as.printAbstractState();
Input: None
Output: Prints the abstract state to the standard output, e.g.
-----------Var and Value-----------
Var4 Value: [5, 5]
Var2 Value: [5, 5]
Var1 Value: {0x7f000005}
0x7f000005 Value: [5, 5]
——————————————---------------------