(self, addr, *args, **kwargs)
Create a native or a Java call state.

        :param addr:    Soot or native addr of the invoke target.
        :param args:   List of SootArgument values.
Create a native or a Java call state.
Create a native or a Java call state .
def state_call(self, addr, *args, **kwargs):
        """
        Create a native or a Java call state.

        :param addr:    Soot or native addr of the invoke target.
        :param args:   List of SootArgument values.
        """
        state = kwargs.pop('base_state', None)
        # check if we need to setup a native or a java callsite
        if isinstance(addr, SootAddressDescriptor):
            # JAVA CALLSITE
            # ret addr precedence: ret_addr kwarg > base_state.addr > terminator
            ret_addr = kwargs.pop('ret_addr', state.addr if state else SootAddressTerminator())
            cc = kwargs.pop('cc', SimCCSoot(self.arch))
            if state is None:
                state = self.state_blank(addr=addr, **kwargs)
            else:
                state = state.copy()
                state.regs.ip = addr
            cc.setup_callsite(state, ret_addr, args, kwargs.pop('prototype', None))
            return state

        else:
            # NATIVE CALLSITE

            # setup native return type
            # TODO roll this into protytype
            ret_type = kwargs.pop('ret_type')
            native_ret_type = self.get_native_type(ret_type)

            # setup function prototype, so the SimCC know how to init the callsite
            prototype = kwargs.pop('prototype', None)
            if prototype is None:
                arg_types = [self.get_native_type(arg.type) for arg in args]
                prototype = SimTypeFunction(args=arg_types, returnty=native_ret_type)
            native_cc = kwargs.pop('cc', None)
            if native_cc is None:
                native_cc = self.get_native_cc()

            # setup native argument values
            native_arg_values = []
            for arg, arg_ty in zip(args, prototype.args):
                if arg.type in ArchSoot.primitive_types or \
                   arg.type == "JNIEnv":
                    # the value of primitive types and the JNIEnv pointer
                    # are just getting copied into the native memory
                    native_arg_value = arg.value
                    if self.arch.bits == 32 and arg.type == "long":
                        # On 32 bit architecture, long values (w/ 64 bit) are copied
                        # as two 32 bit integer
                        # TODO I _think_ all this logic can go away as long as the cc knows how to store large values
                        # TODO this has been mostly implemented 11 Dec 2021
                        # unfortunately no test cases hit this branch so I don't wanna touch it :(
                        upper = native_arg_value.get_bytes(0, 4)
                        lower = native_arg_value.get_bytes(4, 4)
                        idx = args.index(arg)
                        args = args[:idx] \
                               + (SootArgument(upper, 'int'), SootArgument(lower, 'int')) \
                               + args[idx+1:]
                        native_arg_values += [upper, lower]
                        continue
                    if type(arg.value) is BV and len(arg.value) > arg_ty.size:
                        # hack??? all small primitives are passed around as 32bit but cc won't like that
                        native_arg_value = native_arg_value[arg_ty.size - 1:0]
                else:
                    # argument has a relative type
                    # => map Java reference to an opaque reference, which the native code
                    #    can use to access the Java object through the JNI interface
                    native_arg_value = state.jni_references.create_new_reference(obj=arg.value)
                native_arg_values += [native_arg_value]

            # setup native invoke state
            return self.native_simos.state_call(addr, *native_arg_values,
                                                base_state=state,
                                                ret_addr=self.native_return_hook_addr,
                                                cc=native_cc, prototype=prototype, **kwargs)
def state_call ( self , addr , * args , * * kwargs ) : state = kwargs . pop ( 'base_state' , None ) # check if we need to setup a native or a java callsite if isinstance ( addr , SootAddressDescriptor ) : # JAVA CALLSITE # ret addr precedence: ret_addr kwarg > base_state.addr > terminator ret_addr = kwargs . pop ( 'ret_addr' , state . addr if state else SootAddressTerminator ( ) ) cc = kwargs . pop ( 'cc' , SimCCSoot ( self . arch ) ) if state is None : state = self . state_blank ( addr = addr , * * kwargs ) else : state = state . copy ( ) state . regs . ip = addr cc . setup_callsite ( state , ret_addr , args , kwargs . pop ( 'prototype' , None ) ) return state else : # NATIVE CALLSITE # setup native return type # TODO roll this into protytype ret_type = kwargs . pop ( 'ret_type' ) native_ret_type = self . get_native_type ( ret_type ) # setup function prototype, so the SimCC know how to init the callsite prototype = kwargs . pop ( 'prototype' , None ) if prototype is None : arg_types = [ self . get_native_type ( arg . type ) for arg in args ] prototype = SimTypeFunction ( args = arg_types , returnty = native_ret_type ) native_cc = kwargs . pop ( 'cc' , None ) if native_cc is None : native_cc = self . get_native_cc ( ) # setup native argument values native_arg_values = [ ] for arg , arg_ty in zip ( args , prototype . args ) : if arg . type in ArchSoot . primitive_types or arg . type == "JNIEnv" : # the value of primitive types and the JNIEnv pointer # are just getting copied into the native memory native_arg_value = arg . value if self . arch . bits == 32 and arg . type == "long" : # On 32 bit architecture, long values (w/ 64 bit) are copied # as two 32 bit integer # TODO I _think_ all this logic can go away as long as the cc knows how to store large values # TODO this has been mostly implemented 11 Dec 2021 # unfortunately no test cases hit this branch so I don't wanna touch it :( upper = native_arg_value . get_bytes ( 0 , 4 ) lower = native_arg_value . get_bytes ( 4 , 4 ) idx = args . index ( arg ) args = args [ : idx ] + ( SootArgument ( upper , 'int' ) , SootArgument ( lower , 'int' ) ) + args [ idx + 1 : ] native_arg_values += [ upper , lower ] continue if type ( arg . value ) is BV and len ( arg . value ) > arg_ty . size : # hack??? all small primitives are passed around as 32bit but cc won't like that native_arg_value = native_arg_value [ arg_ty . size - 1 : 0 ] else : # argument has a relative type # => map Java reference to an opaque reference, which the native code #    can use to access the Java object through the JNI interface native_arg_value = state . jni_references . create_new_reference ( obj = arg . value ) native_arg_values += [ native_arg_value ] # setup native invoke state return self . native_simos . state_call ( addr , * native_arg_values , base_state = state , ret_addr = self . native_return_hook_addr , cc = native_cc , prototype = prototype , * * kwargs )