<s> import copy <EOL> import re <EOL> from concolica import log <EOL> from concolica import memory <EOL> from concolica . utils import * <EOL> from concolica . vulnerabilities import * <EOL> import reil <EOL> import smt <EOL> import smt . bitvector as bv <EOL> class Registers ( dict ) : <EOL> __slots__ = ( '<STR_LIT>' , '<STR_LIT>' ) <EOL> def __init__ ( self , parent = None ) : <EOL> dict . __init__ ( self ) <EOL> self . _parent = parent <EOL> if self . depth ( ) > <NUM_LIT:2> : <EOL> self . flatten ( ) <EOL> def dirty ( self ) : <EOL> return self . depth ( ) == <NUM_LIT:0> or len ( self ) > <NUM_LIT:0> <EOL> def __getstate__ ( self ) : <EOL> self . flatten ( ) <EOL> return dict ( self ) <EOL> def __setstate__ ( self , d ) : <EOL> self . update ( d ) <EOL> self . _parent = None <EOL> def __contains__ ( self , item ) : <EOL> if dict . __contains__ ( self , item ) : <EOL> return True <EOL> if self . _parent is not None : <EOL> return item in self . _parent <EOL> return False <EOL> def __missing__ ( self , key ) : <EOL> if self . _parent is None : <EOL> raise KeyError ( ) <EOL> return self . _parent [ key ] <EOL> def clear_il_state ( self ) : <EOL> il_register_re = re . compile ( '<STR_LIT>' ) <EOL> for r in self . keys ( ) : <EOL> if il_register_re . match ( r ) : <EOL> del self [ r ] <EOL> def depth ( self ) : <EOL> d = <NUM_LIT:0> <EOL> p = self . _parent <EOL> while p is not None : <EOL> d += <NUM_LIT:1> <EOL> p = p . _parent <EOL> return d <EOL> def flatten ( self ) : <EOL> cs = [ ] <EOL> p = self . _parent <EOL> while p is not None : <EOL> cs . append ( p ) <EOL> p = p . _parent <EOL> cs . reverse ( ) <EOL> for c in cs : <EOL> self . update ( c ) <EOL> self . _parent = p <EOL> class State ( object ) : <EOL> _state_id = interlocked . Counter ( ) <EOL> def __init__ ( self , parent = None ) : <EOL> self . id = <NUM_LIT:0> <EOL> self . parent = parent <EOL> self . score = <NUM_LIT:0> <EOL> self . log = log . StateLogger ( self ) <EOL> if parent : <EOL> self . ip = parent . ip <EOL> self . il_index = parent . il_index <EOL> self . memory = memory . DynamicMemory ( parent . memory ) <EOL> self . registers = Registers ( parent . registers ) <EOL> self . call_stack = copy . copy ( parent . call_stack ) <EOL> self . function_hooks = parent . function_hooks <EOL> self . kernel = parent . kernel <EOL> self . symbols = parent . symbols <EOL> self . solver = smt . Solver ( parent . solver ) <EOL> self . files = copy . deepcopy ( parent . files ) <EOL> self . trace = list ( parent . trace ) <EOL> else : <EOL> self . ip = <NUM_LIT:0> <EOL> self . il_index = <NUM_LIT:0> <EOL> self . memory = None <EOL> self . registers = Registers ( ) <EOL> self . call_stack = [ ] <EOL> self . function_hooks = dict ( ) <EOL> self . kernel = None <EOL> self . symbols = dict ( ) <EOL> self . symbols = None <EOL> self . solver = smt . Solver ( ) <EOL> self . files = [ <EOL> { <EOL> '<STR_LIT:path>' : '<STR_LIT>' , <EOL> '<STR_LIT>' : '<STR_LIT:r>' , <EOL> '<STR_LIT>' : <NUM_LIT:0> , <EOL> '<STR_LIT>' : dict ( ) <EOL> } , <EOL> { <EOL> '<STR_LIT:path>' : '<STR_LIT>' , <EOL> '<STR_LIT>' : '<STR_LIT:w>' , <EOL> '<STR_LIT>' : <NUM_LIT:0> , <EOL> '<STR_LIT>' : dict ( ) <EOL> } , <EOL> { <EOL> '<STR_LIT:path>' : '<STR_LIT>' , <EOL> '<STR_LIT>' : '<STR_LIT:w>' , <EOL> '<STR_LIT>' : <NUM_LIT:0> , <EOL> '<STR_LIT>' : dict ( ) <EOL> } ] <EOL> self . trace = [ ] <EOL> def __getstate__ ( self ) : <EOL> l = None <EOL> try : <EOL> l = self . log <EOL> self . log = None <EOL> return dict ( self . __dict__ ) <EOL> finally : <EOL> self . log = l <EOL> def __setstate__ ( self , d ) : <EOL> self . __dict__ = d <EOL> self . log = log . StateLogger ( self ) <EOL> def clear_il_state ( self ) : <EOL> self . registers . clear_il_state ( ) <EOL> self . il_index = <NUM_LIT:0> <EOL> def fork ( self ) : <EOL> new = State ( self ) <EOL> new . id = State . _state_id . increment ( ) <EOL> self . log . fork ( new . id ) <EOL> return new <EOL> def read ( self , address , size ) : <EOL> if arbitrary ( self , address ) : <EOL> raise ArbitraryRead ( self , address ) <EOL> as_ = concretise ( self , address ) <EOL> try : <EOL> if len ( as_ ) > <NUM_LIT:1> : <EOL> e = None <EOL> value = bv . Symbol ( size , unique_name ( '<STR_LIT>' ) ) <EOL> for a in as_ : <EOL> v = None <EOL> for i in range ( <NUM_LIT:0> , size // <NUM_LIT:8> ) : <EOL> if v is None : <EOL> v = self . memory . read_byte ( self , a . value + i ) <EOL> else : <EOL> v = self . memory . read_byte ( self , a . value + i ) . concatenate ( v ) <EOL> if e is None : <EOL> e = ( address == a ) & ( value == v ) <EOL> else : <EOL> e = e | ( ( address == a ) & ( value == v ) ) <EOL> self . solver . add ( e ) <EOL> else : <EOL> value = self . memory . read_byte ( self , as_ [ <NUM_LIT:0> ] . value ) <EOL> for i in range ( <NUM_LIT:1> , size // <NUM_LIT:8> ) : <EOL> value = self . memory . read_byte ( self , as_ [ <NUM_LIT:0> ] . value + i ) . concatenate ( value ) <EOL> except KeyError : <EOL> raise InvalidRead ( self , address ) <EOL> return value <EOL> def write ( self , address , value ) : <EOL> bs = [ ] <EOL> for i in range ( <NUM_LIT:0> , value . size , <NUM_LIT:8> ) : <EOL> bs . append ( value . extract ( start = i , end = i + <NUM_LIT:8> ) ) <EOL> bs . reverse ( ) <EOL> if arbitrary ( self , address ) : <EOL> raise ArbitraryWrite ( self , address , value ) <EOL> as_ = concretise ( self , address ) <EOL> if len ( as_ ) > <NUM_LIT:1> : <EOL> for a in as_ : <EOL> for i , byte in enumerate ( bs ) : <EOL> self . memory . write_byte ( self , a . value + i , smt . bv . IfThenElse ( <EOL> a != address , <EOL> self . memory . read_byte ( self , a . value + i ) , <EOL> byte ) ) <EOL> else : <EOL> for i , byte in enumerate ( bs ) : <EOL> self . memory . write_byte ( self , as_ [ <NUM_LIT:0> ] . value + i , byte ) <EOL> def branch ( self , address ) : <EOL> ss = [ ] <EOL> if isinstance ( address , reil . OffsetOperand ) : <EOL> self . il_index = address . offset <EOL> ss . append ( self ) <EOL> else : <EOL> self . il_index = <NUM_LIT> <EOL> if address . symbolic : <EOL> if arbitrary ( self , address ) : <EOL> raise ArbitraryExecution ( self , address ) <EOL> else : <EOL> ss = [ ] <EOL> as_ = concretise ( self , address ) <EOL> if len ( as_ ) > <NUM_LIT:1> : <EOL> for a in as_ : <EOL> b = self . fork ( ) <EOL> b . ip = a . value <EOL> ss . append ( b ) <EOL> else : <EOL> self . ip = as_ [ <NUM_LIT:0> ] . value <EOL> ss . append ( self ) <EOL> else : <EOL> self . ip = address . value <EOL> ss . append ( self ) <EOL> return ss <EOL> def throw ( self , exception ) : <EOL> raise exception </s>
