Пример #1
0
 def __read_superclasses_from_sections(section_it):
     '''
     Read the superclasses from the specified section name 
     
     Parameters
     ----------
     section_it: iterator<tuple<int, string>>
         iterator over the sections where the superclass infos are stored
     
     Returns
     -------
     dict<ObjcClass, ObjcClass>
         dict with object as key and the superclass as item
     '''
     superclasses_dict = {}
     for (_, i) in section_it:
         CLASS_PARENT_MATCH = AsmRegEx.compiled_vre(
             AsmRegEx.RE_CLASS_PARENT).search(i)
         if CLASS_PARENT_MATCH is not None:
             clazzname = CLASS_PARENT_MATCH.group(
                 AsmRegEx.RE_CLASS_PARENT_GR_CLASS)
             superclazz_name = CLASS_PARENT_MATCH.group(
                 AsmRegEx.RE_CLASS_PARENT_GR_PARENT)
             superclasses_dict[ObjcClass(clazzname)] = ObjcClass(
                 superclazz_name)
     return superclasses_dict
Пример #2
0
 def __init__(self,
              name,
              category_on_class,
              superclass=None,
              is_static=False,
              is_frameworkclass=False,
              variables=None,
              methods=None):
     ObjcClass.__init__(self, name, superclass, is_static,
                        is_frameworkclass, variables, methods)
     self.__category_on_class = category_on_class
Пример #3
0
 def parse_objc_class_from_classref(self, asmline):
     classref_match = regexp.compiled_vre(
         regexp.RE_CLASSREF).search(asmline)
     if classref_match is not None:
         return ObjcClass(
             classref_match.group(regexp.RE_CLASSREF_GR_CLASSREF))
     return None
Пример #4
0
 def parse_objc_class_from_classref(self, asmline):
     ''' Create ObjcClass from classref ([ds:cls_NSAssertionHandler]) '''
     classsref_match = regexp.compiled_vre(
         regexp.RE_CLASSREF).search(asmline)
     if classsref_match is not None:
         name = classsref_match.group(regexp.RE_CLASSREF_GR_CLASSREF)
         return ObjcClass(name, is_static=True)
     return None
Пример #5
0
 def test_msg_send_eq(self):
     objc_class = ObjcClass('Foo')
     sels = [Selector('alloc'), Selector('init'), Selector('foo:', ['1'])]
     sels2 = [Selector('foo:', ['1'])]
     msg_send1 = MsgSend(objc_class, sels)
     msg_send2 = MethodImplementation(objc_class, sels2)
     res = msg_send1 == msg_send2 and msg_send2 == msg_send1
     print '%s == %s and vice versa = %s' % (msg_send1, msg_send2, res)
     self.assertTrue(res, 'Node quality not correct! Method calls will not link to the corresponding method implementations and vice versa\n')
Пример #6
0
    def setUp(self):
        TestCase.setUp(self)

        self.__category_class = CategoryClass('AnyHttpsCert',
                                              ObjcClass('NSURLRequest'))
        self.__category = MethodImplementation(
            self.category_class,
            [Selector('allowsAnyHTTPSCertificateForHost:')],
            is_static=True)
Пример #7
0
 def parse_objc_class_from_classref(self, asmline):
     ''' Create ObjcClass from classref ([ds:objc_classref_Object1]) '''
     classsref_match = regexp.compiled_vre(
         regexp.RE_CLASSREF).search(asmline)
     # is classref e.g. [ds:objc_classref_Object1]
     if classsref_match is not None:
         name = classsref_match.group(regexp.RE_CLASSREF_GR_CLASSREF)
         return ObjcClass(name, is_static=True)
     return None
Пример #8
0
 def parse_ivar(self, asmline):
     '''Create a ObjcClass from e.g. "IVAR_0x291c" '''
     ivar_match = regexp.compiled_vre(regexp.RE_IVAR).search(asmline)
     if ivar_match is not None:
         ivar_name = ivar_match.group(regexp.RE_IVAR_GR_NAME)
         var = Variable(ivar_name)
         ivar_class = ObjcClass('IVAR', variables=[var])
         return IVar(ivar_class)
     return None
