From 5cbc3b09fb0640a58583100e7a456c1da0a3fe8c Mon Sep 17 00:00:00 2001 From: Kevin Phoenix Date: Tue, 7 Feb 2023 14:34:29 -0700 Subject: [PATCH] Fix low-hanging lint issues (#3777) * Fix low-hanging lint issues * Fix some test failures * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Fix doc warnings * Fix test_pickle.py * Fix code-block doc warning * Try indenting code block --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- angr/__init__.py | 1 - angr/analyses/__init__.py | 1 - angr/analyses/analysis.py | 1 - angr/analyses/cfg/cfb.py | 1 - angr/analyses/cfg/cfg_base.py | 4 +- angr/analyses/cfg/cfg_emulated.py | 26 +- angr/analyses/cfg/cfg_fast.py | 2 +- angr/analyses/cfg/cfg_fast_soot.py | 9 +- angr/analyses/cfg/cfg_job_base.py | 10 +- .../cfg/indirect_jump_resolvers/jumptable.py | 2 +- .../indirect_jump_resolvers/mips_elf_fast.py | 8 +- angr/analyses/cfg_slice_to_sink/graph.py | 4 +- angr/analyses/code_tagging.py | 2 +- angr/analyses/congruency_check.py | 7 +- angr/analyses/datagraph_meta.py | 6 +- angr/analyses/ddg.py | 8 +- angr/analyses/decompiler/callsite_maker.py | 2 +- angr/analyses/decompiler/clinic.py | 2 +- angr/analyses/decompiler/decompiler.py | 7 +- .../optimization_passes/div_simplifier.py | 3 +- .../a_shl_const_sub_a.py | 2 +- .../conv_const_mull_a_shift.py | 2 - angr/analyses/decompiler/region_identifier.py | 12 +- angr/analyses/decompiler/structuring/dream.py | 12 +- .../decompiler/structuring/phoenix.py | 11 +- angr/analyses/identifier/functions/strcmp.py | 3 +- angr/analyses/identifier/functions/strncmp.py | 3 +- angr/analyses/identifier/identify.py | 3 +- angr/analyses/identifier/runner.py | 2 - angr/analyses/loop_analysis.py | 42 +-- angr/analyses/propagator/engine_ail.py | 6 +- .../analyses/reaching_definitions/__init__.py | 2 +- .../reaching_definitions/dep_graph.py | 4 +- .../reaching_definitions/engine_ail.py | 11 +- .../reaching_definitions.py | 2 +- angr/analyses/variable_recovery/engine_ail.py | 7 +- .../variable_recovery/variable_recovery.py | 1 - angr/analyses/veritesting.py | 12 +- angr/analyses/vfg.py | 14 +- angr/angrdb/serializers/cfg_model.py | 2 +- angr/angrdb/serializers/comments.py | 3 +- angr/angrdb/serializers/labels.py | 3 +- angr/angrdb/serializers/xrefs.py | 4 +- angr/annocfg.py | 2 +- angr/blade.py | 2 +- angr/distributed/server.py | 1 - angr/distributed/worker.py | 1 - angr/engines/concrete.py | 4 +- angr/engines/hook.py | 5 +- angr/engines/soot/engine.py | 2 +- angr/engines/soot/expressions/newArray.py | 2 +- .../engines/soot/expressions/newMultiArray.py | 2 +- angr/engines/soot/field_dispatcher.py | 2 +- angr/engines/soot/statements/switch.py | 2 - angr/engines/soot/values/arrayref.py | 2 +- angr/engines/syscall.py | 4 +- angr/engines/vex/claripy/ccall.py | 33 +-- angr/engines/vex/claripy/irop.py | 3 +- angr/engines/vex/heavy/inspect.py | 3 +- angr/exploration_techniques/__init__.py | 1 - angr/exploration_techniques/cacher.py | 141 ---------- angr/exploration_techniques/common.py | 5 +- angr/exploration_techniques/director.py | 4 +- angr/exploration_techniques/explorer.py | 4 +- angr/exploration_techniques/loop_seer.py | 3 +- angr/exploration_techniques/oppologist.py | 4 - angr/exploration_techniques/spiller_db.py | 4 + angr/factory.py | 6 +- angr/knowledge_plugins/cfg/cfg_node.py | 2 +- angr/knowledge_plugins/functions/function.py | 12 +- .../key_definitions/atoms.py | 2 +- .../key_definitions/live_definitions.py | 2 +- .../knowledge_plugins/sync/sync_controller.py | 3 +- angr/knowledge_plugins/types.py | 2 +- .../variables/variable_manager.py | 2 - angr/knowledge_plugins/xrefs/xref_manager.py | 10 +- angr/misc/hookset.py | 7 +- angr/misc/plugins.py | 6 +- angr/procedures/cgc/random.py | 1 - angr/procedures/java_jni/array_operations.py | 7 +- angr/procedures/java_util/collection.py | 3 +- angr/procedures/java_util/iterator.py | 3 +- angr/procedures/java_util/list.py | 4 +- angr/procedures/libc/strncmp.py | 1 - angr/procedures/linux_kernel/fstat.py | 18 +- angr/procedures/linux_kernel/fstat64.py | 26 +- angr/procedures/linux_kernel/stat.py | 3 +- angr/procedures/linux_loader/sim_loader.py | 1 - angr/procedures/posix/dup.py | 3 - angr/procedures/posix/fdopen.py | 2 +- angr/procedures/posix/readdir.py | 7 +- angr/procedures/posix/strtok_r.py | 3 +- angr/procedures/stubs/b64_decode.py | 35 --- angr/procedures/stubs/crazy_scanf.py | 6 - angr/procedures/stubs/format_parser.py | 3 +- angr/project.py | 3 +- angr/sim_manager.py | 5 +- angr/sim_options.py | 6 +- angr/sim_state.py | 1 - angr/sim_type.py | 4 +- angr/simos/javavm.py | 3 - angr/simos/linux.py | 2 +- angr/simos/userland.py | 6 +- angr/simos/windows.py | 10 +- angr/state_plugins/filesystem.py | 255 ------------------ angr/state_plugins/heap/heap_libc.py | 4 +- angr/state_plugins/history.py | 32 --- angr/state_plugins/inspect.py | 5 +- angr/state_plugins/plugin.py | 26 +- angr/state_plugins/preconstrainer.py | 3 +- angr/state_plugins/sim_action.py | 6 - angr/state_plugins/symbolizer.py | 2 +- angr/storage/file.py | 21 +- .../paged_memory/pages/cooperation.py | 2 +- .../paged_memory/stack_allocation_mixin.py | 6 +- angr/storage/memory_mixins/slotted_memory.py | 4 +- angr/type_backend.py | 154 ----------- angr/utils/timing.py | 6 +- pyproject.toml | 32 ++- setup.py | 5 +- .../reaching_definitions/test_dep_graph.py | 6 +- tests/broken_variableseekr.py | 205 -------------- tests/common.py | 3 +- .../key_definitions/test_environment.py | 1 - .../key_definitions/test_live_definitions.py | 1 - tests/test_cfg_manager.py | 2 +- tests/test_cfgemulated.py | 24 +- tests/test_ctype_locale.py | 17 +- tests/test_decompiler.py | 8 +- tests/test_driller_core.py | 1 - tests/test_function_manager.py | 4 +- tests/test_hook.py | 4 +- tests/test_inspect.py | 1 - tests/test_java.py | 2 +- tests/test_jumptables.py | 8 +- tests/test_keystone.py | 2 - tests/test_lseek.py | 6 +- tests/test_ops.py | 1 - tests/test_pickle.py | 33 +-- tests/test_proximitygraph.py | 4 +- tests/test_scanf.py | 2 +- tests/test_serialization.py | 2 +- tests/test_sim_procedure.py | 1 - tests/test_spiller.py | 6 +- tests/test_state.py | 6 +- tests/test_string.py | 16 +- tests/test_structurer.py | 4 +- tests/test_syscall_result.py | 3 - tests/test_tracer.py | 2 +- tests/test_types.py | 31 +-- tests/test_unicorn.py | 18 +- tests/test_variablerecovery.py | 1 - tests/test_vault.py | 3 +- tests/test_veritesting.py | 1 - tests/test_xrefs.py | 2 +- 155 files changed, 456 insertions(+), 1263 deletions(-) delete mode 100644 angr/exploration_techniques/cacher.py delete mode 100644 angr/type_backend.py delete mode 100644 tests/broken_variableseekr.py diff --git a/angr/__init__.py b/angr/__init__.py index 013c25ccd36..2ff99d7b141 100644 --- a/angr/__init__.py +++ b/angr/__init__.py @@ -68,7 +68,6 @@ from . import knowledge_plugins from . import exploration_techniques from .exploration_techniques import ExplorationTechnique -from . import type_backend from . import sim_type as types from .state_hierarchy import StateHierarchy diff --git a/angr/analyses/__init__.py b/angr/analyses/__init__.py index 74072176157..f3a5cdc7a61 100644 --- a/angr/analyses/__init__.py +++ b/angr/analyses/__init__.py @@ -12,7 +12,6 @@ def register_analysis(cls, name): from .vfg import VFG from .boyscout import BoyScout -# from .girlscout import GirlScout from .backward_slice import BackwardSlice from .veritesting import Veritesting from .vsa_ddg import VSA_DDG diff --git a/angr/analyses/analysis.py b/angr/analyses/analysis.py index a7bf02b06a1..621c2779750 100644 --- a/angr/analyses/analysis.py +++ b/angr/analyses/analysis.py @@ -14,7 +14,6 @@ if TYPE_CHECKING: from ..knowledge_base import KnowledgeBase - import angr from ..project import Project from typing_extensions import ParamSpec diff --git a/angr/analyses/cfg/cfb.py b/angr/analyses/cfg/cfb.py index d7352ec6902..27709cad7a6 100644 --- a/angr/analyses/cfg/cfb.py +++ b/angr/analyses/cfg/cfb.py @@ -1,5 +1,4 @@ import logging -import cffi import cle from cle.backends.externs import KernelObject, ExternObject diff --git a/angr/analyses/cfg/cfg_base.py b/angr/analyses/cfg/cfg_base.py index e2218d1c53b..035e69021e7 100644 --- a/angr/analyses/cfg/cfg_base.py +++ b/angr/analyses/cfg/cfg_base.py @@ -2208,7 +2208,7 @@ def _graph_traversal_handler(self, g, src, dst, data, blockaddr_to_function, kno else: self._addr_to_function(returning_target, blockaddr_to_function, known_functions) - to_outside = not blockaddr_to_function[returning_target] is src_function + to_outside = blockaddr_to_function[returning_target] is not src_function n = self.model.get_any_node(returning_target) if n is None: @@ -2346,7 +2346,7 @@ def _graph_traversal_handler(self, g, src, dst, data, blockaddr_to_function, kno if called_function is not None and called_function.returning is False: return - to_outside = not target_function is src_function + to_outside = target_function is not src_function confirmed = called_function is None or called_function.returning is True self.kb.functions._add_fakeret_to( diff --git a/angr/analyses/cfg/cfg_emulated.py b/angr/analyses/cfg/cfg_emulated.py index 4ceb63068a2..8b38005cc12 100644 --- a/angr/analyses/cfg/cfg_emulated.py +++ b/angr/analyses/cfg/cfg_emulated.py @@ -200,12 +200,16 @@ def __init__( jumpkind, or a SimState instance. Unsupported entries in starts will lead to an AngrCFGError being raised. :param keep_state: Whether to keep the SimStates for each CFGNode. - :param resolve_indirect_jumps: Whether to enable the indirect jump resolvers for resolving indirect jumps - :param enable_advanced_backward_slicing: Whether to enable an intensive technique for resolving indirect jumps - :param enable_symbolic_back_traversal: Whether to enable an intensive technique for resolving indirect jumps - :param list indirect_jump_resolvers: A custom list of indirect jump resolvers. If this list is None or empty, - default indirect jump resolvers specific to this architecture and binary - types will be loaded. + :param resolve_indirect_jumps: Whether to enable the indirect jump resolvers for resolving indirect + jumps + :param enable_advanced_backward_slicing: Whether to enable an intensive technique for resolving indirect + jumps + :param enable_symbolic_back_traversal: Whether to enable an intensive technique for resolving indirect + jumps + :param list indirect_jump_resolvers: A custom list of indirect jump resolvers. If this list is None or + empty, + default indirect jump resolvers specific to this architecture and + binary types will be loaded. :param additional_edges: A dict mapping addresses of basic blocks to addresses of successors to manually include and analyze forward from. :param bool no_construct: Skip the construction procedure. Only used in unit-testing. @@ -1242,7 +1246,7 @@ def _pre_job_handling(self, job): # pylint:disable=arguments-differ the_jobs = [] if block_id in self._pending_jobs: - the_jobs: "Pendingjob" = self._pending_jobs.pop(block_id) + the_jobs: "PendingJob" = self._pending_jobs.pop(block_id) for the_job in the_jobs: self._deregister_analysis_job(the_job.caller_func_addr, the_job) else: @@ -2373,8 +2377,8 @@ def _try_resolving_indirect_jumps(self, sim_successors, cfg_node, func_addr, suc else: concrete_target = legit_successor.solver.eval(legit_successor.ip) if ( - not self.project.loader.find_object_containing(concrete_target) - is self.project.loader.main_object + self.project.loader.find_object_containing(concrete_target) + is not self.project.loader.main_object ): should_resolve = False @@ -2846,7 +2850,7 @@ def _search_for_function_hints(self, successor_state): # Now let's live with this big hack... try: const = successor_state.solver.eval_one(data.ast) - except: # pylint: disable=bare-except + except Exception: continue if self._is_address_executable(const): @@ -3111,7 +3115,7 @@ def _create_new_call_stack(self, addr, all_jobs, job, exit_target, jumpkind): # although the jumpkind is not Ijk_Call, it may still jump to a new function... let's see if self.project.is_hooked(exit_target): hooker = self.project.hooked_by(exit_target) - if not hooker is procedures.stubs.UserHook.UserHook: + if hooker is not procedures.stubs.UserHook.UserHook: # if it's not a UserHook, it must be a function # Update the function address of the most recent call stack frame new_call_stack = job.call_stack_copy() diff --git a/angr/analyses/cfg/cfg_fast.py b/angr/analyses/cfg/cfg_fast.py index 68c557a60cb..1c48730bb80 100644 --- a/angr/analyses/cfg/cfg_fast.py +++ b/angr/analyses/cfg/cfg_fast.py @@ -2337,7 +2337,7 @@ def _create_job_call( else: callee_function = self.kb.functions.function(addr=new_function_addr, syscall=is_syscall) if callee_function is not None: - callee_might_return = not (callee_function.returning is False) + callee_might_return = callee_function.returning is not False if callee_might_return: func_edges = [] diff --git a/angr/analyses/cfg/cfg_fast_soot.py b/angr/analyses/cfg/cfg_fast_soot.py index 5e199d30803..903dfceff71 100644 --- a/angr/analyses/cfg/cfg_fast_soot.py +++ b/angr/analyses/cfg/cfg_fast_soot.py @@ -21,13 +21,9 @@ from pysoot.sootir.soot_value import SootLocal from pysoot.sootir.soot_statement import IfStmt, InvokeStmt, GotoStmt, AssignStmt from pysoot.sootir.soot_expr import ( - SootInterfaceInvokeExpr, - SootSpecialInvokeExpr, SootStaticInvokeExpr, - SootVirtualInvokeExpr, SootInvokeExpr, - SootDynamicInvokeExpr, - ) # pylint:disable=unused-import + ) PYSOOT_INSTALLED = True except ImportError: @@ -438,7 +434,8 @@ def _scan_soot_block(self, cfg_job, current_func_addr): # Mark the address as traced self._traced_addresses.add(addr) - # soot_block is only used once per CFGNode. We should be able to clean up the CFGNode here in order to save memory + # soot_block is only used once per CFGNode. We should be able to clean up the CFGNode here in order to save + # memory cfg_node.soot_block = None successors = self._soot_get_successors(addr, current_func_addr, soot_block, cfg_node) diff --git a/angr/analyses/cfg/cfg_job_base.py b/angr/analyses/cfg/cfg_job_base.py index e1e86c110e2..f1dacb84f8c 100644 --- a/angr/analyses/cfg/cfg_job_base.py +++ b/angr/analyses/cfg/cfg_job_base.py @@ -27,7 +27,10 @@ def callsite_repr(self): return "None" s = [] - format_addr = lambda addr: "None" if addr is None else hex(addr) + + def format_addr(addr): + return "None" if addr is None else hex(addr) + for i in range(0, len(self.callsite_tuples), 2): s.append("@".join(map(format_addr, self.callsite_tuples[i : i + 2]))) return " -> ".join(s) @@ -84,7 +87,10 @@ def callsite_repr(self): return "None" s = [] - format_addr = lambda addr: "None" if addr is None else hex(addr) + + def format_addr(addr): + return "None" if addr is None else hex(addr) + for i in range(0, len(self.callsite_tuples), 2): s.append("@".join(map(format_addr, self.callsite_tuples[i : i + 2]))) return " -> ".join(s) diff --git a/angr/analyses/cfg/indirect_jump_resolvers/jumptable.py b/angr/analyses/cfg/indirect_jump_resolvers/jumptable.py index e78d97b3674..62788d6c0d3 100644 --- a/angr/analyses/cfg/indirect_jump_resolvers/jumptable.py +++ b/angr/analyses/cfg/indirect_jump_resolvers/jumptable.py @@ -1976,7 +1976,7 @@ def _initial_state(self, block_addr, cfg, func_addr: int): # FIXME: # this is a hack: for certain architectures, we do not initialize the base pointer, since the jump table on # those architectures may use the bp register to store value - if not self.project.arch.name in {"S390X"}: + if self.project.arch.name not in {"S390X"}: state.regs.bp = state.arch.initial_sp + 0x2000 return state diff --git a/angr/analyses/cfg/indirect_jump_resolvers/mips_elf_fast.py b/angr/analyses/cfg/indirect_jump_resolvers/mips_elf_fast.py index c3b9b5f8e98..77d551960f3 100644 --- a/angr/analyses/cfg/indirect_jump_resolvers/mips_elf_fast.py +++ b/angr/analyses/cfg/indirect_jump_resolvers/mips_elf_fast.py @@ -461,9 +461,11 @@ def _set_gp_load_callback(state, blade, project, gp_offset, gp_value): state.inspect.make_breakpoint( "tmp_write", when=BP_BEFORE, - condition=lambda s, bbl_addr_=block_addr_in_slice, tmp_offset_=tmp_offset: s.scratch.bbl_addr - == bbl_addr_ - and s.inspect.tmp_write_num == tmp_offset_, + condition=( + lambda s, bbl_addr_=block_addr_in_slice, tmp_offset_=tmp_offset: s.scratch.bbl_addr + == bbl_addr_ + and s.inspect.tmp_write_num == tmp_offset_ + ), action=OverwriteTmpValueCallback(gp_value).overwrite_tmp_value, ) break diff --git a/angr/analyses/cfg_slice_to_sink/graph.py b/angr/analyses/cfg_slice_to_sink/graph.py index 841eca6e2c2..69457908f47 100644 --- a/angr/analyses/cfg_slice_to_sink/graph.py +++ b/angr/analyses/cfg_slice_to_sink/graph.py @@ -1,7 +1,7 @@ def slice_callgraph(callgraph, cfg_slice_to_sink): """ - Slice a callgraph, keeping only the nodes present in the representation, and th transitions for which - a path exists. + Slice a callgraph, keeping only the nodes present in the representation, and th transitions for + which a path exists. *Note* that this function mutates the graph passed as an argument. diff --git a/angr/analyses/code_tagging.py b/angr/analyses/code_tagging.py index 2d154766781..6e973da0f1b 100644 --- a/angr/analyses/code_tagging.py +++ b/angr/analyses/code_tagging.py @@ -27,7 +27,7 @@ def __init__(self, func): def analyze(self): for analysis, arches in self.ANALYSES: - if not arches is None and self.project.arch.name not in arches: + if arches is not None and self.project.arch.name not in arches: continue tags = analysis() if tags: diff --git a/angr/analyses/congruency_check.py b/angr/analyses/congruency_check.py index e051348dd93..704e693460f 100644 --- a/angr/analyses/congruency_check.py +++ b/angr/analyses/congruency_check.py @@ -10,7 +10,8 @@ class CongruencyCheck(Analysis): """ - This is an analysis to ensure that angr executes things identically with different execution backends (i.e., unicorn vs vex). + This is an analysis to ensure that angr executes things identically with different execution backends (i.e., unicorn + vs vex). """ def __init__(self, throw=False): @@ -346,8 +347,8 @@ def compare_states(self, sl, sr): # make sure the flags are the same if sl.arch.name in ("AMD64", "X86", "ARM", "ARMEL", "ARMHF", "AARCH64"): # pylint: disable=unused-variable - n_bkp = sr.regs.cc_op, sr.regs.cc_dep1, sr.regs.cc_dep2, sr.regs.cc_ndep - u_bkp = sl.regs.cc_op, sl.regs.cc_dep1, sl.regs.cc_dep2, sl.regs.cc_ndep + sr.regs.cc_op, sr.regs.cc_dep1, sr.regs.cc_dep2, sr.regs.cc_ndep # n_bkp + sl.regs.cc_op, sl.regs.cc_dep1, sl.regs.cc_dep2, sl.regs.cc_ndep # u_bkp if sl.arch.name in ("AMD64", "X86"): n_flags = sr.regs.eflags.canonicalize(var_map=n_map, counter=n_counter)[-1] u_flags = sl.regs.eflags.canonicalize(var_map=u_map, counter=u_counter)[-1] diff --git a/angr/analyses/datagraph_meta.py b/angr/analyses/datagraph_meta.py index 73d20d3c64b..2e463078cb3 100644 --- a/angr/analyses/datagraph_meta.py +++ b/angr/analyses/datagraph_meta.py @@ -5,6 +5,10 @@ l = logging.getLogger(name=__name__) +class DataGraphError(Exception): + pass + + class DataGraphMeta: def __init__(self): self._p = None @@ -71,7 +75,7 @@ def _branch(self, live_defs, node, path=""): l.debug("--> Branch: running block 0x%x" % irsb.addr) block = self._make_block(irsb, live_defs) self._imarks.update(block._imarks) - if block.stop == True: + if block.stop is True: # l.debug(" ### Stopping at block 0x%x" % (irsb.addr)) l.debug(" ### End of path %s" % path) return irsb.addr diff --git a/angr/analyses/ddg.py b/angr/analyses/ddg.py index 1734d65cf60..35453f703ee 100644 --- a/angr/analyses/ddg.py +++ b/angr/analyses/ddg.py @@ -34,7 +34,8 @@ def __eq__(self, other): return type(other) is AST and other.op == self.op and other.operands == self.operands def __repr__(self): - _short_repr = lambda a: a.short_repr + def _short_repr(a): + return a.short_repr if len(self.operands) == 1: return f"{self.op}{_short_repr(self.operands[0])}" @@ -479,7 +480,8 @@ class DDG(Analysis): def __init__(self, cfg, start=None, call_depth=None, block_addrs=None): """ :param cfg: Control flow graph. Please make sure each node has an associated `state` with it, e.g. by - passing the keep_state=True and state_add_options=angr.options.refs arguments to CFGEmulated. + passing the keep_state=True and state_add_options=angr.options.refs arguments to + CFGEmulated. :param start: An address, Specifies where we start the generation of this data dependence graph. :param call_depth: None or integers. A non-negative integer specifies how deep we would like to track in the call tree. None disables call_depth limit. @@ -1510,7 +1512,7 @@ def _build_function_dependency_graphs(self): if dst.block_addr in block_addr_to_func: dst_target_func = block_addr_to_func[dst.block_addr] - if not dst_target_func is src_target_func: + if dst_target_func is not src_target_func: self._function_data_dependencies[dst_target_func].add_edge(src, dst, **data) # diff --git a/angr/analyses/decompiler/callsite_maker.py b/angr/analyses/decompiler/callsite_maker.py index 37d6022a123..8a7b93522f6 100644 --- a/angr/analyses/decompiler/callsite_maker.py +++ b/angr/analyses/decompiler/callsite_maker.py @@ -45,7 +45,7 @@ def _analyze(self): last_stmt = self.block.statements[-1] - if not type(last_stmt) is Stmt.Call: + if type(last_stmt) is not Stmt.Call: self.result_block = self.block return diff --git a/angr/analyses/decompiler/clinic.py b/angr/analyses/decompiler/clinic.py index 73581ccffed..ca7e21a3ebb 100644 --- a/angr/analyses/decompiler/clinic.py +++ b/angr/analyses/decompiler/clinic.py @@ -488,7 +488,7 @@ def _convert(self, block_node): :rtype: ailment.Block """ - if not type(block_node) is BlockNode: + if type(block_node) is not BlockNode: return block_node block = self.project.factory.block(block_node.addr, block_node.size) diff --git a/angr/analyses/decompiler/decompiler.py b/angr/analyses/decompiler/decompiler.py index 0176d072970..addd3683fee 100644 --- a/angr/analyses/decompiler/decompiler.py +++ b/angr/analyses/decompiler/decompiler.py @@ -1,7 +1,7 @@ # pylint:disable=unused-import import logging from collections import defaultdict -from typing import List, Tuple, Optional, Iterable, Union, Type, Set, Dict, Any +from typing import List, Tuple, Optional, Iterable, Union, Type, Set, Dict, Any, TYPE_CHECKING from cle import SymbolType import ailment @@ -19,6 +19,8 @@ from .decompilation_options import DecompilationOption from .decompilation_cache import DecompilationCache +if TYPE_CHECKING: + from .peephole_optimizations.base import PeepholeOptimizationStmtBase, PeepholeOptimizationExprBase l = logging.getLogger(name=__name__) @@ -135,7 +137,8 @@ def _decompile(self): cache.binop_operators = binop_operators # convert function blocks to AIL blocks - progress_callback = lambda p, **kwargs: self._update_progress(p * (70 - 5) / 100.0 + 5, **kwargs) + def progress_callback(p, **kwargs): + return self._update_progress(p * (70 - 5) / 100.0 + 5, **kwargs) if self._regen_clinic or old_clinic is None or self.func.prototype is None: clinic = self.project.analyses.Clinic( diff --git a/angr/analyses/decompiler/optimization_passes/div_simplifier.py b/angr/analyses/decompiler/optimization_passes/div_simplifier.py index 03599749501..8d245847c30 100644 --- a/angr/analyses/decompiler/optimization_passes/div_simplifier.py +++ b/angr/analyses/decompiler/optimization_passes/div_simplifier.py @@ -291,7 +291,8 @@ def _ail_handle_Add(self, expr): return super()._ail_handle_Add(expr) def _match_signed_division_add_operands(self, op0, op1): - # From: Add((Conv(64->32, ((Load(addr=stack_base+4, size=4, endness=Iend_LE) Mulls 0x55555556<32>) >> 0x20<8>)) >> 0x1f<8>), + # From: Add((Conv(64->32, ((Load(addr=stack_base+4, size=4, endness=Iend_LE) Mulls 0x55555556<32>) + # >> 0x20<8>)) >> 0x1f<8>), # Conv(64->32, ((Load(addr=stack_base+4, size=4, endness=Iend_LE) Mulls 0x55555556<32>) >> 0x20<8>))) # To: Load(addr=stack_base+4, size=4, endness=Iend_LE) /s 3 diff --git a/angr/analyses/decompiler/peephole_optimizations/a_shl_const_sub_a.py b/angr/analyses/decompiler/peephole_optimizations/a_shl_const_sub_a.py index a0fd87062cf..2a1d0a0f74d 100644 --- a/angr/analyses/decompiler/peephole_optimizations/a_shl_const_sub_a.py +++ b/angr/analyses/decompiler/peephole_optimizations/a_shl_const_sub_a.py @@ -1,4 +1,4 @@ -from ailment.expression import Convert, BinaryOp, Const +from ailment.expression import BinaryOp, Const from .base import PeepholeOptimizationExprBase diff --git a/angr/analyses/decompiler/peephole_optimizations/conv_const_mull_a_shift.py b/angr/analyses/decompiler/peephole_optimizations/conv_const_mull_a_shift.py index 959a870f9e5..fe671365ceb 100644 --- a/angr/analyses/decompiler/peephole_optimizations/conv_const_mull_a_shift.py +++ b/angr/analyses/decompiler/peephole_optimizations/conv_const_mull_a_shift.py @@ -1,5 +1,3 @@ -import math - from ailment.expression import Convert, BinaryOp, Const from .base import PeepholeOptimizationExprBase diff --git a/angr/analyses/decompiler/region_identifier.py b/angr/analyses/decompiler/region_identifier.py index 54c0bfd1e69..5bdfab1582b 100644 --- a/angr/analyses/decompiler/region_identifier.py +++ b/angr/analyses/decompiler/region_identifier.py @@ -940,8 +940,8 @@ def _region_out_edges(graph, region, data=False): return out_edges def _remove_node(self, graph: networkx.DiGraph, node): # pylint:disable=no-self-use - in_edges = [(src, dst, data) for (src, dst, data) in graph.in_edges(node, data=True) if not src is node] - out_edges = [(src, dst, data) for (src, dst, data) in graph.out_edges(node, data=True) if not dst is node] + in_edges = [(src, dst, data) for (src, dst, data) in graph.in_edges(node, data=True) if src is not node] + out_edges = [(src, dst, data) for (src, dst, data) in graph.out_edges(node, data=True) if dst is not node] if len(in_edges) <= 1 and len(out_edges) <= 1: # it forms a region by itself :-) @@ -988,8 +988,8 @@ def _merge_nodes( dst = new_node graph.add_edge(new_node, dst, **data) - assert not node_a in graph - assert not node_b in graph + assert node_a not in graph + assert node_b not in graph def _absorb_node( self, graph: networkx.DiGraph, node_mommy, node_kiddie, force_multinode=False @@ -1028,8 +1028,8 @@ def _absorb_node( dst = new_node graph.add_edge(new_node, dst, **data) - assert not node_mommy in graph - assert not node_kiddie in graph + assert node_mommy not in graph + assert node_kiddie not in graph def _ensure_jump_at_loop_exit_ends(self, node: Union[Block, MultiNode]) -> None: if isinstance(node, Block): diff --git a/angr/analyses/decompiler/structuring/dream.py b/angr/analyses/decompiler/structuring/dream.py index 1a45d800da1..dd9001dee7e 100644 --- a/angr/analyses/decompiler/structuring/dream.py +++ b/angr/analyses/decompiler/structuring/dream.py @@ -447,7 +447,7 @@ def _merge_same_conditioned_nodes(self, seq): i = 0 while i < len(seq.nodes) - 1: node_0 = seq.nodes[i] - if not type(node_0) is CodeNode: + if type(node_0) is not CodeNode: i += 1 continue rcond_0 = node_0.reaching_condition @@ -455,7 +455,7 @@ def _merge_same_conditioned_nodes(self, seq): i += 1 continue node_1 = seq.nodes[i + 1] - if not type(node_1) is CodeNode: + if type(node_1) is not CodeNode: i += 1 continue rcond_1 = node_1.reaching_condition @@ -522,7 +522,9 @@ def _make_switch_cases_address_loaded_from_memory( { Goto A<64> } else { Goto B<64> } A: (with an indirect jump) - Goto((Conv(32->64, Load(addr=(0x40964c<64> + (Load(addr=stack_base-80, size=8, endness=Iend_LE) Mul 0x4<8>)), size=4, endness=Iend_LE)) + 0x40964c<64>)) + Goto(( + Conv(32->64, Load(addr=(0x40964c<64> + (Load(addr=stack_base-80, size=8, endness=Iend_LE) Mul 0x4<8>)), + size=4, endness=Iend_LE)) + 0x40964c<64>)) B: (the default case) """ @@ -1043,7 +1045,7 @@ def _make_ites(self, seq): break_hard = False for i in range(len(seq.nodes)): node_0 = seq.nodes[i] - if not type(node_0) is CodeNode: + if type(node_0) is not CodeNode: continue rcond_0 = node_0.reaching_condition if rcond_0 is None: @@ -1052,7 +1054,7 @@ def _make_ites(self, seq): continue for j in range(i + 1, len(seq.nodes)): node_1 = seq.nodes[j] - if not type(node_1) is CodeNode: + if type(node_1) is not CodeNode: continue if node_0 is node_1: continue diff --git a/angr/analyses/decompiler/structuring/phoenix.py b/angr/analyses/decompiler/structuring/phoenix.py index d5d2a588ef2..1dbf605481e 100644 --- a/angr/analyses/decompiler/structuring/phoenix.py +++ b/angr/analyses/decompiler/structuring/phoenix.py @@ -242,7 +242,8 @@ def _match_cyclic_while(self, node, head, graph, full_graph) -> Tuple[bool, Opti # 03 | 0x4058c8 | cc_dep2<8> = Conv(8->64, Load(addr=rdi<8>, size=1, endness=Iend_LE)) # 04 | 0x4058c8 | rdi<8> = (rdi<8> + d<8>) # 05 | 0x4058c8 | rsi<8> = (rsi<8> + d<8>) - # 06 | 0x4058c8 | if ((Conv(64->8, cc_dep1<8>) == Conv(64->8, cc_dep2<8>))) { Goto 0x4058c8<64> } else { Goto None } + # 06 | 0x4058c8 | if ((Conv(64->8, cc_dep1<8>) == Conv(64->8, cc_dep2<8>))) { Goto 0x4058c8<64> } + # else { Goto None } # 07 | 0x4058c8 | Goto(0x4058ca<64>) _, head_block = self._find_node_going_to_dst(node, right) @@ -680,7 +681,7 @@ def _refine_cyclic_core(self, loop_head) -> bool: if cont_block is None: # cont_block is not found. but it's ok. one possibility is that src is a jump table head with one # case being the loop head. in such cases, we can just remove the edge. - if not src.addr in self.kb.cfgs["CFGFast"].jump_tables: + if src.addr not in self.kb.cfgs["CFGFast"].jump_tables: l.warning( "_refine_cyclic_core: Cannot find the block going to loop head for edge %r -> %r." "Remove the edge anyway.", @@ -1235,7 +1236,7 @@ def _make_switch_cases_core( if nn is head: continue for src in graph.predecessors(nn): - if not src in to_remove: + if src not in to_remove: other_nodes_inedges.append((src, nn)) for dst in full_graph.successors(nn): if dst not in to_remove: @@ -1427,11 +1428,11 @@ def _match_acyclic_ite(self, graph, full_graph, start_node) -> bool: return True - if right in graph and not left in graph: + if right in graph and left not in graph: # swap them left, right = right, left left_succs, right_succs = right_succs, left_succs # pylint:disable=unused-variable - if left in graph and not right in graph: + if left in graph and right not in graph: # potentially If-then if full_graph.in_degree[left] == 1 and ( full_graph.in_degree[right] == 2 diff --git a/angr/analyses/identifier/functions/strcmp.py b/angr/analyses/identifier/functions/strcmp.py index ab01744a159..0796dc24a60 100644 --- a/angr/analyses/identifier/functions/strcmp.py +++ b/angr/analyses/identifier/functions/strcmp.py @@ -26,8 +26,7 @@ def args(self): # pylint disable=no-self-use def gen_input_output_pair(self): l = 5 - s = rand_str(l, strcmp.non_null) - # pylint disable=unused-variable + rand_str(l, strcmp.non_null) # s return None diff --git a/angr/analyses/identifier/functions/strncmp.py b/angr/analyses/identifier/functions/strncmp.py index 2c109451888..1237ba66485 100644 --- a/angr/analyses/identifier/functions/strncmp.py +++ b/angr/analyses/identifier/functions/strncmp.py @@ -26,8 +26,7 @@ def args(self): # pylint disable=no-self-use def gen_input_output_pair(self): l = 5 - s = rand_str(l, strncmp.non_null) - # pylint disable=unused-variable + rand_str(l, strncmp.non_null) # s return None def can_call_other_funcs(self): diff --git a/angr/analyses/identifier/identify.py b/angr/analyses/identifier/identify.py index 0f729a9a148..feab33cd367 100644 --- a/angr/analyses/identifier/identify.py +++ b/angr/analyses/identifier/identify.py @@ -447,7 +447,8 @@ def _make_regs_symbolic(input_state, reg_list, project): def _prefilter_floats(self, func): # pylint: disable=no-self-use # calling _get_block() from `func` respects the size of the basic block # in extreme cases (like at the end of a section where VEX cannot disassemble the instruction beyond the - # section boundary), directly calling self.project.factory.block() on func.addr may lead to an AngrTranslationError. + # section boundary), directly calling self.project.factory.block() on func.addr may lead to an + # AngrTranslationError. bl = func._get_block(func.addr).vex if any(c.type.startswith("Ity_F") for c in bl.all_constants): diff --git a/angr/analyses/identifier/runner.py b/angr/analyses/identifier/runner.py index 422c62ba382..f0b3c86cc6c 100644 --- a/angr/analyses/identifier/runner.py +++ b/angr/analyses/identifier/runner.py @@ -4,7 +4,6 @@ import claripy -from ...sim_type import SimTypeFunction, SimTypeInt from ... import sim_options as so from ... import SIM_LIBRARIES from ... import BP_BEFORE, BP_AFTER @@ -272,7 +271,6 @@ def test(self, function, test_data, concrete_rand=False, custom_offs=None): outputs.append(result_state.solver.eval(out, cast_to=bytes)) if outputs != test_data.expected_output_args: - # print map(lambda x: x.encode('hex'), [a for a in outputs if a is not None]), map(lambda x: x.encode('hex'), [a for a in test_data.expected_output_args if a is not None]) l.info("mismatch output") return False diff --git a/angr/analyses/loop_analysis.py b/angr/analyses/loop_analysis.py index 20d891f954a..45f44f964ae 100644 --- a/angr/analyses/loop_analysis.py +++ b/angr/analyses/loop_analysis.py @@ -108,6 +108,11 @@ def _handle_AssignStmt(self, stmt): expr = self._expr(right_op) if expr is not None: + try: + from pysoot.sootir.soot_value import SootLocal + except ImportError: + l.error("Please install PySoot before analyzing Java byte code.") + raise if isinstance(left_op, SootLocal): # Log a def for the local variable self.state.locals[left_op.name] = expr @@ -166,6 +171,12 @@ def _handle_SootInterfaceInvokeExpr(self, expr): # Try to annotate the variable when applicable try: + try: + from pysoot.sootir.soot_value import SootValue + except ImportError: + l.error("Please install PySoot before analyzing Java byte code.") + raise + var_type = mapping[full_method] if isinstance(base_var, (SootValue, AnnotatedVariable)): @@ -180,13 +191,6 @@ def _handle_SootInterfaceInvokeExpr(self, expr): class LoopAnalysisState: def __init__(self, block): - # Delayed import - try: - from pysoot.sootir.soot_value import SootValue, SootLocal - except ImportError: - l.error("Please install PySoot before analyzing Java byte code.") - raise - self.block = block self.induction_variables = {} @@ -314,13 +318,14 @@ def _is_bounded_iterator_based(self): """ # Condition 0 - check_0 = lambda cond: ( - isinstance(cond, Condition) - and cond.op == Condition.Equal - and cond.val1 == 0 - and isinstance(cond.val0, AnnotatedVariable) - and cond.val0.type == VariableTypes.HasNext - ) + def check_0(cond): + return ( + isinstance(cond, Condition) + and cond.op == Condition.Equal + and cond.val1 == 0 + and isinstance(cond.val0, AnnotatedVariable) + and cond.val0.type == VariableTypes.HasNext + ) check_0_results = [(check_0(stmt[0]), stmt[0]) for stmt in self.loop_exit_stmts] check_0_conds = [cond for r, cond in check_0_results if r] # remove all False ones @@ -331,9 +336,12 @@ def _is_bounded_iterator_based(self): the_iterator = check_0_conds[0].val0.variable # Condition 1 - check_1 = lambda local: ( - isinstance(local, AnnotatedVariable) and local.type == VariableTypes.Next and local.variable == the_iterator - ) + def check_1(local): + return ( + isinstance(local, AnnotatedVariable) + and local.type == VariableTypes.Next + and local.variable == the_iterator + ) if not any([check_1(local) for local in self.locals.values()]): return None diff --git a/angr/analyses/propagator/engine_ail.py b/angr/analyses/propagator/engine_ail.py index d6d177af472..ff9f37ab74b 100644 --- a/angr/analyses/propagator/engine_ail.py +++ b/angr/analyses/propagator/engine_ail.py @@ -538,9 +538,9 @@ def _ail_handle_DirtyExpression( def _ail_handle_ITE(self, expr: Expr.ITE) -> Optional[PropValue]: # pylint:disable=unused-variable - cond = self._expr(expr.cond) - iftrue = self._expr(expr.iftrue) - iffalse = self._expr(expr.iffalse) + self._expr(expr.cond) # cond + self._expr(expr.iftrue) # iftrue + self._expr(expr.iffalse) # iffalse return PropValue.from_value_and_details(self.state.top(expr.bits), expr.size, expr, self._codeloc()) diff --git a/angr/analyses/reaching_definitions/__init__.py b/angr/analyses/reaching_definitions/__init__.py index 13f50454cdb..84e6f082b50 100644 --- a/angr/analyses/reaching_definitions/__init__.py +++ b/angr/analyses/reaching_definitions/__init__.py @@ -23,7 +23,7 @@ def get_all_definitions(region: "MultiValuedMemory") -> Set["Definition"]: cnt_set: Optional[Union["SimMemoryObject", Set["SimMemoryObject"]]] = page.content[idx] if cnt_set is None: continue - elif not type(cnt_set) is set: + elif type(cnt_set) is not set: cnt_set = {cnt_set} for cnt in cnt_set: for def_ in LiveDefinitions.extract_defs(cnt.object): diff --git a/angr/analyses/reaching_definitions/dep_graph.py b/angr/analyses/reaching_definitions/dep_graph.py index c3e24293a8c..45620a084fc 100644 --- a/angr/analyses/reaching_definitions/dep_graph.py +++ b/angr/analyses/reaching_definitions/dep_graph.py @@ -99,7 +99,6 @@ def _transitive_closure( predecessors = list(graph.predecessors(def_)) result.add_node(def_) - edges_and_data = [] for pred in predecessors: edge_data = graph.get_edge_data(pred, def_) if edge_data is None: @@ -138,8 +137,9 @@ def add_dependencies_for_concrete_pointers_of( assert definition in self.nodes(), "The given Definition must be present in the given graph." known_predecessor_addresses: List[Union[int, claripy.ast.Base]] = list( + # Needs https://github.com/python/mypy/issues/6847 map( - lambda definition: definition.atom.addr, # type: ignore # Needs https://github.com/python/mypy/issues/6847 + lambda definition: definition.atom.addr, # type: ignore filter(lambda p: isinstance(p.atom, MemoryLocation), self.predecessors(definition)), ) ) diff --git a/angr/analyses/reaching_definitions/engine_ail.py b/angr/analyses/reaching_definitions/engine_ail.py index 2e4964a0ad9..eec12fb8946 100644 --- a/angr/analyses/reaching_definitions/engine_ail.py +++ b/angr/analyses/reaching_definitions/engine_ail.py @@ -165,9 +165,7 @@ def _ail_handle_Store(self, stmt: ailment.Stmt.Store) -> None: addr: MultiValues = self._expr(stmt.addr) size: int = stmt.size if stmt.guard is not None: - guard = self._expr(stmt.guard) # pylint:disable=unused-variable - else: - guard = None # pylint:disable=unused-variable + self._expr(stmt.guard) addr_v = addr.one_value() if addr_v is not None and not self.state.is_top(addr_v): @@ -501,11 +499,8 @@ def _ail_handle_Load(self, expr: ailment.Expr.Load) -> MultiValues: size = expr.size bits = expr.bits if expr.guard is not None: - guard = self._expr(expr.guard) # pylint:disable=unused-variable - alt = self._expr(expr.alt) # pylint:disable=unused-variable - else: - guard = None # pylint:disable=unused-variable - alt = None # pylint:disable=unused-variable + self._expr(expr.guard) + self._expr(expr.alt) # convert addrs from MultiValues to a list of valid addresses if addrs.count() == 1: diff --git a/angr/analyses/reaching_definitions/reaching_definitions.py b/angr/analyses/reaching_definitions/reaching_definitions.py index 6919763e4a6..6590ffbf023 100644 --- a/angr/analyses/reaching_definitions/reaching_definitions.py +++ b/angr/analyses/reaching_definitions/reaching_definitions.py @@ -137,7 +137,7 @@ def __init__( self._observe_callback = observe_callback # sanity check - if self._observation_points and any(not type(op) is tuple for op in self._observation_points): + if self._observation_points and any(type(op) is not tuple for op in self._observation_points): raise ValueError('"observation_points" must be tuples.') self._node_iterations: DefaultDict[int, int] = defaultdict(int) diff --git a/angr/analyses/variable_recovery/engine_ail.py b/angr/analyses/variable_recovery/engine_ail.py index ca13aacf466..a343c8f60d0 100644 --- a/angr/analyses/variable_recovery/engine_ail.py +++ b/angr/analyses/variable_recovery/engine_ail.py @@ -268,10 +268,9 @@ def _ail_handle_StackBaseOffset(self, expr: ailment.Expr.StackBaseOffset): return richr def _ail_handle_ITE(self, expr: ailment.Expr.ITE): - # pylint:disable=unused-variable - cond = self._expr(expr.cond) - r0 = self._expr(expr.iftrue) - r1 = self._expr(expr.iffalse) + self._expr(expr.cond) # cond + self._expr(expr.iftrue) # r0 + self._expr(expr.iffalse) # r1 return RichR(self.state.top(expr.bits)) diff --git a/angr/analyses/variable_recovery/variable_recovery.py b/angr/analyses/variable_recovery/variable_recovery.py index 9722848ba3c..01a941e60c8 100644 --- a/angr/analyses/variable_recovery/variable_recovery.py +++ b/angr/analyses/variable_recovery/variable_recovery.py @@ -3,7 +3,6 @@ from typing import Tuple import claripy -import angr # For type annotations; pylint: disable=unused-import from ...errors import SimMemoryMissingError from ...storage.memory_mixins.paged_memory.pages.multi_values import MultiValues diff --git a/angr/analyses/veritesting.py b/angr/analyses/veritesting.py index 8dbdde31c3e..d455d74a22d 100644 --- a/angr/analyses/veritesting.py +++ b/angr/analyses/veritesting.py @@ -1,6 +1,7 @@ import logging from collections import defaultdict from functools import cmp_to_key +from typing import Tuple import networkx @@ -234,11 +235,10 @@ def __init__( self.result, self.final_manager = self._veritesting() - def _veritesting(self): + def _veritesting(self) -> Tuple[bool, SimulationManager]: """ Perform static symbolic execution starting from the given point. - returns (bool, SimulationManager): tuple of the success/failure of veritesting and the subsequent SimulationManager after - execution + :returns: tuple of the success/failure of veritesting and the subsequent SimulationManager after execution """ s = self._input_state.copy() @@ -247,7 +247,7 @@ def _veritesting(self): new_manager = self._execute_and_merge(s) except (ClaripyError, SimError, AngrError): - if not BYPASS_VERITESTING_EXCEPTIONS in s.options: + if BYPASS_VERITESTING_EXCEPTIONS not in s.options: raise l.warning("Veritesting caught an exception.", exc_info=True) return False, SimulationManager(self.project, stashes={"deviated": [s]}) @@ -456,8 +456,8 @@ def is_not_in_cfg(self, s): def _get_successors(self, state): """ - Gets the successors to the current state by step, saves copy of state and finally stashes new unconstrained states - to manager. + Gets the successors to the current state by step, saves copy of state and finally stashes new unconstrained + states to manager. :param SimState state: Current state to step on from :returns SimSuccessors: The SimSuccessors object diff --git a/angr/analyses/vfg.py b/angr/analyses/vfg.py index 3952670e95d..d01e7e1bd9c 100644 --- a/angr/analyses/vfg.py +++ b/angr/analyses/vfg.py @@ -1073,7 +1073,7 @@ def _should_widen_jobs(self, *jobs): addr = job_0.addr - if not addr in self._widening_points(job_0.func_addr): + if addr not in self._widening_points(job_0.func_addr): return False tracing_times = self._tracing_times[job_0.block_id] @@ -1101,8 +1101,6 @@ def _widen_jobs(self, *jobs): l.debug("Widening %s", job_1) new_state, _ = self._widen_states(job_0.state, job_1.state) - # print "job_0.state.eax =", job_0.state.regs.eax._model_vsa, "job_1.state.eax =", job_1.state.regs.eax._model_vsa - # print "new_job.state.eax =", new_state.regs.eax._model_vsa new_job = VFGJob( jobs[0].addr, @@ -1491,8 +1489,10 @@ def _create_new_jobs(self, job, successor, new_block_id, new_call_stack): if job.call_skipped: # TODO: Make sure the return values make sense - # if self.project.arch.name == 'X86': - # successor_state.regs.eax = successor_state.solver.BVS('ret_val', 32, min=0, max=0xffffffff, stride=1) + # if self.project.arch.name == "X86": + # successor_state.regs.eax = successor_state.solver.BVS( + # "ret_val", 32, min=0, max=0xFFFFFFFF, stride=1 + # ) new_job = VFGJob( successor_addr, @@ -1534,10 +1534,10 @@ def _create_new_jobs(self, job, successor, new_block_id, new_call_stack): if isinstance(reg_sp_expr._model_vsa, claripy.vsa.StridedInterval): reg_sp_si = reg_sp_expr._model_vsa - reg_sp_val = reg_sp_si.min + reg_sp_si.min # reg_sp_val elif isinstance(reg_sp_expr._model_vsa, claripy.vsa.ValueSet): reg_sp_si = next(iter(reg_sp_expr._model_vsa.items()))[1] - reg_sp_val = reg_sp_si.min + reg_sp_si.min # reg_sp_val # TODO: Finish it! new_job = VFGJob( diff --git a/angr/angrdb/serializers/cfg_model.py b/angr/angrdb/serializers/cfg_model.py index 493e629664e..6559f37f2b1 100644 --- a/angr/angrdb/serializers/cfg_model.py +++ b/angr/angrdb/serializers/cfg_model.py @@ -1,5 +1,5 @@ # pylint:disable=unused-import -from ..models import DbCFGModel, DbKnowledgeBase +from ..models import DbCFGModel from ...knowledge_plugins.cfg.cfg_model import CFGModel diff --git a/angr/angrdb/serializers/comments.py b/angr/angrdb/serializers/comments.py index ccb6651c65e..5f6fa7305d8 100644 --- a/angr/angrdb/serializers/comments.py +++ b/angr/angrdb/serializers/comments.py @@ -1,7 +1,6 @@ # pylint:disable=unused-import -from ..models import DbKnowledgeBase, DbComment +from ..models import DbComment from ...knowledge_plugins.comments import Comments -from ...knowledge_base import KnowledgeBase class CommentsSerializer: diff --git a/angr/angrdb/serializers/labels.py b/angr/angrdb/serializers/labels.py index 7721abba8fd..b847c991264 100644 --- a/angr/angrdb/serializers/labels.py +++ b/angr/angrdb/serializers/labels.py @@ -1,7 +1,6 @@ # pylint:disable=unused-import -from ..models import DbKnowledgeBase, DbLabel +from ..models import DbLabel from ...knowledge_plugins.labels import Labels -from ...knowledge_base import KnowledgeBase class LabelsSerializer: diff --git a/angr/angrdb/serializers/xrefs.py b/angr/angrdb/serializers/xrefs.py index 7f1bb8f584b..09a4aa8fd18 100644 --- a/angr/angrdb/serializers/xrefs.py +++ b/angr/angrdb/serializers/xrefs.py @@ -1,8 +1,6 @@ # pylint:disable=unused-import -from ..models import DbKnowledgeBase, DbXRefs +from ..models import DbXRefs from ...knowledge_plugins.xrefs import XRefManager -from ...knowledge_plugins.cfg import CFGModel -from ...knowledge_base import KnowledgeBase class XRefsSerializer: diff --git a/angr/annocfg.py b/angr/annocfg.py index 79b4234d714..6d0628fa372 100644 --- a/angr/annocfg.py +++ b/angr/annocfg.py @@ -267,7 +267,7 @@ def successor_func(self, path): """ whitelist = self.get_whitelisted_statements(path.addr) - last_stmt = self.get_last_statement_index(path.addr) + self.get_last_statement_index(path.addr) # pass in those arguments successors = path.step(stmt_whitelist=whitelist, last_stmt=None) diff --git a/angr/blade.py b/angr/blade.py index 2b31232c751..e2e14e252d9 100644 --- a/angr/blade.py +++ b/angr/blade.py @@ -348,7 +348,7 @@ def _backward_slice_recursive(self, level, run, regs, stack_offsets, prev, exit_ # if there are conditional exits, we *always* add them into the slice (so if they should not be taken, we do not # lose the condition) for stmt_idx_, s_ in enumerate(self._get_irsb(run).statements): - if not type(s_) is pyvex.IRStmt.Exit: + if type(s_) is not pyvex.IRStmt.Exit: continue if s_.jumpkind != "Ijk_Boring": continue diff --git a/angr/distributed/server.py b/angr/distributed/server.py index f4609a1b297..2d95c0206cf 100644 --- a/angr/distributed/server.py +++ b/angr/distributed/server.py @@ -1,7 +1,6 @@ from typing import Dict, Tuple import logging -import pickle import time import os import tempfile diff --git a/angr/distributed/worker.py b/angr/distributed/worker.py index 72116981dd9..799f6b259c7 100644 --- a/angr/distributed/worker.py +++ b/angr/distributed/worker.py @@ -173,7 +173,6 @@ def _state_priority(state): return state.history.depth def _pickle_state(self, state): - # state.project = None # this way we lose all changes the state makes after running... e.g., make_continuation() pass def _post_pickle_state(self, state, prio, sid): diff --git a/angr/engines/concrete.py b/angr/engines/concrete.py index ab38ebc0053..1be1230b199 100644 --- a/angr/engines/concrete.py +++ b/angr/engines/concrete.py @@ -157,13 +157,13 @@ def check_concrete_target_methods(concrete_target): :return: True if the concrete target is compliant """ entry_point = concrete_target.read_register("pc") - if not type(entry_point) is int: + if type(entry_point) is not int: l.error("read_register result type is %s, should be ", (type(entry_point))) return False mem_read = concrete_target.read_memory(entry_point, 0x4) - if not type(mem_read) is bytes: + if type(mem_read) is not bytes: l.error("read_memory result type is %s, should be ", (type(mem_read))) return False diff --git a/angr/engines/hook.py b/angr/engines/hook.py index 28523a3b7d3..352c9987496 100644 --- a/angr/engines/hook.py +++ b/angr/engines/hook.py @@ -20,7 +20,8 @@ class HooksMixin(SuccessorsMixin, ProcedureMixin): """ def _lookup_hook(self, state, procedure): - # TODO this is moderately controversial. If the jumpkind was NoHook and the user provided the procedure argument, which takes precedence? + # TODO this is moderately controversial. If the jumpkind was NoHook and the user provided the procedure + # argument, which takes precedence? # tentative guess: passed argument takes priority if procedure is not None: return procedure @@ -29,7 +30,7 @@ def _lookup_hook(self, state, procedure): if state.history and state.history.parent and state.history.parent.jumpkind == "Ijk_NoHook": return None - if not type(state._ip) is int and state._ip.symbolic: + if type(state._ip) is not int and state._ip.symbolic: # symbolic IP is not supported return None diff --git a/angr/engines/soot/engine.py b/angr/engines/soot/engine.py index d43dfb11dd6..69e87d9b391 100644 --- a/angr/engines/soot/engine.py +++ b/angr/engines/soot/engine.py @@ -12,7 +12,7 @@ from ...errors import SimEngineError, SimTranslationError from cle import CLEError from ...state_plugins.inspect import BP_AFTER, BP_BEFORE -from ...sim_type import SimTypeNum, SimTypeFunction, parse_type +from ...sim_type import SimTypeFunction, parse_type from ..engine import SuccessorsMixin from ..procedure import ProcedureMixin from .exceptions import BlockTerminationNotice, IncorrectLocationException diff --git a/angr/engines/soot/expressions/newArray.py b/angr/engines/soot/expressions/newArray.py index 11f29239dd3..508c7b92462 100644 --- a/angr/engines/soot/expressions/newArray.py +++ b/angr/engines/soot/expressions/newArray.py @@ -31,7 +31,7 @@ def _bound_array_size(state, array_size): size_stays_below_maximum = state.solver.eval_upto(max_array_size.SGE(array_size), 2) # overwrite size, if it *always* exceeds the maximum - if not True in size_stays_below_maximum: + if True not in size_stays_below_maximum: l.warning( "Array size %s always exceeds maximum size. " "It gets overwritten with the maximum %s.", array_size, diff --git a/angr/engines/soot/expressions/newMultiArray.py b/angr/engines/soot/expressions/newMultiArray.py index a1d7767b40e..de661a19484 100644 --- a/angr/engines/soot/expressions/newMultiArray.py +++ b/angr/engines/soot/expressions/newMultiArray.py @@ -43,7 +43,7 @@ def _bound_multi_array_size(state, multi_array_size): size_stays_below_maximum = state.solver.eval_upto(max_multi_array_size.SGE(multi_array_size), 2) # overwrite size, if it *always* exceeds the maximum - if not True in size_stays_below_maximum: + if True not in size_stays_below_maximum: l.warning( "Array size %s always exceeds maximum size. " "It gets overwritten with the maximum %s.", multi_array_size, diff --git a/angr/engines/soot/field_dispatcher.py b/angr/engines/soot/field_dispatcher.py index 769c865eea5..11f1ac7d63d 100644 --- a/angr/engines/soot/field_dispatcher.py +++ b/angr/engines/soot/field_dispatcher.py @@ -40,7 +40,7 @@ def _class_contains_field(field_class, field_name, field_type): if not field_class.is_loaded: return False # check if a field with the given name exists - if not field_name in field_class.fields: + if field_name not in field_class.fields: return False field = field_class.fields[field_name] # check type diff --git a/angr/engines/soot/statements/switch.py b/angr/engines/soot/statements/switch.py index 68e24f07b30..9dda476ed12 100644 --- a/angr/engines/soot/statements/switch.py +++ b/angr/engines/soot/statements/switch.py @@ -1,7 +1,5 @@ import logging -from claripy import Or - from .base import SimSootStmt l = logging.getLogger("angr.engines.soot.statements.switch") diff --git a/angr/engines/soot/values/arrayref.py b/angr/engines/soot/values/arrayref.py index c740ae2c144..dbb053ab80e 100644 --- a/angr/engines/soot/values/arrayref.py +++ b/angr/engines/soot/values/arrayref.py @@ -105,7 +105,7 @@ def check_array_bounds(idx, array, state): # For now we just constraint the index to stay within the bounds # raise exception, if index is *always* invalid - if not True in idx_stays_within_bounds: + if True not in idx_stays_within_bounds: raise SimEngineError( "Access of %s[%s] (length %s) is always invalid. " "Cannot continue w/o raising java.lang.ArrayIndexOutOfBoundsException." diff --git a/angr/engines/syscall.py b/angr/engines/syscall.py index a8a7563a284..3f3affa6c53 100644 --- a/angr/engines/syscall.py +++ b/angr/engines/syscall.py @@ -31,7 +31,9 @@ def process_successors(self, successors, **kwargs): if sys_procedure is None: if angr.sim_options.BYPASS_UNSUPPORTED_SYSCALL not in state.options: raise AngrUnsupportedSyscallError( - "Trying to perform a syscall on an emulated system which is not currently cofigured to support syscalls. To resolve this, make sure that your SimOS is a subclass of SimUserspace, or set the BYPASS_UNSUPPORTED_SYSCALL state option." + "Trying to perform a syscall on an emulated system which is not currently cofigured to support " + "syscalls. To resolve this, make sure that your SimOS is a subclass of SimUserspace, or set the " + "BYPASS_UNSUPPORTED_SYSCALL state option." ) else: try: diff --git a/angr/engines/vex/claripy/ccall.py b/angr/engines/vex/claripy/ccall.py index b2e94e5a485..6add3f4c335 100644 --- a/angr/engines/vex/claripy/ccall.py +++ b/angr/engines/vex/claripy/ccall.py @@ -355,7 +355,6 @@ def pc_actions_LOGIC(state, nbits, arg_l, arg_r, cc_ndep, platform=None): def pc_actions_DEC(state, nbits, res, _, cc_ndep, platform=None): arg_l = res + 1 - arg_r = 1 cf = (cc_ndep & data[platform]["CondBitMasks"]["G_CC_MASK_C"])[data[platform]["CondBitOffsets"]["G_CC_SHIFT_C"]] pf = calc_paritybit(res) @@ -473,7 +472,6 @@ def pc_actions_SBB(state, nbits, cc_dep1, cc_dep2, cc_ndep, platform=None): def pc_actions_INC(state, nbits, res, _, cc_ndep, platform=None): arg_l = res - 1 - arg_r = 1 cf = (cc_ndep & data[platform]["CondBitMasks"]["G_CC_MASK_C"])[data[platform]["CondBitOffsets"]["G_CC_SHIFT_C"]] pf = calc_paritybit(res) @@ -946,7 +944,8 @@ def pc_calculate_condition_simple(state, cond, cc_op, cc_dep1, cc_dep2, cc_ndep, r = globals()[cond_funcname](state, cc_expr) else: l.warning( - "Operation %s with condition %s is not supported in pc_calculate_condition_simple(). Consider implementing.", + "Operation %s with condition %s is not supported in pc_calculate_condition_simple(). " + "Consider implementing.", op, cond, ) @@ -1397,8 +1396,10 @@ def bad(msg): and state.project.concrete_target is not None ): return bad( - "angr doesn't support Windows Heaven's gate calls https://rce.co/knockin-on-heavens-gate-dynamic-processor-mode-switching/ \n" - "Please use the native 32 bit libs (not WoW64) or implement a simprocedure to avoid executing these instructions" + "angr doesn't support Windows Heaven's gate calls " + "https://rce.co/knockin-on-heavens-gate-dynamic-processor-mode-switching/ \n" + "Please use the native 32 bit libs (not WoW64) or implement a simprocedure to avoid executing these " + "instructions" ) # RPL=11 check @@ -1436,7 +1437,7 @@ def bad(msg): return bad("index out of range") ldt_base = ldt[47:16] - ldt_base_value = state.solver.eval_one(ldt_base) + state.solver.eval_one(ldt_base) ldt_value = state.solver.eval_one(ldt_base) descriptor = state.memory.load(ldt_value + seg_selector * 8, 8, endness="Iend_LE") @@ -1446,7 +1447,7 @@ def bad(msg): return bad("present bit set to 0") base = get_segdescr_base(state, descriptor) - limit = get_segdescr_limit(state, descriptor) + get_segdescr_limit(state, descriptor) # When a concrete target is set and memory is read directly from the process sometimes a negative offset # from a segment register is used @@ -1665,9 +1666,9 @@ def armg_calculate_flag_v(state, cc_op, cc_dep1, cc_dep2, cc_dep3): def armg_calculate_flags_nzcv(state, cc_op, cc_dep1, cc_dep2, cc_dep3): - # NOTE: adding constraints afterwards works here *only* because the constraints are actually useless, because we require - # cc_op to be unique. If we didn't, we'd need to pass the constraints into any functions called after the constraints were - # created. + # NOTE: adding constraints afterwards works here *only* because the constraints are actually useless, because we + # require cc_op to be unique. If we didn't, we'd need to pass the constraints into any functions called after the + # constraints were created. n = armg_calculate_flag_n(state, cc_op, cc_dep1, cc_dep2, cc_dep3) z = armg_calculate_flag_z(state, cc_op, cc_dep1, cc_dep2, cc_dep3) c = armg_calculate_flag_c(state, cc_op, cc_dep1, cc_dep2, cc_dep3) @@ -1691,9 +1692,9 @@ def armg_calculate_condition(state, cond_n_op, cc_dep1, cc_dep2, cc_dep3): concrete_cond = op_concretize(cond) flag = None - # NOTE: adding constraints afterwards works here *only* because the constraints are actually useless, because we require - # cc_op to be unique. If we didn't, we'd need to pass the constraints into any functions called after the constraints were - # created. + # NOTE: adding constraints afterwards works here *only* because the constraints are actually useless, because we + # require cc_op to be unique. If we didn't, we'd need to pass the constraints into any functions called after the + # constraints were created. if concrete_cond == ARMCondAL: flag = claripy.BVV(1, 32) @@ -1960,9 +1961,9 @@ def arm64g_calculate_flag_v(state, cc_op, cc_dep1, cc_dep2, cc_dep3): def arm64g_calculate_data_nzcv(state, cc_op, cc_dep1, cc_dep2, cc_dep3): - # NOTE: adding constraints afterwards works here *only* because the constraints are actually useless, because we require - # cc_op to be unique. If we didn't, we'd need to pass the constraints into any functions called after the constraints were - # created. + # NOTE: adding constraints afterwards works here *only* because the constraints are actually useless, because we + # require cc_op to be unique. If we didn't, we'd need to pass the constraints into any functions called after the + # constraints were created. n = arm64g_calculate_flag_n(state, cc_op, cc_dep1, cc_dep2, cc_dep3) z = arm64g_calculate_flag_z(state, cc_op, cc_dep1, cc_dep2, cc_dep3) c = arm64g_calculate_flag_c(state, cc_op, cc_dep1, cc_dep2, cc_dep3) diff --git a/angr/engines/vex/claripy/irop.py b/angr/engines/vex/claripy/irop.py index 401c4411deb..edc181bb58f 100644 --- a/angr/engines/vex/claripy/irop.py +++ b/angr/engines/vex/claripy/irop.py @@ -1000,7 +1000,8 @@ def _auto_vectorize(self, f, args, rm=None, rm_passed=False): for lane_args in self.vector_args(args): if self._float: # HACK HACK HACK - # this is such a weird divergence. why do the fp generics take several args and the int generics take a list? + # this is such a weird divergence. why do the fp generics take several args and the int generics + # take a list? result.append(f(*lane_args).raw_to_bv()) else: result.append(f(lane_args)) diff --git a/angr/engines/vex/heavy/inspect.py b/angr/engines/vex/heavy/inspect.py index c7aa4fe6b57..090bbfca9df 100644 --- a/angr/engines/vex/heavy/inspect.py +++ b/angr/engines/vex/heavy/inspect.py @@ -3,7 +3,8 @@ class SimInspectMixin(VEXMixin): - # open question: what should be done about the BP_AFTER breakpoints in cases where the engine uses exceptional control flow? + # open question: what should be done about the BP_AFTER breakpoints in cases where the engine uses exceptional + # control flow? def _perform_vex_stmt_Dirty_call(self, func_name, ty, args, func=NO_OVERRIDE): self.state._inspect( "dirty", when=BP_BEFORE, dirty_name=func_name, dirty_args=args, dirty_handler=func, dirty_result=NO_OVERRIDE diff --git a/angr/exploration_techniques/__init__.py b/angr/exploration_techniques/__init__.py index 0d467e592c4..85697cb69d8 100644 --- a/angr/exploration_techniques/__init__.py +++ b/angr/exploration_techniques/__init__.py @@ -124,7 +124,6 @@ def complete(self, simgr): # pylint:disable=no-self-use,unused-argument from .slicecutor import Slicecutor -from .cacher import Cacher from .driller_core import DrillerCore from .loop_seer import LoopSeer from .tracer import Tracer diff --git a/angr/exploration_techniques/cacher.py b/angr/exploration_techniques/cacher.py deleted file mode 100644 index e44f30df852..00000000000 --- a/angr/exploration_techniques/cacher.py +++ /dev/null @@ -1,141 +0,0 @@ -import os -import string -import hashlib -import tempfile -import logging - -from . import ExplorationTechnique -from .common import condition_to_lambda - - -l = logging.getLogger(name=__name__) - - -class Cacher(ExplorationTechnique): - """ - An exploration technique that caches states during symbolic execution. - - DO NOT USE THIS - THIS IS FOR ARCHIVAL PURPOSES ONLY - """ - - def __init__( - self, when=None, dump_cache=True, load_cache=True, container=None, lookup=None, dump_func=None, load_func=None - ): - """ - :param dump_cache: Whether to dump data to cache. - :param load_cache: Whether to load data from cache. - :param container: Data container. - :param when: If provided, should be a function that takes a SimulationManager and returns - a Boolean, or the address of the state to be cached. - :param lookup: A function that returns True if cache hit and False otherwise. - :param dump_func: If provided, should be a function that defines how Cacher should cache the - SimulationManager. Default to caching the active stash. - :param load_func: If provided, should be a function that defines how Cacher should uncache the - SimulationManager. Default to uncaching the stash to be stepped. - """ - super().__init__() - self._dump_cond, _ = condition_to_lambda(when) - self._dump_cache = dump_cache - self._load_cache = load_cache - self._cache_lookup = self._lookup if lookup is None else lookup - self._dump_func = self._dump_stash if dump_func is None else dump_func - self._load_func = self._load_stash if load_func is None else load_func - - self.container = container - self.container_pickle_str = isinstance(container, str) and not all(c in string.printable for c in container) - - def setup(self, simgr): - binary = simgr._project.filename - binhash = hashlib.md5(open(binary).read()).hexdigest() - - if self.container is None: - # Create a temporary directory to hold the cache files - tmp_directory = tempfile.mkdtemp(prefix="angr_cacher_container") - self.container = os.path.join(tmp_directory, f"{os.path.basename(binary)}-{binhash}.cache") - - # Container is the file name. - elif isinstance(self.container, str) and not self.container_pickle_str: - try: - self.container = self.container % { - "name": os.path.basename(binary), - "binhash": binhash, - "addr": "%(addr)s", - } - except KeyError: - l.error("Only the following cache keys are accepted: 'name', 'binhash' and 'addr'.") - raise - - if self._load_cache and self._cache_lookup(): - l.warning("Uncaching from %s...", self.container) - self._load_func(self.container, simgr) - - self.project = simgr._project - - def step(self, simgr, stash="active", **kwargs): - # We cache if any of the states in 'stash' satisfies the condition. - for s in simgr.stashes[stash]: - if self._dump_cache and self._dump_cond(s): - if isinstance(self.container, str): - self.container = self.container % {"addr": hex(s.addr)[:-1]} - - if self._cache_lookup(): - continue - - l.warning("Caching to %s...", self.container) - - self._dump_func(self.container, simgr, stash) - - return simgr.step(stash=stash, **kwargs) - - def _lookup(self): - if isinstance(self.container, str): - if self.container_pickle_str: - return True - - elif os.path.exists(self.container): - return True - - else: - return False - - elif isinstance(self.container, file): - return True - - else: - l.warning("Default Cacher cannot recognize containers of type other than 'str' and 'file'.") - return False - - @staticmethod - def _load_stash(container, simgr): - project = simgr._project - cached_project = project.load_function(container) - - if cached_project is not None: - cached_project.analyses = project.analyses - cached_project.store_function = project.store_function - cached_project.load_function = project.load_function - - stash = cached_project.storage["cached_states"] - for s in stash: - s.project = cached_project - - simgr.stashes["active"] = stash - cached_project.storage = None - - simgr._project = cached_project - - else: - l.error("Something went wrong during Project unpickling...") - - @staticmethod - def _dump_stash(container, simgr, stash): - for s in simgr.stashes[stash]: - s.project = None - s.history.trim() - - project = simgr._project - project.storage["cached_states"] = simgr.stashes[stash] - project.store_function(container) - - for s in simgr.stashes[stash]: - s.project = project diff --git a/angr/exploration_techniques/common.py b/angr/exploration_techniques/common.py index b030d38d3e4..0c632919e8d 100644 --- a/angr/exploration_techniques/common.py +++ b/angr/exploration_techniques/common.py @@ -15,7 +15,10 @@ def condition_to_lambda(condition, default=False): at, or None if no addresses were provided statically. """ if condition is None: - condition_function = lambda state: default + + def condition_function(state): + return default + static_addrs = set() elif isinstance(condition, int): diff --git a/angr/exploration_techniques/director.py b/angr/exploration_techniques/director.py index a53b7170bb0..3c8de0931ed 100644 --- a/angr/exploration_techniques/director.py +++ b/angr/exploration_techniques/director.py @@ -476,8 +476,8 @@ def _categorize_states(self, simgr): Categorize all states into two different groups: reaching the destination within the peek depth, and not reaching the destination within the peek depth. - :param SimulationManager simgr: The simulation manager that contains states. All active states (state belonging to "active" stash) - are subjected to categorization. + :param SimulationManager simgr: The simulation manager that contains states. All active states (state + belonging to "active" stash) are subjected to categorization. :return: The categorized simulation manager. :rtype: angr.SimulationManager """ diff --git a/angr/exploration_techniques/explorer.py b/angr/exploration_techniques/explorer.py index e70dcee00a7..773fc231f6b 100644 --- a/angr/exploration_techniques/explorer.py +++ b/angr/exploration_techniques/explorer.py @@ -98,9 +98,9 @@ def __init__( l.warning("Providing an incomplete CFG can cause viable paths to be discarded!") def setup(self, simgr): - if not self.find_stash in simgr.stashes: + if self.find_stash not in simgr.stashes: simgr.stashes[self.find_stash] = [] - if not self.avoid_stash in simgr.stashes: + if self.avoid_stash not in simgr.stashes: simgr.stashes[self.avoid_stash] = [] def step(self, simgr, stash="active", **kwargs): diff --git a/angr/exploration_techniques/loop_seer.py b/angr/exploration_techniques/loop_seer.py index 5cda9b4ff71..bf9dd02368f 100644 --- a/angr/exploration_techniques/loop_seer.py +++ b/angr/exploration_techniques/loop_seer.py @@ -29,7 +29,8 @@ def __init__( """ :param cfg: Normalized CFG is required. :param functions: Function(s) containing the loop(s) to be analyzed. - :param loops: Specific group of Loop(s) to be analyzed, if this is None we run the LoopFinder analysis. + :param loops: Specific group of Loop(s) to be analyzed, if this is None we run the LoopFinder + analysis. :param use_header: Whether to use header based trip counter to compare with the bound limit. :param bound: Limit the number of iterations a loop may be executed. :param bound_reached: If provided, should be a function that takes the LoopSeer and the succ_state. diff --git a/angr/exploration_techniques/oppologist.py b/angr/exploration_techniques/oppologist.py index d706c0f32c6..05a86f59507 100644 --- a/angr/exploration_techniques/oppologist.py +++ b/angr/exploration_techniques/oppologist.py @@ -1,5 +1,3 @@ -from collections import defaultdict - import claripy import functools @@ -52,8 +50,6 @@ def _oppologize(self, simgr, state, pn, **kwargs): @staticmethod def _combine_results(*results): - all_results = defaultdict(list) - final = SimSuccessors(results[0].addr, results[0].initial_state) final.description = "Oppology" final.sort = "Oppologist" diff --git a/angr/exploration_techniques/spiller_db.py b/angr/exploration_techniques/spiller_db.py index 64c0837cdcc..4d0db46c9c5 100644 --- a/angr/exploration_techniques/spiller_db.py +++ b/angr/exploration_techniques/spiller_db.py @@ -21,3 +21,7 @@ class PickledState(Base): except ImportError: sqlalchemy = None + create_engine = None + Base = None + OperationalError = None + sessionmaker = None diff --git a/angr/factory.py b/angr/factory.py index 9e183f5422e..033db50aac1 100644 --- a/angr/factory.py +++ b/angr/factory.py @@ -172,7 +172,8 @@ def simulation_manager( """ Constructs a new simulation manager. - :param thing: Optional - What to put in the new SimulationManager's active stash (either a SimState or a list of SimStates). + :param thing: What to put in the new SimulationManager's active stash (either a SimState or a list of + SimStates). :param kwargs: Any additional keyword arguments will be passed to the SimulationManager constructor :returns: The new SimulationManager :rtype: angr.sim_manager.SimulationManager @@ -182,7 +183,8 @@ def simulation_manager( * If nothing is passed in, the SimulationManager is seeded with a state initialized for the program entry point, i.e. :meth:`entry_state()`. * If a :class:`SimState` is passed in, the SimulationManager is seeded with that state. - * If a list is passed in, the list must contain only SimStates and the whole list will be used to seed the SimulationManager. + * If a list is passed in, the list must contain only SimStates and the whole list will be used to seed the + SimulationManager. """ if thing is None: thing = [self.entry_state()] diff --git a/angr/knowledge_plugins/cfg/cfg_node.py b/angr/knowledge_plugins/cfg/cfg_node.py index 533e60c19bd..db881391474 100644 --- a/angr/knowledge_plugins/cfg/cfg_node.py +++ b/angr/knowledge_plugins/cfg/cfg_node.py @@ -334,7 +334,7 @@ def __repr__(self): def __eq__(self, other): if isinstance(other, SimSuccessors): raise ValueError("You do not want to be comparing a SimSuccessors instance to a CFGNode.") - if not type(other) is CFGNode: + if type(other) is not CFGNode: return False return self.addr == other.addr and self.size == other.size and self.simprocedure_name == other.simprocedure_name diff --git a/angr/knowledge_plugins/functions/function.py b/angr/knowledge_plugins/functions/function.py index c3602f69c30..fe578d31f39 100644 --- a/angr/knowledge_plugins/functions/function.py +++ b/angr/knowledge_plugins/functions/function.py @@ -5,9 +5,7 @@ import itertools from collections import defaultdict from typing import Union, Optional, Iterable, Set, Generator -from typing import ( - Type, -) # For some reasons the linter doesn't recognize the use in apply_definition but PyCharm needs it imported to correctly recognize it # pylint: disable=unused-import +from typing import Type from itanium_demangler import parse @@ -1527,13 +1525,7 @@ def demangled_name(self): return ast.__str__() return self.name - def apply_definition(self, definition, calling_convention=None): - """ - - :param str definition: - :param Optional[Union[SimCC, Type[SimCC]]] calling_convention: - :return None: - """ + def apply_definition(self, definition: str, calling_convention: Optional[Union[SimCC, Type[SimCC]]] = None) -> None: if not definition.endswith(";"): definition += ";" func_def = parse_defns(definition, arch=self.project.arch) diff --git a/angr/knowledge_plugins/key_definitions/atoms.py b/angr/knowledge_plugins/key_definitions/atoms.py index 0cfe6da33c6..2d42d919021 100644 --- a/angr/knowledge_plugins/key_definitions/atoms.py +++ b/angr/knowledge_plugins/key_definitions/atoms.py @@ -269,7 +269,7 @@ def symbolic(self) -> bool: if isinstance(self.addr, int): return False elif isinstance(self.addr, SpOffset): - return not type(self.addr.offset) is int + return type(self.addr.offset) is not int return True def __eq__(self, other): diff --git a/angr/knowledge_plugins/key_definitions/live_definitions.py b/angr/knowledge_plugins/key_definitions/live_definitions.py index be91f3235f1..945b9746a25 100644 --- a/angr/knowledge_plugins/key_definitions/live_definitions.py +++ b/angr/knowledge_plugins/key_definitions/live_definitions.py @@ -670,7 +670,7 @@ def add_tmp_use(self, atom: Tmp, code_loc: CodeLocation) -> None: if atom.tmp_idx in self.tmps: defs = self.tmps[atom.tmp_idx] for d in defs: - assert not type(d.atom) is Tmp + assert type(d.atom) is not Tmp self.add_use_by_def(d, code_loc) def add_tmp_use_by_def(self, def_: Definition, code_loc: CodeLocation) -> None: diff --git a/angr/knowledge_plugins/sync/sync_controller.py b/angr/knowledge_plugins/sync/sync_controller.py index 770da3e61b1..249bb57ea95 100644 --- a/angr/knowledge_plugins/sync/sync_controller.py +++ b/angr/knowledge_plugins/sync/sync_controller.py @@ -16,11 +16,10 @@ def import_binsync(): + global binsync global binsync_available try: import binsync - from binsync.client import Client - from binsync.data.stack_variable import StackVariable, StackOffsetType binsync_available = True except ImportError: diff --git a/angr/knowledge_plugins/types.py b/angr/knowledge_plugins/types.py index 4b6bec80535..f93bc541a7e 100644 --- a/angr/knowledge_plugins/types.py +++ b/angr/knowledge_plugins/types.py @@ -48,7 +48,7 @@ def __getitem__(self, item): return ALL_TYPES[item] def __setitem__(self, item, value): - if not type(value) is TypeRef: + if type(value) is not TypeRef: raise TypeError("Can only store TypeRefs in TypesStore") super().__setitem__(item, value.with_arch(self.kb._project.arch)) diff --git a/angr/knowledge_plugins/variables/variable_manager.py b/angr/knowledge_plugins/variables/variable_manager.py index a41ff841c87..76c939dc65a 100644 --- a/angr/knowledge_plugins/variables/variable_manager.py +++ b/angr/knowledge_plugins/variables/variable_manager.py @@ -131,7 +131,6 @@ def serialize_to_cmessage(self): cmsg = self._get_cmsg() # variables - temp_variables = [] register_variables = [] stack_variables = [] memory_variables = [] @@ -170,7 +169,6 @@ def serialize_to_cmessage(self): cmsg.accesses.extend(accesses) # unified variables - unified_temp_variables = [] unified_register_variables = [] unified_stack_variables = [] unified_memory_variables = [] diff --git a/angr/knowledge_plugins/xrefs/xref_manager.py b/angr/knowledge_plugins/xrefs/xref_manager.py index b2c902509b9..5d79b31e0a1 100644 --- a/angr/knowledge_plugins/xrefs/xref_manager.py +++ b/angr/knowledge_plugins/xrefs/xref_manager.py @@ -61,7 +61,10 @@ def get_xrefs_by_dst_region(self, start, end): bounded by start and end. Will only return absolute xrefs, not relative ones (like SP offsets) """ - f = lambda x: isinstance(x, int) and start <= x <= end + + def f(x): + return isinstance(x, int) and start <= x <= end + addrs = filter(f, self.xrefs_by_dst.keys()) refs = set() for addr in addrs: @@ -73,7 +76,10 @@ def get_xrefs_by_ins_addr_region(self, start, end) -> Set[XRef]: Get a set of XRef objects that originate at a given address region bounded by start and end. Useful for finding references from a basic block or function. """ - f = lambda x: isinstance(x, int) and start <= x <= end + + def f(x): + return isinstance(x, int) and start <= x <= end + addrs = filter(f, self.xrefs_by_ins_addr.keys()) refs = set() for addr in addrs: diff --git a/angr/misc/hookset.py b/angr/misc/hookset.py index d57b2e48685..38aca6f4d19 100644 --- a/angr/misc/hookset.py +++ b/angr/misc/hookset.py @@ -1,6 +1,7 @@ """ These classes perform some python magic that we use to implement the nesting of exploration technique methods. -This process is formalized as a "hooking" of a python method - each exploration technique's methods "hooks" a method of the same name on the simulation manager class. +This process is formalized as a "hooking" of a python method - each exploration technique's methods "hooks" a method of +the same name on the simulation manager class. """ @@ -34,8 +35,8 @@ def remove_hooks(target, **hooks): :param target: The object from which to remove hooks. If all hooks are removed from a given method, the HookedMethod object will be removed and replaced with the original function. - :param hooks: Any keywords will be interpreted as hooks to remove. You must provide the exact hook that was applied - so that it can it can be identified for removal among any other hooks. + :param hooks: Any keywords will be interpreted as hooks to remove. You must provide the exact hook that was + applied so that it can it can be identified for removal among any other hooks. """ for name, hook in hooks.items(): hooked = getattr(target, name) diff --git a/angr/misc/plugins.py b/angr/misc/plugins.py index 8addcd76520..925f1ef7551 100644 --- a/angr/misc/plugins.py +++ b/angr/misc/plugins.py @@ -206,10 +206,12 @@ def release_plugin(self, name): class PluginPreset: """ A plugin preset object contains a mapping from name to a plugin class. - A preset can be active on a hub, which will cause it to handle requests for plugins which are not already present on the hub. + A preset can be active on a hub, which will cause it to handle requests for plugins which are not already present + on the hub. Unlike Plugins and PluginHubs, instances of PluginPresets are defined on the module level for individual presets. - You should register the preset instance with a hub to allow plugins to easily add themselves to the preset without an explicit reference to the preset itself. + You should register the preset instance with a hub to allow plugins to easily add themselves to the preset without + an explicit reference to the preset itself. """ def __init__(self): diff --git a/angr/procedures/cgc/random.py b/angr/procedures/cgc/random.py index fe5804b7156..f6f9568682e 100644 --- a/angr/procedures/cgc/random.py +++ b/angr/procedures/cgc/random.py @@ -1,7 +1,6 @@ import itertools import angr -import claripy rand_count = itertools.count() diff --git a/angr/procedures/java_jni/array_operations.py b/angr/procedures/java_jni/array_operations.py index a1f7cbb12b7..4941362a03f 100644 --- a/angr/procedures/java_jni/array_operations.py +++ b/angr/procedures/java_jni/array_operations.py @@ -81,7 +81,10 @@ def run(self, ptr_env, length_, element_type_, initial_element_): # if available, set the initial_element as the arrays default value if self.state.solver.eval(initial_element_ != 0): initial_element = self.state.jni_references.lookup(initial_element_) - generator = lambda state: initial_element + + def generator(state): + return initial_element + array.add_default_value_generator(generator) else: initial_element = None @@ -250,7 +253,7 @@ def _check_region_bounds(array, start_idx, length, state): # True and False at the same time range_stays_within_bounds = state.solver.eval_upto(range_constraints, 2) - if not True in range_stays_within_bounds: + if True not in range_stays_within_bounds: # There is no valid combination of start_idx and length, s.t. the # range stays within the array bounds. # Correct simulation must continue with a raised Exception diff --git a/angr/procedures/java_util/collection.py b/angr/procedures/java_util/collection.py index 92d8d18bcc5..9aa920a27d5 100644 --- a/angr/procedures/java_util/collection.py +++ b/angr/procedures/java_util/collection.py @@ -2,8 +2,7 @@ import logging from ..java import JavaSimProcedure -from ...engines.soot.expressions import SimSootExpr_NewArray, SimSootExpr_NullConstant -from ...engines.soot.values import SimSootValue_StringRef, SimSootValue_ThisRef +from ...engines.soot.values import SimSootValue_ThisRef log = logging.getLogger(name=__name__) diff --git a/angr/procedures/java_util/iterator.py b/angr/procedures/java_util/iterator.py index c99900b7181..8cf0dd16757 100644 --- a/angr/procedures/java_util/iterator.py +++ b/angr/procedures/java_util/iterator.py @@ -2,8 +2,7 @@ import logging from ..java import JavaSimProcedure -from ...engines.soot.expressions import SimSootExpr_NewArray, SimSootExpr_NullConstant -from ...engines.soot.values import SimSootValue_StringRef, SimSootValue_ThisRef +from ...engines.soot.values import SimSootValue_ThisRef from .collection import ELEMS, SIZE, INDEX log = logging.getLogger(name=__name__) diff --git a/angr/procedures/java_util/list.py b/angr/procedures/java_util/list.py index ffe7460de09..0f443e45dc3 100644 --- a/angr/procedures/java_util/list.py +++ b/angr/procedures/java_util/list.py @@ -55,7 +55,7 @@ def run(self, this_ref, index): try: array_ref = this_ref.load_field(self.state, ELEMS, "java.lang.Object[]") - array_len = this_ref.load_field(self.state, SIZE, "int") + this_ref.load_field(self.state, SIZE, "int") # TODO should check boundaries? return self.state.javavm_memory.load_array_element(array_ref, index) @@ -74,7 +74,7 @@ def run(self, this_ref): try: array_ref = this_ref.load_field(self.state, ELEMS, "java.lang.Object[]") - array_len = this_ref.load_field(self.state, SIZE, "int") + this_ref.load_field(self.state, SIZE, "int") # TODO should check boundaries? diff --git a/angr/procedures/libc/strncmp.py b/angr/procedures/libc/strncmp.py index 0e8ecbde3b1..c6d60fa7d65 100644 --- a/angr/procedures/libc/strncmp.py +++ b/angr/procedures/libc/strncmp.py @@ -26,7 +26,6 @@ def run( # determine the maximum number of bytes to compare concrete_run = False - # if not self.state.solver.symbolic(a_len) and not self.state.solver.symbolic(b_len) and not self.state.solver.symbolic(limit): if ( self.state.solver.single_valued(a_len) and self.state.solver.single_valued(b_len) diff --git a/angr/procedures/linux_kernel/fstat.py b/angr/procedures/linux_kernel/fstat.py index 4137a67cddc..a71e062f405 100644 --- a/angr/procedures/linux_kernel/fstat.py +++ b/angr/procedures/linux_kernel/fstat.py @@ -19,7 +19,8 @@ def run(self, fd, stat_buf): return 0 def _store_amd64(self, stat_buf, stat): - store = lambda offset, val: self.state.memory.store(stat_buf + offset, val, endness="Iend_LE") + def store(offset, val): + return self.state.memory.store(stat_buf + offset, val, endness="Iend_LE") store(0x00, stat.st_dev) store(0x08, stat.st_ino) @@ -61,9 +62,8 @@ def _store_amd64(self, stat_buf, stat): # state.st_ctimensec) def _store_ppc64(self, stat_buf, stat): - store = lambda offset, val: self.state.memory.store( - stat_buf + offset, val, endness=self.state.arch.memory_endness - ) + def store(offset, val): + return self.state.memory.store(stat_buf + offset, val, endness=self.state.arch.memory_endness) store(0x00, stat.st_dev) store(0x08, stat.st_ino) @@ -86,9 +86,8 @@ def _store_ppc64(self, stat_buf, stat): store(0x88, self.state.solver.BVV(0, 64)) def _store_mips64(self, stat_buf, stat): - store = lambda offset, val: self.state.memory.store( - stat_buf + offset, val, endness=self.state.arch.memory_endness - ) + def store(offset, val): + return self.state.memory.store(stat_buf + offset, val, endness=self.state.arch.memory_endness) store(0x00, stat.st_dev) store(0x04, self.state.solver.BVV(0, 32 * 3)) @@ -111,9 +110,8 @@ def _store_mips64(self, stat_buf, stat): store(0x60, stat.st_blocks) def _store_aarch64(self, stat_buf, stat): - store = lambda offset, val: self.state.memory.store( - stat_buf + offset, val, endness=self.state.arch.memory_endness - ) + def store(offset, val): + return self.state.memory.store(stat_buf + offset, val, endness=self.state.arch.memory_endness) store(0x00, stat.st_dev) store(0x08, stat.st_ino) diff --git a/angr/procedures/linux_kernel/fstat64.py b/angr/procedures/linux_kernel/fstat64.py index 34bf8cf3934..3cee6e29725 100644 --- a/angr/procedures/linux_kernel/fstat64.py +++ b/angr/procedures/linux_kernel/fstat64.py @@ -24,7 +24,9 @@ def run(self, fd, stat_buf): # pylint:disable=arguments-differ return 0 def _store_arm(self, stat_buf, stat): - store = lambda offset, val: self.state.memory.store(stat_buf + offset, val, endness="Iend_LE") + def store(offset, val): + return self.state.memory.store(stat_buf + offset, val, endness="Iend_LE") + store(0x00, stat.st_dev) store(0x0C, stat.st_ino) store(0x10, stat.st_mode) @@ -44,7 +46,9 @@ def _store_arm(self, stat_buf, stat): store(0x60, stat.st_ino) # weird verification st_ino def _store_i386(self, stat_buf, stat): - store = lambda offset, val: self.state.memory.store(stat_buf + offset, val, endness="Iend_LE") + def store(offset, val): + return self.state.memory.store(stat_buf + offset, val, endness="Iend_LE") + store(0x00, stat.st_dev) store(0x0C, stat.st_ino) store(0x10, stat.st_mode) @@ -65,7 +69,8 @@ def _store_i386(self, stat_buf, stat): store(0x5C, stat.st_ino) # weird verification st_ino def _store_amd64(self, stat_buf, stat): - store = lambda offset, val: self.state.memory.store(stat_buf + offset, val, endness="Iend_LE") + def store(offset, val): + return self.state.memory.store(stat_buf + offset, val, endness="Iend_LE") store(0x00, stat.st_dev) store(0x08, stat.st_ino) @@ -89,9 +94,8 @@ def _store_amd64(self, stat_buf, stat): store(0x88, self.state.solver.BVV(0, 64)) def _store_ppc32(self, stat_buf, stat): - store = lambda offset, val: self.state.memory.store( - stat_buf + offset, val, endness=self.state.arch.memory_endness - ) + def store(offset, val): + return self.state.memory.store(stat_buf + offset, val, endness=self.state.arch.memory_endness) store(0x00, stat.st_dev) store(0x08, stat.st_ino) @@ -115,9 +119,8 @@ def _store_ppc32(self, stat_buf, stat): store(0x64, self.state.solver.BVV(0, 32)) def _store_mips32(self, stat_buf, stat): - store = lambda offset, val: self.state.memory.store( - stat_buf + offset, val, endness=self.state.arch.memory_endness - ) + def store(offset, val): + return self.state.memory.store(stat_buf + offset, val, endness=self.state.arch.memory_endness) store(0x00, stat.st_dev) store(0x04, self.state.solver.BVV(0, 32 * 3)) @@ -138,9 +141,8 @@ def _store_mips32(self, stat_buf, stat): store(0x58, stat.st_blocks) def _store_arm_eabi(self, stat_buf, stat): - store = lambda offset, val: self.state.memory.store( - stat_buf + offset, val, endness=self.state.arch.memory_endness - ) + def store(offset, val): + return self.state.memory.store(stat_buf + offset, val, endness=self.state.arch.memory_endness) store(0x00, stat.st_dev) store(0x02, self.state.solver.BVV(0, 8 * 10)) diff --git a/angr/procedures/linux_kernel/stat.py b/angr/procedures/linux_kernel/stat.py index 9e7d5618342..aebd236b5eb 100644 --- a/angr/procedures/linux_kernel/stat.py +++ b/angr/procedures/linux_kernel/stat.py @@ -10,7 +10,8 @@ def run(self, file_path, stat_buf): return 0 def _store_amd64(self, stat_buf, stat): - store = lambda offset, val: self.state.memory.store(stat_buf + offset, val) + def store(offset, val): + return self.state.memory.store(stat_buf + offset, val) store(0x00, stat.st_dev) store(0x08, stat.st_ino) diff --git a/angr/procedures/linux_loader/sim_loader.py b/angr/procedures/linux_loader/sim_loader.py index 24e319882fb..2df64c57045 100644 --- a/angr/procedures/linux_loader/sim_loader.py +++ b/angr/procedures/linux_loader/sim_loader.py @@ -1,5 +1,4 @@ import angr -import claripy import logging l = logging.getLogger(name=__name__) diff --git a/angr/procedures/posix/dup.py b/angr/procedures/posix/dup.py index 19f4c92fb86..7e3c4ee9fc3 100644 --- a/angr/procedures/posix/dup.py +++ b/angr/procedures/posix/dup.py @@ -1,7 +1,4 @@ import angr -from angr.sim_type import SimTypeInt, SimTypeFd -from angr.state_plugins import SimSystemPosix -from angr.storage.file import SimFileDescriptor ################################## # dup diff --git a/angr/procedures/posix/fdopen.py b/angr/procedures/posix/fdopen.py index 1c7b1bb68f0..b3205af67a5 100644 --- a/angr/procedures/posix/fdopen.py +++ b/angr/procedures/posix/fdopen.py @@ -37,7 +37,7 @@ def run(self, fd_int, m_addr): m_strlen = self.inline_call(strlen, m_addr) m_expr = self.state.memory.load(m_addr, m_strlen.max_null_index, endness="Iend_BE") - mode = self.state.solver.eval(m_expr, cast_to=bytes) + self.state.solver.eval(m_expr, cast_to=bytes) # TODO: handle append and other mode subtleties diff --git a/angr/procedures/posix/readdir.py b/angr/procedures/posix/readdir.py index fa2581c2733..b9d98bceae1 100644 --- a/angr/procedures/posix/readdir.py +++ b/angr/procedures/posix/readdir.py @@ -45,8 +45,11 @@ def _build_amd64(self): self.condition = self.state.solver.BoolS("readdir_cond") # TODO: variable key def _store_amd64(self, ptr): - stores = lambda offset, val: self.state.memory.store(ptr + offset, val, endness="Iend_BE") - storei = lambda offset, val: self.state.memory.store(ptr + offset, val, endness="Iend_LE") + def stores(offset, val): + return self.state.memory.store(ptr + offset, val, endness="Iend_BE") + + def storei(offset, val): + return self.state.memory.store(ptr + offset, val, endness="Iend_LE") storei(0, self.struct.d_ino) storei(8, self.struct.d_off) diff --git a/angr/procedures/posix/strtok_r.py b/angr/procedures/posix/strtok_r.py index 26a7b31479e..54096f9f5ff 100644 --- a/angr/procedures/posix/strtok_r.py +++ b/angr/procedures/posix/strtok_r.py @@ -43,7 +43,8 @@ def run(self, str_ptr, delim_ptr, save_ptr, str_strlen=None, delim_strlen=None): write_length = self.state.solver.If(where.ret_expr != 0, delim_strlen.ret_expr, 0) write_content = self.state.solver.BVV(0, delim_strlen.max_null_index * 8) - # do a symbolic write (we increment the limit because of the possibility that the write target is 0, in which case the length will be 0, anyways) + # do a symbolic write (we increment the limit because of the possibility that the write target is 0, + # in which case the length will be 0, anyways) l.debug("... doing the symbolic write") self.state.memory.store( where.ret_expr, diff --git a/angr/procedures/stubs/b64_decode.py b/angr/procedures/stubs/b64_decode.py index 2e24cc61445..530a22b0a2f 100644 --- a/angr/procedures/stubs/b64_decode.py +++ b/angr/procedures/stubs/b64_decode.py @@ -10,38 +10,3 @@ def run(self, src, dst, length): cpy = self.inline_call(strncpy, dst, src, length) self.state.memory.store(dst + 16, self.state.solver.BVV(0, 8)) return cpy.ret_expr - - -# -# if length.is_symbolic(): -# raise Exception("SYMBOLIC LENGTH WTF") -# -# ln = length.solver.any() -# full_str = self.state.memory.load(src, ln) -# -# for i in range(ln//4): -# part = se.Extract(ln*8 - i*4*8 - 1, ln*8 - (i+1)*4*8, full_str) -# -# -# -# -# -# memcpy = angr.SIM_PROCEDURES['libc']['memcpy'] -# -# fmt = self.get_arg_expr(1) #pylint:disable=unused-variable -# one = self.get_arg_expr(2) -# two = self.get_arg_expr(3) -# three = self.get_arg_expr(4) -# -# self.inline_call(memcpy, one, src, 5) -# self.state.memory.store(one+4, self.state.solver.BVV(0, 8)) -# self.inline_call(memcpy, two, src+6, 8192) -# self.state.memory.store(two+8191, self.state.solver.BVV(0, 8)) -# self.inline_call(memcpy, three, src+6+8193, 12) -# self.state.memory.store(three+11, self.state.solver.BVV(0, 8)) -# -# if angr.o.SYMBOLIC in self.state.options: -# crazy_str = "index.asp?authorization=M3NhZG1pbjoyNzk4ODMwMw==&yan=yes\x00" -# self.state.add_constraints(self.state.memory.load(two, len(crazy_str)) == self.state.solver.BVV(crazy_str)) -# -# self.exit_return(self.state.solver.BVV(3)) diff --git a/angr/procedures/stubs/crazy_scanf.py b/angr/procedures/stubs/crazy_scanf.py index 24bada2dda4..af8f4c18e6e 100644 --- a/angr/procedures/stubs/crazy_scanf.py +++ b/angr/procedures/stubs/crazy_scanf.py @@ -14,10 +14,4 @@ def run(self, src, fmt, one, two, three): # pylint:disable=unused-argument self.inline_call(memcpy, three, src + 6 + 8193, 12) self.state.memory.store(three + 11, self.state.solver.BVV(0, 8)) - # if angr.o.SYMBOLIC in self.state.options: - # #crazy_str = "index.asp?authorization=M3NhZG1pbjoyNzk4ODMwMw==&yan=yes\x00" - # #crazy_str = "index.asp?authorization=3sadmin:27988303&yan=yes\x00" - # crazy_str = "authorization=3sadmin:27988303\x00" - # self.state.add_constraints(self.state.memory.load(two, len(crazy_str)) == self.state.solver.BVV(crazy_str)) - return self.state.solver.BVV(3) diff --git a/angr/procedures/stubs/format_parser.py b/angr/procedures/stubs/format_parser.py index 8cd26a7c6f4..d7f4982c531 100644 --- a/angr/procedures/stubs/format_parser.py +++ b/angr/procedures/stubs/format_parser.py @@ -58,7 +58,8 @@ def _get_str_at(self, str_addr, max_length=None): def replace(self, va_arg): """ - Implement printf - based on the stored format specifier information, format the values from the arg getter function `args` into a string. + Implement printf - based on the stored format specifier information, format the values from the arg getter + function `args` into a string. :param va_arg: A function which takes a type and returns the next argument of that type :return: The result formatted string diff --git a/angr/project.py b/angr/project.py index 1288fa80f60..29e640d83f9 100644 --- a/angr/project.py +++ b/angr/project.py @@ -82,7 +82,8 @@ class Project: :ivar analyses: The available analyses. :type analyses: angr.analysis.Analyses :ivar entry: The program entrypoint. - :ivar factory: Provides access to important analysis elements such as path groups and symbolic execution results. + :ivar factory: Provides access to important analysis elements such as path groups and symbolic execution + results. :type factory: AngrObjectFactory :ivar filename: The filename of the executable. :ivar loader: The program loader. diff --git a/angr/sim_manager.py b/angr/sim_manager.py index 1293f1b226e..90d65cd0e44 100644 --- a/angr/sim_manager.py +++ b/angr/sim_manager.py @@ -606,7 +606,10 @@ def move(self, from_stash, to_stash, filter_func=None): :rtype: SimulationManager """ filter_func = filter_func or (lambda s: True) - stash_splitter = lambda states: reversed(self._filter_states(filter_func, states)) + + def stash_splitter(states): + return reversed(self._filter_states(filter_func, states)) + return self.split(stash_splitter, from_stash=from_stash, to_stash=to_stash) def stash(self, filter_func=None, from_stash="active", to_stash="stashed"): diff --git a/angr/sim_options.py b/angr/sim_options.py index 7c7fb8372af..99971d08dbb 100644 --- a/angr/sim_options.py +++ b/angr/sim_options.py @@ -7,7 +7,8 @@ # This option controls whether or not constraints are tracked in the analysis. TRACK_CONSTRAINTS = "TRACK_CONSTRAINTS" -# This option controls whether or not various entities (IRExpr constants, reads, writes, etc) get simplified automatically +# This option controls whether or not various entities (IRExpr constants, reads, writes, etc) get simplified +# automatically SIMPLIFY_EXPRS = "SIMPLIFY_EXPRS" SIMPLIFY_MEMORY_READS = "SIMPLIFY_MEMORY_READS" SIMPLIFY_MEMORY_WRITES = "SIMPLIFY_MEMORY_WRITES" @@ -49,7 +50,8 @@ # This variable causes claripy to use a string solver (CVC4) STRINGS_ANALYSIS = "STRINGS_ANALYSIS" -# Generate symbolic values for non-existent values. The absence of this option causes Unconstrained() to return default concrete values (like 0) +# Generate symbolic values for non-existent values. The absence of this option causes Unconstrained() to return default +# concrete values (like 0) SYMBOLIC_INITIAL_VALUES = "SYMBOLIC_INITIAL_VALUES" # this causes angr to use SimAbstractMemory for the memory region diff --git a/angr/sim_state.py b/angr/sim_state.py index d6a4c0b4fdd..14e2bef249e 100644 --- a/angr/sim_state.py +++ b/angr/sim_state.py @@ -11,7 +11,6 @@ l = logging.getLogger(name=__name__) -import angr # For type annotations; pylint:disable=unused-import import claripy import archinfo from archinfo.arch_soot import SootAddressDescriptor diff --git a/angr/sim_type.py b/angr/sim_type.py index 4d52f8059fd..ea48cc35117 100644 --- a/angr/sim_type.py +++ b/angr/sim_type.py @@ -1258,7 +1258,7 @@ def __getitem__(self, k): if isinstance(f, NamedTypeMixin) and f.name is None: try: return f[k] - except: + except KeyError: continue else: return self._values[k] @@ -1492,7 +1492,7 @@ def __getitem__(self, k): if isinstance(f, NamedTypeMixin) and f.name is None: try: return f[k] - except: + except KeyError: continue else: return self._values[k] diff --git a/angr/simos/javavm.py b/angr/simos/javavm.py index 0607cd67b9f..126eccf750c 100644 --- a/angr/simos/javavm.py +++ b/angr/simos/javavm.py @@ -316,9 +316,6 @@ def _get_default_symbolic_value_by_type(type_, state): return SimSootValue_StringRef.new_string(state, StringS(f"default_value_{type_}", 1000)) if type_.endswith("[][]"): raise NotImplementedError - # multiarray = SimSootExpr_NewMultiArray.new_array(self.state, element_type, size) - # multiarray.add_default_value_generator(lambda s: SimSootExpr_NewMultiArray._generate_inner_array(s, element_type, sizes)) - # return multiarray if type_.endswith("[]"): array = SimSootExpr_NewArray.new_array(state, type_[:-2], BVV(2, 32)) return array diff --git a/angr/simos/linux.py b/angr/simos/linux.py index 11b612090c6..0b075f9aa86 100644 --- a/angr/simos/linux.py +++ b/angr/simos/linux.py @@ -4,7 +4,7 @@ import claripy from cle import MetaELF -from cle.backends.elf.symbol import ELFSymbol, ELFSymbolType +from cle.backends.elf.symbol import ELFSymbolType from cle.backends.elf.elfcore import ELFCore from cle.address_translator import AT from cle.backends.elf.relocation.arm64 import R_AARCH64_TLSDESC diff --git a/angr/simos/userland.py b/angr/simos/userland.py index 580c20eefe1..3ff08feb7c8 100644 --- a/angr/simos/userland.py +++ b/angr/simos/userland.py @@ -27,7 +27,8 @@ def __init__(self, project, syscall_library=None, syscall_addr_alignment=4, **kw # syscall_abis is a dict of tuples {name: (base_number, min_number, max_number)} # min_number and max_number are just cached from SimSyscallLibrary.{min,max}imum_sysall_number # base_number is used to map the syscalls into the syscall address space - it's a "base address" - # but a number. to convert from syscall number to address it's (number - min_num + base_num) * alignment + kernel_base + # but a number. to convert from syscall number to address it's + # (number - min_num + base_num) * alignment + kernel_base def configure_project(self, abi_list=None): # pylint: disable=arguments-differ if abi_list is None: @@ -136,7 +137,8 @@ def syscall_from_number(self, number, allow_unsupported=True, abi=None): Get a syscall SimProcedure from its number. :param number: The syscall number - :param allow_unsupported: Whether to return a "stub" syscall for unsupported numbers instead of throwing an error + :param allow_unsupported: Whether to return a "stub" syscall for unsupported numbers instead of throwing an + error :param abi: The name of the abi to use. If None, will assume that the abis have disjoint numbering schemes and pick the right one. :return: The SimProcedure for the syscall diff --git a/angr/simos/windows.py b/angr/simos/windows.py index 4c04bc5b13c..efe86865d04 100644 --- a/angr/simos/windows.py +++ b/angr/simos/windows.py @@ -359,14 +359,14 @@ def handle_exception(self, successors, engine, exception): else: exc_state = r.flat_successors[0] - except: + except Exception as e: # lol no _l.error( "Got some weirdo error while re-executing %d instructions at %#x " "for exception windup", num_inst, successors.initial_state.addr, ) - raise exception + raise exception from e else: # duplicate the history-cycle code here... exc_state = successors.initial_state.copy() @@ -500,7 +500,8 @@ def initialize_gdt_x86(self, state, concrete_target): @staticmethod def _read_fs_register_x86(concrete_target): """ - Injects small shellcode to leak the fs segment register address. In Windows x86 this address is pointed by gs:[0x18] + Injects small shellcode to leak the fs segment register address. In Windows x86 this address is pointed by + gs:[0x18] :param concrete_target: ConcreteTarget which will be used to get the fs register address :return: fs register address :rtype string @@ -513,7 +514,8 @@ def _read_fs_register_x86(concrete_target): @staticmethod def _read_gs_register_x64(concrete_target): """ - Injects small shellcode to leak the gs segment register address. In Windows x64 this address is pointed by gs:[0x30] + Injects small shellcode to leak the gs segment register address. In Windows x64 this address is pointed by + gs:[0x30] :param concrete_target: ConcreteTarget which will be used to get the fs register address :return: gs register address :rtype string diff --git a/angr/state_plugins/filesystem.py b/angr/state_plugins/filesystem.py index bfabe542217..c48ae523c26 100644 --- a/angr/state_plugins/filesystem.py +++ b/angr/state_plugins/filesystem.py @@ -467,258 +467,3 @@ def _get_stat(self, guest_path, dereference=False): return stat except OSError: return None - - -# class SimDirectory(SimStatePlugin): -# """ -# This is the base class for directories in angr's emulated filesystem. An instance of this class or a subclass will -# be found as ``state.fs``, representing the root of the filesystem. -# -# :ivar files: A mapping from filename to file that this directory contains. -# """ -# def __init__(self, files=None, writable=True, parent=None, pathsep='/'): -# super(SimDirectory, self).__init__() -# self.files = files -# self.writable = writable -# self.parent = parent if parent is not None else self -# self.pathsep = pathsep -# self.files['.'] = self -# self.files['..'] = self.parent -# -# def __len__(self): -# return len(self.files) -# -# def lookup(self, path, writing=False): -# """ -# Look up the file or directory at the end of the given path. -# This method should be called on the current working directory object. -# -# :param str path: The path to look up -# :param bool writing: Whether the operation desired requires write permissions -# :returns: The SimDirectory or SimFile object specified, or None if not found, or False if writing -# was requested and the target is nonwritable -# """ -# if len(path) == 0: -# return None -# if path[0] == self.pathsep: -# # lookup the filesystem root -# root = self -# while root.parent is not root: -# root = root.parent -# return root._lookup(path[1:], writing) -# else: -# return self._lookup(path, writing) -# -# def _lookup(self, path, writing): -# while path.startswith(self.pathsep): -# path = path[1:] -# -# if len(path) == 0: -# if writing and not self.writable: -# return False -# return self -# -# for fname, simfile in self.files.items(): -# if path.startswith(fname): -# if len(path) == len(fname): -# if writing and not simfile.writable: -# return False -# return simfile -# elif path[len(fname)] == self.pathsep: -# if isinstance(simfile, SimDirectory): -# return simfile._lookup(path[len(fname)+1:]) -# else: # TODO: symlinks -# return None -# -# return None -# -# def insert(self, path, simfile): -# """ -# Add a file to the filesystem. -# This method should be called on the current working directory object. -# -# :param str path: The path to insert the new file at -# :param simfile: The new file or directory -# :returns: A boolean indicating whether the operation succeeded -# """ -# while len(path) > 1 and path[-1] == self.pathsep: -# path = path[:-1] -# -# if self.pathsep not in path: -# if path in self.files: -# return False -# if isinstance(simfile, SimDirectory): -# if simfile.parent is simfile: -# simfile.parent = self -# simfile.pathsep = self.pathsep -# else: -# l.error("Trying to add directory to filesystem which already has a parent") -# -# self.files[path] = simfile -# simfile.set_state(self.state) -# return True -# else: -# lastsep = path.rindex(self.pathsep) + 1 -# head, tail = path[:lastsep], path[lastsep:] -# parent = self.lookup(head, True) -# -# if not parent: -# return False -# return parent.insert(tail, simfile) -# -# def remove(self, path): -# """ -# Remove a file from the filesystem. If the target is a directory, the directory must be empty. -# This method should be called on the current working directory object. -# -# :param str path: The path to remove the file at -# :returns: A boolean indicating whether the operation succeeded -# """ -# while len(path) > 1 and path[-1] == self.pathsep: -# # TODO: when symlinks exist this will need to be fixed to delete the target of the -# # symlink instead of the link itself -# path = path[:-1] -# -# if self.pathsep not in path: -# if path in ('.', '..'): -# return False -# if path not in self.files: -# return False -# if isinstance(self.files[path], SimDirectory) and len(self.files[path]) != 2: -# return False -# -# del self.files[path] -# return True -# else: -# lastsep = path.rindex(self.pathsep) + 1 -# head, tail = path[:lastsep], path[lastsep:] -# parent = self.lookup(head, True) -# -# if not parent: -# return False -# return parent.remove(tail) -# -# @SimStatePlugin.memo -# def copy(self, memo): -# return SimDirectory( -# files={x: y.copy(memo) for x, y in self.files.items()}, -# writable=self.writable, -# parent=self.parent.copy(memo), -# pathsep=self.pathsep) -# -# def merge(self, others, conditions, ancestor=None): -# new_files = {path: (simfile, [], []) for path, simfile in self.files.items() if path not in ('.', '..')} -# for other, condition in zip(others, conditions): -# if type(other) is not type(self): -# raise SimMergeError("Can't merge filesystem elements of disparate types") -# for path, simfile in other.files.items(): -# if path in ('.', '..'): -# continue -# if path not in new_files: -# l.warning("Cannot represent the conditional creation of files") -# new_files[path] = (simfile, [], []) -# else: -# new_files[path][1].append(simfile) -# new_files[path][2].append(condition) -# -# for k in new_files: -# new_files[k][0].merge(new_files[k][1], new_files[k][2], ancestor) -# new_files[k] = new_files[k][0] -# new_files['.'] = self -# new_files['..'] = self.parent -# self.files = new_files -# -# def widen(self, others): -# new_files = {path: [simfile] for path, simfile in self.files.items() if path not in ('.', '..')} -# for other in others: -# if type(other) is not type(self): -# raise SimMergeError("Can't merge filesystem elements of disparate types") -# for path, simfile in other.files.items(): -# if path in ('.', '..'): -# continue -# if path not in new_files: -# new_files[path] = [simfile] -# else: -# new_files[path].append(simfile) -# -# for k in new_files: -# new_files[k][0].widen(new_files[k][1:]) -# new_files[k] = new_files[k][0] -# new_files['.'] = self -# new_files['..'] = self.parent -# self.files = new_files -# -# class SimDirectoryConcrete(SimDirectory): -# """ -# A SimDirectory that forwards its requests to the host filesystem -# -# :param host_path: The path on the host filesystem to provide -# :param writable: Whether to allow mutation of the host filesystem by the guest -# """ -# def __init__(self, host_path, writable=False, pathsep='/', host_root=None, parent=None): -# super(SimConcreteDirectory, self).__init__(files={}, writable=writable, parent=parent, pathsep=pathsep) -# self.host_path = os.path.realpath(host_path) -# self.host_root = self.host_path if host_root is None else host_root -# -# def _lookup(self, path, writing): -# partial_path = self.host_path -# for i, pathkey in enumerate(path.split(self.pathsep)): -# if partial_path == self.host_root and pathkey == '..': -# target = self.pathsep.join(path.split(self.pathsep)[i+1:]) -# return self.parent._lookup(target, writing) -# if not os.path.isdir(partial_path): -# return None -# -# partial_path = os.path.realpath(partial_path + self.pathsep + pathkey) -# -# if writing and not self.writable: -# return False -# -# if os.path.isdir(partial_path): -# f = SimDirectoryConcrete(host_path=partial_path, writable=self.writable, host_root=self.host_root, parent=self.parent) -# f.set_state(self.state) -# return f -# elif os.path.isfile(partial_path): -# try: -# f = SimFileConcrete(host_path=partial_path, writable=self.writable) -# f.set_state(self.state) -# return f -# except OSError: -# return None -# else: -# raise SimFilesystemError("Can't handle something other than a file or directory in a concrete filesystem") -# -# def insert(self, path, simfile): -# if self.pathsep in path: -# return super(SimDirectoryConcrete, self).insert(path, simfile) -# else: -# fullpath = os.path.join(self.host_path, path) -# if os.path.exists(fullpath): -# return False -# with open(fullpath, 'w') as fp: -# fp.write(simfile.concretize()) -# return True -# -# def remove(self, path): -# if self.pathsep in path: -# return super(SimDirectoryConcrete, self).remove(path) -# else: -# fullpath = os.path.join(self.host_path, path) -# if not os.path.exists(fullpath): -# return False -# if os.path.isdir(fullpath): -# try: -# os.rmdir(fullpath) -# except OSError: -# return False -# return True -# elif os.path.isfile(fullpath): -# try: -# os.unlink(fullpath) -# except OSError: -# return False -# return True -# else: -# raise SimFilesystemError("Can't handle anything but files and directories in concrete filesystem") -# -# SimDirectory.register_default('fs') diff --git a/angr/state_plugins/heap/heap_libc.py b/angr/state_plugins/heap/heap_libc.py index 68a3e07c22f..771defb0b1d 100644 --- a/angr/state_plugins/heap/heap_libc.py +++ b/angr/state_plugins/heap/heap_libc.py @@ -39,7 +39,7 @@ def realloc(self, ptr, size): :param ptr: the location in memory to be reallocated :param size: the new size desired for the allocation - :returns: the address of the allocation, or a NULL pointer if the allocation was freed or if no new allocation - was made + :returns: the address of the allocation, or a NULL pointer if the allocation was freed or if no new + allocation was made """ raise NotImplementedError(f"{self.realloc.__func__.__name__} not implemented for {self.__class__.__name__}") diff --git a/angr/state_plugins/history.py b/angr/state_plugins/history.py index fbc47520533..e2b2461aeb5 100644 --- a/angr/state_plugins/history.py +++ b/angr/state_plugins/history.py @@ -286,38 +286,6 @@ def action_writes(action): # (insn_addr is None or (x.sim_procedure is None and addr_of_stmt(x.bbl_addr, x.stmt_idx) == insn_addr)) ] - # def _record_state(self, state, strong_reference=True): - # else: - # # state.scratch.bbl_addr may not be initialized as final states from the "flat_successors" list. We need to get - # # the value from _target in that case. - # if self.addr is None and not self._target.symbolic: - # self._addrs = [ self._target._model_concrete.value ] - # else: - # # FIXME: redesign so this does not happen - # l.warning("Encountered a path to a SimProcedure with a symbolic target address.") - # - # if o.UNICORN in state.options: - # self.extra_length += state.scratch.executed_block_count - 1 - # - # if o.TRACK_ACTION_HISTORY in state.options: - # self._events = state.history.events - # - # # record constraints, added constraints, and satisfiability - # self._all_constraints = state.solver.constraints - # self._fresh_constraints = state.history.fresh_constraints - # - # if isinstance(state.solver._solver, claripy.frontend_mixins.SatCacheMixin): - # self._satisfiable = state.solver._solver._cached_satness - # else: - # self._satisfiable = None - # - # # record the state as a weak reference - # self._state_weak_ref = weakref.ref(state) - # - # # and as a strong ref - # if strong_reference: - # self._state_strong_ref = state - def demote(self): """ Demotes this history node, causing it to drop the strong state reference. diff --git a/angr/state_plugins/inspect.py b/angr/state_plugins/inspect.py index c839539c33d..04c466b4431 100644 --- a/angr/state_plugins/inspect.py +++ b/angr/state_plugins/inspect.py @@ -135,7 +135,8 @@ class BP: def __init__(self, when=BP_BEFORE, enabled=None, condition=None, action=None, **kwargs): if len({k.replace("_unique", "") for k in kwargs} - set(inspect_attributes)) != 0: raise ValueError( - f"Invalid inspect attribute(s) {kwargs} passed in. Should be one of {inspect_attributes}, or their _unique option." + f"Invalid inspect attribute(s) {kwargs} passed in. " + f"Should be one of {inspect_attributes}, or their _unique option." ) self.kwargs = kwargs @@ -200,7 +201,7 @@ def fire(self, state): :param state: The state. """ if self.action is None or self.action == BP_IPDB: - ipdb = __import__("ipdb").set_trace() + __import__("ipdb").set_trace() elif self.action == BP_IPYTHON: import IPython diff --git a/angr/state_plugins/plugin.py b/angr/state_plugins/plugin.py index 5fd26fb51c3..9d52307bdf2 100644 --- a/angr/state_plugins/plugin.py +++ b/angr/state_plugins/plugin.py @@ -76,16 +76,26 @@ def merge(self, others, merge_conditions, common_ancestor=None): # pylint:disab the target state, so this should mutate the current instance to merge with the others. Note that when multiple instances of a single plugin object (for example, a file) are referenced in the state, - it is important that merge only ever be called once. This should be solved by designating one of the plugin's referees as the "real owner", who should be the one to actually merge it. - This technique doesn't work to resolve the similar issue that arises during copying because merging doesn't produce a new reference to insert. + it is important that merge only ever be called once. This should be solved by designating one of the plugin's + referees as the "real owner", who should be the one to actually merge it. This technique doesn't work to + resolve the similar issue that arises during copying because merging doesn't produce a new reference to insert. There will be n ``others`` and n+1 merge conditions, since the first condition corresponds to self. To match elements up to conditions, say ``zip([self] + others, merge_conditions)`` - When implementing this, make sure that you "deepen" both ``others`` and ``common_ancestor`` before calling sub-elements' merge methods, - e.g. ``self.foo.merge([o.foo for o in others], merge_conditions, common_ancestor=common_ancestor.foo if common_ancestor is not None else None)``. + When implementing this, make sure that you "deepen" both ``others`` and ``common_ancestor`` before calling + sub-elements' merge methods, e.g. - During static analysis, merge_conditions can be None, in which case you should use ``state.solver.union(values)``. + .. code-block:: python + + self.foo.merge( + [o.foo for o in others], + merge_conditions, + common_ancestor=common_ancestor.foo if common_ancestor is not None else None + ) + + During static analysis, merge_conditions can be None, in which case you should use + ``state.solver.union(values)``. TODO: fish please make this less bullshit There is a utility ``state.solver.ite_cases`` which will help with constructing arbitrarily large merged ASTs. @@ -117,7 +127,8 @@ def register_default(cls, name, xtr=None): if cls is SimStatePlugin: if once("simstateplugin_register_default deprecation"): l.critical( - "SimStatePlugin.register_default(name, cls) is deprecated, please use SimState.register_default(name)" + "SimStatePlugin.register_default(name, cls) is deprecated, " + "please use SimState.register_default(name)" ) from angr.sim_state import SimState @@ -128,7 +139,8 @@ def register_default(cls, name, xtr=None): if xtr is cls: if once("simstateplugin_register_default deprecation case 2"): l.critical( - "SimStatePlugin.register_default(name, cls) is deprecated, please use cls.register_default(name)" + "SimStatePlugin.register_default(name, cls) is deprecated, " + "please use cls.register_default(name)" ) xtr = None diff --git a/angr/state_plugins/preconstrainer.py b/angr/state_plugins/preconstrainer.py index 11df3d25a60..0f866de288d 100644 --- a/angr/state_plugins/preconstrainer.py +++ b/angr/state_plugins/preconstrainer.py @@ -13,7 +13,8 @@ class SimStatePreconstrainer(SimStatePlugin): """ This state plugin manages the concept of preconstraining - adding constraints which you would like to remove later. - :param constrained_addrs : SimActions for memory operations whose addresses should be constrained during crash analysis + :param constrained_addrs: SimActions for memory operations whose addresses should be constrained during crash + analysis """ def __init__(self, constrained_addrs=None): diff --git a/angr/state_plugins/sim_action.py b/angr/state_plugins/sim_action.py index e69d9ad6be2..05c95758a57 100644 --- a/angr/state_plugins/sim_action.py +++ b/angr/state_plugins/sim_action.py @@ -45,12 +45,6 @@ def __repr__(self): def _desc(self): raise NotImplementedError() - # def __getstate__(self): - # return { k: getattr(self, k) for k in sum([ c.__slots__ for c in self.__class__.mro() if hasattr(c, '__slots__')], []) } #pylint:disable=no-member - # def __setstate__(self, s): - # for k,v in s.items(): - # setattr(self, k, v) - @staticmethod def _make_object(v): if v is None: diff --git a/angr/state_plugins/symbolizer.py b/angr/state_plugins/symbolizer.py index e0f50aff5ac..1f854c1b91e 100644 --- a/angr/state_plugins/symbolizer.py +++ b/angr/state_plugins/symbolizer.py @@ -175,7 +175,7 @@ def _preconstrain(self, value, name_prefix="address_"): def _should_symbolize(self, addr): return ( self._page_id(addr) in self.symbolization_target_pages - and not self._page_id(addr) in self.ignore_target_pages + and self._page_id(addr) not in self.ignore_target_pages ) def _resymbolize_int(self, be, le=0, base=0, offset=0, skip=()): diff --git a/angr/storage/file.py b/angr/storage/file.py index 024a181d95b..1e7b6b6c115 100644 --- a/angr/storage/file.py +++ b/angr/storage/file.py @@ -120,7 +120,8 @@ def read(self, pos, size, **kwargs): :param pos: The offset in the file to read from. :param size: The size to read. May be symbolic. - :return: A tuple of the data read (a bitvector of the length that is the maximum length of the read), the actual size of the read, and the new file position pointer. + :return: A tuple of the data read (a bitvector of the length that is the maximum length of the read), + the actual size of the read, and the new file position pointer. """ raise NotImplementedError @@ -480,10 +481,13 @@ def read(self, pos, size, **kwargs): """ Read a packet from the stream. - :param int pos: The packet number to read from the sequence of the stream. May be None to append to the stream. + :param int pos: The packet number to read from the sequence of the stream. May be None to append to the + stream. :param size: The size to read. May be symbolic. - :param short_reads: Whether to replace the size with a symbolic value constrained to less than or equal to the original size. If unspecified, will be chosen based on the state option. - :return: A tuple of the data read (a bitvector of the length that is the maximum length of the read) and the actual size of the read. + :param short_reads: Whether to replace the size with a symbolic value constrained to less than or equal to the + original size. If unspecified, will be chosen based on the state option. + :return: A tuple of the data read (a bitvector of the length that is the maximum length of the read) + and the actual size of the read. """ short_reads = kwargs.pop("short_reads", None) @@ -505,7 +509,8 @@ def read(self, pos, size, **kwargs): self.state.add_constraints(realsize <= size) # assert that the packet fits within the read request if not self.state.solver.satisfiable(): raise SimFileError( - f"SimPackets could not fit the current packet into the read request of {size} bytes: {self.content[pos]}" + "SimPackets could not fit the current packet into the read " + f"request of {size} bytes: {self.content[pos]}" ) return self.content[pos] + (pos + 1,) @@ -560,9 +565,11 @@ def write(self, pos, data, size=None, events=True, **kwargs): """ Write a packet to the stream. - :param int pos: The packet number to write in the sequence of the stream. May be None to append to the stream. + :param int pos: The packet number to write in the sequence of the stream. May be None to append to the + stream. :param data: The data to write, as a string or bitvector. - :param size: The optional size to write. May be symbolic; must be constrained to at most the size of data. + :param size: The optional size to write. May be symbolic; must be constrained to at most the size of + data. :return: The next packet to use after this """ if events: diff --git a/angr/storage/memory_mixins/paged_memory/pages/cooperation.py b/angr/storage/memory_mixins/paged_memory/pages/cooperation.py index 47fdaa4e475..050cc98abcd 100644 --- a/angr/storage/memory_mixins/paged_memory/pages/cooperation.py +++ b/angr/storage/memory_mixins/paged_memory/pages/cooperation.py @@ -176,7 +176,7 @@ def _compose_objects( elements: List[Set[claripy.ast.Base]] = [] for i, (a, objs) in enumerate(c_objects): chopped_set = set() - if not type(objs) is set: + if type(objs) is not set: objs = {objs} for o in objs: if o.includes(a): diff --git a/angr/storage/memory_mixins/paged_memory/stack_allocation_mixin.py b/angr/storage/memory_mixins/paged_memory/stack_allocation_mixin.py index 9fb8c75c52c..d4678bf4627 100644 --- a/angr/storage/memory_mixins/paged_memory/stack_allocation_mixin.py +++ b/angr/storage/memory_mixins/paged_memory/stack_allocation_mixin.py @@ -32,10 +32,12 @@ def allocate_stack_pages(self, addr: int, size: int, **kwargs): Pre-allocates pages for the stack without triggering any logic related to reading from them. :param addr: The highest address that should be mapped - :param size: The number of bytes to be allocated. byte 1 is the one at addr, byte 2 is the one before that, and so on. + :param size: The number of bytes to be allocated. byte 1 is the one at addr, byte 2 is the one before that, and + so on. :return: A list of the new page objects """ - # weird off-by-ones here. we want to calculate the last byte requested, find its pageno, and then use that to determine what the last page allocated will be and then how many pages are touched + # weird off-by-ones here. we want to calculate the last byte requested, find its pageno, and then use that to + # determine what the last page allocated will be and then how many pages are touched pageno = addr // self.page_size if pageno != self._red_pageno: raise SimMemoryError("Trying to allocate stack space in a place that isn't the top of the stack") diff --git a/angr/storage/memory_mixins/slotted_memory.py b/angr/storage/memory_mixins/slotted_memory.py index 38e5b61fb35..15a514245c0 100644 --- a/angr/storage/memory_mixins/slotted_memory.py +++ b/angr/storage/memory_mixins/slotted_memory.py @@ -48,8 +48,8 @@ def merge(self, others, merge_conditions, common_ancestor=None): def _resolve_access(self, addr, size): """ - Resolves a memory access of a certain size. Returns a sequence of the bases, offsets, and sizes of the accesses required - to fulfil this. + Resolves a memory access of a certain size. Returns a sequence of the bases, offsets, and sizes of the accesses + required to fulfil this. """ # if we fit in one word diff --git a/angr/type_backend.py b/angr/type_backend.py deleted file mode 100644 index 1d69abf546a..00000000000 --- a/angr/type_backend.py +++ /dev/null @@ -1,154 +0,0 @@ -import claripy - -from .sim_type import SimTypePointer as Ptr, SimTypeTop as Top - - -class TypedValue(claripy.BackendObject): - def __init__(self, ty, value): - self.ty = ty - self.value = value - - def __repr__(self): - return f"TypedValue({repr(self.ty)}, {repr(self.value)})" - - -class TypeBackend(claripy.Backend): - def __init__(self): - super().__init__(solver_required=False) - - self._op_expr["BVS"] = self._make_top - self._op_expr["BVV"] = self._make_top - - self._op_raw["__add__"] = self._do_add - self._op_raw["__sub__"] = self._do_sub - self._op_raw["__and__"] = self._do_and - self._op_raw["__or__"] = self._do_or - self._op_raw["__xor__"] = self._do_xor - - @staticmethod - def _make_top(ast, **kwargs): # pylint: disable=unused-argument - return TypedValue(Top(label=[]), ast) - - def _do_add(self, *args): - if len(args) != 2: - return reduce(self._do_add, args) - - a, b = args - good_a = type(a.ty) is Ptr - good_b = type(b.ty) is Ptr - val = a.value + b.value - out = TypedValue(Top(), val) - - if good_a: - if not good_b: - out.ty = Ptr(a.ty.pts_to, offset=a.ty.offset + b.value) - elif good_b: - out.ty = Ptr(b.ty.pts_to, offset=b.ty.offset + a.value) - else: - out.ty = Top() - - out.ty.label = a.ty.label + b.ty.label - return out - - def _do_and(self, *args): - if len(args) != 2: - return reduce(self._do_and, args) - - a, b = args - good_a = type(a.ty) is Ptr - good_b = type(b.ty) is Ptr - val = a.value & b.value - out = TypedValue(Top(), val) - - if good_a: - if not good_b: - out.ty = Ptr(a.ty.pts_to, offset=a.ty.offset & b.value) - elif good_b: - out.ty = Ptr(b.ty.pts_to, offset=b.ty.offset & a.value) - else: - out.ty = Top() - - out.ty.label = a.ty.label + b.ty.label - return out - - def _do_or(self, *args): - if len(args) != 2: - return reduce(self._do_or, args) - - a, b = args - good_a = type(a.ty) is Ptr - good_b = type(b.ty) is Ptr - val = a.value | b.value - out = TypedValue(Top(), val) - - if good_a: - if not good_b: - out.ty = Ptr(a.ty.pts_to, offset=a.ty.offset | b.value) - elif good_b: - out.ty = Ptr(b.ty.pts_to, offset=b.ty.offset | a.value) - else: - out.ty = Top(label=[]) - - out.ty.label = a.ty.label + b.ty.label - return out - - def _do_xor(self, *args): - if len(args) != 2: - return reduce(self._do_xor, args) - - a, b = args - good_a = type(a.ty) is Ptr - good_b = type(b.ty) is Ptr - val = a.value ^ b.value - out = TypedValue(Top(), val) - - if good_a: - if not good_b: - out.ty = Ptr(a.ty.pts_to, offset=a.ty.offset ^ b.value) - elif good_b: - out.ty = Ptr(b.ty.pts_to, offset=b.ty.offset ^ a.value) - else: - out.ty = Top() - - out.ty.label = a.ty.label + b.ty.label - return out - - def _do_sub(self, *args): - if len(args) != 2: - return reduce(self._do_sub, args) - - a, b = args - good_a = type(a.ty) is Ptr - good_b = type(b.ty) is Ptr - val = a.value - b.value - out = TypedValue(Top(None), val) - - if good_a and not good_b: - out.ty = Ptr(a.ty.pts_to, offset=a.ty.offset - b.value) - else: - out.ty = Top() - - out.ty.label = a.ty.label + b.ty.label - return out - - def apply_annotation(self, obj, a): - if type(a) is TypeAnnotation: - return TypedValue(a.ty, obj.value) - return obj - - @staticmethod - def default_op(expr): - return TypedValue(Top(label=[]), expr) - - -class TypeAnnotation(claripy.Annotation): - def __init__(self, ty): - self.ty = ty - - @property - def eliminatable(self): # pylint:disable=no-self-use - return False - - @property - def relocatable(self): # pylint:disable=no-self-use - return False diff --git a/angr/utils/timing.py b/angr/utils/timing.py index 52030566e76..dfa347a9802 100644 --- a/angr/utils/timing.py +++ b/angr/utils/timing.py @@ -1,5 +1,4 @@ # pylint:disable=no-member -import sys import time from functools import wraps from collections import defaultdict @@ -16,7 +15,10 @@ def timethis(func): @wraps(func) def timed_func(*args, **kwargs): if TIMING: - _t = lambda: time.perf_counter_ns() / 1000000 + + def _t(): + return time.perf_counter_ns() / 1000000 + start = _t() r = func(*args, **kwargs) millisec = _t() - start diff --git a/pyproject.toml b/pyproject.toml index 96bc03afade..33f32585e88 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -13,21 +13,31 @@ force-exclude = ''' ''' [tool.ruff] +line-length = 120 extend-ignore = [ - "F401", "F403", "E402", # No import checks + "E402", # Bottom imports "E741", # Variable names - "E731", # Allow lambdas - "E501", # No line length check - - # TODO: Enable these! - "F841", # dead code - # TODO: BUG! This hides bugs! - "F821", # name not found (maybe because we directly edit globals() or import later :( ) +] - "E712", "E713", "E714", "E722", # Code quality +exclude = [ + "*_pb2.py", # Autogenerated protobuf files ] -# TODO: BUG! This hides bugs! See: https://github.com/angr/angr/issues/3685 + [tool.ruff.per-file-ignores] -"angr/procedures/definitions/*" = ["F601"] +"angr/misc/bug_report.py" = [ + "F821", # name not found +] +"angr/procedures/definitions/*" = [ # TODO: Move to exclude + "F601", # TODO: BUG! This hides bugs! See: https://github.com/angr/angr/issues/3685 + "E501", # No line length check + "F401", +] +"angr/state_plugins/solver.py" = [ + "E501", # Long docstrings with examples + ] +"__init__.py" = [ + "F401", + "F403", +] diff --git a/setup.py b/setup.py index 1781ae71e11..315eebf9bba 100644 --- a/setup.py +++ b/setup.py @@ -1,5 +1,6 @@ # pylint: disable=missing-class-docstring import glob +import importlib import os import platform import shutil @@ -23,12 +24,12 @@ def _build_native(): try: - import pyvex # pylint:disable=unused-import,import-outside-toplevel + importlib.import_module("pyvex") except ImportError as e: raise LibError("You must install pyvex before building angr") from e try: - import unicorn # pylint:disable=unused-import,import-outside-toplevel + importlib.import_module("unicorn") except ImportError as e: raise LibError("You must install unicorn before building angr") from e diff --git a/tests/analyses/reaching_definitions/test_dep_graph.py b/tests/analyses/reaching_definitions/test_dep_graph.py index 1b7499b78cf..bf49903fae7 100644 --- a/tests/analyses/reaching_definitions/test_dep_graph.py +++ b/tests/analyses/reaching_definitions/test_dep_graph.py @@ -303,7 +303,7 @@ def test_add_dependencies_for_concrete_pointers_of_adds_a_definition_for_data_po self.assertEqual(nodes, [register_definition, memory_definition]) self.assertListEqual(predecessors, [memory_definition]) - def test_add_dependencies_for_concrete_pointers_of_does_nothing_if_data_pointed_to_by_definition_is_already_in_dependency_graph( + def test_add_dependencies_for_concrete_pointers_of_does_nothing_if_data_pointed_to_by_definition_is_already_in_dependency_graph( # noqa: E501 self, ): arch = self.ArchMock() @@ -358,7 +358,7 @@ def test_add_dependencies_for_concrete_pointers_of_does_nothing_if_pointer_is_no self.assertEqual(nodes_before_call, dependency_graph.nodes()) - def test_add_dependencies_for_concrete_pointers_of_create_memory_location_with_undefined_data_if_data_pointed_to_by_definition_is_not_known( + def test_add_dependencies_for_concrete_pointers_of_create_memory_location_with_undefined_data_if_data_pointed_to_by_definition_is_not_known( # noqa: E501 self, ): arch = self.ArchMock() @@ -394,7 +394,7 @@ def test_add_dependencies_for_concrete_pointers_of_create_memory_location_with_u self.assertEqual(nodes, [register_definition, memory_definition]) self.assertListEqual(predecessors, [memory_definition]) - def test_add_dependencies_for_concrete_pointers_of_adds_a_definition_with_codelocation_in_binary_if_data_in_readonly_memory( + def test_add_dependencies_for_concrete_pointers_of_adds_a_definition_with_codelocation_in_binary_if_data_in_readonly_memory( # noqa: E501 self, ): arch = self.ArchMock() diff --git a/tests/broken_variableseekr.py b/tests/broken_variableseekr.py deleted file mode 100644 index a5c08a45141..00000000000 --- a/tests/broken_variableseekr.py +++ /dev/null @@ -1,205 +0,0 @@ -#!/usr/bin/env python - -import logging - -l = logging.getLogger("angr.tests") - -import nose -import angr -from angr import AngrError - - -# load the tests -import os - -test_location = os.path.dirname(os.path.realpath(__file__)) -projects = {} -projects["fauxwares"] = {} -projects["cfg_1"] = {} -projects["allcmps"] = {} -projects["basic_buffer_overflows"] = {} -projects["uninitialized_reads"] = {} - - -def setup_x86(): - fauxware = projects["fauxwares"] - fauxware["x86"] = angr.Project(test_location + "/blob/i386/fauxware", arch="X86") - - -def setup_amd64(): - fauxware = projects["fauxwares"] - cfg_1 = projects["cfg_1"] - all_cmps = projects["allcmps"] - basic_buffer_overflows = projects["basic_buffer_overflows"] - uninitialized_reads = projects["uninitialized_reads"] - - fauxware["amd64"] = angr.Project(test_location + "/blob/x86_64/fauxware", arch="AMD64") - cfg_1["amd64"] = angr.Project(test_location + "/blob/x86_64/cfg_1", arch="AMD64") - all_cmps["amd64"] = angr.Project(test_location + "/blob/x86_64/allcmps", arch="AMD64") - basic_buffer_overflows["amd64"] = angr.Project(test_location + "/blob/x86_64/basic_buffer_overflows") - uninitialized_reads["amd64"] = angr.Project(test_location + "/blob/x86_64/uninitialized_reads") - - -def setup_ppc32(): - fauxware = projects["fauxwares"] - fauxware["ppc32"] = angr.Project(test_location + "/blob/ppc/fauxware", arch="PPC32") - - -def setup_mipsel(): - fauxware = projects["fauxwares"] - fauxware["mipsel"] = angr.Project(test_location + "/blob/mipsel/fauxware", arch=angr.SimMIPS32(endness="Iend_LE")) - - -def setup_arm(): - fauxware = projects["fauxwares"] - fauxware["arm"] = angr.Project(test_location + "/blob/armel/fauxware", arch=angr.SimARM(endness="Iend_LE")) - - -def setup_module(): - setup_x86() - setup_amd64() - setup_arm() - setup_ppc32() - setup_mipsel() - - -def test_fauxware(arch, start): - fauxware = projects["fauxwares"] - cfg = fauxware[arch].analyses.CFG() - vfg = fauxware[arch].analyses.VFG(start=start) - variable_seekr = angr.VariableSeekr(fauxware[arch], cfg, vfg) - variable_seekr.construct(func_start=start) - function_manager = cfg.function_manager - for func_addr, _ in function_manager.functions.items(): - l.info("Function %08xh", func_addr) - variable_manager = variable_seekr.get_variable_manager(func_addr) - if variable_manager is None: - continue - # TODO: Check the result returned - l.info("Variables: ") - for var in variable_manager.variables: - if isinstance(var, angr.StackVariable): - l.info(var.detail_str()) - else: - l.info("%s(%d), referenced at %08x", var, var._size, var._inst_addr) - - -def test_cfg_1(arch, start): - cfg_1 = projects["cfg_1"] - cfg = cfg_1[arch].analyses.CFG() - vfg = cfg_1[arch].analyses.VFG(start=start) - variable_seekr = angr.VariableSeekr(cfg_1[arch], cfg, vfg) - variable_seekr.construct(func_start=start) - function_manager = cfg.function_manager - for func_addr, _ in function_manager.functions.items(): - l.info("Function %08xh", func_addr) - variable_manager = variable_seekr.get_variable_manager(func_addr) - if variable_manager is None: - continue - # TODO: Check the result returned - l.info("Variables: ") - for var in variable_manager.variables: - if isinstance(var, angr.StackVariable): - l.info(var.detail_str()) - else: - l.info("%s(%d), referenced at %08x", var, var._size, var._inst_addr) - - -def test_allcmps(arch, starts): - allcmps = projects["allcmps"] - cfg = allcmps[arch].analyses.CFG() - for start in starts: - allcmps[arch].analyses.VFG(start=start) - vfg = allcmps[arch].vfg - variable_seekr = angr.VariableSeekr(allcmps[arch], cfg, vfg) - - for start in starts: - variable_seekr.construct(func_start=start) - function_manager = cfg.function_manager - for func_addr, _ in function_manager.functions.items(): - l.info("Function %xh", func_addr) - variable_manager = variable_seekr.get_variable_manager(func_addr) - if variable_manager is None: - continue - # TODO: Check the result returned - l.info("Variables: ") - for var in variable_manager.variables: - if isinstance(var, angr.StackVariable): - l.info(var.detail_str()) - else: - l.info("%s(%d), referenced at %08x", var, var._size, var._inst_addr) - - -def test_basic_buffer_overflows(arch, starts): - basic_buffer_overflows = projects["basic_buffer_overflows"] - cfg = basic_buffer_overflows[arch].analyses.CFG() - for start in starts: - basic_buffer_overflows[arch].analyses.VFG(start=start) - vfg = basic_buffer_overflows[arch].vfg - variable_seekr = angr.VariableSeekr(basic_buffer_overflows[arch], cfg, vfg) - - for start in starts: - variable_seekr.construct(func_start=start) - function_manager = cfg.function_manager - for func_addr, _ in function_manager.functions.items(): - l.info("Function %xh", func_addr) - variable_manager = variable_seekr.get_variable_manager(func_addr) - if variable_manager is None: - continue - # TODO: Check the result returned - l.info("Variables: ") - for var in variable_manager.variables: - if isinstance(var, angr.StackVariable): - l.info(var.detail_str()) - else: - l.info("%s(%d), referenced at %08x", var, var._size, var._inst_addr) - - -def test_uninitialized_reads(arch, starts): - uninitialized_reads = projects["uninitialized_reads"] - cfg = uninitialized_reads[arch].analyses.CFG() - for start in starts: - uninitialized_reads[arch].analyses.VFG(start=start) - vfg = uninitialized_reads[arch].vfg - variable_seekr = angr.VariableSeekr(uninitialized_reads[arch], cfg, vfg) - - for start in starts: - try: - variable_seekr.construct(func_start=start) - except AngrError: - l.info("AngrError...") - continue - function_manager = cfg.function_manager - for func_addr, _ in function_manager.functions.items(): - l.info("Function %xh", func_addr) - variable_manager = variable_seekr.get_variable_manager(func_addr) - if variable_manager is None: - continue - # TODO: Check the result returned - l.info("Variables: ") - for var in variable_manager.variables: - if isinstance(var, angr.StackVariable): - l.info(var.detail_str()) - else: - l.info("%s(%d), referenced at %08x", var, var._size, var._inst_addr) - - -if __name__ == "__main__": - try: - __import__("standard_logging") - __import__("angr_debug") - except ImportError: - pass - - logging.getLogger("angr.cfg").setLevel(logging.DEBUG) - logging.getLogger("angr.vfg").setLevel(logging.DEBUG) - logging.getLogger("angr.state_plugins.symbolic_memory").setLevel(logging.INFO) - # logging.getLogger('angr.state_plugins.abstract_memory').setLevel(logging.DEBUG) - logging.getLogger("claripy.claripy").setLevel(logging.ERROR) - l.setLevel(logging.DEBUG) - setup_amd64() - l.info("LOADED") - # test_fauxware('amd64', 0x40071d) - # test_basic_buffer_overflows('amd64', (0x40068f, 0x40055c, 0x4005b6, 0x40063e)) - test_uninitialized_reads("amd64", (0x40052C, 0x40056C)) - l.info("DONE") diff --git a/tests/common.py b/tests/common.py index 902f40ab820..443173bff5a 100644 --- a/tests/common.py +++ b/tests/common.py @@ -21,7 +21,8 @@ if not os.path.isdir(bin_location): raise Exception( - "Can't find the angr/binaries repo for holding testcases. It should be cloned into the same folder as the rest of your angr modules." + "Can't find the angr/binaries repo for holding testcases. " + "It should be cloned into the same folder as the rest of your angr modules." ) diff --git a/tests/knowledge_plugins/key_definitions/test_environment.py b/tests/knowledge_plugins/key_definitions/test_environment.py index bfee3541620..ac08ac5a6f7 100644 --- a/tests/knowledge_plugins/key_definitions/test_environment.py +++ b/tests/knowledge_plugins/key_definitions/test_environment.py @@ -2,7 +2,6 @@ import claripy -from angr.knowledge_plugins.key_definitions.atoms import SpOffset from angr.knowledge_plugins.key_definitions.environment import Environment from angr.knowledge_plugins.key_definitions.undefined import UNDEFINED diff --git a/tests/knowledge_plugins/key_definitions/test_live_definitions.py b/tests/knowledge_plugins/key_definitions/test_live_definitions.py index e022a0c9594..7cff7889593 100644 --- a/tests/knowledge_plugins/key_definitions/test_live_definitions.py +++ b/tests/knowledge_plugins/key_definitions/test_live_definitions.py @@ -1,7 +1,6 @@ from unittest import TestCase import archinfo -import claripy from angr.storage.memory_mixins.paged_memory.pages.multi_values import MultiValues from angr.knowledge_plugins.key_definitions.atoms import Register, SpOffset diff --git a/tests/test_cfg_manager.py b/tests/test_cfg_manager.py index d155e5ee185..c9bce344aa8 100644 --- a/tests/test_cfg_manager.py +++ b/tests/test_cfg_manager.py @@ -22,7 +22,7 @@ def test_cfg_manager_copies_cfg_graphs(self): assert original_graph.edges() == new_graph.edges() assert original_graph.nodes() == new_graph.nodes() - assert not original_graph is new_graph + assert original_graph is not new_graph if __name__ == "__main__": diff --git a/tests/test_cfgemulated.py b/tests/test_cfgemulated.py index 0552d1ad809..8d8c36de1f4 100644 --- a/tests/test_cfgemulated.py +++ b/tests/test_cfgemulated.py @@ -185,7 +185,7 @@ def test_not_returning(self): binary_path = os.path.join(test_location, "x86_64", "not_returning") proj = angr.Project(binary_path, use_sim_procedures=True, load_options={"auto_load_libs": False}) - cfg = proj.analyses.CFGEmulated(context_sensitivity_level=0, fail_fast=True) # pylint:disable=unused-variable + proj.analyses.CFGEmulated(context_sensitivity_level=0, fail_fast=True) # pylint:disable=unused-variable # function_a returns assert proj.kb.functions.function(name="function_a") is not None @@ -270,7 +270,7 @@ def test_cfg_6(self): o.modes["fastpath"] |= {o.DO_CCALLS} binary_path = test_location + "/i386/bios.bin.elf" proj = angr.Project(binary_path, use_sim_procedures=True, page_size=1, auto_load_libs=False) - cfg = proj.analyses.CFGEmulated(context_sensitivity_level=1, fail_fast=True) # pylint:disable=unused-variable + proj.analyses.CFGEmulated(context_sensitivity_level=1, fail_fast=True) # pylint:disable=unused-variable assert {f for f in proj.kb.functions} >= set(function_addresses) o.modes["fastpath"] ^= {o.DO_CCALLS} @@ -425,18 +425,18 @@ def test_armel_final_missing_block(self): def test_armel_final_missing_block_b(self): # When _pending_jobs is not sorted, it is possible that we first process a pending job created earlier and then - # process another pending job created later. Ideally, we hope that jobs are always processed in a topological order, - # and the unsorted pending jobs break this assumption. In this test binary, at one point there can be two pending - # jobs, 0x10b05/0x10ac5(Ijk_FakeRet) and 0x10bbe(Ijk_FakeRet). If 0x10bbe is processed before 0x10b05, we do not - # know whether the function 0x10a29(aes) returns or not. As a result, the final block of the main function is not - # confirmed, and is not added to the function graph of function main. + # process another pending job created later. Ideally, we hope that jobs are always processed in a topological + # order, and the unsorted pending jobs break this assumption. In this test binary, at one point there can be two + # pending jobs, 0x10b05/0x10ac5(Ijk_FakeRet) and 0x10bbe(Ijk_FakeRet). If 0x10bbe is processed before 0x10b05, + # we do not # know whether the function 0x10a29(aes) returns or not. As a result, the final block of the main + # function is not confirmed, and is not added to the function graph of function main. # - # In fact, this also hints a different bug. We should always "confirm" that a function returns if its FakeRet job - # are processed for whatever reason. + # In fact, this also hints a different bug. We should always "confirm" that a function returns if its FakeRet + # job are processed for whatever reason. # - # Fixing either bug will resolve the issue that the final block does not show up in the function graph of main. To - # stay on the safe side, both of them are fixed. Thanks @tyb0807 for reporting this issue and providing a test - # binary. + # Fixing either bug will resolve the issue that the final block does not show up in the function graph of main. + # To stay on the safe side, both of them are fixed. Thanks @tyb0807 for reporting this issue and providing a + # test binary. # EDG says: This binary is compiled incorrectly. # The binary's app code was compiled as CortexM, but linked against ARM libraries. # This is illegal, and does not actually execute on a real CortexM. diff --git a/tests/test_ctype_locale.py b/tests/test_ctype_locale.py index 9daf944e6ba..08cb898369a 100644 --- a/tests/test_ctype_locale.py +++ b/tests/test_ctype_locale.py @@ -38,9 +38,9 @@ def test_ctype_b_loc(self): # libc_start_main bin_path = os.path.join(test_location, "..", "..", "binaries", "tests", "x86_64", "ctype_b_loc") - ctype_b_loc = lambda state, arguments: angr.SIM_PROCEDURES["glibc"]["__ctype_b_loc"]().execute( - state, arguments=arguments - ) + def ctype_b_loc(state, arguments): + return angr.SIM_PROCEDURES["glibc"]["__ctype_b_loc"]().execute(state, arguments=arguments) + b = angr.Project(bin_path, auto_load_libs=False) p = b.factory.full_init_state() pg = b.factory.simulation_manager(p) @@ -87,9 +87,9 @@ def test_ctype_tolower_loc(self): # libc_start_main bin_path = os.path.join(test_location, "..", "..", "binaries", "tests", "x86_64", "ctype_tolower_loc") - ctype_tolower_loc = lambda state, arguments: angr.SIM_PROCEDURES["glibc"]["__ctype_tolower_loc"]().execute( - state, arguments=arguments - ) + def ctype_tolower_loc(state, arguments): + return angr.SIM_PROCEDURES["glibc"]["__ctype_tolower_loc"]().execute(state, arguments=arguments) + b = angr.Project(bin_path, auto_load_libs=False) p = b.factory.full_init_state() pg = b.factory.simulation_manager(p) @@ -136,9 +136,8 @@ def test_ctype_toupper_loc(self): # libc_start_main bin_path = os.path.join(test_location, "..", "..", "binaries", "tests", "x86_64", "ctype_toupper_loc") - ctype_toupper_loc = lambda state, arguments: angr.SIM_PROCEDURES["glibc"]["__ctype_toupper_loc"]().execute( - state, arguments=arguments - ) + def ctype_toupper_loc(state, arguments): + return angr.SIM_PROCEDURES["glibc"]["__ctype_toupper_loc"]().execute(state, arguments=arguments) b = angr.Project(bin_path, auto_load_libs=False) p = b.factory.full_init_state() diff --git a/tests/test_decompiler.py b/tests/test_decompiler.py index 9426cb0e1b2..08013d7f1ac 100644 --- a/tests/test_decompiler.py +++ b/tests/test_decompiler.py @@ -81,9 +81,7 @@ def test_decompiling_all_x86_64(self, decompiler_options=None): if f.is_simprocedure: l.debug("Skipping SimProcedure %s.", repr(f)) continue - dec = p.analyses[Decompiler].prep()( - f, cfg=cfg.model, options=decompiler_options - ) # pylint: disable=unused-variable + p.analyses[Decompiler].prep()(f, cfg=cfg.model, options=decompiler_options) # FIXME: This test does not pass # assert dec.codegen is not None, "Failed to decompile function %s." % repr(f) # self._print_decompilation_result(dec) @@ -1832,7 +1830,7 @@ def test_decompiling_remove_write_protected_non_symlink(self, decompiler_options @structuring_algo("phoenix") def test_decompiling_split_lines_split(self, decompiler_options=None): - # region identifier's fine-tuned loop refinement logic ensures there is only one goto statement in the + # Region identifier's fine-tuned loop refinement logic ensures there is only one goto statement in the # decompilation output. bin_path = os.path.join(test_location, "x86_64", "decompiler", "split.o") proj = angr.Project(bin_path, auto_load_libs=False) @@ -2213,7 +2211,7 @@ def test_complex_stack_offset_calculation(self, decompiler_options=None): # The highest level symptom here is that two variable used are # confused and this shows up in the addition types. - assert not "Other Possible Types" in d.codegen.text + assert "Other Possible Types" not in d.codegen.text # check that the variable used in free is different from the one used in atoi m = re.search(r"free\(([^)]+)", d.codegen.text) diff --git a/tests/test_driller_core.py b/tests/test_driller_core.py index 0b21173a6ac..d9b126bca4c 100644 --- a/tests/test_driller_core.py +++ b/tests/test_driller_core.py @@ -1,6 +1,5 @@ # pylint: disable=missing-class-docstring,disable=no-self-use import os -import logging import unittest from common import bin_location diff --git a/tests/test_function_manager.py b/tests/test_function_manager.py index 6bcd3c0342c..b0db49a9075 100644 --- a/tests/test_function_manager.py +++ b/tests/test_function_manager.py @@ -62,7 +62,7 @@ def test_amd64(self): None, } - cfg = self.project.analyses.CFGEmulated() # pylint:disable=unused-variable + self.project.analyses.CFGEmulated() assert {k for k in self.project.kb.functions.keys() if k < 0x500000} == expected_functions main = self.project.kb.functions.function(name="main") @@ -75,7 +75,7 @@ def test_amd64(self): assert main.has_return rejected = self.project.kb.functions.function(name="rejected") - assert rejected.returning == False + assert rejected.returning is False # transition graph main_g = main.transition_graph diff --git a/tests/test_hook.py b/tests/test_hook.py index 5d3380e92ed..c72b82e06a5 100644 --- a/tests/test_hook.py +++ b/tests/test_hook.py @@ -69,8 +69,8 @@ def one_time_hook(self, _): s.run() def test_nonzero_length_userhook(self): - # If a user hook overwrites any instruction (length > 0), we should allow the execution of another hook that follows - # this hook immediately. + # If a user hook overwrites any instruction (length > 0), we should allow the execution of another hook that + # follows this hook immediately. class TwoTimesHook: def __init__(self): diff --git a/tests/test_inspect.py b/tests/test_inspect.py index 1d0f9a4735e..f50652033b2 100644 --- a/tests/test_inspect.py +++ b/tests/test_inspect.py @@ -257,7 +257,6 @@ def test_inspect_engine_process(self): ), auto_load_libs=False, ) - constraints = [] def check_first_symbolic_fork(state): succs = state.inspect.sim_successors.successors diff --git a/tests/test_java.py b/tests/test_java.py index faac1d10fc2..f29cd8469f0 100644 --- a/tests/test_java.py +++ b/tests/test_java.py @@ -13,7 +13,7 @@ SootArgument, SootAddressTerminator, ) -from claripy.backends.backend_smtlib_solvers import z3str_popen # pylint:disable=unused-import +from claripy.backends.backend_smtlib_solvers import z3str_popen # noqa: F401 try: import pysoot diff --git a/tests/test_jumptables.py b/tests/test_jumptables.py index 9eccb07cdde..38b22ec82ed 100644 --- a/tests/test_jumptables.py +++ b/tests/test_jumptables.py @@ -2421,8 +2421,8 @@ def test_s390x_cfgswitches(self): self._compare(cfg.jump_tables, all_jumptables) def test_arm_libsoap(self): - # This is the ADDLS type of jump table (IndirectJumpType.JumpTable_AddressComputed) where no actual table is used - # libsoap.so seems to be compiled from gSOAP, which is an open-source product + # This is the ADDLS type of jump table (IndirectJumpType.JumpTable_AddressComputed) where no actual table is + # used libsoap.so seems to be compiled from gSOAP, which is an open-source product p = angr.Project(os.path.join(test_location, "armel", "libsoap.so"), auto_load_libs=False) cfg = p.analyses.CFGFast(data_references=True) @@ -2549,8 +2549,8 @@ def test_arm_libsoap(self): ], ), J(0x41B0B4, None, [0x41B0C4, 0x41B0C8, 0x41B0CC, 0x41B0D0, 0x41B0D4]), - # 0x41d0e8 and 0x41d0fc are the same jump table - they appear twice because the CFG is not normalized (the two - # blocks 0x41d0e8 and 0x41d0fc overlap and end at the same instruction) + # 0x41d0e8 and 0x41d0fc are the same jump table - they appear twice because the CFG is not normalized + # (the two blocks 0x41d0e8 and 0x41d0fc overlap and end at the same instruction) J( 0x41D0E8, None, diff --git a/tests/test_keystone.py b/tests/test_keystone.py index 1fa9ca9592c..a1902f5a3a5 100644 --- a/tests/test_keystone.py +++ b/tests/test_keystone.py @@ -3,8 +3,6 @@ import sys import unittest -from common import skip_if_not_linux - import angr l = logging.getLogger("angr.tests") diff --git a/tests/test_lseek.py b/tests/test_lseek.py index fc7f845d181..b5abced4fa1 100644 --- a/tests/test_lseek.py +++ b/tests/test_lseek.py @@ -1,4 +1,3 @@ -import archinfo import unittest import logging @@ -11,7 +10,10 @@ FAKE_ADDR = 0x100000 -lseek = lambda state, arguments: SIM_PROCEDURES["linux_kernel"]["lseek"]().execute(state, arguments=arguments) + +def lseek(state, arguments): + return SIM_PROCEDURES["linux_kernel"]["lseek"]().execute(state, arguments=arguments) + # Taken from unistd.h SEEK_SET = 0 # Seek from beginning of file. diff --git a/tests/test_ops.py b/tests/test_ops.py index f046eea887d..7062cc624e8 100644 --- a/tests/test_ops.py +++ b/tests/test_ops.py @@ -1,6 +1,5 @@ import angr import claripy -import archinfo # all the input values were generated via # [random.randrange(256) for _ in range(16)] diff --git a/tests/test_pickle.py b/tests/test_pickle.py index 7813a12b091..991b6487133 100644 --- a/tests/test_pickle.py +++ b/tests/test_pickle.py @@ -1,3 +1,4 @@ +from contextlib import suppress from claripy import BVS from angr.storage import SimFile import pickle @@ -13,33 +14,20 @@ class TestPickle(unittest.TestCase): @classmethod def tearDown(self): - # pylint: disable=bare-except - try: - shutil.rmtree("pickletest") - except: - pass - try: - shutil.rmtree("pickletest2") - except: - pass - try: + shutil.rmtree("pickletest", ignore_errors=True) + shutil.rmtree("pickletest2", ignore_errors=True) + with suppress(FileNotFoundError): os.remove("pickletest_good") - except: - pass - try: + with suppress(FileNotFoundError): os.remove("pickletest_bad") - except: - pass def _load_pickles(self): # This is the working case f = open("pickletest_good", "rb") - print(pickle.load(f)) f.close() # This will not work f = open("pickletest_bad", "rb") - print(pickle.load(f)) f.close() def _make_pickles(self): @@ -49,7 +37,6 @@ def _make_pickles(self): "/dev/stdin": SimFile("/dev/stdin"), "/dev/stdout": SimFile("/dev/stdout"), "/dev/stderr": SimFile("/dev/stderr"), - # '/dev/urandom': SimFile('/dev/urandom', 0), } MEM_SIZE = 1024 @@ -57,24 +44,20 @@ def _make_pickles(self): for f in fs: mem = BVS(f, MEM_SIZE * 8) mem_bvv[f] = mem - # debug_wait() f = open("pickletest_good", "wb") - # fname = f.name pickle.dump(mem_bvv, f, -1) f.close() # If you do not have a state you cannot write - entry_state = p.factory.entry_state(fs=fs) # pylint:disable=unused-variable + _ = p.factory.entry_state(fs=fs) for f in fs: mem = mem_bvv[f] fs[f].write(0, mem, MEM_SIZE) f = open("pickletest_bad", "wb") - # fname = f.name pickle.dump(mem_bvv, f, -1) f.close() - # print "Test case generated run '%s ' to execute the test" % sys.argv[0] def test_pickling(self): self._make_pickles() @@ -86,8 +69,8 @@ def test_project_pickling(self): # AnalysesHub should not be pickled together with the project itself p = angr.Project(os.path.join(tests_location, "i386", "fauxware")) - # make a copy of the active_preset so that we do not touch the global preset object. this is only for writing this - # test case. + # make a copy of the active_preset so that we do not touch the global preset object. this is only for writing + # this test case. p.analyses._active_preset = pickle.loads(pickle.dumps(p.analyses._active_preset, -1)) assert len(p.analyses._active_preset._default_plugins) > 0 p.analyses._active_preset = p.analyses._active_preset diff --git a/tests/test_proximitygraph.py b/tests/test_proximitygraph.py index 63dcac5e745..9854cf5f85b 100644 --- a/tests/test_proximitygraph.py +++ b/tests/test_proximitygraph.py @@ -12,11 +12,11 @@ def test_fauxware(): cfg = proj.analyses.CFG(data_references=True, cross_references=True, normalize=True) func = cfg.kb.functions["main"] - prox = proj.analyses.Proximity(func, cfg.model, cfg.kb.xrefs) # pylint:disable=unused-variable + proj.analyses.Proximity(func, cfg.model, cfg.kb.xrefs) # once we have decompiled code, things are different... dec = proj.analyses.Decompiler(func, cfg=cfg.model) - prox = proj.analyses.Proximity(func, cfg.model, cfg.kb.xrefs, decompilation=dec) # pylint:disable=unused-variable + proj.analyses.Proximity(func, cfg.model, cfg.kb.xrefs, decompilation=dec) if __name__ == "__main__": diff --git a/tests/test_scanf.py b/tests/test_scanf.py index d0b2c49ca55..d7dea502315 100644 --- a/tests/test_scanf.py +++ b/tests/test_scanf.py @@ -187,7 +187,7 @@ def test_scanf_multi(self): # check the outputs total_outputs = 0 for path in pg.found: - test_input = path.posix.dumps(0) + path.posix.dumps(0) test_output = path.posix.dumps(1) if test_output in expected_outputs: assert expected_outputs[test_output].check(path), "Test case failed. Output is %s." % test_output diff --git a/tests/test_serialization.py b/tests/test_serialization.py index 4d9670a54e8..0692bdd14ef 100644 --- a/tests/test_serialization.py +++ b/tests/test_serialization.py @@ -54,7 +54,7 @@ def internaltest_cfgfast(p): # generate capstone blocks main_function = cfg.functions.function(name="main") for b in main_function.blocks: - c = b.capstone # pylint:disable=unused-variable + b.capstone pickle.dump(cfg, state, -1) diff --git a/tests/test_sim_procedure.py b/tests/test_sim_procedure.py index 65bebdcd6ff..852c6ab92af 100644 --- a/tests/test_sim_procedure.py +++ b/tests/test_sim_procedure.py @@ -1,6 +1,5 @@ import os import angr -import claripy from angr.codenode import BlockNode, HookNode, SyscallNode BIN_PATH = os.path.join(os.path.dirname(os.path.realpath(__file__)), "..", "..", "binaries") diff --git a/tests/test_spiller.py b/tests/test_spiller.py index 25f4621eb20..7e5bd06f77b 100644 --- a/tests/test_spiller.py +++ b/tests/test_spiller.py @@ -3,6 +3,7 @@ import os import gc import unittest +import claripy def _bin(*s): @@ -24,9 +25,8 @@ def priority_key(state): class TestSpiller(unittest.TestCase): @classmethod def setUp(self): - # clean up AST cache in claripy, because a cached AST might believe it has been stored in ana after we clean up the - # ana storage - import claripy # pylint:disable=import-outside-toplevel + # clean up AST cache in claripy, because a cached AST might believe it + # has been stored in ana after we clean up the ana storage claripy.ast.bv._bvv_cache.clear() claripy.ast.bv.BV._hash_cache.clear() diff --git a/tests/test_state.py b/tests/test_state.py index c05fb7df238..f2bc744c177 100644 --- a/tests/test_state.py +++ b/tests/test_state.py @@ -152,9 +152,9 @@ def test_state_merge_3way(self): assert m.satisfiable(extra_constraints=(m.memory.load(0x400000, 4) == 10,)) def test_state_merge_optimal_nostrongrefstate(self): - # We do not specify the state option EFFICIENT_STATE_MERGING, and as a result, state histories do not store strong - # references to states. This will result in less efficient state merging since SimStateHistory will be the only - # state plugin that knows the common ancestor of all instances to merge. But it should still succeed. + # We do not specify the state option EFFICIENT_STATE_MERGING, and as a result, state histories do not store + # strong # references to states. This will result in less efficient state merging since SimStateHistory will be + # the only # state plugin that knows the common ancestor of all instances to merge. But it should still succeed. binary_path = os.path.join(binaries_base, "tests", "x86_64", "state_merge_0") p = angr.Project(binary_path, auto_load_libs=False) diff --git a/tests/test_string.py b/tests/test_string.py index e63ab669759..8ed6e26182a 100644 --- a/tests/test_string.py +++ b/tests/test_string.py @@ -624,15 +624,15 @@ def test_strcpy(): s.add_constraints(ln == 15) # readsize = 16 - # both_strs = s.solver.Concat(*[ s.memory.load(dst_addr, readsize, endness='Iend_BE'), s.memory.load(src_addr, readsize, endness='Iend_BE') ]) + # both_strs = s.solver.Concat( + # *[s.memory.load(dst_addr, readsize, endness="Iend_BE"), s.memory.load(src_addr, readsize, endness="Iend_BE")] + # ) # for i in s.solver.eval_upto(both_strs, 50, cast_to=bytes): - - # print c.solver.eval_upto(10) - # assert c.solver.eval_upto(10) == [0] - # assert s.solver.solution(s.memory.load(dst_addr, 4, endness='Iend_BE'), 0x42434400) - # assert s.solver.solution(s.memory.load(dst_addr, 4, endness='Iend_BE'), 0x42434445) - # assert s.solver.solution(s.memory.load(dst_addr, 4, endness='Iend_BE'), 0x00414100) - # assert not s.solver.solution(s.memory.load(dst_addr, 4, endness='Iend_BE'), 0x00010203) + # assert s.solver.eval_upto(10) == [0] + # assert s.solver.solution(s.memory.load(dst_addr, 4, endness="Iend_BE"), 0x42434400) + # assert s.solver.solution(s.memory.load(dst_addr, 4, endness="Iend_BE"), 0x42434445) + # assert s.solver.solution(s.memory.load(dst_addr, 4, endness="Iend_BE"), 0x00414100) + # assert not s.solver.solution(s.memory.load(dst_addr, 4, endness="Iend_BE"), 0x00010203) def broken_sprintf(): diff --git a/tests/test_structurer.py b/tests/test_structurer.py index 0639dc7bf15..7ed172458df 100644 --- a/tests/test_structurer.py +++ b/tests/test_structurer.py @@ -117,7 +117,7 @@ def test_smoketest(): ri = p.analyses.RegionIdentifier(main_func, graph=clinic.graph) # structure it - st = p.analyses[DreamStructurer].prep()(ri.region) # pylint:disable=unused-variable + st = p.analyses[DreamStructurer].prep()(ri.region) # simplify it _ = p.analyses.RegionSimplifier(main_func, st.result) @@ -140,7 +140,7 @@ def test_smoketest_cm3_firmware(): ri = p.analyses.RegionIdentifier(main_func, graph=clinic.graph) # structure it - st = p.analyses[DreamStructurer].prep()(ri.region) # pylint:disable=unused-variable + p.analyses[DreamStructurer].prep()(ri.region) def test_simple(): diff --git a/tests/test_syscall_result.py b/tests/test_syscall_result.py index b4e6ed58ee8..86909f62207 100644 --- a/tests/test_syscall_result.py +++ b/tests/test_syscall_result.py @@ -2,9 +2,6 @@ import logging -from angr.procedures.stubs.ReturnUnconstrained import ReturnUnconstrained -from angr.simos import SimUserland - l = logging.getLogger("angr.tests") import os diff --git a/tests/test_tracer.py b/tests/test_tracer.py index 593d97290cb..4ac38f2643d 100644 --- a/tests/test_tracer.py +++ b/tests/test_tracer.py @@ -337,7 +337,7 @@ def test_cgc_se1_palindrome_raw(): b"\tPlease enter a possible palindrome: " ) # make sure there were no 'Nope's from non-palindromes - assert not b"Nope" in stdout_dump + assert b"Nope" not in stdout_dump # now test crashing input simgr, _ = tracer_cgc(b, "tracer_cgc_se1_palindrome_raw_yescrash", b"A" * 129) diff --git a/tests/test_types.py b/tests/test_types.py index df054b27b53..f61e798998c 100644 --- a/tests/test_types.py +++ b/tests/test_types.py @@ -1,9 +1,6 @@ -# pylint:disable=unused-variable - from typing import Dict import archinfo -import claripy import angr from angr.sim_type import ( @@ -25,19 +22,6 @@ from angr.utils.library import convert_cproto_to_py, convert_cppproto_to_py -def test_type_annotation(): - my_ty = angr.sim_type.SimTypeTop() - ptr = claripy.BVS("ptr", 32).annotate( - angr.type_backend.TypeAnnotation(angr.sim_type.SimTypePointer(my_ty, label=[])) - ) - ptroffset = ptr + 4 - - bt = angr.type_backend.TypeBackend() - tv = bt.convert(ptroffset) - assert tv.ty.pts_to is my_ty - assert claripy.is_true(tv.ty.offset == 4) - - def test_cproto_conversion(): # A normal function declaration cproto_0 = "int main(int argc, char** argv);" @@ -51,9 +35,9 @@ def test_cproto_conversion(): assert isinstance(pyproto.returnty, SimTypeInt) # Directly comparing the strings... how bad can I be? - assert ( - the_str - == '# int main(int argc, char** argv);\n"main": SimTypeFunction([SimTypeInt(signed=True), SimTypePointer(SimTypePointer(SimTypeChar(), offset=0), offset=0)], SimTypeInt(signed=True), arg_names=["argc", "argv"]),' + assert the_str == ( + '# int main(int argc, char** argv);\n"main": SimTypeFunction([SimTypeInt(signed=True), SimTypePointer(' + 'SimTypePointer(SimTypeChar(), offset=0), offset=0)], SimTypeInt(signed=True), arg_names=["argc", "argv"]),' ) # A bad function declaration @@ -73,7 +57,10 @@ def test_cproto_conversion(): def test_cppproto_conversion(): # a demangled class constructor prototype, without parameter names - proto_0 = "std::basic_ifstream>::{ctor}(std::__cxx11::basic_string, std::allocator> const&, std::_Ios_Openmode)" + proto_0 = ( + "std::basic_ifstream>::{ctor}(std::__cxx11::basic_string, std::allocator> const&, std::_Ios_Openmode)" + ) name, proto, s = convert_cppproto_to_py(proto_0, with_param_names=False) assert proto.ctor is True assert name == "std::basic_ifstream::__ctor__" @@ -240,7 +227,8 @@ def test_arg_names(): nsig = sig.with_arch(angr.archinfo.ArchAMD64()) assert sig.arg_names == nsig.arg_names, "Function type generated with .with_arch() doesn't have identical arg_names" - # If for some reason only some of the parameters are named, the list can only be partially not None, but has to match the positions + # If for some reason only some of the parameters are named, + # the list can only be partially not None, but has to match the positions fdef: Dict[str, SimTypeFunction] = angr.types.parse_defns("int f(int param1, int);") sig = fdef["f"] assert sig.arg_names == ["param1", None] @@ -308,7 +296,6 @@ def test_bitfield_struct(): if __name__ == "__main__": - test_type_annotation() test_cproto_conversion() test_cppproto_conversion() test_struct_deduplication() diff --git a/tests/test_unicorn.py b/tests/test_unicorn.py index 2902437a485..cc41c131b43 100644 --- a/tests/test_unicorn.py +++ b/tests/test_unicorn.py @@ -377,9 +377,21 @@ def test_concrete_transmits(): pg_unicorn = p.factory.simulation_manager(s_unicorn) pg_unicorn.run(n=10) - assert ( - pg_unicorn.one_active.posix.dumps(1) - == b"1) Add number to the array\n2) Add random number to the array\n3) Sum numbers\n4) Exit\nRandomness added\n1) Add number to the array\n2) Add random number to the array\n3) Sum numbers\n4) Exit\n Index: \n1) Add number to the array\n2) Add random number to the array\n3) Sum numbers\n4) Exit\n" + assert pg_unicorn.one_active.posix.dumps(1) == ( + b"1) Add number to the array\n" + b"2) Add random number to the array\n" + b"3) Sum numbers\n" + b"4) Exit\n" + b"Randomness added\n" + b"1) Add number to the array\n" + b"2) Add random number to the array\n" + b"3) Sum numbers\n" + b"4) Exit\n" + b" Index: \n" + b"1) Add number to the array\n" + b"2) Add random number to the array\n" + b"3) Sum numbers\n" + b"4) Exit\n" ) diff --git a/tests/test_variablerecovery.py b/tests/test_variablerecovery.py index d6f36d03622..876eaa10d90 100644 --- a/tests/test_variablerecovery.py +++ b/tests/test_variablerecovery.py @@ -1,4 +1,3 @@ -import sys import os import logging import unittest diff --git a/tests/test_vault.py b/tests/test_vault.py index 0a1cdff70b2..76b8d30299c 100644 --- a/tests/test_vault.py +++ b/tests/test_vault.py @@ -155,8 +155,7 @@ def test_project(self): gc.collect() - p = v.load(ps) - # assert not hasattr(p, '_asdf') + v.load(ps) assert sum(1 for k in v.keys() if k.startswith("Project")) == 1 diff --git a/tests/test_veritesting.py b/tests/test_veritesting.py index 78afdc5c262..f65286c36cf 100644 --- a/tests/test_veritesting.py +++ b/tests/test_veritesting.py @@ -69,7 +69,6 @@ def _run_veritesting_skm(self, arch): proj = angr.Project(os.path.join(location, arch, "veritesting_skm")) # start the analysis after the call to lexer_read_line - start_address = 0x4024AE state = proj.factory.blank_state(addr=0x4024AE, remove_options={angr.sim_options.UNICORN}) # set up the structures for the user_input diff --git a/tests/test_xrefs.py b/tests/test_xrefs.py index 7122f3ed8f8..45d5558e655 100644 --- a/tests/test_xrefs.py +++ b/tests/test_xrefs.py @@ -38,7 +38,7 @@ def test_lwip_udpecho_bm(): def test_lwip_udpecho_bm_the_better_way(): bin_path = os.path.join(test_location, "armel", "lwip_udpecho_bm.elf") p = angr.Project(bin_path, auto_load_libs=False) - cfg = p.analyses.CFG(cross_references=True) # pylint:disable=unused-variable + p.analyses.CFG(cross_references=True) timenow_cp_xrefs = p.kb.xrefs.get_xrefs_by_dst(0x23D4) # the constant in the constant pool timenow_xrefs = p.kb.xrefs.get_xrefs_by_dst(0x1FFF36F4) # the value in .bss