1# This module contains the analysis options.
2# All variables with names of all caps will be registered as a state option to SimStateOptions.
3
4import string
5from .sim_state_options import SimStateOptions
6
7# This option controls whether or not constraints are tracked in the analysis.
8TRACK_CONSTRAINTS = "TRACK_CONSTRAINTS"
9
10# This option controls whether or not various entities (IRExpr constants, reads, writes, etc) get simplified automatically
11SIMPLIFY_EXPRS = "SIMPLIFY_EXPRS"
12SIMPLIFY_MEMORY_READS = "SIMPLIFY_MEMORY_READS"
13SIMPLIFY_MEMORY_WRITES = "SIMPLIFY_MEMORY_WRITES"
14SIMPLIFY_REGISTER_READS = "SIMPLIFY_REGISTER_READS"
15SIMPLIFY_REGISTER_WRITES = "SIMPLIFY_REGISTER_WRITES"
16SIMPLIFY_RETS = "SIMPLIFY_RETS"
17SIMPLIFY_EXIT_STATE = "SIMPLIFY_EXIT_STATE"
18SIMPLIFY_EXIT_TARGET = "SIMPLIFY_EXIT_TARGET"
19SIMPLIFY_EXIT_GUARD = "SIMPLIFY_EXIT_GUARD"
20SIMPLIFY_CONSTRAINTS = "SIMPLIFY_CONSTRAINTS"
21
22# This option controls whether the helper functions are actually executed for CCALL expressions.
23# Without this, the arguments are parsed, but the calls aren't executed, and an unconstrained symbolic
24# variable is returned, instead.
25DO_CCALLS = "DO_CCALLS"
26
27# Whether we should use the simplified ccalls or not.
28USE_SIMPLIFIED_CCALLS = "USE_SIMPLIFIED_CCALLS"
29
30# This option controls whether or not emulated exits and coderefs are added from a call instruction to its ret site.
31DO_RET_EMULATION = "DO_RET_EMULATION"
32
33# If this option is present, the guards to emulated ret exits are True instead of False
34TRUE_RET_EMULATION_GUARD = "TRUE_RET_EMULATION_GUARD"
35
36# This option causes the analysis to immediately concretize any symbolic value that it comes across
37CONCRETIZE = "CONCRETIZE"
38
39# This option prevents angr from doing hundreds of constraint solves to resolve symbolic jump targets
40NO_SYMBOLIC_JUMP_RESOLUTION = "NO_SYMBOLIC_JUMP_RESOLUTION"
41
42# This option prevents angr from doing hundreds of constraint solves when it hits a symbolic syscall
43NO_SYMBOLIC_SYSCALL_RESOLUTION = "NO_SYMBOLIC_SYSCALL_RESOLUTION"
44
45# The absense of this option causes the analysis to avoid reasoning about most symbolic values.
46SYMBOLIC = "SYMBOLIC"
47
48# This variable causes claripy to use a string solver (CVC4)
49STRINGS_ANALYSIS = "STRINGS_ANALYSIS"
50
51# Generate symbolic values for non-existent values. The absence of this option causes Unconstrained() to return default concrete values (like 0)
52SYMBOLIC_INITIAL_VALUES = "SYMBOLIC_INITIAL_VALUES"
53
54# this causes angr to use SimAbstractMemory for the memory region
55ABSTRACT_MEMORY = "ABSTRACT_MEMORY"
56
57# This causes symbolic memory to avoid performing symbolic reads and writes. Unconstrained results
58# are returned instead, if these options are present.
59AVOID_MULTIVALUED_READS = "AVOID_MULTIVALUED_READS"
60AVOID_MULTIVALUED_WRITES = "AVOID_MULTIVALUED_WRITES"
61
62# This option concretizes symbolically sized writes
63CONCRETIZE_SYMBOLIC_WRITE_SIZES = "CONCRETIZE_SYMBOLIC_WRITE_SIZES"
64
65# This option concretizes the read size if it's symbolic from the file
66CONCRETIZE_SYMBOLIC_FILE_READ_SIZES = "CONCRETIZE_SYMBOLIC_FILE_READ_SIZES"
67
68# If absent, treat the end of files as a frontier at which new data will be created
69# If present, treat the end of files as an EOF
70FILES_HAVE_EOF = "FILES_HAVE_EOF"
71UNKNOWN_FILES_HAVE_EOF = FILES_HAVE_EOF
72
73# Attempting to open an unkown file will result in creating it with a symbolic length
74ALL_FILES_EXIST = "ALL_FILES_EXIST"
75
76# Reads from devices will have a symbolic size
77SHORT_READS = "SHORT_READS"
78
79# This causes angr to support fully symbolic writes. It is very likely that speed will suffer.
80SYMBOLIC_WRITE_ADDRESSES = "SYMBOLIC_WRITE_ADDRESSES"
81
82# This causes symbolic memory to avoid concretizing memory address to a single value when the
83# range check fails.
84CONSERVATIVE_WRITE_STRATEGY = "CONSERVATIVE_WRITE_STRATEGY"
85CONSERVATIVE_READ_STRATEGY = "CONSERVATIVE_READ_STRATEGY"
86
87# This enables dependency tracking for all Claripy ASTs.
88AST_DEPS = "AST_DEPS"
89
90# This controls whether the temps are treated as symbolic values (for easier debugging) or just written as the z3 values
91SYMBOLIC_TEMPS = "SYMBOLIC_TEMPS"
92
93# These are options for tracking various types of actions
94TRACK_MEMORY_ACTIONS = "TRACK_MEMORY_ACTIONS"
95TRACK_REGISTER_ACTIONS = "TRACK_REGISTER_ACTIONS"
96TRACK_TMP_ACTIONS = "TRACK_TMP_ACTIONS"
97TRACK_JMP_ACTIONS = "TRACK_JMP_ACTIONS"
98TRACK_CONSTRAINT_ACTIONS = "TRACK_CONSTRAINT_ACTIONS"
99# note that TRACK_OP_ACTIONS is not enabled in symbolic mode by default, since Yan is worried about its performance
100# impact. someone should measure it and make a final decision.
101TRACK_OP_ACTIONS = "TRACK_OP_ACTIONS"
102
103# track the history of actions through a path (multiple states). This action affects things on the angr level
104TRACK_ACTION_HISTORY = "TRACK_ACTION_HISTORY"
105
106# track memory mapping and permissions
107TRACK_MEMORY_MAPPING = "TRACK_MEMORY_MAPPING"
108
109# track constraints in solver. This is required to enable unsat_core()
110CONSTRAINT_TRACKING_IN_SOLVER = "CONSTRAINT_TRACKING_IN_SOLVER"
111
112# this is an internal option to automatically track dependencies in SimProcedures
113AUTO_REFS = "AUTO_REFS"
114
115# Whether we should track dependencies in SimActions
116# If none of the ref options above exist, this option does nothing
117ACTION_DEPS = "ACTION_DEPS"
118
119# This enables the tracking of reverse mappings (name->addr and hash->addr) in SimSymbolicMemory
120REVERSE_MEMORY_NAME_MAP = "REVERSE_MEMORY_NAME_MAP"
121REVERSE_MEMORY_HASH_MAP = "REVERSE_MEMORY_HASH_MAP"
122
123# This enables tracking of which bytes in the state are symbolic
124MEMORY_SYMBOLIC_BYTES_MAP = "MEMORY_SYMBOLIC_BYTES_MAP"
125
126# this makes engine copy states
127COPY_STATES = "COPY_STATES"
128COW_STATES = COPY_STATES
129
130# this replaces calls with an unconstraining of the return register
131CALLLESS = "CALLLESS"
132
133# these enables independent constraint set optimizations. The first is a master toggle, and the second controls
134# splitting constraint sets during simplification
135COMPOSITE_SOLVER = "COMPOSITE_SOLVER"
136ABSTRACT_SOLVER = "ABSTRACT_SOLVER"
137
138# this stops SimRun for checking the satisfiability of successor states
139LAZY_SOLVES = "LAZY_SOLVES"
140
141# This makes angr downsize solvers wherever reasonable.
142DOWNSIZE_Z3 = "DOWNSIZE_Z3"
143
144# Turn-on superfastpath mode
145SUPER_FASTPATH = "SUPER_FASTPATH"
146
147# use FastMemory for memory
148FAST_MEMORY = "FAST_MEMORY"
149
150# use FastMemory for registers
151FAST_REGISTERS = "FAST_REGISTERS"
152
153# Under-constrained symbolic execution
154UNDER_CONSTRAINED_SYMEXEC = "UNDER_CONSTRAINED_SYMEXEC"
155
156# enable unicorn engine
157UNICORN = "UNICORN"
158UNICORN_ZEROPAGE_GUARD = "UNICORN_ZEROPAGE_GUARD"
159UNICORN_SYM_REGS_SUPPORT = "UNICORN_SYM_REGS_SUPPORT"
160UNICORN_TRACK_BBL_ADDRS = "UNICORN_TRACK_BBL_ADDRS"
161UNICORN_TRACK_STACK_POINTERS = "UNICORN_TRACK_STACK_POINTERS"
162
163# concretize symbolic data when we see it "too often"
164UNICORN_THRESHOLD_CONCRETIZATION = "UNICORN_THRESHOLD_CONCRETIZATION"
165
166# aggressively concretize symbolic data when we see it in unicorn
167UNICORN_AGGRESSIVE_CONCRETIZATION = "UNICORN_AGGRESSIVE_CONCRETIZATION"
168
169UNICORN_HANDLE_TRANSMIT_SYSCALL = "UNICORN_HANDLE_TRANSMIT_SYSCALL"
170
171# floating point support
172SUPPORT_FLOATING_POINT = "SUPPORT_FLOATING_POINT"
173
174# Turn on memory region mapping logging
175REGION_MAPPING = 'REGION_MAPPING'
176
177# Resilience options
178BYPASS_UNSUPPORTED_IROP = "BYPASS_UNSUPPORTED_IROP"
179BYPASS_ERRORED_IROP = "BYPASS_ERRORED_IROP"
180BYPASS_UNSUPPORTED_IREXPR = "BYPASS_UNSUPPORTED_IREXPR"
181BYPASS_UNSUPPORTED_IRSTMT = "BYPASS_UNSUPPORTED_IRSTMT"
182BYPASS_UNSUPPORTED_IRDIRTY = "BYPASS_UNSUPPORTED_IRDIRTY"
183BYPASS_UNSUPPORTED_IRCCALL = "BYPASS_UNSUPPORTED_IRCCALL"
184BYPASS_ERRORED_IRCCALL = "BYPASS_ERRORED_IRCCALL"
185BYPASS_UNSUPPORTED_SYSCALL = "BYPASS_UNSUPPORTED_SYSCALL"
186BYPASS_ERRORED_IRSTMT = "BYPASS_ERRORED_IRSTMT"
187UNSUPPORTED_BYPASS_ZERO_DEFAULT = "UNSUPPORTED_BYPASS_ZERO_DEFAULT"
188
189UNINITIALIZED_ACCESS_AWARENESS = 'UNINITIALIZED_ACCESS_AWARENESS'
190BEST_EFFORT_MEMORY_STORING = 'BEST_EFFORT_MEMORY_STORING'
191
192# Approximation options (to optimize symbolic execution)
193APPROXIMATE_GUARDS = "APPROXIMATE_GUARDS"
194APPROXIMATE_SATISFIABILITY = "APPROXIMATE_SATISFIABILITY" # does GUARDS and the rest of the constraints
195APPROXIMATE_MEMORY_SIZES = "APPROXIMATE_MEMORY_SIZES"
196APPROXIMATE_MEMORY_INDICES = "APPROXIMATE_MEMORY_INDICES"
197VALIDATE_APPROXIMATIONS = "VALIDATE_APPROXIMATIONS"
198
199# use an experimental replacement solver
200REPLACEMENT_SOLVER = "REPLACEMENT_SOLVER"
201
202# use a cache-less solver in claripy
203CACHELESS_SOLVER = "CACHELESS_SOLVER"
204
205# IR optimization
206OPTIMIZE_IR = "OPTIMIZE_IR"
207NO_CROSS_INSN_OPT = "NO_CROSS_INSN_OPT"
208
209SPECIAL_MEMORY_FILL = "SPECIAL_MEMORY_FILL"
210
211# using this option the value inside the register ip is kept symbolic
212KEEP_IP_SYMBOLIC = "KEEP_IP_SYMBOLIC"
213
214# Do not try to concretize a symbolic IP. With this option, all states with symbolic IPs will be seen as unconstrained.
215NO_IP_CONCRETIZATION = "NO_IP_CONCRETIZATION"
216
217# Do not union values from different locations when reading from the memory for a reduced loss in precision
218# It is only applied to SimAbstractMemory
219KEEP_MEMORY_READS_DISCRETE = "KEEP_MEMORY_READS_DISCRETE"
220
221# Raise a SimSegfaultError on illegal memory accesses
222STRICT_PAGE_ACCESS = "STRICT_PAGE_ACCESS"
223
224# Raise a SimSegfaultError when executing nonexecutable memory
225ENABLE_NX = "ENABLE_NX"
226
227# Ask the SimOS to handle segfaults
228EXCEPTION_HANDLING = "EXCEPTION_HANDLING"
229
230# Use system timestamps in simprocedures instead of returning symbolic values
231USE_SYSTEM_TIMES = "USE_SYSTEM_TIMES"
232
233# Track variables in state.solver.all_variables
234TRACK_SOLVER_VARIABLES = "TRACK_SOLVER_VARIABLES"
235
236# Efficient state merging requires potential state ancestors being kept in memory
237EFFICIENT_STATE_MERGING = "EFFICIENT_STATE_MERGING"
238
239# Return 0 any unspecified bytes in memory/registers
240ZERO_FILL_UNCONSTRAINED_MEMORY = 'ZERO_FILL_UNCONSTRAINED_MEMORY'
241ZERO_FILL_UNCONSTRAINED_REGISTERS = 'ZERO_FILL_UNCONSTRAINED_REGISTERS'
242INITIALIZE_ZERO_REGISTERS = ZERO_FILL_UNCONSTRAINED_REGISTERS
243
244# Return a new symbolic variable for any unspecified bytes in memory/registers. If neither these nor the above options
245# are specified, a warning will be issued and an unconstrained symbolic variable will be generated
246SYMBOL_FILL_UNCONSTRAINED_MEMORY = 'SYMBOL_FILL_UNCONSTRAINED_MEMORY'
247SYMBOL_FILL_UNCONSTRAINED_REGISTERS = 'SYMBOL_FILL_UNCONSTRAINED_REGISTERS'
248
249# Attempt to support wacky ops not found in libvex
250EXTENDED_IROP_SUPPORT = 'EXTENDED_IROP_SUPPORT'
251
252# For each division operation, produce a successor state with the constraint that the divisor is zero
253PRODUCE_ZERODIV_SUCCESSORS = 'PRODUCE_ZERODIV_SUCCESSORS'
254
255SYNC_CLE_BACKEND_CONCRETE = 'SYNC_CLE_BACKEND_CONCRETE'
256
257# Allow POSIX API send() to fail
258ALLOW_SEND_FAILURES = 'ALLOW_SEND_FAILURES'
259
260# Use hybrid solver
261HYBRID_SOLVER = 'HYBRID_SOLVER'
262
263# This tells the hybrid solver to use the approximate backend first. The exact backend will be used
264# only if the number of possible approximate solutions is greater than what was request by user.
265# Note, that this option will only take effect if a hybrid solver used.
266APPROXIMATE_FIRST = 'APPROXIMATE_FIRST'
267
268# Disable optimizations based on symbolic memory bytes being single-valued in SimSymbolicMemory. This is useful in
269# tracing mode since such optimizations are unreliable since preconstraints will be removed after tracing is done.
270SYMBOLIC_MEMORY_NO_SINGLEVALUE_OPTIMIZATIONS = 'SYMBOLIC_MEMORY_NO_SINGLEVALUE_OPTIMIZATIONS'
271
272# When SimMemory.find() is called, apply a strict size-limit condition check. This is mainly used in tracing mode. When
273# this option is enabled, constraint replacement and solves will kick in when testing the byte-equivalence constraints
274# built in SimMemory._find(), and less cases will be satisfiable. In tracing mode, this means the character to find will
275# have to show up at the exact location as specified in the concrete input. When this option is disabled, constraint
276# replacement and solves will not be triggered when testing byte-equivalence constraints, which in tracing mode, will
277# allow some flexibility regarding the position of character to find at the cost of larger constraints built in
278# SimMemory._find() and more time and memory consumption.
279MEMORY_FIND_STRICT_SIZE_LIMIT = 'MEMORY_FIND_STRICT_SIZE_LIMIT'
280
281# return unconstrained symbols from cpuid
282CPUID_SYMBOLIC = 'CPUID_SYMBOLIC'
283
284#
285# CGC specific state options
286#
287
288CGC_ZERO_FILL_UNCONSTRAINED_MEMORY = ZERO_FILL_UNCONSTRAINED_MEMORY
289# Make sure the receive syscall always read as many bytes as the program wants
290CGC_NO_SYMBOLIC_RECEIVE_LENGTH = 'CGC_NO_SYMBOLIC_RECEIVE_LENGTH'
291BYPASS_VERITESTING_EXCEPTIONS = 'BYPASS_VERITESTING_EXCEPTIONS'
292# Make sure filedescriptors on transmit and receive are always 1 and 0
293CGC_ENFORCE_FD = 'CGC_ENFORCE_FD'
294# FDWAIT will always return FDs as non blocking
295CGC_NON_BLOCKING_FDS = 'CGC_NON_BLOCKING_FDS'
296
297# Allows memory breakpoints to get more accurate sizes in case of reading large chunks
298# Sacrafice performance for more fine tune memory read size
299MEMORY_CHUNK_INDIVIDUAL_READS = "MEMORY_CHUNK_INDIVIDUAL_READS"
300
301# Synchronize memory mapping reported by angr with the concrete process.
302SYMBION_SYNC_CLE = "SYMBION_SYNC_CLE"
303# Removes stubs SimProc on synchronization with concrete process.
304# We will execute SimProc for functions for which we have one, and the real function for the one we have not.
305SYMBION_KEEP_STUBS_ON_SYNC = "SYMBION_KEEP_STUBS_ON_SYNC"
306
307# Activate the heuristic that tries to understand if an unknown method (e. g. library call) gets or sets an
308# attribute inside the object. Turn on this option to have a better approximation of the internal structure of the
309# symbolic object.
310JAVA_IDENTIFY_GETTER_SETTER = "JAVA_IDENTIFY_GETTER_SETTER"
311# Activate attributes tracking for objects.
312JAVA_TRACK_ATTRIBUTES = "JAVA_TRACK_ATTRIBUTES"
313
314#
315# Register those variables as Boolean state options
316#
317
318_g = globals().copy()
319for k, v in _g.items():
320    if all([ char in string.ascii_uppercase + "_" + string.digits for char in k ]) and type(v) is str:
321        if k in ("UNKNOWN_FILES_HAVE_EOF", "CGC_ZERO_FILL_UNCONSTRAINED_MEMORY", "COW_STATES", "INITIALIZE_ZERO_REGISTERS"):
322            # UNKNOWN_FILES_HAVE_EOF == FILES_HAVE_EOF
323            # CGC_ZERO_FILL_UNCONSTRAINED_MEMORY == ZERO_FILL_UNCONSTRAINED_MEMORY
324            # INITIALIZE_ZERO_REGISTERS == ZERO_FILL_UNCONSTRAINED_REGISTERS
325            continue
326        SimStateOptions.register_bool_option(v)
327
328
329# useful sets of options
330resilience = { BYPASS_UNSUPPORTED_IROP, BYPASS_UNSUPPORTED_IREXPR, BYPASS_UNSUPPORTED_IRSTMT, BYPASS_UNSUPPORTED_IRDIRTY, BYPASS_UNSUPPORTED_IRCCALL, BYPASS_ERRORED_IRCCALL, BYPASS_UNSUPPORTED_SYSCALL, BYPASS_ERRORED_IROP, BYPASS_VERITESTING_EXCEPTIONS, BYPASS_ERRORED_IRSTMT }
331resilience_options = resilience # alternate name?
332refs = { TRACK_REGISTER_ACTIONS, TRACK_MEMORY_ACTIONS, TRACK_TMP_ACTIONS, TRACK_JMP_ACTIONS, ACTION_DEPS, TRACK_CONSTRAINT_ACTIONS }
333approximation = { APPROXIMATE_SATISFIABILITY, APPROXIMATE_MEMORY_SIZES, APPROXIMATE_MEMORY_INDICES }
334symbolic = { DO_CCALLS, SYMBOLIC, TRACK_CONSTRAINTS, SYMBOLIC_INITIAL_VALUES, COMPOSITE_SOLVER }
335simplification = { SIMPLIFY_MEMORY_WRITES, SIMPLIFY_REGISTER_WRITES }
336common_options = { COW_STATES, OPTIMIZE_IR, TRACK_MEMORY_MAPPING, SUPPORT_FLOATING_POINT, EXTENDED_IROP_SUPPORT, ALL_FILES_EXIST, FILES_HAVE_EOF } | simplification
337unicorn = { UNICORN, UNICORN_SYM_REGS_SUPPORT, ZERO_FILL_UNCONSTRAINED_REGISTERS, UNICORN_HANDLE_TRANSMIT_SYSCALL, UNICORN_TRACK_BBL_ADDRS, UNICORN_TRACK_STACK_POINTERS }
338concrete = { SYNC_CLE_BACKEND_CONCRETE }
339
340modes = {
341    'symbolic': common_options | symbolic | { TRACK_CONSTRAINT_ACTIONS }, #| approximation | { VALIDATE_APPROXIMATIONS }
342    'symbolic_approximating': common_options | symbolic | approximation | { TRACK_CONSTRAINT_ACTIONS },
343    'static': (common_options - simplification) | { REGION_MAPPING, BEST_EFFORT_MEMORY_STORING, SYMBOLIC_INITIAL_VALUES, DO_CCALLS, DO_RET_EMULATION, TRUE_RET_EMULATION_GUARD, TRACK_CONSTRAINTS, ABSTRACT_MEMORY, ABSTRACT_SOLVER, USE_SIMPLIFIED_CCALLS, REVERSE_MEMORY_NAME_MAP },
344    'fastpath': (common_options - simplification ) | (symbolic - { SYMBOLIC, DO_CCALLS }) | resilience | { TRACK_OP_ACTIONS, BEST_EFFORT_MEMORY_STORING, AVOID_MULTIVALUED_READS, AVOID_MULTIVALUED_WRITES, SYMBOLIC_INITIAL_VALUES, DO_RET_EMULATION, NO_SYMBOLIC_JUMP_RESOLUTION, NO_SYMBOLIC_SYSCALL_RESOLUTION, FAST_REGISTERS },
345    'tracing': (common_options - simplification - {SUPPORT_FLOATING_POINT, ALL_FILES_EXIST}) | symbolic | resilience | (unicorn - { UNICORN_TRACK_STACK_POINTERS }) | { CGC_NO_SYMBOLIC_RECEIVE_LENGTH, REPLACEMENT_SOLVER, EXCEPTION_HANDLING, ZERO_FILL_UNCONSTRAINED_MEMORY, PRODUCE_ZERODIV_SUCCESSORS, ALLOW_SEND_FAILURES, SYMBOLIC_MEMORY_NO_SINGLEVALUE_OPTIMIZATIONS, MEMORY_FIND_STRICT_SIZE_LIMIT, CPUID_SYMBOLIC },
346}
347