Skip to content

Commit 57c438f

Browse files
committed
linting
1 parent 3338fa2 commit 57c438f

File tree

10 files changed

+48
-35
lines changed

10 files changed

+48
-35
lines changed

angrop/chain_builder/__init__.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,8 @@ def __init__(self, project, rop_gadgets, pivot_gadgets, syscall_gadgets, arch, b
4444
self._pivot = Pivot(self)
4545
self._sys_caller = SysCaller(self)
4646
if not SysCaller.supported_os(self.project.loader.main_object.os):
47-
l.warning("%s is not a fully supported OS, SysCaller may not work on this OS", self.project.loader.main_object.os)
47+
l.warning("%s is not a fully supported OS, SysCaller may not work on this OS",
48+
self.project.loader.main_object.os)
4849

4950
def set_regs(self, *args, **kwargs):
5051
"""

angrop/chain_builder/builder.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -204,4 +204,4 @@ def _get_fill_val(self):
204204

205205
@abstractmethod
206206
def update(self):
207-
raise NotImplementedError("each Builder class should have an `update` method!")
207+
raise NotImplementedError("each Builder class should have an `update` method!")

angrop/chain_builder/pivot.py

+10-7
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,17 @@ def cmp(g1, g2):
1717
return -1
1818
if g1.stack_change + g1.stack_change_after_pivot > g2.stack_change + g2.stack_change_after_pivot:
1919
return 1
20-
20+
2121
if g1.block_length < g2.block_length:
2222
return -1
2323
if g1.block_length > g2.block_length:
2424
return 1
2525
return 0
2626

2727
class Pivot(Builder):
28-
28+
"""
29+
a chain_builder that builds stack pivoting rop chains
30+
"""
2931
def __init__(self, chain_builder):
3032
super().__init__(chain_builder)
3133
self._pivot_gadgets = None
@@ -69,7 +71,7 @@ def pivot_addr(self, addr):
6971
state = chain.exec()
7072
if state.solver.eval(state.regs.sp == addr.data):
7173
return chain
72-
except Exception:
74+
except Exception: # pylint: disable=broad-exception-caught
7375
continue
7476

7577
raise RopException(f"Fail to pivot the stack to {addr.data}!")
@@ -101,9 +103,10 @@ def pivot_reg(self, reg_val):
101103
if len(variables) == 1 and variables.pop().startswith(f'reg_{reg}'):
102104
return chain
103105
else:
104-
chain_str = '\n-----\n'.join([str(self.project.factory.block(g.addr).capstone)for g in chain._gadgets])
106+
insts = [str(self.project.factory.block(g.addr).capstone) for g in chain._gadgets]
107+
chain_str = '\n-----\n'.join(insts)
105108
l.exception("Somehow angrop thinks\n%s\ncan be use for stack pivoting", chain_str)
106-
except Exception as e:
109+
except Exception: # pylint: disable=broad-exception-caught
107110
continue
108111

109112
raise RopException(f"Fail to pivot the stack to {reg}!")
@@ -115,7 +118,7 @@ def same_effect(g1, g2):
115118
if g1.changed_regs != g2.changed_regs:
116119
return False
117120
return True
118-
121+
119122
def better_than(self, g1, g2):
120123
if not self.same_effect(g1, g2):
121124
return False
@@ -144,4 +147,4 @@ def _filter_gadgets(self, gadgets):
144147
break
145148
gadgets -= to_remove
146149
gadgets = sorted(gadgets, key=functools.cmp_to_key(cmp))
147-
return gadgets
150+
return gadgets

angrop/chain_builder/sys_caller.py

+1-3
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,7 @@
44
import angr
55

66
from .func_caller import FuncCaller
7-
from .. import common
87
from ..errors import RopException
9-
from ..rop_gadget import RopGadget
108

119
l = logging.getLogger(__name__)
1210

@@ -137,7 +135,7 @@ def do_syscall(self, syscall_num, args, needs_return=True, **kwargs):
137135
try:
138136
return self._func_call(gadget, cc, args, extra_regs=extra_regs,
139137
needs_return=needs_return, **kwargs)
140-
except Exception:
138+
except Exception: # pylint: disable=broad-exception-caught
141139
continue
142140

143141
raise RopException(f"Fail to invoke syscall {syscall_num} with arguments: {args}!")

angrop/gadget_finder/__init__.py

+7-3
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,11 @@ def run_worker(addr):
3939
return _global_gadget_analyzer.analyze_gadget(addr)
4040

4141
class GadgetFinder:
42-
43-
def __init__(self, project, fast_mode=None, only_check_near_rets=True, max_block_size=None, max_sym_mem_access=None, is_thumb=False, kernel_mode=False):
42+
"""
43+
a class to find ROP gadgets
44+
"""
45+
def __init__(self, project, fast_mode=None, only_check_near_rets=True, max_block_size=None,
46+
max_sym_mem_access=None, is_thumb=False, kernel_mode=False):
4447
# configurations
4548
self.project = project
4649
self.fast_mode = fast_mode
@@ -187,9 +190,10 @@ def _addresses_to_check_with_caching(self, show_progress=True):
187190

188191
yield a
189192

190-
def block_hash(self, block):
193+
def block_hash(self, block):# pylint:disable=no-self-use
191194
"""
192195
a hash to uniquely identify a simple block
196+
TODO: block.bytes is too primitive
193197
"""
194198
return block.bytes
195199

angrop/gadget_finder/gadget_analyzer.py

+8-6
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ def __init__(self, project, fast_mode, kernel_mode=False, arch=None, stack_gsize
3434
# initial state that others are based off, all analysis should copy the state first and work on
3535
# the copied state
3636
self._stack_bsize = stack_gsize * self.project.arch.bytes # number of controllable bytes on stack
37-
self._state = rop_utils.make_symbolic_state(self.project, self.arch.reg_set.union({self.arch.base_pointer}), stack_gsize=stack_gsize)
37+
sym_reg_set = self.arch.reg_set.union({self.arch.base_pointer})
38+
self._state = rop_utils.make_symbolic_state(self.project, sym_reg_set, stack_gsize=stack_gsize)
3839
self._concrete_sp = self._state.solver.eval(self._state.regs.sp)
3940

4041
@rop_utils.timeout(3)
@@ -203,7 +204,7 @@ def _reach_unconstrained_or_syscall(self, addr):
203204
succ = self.project.factory.successors(state)
204205
state = succ.flat_successors[0]
205206
state2 = rop_utils.step_to_unconstrained_successor(self.project, state=state)
206-
except Exception:
207+
except Exception: # pylint: disable=broad-exception-caught
207208
return init_state, final_state
208209
return init_state, state2
209210
return init_state, final_state
@@ -224,7 +225,8 @@ def _identify_transit_type(self, final_state, ctrl_type):
224225
continue
225226
if act.size != self.project.arch.bits:
226227
continue
227-
if (act.data.ast == final_state.ip).symbolic or not final_state.solver.eval(act.data.ast == final_state.ip):
228+
if (act.data.ast == final_state.ip).symbolic or \
229+
not final_state.solver.eval(act.data.ast == final_state.ip):
228230
continue
229231
sols = final_state.solver.eval_upto(final_state.regs.sp-act.addr.ast, 2)
230232
if len(sols) != 1:
@@ -507,7 +509,7 @@ def _check_if_stack_controls_ast(self, ast, initial_state, gadget_stack_change=N
507509
concrete_stack_s = initial_state.copy()
508510
concrete_stack_s.add_constraints(
509511
initial_state.memory.load(initial_state.regs.sp, stack_bytes_length) == concrete_stack)
510-
test_constraint = (ast != test_val)
512+
test_constraint = ast != test_val
511513
# stack must have set the register and it must be able to set the register to all 1's or all 0's
512514
ans = not concrete_stack_s.solver.satisfiable(extra_constraints=(test_constraint,)) and \
513515
rop_utils.fast_unconstrained_check(initial_state, ast)
@@ -611,7 +613,7 @@ def _build_mem_access(self, a, gadget, init_state, final_state):
611613
elif len(test_data) == 1:
612614
mem_access.data_constant = test_data[0]
613615
else:
614-
raise Exception("No data values, something went wrong")
616+
raise RopException("No data values, something went wrong")
615617
elif a.action == "read":
616618
# for reads we want to know if any register will have the data after
617619
succ_state = final_state
@@ -738,7 +740,7 @@ def _analyze_mem_access(self, final_state, init_state, gadget):
738740
continue
739741

740742
# ignore read/write on stack after pivot
741-
if a.addr.ast.symbolic and not (a.addr.ast.variables - sp_vars):
743+
if a.addr.ast.symbolic and not a.addr.ast.variables - sp_vars:
742744
continue
743745

744746
# ignore read/write on stack

angrop/rop.py

+9-4
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,9 @@ def __init__(self, only_check_near_rets=True, max_block_size=None, max_sym_mem_a
5050
self.roparg_filler = None
5151

5252
# gadget finder configurations
53-
self.gadget_finder = GadgetFinder(self.project, fast_mode=fast_mode, only_check_near_rets=only_check_near_rets, max_block_size=max_block_size, max_sym_mem_access=max_sym_mem_access, is_thumb=is_thumb, kernel_mode=kernel_mode)
53+
self.gadget_finder = GadgetFinder(self.project, fast_mode=fast_mode, only_check_near_rets=only_check_near_rets,
54+
max_block_size=max_block_size, max_sym_mem_access=max_sym_mem_access,
55+
is_thumb=is_thumb, kernel_mode=kernel_mode)
5456
self.arch = self.gadget_finder.arch
5557

5658
# chain builder
@@ -69,12 +71,13 @@ def _screen_gadgets(self):
6971
# the duplicates (other gadgets with the same instructions)
7072
block = self.project.factory.block(g.addr)
7173
h = self.gadget_finder.block_hash(block)
74+
addr = None
7275
if h not in self._duplicates:
7376
continue
7477
for addr in self._duplicates[h]:
7578
if not self._contain_badbytes(addr):
7679
break
77-
else:
80+
if not addr:
7881
continue
7982
g = self.gadget_finder.analyze_gadget(addr)
8083
if type(g) is RopGadget:
@@ -103,7 +106,8 @@ def find_gadgets(self, processes=4, show_progress=True):
103106
Saves stack pivots in self.stack_pivots
104107
:param processes: number of processes to use
105108
"""
106-
self._all_gadgets, self._duplicates = self.gadget_finder.find_gadgets(processes=processes, show_progress=show_progress)
109+
self._all_gadgets, self._duplicates = self.gadget_finder.find_gadgets(processes=processes,
110+
show_progress=show_progress)
107111
self._screen_gadgets()
108112
return self.rop_gadgets
109113

@@ -113,7 +117,8 @@ def find_gadgets_single_threaded(self, show_progress=True):
113117
Saves gadgets in self.gadgets
114118
Saves stack pivots in self.stack_pivots
115119
"""
116-
self._all_gadgets, self._duplicates = self.gadget_finder.find_gadgets_single_threaded(show_progress=show_progress)
120+
self._all_gadgets, self._duplicates = self.gadget_finder.find_gadgets_single_threaded(
121+
show_progress=show_progress)
117122
self._screen_gadgets()
118123
return self.rop_gadgets
119124

angrop/rop_gadget.py

+5-5
Original file line numberDiff line numberDiff line change
@@ -176,9 +176,9 @@ def __str__(self):
176176
for move in self.reg_moves:
177177
s += "Register move: [%s to %s, %d bits]\n" % (move.from_reg, move.to_reg, move.bits)
178178
s += "Register dependencies:\n"
179-
for reg in self.reg_dependencies:
179+
for reg, deps in self.reg_dependencies.items():
180180
controllers = self.reg_controllers.get(reg, [])
181-
dependencies = [x for x in self.reg_dependencies[reg] if x not in controllers]
181+
dependencies = [x for x in deps if x not in controllers]
182182
s += " " + reg + ": [" + " ".join(controllers) + " (" + " ".join(dependencies) + ")]" + "\n"
183183
for mem_access in self.mem_changes:
184184
if mem_access.op == "__add__":
@@ -256,8 +256,8 @@ def __init__(self, addr):
256256
self.stack_change_after_pivot = None
257257
# TODO: sp_controllers can be registers, payload on stack, and symbolic read data
258258
# but we do not handle symbolic read data, yet
259-
self.sp_reg_controllers = {}
260-
self.sp_stack_controllers = {}
259+
self.sp_reg_controllers = set()
260+
self.sp_stack_controllers = set()
261261

262262
def __str__(self):
263263
s = f"PivotGadget {self.addr:#x}\n"
@@ -273,7 +273,7 @@ def sp_controllers(self):
273273

274274
def __repr__(self):
275275
return f"<PivotGadget {self.addr:#x}>"
276-
276+
277277
def copy(self):
278278
new = super().copy()
279279
new.stack_change_after_pivot = self.stack_change_after_pivot

angrop/rop_utils.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,7 @@ def step_one_block(project, state, stop_at_syscall=False):
231231
last_inst_addr = block.capstone.insns[-2].address
232232
else:
233233
last_inst_addr = block.capstone.insns[-1].address
234-
for i in range(num_insts): # considering that it may get into kernel mode
234+
for _ in range(num_insts): # considering that it may get into kernel mode
235235
if state.addr != last_inst_addr:
236236
state = step_one_inst(project, state, stop_at_syscall=stop_at_syscall)
237237
if stop_at_syscall and is_in_kernel(project, state):
@@ -243,8 +243,7 @@ def step_one_block(project, state, stop_at_syscall=False):
243243
if stop_at_syscall and is_in_kernel(project, succ.flat_successors[0]):
244244
return None, succ.flat_successors[0]
245245
return succ, None
246-
else:
247-
raise RopException("Fail to reach the last instruction!")
246+
raise RopException("Fail to reach the last instruction!")
248247

249248
def step_one_inst(project, state, stop_at_syscall=False):
250249
if is_in_kernel(project, state):
@@ -262,7 +261,8 @@ def step_one_inst(project, state, stop_at_syscall=False):
262261
raise RopException(f"fail to step state: {state}")
263262
return succ.flat_successors[0]
264263

265-
def step_to_unconstrained_successor(project, state, max_steps=2, allow_simprocedures=False, stop_at_syscall=False, precise_action=False):
264+
def step_to_unconstrained_successor(project, state, max_steps=2, allow_simprocedures=False,
265+
stop_at_syscall=False, precise_action=False):
266266
"""
267267
steps up to two times to try to find an unconstrained successor
268268
:param state: the input state

tests/test_find_gadgets.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33

44
import angr
55
import angrop # pylint: disable=unused-import
6-
from angrop.rop_gadget import RopGadget, PivotGadget
76

87
l = logging.getLogger(__name__)
98

@@ -58,6 +57,7 @@ def test_arm_thumb_mode():
5857
assert gadget.block_length == 6
5958

6059
def test_pivot_gadget():
60+
# pylint: disable=pointless-string-statement
6161
proj = angr.Project(os.path.join(tests_dir, "i386", "bronze_ropchain"), auto_load_libs=False)
6262
rop = proj.analyses.ROP()
6363

0 commit comments

Comments
 (0)