Add hook decorator (#28)
* Add m.add_hook test * Add @m.hook test * Add `hook` decorator for convenience * Update readme and examples * Update run_callback * Improve `add_hook` docstring expound on callback structure * Rm debug print * Improve docstring
This commit is contained in:
parent
98567efeaa
commit
d6393cc8a6
@ -66,6 +66,7 @@ hook_pc = 0x400ca0
|
|||||||
|
|
||||||
m = Manticore('./path/to/binary')
|
m = Manticore('./path/to/binary')
|
||||||
|
|
||||||
|
@m.hook(hook_pc)
|
||||||
def hook(state):
|
def hook(state):
|
||||||
cpu = state.cpu
|
cpu = state.cpu
|
||||||
print 'eax', cpu.EAX
|
print 'eax', cpu.EAX
|
||||||
@ -73,6 +74,5 @@ def hook(state):
|
|||||||
|
|
||||||
m.terminate() # tell Manticore to stop
|
m.terminate() # tell Manticore to stop
|
||||||
|
|
||||||
m.add_hook(hook_pc, hook)
|
|
||||||
m.run()
|
m.run()
|
||||||
```
|
```
|
||||||
|
|||||||
@ -19,11 +19,10 @@ if __name__ == '__main__':
|
|||||||
m.workers = 3
|
m.workers = 3
|
||||||
m.context['count'] = 0
|
m.context['count'] = 0
|
||||||
|
|
||||||
|
@m.hook(None)
|
||||||
def explore(state):
|
def explore(state):
|
||||||
m.context['count'] += 1
|
m.context['count'] += 1
|
||||||
|
|
||||||
m.add_hook(None, explore)
|
|
||||||
|
|
||||||
m.run()
|
m.run()
|
||||||
|
|
||||||
print "Executed ", m.context['count'], " instructions."
|
print "Executed ", m.context['count'], " instructions."
|
||||||
|
|||||||
@ -11,6 +11,7 @@ if __name__ == '__main__':
|
|||||||
path = sys.argv[1]
|
path = sys.argv[1]
|
||||||
m = Manticore(path)
|
m = Manticore(path)
|
||||||
|
|
||||||
|
@m.hook(0x109f0)
|
||||||
def myhook(state):
|
def myhook(state):
|
||||||
flag = ''
|
flag = ''
|
||||||
cpu = state.cpu
|
cpu = state.cpu
|
||||||
@ -24,7 +25,5 @@ if __name__ == '__main__':
|
|||||||
print 'flag is:', flag
|
print 'flag is:', flag
|
||||||
m.terminate()
|
m.terminate()
|
||||||
|
|
||||||
m.add_hook(0x109f0, myhook)
|
|
||||||
|
|
||||||
m.run()
|
m.run()
|
||||||
print 'done'
|
print 'done'
|
||||||
|
|||||||
@ -5,34 +5,24 @@ from manticore import Manticore
|
|||||||
|
|
||||||
# This example demonstrates a basic hook (PC register)
|
# This example demonstrates a basic hook (PC register)
|
||||||
|
|
||||||
def get_args():
|
|
||||||
class Args(object): pass
|
|
||||||
args = Args()
|
|
||||||
args.replay = None; args.data = ''; args.dumpafter = 0; args.maxstates = 0;
|
|
||||||
args.maxstorage = 0; args.stats = True; args.verbose = False; args.log = '-';
|
|
||||||
return args
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
path = sys.argv[1]
|
path = sys.argv[1]
|
||||||
args = get_args()
|
pc = int(sys.argv[2], 0)
|
||||||
|
|
||||||
args.programs = sys.argv[1:]
|
m = Manticore(path)
|
||||||
# Create a new Manticore object
|
|
||||||
m = Manticore(None, path, args)
|
|
||||||
|
|
||||||
# Trigger an event when PC reaches a certain value
|
# Trigger an event when PC reaches a certain value
|
||||||
|
@m.hook(pc)
|
||||||
def reached_goal(state):
|
def reached_goal(state):
|
||||||
cpu = state.cpu
|
cpu = state.cpu
|
||||||
|
|
||||||
assert cpu.PC == 0x10858
|
assert cpu.PC == pc
|
||||||
|
|
||||||
instruction = cpu.read(cpu.PC, 4)
|
instruction = cpu.read_int(cpu.PC)
|
||||||
print "Execution goal reached."
|
print "Execution goal reached."
|
||||||
print "Instruction bytes: {:08x}".format(cpu.pc)
|
print "Instruction bytes: {:08x}".format(instruction)
|
||||||
|
|
||||||
m.add_pc_hook(0x10858, reached_goal)
|
# Start path exploration. m.run() returns when Manticore
|
||||||
|
|
||||||
# Start path exploration. start() returns when Manticore
|
|
||||||
# finishes
|
# finishes
|
||||||
m.run()
|
m.run()
|
||||||
|
|
||||||
|
|||||||
@ -12,11 +12,11 @@ if __name__ == '__main__':
|
|||||||
# Set to the address of the conditonal checking for the first complex branch
|
# Set to the address of the conditonal checking for the first complex branch
|
||||||
to_abandon = int(sys.argv[2], 0)
|
to_abandon = int(sys.argv[2], 0)
|
||||||
|
|
||||||
|
@m.hook(to_abandon)
|
||||||
def explore(state):
|
def explore(state):
|
||||||
print "Abandoning state at PC: ", hex(state.cpu.PC)
|
print "Abandoning state at PC: ", hex(state.cpu.PC)
|
||||||
state.abandon()
|
state.abandon()
|
||||||
|
|
||||||
print "Adding hook to: ", hex(to_abandon)
|
print "Adding hook to: ", hex(to_abandon)
|
||||||
m.add_hook(to_abandon, explore)
|
|
||||||
|
|
||||||
m.run()
|
m.run()
|
||||||
|
|||||||
@ -305,10 +305,21 @@ class Manticore(object):
|
|||||||
logging.getLogger(log_type).setLevel(level)
|
logging.getLogger(log_type).setLevel(level)
|
||||||
self._verbosity = setting
|
self._verbosity = setting
|
||||||
|
|
||||||
|
def hook(self, pc):
|
||||||
|
'''
|
||||||
|
A decorator used to register a hook function for a given instruction address
|
||||||
|
(`pc`). Equivalent to calling `add_hook`.
|
||||||
|
'''
|
||||||
|
def decorator(f):
|
||||||
|
self.add_hook(pc, f)
|
||||||
|
return f
|
||||||
|
return decorator
|
||||||
|
|
||||||
def add_hook(self, pc, callback):
|
def add_hook(self, pc, callback):
|
||||||
'''
|
'''
|
||||||
Add a callback to be invoked on executing a program counter. Pass 'None'
|
Add a callback to be invoked on executing a program counter. Pass 'None'
|
||||||
for pc to invoke callback on every instruction.
|
for pc to invoke callback on every instruction. `callback` should be a callable
|
||||||
|
that takes one `manticore.core.executor.State` argument.
|
||||||
'''
|
'''
|
||||||
if not (isinstance(pc, (int, long)) or pc is None):
|
if not (isinstance(pc, (int, long)) or pc is None):
|
||||||
raise TypeError("pc must be either an int or None, not {}".format(pc.__class__.__name__))
|
raise TypeError("pc must be either an int or None, not {}".format(pc.__class__.__name__))
|
||||||
|
|||||||
21
test/test_manticore.py
Normal file
21
test/test_manticore.py
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
import unittest
|
||||||
|
|
||||||
|
from manticore import Manticore
|
||||||
|
|
||||||
|
class ManticoreTest(unittest.TestCase):
|
||||||
|
def setUp(self):
|
||||||
|
self.m = Manticore('test/binaries/arguments_linux_amd64')
|
||||||
|
|
||||||
|
def test_add_hook(self):
|
||||||
|
def tmp(state):
|
||||||
|
pass
|
||||||
|
entry = 0x00400e40
|
||||||
|
self.m.add_hook(entry, tmp)
|
||||||
|
self.assertTrue(tmp in self.m._hooks[entry])
|
||||||
|
|
||||||
|
def test_hook_dec(self):
|
||||||
|
entry = 0x00400e40
|
||||||
|
@self.m.hook(entry)
|
||||||
|
def tmp(state):
|
||||||
|
pass
|
||||||
|
self.assertTrue(tmp in self.m._hooks[entry])
|
||||||
Loading…
x
Reference in New Issue
Block a user