Ejemplo n.º 1
0
    def include_heuristics(filename, platform, error):
        """Try to find missing includes from error message."""
        include = None
        msg = str(error)
        if "before: " in msg:
            key = msg.rsplit("before: ", 1)[1].strip()
            include = cparser.StructVisitor.all_known_types.get(key, None)
        if include is None:
            return False, None

        # Problem with typedef, TODO: improve this error handling
        if filename == include:
            return False, None

        new_error = create_dissector(filename, platform, folders, [include])
        if new_error != error:
            FileConfig.add_include(filename, include)
            if new_error is None:
                return True, None  # Worked
            return False, new_error  # Try more
        return False, None  # Give up
Ejemplo n.º 2
0
    def include_heuristics(filename, platform, error):
        """Try to find missing includes from error message."""
        include = None
        msg = str(error)
        if 'before: ' in msg:
            key = msg.rsplit('before: ', 1)[1].strip()
            include = cparser.StructVisitor.all_known_types.get(key, None)
        if include is None:
            return False, None

        # Problem with typedef, TODO: improve this error handling
        if filename == include:
            return False, None

        new_error = create_dissector(filename, platform, folders, [include])
        if new_error != error:
            FileConfig.add_include(filename, include)
            if new_error is None:
                return True, None  # Worked
            return False, new_error  # Try more
        return False, None  # Give up
Ejemplo n.º 3
0
def parse_headers(headers):
    """Parse 'headers' to create a Wireshark protocol dissector."""
    folders = {os.path.dirname(i) for i in headers}  # Folders to -Include
    failed = []  # Filenames, platforms pairs we have failed to parse so far

    def include_heuristics(filename, platform, error):
        """Try to find missing includes from error message."""
        include = None
        msg = str(error)
        if "before: " in msg:
            key = msg.rsplit("before: ", 1)[1].strip()
            include = cparser.StructVisitor.all_known_types.get(key, None)
        if include is None:
            return False, None

        # Problem with typedef, TODO: improve this error handling
        if filename == include:
            return False, None

        new_error = create_dissector(filename, platform, folders, [include])
        if new_error != error:
            FileConfig.add_include(filename, include)
            if new_error is None:
                return True, None  # Worked
            return False, new_error  # Try more
        return False, None  # Give up

    def print_status(tries=[]):
        """Print a status message with how many headers failed to parse."""
        if tries and tries[-1] == 0:
            return
        tries.append(len({i for i, j, k in failed}))
        if tries[-1] == 0:
            msg = "Successfully parsed all %i" % len(headers)
        else:
            msg = "Failed to parse %i out of %i" % (tries[-1], len(headers))
        print("[%i] %s header files" % (len(tries), msg))

    def filenames_have_shared_path(f1, f2):
        p1 = os.path.dirname(f1)
        p2 = os.path.dirname(f2)
        c = os.path.commonprefix([p1, p2])
        return c == p1 or c == p2

    print("[0] Attempting to parse %i header files" % len(headers))

    # First try, in the order given through the CLI
    for filename in headers:
        for platform in Options.platforms:
            error = create_dissector(filename, platform, folders)
            if error is not None:
                failed.append([filename, platform, error])
    print_status()

    # Try to include files based on decoding the error messages
    work_list = failed[:]
    for tmp in range(2, 4):
        for i in reversed(range(len(work_list))):
            status, new_error = include_heuristics(*work_list[i])
            if not status and new_error is not None:
                work_list[i][2] = new_error
            else:
                if status:
                    failed.remove(work_list[i])
                work_list.pop(i)
        print_status()

    # Try to include all who worked as it might help
    failed_names = [filename for filename, platform, error in failed]
    includes = [f for f in headers if f not in failed_names and filenames_have_shared_path(filename, f)]

    for i in reversed(range(len(failed))):
        filename, platform, tmp = failed.pop(i)
        error = create_dissector(filename, platform, folders, includes)
        if error is None:
            # Worked, record it in case anyone else needs this file
            for inc in includes:
                FileConfig.add_include(filename, inc)
            includes.append(filename)
        else:
            failed.append([filename, platform, error])
    print_status()

    # Try to include files based on decoding the error messages
    work_list = failed[:]
    for tmp in range(5, 7):
        for i in reversed(range(len(work_list))):
            status, new_error = include_heuristics(*work_list[i])
            if not status and new_error is not None:
                work_list[i][2] = new_error
            else:
                if status:
                    failed.remove(work_list[i])
                work_list.pop(i)
        print_status()

    # Give up!
    for filename, platform, error in failed:
        print('Skipped "%s":%s as it raised %s' % (filename, platform.name, repr(error)))

    return len({i for i, j, k in failed})
