@@ -1,3 +1,7 @@
|
||||
import fcntl
|
||||
|
||||
import cgcrandom
|
||||
import weakref
|
||||
import errno
|
||||
import os, struct
|
||||
from ..utils.helpers import issymbolic
|
||||
@@ -35,7 +39,7 @@ class SymbolicSyscallArgument(Exception):
|
||||
|
||||
class File(object):
|
||||
def __init__(self, *args, **kwargs):
|
||||
#Todo: assert file is seekable otherwise we should save wwhat was
|
||||
#Todo: assert file is seekable otherwise we should save what was
|
||||
#read/write to the state
|
||||
self.file = file(*args,**kwargs)
|
||||
def stat(self):
|
||||
@@ -109,6 +113,7 @@ class SymbolicFile(object):
|
||||
else:
|
||||
symbols_cnt+=1
|
||||
|
||||
self._constraints = constraints
|
||||
self.pos = 0
|
||||
self.max_size=min(len(data), max_size)
|
||||
if symbols_cnt > max_size:
|
||||
@@ -130,7 +135,7 @@ class SymbolicFile(object):
|
||||
|
||||
@property
|
||||
def constraints(self):
|
||||
return self._constraints()
|
||||
return self._constraints
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
@@ -257,13 +262,17 @@ class Linux(object):
|
||||
This class emulates the most common Linux system calls
|
||||
'''
|
||||
|
||||
def __init__(self, program, argv=[], envp=[]):
|
||||
def __init__(self, program, argv=None, envp=None):
|
||||
'''
|
||||
Builds a Linux OS model
|
||||
:param string program: The path to ELF binary
|
||||
:param list argv: The argv array; not including binary.
|
||||
:param list envp: The ENV variables.
|
||||
'''
|
||||
|
||||
argv = [] if argv is None else argv
|
||||
envp = [] if envp is None else envp
|
||||
|
||||
self.program = program
|
||||
self.clocks = 0
|
||||
self.files = []
|
||||
@@ -503,7 +512,7 @@ class Linux(object):
|
||||
#load vdso #TODO or #IGNORE
|
||||
vdso_top = {32: 0x7fff0000, 64: 0x7fff00007fff0000}[bits]
|
||||
vdso_size = len(file('vdso%2d.dump'%bits).read())
|
||||
vdso_addr = cpu.memory.mmapFile(cpu.memory._floor(vdso_top - vdso_size),
|
||||
vdso_addr = self.memory.mmapFile(self.memory._floor(vdso_top - vdso_size),
|
||||
vdso_size, 'r x',
|
||||
{32: 'vdso32.dump', 64: 'vdso64.dump'}[bits],
|
||||
0 )
|
||||
@@ -754,7 +763,7 @@ class Linux(object):
|
||||
logger.debug("Main elf brk %x:"%elf_brk)
|
||||
|
||||
#FIXME Need a way to inspect maps and perms so
|
||||
#we can roollback all to the initial state after zeroing
|
||||
#we can rollback all to the initial state after zeroing
|
||||
#if elf_brk-elf_bss > 0:
|
||||
# saved_perms = cpu.mem.perms(elf_bss)
|
||||
# cpu.memory.mprotect(cpu.mem._ceil(elf_bss), elf_brk-elf_bss, 'rw ')
|
||||
@@ -947,7 +956,7 @@ class Linux(object):
|
||||
|
||||
|
||||
:param self: current CPU.
|
||||
:param fd: a valid file descripor
|
||||
:param fd: a valid file descriptor
|
||||
:param offset: the offset in bytes
|
||||
:param whence: SEEK_SET: The file offset is set to offset bytes.
|
||||
SEEK_CUR: The file offset is set to its current location plus offset bytes.
|
||||
@@ -1001,7 +1010,7 @@ class Linux(object):
|
||||
and optionally sets *tx_bytes to zero.
|
||||
|
||||
:param cpu current CPU
|
||||
:param fd a valid file descripor
|
||||
:param fd a valid file descriptor
|
||||
:param buf a memory buffer
|
||||
:param count number of bytes to send
|
||||
:return: 0 Success
|
||||
@@ -1017,7 +1026,7 @@ class Linux(object):
|
||||
|
||||
# TODO check count bytes from buf
|
||||
if buf not in cpu.memory or buf+count not in cpu.memory:
|
||||
logger.debug("WRITE: buf points to invalid address. Rerurning EFAULT")
|
||||
logger.debug("WRITE: buf points to invalid address. Returning EFAULT")
|
||||
return errno.EFAULT
|
||||
|
||||
if fd > 2 and self.files[fd].is_full():
|
||||
@@ -1175,11 +1184,11 @@ class Linux(object):
|
||||
return 0
|
||||
|
||||
def sys_sigaction(self, cpu, signum, act, oldact):
|
||||
logger.debug("SIGACTION, Ignoring chaging signal handler for signal %d", signum)
|
||||
logger.debug("SIGACTION, Ignoring changing signal handler for signal %d", signum)
|
||||
return 0
|
||||
|
||||
def sys_sigprocmask(self, how, newset, oldset):
|
||||
logger.debug("SIGACTION, Ignoring chaging signal mask set cmd:%d", how)
|
||||
logger.debug("SIGACTION, Ignoring changing signal mask set cmd:%d", how)
|
||||
return 0
|
||||
|
||||
def sys_close(self, cpu, fd):
|
||||
@@ -1298,8 +1307,8 @@ class Linux(object):
|
||||
size = cpu.read_int(iov + i * 16 + 8, 64)
|
||||
|
||||
data = ""
|
||||
for i in xrange(0,size):
|
||||
data += Operators.CHR(cpu.read_int(buf + i, 8))
|
||||
for j in xrange(0,size):
|
||||
data += Operators.CHR(cpu.read_int(buf + j, 8))
|
||||
logger.debug("WRITEV(%r, %r, %r) -> <%r> (size:%r)"%(fd, buf, size, data, len(data)))
|
||||
self.files[fd].write(data)
|
||||
total+=size
|
||||
@@ -1322,9 +1331,9 @@ class Linux(object):
|
||||
size = cpu.read_int(iov + i * 8 + 4, 32)
|
||||
|
||||
data = ""
|
||||
for i in xrange(0,size):
|
||||
data += Operators.CHR(cpu.read_int(buf + i, 8))
|
||||
self.files[fd].write(Operators.CHR(cpu.read_int(buf + i, 8)))
|
||||
for j in xrange(0,size):
|
||||
data += Operators.CHR(cpu.read_int(buf + j, 8))
|
||||
self.files[fd].write(Operators.CHR(cpu.read_int(buf + j, 8)))
|
||||
logger.debug("WRITEV(%r, %r, %r) -> <%r> (size:%r)"%(fd, buf, size, data, len(data)))
|
||||
total+=size
|
||||
return total
|
||||
@@ -1568,9 +1577,9 @@ class Linux(object):
|
||||
|
||||
def sched(self):
|
||||
''' Yield CPU.
|
||||
This will choose another process from the RUNNNIG list and change
|
||||
This will choose another process from the running list and change
|
||||
current running process. May give the same cpu if only one running
|
||||
proccess.
|
||||
process.
|
||||
'''
|
||||
if len(self.procs)>1:
|
||||
logger.debug("SCHED:")
|
||||
@@ -1599,7 +1608,7 @@ class Linux(object):
|
||||
|
||||
def wait(self, readfds, writefds, timeout):
|
||||
''' Wait for filedescriptors or timout.
|
||||
Adds the current proceess in the correspondant wainting list and
|
||||
Adds the current process in the correspondant wainting list and
|
||||
yield the cpu to another running process.
|
||||
'''
|
||||
logger.debug("WAIT:")
|
||||
@@ -1664,7 +1673,7 @@ class Linux(object):
|
||||
self.awake(procid)
|
||||
|
||||
def check_timers(self):
|
||||
''' Awake proccess if timer has expired '''
|
||||
''' Awake process if timer has expired '''
|
||||
if self._current is None :
|
||||
#Advance the clocks. Go to future!!
|
||||
advance = min([self.clocks] + filter(lambda x: x is not None, self.timers)) +1
|
||||
@@ -1679,7 +1688,7 @@ class Linux(object):
|
||||
|
||||
def execute(self):
|
||||
"""
|
||||
Execute one cpu instruction in the current thread (only one suported).
|
||||
Execute one cpu instruction in the current thread (only one supported).
|
||||
:rtype: bool
|
||||
:return: C{True}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import cgcrandom
|
||||
import weakref
|
||||
import sys, os, struct
|
||||
from ..core.memory import Memory, MemoryException, SMemory32
|
||||
from ..core.memory import Memory, MemoryException, SMemory32, Memory32
|
||||
from ..core.smtlib import Expression, Operators, solver
|
||||
# TODO use cpu factory
|
||||
from ..core.cpu.x86 import I386Cpu, Sysenter
|
||||
|
||||
Reference in New Issue
Block a user