AE Python APIs - SVF-tools/Software-Security-Analysis GitHub Wiki
Essential API Documentation for Labs and Assignments (Python Version)
Lab-Exercise-3
Lab-Exercise-3 still uses the dense AbstractState value object directly — loadValue / storeValue are local convenience wrappers around store / load. In Assignment-3 the same operations route through AbstractInterpretation (see below).
| API | Introduction |
|---|---|
getNodeID(variable: str) -> int |
Retrieves the node ID of the specified variable (helper defined in the lab's AEMgr). |
IntervalValue(lower: int, upper: int) |
Creates an interval value. |
AbstractValue.getInterval() -> IntervalValue |
Retrieves the interval value of the abstract value. |
AbstractValue.join_with(value: AbstractValue) |
Merges the current value with another value. |
getMemObjAddress(variable: str) -> AddressValue |
Retrieves the memory object address of the specified variable (helper). |
AddressValue(getMemObjAddress(variable: str)) |
Creates an address value initialized to the memory object address of the specified variable. |
AbstractState.widening(other: AbstractState) -> AbstractState |
Returns a new AbstractState that is the widening of self with other. |
AbstractState.narrowing(other: AbstractState) -> AbstractState |
Returns a new AbstractState that is the narrowing of self with other. |
AbstractState.joinWith(other: AbstractState) |
Joins (in place) the current state with another state. |
AbstractValue.meet_with(value: AbstractValue) |
Performs an intersection operation between the current value and another value. |
getGepObjAddress(variable: str, offset: int) -> AddressValue |
Retrieves the GEP (GetElementPtr) object address of the specified variable with the given offset (helper). |
AbstractState.store(addr: int, val: AbstractValue) |
Store an AbstractValue at virtual address addr. (Lab-Exercise-3's AEState.storeValue(varId, val) is a thin wrapper around this.) |
AbstractState.load(addr: int) -> AbstractValue |
Load the AbstractValue at virtual address addr. (Lab-Exercise-3's AEState.loadValue(varId) is a thin wrapper.) |
AbstractState.printAbstractState() |
Prints the abstract state for debugging purposes. |
Assignment-3
Note on naming: In Assignment-3's Python skeleton,
AbstractExecutionkeeps a reference to anAbstractInterpretationinstance under the field namesvf_state_mgr. The dense GEP / load / store helpers that used to live onAEStateare now methods onpysvf.AbstractInterpretation. The per-ICFGNodevalue object is still apysvf.AbstractState; you get one withgetAbsStateFromTrace(node).
| API | Introduction |
|---|---|
SVFUtil.isa(stmt.getICFGNode()) / stmt.getICFGNode().isCall() |
Check if the statement's containing ICFG node is a call. |
stmt.asGepStmt() |
Downcast SVFStmt to GepStmt (returns None if not a GepStmt). |
AbstractExecution.getAbsStateFromTrace(node: ICFGNode) -> AbstractState |
Retrieves the abstract state of the given ICFG node from the trace. |
GepStmt.getLHSVarID() -> int |
Retrieves the left-hand side variable ID of the GepStmt. |
GepStmt.getRHSVarID() -> int |
Retrieves the right-hand side variable ID of the GepStmt. |
as[var_id].getAddrs() -> AddressValue |
Retrieves the addresses stored at var_id in the abstract state. |
as.getIDFromAddr(addr: int) -> int |
Retrieves the internal object ID from a virtual address. |
svfir.getBaseObject(id: int).getByteSizeOfObj() -> int |
Retrieves the byte size of the base object. |
pysvf.Options.max_field_limit() -> int |
Retrieves the value of the max-field-limit option (Options.WidenDelay is C++-only — Python skeleton hard-codes the widening delay). |
AbstractExecution.handleICFGNode(node: ICFGNode) |
Handles a singleton WTO node (Weak Topological Order). |
AbstractExecution.handleICFGCycle(cycle: ICFGCycleWTO) |
Handles WTO cycles (a set of ICFGNodes). |
cycle.head.getICFGNode() |
Get the cycle head ICFGNode. |
AbstractExecution.mergeStatesFromPredecessors(node: ICFGNode) -> AbstractState |
Merges states from predecessor ICFG nodes. |
CopyStmt.getLHSVarID() -> int / .getRHSVarID() -> int |
LHS / RHS variable IDs of a copy statement. |
BinaryOPStmt.getOpVarId(index: int) -> int |
Retrieves the operand variable ID of the binary operation statement. |
BinaryOPStmt.getResId() -> int |
Retrieves the result variable ID of the binary operation statement. |
BinaryOPStmt.getOpcode() -> int |
Retrieves the opcode of the binary operation statement (compare with constants from pysvf.enums.OpCode). |
CallPE.getResId() -> int |
Retrieves the formal-parameter variable ID for a phi-like call parameter statement. |
CallPE.getOpVarNum() -> int |
Retrieves the number of actual-parameter operands in a phi-like CallPE. |
CallPE.getOpVarId(index: int) -> int |
Retrieves the actual-parameter variable ID at index. |
CallPE.getOpCallICFGNode(index: int) -> CallICFGNode |
Retrieves the call site corresponding to the actual-parameter operand at index. |
self.svf_state_mgr.loadValue(pointer: ValVar, node: ICFGNode) -> AbstractValue |
Loads the abstract value pointed to by pointer at node. Replaces the old AEState.loadValue(varId). |
self.svf_state_mgr.storeValue(pointer: ValVar, val: AbstractValue, node: ICFGNode) |
Stores val through pointer at node. Replaces the old AEState.storeValue(varId, val). |
LoadStmt.getRHSVarID() -> int / .getLHSVarID() -> int |
LHS / RHS variable IDs of a load statement. |
IntervalValue.getIntNumeral() -> int |
Returns the integer representation of the interval value. |
self.svf_state_mgr.getGepByteOffset(gep: GepStmt) -> IntervalValue |
Retrieves the byte offset of a GEP statement. Replaces AEState.getByteOffset(gep). |
self.svf_state_mgr.getGepElementIndex(gep: GepStmt) -> IntervalValue |
Retrieves the element index of a GEP statement. Replaces AEState.getElementIndex(gep). |
self.svf_state_mgr.getGepObjAddrs(pointer: ValVar, offset: IntervalValue) -> AddressValue |
Retrieves the addresses of GEP objects. Replaces AEState.getGepObjAddrs(varID, offset). |
AbstractExecutionHelper.reportBufOverflow(node: ICFGNode, msg: str) |
Reports a buffer overflow for a given ICFG node (Assignment-3 helper). |
AbstractExecutionHelper.updateGepObjOffsetFromBase(abstractState: AbstractState, gepAddrs: AddressValue, objAddrs: AddressValue, offset: IntervalValue) |
Updates the GEP object offset from the base. |
AbstractExecution.getAccessOffset(objId: int, gep: GepStmt) -> IntervalValue |
Returns the accessing offset of an object at a GepStmt. |
AbstractExecution.updateStateOnExtCall(extCallNode: CallICFGNode) |
Handles external calls, checking for buffer overflows, and updates abstract states using memcpy-like APIs via AbstractExecutionHelper.handleMemcpy. |
AbstractExecutionHelper.handleMemcpy(abstractState: AbstractState, dst: SVFVar, src: SVFVar, len: IntervalValue, start_idx: int) |
Simulates a memcpy operation in abstractState: copies len bytes from the source variable src to the destination variable dst, starting at offset start_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. |
AbstractExecutionHelper.getStrlen(abstractState: AbstractState, strValue: SVFVar) -> IntervalValue |
Returns the length of a null-terminated string starting at strValue in abstractState. |
AbstractExecutionHelper.addToGepObjOffsetFromBase(obj: GepObjVar, offset: IntervalValue) |
Adds an offset to the GEP object offset from the base object. |
AbstractExecutionHelper.hasGepObjOffsetFromBase(obj: GepObjVar) -> bool |
Checks if there is a GEP object offset from the base object. |
AbstractExecutionHelper.getGepObjOffsetFromBase(obj: GepObjVar) -> IntervalValue |
Retrieves the GEP object offset from the base object. |
AbstractState.printAbstractState() |
Prints the abstract state. |
AbstractState.clone() -> AbstractState |
Returns an independent copy. Use this before mutating a state kept in self.post_abs_trace. |
self.post_abs_trace is an alias of self.svf_state_mgr, not a plain Python dictionary. Indexing it returns a reference to a C++ AbstractState; save previous loop states with .clone() before calling code that mutates the trace.
CallPE.getResId / getOpVarId / getOpCallICFGNode
CallPE is phi-like in current pysvf: the result is the formal parameter, and each operand is one actual parameter from a specific call site.
def updateStateOnCall(self, call: pysvf.CallPE):
abstract_state = self.post_abs_trace[call.getICFGNode()]
formal = call.getResId()
result = AbstractValue()
for i in range(call.getOpVarNum()):
call_site = call.getOpCallICFGNode(i)
if call_site in self.post_abs_trace:
actual = call.getOpVarId(i)
result.join_with(self.post_abs_trace[call_site][actual])
abstract_state[formal] = result
AbstractExecutionHelper.handleMemcpy(abstractState: AbstractState, dst: SVFVar, src: SVFVar, len: IntervalValue, start_idx: int)
-
Simulates a memcpy operation in
abstractState: 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.For example
# abstract_state is an AbstractState # dst is a pysvf.SVFVar, whose type can be Array or Pointer. # src is a pysvf.SVFVar, whose type can be Array or Pointer. # len is an IntervalValue; we copy the lower bound bytes # start_idx is the starting position # 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(abstract_state, dst, src, IntervalValue(5, 5), 2); # 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. self.helper.handleMemcpy(abstract_state, dst, src, length, start_idx)