Beispiel #1
0
    def __init__(self, platforms):
        """Create a new delegator instance.

        'platforms' is a set of all platforms to support
        """
        super().__init__('luastructs', Platform.mappings['default'], None)
        self.platforms = platforms
        self.field_var = 'f.'
        self.description = 'Lua C Structs'
        self.dissectors = {self.platform.name: self}

        self.var = create_lua_var('delegator')
        self.table_var = create_lua_var('dissector_table')
        self.id_table = create_lua_var('message_ids')
        self.sizes_table = create_lua_var('dissector_sizes')
        self.msg_var = create_lua_var('msg_node')

        # Add fields, don't change sizes!
        endian = Platform.big
        self.add_field(Field('Version', 'uint8', 1, 0, endian))
        values = {p.flag: p.name for name, p in self.platforms.items()}
        field = Field('Flags', 'uint8', 1, 0, endian)
        field.set_list_validation(values)
        self.add_field(field)
        self.add_field(Field('Message', 'uint16', 2, 0, endian))
        self.add_field(Field('Message length', 'uint32', 4, 0, endian))

        self.version, self.flags, self.msg_id, self.length = self.children
Beispiel #2
0
    def __init__(self, name, id=None, description=None):
        """Create a Protocol, for generating a dissector.

        'name' is the name of the Protocol to dissect
        'id' a list of message id's
        'description' the description of the protocol to dissect
        """
        if description is None:
            description = 'struct %s' % name
        self.name = name
        self.id = id
        self.description = description
        self.dissectors = {} # Map platform names to dissectors
        self.var = create_lua_var('proto_%s' % name)
Beispiel #3
0
    def _dissector_func(self):
        """Add the code for the dissector function for the protocol."""
        data = ['-- Delegator dissector function for %s' % self.name]

        # Add dissector function
        data.append('function delegator.dissector(buffer, pinfo, tree)')
        data.append('\tlocal subtree = tree:add(delegator, buffer())')
        data.append('\tpinfo.cols.protocol = delegator.name')
        data.append('\tpinfo.cols.info = delegator.description\n')

        # Fields code
        data.append(self.version.get_code(0))
        data.append(self.flags.get_code(1))
        t = '\tpinfo.private.platform_flag = {flag}'
        data.append(t.format(flag=self.flags._value_var))
        data.append(self.msg_id.get_code(2, store=self.msg_var))
        t = '\tsubtree:add(f.messagelength, buffer(4):len()):set_generated()'
        data.extend([t, ''])

        # Find message id and flag
        msg_var = create_lua_var('id_value')
        data.append(self.msg_id._store_value(msg_var))
        data.append(self.length._store_value('length_value', offset=4))
        data.append('')

        # Call the right dissector
        data.append('\t-- Call the correct dissector, or try and guess which')
        data.append('''\
    if {ids}[{msg}] then
        {node}:append_text(" (" .. {ids}[{msg}] ..")")
        {table}:try({ids}[{msg}], buffer(4):tvb(), pinfo, tree)
    else
        {node}:add_expert_info(PI_MALFORMED, PI_WARN, "Unknown message id")
        if {sizes}[{flag}] and {sizes}[{flag}][{length}] then
            for key, value in pairs({sizes}[{flag}][{length}]) do
                {table}:try(value, buffer(4):tvb(), pinfo, tree)
            end
        end
    end\nend\n\n'''.format(ids=self.id_table, msg=msg_var, node=self.msg_var,
                sizes=self.sizes_table, flag=self.flags._value_var,
                table=self.table_var, length=self.length._value_var))

        return '\n'.join(i for i in data if i is not None)
Beispiel #4
0
    def match(self, name, code, definition=False, field=None):
        """Modify fields code if a cnf file demands it."""
        # Handle extra code rules
        if name is None and code is None:
            if definition:
                token = self.t_def_extra
            else:
                token = self.t_func_extra
            return self.rules.get((name, token), '')

        if definition:
            tokens = self.def_tokens
        else:
            tokens = self.func_tokens

        # Modify code if field match any rules, body first
        for token in sorted(tokens):
            content = self.rules.get((name, token), '')
            if not content:
                continue

            if not definition and field is not None:
                # Insert field offset into content
                content = content.replace('{OFFSET}', str(field.offset))

                # Insert value into content and code
                if '{VALUE}' in content:
                    variable = create_lua_var('field_value_var')
                    code = field.get_code(field.offset, store=variable)
                    content = content.replace('{VALUE}', variable)

            if token.endswith('_HEADER'):
                code = '%s\n%s' % (content, code)
            elif token.endswith('_FOOTER'):
                code = '%s\n%s' % (code, content)
            elif token.endswith('_BODY'):
                content = content.replace('%(DEFAULT_BODY)s', code)
                content = content.replace('{DEFAULT_BODY}', code)
                code = content

        return code