Пример #9
0
 def parse_objc_class_from_framework_class(self, asmline):
     ''' Create ObjcClass from frameworkclass e.g. ([ds:bind__OBJC_CLASS_$_NSUserDefaults]) '''
     frameworkclass_match = regexp.compiled_vre(
         regexp.RE_FRAMEWORKCLASS).search(asmline)
     # is frameworkclass e.g. [ds:bind__OBJC_CLASS_$_NSUserDefaults]
     if frameworkclass_match is not None:
         name = frameworkclass_match.group(
             regexp.RE_FRAMEWORKCLASS_GR_FCLASS)
         return ObjcClass(name, is_frameworkclass=True)
     return None
Пример #10
0
 def parse_ivar(self, asmline):
     '''Create a ObjcClass from e.g. [ds:_OBJC_IVAR_$_AppDelegate.obj3] 
         and set AppDelegate as the class with the attribute obj3 '''
     ivar_match = regexp.compiled_vre(regexp.RE_IVAR).search(asmline)
     if ivar_match is not None:
         ivar_class = ivar_match.group(regexp.RE_IVAR_GR_CLASS)
         ivar_name = ivar_match.group(regexp.RE_IVAR_GR_IVAR)
         var = Variable(ivar_name)
         ivar_class = ObjcClass(ivar_class, variables=[var])
         return IVar(ivar_class)
     return None
Пример #11
0
 def test_filter_method_definition(self):
     ''' Test `md_filter_method_defintion` '''
     selname = 'application:handleOpenURL:'
     sel = Selector(selname)
     msg_send = MsgSend(ObjcClass('AppDelegate'), [sel])
     res = md_filter_method_defintion(msg_send,
                                      class_name=None,
                                      selector_name=selname,
                                      search_substring=True)
     print '%s has selector %s = %s' % (msg_send, sel, res)
     self.assertTrue(res, self.MSG % 'MethodDefFilterUtil')
Пример #12
0
 def msg_send_from_destination(self, destination, selector):
     ''' Overwritten to accept other ints as destination.
     Currently annotation in Hopper is not so good, leading often to hex values (parsed to int) in the `destination_register`. '''
     # temporary workaround to read a msgSend even if destination is integer (transformed from hex)
     # because Hopper is currently not annotating all destinations!
     msg_send = ObjectiveCRuntime.msg_send_from_destination(
         self, destination, selector)
     if msg_send is None:
         arm_fix = isinstance(destination, int)
         if selector is not None and arm_fix:
             msg_send = MsgSend(ObjcClass(str(destination)), [selector])
     return msg_send
Пример #13
0
    def test_filter_category(self):
        ''' Tests for the method `md_filter_category` '''
        category_on_class_name = 'NSURLRequest'
        category_on_class = ObjcClass(category_on_class_name)
        category_name = 'AnyHttpsCert'
        cclass = CategoryClass(category_name,
                               category_on_class=category_on_class)
        selector = Selector('allowsAnyHTTPSCertificateForHost')
        category_msg_send = MsgSend(cclass, [selector])

        # test with all properties at once
        category_match = md_filter_category(category_msg_send,
                                            str(selector),
                                            category_on_class_name,
                                            category_name,
                                            search_substring=False)
        print '%s is category on %s with name %s and selector %s = %s' % (
            category_msg_send, category_on_class_name, category_name, selector,
            category_match)

        category_match2 = md_filter_category(category_msg_send,
                                             str(selector),
                                             category_on_class_name,
                                             category_name=None,
                                             search_substring=False)
        print '%s is category on %s and selector %s = %s' % (
            category_msg_send, category_on_class_name, selector,
            category_match2)

        # category_on test
        category_match3 = md_filter_category(
            category_msg_send, category_on=category_on_class_name)
        print '%s is category on %s = %s' % (
            category_msg_send, category_on_class_name, category_match3)

        # category name test
        category_match4 = md_filter_category(category_msg_send,
                                             category_name=category_name)
        print '%s is category with name %s = %s' % (
            category_msg_send, category_name, category_match4)

        # selector test
        category_match5 = md_filter_category(category_msg_send,
                                             selector=str(selector))
        print '%s is category with selector %s = %s' % (
            category_msg_send, str(selector), category_match5)

        self.assertTrue(
            all((category_match, category_match2, category_match3,
                 category_match4, category_match5)),
            self.MSG % 'md_filter_category')
