Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def value(self):
return self.relative_addr
class BinjaBin(Backend):
"""
Get information from binaries using Binary Ninja. Basing this on idabin.py, but will try to be more complete.
TODO: add more features as Binary Ninja's feature set improves
"""
is_default = True # Tell CLE to automatically consider using the BinjaBin backend
BINJA_ARCH_MAP = {"aarch64": archinfo.ArchAArch64(endness='Iend_LE'),
"armv7": archinfo.ArchARMEL(endness='Iend_LE'),
"thumb2": archinfo.ArchARMEL(endness='Iend_LE'),
"armv7eb": archinfo.ArchARMEL(endness='Iend_BE'),
"thumb2eb": archinfo.ArchARMEL(endness='Iend_BE'),
"mipsel32": archinfo.ArchMIPS32(endness='Iend_LE'),
"mips32": archinfo.ArchMIPS32(endness='Iend_BE'),
"ppc": archinfo.ArchPPC32(endness="Iend_BE"),
"ppc_le": archinfo.ArchPPC32(endness="Iend_LE"),
"x86": archinfo.ArchX86(),
"x86_64": archinfo.ArchAMD64()}
def __init__(self, binary, *args, **kwargs):
super().__init__(binary, *args, **kwargs)
if not bn:
raise CLEError(BINJA_NOT_INSTALLED_STR)
# get_view_of_file can take a bndb or binary - wait for autoanalysis to complete
self.bv = bn.BinaryViewType.get_view_of_file(binary, False)
l.info("Analyzing %s, this may take some time...", binary)
self.bv.update_analysis_and_wait()
l.info("Analysis complete")
# Note may want to add option to kick off linear sweep
def prepare_call_state(self, calling_state, initial_state=None,
preserve_registers=(), preserve_memory=()):
"""
This function prepares a state that is executing a call instruction.
If given an initial_state, it copies over all of the critical registers to it from the
calling_state. Otherwise, it prepares the calling_state for action.
This is mostly used to create minimalistic for CFG generation. Some ABIs, such as MIPS PIE and
x86 PIE, require certain information to be maintained in certain registers. For example, for
PIE MIPS, this function transfer t9, gp, and ra to the new state.
"""
if isinstance(self.arch, ArchMIPS32):
if initial_state is not None:
initial_state = self.state_blank()
mips_caller_saves = ('s0', 's1', 's2', 's3', 's4', 's5', 's6', 's7', 'gp', 'sp', 'bp', 'ra')
preserve_registers = preserve_registers + mips_caller_saves + ('t9',)
if initial_state is None:
new_state = calling_state.copy()
else:
new_state = initial_state.copy()
for reg in set(preserve_registers):
new_state.registers.store(reg, calling_state.registers.load(reg))
for addr, val in set(preserve_memory):
new_state.memory.store(addr, calling_state.memory.load(addr, val))
return new_state
def prepare_call_state(self, calling_state, initial_state=None,
preserve_registers=(), preserve_memory=()):
"""
This function prepares a state that is executing a call instruction.
If given an initial_state, it copies over all of the critical registers to it from the
calling_state. Otherwise, it prepares the calling_state for action.
This is mostly used to create minimalistic for CFG generation. Some ABIs, such as MIPS PIE and
x86 PIE, require certain information to be maintained in certain registers. For example, for
PIE MIPS, this function transfer t9, gp, and ra to the new state.
"""
if isinstance(self.arch, ArchMIPS32):
if initial_state is not None:
initial_state = self.state_blank()
mips_caller_saves = ('s0', 's1', 's2', 's3', 's4', 's5', 's6', 's7', 'gp', 'sp', 'bp', 'ra')
preserve_registers = preserve_registers + mips_caller_saves + ('t9',)
if initial_state is None:
new_state = calling_state.copy()
else:
new_state = initial_state.copy()
for reg in set(preserve_registers):
new_state.registers.store(reg, calling_state.registers.load(reg))
for addr, val in set(preserve_memory):
new_state.memory.store(addr, calling_state.memory.load(addr, val))
return new_state
def state_blank(self, fs=None, concrete_fs=False, chroot=None, **kwargs):
state = super(SimLinux, self).state_blank(**kwargs)
if self.project.loader.tls_object is not None:
if isinstance(state.arch, ArchAMD64):
state.regs.fs = self.project.loader.tls_object.user_thread_pointer
elif isinstance(state.arch, ArchX86):
state.regs.gs = self.project.loader.tls_object.user_thread_pointer >> 16
elif isinstance(state.arch, (ArchMIPS32, ArchMIPS64)):
state.regs.ulr = self.project.loader.tls_object.user_thread_pointer
elif isinstance(state.arch, ArchPPC32):
state.regs.r2 = self.project.loader.tls_object.user_thread_pointer
elif isinstance(state.arch, ArchPPC64):
state.regs.r13 = self.project.loader.tls_object.user_thread_pointer
elif isinstance(state.arch, ArchAArch64):
state.regs.tpidr_el0 = self.project.loader.tls_object.user_thread_pointer
last_addr = self.project.loader.main_object.max_addr
brk = last_addr - last_addr % 0x1000 + 0x1000
state.register_plugin('posix', SimStateSystem(fs=fs, concrete_fs=concrete_fs, chroot=chroot, brk=brk))
if self.project.loader.main_object.is_ppc64_abiv1:
state.libc.ppc64_abiv = 'ppc64_1'
def state_blank(self, fs=None, concrete_fs=False, chroot=None,
cwd=b'/home/user', pathsep=b'/', **kwargs):
state = super(SimLinux, self).state_blank(**kwargs)
if self.project.loader.tls_object is not None:
if isinstance(state.arch, ArchAMD64):
state.regs.fs = self.project.loader.tls_object.user_thread_pointer
elif isinstance(state.arch, ArchX86):
state.regs.gs = self.project.loader.tls_object.user_thread_pointer >> 16
elif isinstance(state.arch, (ArchMIPS32, ArchMIPS64)):
state.regs.ulr = self.project.loader.tls_object.user_thread_pointer
elif isinstance(state.arch, ArchPPC32):
state.regs.r2 = self.project.loader.tls_object.user_thread_pointer
elif isinstance(state.arch, ArchPPC64):
state.regs.r13 = self.project.loader.tls_object.user_thread_pointer
elif isinstance(state.arch, ArchAArch64):
state.regs.tpidr_el0 = self.project.loader.tls_object.user_thread_pointer
if fs is None:
fs = {}
for name in fs:
if type(fs[name]) is str:
fs[name] = fs[name].encode('utf-8')
if type(fs[name]) is bytes:
fs[name] = claripy.BVV(fs[name])
def state_blank(self, fs=None, concrete_fs=False, chroot=None, **kwargs):
state = super(SimLinux, self).state_blank(**kwargs) #pylint:disable=invalid-name
if self.proj.loader.tls_object is not None:
if isinstance(state.arch, ArchAMD64):
state.regs.fs = self.proj.loader.tls_object.thread_pointer
elif isinstance(state.arch, ArchX86):
state.regs.gs = self.proj.loader.tls_object.thread_pointer >> 16
elif isinstance(state.arch, ArchMIPS32):
state.regs.ulr = self.proj.loader.tls_object.thread_pointer
state.register_plugin('posix', SimStateSystem(fs=fs, concrete_fs=concrete_fs, chroot=chroot))
if self.proj.loader.main_bin.is_ppc64_abiv1:
state.libc.ppc64_abiv = 'ppc64_1'
return state
class SimCCO32(SimCC):
ARG_REGS = [ 'a0', 'a1', 'a2', 'a3' ]
FP_ARG_REGS = [] # TODO: ???
STACKARG_SP_BUFF = 16
CALLER_SAVED_REGS = [] # TODO: ???
RETURN_ADDR = SimRegArg('lr', 4)
RETURN_VAL = SimRegArg('v0', 4)
ARCH = archinfo.ArchMIPS32
class SimCCO32LinuxSyscall(SimCC):
# TODO: Make sure all the information is correct
ARG_REGS = [ 'a0', 'a1', 'a2', 'a3' ]
FP_ARG_REGS = [] # TODO: ???
RETURN_VAL = SimRegArg('v0', 4)
RETURN_ADDR = SimRegArg('ip_at_syscall', 4)
ARCH = archinfo.ArchMIPS32
@classmethod
def _match(cls, arch, args, sp_delta): # pylint: disable=unused-argument
# never appears anywhere except syscalls
return False
@staticmethod
def syscall_num(state):
return state.regs.v0
class SimCCO64(SimCC): # TODO: add n32 and n64
ARG_REGS = [ 'a0', 'a1', 'a2', 'a3' ]
FP_ARG_REGS = [] # TODO: ???
STACKARG_SP_BUFF = 32
RETURN_ADDR = SimRegArg('lr', 8)
RETURN_VAL = SimRegArg('v0', 8)
def __init__(self, endianess=Endianess.LITTLE):
super(ArchitectureMips,self).__init__(CS_ARCH_MIPS, CS_MODE_32, 4, 4, endianess, branch_delay_slot=True)
self._name = 'MIPS'
if 'keystone' in globals():
self._ksarch = (keystone.KS_ARCH_MIPS, keystone.KS_MODE_MIPS32)
if 'archinfo' in globals():
self._info = archinfo.ArchMIPS32()
self._searcher = SearcherMIPS()