Beispiel #5
0
    def match(self, name, code, definition=False, field=None):
        """Modify fields code if a cnf file demands it."""
        # Handle extra code rules
        if name is None and code is None:
            if definition:
                token = self.t_def_extra
            else:
                token = self.t_func_extra
            return self.rules.get((name, token), '')

        if definition:
            tokens = self.def_tokens
        else:
            tokens = self.func_tokens

        # Modify code if field match any rules, body first
        for token in sorted(tokens):
            content = self.rules.get((name, token), '')
            if not content:
                continue

            if not definition and field is not None:
                # Insert field offset into content
                content = content.replace('{OFFSET}', str(field.offset))

                # Insert value into content and code
                if '{VALUE}' in content:
                    variable = create_lua_var('field_value_var')
                    code = field.get_code(field.offset, store=variable)
                    content = content.replace('{VALUE}', variable)

            if token.endswith('_HEADER'):
                code = '%s\n%s' % (content, code)
            elif token.endswith('_FOOTER'):
                code = '%s\n%s' % (code, content)
            elif token.endswith('_BODY'):
                content = content.replace('%(DEFAULT_BODY)s', code)
                content = content.replace('{DEFAULT_BODY}', code)
                code = content

        return code
Beispiel #6
0
    def __init__(self, name, platform, conf=None):
        """Create a new dissector instance.

        'name' is the protocol name
        'platform' is the platform dissecting messages from
        'conf' is an optional config object
        """
        self.name = name
        self.platform = platform
        self.endian = platform.endian
        self.conf = conf

        self.field_var = 'f.'
        from config import Options
        if len(Options.platforms) > 1:
            self.field_var += create_lua_var(platform.name)

        self.children = [] # List of all child fields

        self._pushed = False
        self._increase_offset = True
Beispiel #7
0
    def _dissector_func(self):
        """Add the code for the dissector function for the protocol."""
        data = ['-- Dissector function for: %s' % self.name]

        def retrieve_pinfo():
            data.append('\tif pinfo.private.field_name then')
            t = '\t\tsubtree:set_text(pinfo.private.field_name .. ": {name}")'
            data.append(t.format(name=child.name))
            data.append('\t\tpinfo.private.field_name = nil\n\telse')
            t = '\t\tpinfo.cols.info:append("({desc})")'
            data.append(t.format(desc=self.description))
            data.append('\tend')

        # Dissector function
        func_diss = 'function {var}.dissector(buffer, pinfo, tree)'
        data.append(func_diss.format(var=self.var))

        # Retrieve flag value from private info table
        flag_var = create_lua_var('flag')
        flag = '\tlocal {var} = tonumber(pinfo.private.platform_flag)'
        data.append(flag.format(var=flag_var))

        # If only 1 or less dissectors, insert dissector code directly
        if len(self.dissectors) < 2:
            if self.dissectors:
                child = list(self.dissectors.values())[0]
                sub_tree = '\tlocal subtree = tree:{add}({var}, buffer())'
                data.append(sub_tree.format(add=child.add_var, var=self.var))
                retrieve_pinfo()
                data.append(child.get_code(0))
            data.extend(['end', ''])
            return '\n'.join(i for i in data if i is not None)

        # Get flags and call the platform specific function
        table = {}
        for child in self.dissectors.values():
            child._func_name = create_lua_var(
                    '%s_%s' % (self.var, child.platform.name))
            table[child.platform.flag] = child._func_name
        table = create_lua_valuestring(table, wrap=False)
        data.append('\tlocal func_mapping = {table}'.format(table=table))
        data.append('\tif func_mapping[{var}] then'.format(var=flag_var))
        call = '\t\t func_mapping[{var}](buffer, pinfo, tree)'
        data.append(call.format(var=flag_var))
        data.extend(['\tend', 'end', ''])

        # Modify name if sub-dissector
        pinfo_func = create_lua_var('%s_pinfo_magic' % self.var)
        data.append('-- Function for retrieving parent dissector name')
        data.append('function {func}(pinfo, subtree)'.format(func=pinfo_func))
        retrieve_pinfo()
        data.extend(['end', ''])

        # Create dissector function for each dissector
        for child in self.dissectors.values():
            data.append('-- Dissector function for: %s (platform: %s)' % (
                    child.name, child.platform.name))
            func = 'function {name}(buffer, pinfo, tree)'
            data.append(func.format(name=child._func_name))

            # Add subtree
            sub_tree = '\tlocal subtree = tree:{add}({var}, buffer())'
            data.append(sub_tree.format(add=child.add_var, var=self.var))
            data.append('\t{func}(pinfo, subtree)'.format(func=pinfo_func))

            # Add the actual field code for each field
            data.append(child.get_code(0))
            data.extend(['end', ''])

        return '\n'.join(i for i in data if i is not None)