# Path: sibyl/heuristics/heuristic.py
# class Heuristic(object):
#     """Main class for heuristics, handle common methods related to them"""
# 
#     # Enabled passes
#     # passes are functions taking 'self' and returning a dict:
#     #    candidates -> estimated probability
#     heuristics = []
# 
#     def __init__(self):
#         self._votes = None
# 
#     def do_votes(self):
#         """Call heuristics and get back votes
#         Use a cumulative linear strategy for comparison
#         """
#         votes = {}
#         for heuristic in self.heuristics:
#             for name, vote in heuristic(self).iteritems():
#                 votes[name] = votes.get(name, 0) + vote
#         self._votes = votes
# 
#     @property
#     def votes(self):
#         """Cumulative votes for each candidates"""
#         if not self._votes:
#             self.do_votes()
#         return self._votes
# 
#     @property
#     def heuristic_names(self):
#         """Return the list of available heuristics"""
#         return [func.__name__ for func in self.heuristics]
# 
#     def name2heuristic(self, name):
#         """Return the heuristic named @name"""
#         for func in self.heuristics:
#             if func.__name__ == name:
#                 return func
#         else:
#             raise KeyError("Unable to find %s" % name)
# 
#     def guess(self):
#         """Return the best candidate"""
#         sorted_votes = sorted(self.votes.iteritems(), key=lambda x:x[1])
#         if not sorted_votes:
#             # No solution
#             return False
#         best, _ = sorted_votes[-1]
#         return best
# 
# Path: sibyl/config.py
# class Config(object):
#     def __init__(self, default_config, files):
#     def expandpath(path):
#     def parse_files(self, files):
#     def dump(self):
#     def jit_engine(self):
#     def available_tests(self):
#     def miasm_engine(self):
#     def pin_root(self):
#     def pin_tracer(self):
#     def prune_strategy(self):
#     def prune_keep(self):
#     def prune_keep_max(self):
#     def stubs(self):
#     def idaq64_path(self):
#     def ghidra_headless_path(self):
#     def ghidra_export_function(self):


import logging
import re
import tempfile
import subprocess
import shutil
import os
import sibyl.heuristics.csts as csts
from miasm2.core.asmblock import AsmBlockBad, log_asmblock
from sibyl.heuristics.heuristic import Heuristic
from sibyl.config import config

    # Search for function prologs

    pattern = "(" + ")|(".join(prologs) + ")"
    for find_iter, vaddr_base in _virt_find(data, pattern):
        for match in find_iter:
            addr = match.start() + vaddr_base
            addresses[addr] = 1

    return addresses


def named_symbols(func_heur):
    """Return the addresses of named symbols"""

    cont = func_heur.cont
    loc_db = cont.loc_db

    # Use the entry point
    addresses = [cont.entry_point]
    # Add address of symbol with a name (like 'main')
    addresses += [loc_db.get_location_offset(loc)
                  for loc in loc_db.loc_keys
                  if loc_db.get_location_names(loc) is not None]
    return {addr: 1 for addr in addresses}


def ida_funcs(func_heur):
    """Use IDA heuristics to find functions"""


# Path: sibyl/heuristics/heuristic.py
# class Heuristic(object):
#     """Main class for heuristics, handle common methods related to them"""
# 
#     # Enabled passes
#     # passes are functions taking 'self' and returning a dict:
#     #    candidates -> estimated probability
#     heuristics = []
# 
#     def __init__(self):
#         self._votes = None
# 
#     def do_votes(self):
#         """Call heuristics and get back votes
#         Use a cumulative linear strategy for comparison
#         """
#         votes = {}
#         for heuristic in self.heuristics:
#             for name, vote in heuristic(self).iteritems():
#                 votes[name] = votes.get(name, 0) + vote
#         self._votes = votes
# 
#     @property
#     def votes(self):
#         """Cumulative votes for each candidates"""
#         if not self._votes:
#             self.do_votes()
#         return self._votes
# 
#     @property
#     def heuristic_names(self):
#         """Return the list of available heuristics"""
#         return [func.__name__ for func in self.heuristics]
# 
#     def name2heuristic(self, name):
#         """Return the heuristic named @name"""
#         for func in self.heuristics:
#             if func.__name__ == name:
#                 return func
#         else:
#             raise KeyError("Unable to find %s" % name)
# 
#     def guess(self):
#         """Return the best candidate"""
#         sorted_votes = sorted(self.votes.iteritems(), key=lambda x:x[1])
#         if not sorted_votes:
#             # No solution
#             return False
#         best, _ = sorted_votes[-1]
#         return best
# 
# Path: sibyl/config.py
# class Config(object):
#     def __init__(self, default_config, files):
#     def expandpath(path):
#     def parse_files(self, files):
#     def dump(self):
#     def jit_engine(self):
#     def available_tests(self):
#     def miasm_engine(self):
#     def pin_root(self):
#     def pin_tracer(self):
#     def prune_strategy(self):
#     def prune_keep(self):
#     def prune_keep_max(self):
#     def stubs(self):
#     def idaq64_path(self):
#     def ghidra_headless_path(self):
#     def ghidra_export_function(self):


# Path: sibyl/heuristics/func.py
import logging
import re
import tempfile
import subprocess
import shutil
import os
import sibyl.heuristics.csts as csts
from miasm2.core.asmblock import AsmBlockBad, log_asmblock
from sibyl.heuristics.heuristic import Heuristic
from sibyl.config import config


    # Search for function prologs

    pattern = "(" + ")|(".join(prologs) + ")"
    for find_iter, vaddr_base in _virt_find(data, pattern):
        for match in find_iter:
            addr = match.start() + vaddr_base
            addresses[addr] = 1

    return addresses


def named_symbols(func_heur):
    """Return the addresses of named symbols"""

    cont = func_heur.cont
    loc_db = cont.loc_db

    # Use the entry point
    addresses = [cont.entry_point]
    # Add address of symbol with a name (like 'main')
    addresses += [loc_db.get_location_offset(loc)
                  for loc in loc_db.loc_keys
                  if loc_db.get_location_names(loc) is not None]
    return {addr: 1 for addr in addresses}


def ida_funcs(func_heur):
    """Use IDA heuristics to find functions"""


    idaq64_path = config.idaq64_path