# 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
    script_name = os.path.basename(config.ghidra_export_function)
    run = subprocess.Popen(
        [
            ghidra_headless_path, tmp_project_location, "fakeproj",
            "-import", func_heur.filename,
            "-preScript", script_name,
            "-scriptPath", script_path,
            "-scriptlog", tmp_log.name,
        ],
        env=env,
        stdout=subprocess.PIPE,
        stderr=subprocess.PIPE,
    )
    run.communicate()

    # Get back addresses
    tmp_log.seek(0)
    addresses = {}
    for line in tmp_log:
        info = re.findall(script_name + "> 0x([0-9a-f]+)", line)
        if info:
            addresses[int(info[0], 16)] = 1

    # Clean-up
    tmp_log.close()
    shutil.rmtree(tmp_project_location)

    return addresses



# 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

    script_name = os.path.basename(config.ghidra_export_function)
    run = subprocess.Popen(
        [
            ghidra_headless_path, tmp_project_location, "fakeproj",
            "-import", func_heur.filename,
            "-preScript", script_name,
            "-scriptPath", script_path,
            "-scriptlog", tmp_log.name,
        ],
        env=env,
        stdout=subprocess.PIPE,
        stderr=subprocess.PIPE,
    )
    run.communicate()

    # Get back addresses
    tmp_log.seek(0)
    addresses = {}
    for line in tmp_log:
        info = re.findall(script_name + "> 0x([0-9a-f]+)", line)
        if info:
            addresses[int(info[0], 16)] = 1

    # Clean-up
    tmp_log.close()
    shutil.rmtree(tmp_project_location)

    return addresses



class FuncHeuristic(Heuristic):