Skip to content

Instantly share code, notes, and snippets.

@zhuyifei1999
Created November 8, 2019 06:12
Show Gist options
  • Save zhuyifei1999/496a937a7ad4e211c8b60d2556515e03 to your computer and use it in GitHub Desktop.
Save zhuyifei1999/496a937a7ad4e211c8b60d2556515e03 to your computer and use it in GitHub Desktop.
def patch_unicorn_unmapped():
import ast
import inspect
import textwrap
func = angr.state_plugins.unicorn_engine.Unicorn._hook_mem_unmapped_core
code = func.__code__
source = inspect.getsource(code)
tree = ast.parse(textwrap.dedent(source), code.co_filename)
lineoffset = code.co_firstlineno - tree.body[0].lineno
ast.increment_lineno(tree, lineoffset)
assert isinstance(tree, ast.Module)
assert len(tree.body) == 1
assert isinstance(tree.body[0], ast.FunctionDef)
assert tree.body[0].name == '_hook_mem_unmapped_core'
ind = [i for i, o in enumerate(tree.body[0].body)
if isinstance(o, ast.FunctionDef) and o.name == '_missing']
assert len(ind) == 1
ind = ind[0]
def mk_replacement():
self = _taint = start = data = None
def _missing(pos, chunk_size, data=data):
def partition_mmio(start=pos, end=pos+chunk_size):
mmio_regions = sorted(
(region.lower, region.upper + 1)
for region in self.state.simmio.regions
)
while start < end:
if not mmio_regions:
yield start, end, False
break
r = mmio_regions[0]
if start < r[0]:
newstart = min(end, r[0])
yield start, newstart, False
start = newstart
elif r[0] <= start < r[1]:
newstart = min(end, r[1])
yield start, newstart, True
start = newstart
mmio_regions.pop(0)
elif r[1] <= start:
mmio_regions.pop(0)
else:
assert False
for istart, iend, is_mmio in partition_mmio():
if is_mmio:
_taint(istart, iend-istart)
else:
data[istart-start:iend-start] = b"\0"*(iend-istart)
return _missing
rcode = mk_replacement().__code__
source = inspect.getsource(rcode)
rtree = ast.parse(textwrap.dedent(source), rcode.co_filename)
rlineoffset = rcode.co_firstlineno - rtree.body[0].lineno
ast.increment_lineno(rtree, rlineoffset)
assert isinstance(rtree, ast.Module)
assert len(rtree.body) == 1
assert isinstance(rtree.body[0], ast.FunctionDef)
assert rtree.body[0].name == '_missing'
tree.body[0].body[ind] = rtree.body[0]
ns = {**angr.state_plugins.unicorn_engine.__dict__}
exec(compile(tree, code.co_filename, 'exec'), ns)
f = ns['_hook_mem_unmapped_core']
func.__code__ = f.__code__
patch_unicorn_unmapped()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment