def run(self): # Architecture architecture = False if self.args.architecture: architecture = self.args.architecture else: with open(self.args.filename) as fdesc: architecture = ArchHeuristic(fdesc).guess() if not architecture: raise ValueError( "Unable to recognize the architecture, please specify it") if self.args.verbose: print "Guessed architecture: %s" % architecture cont = Container.from_stream(open(self.args.filename)) machine = Machine(architecture) addr_size = machine.ira().pc.size / 4 fh = FuncHeuristic(cont, machine) # Enable / disable heuristics for name in self.args.enable_heuristic: heur = fh.name2heuristic(name) if heur not in fh.heuristics: fh.heuristics.append(heur) for name in self.args.disable_heuristic: heur = fh.name2heuristic(name) fh.heuristics.remove(heur) if self.args.verbose: print "Heuristics to run: %s" % ", ".join(fh.heuristic_names) # Launch guess fmt = "0x{:0%dx}" % addr_size for addr in fh.guess(): print fmt.format(addr)
def run(self): # Architecture architecture = False if self.args.architecture: architecture = self.args.architecture else: with open(self.args.filename) as fdesc: architecture = ArchHeuristic(fdesc).guess() if not architecture: raise ValueError("Unable to recognize the architecture, please specify it") if self.args.verbose: print "Guessed architecture: %s" % architecture cont = Container.from_stream(open(self.args.filename)) machine = Machine(architecture) addr_size = machine.ira().pc.size / 4 fh = FuncHeuristic(cont, machine) # Enable / disable heuristics for name in self.args.enable_heuristic: heur = fh.name2heuristic(name) if heur not in fh.heuristics: fh.heuristics.append(heur) for name in self.args.disable_heuristic: heur = fh.name2heuristic(name) fh.heuristics.remove(heur) if self.args.verbose: print "Heuristics to run: %s" % ", ".join(fh.heuristic_names) # Launch guess fmt = "0x{:0%dx}" % addr_size for addr in fh.guess(): print fmt.format(addr)
def get_funcs_heuristics(c_file, filename): """Get function from Sibyl heuristics""" # Force the activation of all heuristics fh = FuncHeuristic(None, None, "") cmd = ["sibyl", "func"] for name in fh.heuristic_names: cmd += ["-e", name] cmd.append(filename) print " ".join(cmd) sibyl = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout, stderr = sibyl.communicate() if stderr: raise RuntimeError("Something gone wrong...:\n%s" % stderr) # Parse output and merge with symtab (ground truth) to_check_symtab, extra = get_funcs_exe_source(c_file, filename) addr2name = {addr: name for addr, name in to_check_symtab} to_check = [] for line in stdout.split("\n"): if not line: continue addr = int(line, 0) if addr in addr2name: to_check.append((addr, name)) return to_check, extra
def run(self): # Architecture map_addr = int(self.args.mapping_base, 0) architecture = False if self.args.architecture: architecture = self.args.architecture else: with open(self.args.filename) as fdesc: architecture = ArchHeuristic(fdesc).guess() if not architecture: raise ValueError("Unable to recognize the architecture, please specify it") if self.args.verbose: print "Guessed architecture: %s" % architecture #cont = Container.from_stream(open(self.args.filename)) cont = Container.from_stream(open(self.args.filename), addr=map_addr) machine = Machine(architecture) addr_size = machine.ira().pc.size / 4 fh = FuncHeuristic(cont, machine, self.args.filename) # Default: force only IDA or GHIDRA if available if config.idaq64_path: fh.heuristics = [ida_funcs] elif config.ghidra_headless_path: fh.heuristics = [ghidra_funcs] # Enable / disable heuristics for name in self.args.enable_heuristic: heur = fh.name2heuristic(name) if heur not in fh.heuristics: fh.heuristics.append(heur) for name in self.args.disable_heuristic: heur = fh.name2heuristic(name) fh.heuristics.remove(heur) if self.args.verbose: print "Heuristics to run: %s" % ", ".join(fh.heuristic_names) # Launch guess fmt = "0x{:0%dx}" % addr_size for addr in fh.guess(): print fmt.format(addr)
# License for more details. # # You should have received a copy of the GNU General Public License # along with Sibyl. If not, see <http://www.gnu.org/licenses/>. import os from miasm2.analysis.machine import Machine from miasm2.analysis.binary import Container from sibyl.config import config, config_paths from sibyl.actions.action import Action from sibyl.heuristics.func import FuncHeuristic, ida_funcs from sibyl.heuristics.arch import ArchHeuristic heur_names = FuncHeuristic(None, None, "").heuristic_names class ActionFunc(Action): """Function discovering""" _name_ = "func" _desc_ = "Function discovering" _args_ = [ # Mandatory (["filename"], { "help": "File to load" }), # Optional (["-a", "--architecture"], { "help": "Target architecture",
else: with open(args.filename) as fdesc: architecture = ArchHeuristic(fdesc).guess() if not architecture: raise ValueError( "Unable to recognize the architecture, please specify it") if not args.quiet: print "Guessed architecture: %s" % architecture machine = Machine(architecture) if not args.address: if not args.quiet: print "No function address provided, start guessing" cont = Container.from_stream(open(args.filename)) fh = FuncHeuristic(cont, machine) addresses = list(fh.guess()) if not args.quiet: print "Found %d addresses" % len(addresses) else: addresses = [int(addr, 0) for addr in args.address] map_addr = int(args.mapping_base, 0) if args.monoproc: cpu_count = lambda: 1 Process = FakeProcess for abicls in ABIS: if args.abi == abicls.__name__: break else: raise ValueError("Unknown ABI name: %s" % args.abi)
def run(self): """Launch search""" # Import multiprocessing only when required from multiprocessing import cpu_count, Queue, Process # Parse args self.map_addr = int(self.args.mapping_base, 0) if self.args.monoproc: cpu_count = lambda: 1 Process = FakeProcess # Architecture architecture = False if self.args.architecture: architecture = self.args.architecture else: with open(self.args.filename) as fdesc: architecture = ArchHeuristic(fdesc).guess() if not architecture: raise ValueError( "Unable to recognize the architecture, please specify it") if self.args.verbose > 0: print "Guessed architecture: %s" % architecture self.machine = Machine(architecture) if not self.args.address: if self.args.verbose > 0: print "No function address provided, start guessing" cont = Container.from_stream(open(self.args.filename)) fh = FuncHeuristic(cont, self.machine) addresses = list(fh.guess()) if self.args.verbose > 0: print "Found %d addresses" % len(addresses) else: addresses = [int(addr, 0) for addr in self.args.address] # Select ABI if self.args.abi is None: candidates = set(abicls for abicls in ABIS if architecture in abicls.arch) if not candidates: raise ValueError("No ABI for architecture %s" % architecture) if len(candidates) > 1: print "Please specify the ABI:" print "\t" + "\n\t".join(cand.__name__ for cand in candidates) exit(0) abicls = candidates.pop() else: for abicls in ABIS: if self.args.abi == abicls.__name__: break else: raise ValueError("Unknown ABI name: %s" % self.args.abi) self.abicls = abicls # Select Test set self.tests = [] for tname, tcases in config.available_tests.iteritems(): if "all" in self.args.tests or tname in self.args.tests: self.tests += tcases if self.args.verbose > 0: print "Found %d test cases" % len(self.tests) # Prepare multiprocess cpu_c = cpu_count() addr_queue = Queue() msg_queue = Queue() processes = [] # Add tasks for address in addresses: addr_queue.put(address) # Add poison pill for _ in xrange(cpu_c): addr_queue.put(None) # Launch workers for _ in xrange(cpu_c): p = Process(target=self.do_test, args=(addr_queue, msg_queue)) processes.append(p) p.start() addr_queue.close() # Get results nb_poison = 0 results = {} # address -> possible functions while nb_poison < cpu_c: msg = msg_queue.get() # Poison pill if msg is None: nb_poison += 1 continue # Save result results[msg.address] = msg.results # Display status if needed if self.args.verbose > 0: sys.stdout.write("\r%d / %d" % (len(results), len(addresses))) sys.stdout.flush() if msg.results and self.args.output_format == "human": prefix = "" if self.args.verbose > 0: prefix = "\r" print prefix + "0x%08x : %s" % (msg.address, ",".join( msg.results)) # End connexions msg_queue.close() msg_queue.join_thread() addr_queue.join_thread() for p in processes: p.join() if not addr_queue.empty(): raise RuntimeError("An error occured: queue is not empty") # Print final results if self.args.output_format == "JSON": # Expand results to always have the same key, and address as int print json.dumps({ "information": { "total_count": len(addresses), "test_cases": len(self.tests) }, "results": [{ "address": addr, "functions": result } for addr, result in results.iteritems()], })