Work-in-Progress support for NetBSD/amd64 binaries
This commit is contained in:
parent
07740c2fc7
commit
f22afeb235
@ -1,4 +1,4 @@
|
||||
from .x86 import AMD64Cpu, I386Cpu, AMD64LinuxSyscallAbi, I386LinuxSyscallAbi, I386CdeclAbi, SystemVAbi
|
||||
from .x86 import AMD64Cpu, I386Cpu, AMD64LinuxSyscallAbi, AMD64NetBSDSyscallAbi, I386LinuxSyscallAbi, I386CdeclAbi, SystemVAbi
|
||||
from .arm import Armv7Cpu, Armv7CdeclAbi, Armv7LinuxSyscallAbi
|
||||
|
||||
|
||||
@ -17,7 +17,7 @@ class CpuFactory(object):
|
||||
def get_function_abi(cpu, os, machine):
|
||||
if os == 'linux' and machine == 'i386':
|
||||
return I386CdeclAbi(cpu)
|
||||
elif os == 'linux' and machine == 'amd64':
|
||||
elif (os == 'linux' or os == 'netbsd') and machine == 'amd64':
|
||||
return SystemVAbi(cpu)
|
||||
elif os == 'linux' and machine == 'armv7':
|
||||
return Armv7CdeclAbi(cpu)
|
||||
@ -32,5 +32,7 @@ class CpuFactory(object):
|
||||
return AMD64LinuxSyscallAbi(cpu)
|
||||
elif os == 'linux' and machine == 'armv7':
|
||||
return Armv7LinuxSyscallAbi(cpu)
|
||||
elif os == 'netbsd' and machine == 'amd64':
|
||||
return AMD64NetBSDSyscallAbi(cpu)
|
||||
else:
|
||||
return NotImplementedError("OS and machine combination not supported: {}/{}".format(os, machine))
|
||||
|
||||
@ -5952,6 +5952,25 @@ class AMD64LinuxSyscallAbi(SyscallAbi):
|
||||
self._cpu.RAX = result
|
||||
|
||||
|
||||
class AMD64NetBSDSyscallAbi(SyscallAbi):
|
||||
'''
|
||||
AMD64 NetBSD system call ABI
|
||||
'''
|
||||
|
||||
# TODO(yan): Floating point or wide arguments that deviate from the norm are
|
||||
# not yet supported.
|
||||
|
||||
def syscall_number(self):
|
||||
return self._cpu.RAX
|
||||
|
||||
def get_arguments(self):
|
||||
for reg in ('RDI', 'RSI', 'RDX', 'R10', 'R8', 'R9'):
|
||||
yield reg
|
||||
|
||||
def write_result(self, result):
|
||||
self._cpu.RAX = result
|
||||
|
||||
|
||||
class I386CdeclAbi(Abi):
|
||||
'''
|
||||
i386 cdecl function call semantics
|
||||
|
||||
@ -11,16 +11,17 @@ from contextlib import contextmanager
|
||||
|
||||
from threading import Timer
|
||||
|
||||
# FIXME: remove this three
|
||||
# FIXME: remove these
|
||||
import elftools
|
||||
from elftools.elf.elffile import ELFFile
|
||||
from elftools.elf.sections import NoteSection
|
||||
from elftools.elf.sections import SymbolTableSection
|
||||
|
||||
from .core.executor import Executor
|
||||
from .core.state import State, TerminateState
|
||||
from .core.smtlib import solver, ConstraintSet
|
||||
from .core.workspace import ManticoreOutput
|
||||
from .platforms import linux, decree, evm
|
||||
from .platforms import linux, netbsd, decree, evm
|
||||
from .utils.helpers import issymbolic, is_binja_disassembler
|
||||
from .utils.nointerrupt import WithKeyboardInterruptAs
|
||||
from .utils.event import Eventful
|
||||
@ -76,6 +77,19 @@ def make_decree(program, concrete_start='', **kwargs):
|
||||
return initial_state
|
||||
|
||||
|
||||
def make_elf(program, argv=None, env=None, entry_symbol=None, symbolic_files=None, concrete_start=''):
|
||||
#with open(program, 'rb') as f:
|
||||
with open(program, 'rb') as f:
|
||||
for sect in ELFFile(f).iter_sections():
|
||||
if not isinstance(sect, NoteSection):
|
||||
continue
|
||||
for note in sect.iter_notes():
|
||||
if note['n_name'] == 'NetBSD':
|
||||
logger.info("NetBSD binary detected")
|
||||
return make_netbsd(program, argv, env, entry_symbol, symbolic_files, concrete_start)
|
||||
return make_linux(program, argv, env, entry_symbol, symbolic_files, concrete_start)
|
||||
|
||||
|
||||
def make_linux(program, argv=None, env=None, entry_symbol=None, symbolic_files=None, concrete_start=''):
|
||||
env = {} if env is None else env
|
||||
argv = [] if argv is None else argv
|
||||
@ -120,6 +134,50 @@ def make_linux(program, argv=None, env=None, entry_symbol=None, symbolic_files=N
|
||||
return initial_state
|
||||
|
||||
|
||||
def make_netbsd(program, argv=None, env=None, entry_symbol=None, symbolic_files=None, concrete_start=''):
|
||||
env = {} if env is None else env
|
||||
argv = [] if argv is None else argv
|
||||
env = ['%s=%s' % (k, v) for k, v in env.items()]
|
||||
|
||||
logger.info('Loading program %s', program)
|
||||
|
||||
constraints = ConstraintSet()
|
||||
platform = netbsd.SNetBSD(program, argv=argv, envp=env,
|
||||
symbolic_files=symbolic_files)
|
||||
if entry_symbol is not None:
|
||||
entry_pc = platform._find_symbol(entry_symbol)
|
||||
if entry_pc is None:
|
||||
logger.error("No symbol for '%s' in %s", entry_symbol, program)
|
||||
raise Exception("Symbol not found")
|
||||
else:
|
||||
logger.info("Found symbol '%s' (%x)", entry_symbol, entry_pc)
|
||||
#TODO: use argv as arguments for function
|
||||
platform.set_entry(entry_pc)
|
||||
|
||||
initial_state = State(constraints, platform)
|
||||
|
||||
if concrete_start != '':
|
||||
logger.info('Starting with concrete input: %s', concrete_start)
|
||||
|
||||
for i, arg in enumerate(argv):
|
||||
argv[i] = initial_state.symbolicate_buffer(arg, label='ARGV%d' % (i + 1))
|
||||
|
||||
for i, evar in enumerate(env):
|
||||
env[i] = initial_state.symbolicate_buffer(evar, label='ENV%d' % (i + 1))
|
||||
|
||||
# If any of the arguments or environment refer to symbolic values, re-
|
||||
# initialize the stack
|
||||
if any(issymbolic(x) for val in argv + env for x in val):
|
||||
platform.setup_stack([program] + argv, env)
|
||||
|
||||
platform.input.write(concrete_start)
|
||||
|
||||
# set stdin input...
|
||||
platform.input.write(initial_state.symbolicate_buffer('+' * 256,
|
||||
label='STDIN'))
|
||||
return initial_state
|
||||
|
||||
|
||||
def make_initial_state(binary_path, **kwargs):
|
||||
if 'disasm' in kwargs:
|
||||
if kwargs.get('disasm') == "binja-il":
|
||||
@ -128,8 +186,8 @@ def make_initial_state(binary_path, **kwargs):
|
||||
del kwargs['disasm']
|
||||
magic = file(binary_path).read(4)
|
||||
if magic == '\x7fELF':
|
||||
# Linux
|
||||
state = make_linux(binary_path, **kwargs)
|
||||
# ELF
|
||||
state = make_elf(binary_path, **kwargs)
|
||||
elif magic == '\x7fCGC':
|
||||
# Decree
|
||||
state = make_decree(binary_path, **kwargs)
|
||||
|
||||
2553
manticore/platforms/netbsd.py
Normal file
2553
manticore/platforms/netbsd.py
Normal file
File diff suppressed because it is too large
Load Diff
27
manticore/platforms/netbsd_syscalls.py
Normal file
27
manticore/platforms/netbsd_syscalls.py
Normal file
@ -0,0 +1,27 @@
|
||||
amd64 = {
|
||||
1: "sys_exit",
|
||||
2: "sys_fork",
|
||||
3: "sys_read",
|
||||
4: "sys_write",
|
||||
5: "sys_open",
|
||||
6: "sys_close",
|
||||
9: "sys_link",
|
||||
10: "sys_unlink",
|
||||
12: "sys_chdir",
|
||||
15: "sys_chmod",
|
||||
17: "sys_brk",
|
||||
20: "sys_getpid",
|
||||
22: "sys_unmount",
|
||||
23: "sys_setuid",
|
||||
24: "sys_getuid",
|
||||
25: "sys_geteuid",
|
||||
26: "sys_ptrace",
|
||||
33: "sys_access",
|
||||
36: "sys_sync",
|
||||
37: "sys_kill",
|
||||
39: "sys_getppid",
|
||||
41: "sys_dup",
|
||||
42: "sys_pipe",
|
||||
58: "sys_readlink",
|
||||
92: "sys_fcntl",
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user