Example #1
0
    def test_pickle(self):
        my_solver = Solver()
        mem = SMemory(my_solver, 32, 12)

        #start with no maps
        self.assertEqual(len(mem.mappings()), 0)
        #alloc/map a byte
        addr_a = mem.mmap(None, 0x1000, 'r')

        #one map
        self.assertEqual(len(mem.mappings()), 1)

        #file mapping
        rwx_file = tempfile.NamedTemporaryFile('w+b', delete=False)
        rwx_file.file.write('a'*0x3000)
        rwx_file.close()
        addr_f = mem.mmapFile(0, 0x3000, 'rwx', rwx_file.name)
        mem.munmap(addr_f+0x1000, 0x1000)
        #two map2
        self.assertEqual(len(mem.mappings()), 3)

        sym = my_solver.mkBitVec(8)
        mem.putchar(addr_f, sym)

        #save it
        
        s = StringIO(pickle.dumps(mem))

        #load it
        mem1 = pickle.load(s)

        #two maps
        self.assertEqual(len(mem1.mappings()), 3)

        os.unlink(rwx_file.name)
Example #2
0
    def testMultiSymbolic(self):
        my_solver = Solver()
        mem = SMemory(my_solver, 32, 12)

        #alloc/map a little mem
        size = 0x10000
        addr = mem.mmap(None, size, 'rwx')
        #initialize first 10 bytes as [100, 101, 102, .. 109]
        for i in xrange(addr, addr+10):
            mem.putchar(i, chr(100+i-addr))

        #Make a char that ranges from 'A' to 'Z'
        v = my_solver.mkBitVec(32) 
        my_solver.add(v>=ord('A'))
        my_solver.add(v<=ord('Z'))

        #assign it to the firt 10 bytes
        mem.putchar(addr+5, chr(v))


        #mak a free symbol of 32 bits
        x = my_solver.mkBitVec(32) 
        #constraint it to range into [addr, addr+10)
        my_solver.add(x>=addr)
        my_solver.add(x<addr+10)

        #so now lets ask the memory for values pointed by addr
        c = mem.getchar(x)
        for val in my_solver.getallvalues(c,1000):
            self.assertTrue(val>=100 and val<110 or val >= ord('A') and val <= ord('Z'))
Example #3
0
    def test_mix_of_concrete_and_symbolic(self):
        my_solver = Solver()
        mem = SMemory(my_solver, 32, 12)
        
        start_mapping_addr = mem.mmap(None, 0x1000, 'rwx')
        
        concretes = [0, 2, 4, 6]
        symbolics = [1, 3, 5, 7]
        
        for range in concretes:
            mem.putchar(start_mapping_addr+range, 'C')
        
        for range in symbolics:
            mem.putchar(start_mapping_addr+range, my_solver.mkBitVec(8))

        for range in concretes:
            self.assertTrue(isconcrete(mem.getchar(start_mapping_addr+range)))

        for range in concretes:
            self.assertFalse(issymbolic(mem.getchar(start_mapping_addr+range)))
        
        for range in symbolics:
            self.assertTrue(issymbolic(mem.getchar(start_mapping_addr+range)))                

        for range in symbolics:
            self.assertFalse(isconcrete(mem.getchar(start_mapping_addr+range)))
    
        for range in symbolics:
            mem.putchar(start_mapping_addr+range, 'C')
        
        for range in concretes:
            mem.putchar(start_mapping_addr+range, my_solver.mkBitVec(8))

        for range in symbolics:
            self.assertTrue(isconcrete(mem.getchar(start_mapping_addr+range)))

        for range in symbolics:
            self.assertFalse(issymbolic(mem.getchar(start_mapping_addr+range)))
        
        for range in concretes:
            self.assertTrue(issymbolic(mem.getchar(start_mapping_addr+range)))                

        for range in concretes:
            self.assertFalse(isconcrete(mem.getchar(start_mapping_addr+range)))
Example #4
0
    def testBasicSymbolic(self):
        my_solver = Solver()
        mem = SMemory(my_solver, 32, 12)

        #alloc/map a little mem
        size = 0x10000
        addr = mem.mmap(None, size, 'rwx')
        #initialize first 10 bytes as [100, 101, 102, .. 109]
        for i in xrange(addr, addr+10):
            mem.putchar(i, chr(100+i-addr))

        #mak a free symbol of 32 bits
        x = my_solver.mkBitVec(32) 
        #constraint it to range into [addr, addr+10)
        my_solver.add(x>=addr)
        my_solver.add(x<addr+10)

        #Well.. x is symbolic
        self.assertTrue(issymbolic(x))
        #It shall be a solution
        self.assertTrue(my_solver.check(), 'sat')
        #if we ask for a possible solution (an x that comply with the constraints)
        sol = my_solver.getvalue(x)
        #it should comply..
        self.assertTrue(sol >= addr and sol<addr+10)

        #min and max value should be addr and addr+9
        m, M = my_solver.minmax(x)
        self.assertEqual(m, addr)
        self.assertEqual(M, addr+9)

        #If we ask for all possible solutions...
        for val in my_solver.getallvalues(x):
            #any solution must comply..
            self.assertTrue(sol >= addr and sol<addr+10)

        #so now lets ask the memory for values pointed by addr
        c = mem.getchar(x)
        for val in my_solver.getallvalues(c):
            self.assertTrue(val>=100 and val<110)

        #constarint the address a litlle more
        my_solver.add(x<=addr)
        #It shall be a solution
        self.assertTrue(my_solver.check(), 'sat')
        #if we ask for a possible solution 
        sol = my_solver.getvalue(x)
        #it must be addr
        self.assertTrue(sol == addr)

        #lets ask the memory for the value under that address
        c = mem.getchar(x)
        sol = my_solver.getvalue(c)
        self.assertTrue(sol==100)