Ejemplo n.º 4
0
def parse_headers(headers):
    """Parse 'headers' to create a Wireshark protocol dissector."""
    folders = {os.path.dirname(i) for i in headers}  # Folders to -Include
    failed = []  # Filenames, platforms pairs we have failed to parse so far

    def include_heuristics(filename, platform, error):
        """Try to find missing includes from error message."""
        include = None
        msg = str(error)
        if 'before: ' in msg:
            key = msg.rsplit('before: ', 1)[1].strip()
            include = cparser.StructVisitor.all_known_types.get(key, None)
        if include is None:
            return False, None

        # Problem with typedef, TODO: improve this error handling
        if filename == include:
            return False, None

        new_error = create_dissector(filename, platform, folders, [include])
        if new_error != error:
            FileConfig.add_include(filename, include)
            if new_error is None:
                return True, None  # Worked
            return False, new_error  # Try more
        return False, None  # Give up

    def print_status(tries=[]):
        """Print a status message with how many headers failed to parse."""
        if tries and tries[-1] == 0:
            return
        tries.append(len({i for i, j, k in failed}))
        if tries[-1] == 0:
            msg = 'Successfully parsed all %i' % len(headers)
        else:
            msg = 'Failed to parse %i out of %i' % (tries[-1], len(headers))
        print('[%i] %s header files' % (len(tries), msg))

    def filenames_have_shared_path(f1, f2):
        p1 = os.path.dirname(f1)
        p2 = os.path.dirname(f2)
        c = os.path.commonprefix([p1, p2])
        return c == p1 or c == p2

    print('[0] Attempting to parse %i header files' % len(headers))

    # First try, in the order given through the CLI
    for filename in headers:
        for platform in Options.platforms:
            error = create_dissector(filename, platform, folders)
            if error is not None:
                failed.append([filename, platform, error])
    print_status()

    # Try to include files based on decoding the error messages
    work_list = failed[:]
    for tmp in range(2, 4):
        for i in reversed(range(len(work_list))):
            status, new_error = include_heuristics(*work_list[i])
            if not status and new_error is not None:
                work_list[i][2] = new_error
            else:
                if status:
                    failed.remove(work_list[i])
                work_list.pop(i)
        print_status()

    # Try to include all who worked as it might help
    failed_names = [filename for filename, platform, error in failed]
    includes = [
        f for f in headers
        if f not in failed_names and filenames_have_shared_path(filename, f)
    ]

    for i in reversed(range(len(failed))):
        filename, platform, tmp = failed.pop(i)
        error = create_dissector(filename, platform, folders, includes)
        if error is None:
            # Worked, record it in case anyone else needs this file
            for inc in includes:
                FileConfig.add_include(filename, inc)
            includes.append(filename)
        else:
            failed.append([filename, platform, error])
    print_status()

    # Try to include files based on decoding the error messages
    work_list = failed[:]
    for tmp in range(5, 7):
        for i in reversed(range(len(work_list))):
            status, new_error = include_heuristics(*work_list[i])
            if not status and new_error is not None:
                work_list[i][2] = new_error
            else:
                if status:
                    failed.remove(work_list[i])
                work_list.pop(i)
        print_status()

    # Give up!
    for filename, platform, error in failed:
        print('Skipped "%s":%s as it raised %s' %
              (filename, platform.name, repr(error)))

    return len({i for i, j, k in failed})