Пример #14
0
 def parse_meth_impl(asmline):
     ''' Parse a method implementation like e.g. "methImpl_AppDelegate_applicationDidFinishLaunching_". 
     
     For more details see `RE_METH_IMPL`.
     
     Returns
     -------
     MethodImplementation
     ''' 
     meth_impl_match = regexp.compiled_vre(regexp.RE_METH_IMPL).search(asmline)
     if meth_impl_match is not None:
         classname = meth_impl_match.group(regexp.RE_METH_IMPL_GR_CLASS)
         selectorname = meth_impl_match.group(regexp.RE_METH_IMPL_GR_SELECTOR)
         selector = Selector.selector_from_underscore_delimiter(selectorname)
         is_static = regexp.method_implementation_is_static(meth_impl_match.group(regexp.RE_METH_IMPL_GR_STATIC))
         if classname is not None:
             objc_class = ObjcClass(classname, is_static = is_static)
             return MethodImplementation(objc_class, [selector], is_static)
     return None
Пример #15
0
    def set_class_of_func(self, value):
        self.__class_of_func = value

    def __str__(self):
        return '%s.%s' % (self.get_class_of_func(), Function.__str__(self))
    
    def __eq__(self, other):
        if isinstance(other, ClassFunc):
            return self is other or (Function.__eq__(self, other) and self.class_of_func == other.class_of_func)
        return False
    
    def __hash__(self):
        return hash((Function.__hash__(self), self.class_of_func))
    
    class_of_func = property(get_class_of_func, set_class_of_func, None, "__class_of_func(ObjcClass) -- the class to which the function belongs.")

    
#####################################################################################
# NSObjectInterface                                                                 #
#####################################################################################
    def get_nsobject(self):
        return self.get_class_of_func()
        
if __name__ == '__main__':
    class_of_func = ObjcClass('AppDelegate')
    function = 'function'
    args = ['1', '2', '3']
    classfunc = ClassFunc(class_of_func, function, args)
    print classfunc
Пример #16
0
        return '''%s(%s, category_on_class: %s\nsuperclass: %s, static: %s, frameworkclass: %s, \nvariables: %s, \nmethods: %s) ''' % (
            self.__class__.__name__, self.get_objc_name(),
            self.get_category_on_class(),
            self.get_superclass().get_objc_name(), self.get_is_static(),
            self.get_is_frameworkclass(), self.get_variables(),
            self.get_methods())

    def __static_str(self):
        is_static = self.is_static
        return '+' if is_static else '-'

    category_on_class = property(
        get_category_on_class, set_category_on_class, None,
        "category_on_class(ObjcClass) -- the class on which the category is added"
    )

    #####################################################################################
    # HopperAnnotationInterface                                                         #
    #####################################################################################

    def hopper_str(self):
        return '%s(%s(%s))' % (self.__class__.__name__,
                               self.get_category_on_class(),
                               self.get_objc_name())


if __name__ == '__main__':
    category_on_class = ObjcClass('NSURLRequest')
    cclass = CategoryClass('AnyHttpsCert', category_on_class=category_on_class)
    print cclass
Пример #17
0
 def __eq__(self, other):
     if isinstance(other, CategoryClass):
         return self is other or ObjcClass.__eq__(
             self, other) and (self.get_category_on_class()) == (
                 other.get_category_on_class())
     return False
Пример #18
0
 def __hash__(self):
     return hash((ObjcClass.__hash__(self), self.get_category_on_class()))
