|
|
@ -13,20 +13,19 @@ log = logging.getLogger(__name__) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class TaintRecord: |
|
|
|
class TaintRecord: |
|
|
|
""" |
|
|
|
"""TaintRecord contains tainting information for a specific (state, node) |
|
|
|
TaintRecord contains tainting information for a specific (state, node) |
|
|
|
the information specifies the taint status before executing the operation |
|
|
|
the information specifies the taint status before executing the operation belonging to the state |
|
|
|
belonging to the state.""" |
|
|
|
""" |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def __init__(self): |
|
|
|
def __init__(self): |
|
|
|
""" Builds a taint record """ |
|
|
|
"""Builds a taint record.""" |
|
|
|
self.stack = [] |
|
|
|
self.stack = [] |
|
|
|
self.memory = {} |
|
|
|
self.memory = {} |
|
|
|
self.storage = {} |
|
|
|
self.storage = {} |
|
|
|
self.states = [] |
|
|
|
self.states = [] |
|
|
|
|
|
|
|
|
|
|
|
def stack_tainted(self, index: int) -> Union[bool, None]: |
|
|
|
def stack_tainted(self, index: int) -> Union[bool, None]: |
|
|
|
""" Returns taint value of stack element at index |
|
|
|
"""Returns taint value of stack element at index. |
|
|
|
|
|
|
|
|
|
|
|
:param index: |
|
|
|
:param index: |
|
|
|
:return: |
|
|
|
:return: |
|
|
@ -36,7 +35,7 @@ class TaintRecord: |
|
|
|
return None |
|
|
|
return None |
|
|
|
|
|
|
|
|
|
|
|
def memory_tainted(self, index: int) -> bool: |
|
|
|
def memory_tainted(self, index: int) -> bool: |
|
|
|
""" Returns taint value of memory element at index |
|
|
|
"""Returns taint value of memory element at index. |
|
|
|
|
|
|
|
|
|
|
|
:param index: |
|
|
|
:param index: |
|
|
|
:return: |
|
|
|
:return: |
|
|
@ -46,7 +45,7 @@ class TaintRecord: |
|
|
|
return False |
|
|
|
return False |
|
|
|
|
|
|
|
|
|
|
|
def storage_tainted(self, index: int) -> bool: |
|
|
|
def storage_tainted(self, index: int) -> bool: |
|
|
|
""" Returns taint value of storage element at index |
|
|
|
"""Returns taint value of storage element at index. |
|
|
|
|
|
|
|
|
|
|
|
:param index: |
|
|
|
:param index: |
|
|
|
:return: |
|
|
|
:return: |
|
|
@ -56,14 +55,14 @@ class TaintRecord: |
|
|
|
return False |
|
|
|
return False |
|
|
|
|
|
|
|
|
|
|
|
def add_state(self, state: GlobalState) -> None: |
|
|
|
def add_state(self, state: GlobalState) -> None: |
|
|
|
""" Adds state with this taint record |
|
|
|
"""Adds state with this taint record. |
|
|
|
|
|
|
|
|
|
|
|
:param state: |
|
|
|
:param state: |
|
|
|
""" |
|
|
|
""" |
|
|
|
self.states.append(state) |
|
|
|
self.states.append(state) |
|
|
|
|
|
|
|
|
|
|
|
def clone(self) -> "TaintRecord": |
|
|
|
def clone(self) -> "TaintRecord": |
|
|
|
""" Clones this record |
|
|
|
"""Clones this record. |
|
|
|
|
|
|
|
|
|
|
|
:return: |
|
|
|
:return: |
|
|
|
""" |
|
|
|
""" |
|
|
@ -75,14 +74,15 @@ class TaintRecord: |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class TaintResult: |
|
|
|
class TaintResult: |
|
|
|
""" Taint analysis result obtained after having ran the taint runner""" |
|
|
|
"""Taint analysis result obtained after having ran the taint runner.""" |
|
|
|
|
|
|
|
|
|
|
|
def __init__(self): |
|
|
|
def __init__(self): |
|
|
|
"""Create a new tains result.""" |
|
|
|
"""Create a new tains result.""" |
|
|
|
self.records = [] |
|
|
|
self.records = [] |
|
|
|
|
|
|
|
|
|
|
|
def check(self, state: GlobalState, stack_index: int) -> Union[bool, None]: |
|
|
|
def check(self, state: GlobalState, stack_index: int) -> Union[bool, None]: |
|
|
|
"""Checks if stack variable is tainted, before executing the instruction |
|
|
|
"""Checks if stack variable is tainted, before executing the |
|
|
|
|
|
|
|
instruction. |
|
|
|
|
|
|
|
|
|
|
|
:param state: state to check variable in |
|
|
|
:param state: state to check variable in |
|
|
|
:param stack_index: index of stack variable |
|
|
|
:param stack_index: index of stack variable |
|
|
@ -94,14 +94,14 @@ class TaintResult: |
|
|
|
return record.stack_tainted(stack_index) |
|
|
|
return record.stack_tainted(stack_index) |
|
|
|
|
|
|
|
|
|
|
|
def add_records(self, records: List[TaintRecord]) -> None: |
|
|
|
def add_records(self, records: List[TaintRecord]) -> None: |
|
|
|
""" Adds records to this taint result |
|
|
|
"""Adds records to this taint result. |
|
|
|
|
|
|
|
|
|
|
|
:param records: |
|
|
|
:param records: |
|
|
|
""" |
|
|
|
""" |
|
|
|
self.records += records |
|
|
|
self.records += records |
|
|
|
|
|
|
|
|
|
|
|
def _try_get_record(self, state: GlobalState) -> Union[TaintRecord, None]: |
|
|
|
def _try_get_record(self, state: GlobalState) -> Union[TaintRecord, None]: |
|
|
|
""" Finds record belonging to the state |
|
|
|
"""Finds record belonging to the state. |
|
|
|
|
|
|
|
|
|
|
|
:param state: |
|
|
|
:param state: |
|
|
|
:return: |
|
|
|
:return: |
|
|
@ -113,16 +113,15 @@ class TaintResult: |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class TaintRunner: |
|
|
|
class TaintRunner: |
|
|
|
""" |
|
|
|
"""Taint runner, is able to run taint analysis on symbolic execution |
|
|
|
Taint runner, is able to run taint analysis on symbolic execution result |
|
|
|
result.""" |
|
|
|
""" |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@staticmethod |
|
|
|
@staticmethod |
|
|
|
def execute( |
|
|
|
def execute( |
|
|
|
statespace: SymExecWrapper, node: Node, state: GlobalState, initial_stack=None |
|
|
|
statespace: SymExecWrapper, node: Node, state: GlobalState, initial_stack=None |
|
|
|
) -> TaintResult: |
|
|
|
) -> TaintResult: |
|
|
|
""" |
|
|
|
"""Runs taint analysis on the statespace. |
|
|
|
Runs taint analysis on the statespace |
|
|
|
|
|
|
|
:param initial_stack: |
|
|
|
:param initial_stack: |
|
|
|
:param statespace: symbolic statespace to run taint analysis on |
|
|
|
:param statespace: symbolic statespace to run taint analysis on |
|
|
|
:param node: taint introduction node |
|
|
|
:param node: taint introduction node |
|
|
@ -196,8 +195,8 @@ class TaintRunner: |
|
|
|
def execute_node( |
|
|
|
def execute_node( |
|
|
|
node: Node, last_record: TaintRecord, state_index=0 |
|
|
|
node: Node, last_record: TaintRecord, state_index=0 |
|
|
|
) -> List[TaintRecord]: |
|
|
|
) -> List[TaintRecord]: |
|
|
|
""" |
|
|
|
"""Runs taint analysis on a given node. |
|
|
|
Runs taint analysis on a given node |
|
|
|
|
|
|
|
:param node: node to analyse |
|
|
|
:param node: node to analyse |
|
|
|
:param last_record: last taint record to work from |
|
|
|
:param last_record: last taint record to work from |
|
|
|
:param state_index: state index to start from |
|
|
|
:param state_index: state index to start from |
|
|
|