Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add symbol resolution feature for binary analysis #1302

Merged
merged 4 commits into from
Jan 1, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 42 additions & 22 deletions manticore/native/manticore.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ def __init__(self, path_or_state, argv=None, workspace_url=None, policy='random'
if isinstance(path_or_state, str):
if not os.path.isfile(path_or_state):
raise OSError(f'{path_or_state} is not an existing regular file')

initial_state = _make_initial_state(path_or_state, argv=argv, **kwargs)
else:
initial_state = path_or_state
Expand Down Expand Up @@ -79,6 +78,19 @@ def decree(cls, path, concrete_start='', **kwargs):
except KeyError: # FIXME(mark) magic parsing for DECREE should raise better error
raise Exception(f'Invalid binary: {path}')

@property
def binary_path(self):
"""
Assumes that self._initial_state.platform.program always
refers to current program. Might not be true in case program
calls execve().
"""
return self._initial_state.platform.program

###############################
# Hook Callback Methods
###############################

def init(self, f):
'''
A decorator used to register a hook function to run before analysis begins. Hook
Expand Down Expand Up @@ -137,32 +149,40 @@ def _hook_callback(self, state, pc, instruction):
for cb in self._hooks.get(None, []):
cb(state)

#############################################################################
#############################################################################
#############################################################################
# Move all the following elsewhere Not all manticores have this
def _get_symbol_address(self, symbol):
'''
Return the address of |symbol| within the binary
'''
###############################
# Symbol Resolution
###############################

def resolve(self, symbol):
"""
A helper method used to resolve a symbol name into a memory address when
injecting hooks for analysis.

:param symbol: function name to be resolved
:type symbol: string

:param line: if more functions present, optional line number can be included
:type line: int or None
"""

with open(self.binary_path, 'rb') as f:

# XXX(yan) This is a bit obtuse; once PE support is updated this should
# be refactored out
if self._binary_type == 'ELF':
self._binary_obj = ELFFile(open(self._binary, 'rb'))
elffile = ELFFile(f)

if self._binary_obj is None:
return NotImplementedError("Symbols aren't supported")
# iterate over sections and identify symbol table section
for section in elffile.iter_sections():
if not isinstance(section, SymbolTableSection):
continue

for section in self._binary_obj.iter_sections():
if not isinstance(section, SymbolTableSection):
continue
# get list of symbols by name
symbols = section.get_symbol_by_name(symbol)
if not symbols:
continue

symbols = section.get_symbol_by_name(symbol)
if not symbols:
continue
# return first indexed memory address for the symbol,
return symbols[0].entry['st_value']

return symbols[0].entry['st_value']
raise ValueError(f"The {self.binary_path} ELFfile does not contain symbol {symbol}")


def _make_initial_state(binary_path, **kwargs):
Expand Down
2 changes: 2 additions & 0 deletions manticore/platforms/decree.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,8 @@ def __init__(self, programs, **kwargs):
'''
programs = programs.split(",")
super().__init__(path=programs[0], **kwargs)

self.program = programs[0]
self.clocks = 0
self.files = []
self.syscall_trace = []
Expand Down
9 changes: 9 additions & 0 deletions tests/test_manticore.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,15 @@ def test_hook_dec_err(self):
def tmp(state):
pass

def test_symbol_resolution(self):
dirname = os.path.dirname(__file__)
self.m = Manticore(os.path.join(dirname, 'binaries', 'basic_linux_amd64'))
self.assertTrue(self.m.resolve('sbrk'), 0x449ee0)

def test_symbol_resolution_fail(self):
with self.assertRaises(ValueError):
self.m.resolve("does_not_exist")

def test_integration_basic_stdin(self):
import struct
dirname = os.path.dirname(__file__)
Expand Down