Пример #19
0
            Returns a `MethodImplementation` where the class is a `CategoryClass`.
        '''
        msg_send = None
        category_match = AsmRegEx.compiled_vre(
            AsmRegEx.RE_CATEGORY).search(asmline)
        if category_match is not None:
            category_on_class = category_match.group(
                AsmRegEx.RE_CATEGORY_ON_CLASS)
            classname = category_match.group(AsmRegEx.RE_CATEGORY_CLASS)
            category_is_static = category_match.group(
                AsmRegEx.RE_CATEGORY_STATIC_SYMBOL
            ) == AsmRegEx.RE_CATEGORY_SYMBOL_STATIC
            selectorname = category_match.group(AsmRegEx.RE_CATEGORY_SELECTOR)
            selector = Selector(selectorname)
            cclass = CategoryClass(classname, category_on_class)
            msg_send = MethodImplementation(cclass, [selector],
                                            is_static=category_is_static)
        return msg_send

if __name__ == '__main__':
    from vizasm.model.objc.object.nsobject.objcclass.ObjcClass import ObjcClass
    method = MethodImplementation(ObjcClass('AppDelegate'),
                                  [Selector('applicationDidFinishLaunching:')],
                                  is_static=False)
    print method

    category_msg_send = MethodImplementation.create_from_asm_line(
        ' +[NSURLRequest(AnyHttpsCert) allowsAnyHTTPSCertificateForHost:]_100001c70:'
    )
    print 'MsgSend from category: %s ' % (category_msg_send)
Пример #20
0
    from vizasm.analysis.asm.cpu.x86.Cpu_x86 import Cpu_x86
    from vizasm.analysis.asm.cpu.x86.Register_x86 import Register_x86 as reg
    cpu = Cpu_x86({})
    pu = ParseUtil_x86(cpu, reg)
    imp_stub_x86 = pu.parse_imp(
        'call       imp___symbol_stub__objc_setProperty')
    stackvar = pu.parse_stackvar(
        '00002caf 8B4D14                          mov        ecx, dword [ss:ebp-0x48+arg_4]'
    )
    cls_ref = pu.parse_objc_class_from_classref('[ds:cls_NSAssertionHandler]')
    cls_ref2 = pu.parse_objc_class_from_classref(
        'dword [ds:eax-0x25e1+cls_Object1]')

    cpu.read_line('mov        ecx, dword [ds:eax-0x25e1+cls_Object1]')
    var_assignment_without_ivar_ref = pu.parse_var_assignment_without_ivar_ref_from_asmline(
        'dword [ds:ecx+0x8]')
    cpu.memory.registers.set_value_for_register(
        reg('eax'),
        MsgSend(ObjcClass('Object1'),
                [Selector('alloc'), Selector('init')]))
    var_assignment_with_ivar_ref = pu.parse_var_assignment_with_ivar_ref_from_asmline(
        'mov dword [ds:ecx+0x8], eax')
    print imp_stub_x86
    print cls_ref
    print cls_ref2
    print stackvar
    print var_assignment_without_ivar_ref
    print var_assignment_with_ivar_ref
    print pu.parse_imp(
        '[ds:eax-0x221e+imp___nl_symbol_ptr__NSStreamSocketSecurityLevelKey]')
Пример #21
0
    print pu.parse_assignment_split('str r0, [r4, r5]')
    print 'register: %s' % pu.parse_register(
        ' r2                                ; XREF=0x31ae')
    print pu.parse_stack_push_via_stm('stm.w      sp, {r3, r11}',
                                      cpu.stack_pointer_register())
    print pu.parse_stack_push_via_stm('stm.w      sp, {r2, r9}',
                                      cpu.stack_pointer_register().register)
    print pu.parse_stack_access('[sp, #0x8]')
    print pu.parse_stack_access('[sp]')
    print pu.parse_offset_addring_offset_needed('[r0, r4]')
    print pu.parse_offset_addressing('[r0]')

    # VarAssignment test
    cpu.memory.registers.set_value_for_register(
        reg('r5'),
        IVar(ObjcClass('SelfClass'),
             MsgSend(ObjcClass('Foo'),
                     [Selector('alloc'), Selector('init')])))
    cpu.memory.registers.set_value_for_register(reg('r0'), ObjcClass('Foo'))
    cpu.memory.registers.set_value_for_register(reg('r4'),
                                                ObjcClass('SelfClass'))
    print pu.parse_var_assignment_with_ivar_ref_from_asmline(
        'str r0, [r4, r5]')
    print pu.parse_var_assignment_without_ivar_ref_from_asmline('[sp, r5]')
    print pu.parse_var_assignment_with_ivar_ref_from_asmline(
        'str r0, [sp, r5]')
    print 'stack access: %s' % str(pu.parse_stack_access('[sp, #0x4]'))
    print 'stack access: %s' % str(pu.parse_stack_access('[sp], #0x4'))
    print 'stack access: %s' % str(pu.parse_stack_access('[sp]'))

    print pu.parse_add('add        r7, sp, #0xc')
Пример #22
0
            the `Selector` with which the `MsgSend` shall be created.
            
        Returns
        -------
        MsgSend
            the created `MsgSend` 
        ''' 
        return MsgSend.create_from_msgsend(self, selector)
        
    selectors = property(get_selectors, set_selectors, None, "__selectors(list) -- the selector(s) to send to the class (default [])")
    msg_receiver = property(get_msg_receiver, set_msg_receiver, None, "__msg_receiver(ObjClass) -- the class to which the message(s) will be sent")
        