Example #5
0
    def test_one_concrete_one_symbolic(self):
        #global mainsolver
        my_solver = Solver()
        mem = SMemory(my_solver, 32, 12)
        
        addr_for_symbol1 = mem.mmap(None, 0x1000, 'rwx')
        mem.putchar(addr_for_symbol1, 'A')

        symbol1 = my_solver.mkBitVec(8)
        
        my_solver.add(OR(symbol1==ord('B'), symbol1==ord('C')))

        mem.putchar(addr_for_symbol1+1, symbol1)
        
        values = list(my_solver.getallvalues(symbol1))
        self.assertIn(ord('B'), values)
        self.assertIn(ord('C'), values)
        
        symbol2 = my_solver.mkBitVec(32)
        my_solver.add(symbol2>=addr_for_symbol1)
        my_solver.add(symbol2<=addr_for_symbol1+1)

        c = mem.getchar(symbol2)
        self.assertTrue(issymbolic(c))           
        
        values = list(my_solver.getallvalues(c))
        
        self.assertIn(ord('A'), values)
        self.assertIn(ord('B'), values)
        self.assertIn(ord('C'), values)
Example #6
0
 def test_mix_of_concrete_and_symbolic__push_pop_cleaning_store(self):
     #global mainsolver
     my_solver = Solver()
     mem = SMemory(my_solver, 32, 12)
     
     start_mapping_addr = mem.mmap(None, 0x1000, 'rwx')
     
     concrete_addr = start_mapping_addr
     symbolic_addr = start_mapping_addr+1
     
     mem.putchar(concrete_addr, 'C')
     sym = my_solver.mkBitVec(8)
     
     mem.putchar(symbolic_addr, sym)
     my_solver.add(sym.uge(0xfe))
     values = list(my_solver.getallvalues(sym))
     self.assertIn(0xfe, values)
     self.assertIn(0xff, values)
     self.assertNotIn(0x7f, values)
     values = list(my_solver.getallvalues(mem.getchar(symbolic_addr)))
     self.assertIn(0xfe, values)
     self.assertIn(0xff, values)
     self.assertNotIn(0x7f, values)
                 
     my_solver.push()
     my_solver.add(sym==0xfe)
     values = list(my_solver.getallvalues(sym))
     self.assertIn(0xfe, values)
     self.assertNotIn(0xff, values)
     self.assertNotIn(0x7f, values)
     values = list(my_solver.getallvalues(mem.getchar(symbolic_addr)))
     self.assertIn(0xfe, values)
     self.assertNotIn(0xff, values)
     self.assertNotIn(0x7f, values)
     
     my_solver.pop()
     values = list(my_solver.getallvalues(sym))
     self.assertIn(0xfe, values)
     self.assertIn(0xff, values)
     self.assertNotIn(0x7f, values)
     values = list(my_solver.getallvalues(mem.getchar(symbolic_addr)))
     self.assertIn(0xfe, values)
     self.assertIn(0xff, values)
     self.assertNotIn(0x7f, values)
Example #7
0
args.argv += prg_args
print "[+] Running", args.program
print "\twith arguments:", args.argv
print "\twith environment:", args.env

# guess architecture from file
from elftools.elf.elffile import ELFFile
arch = {'x86':'i386','x64':'amd64'}[ELFFile(file(args.program)).get_machine_arch()]
bits = {'i386':32, 'amd64':64}[arch]
print "[+] Detected arch:", arch

#Make working directory
folder = tempfile.mkdtemp(prefix=args.worspace, dir='./')

# Make initial state
solver = Solver()
mem = SMemory(solver, bits,12)
linux = SLinux(solver, [Cpu(mem, arch)], mem, symbolic_files=args.sym)
del solver
del mem

WILDCARD = '+'
input_symbols = []
argv = [ args.program ] # argv[0] not symbolic #fix?
for i in range(len(args.argv)):
    if WILDCARD in args.argv[i]:
        print "Argument %d has symbols"%i
        name = "ARG%d"%i
        size = len(args.argv[i])
        sarg = linux.solver.mkArray(name=name, is_input=True, max_size=size)
        for j in range(size):