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
|
from .arm import Armv7Cpu, Armv7CdeclAbi, Armv7LinuxSyscallAbi
|
||||||
|
|
||||||
|
|
||||||
@ -17,7 +17,7 @@ class CpuFactory(object):
|
|||||||
def get_function_abi(cpu, os, machine):
|
def get_function_abi(cpu, os, machine):
|
||||||
if os == 'linux' and machine == 'i386':
|
if os == 'linux' and machine == 'i386':
|
||||||
return I386CdeclAbi(cpu)
|
return I386CdeclAbi(cpu)
|
||||||
elif os == 'linux' and machine == 'amd64':
|
elif (os == 'linux' or os == 'netbsd') and machine == 'amd64':
|
||||||
return SystemVAbi(cpu)
|
return SystemVAbi(cpu)
|
||||||
elif os == 'linux' and machine == 'armv7':
|
elif os == 'linux' and machine == 'armv7':
|
||||||
return Armv7CdeclAbi(cpu)
|
return Armv7CdeclAbi(cpu)
|
||||||
@ -32,5 +32,7 @@ class CpuFactory(object):
|
|||||||
return AMD64LinuxSyscallAbi(cpu)
|
return AMD64LinuxSyscallAbi(cpu)
|
||||||
elif os == 'linux' and machine == 'armv7':
|
elif os == 'linux' and machine == 'armv7':
|
||||||
return Armv7LinuxSyscallAbi(cpu)
|
return Armv7LinuxSyscallAbi(cpu)
|
||||||
|
elif os == 'netbsd' and machine == 'amd64':
|
||||||
|
return AMD64NetBSDSyscallAbi(cpu)
|
||||||
else:
|
else:
|
||||||
return NotImplementedError("OS and machine combination not supported: {}/{}".format(os, machine))
|
return NotImplementedError("OS and machine combination not supported: {}/{}".format(os, machine))
|
||||||
|
|||||||
@ -5952,6 +5952,25 @@ class AMD64LinuxSyscallAbi(SyscallAbi):
|
|||||||
self._cpu.RAX = result
|
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):
|
class I386CdeclAbi(Abi):
|
||||||
'''
|
'''
|
||||||
i386 cdecl function call semantics
|
i386 cdecl function call semantics
|
||||||
|
|||||||
@ -11,16 +11,17 @@ from contextlib import contextmanager
|
|||||||
|
|
||||||
from threading import Timer
|
from threading import Timer
|
||||||
|
|
||||||
# FIXME: remove this three
|
# FIXME: remove these
|
||||||
import elftools
|
import elftools
|
||||||
from elftools.elf.elffile import ELFFile
|
from elftools.elf.elffile import ELFFile
|
||||||
|
from elftools.elf.sections import NoteSection
|
||||||
from elftools.elf.sections import SymbolTableSection
|
from elftools.elf.sections import SymbolTableSection
|
||||||
|
|
||||||
from .core.executor import Executor
|
from .core.executor import Executor
|
||||||
from .core.state import State, TerminateState
|
from .core.state import State, TerminateState
|
||||||
from .core.smtlib import solver, ConstraintSet
|
from .core.smtlib import solver, ConstraintSet
|
||||||
from .core.workspace import ManticoreOutput
|
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.helpers import issymbolic, is_binja_disassembler
|
||||||
from .utils.nointerrupt import WithKeyboardInterruptAs
|
from .utils.nointerrupt import WithKeyboardInterruptAs
|
||||||
from .utils.event import Eventful
|
from .utils.event import Eventful
|
||||||
@ -76,6 +77,19 @@ def make_decree(program, concrete_start='', **kwargs):
|
|||||||
return initial_state
|
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=''):
|
def make_linux(program, argv=None, env=None, entry_symbol=None, symbolic_files=None, concrete_start=''):
|
||||||
env = {} if env is None else env
|
env = {} if env is None else env
|
||||||
argv = [] if argv is None else argv
|
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
|
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):
|
def make_initial_state(binary_path, **kwargs):
|
||||||
if 'disasm' in kwargs:
|
if 'disasm' in kwargs:
|
||||||
if kwargs.get('disasm') == "binja-il":
|
if kwargs.get('disasm') == "binja-il":
|
||||||
@ -128,8 +186,8 @@ def make_initial_state(binary_path, **kwargs):
|
|||||||
del kwargs['disasm']
|
del kwargs['disasm']
|
||||||
magic = file(binary_path).read(4)
|
magic = file(binary_path).read(4)
|
||||||
if magic == '\x7fELF':
|
if magic == '\x7fELF':
|
||||||
# Linux
|
# ELF
|
||||||
state = make_linux(binary_path, **kwargs)
|
state = make_elf(binary_path, **kwargs)
|
||||||
elif magic == '\x7fCGC':
|
elif magic == '\x7fCGC':
|
||||||
# Decree
|
# Decree
|
||||||
state = make_decree(binary_path, **kwargs)
|
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