if __name__ == '__main__':
    from vizasm.model.objc.function.MethodImplementation import MethodImplementation

    objcclass = ObjcClass('NSUserDefaults')
    sel1 = Selector('standardUserDefaults')
    sel2 = Selector('objectForKey:', ['aKey'])
    sel3 = Selector('setValueForKey:value:', ['aKey', 'value'])
    msg = MsgSend(objcclass, [sel1, sel2, sel3]) 
    print msg   
    msg2 = MsgSend(objcclass, [Selector('alloc'), Selector('init'), Selector('httpsConnection')])
    print msg2   
    msg2 = MsgSend(objcclass, [Selector('new'), Selector('httpsConnection')])
    print msg2   
    msg4 = MsgSend(objcclass, [Selector('alloc'), Selector('init')])
    print msg4
     
    msg3 = MsgSend.create_from_msgsend(msg, sel1)
    print msg3
Пример #23
0
    ivar2 = pu.parse_ivar('[ds:_OBJC_IVAR_$_AppDelegate.obj3] ')
    d[ivar2] = 'test2'
    # this should not overwrite ivar2 but add an additional entry in the dict, cause ivar3 is not equal to ivar2
    ivar3 = pu.parse_ivar('[ds:_OBJC_IVAR_$_AppDelegate.obj2] ')
    d[ivar3] = 'test3'
    print d

    print 'list equal test: should be true'
    x = [ivar]
    y = [ivar]
    print '[ivar] equals [ivar]: %s' % (x == y)
    print '[ivar] equals [ivar2]: %s' % (x == [ivar2])

    print '\nivar without ref: %s' % (ivar)
    ivar.set_ivar_ref(
        MsgSend(ObjcClass('Object3'),
                [Selector('alloc'), Selector('init')]))
    print 'ivar with ref: %s' % (ivar)

    print 'StackVar'
    print pu.parse_stackvar('dword [ss:rbp-0x60+arg_0]')
    print pu.parse_stackvar('[ss:rbp-0x30+var_41]')
    '''
    print 'ObjcClass'
    fclass = ObjcClass.create_from_asm_line('[ds:bind__OBJC_CLASS_$_NSUserDefaults]')
    fclass2 = ObjcClass.create_from_asm_line('[ds:bind__OBJC_CLASS_$_NSUserDefaults]')
    classref = ObjcClass.create_from_asm_line('[ds:objc_classref_Object1]')
    print 'fclass: %s' % (fclass)
    print 'classref: %s' % (classref)
    
    print fclass.__hash__() == fclass2.__hash__()
Пример #24
0
class MethodCall(object, AddMethodCallToGraphInterface):
    ''' 
    The `Methodcall` stores messages a sender has sent.
    This model is uses for a method (sender) that sends several messages and is the output of the `Cpu`.

    If the sender is not present at creation, using None as argument for the sender creates a pseudo none sender. 
    You can check if this sender is still present with the method has_no_sender().
    
    Parameters
    ----------
    __sender: FunctionInterface, optional (default is PSEUDO_NONE_SENDER)
    __calls: list<MethodCallItem>, optional (default is [])
    '''
    
    PSEUDO_NONE_NAME = 'pseudo none'
    PSEUDO_NONE_SENDER = MsgSend(ObjcClass(PSEUDO_NONE_NAME), [])
    
    def __init__(self, sender = None, calls = None):
        object.__init__(self)
        if calls is None:
            calls = []
        # fix for creation with None as sender
        if sender is None:
            sender = MethodCall.PSEUDO_NONE_SENDER
        self.__sender = sender
        self.__calls = calls

    def __len__(self):
        return len(self.get_calls())

    def __eq__(self, other): 
        if isinstance(other, MethodCall):
            return self is other or ((self.get_sender(), self.get_calls())) == ((other.sender(), other.get_msg()))   
        return False
    
    def __ne__(self, other):
        return not self == other
    
    def __hash__(self):
        return hash((self.get_sender().__hash__(), tuple(self.get_calls()).__hash__()))
    
    def __iter__(self):
        return iter(sorted(self.calls))
    
    def format_head(self):
        ''' Format the head (first line) of the `MethodCall`.
        No newline will be appended.
        '''
        return 'Method: %s' % (self.get_sender())
        
    def __str__(self):
        head = self.format_head()
        return '%s:\n%s\n%s' % (head, (len(head) + 1) * '-', ''.join(str(call) for call in self))
    
    def __repr__(self):
        return '%s(%s: %s)' % (self.__class__.__name__, self.get_sender(), self.get_calls())
    
    def get_sender(self):
        return self.__sender

    def get_calls(self):
        return self.__calls

    def set_sender(self, value):
        self.__sender = value

    def set_calls(self, value):
        self.__calls = value
        
    sender = property(get_sender, set_sender, None, "__sender(MsgSend, optional (default is PSEUDO_NONE_SENDER))")
    calls = property(get_calls, set_calls, None, "__calls:(list<MethodCallItem>, optional (default is []))")

    def add_methodcall(self, call, linenr, address = None):
        ''' Add a call.
        
        Parameters:
        -----------
        call: Function or MsgSend
        linenr: int
        address: int
        '''
        self.add_methodcallitem(MethodCallItem(call, linenr, address)) 
        
    def add_methodcallitem(self, methodcallitem):
        ''' Add the `MethodCallItem`.
        
        Parameters:
        -----------
        methodcallitem: MethodCallItem
            the `MethodCallItem` which shall be added
        '''
        self.get_calls().append(methodcallitem) 

    def idx_methodcallitem(self, linenr):
        ''' Return the index of the `MethodCallItem` with the given line number'''
        for i, methocallitem in enumerate(self.calls):
            if methocallitem.linenr == linenr:
                return i
        return None
                    
    def has_no_sender(self):
        ''' Check if the `Methodcall` has a sender. 
        If the `MethodCall` is initialized with None as sender, a pseudo none sender is created and used.
        ''' 
        return self.get_sender() == MethodCall.PSEUDO_NONE_SENDER
    
    def is_empty(self):
        ''' Returns if the methodcall does not contain any calls '''
        return len(self.get_calls()) == 0

    def create_gephi_attr_dicts(self, asm_lines, filtered_methodcall = None):    
        '''
        Construct the attribute dictionary describing the graph style.
        Use the created dictionaries with the `add_to_graph` method.
        
        The attributes are:
        Calling Method:
            assembler code
            the method calls (filtered or not)
        Method:
            line number in the asm file
            address in the asm file
            surrounding lines
            
        Parameters
        ----------
        asm_lines: string
            the assembler method as string
        filtered_methodcall: MethodCall, optional (default is None)
            the filtered `MethodCall`
        
        Returns
        -------
        methodcall_sender_attr_dict: dict
        methodcall_calls_attr_list_dict: dict
        '''
        method_lines_list = [str(methodcallitem) for methodcallitem in self.calls]

        if filtered_methodcall is None:
            filtered_methodcall = self
            
        # construct calls attribute dictionary
        methodcall_calls_attr_list_dict = []
        cnt_surrounding_lines = setting_for_key(SETTINGS_CNT_SURROUNDING_LINES)
        if cnt_surrounding_lines >= 0:
            for i, methodcallitem in enumerate(filtered_methodcall.calls):
                # construct leading and trailing lines
                # index of the current line (filtered `MethodCall`) in the list of method lines 
                current_line = str(filtered_methodcall.calls[i].call)
                linenr = methodcallitem.linenr
                idx_line = self.idx_methodcallitem(linenr)
                # idx_line = method_lines_list.index(current_line)
                lines_before, lines_after = Util.surrounding_elements_from_list(method_lines_list, idx_line, cnt_surrounding_lines)
                
                surrounding_lines = NodeAttributes.NPATTERN_SURROUND_LINES % (Util.strlist_to_str(lines_before), current_line, Util.strlist_to_str(lines_after))
                methodcall_attr_dict = {NodeAttributes.NATTR_METHOD_SURROUNDING_LINES % cnt_surrounding_lines : surrounding_lines}
                
                methodcall_attr_dict.update(methodcallitem.get_gexf_viz_attr_dict())
                
                methodcall_calls_attr_list_dict.append(methodcall_attr_dict)
        
        # add method signature to list of method lines 
        method_lines_list.insert(0, filtered_methodcall.format_head() + ":\n")
        
        # construct sender attribute dictionary
        method_lines = Util.strlist_to_str(method_lines_list)
        methodcall_sender_attr_dict = {NodeAttributes.NATTR_METHOD : method_lines, NodeAttributes.NATTR_ASM_CODE : asm_lines}
        
        return (methodcall_sender_attr_dict, methodcall_calls_attr_list_dict)
   
#####################################################################################
# AddToGraphInterface                                                               #
#####################################################################################
    
    def add_to_graph(self, graph, methodcall_sender_attr_dict = None, methodcall_calls_attr_list_dict = None, sender_methodcall_edge_attr_dict = None):
        ''' Add the `MethodCall` to the graph
        
        Parameters
        ----------
        methodcall_sender_attr_dict: dict, optional (Default {})
        methodcall_calls_attr_list_dict: dict, optional (Default {})
        methodcall_calls_attr_list_dict: dict, optional (Default {})
         '''
        
        if methodcall_sender_attr_dict is None:
            methodcall_sender_attr_dict = {}
        if methodcall_calls_attr_list_dict is None:
            methodcall_calls_attr_list_dict = []
        if sender_methodcall_edge_attr_dict is None:
            sender_methodcall_edge_attr_dict = {}
            
        if len(self) > 0:
            key = self.sender
            graph.add_node(key)
            graph.add_attributes(key, methodcall_sender_attr_dict)
            for idx, methodcallitem in enumerate(self):
                # only set the next attribute dictionary if list is not empty
                if methodcall_calls_attr_list_dict:
                    methodcall_attr_dict = deepcopy(methodcall_calls_attr_list_dict[idx])
                else:
                    methodcall_attr_dict = {}
                    
                edge_label = methodcallitem.call
                graph.add_node(edge_label)
                graph.add_edge(self.sender, edge_label, key = None, attr_dict = deepcopy(sender_methodcall_edge_attr_dict))
                methodcall_attr_dict.update({NodeAttributes.NATTR_LINENUMBER : str(methodcallitem.linenr)}) 
                methodcall_attr_dict.update({NodeAttributes.NATTR_ADDRESS : str(hex(methodcallitem.address))}) 
                graph.add_attributes(edge_label, methodcall_attr_dict)
Пример #25
0
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

VizAsm is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with VizAsm.  If not, see <http://www.gnu.org/licenses/>.
'''

from vizasm.model.objc.function.MsgSend import MsgSend

class MethodSelectorArgument(MsgSend):
    ''' 
    A `MethodSelectorArgument` is a `MsgSend` without any selectors and overwritten __str__ method..    
    It's used for the unknown arguments of a method implementations `Selector`
    '''
    
    def __init__(self, msg_send_class):
        MsgSend.__init__(self, msg_send_class, [])
        
    def __str__(self):
        return str(self.msg_receiver)

if __name__ == '__main__':
    from vizasm.model.objc.object.nsobject.objcclass.ObjcClass import ObjcClass
    print MethodSelectorArgument(ObjcClass('arg1'))