Example #1
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 #2
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 #3
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 #4
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 #5
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 #6
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 #7
0
    def putchar(self, addr, data):
        """
        Concrete/Symbolic putchar implementation
        
        @param addr: the address to put a concrete or symbolic content
        @param data: the content to put in C{addr}
        
        @todo: if addr is Readable/Executable? Double checked when accesing parent class!
        @todo: Instead of concretizing all possible values in range raise exception
               and make executor for arr on each mapped page

        """
        if issymbolic(addr):
            logger.debug("Write to symbolic address %s", addr)
            addr_min, addr_max = self.solver.minmax(addr)
            logger.debug("Range: %x <-> %x Data: %s", addr_min, addr_max, data)
            #Mark and intialize symbolic range
            for i in xrange(addr_min, addr_max + 1):
                if not self.isWriteable(i):
                    raise MemoryException("No Access Writting", i)
            for i in xrange(addr_min, addr_max + 1):
                if not i in self.addr2symbol:
                    self.symbol[i] = self.getchar(i)
                    self.addr2symbol.add(i)

            self.symbol[addr] = chr(data)
        else:
            #concrete addr case
            if not self.isWriteable(addr):
                raise MemoryException("No Access Writting", addr)
            if issymbolic(data):
                self.symbol[addr] = chr(data)
                self.addr2symbol.add(addr)
            else:
                #both concrete
                self.addr2symbol.discard(addr)
                super(SMemory, self).putchar(addr, data)
Example #8
0
    def getchar(self, addr):
        """
        Concrete/Symbolic getchar implementation
        @rtype: str[1] or BitVec[8]
        
        @param addr: the address to obtain its content
        @return: a character or a symbol stored in C{addr}
        
        @todo:  if addr is Readable/Executable? Double checked when accesing parebnt class!!!
        """
        if issymbolic(addr):
            logger.debug("Read from symbolic address %s",
                         str(addr).replace("\n", ""))
            addr_min, addr_max = self.solver.minmax(addr)
            self.solver.add(addr.uge(addr_min))
            self.solver.add(addr.ule(addr_max))
            logger.debug("Range: %x <-> %x", addr_min, addr_max)
            if addr_max - addr_min > 0x10000000:
                raise MemoryException(
                    "Dangling symbolic pointer [0x%08x-0x%08x]" %
                    (addr_min, addr_max), addr)
            #Symbolic address case
            for i in xrange(addr_min, addr_max + 1):
                if not self.isReadable(i):
                    raise MemoryException("No Access Reading", i)
                if not i in self.addr2symbol:
                    self.symbol[i] = self.getchar(i)
                    self.addr2symbol.add(i)
            return chr(self.solver.simplify(self.symbol[addr]))

        if not self.isReadable(addr):
            raise MemoryException("No Access Reading", addr)

        #if the pointed value is a symbol...
        if self.isSymbolic(addr):
            return chr(self.solver.simplify(self.symbol[addr]))

        return super(SMemory, self).getchar(addr)
Example #9
0
                    #add the constraint
                    new_state.solver.add(counter == new_counter)
                    #and set the PC of the new state to the concrete pc-dest
                    new_state.cpu.setRegister(e.reg_name, new_counter)
                    #add the state to the list of pending states
                    executor.putState(new_state)

                #keep analizing one of the states already loaded up
                new_counter = vals[0]

                current_state.solver.add(counter == new_counter)
                new_state.cpu.setRegister(e.reg_name, new_counter)

            except SymbolicPCException, e:
                #if PC gets "tainted" with symbols do stuff
                assert issymbolic(current_state.cpu.PC)
                #get all possible PC destinations (raise if more tahn 100 options)
                vals = list(
                    current_state.solver.getallvalues(current_state.cpu.PC,
                                                      maxcnt=100))
                print "Symbolic PC found, possible detinations are: ", [
                    "%x" % x for x in vals
                ]

                #Shuffle the possibilities,
                random.shuffle(vals)
                #we will keep one state for the current analisys and save
                #all the rest to files
                current_pc = current_state.cpu.PC
                for new_pc in vals[1:]:
                    new_state = current_state.branch()
Example #10
0
                    new_state.solver.add(counter == new_counter)
                    #and set the PC of the new state to the concrete pc-dest
                    new_state.cpu.setRegister(e.reg_name, new_counter )
                    #add the state to the list of pending states
                    executor.putState(new_state)

                #keep analizing one of the states already loaded up
                new_counter = vals[0]

                current_state.solver.add(counter == new_counter)
                new_state.cpu.setRegister(e.reg_name, new_counter)


            except SymbolicPCException, e:
                #if PC gets "tainted" with symbols do stuff
                assert issymbolic(current_state.cpu.PC)
                #get all possible PC destinations (raise if more tahn 100 options)
                vals = list(current_state.solver.getallvalues(current_state.cpu.PC, maxcnt = 100))
                print "Symbolic PC found, possible detinations are: ", ["%x"%x for x in vals]

                #Shuffle the possibilities, 
                random.shuffle(vals)
                #we will keep one state for the current analisys and save 
                #all the rest to files
                current_pc = current_state.cpu.PC
                for new_pc in vals[1:]:
                    new_state = current_state.branch()
                    #add the constraint
                    new_state.solver.add(new_state.cpu.PC == new_pc)
                    #and set the PC of the new state to the concrete pc-dest
                    new_state.cpu.PC = new_pc