# This submodule stores and manages FLIRT signaturesfromtypingimportSet,List,Dict,Optionalimportosimportjsonfromcollectionsimportdefaultdictimportloggingimportnampa_l=logging.getLogger(__name__)
[docs]classFlirtSignature:""" This class describes a FLIRT signature. """
FS=FlirtSignature# A dict from architecture names to FLIRT signatures under that architecture. Arch names are always in lower case.FLIRT_SIGNATURES_BY_ARCH:dict[str,list[FlirtSignature]]=defaultdict(list)LIBRARY_TO_SIGNATURES:dict[str,list[FlirtSignature]]=defaultdict(list)STRING_TO_LIBRARIES:dict[str,set[str]]=defaultdict(set)
[docs]defload_signatures(path:str)->None:""" Recursively load all FLIRT signatures under a specific path. :param path: Location of FLIRT signatures. """FLIRT_SIGNATURES_BY_ARCH.clear()LIBRARY_TO_SIGNATURES.clear()STRING_TO_LIBRARIES.clear()forroot,_,filenamesinos.walk(path):forfilenameinfilenames:iffilename.endswith(".sig"):# parse itsig_path=os.path.join(root,filename)try:withopen(sig_path,"rb")asf:flirt_header=nampa.flirt.parse_header(f)exceptnampa.flirt.FlirtException:_l.warning("Failed to load FLIRT signature file %s.",sig_path)continue# is there a meta data file?meta_path=os.path.join(root,filename[:-4]+".meta")ifos.path.isfile(meta_path):# yes!withopen(meta_path)asf:meta=json.load(f)arch=meta.get("arch",None)platform=meta.get("platform",None)os_name=meta.get("os",None)os_version=meta.get("os_version",None)compiler=meta.get("compiler",None)compiler_version=meta.get("compiler_version",None)unique_strings=meta.get("unique_strings",None)else:# nope... we need to extract information from the signature file# TODO: Convert them to angr-specific stringsarch=flirt_header.archplatform=flirt_header.os_typesos_name=Noneos_version=Noneunique_strings=Nonecompiler=Nonecompiler_version=Nonesignature=FlirtSignature(arch,platform,flirt_header.library_name.decode("utf-8"),sig_path,unique_strings=unique_strings,compiler=compiler,compiler_version=compiler_version,os_name=os_name,os_version=os_version,)FLIRT_SIGNATURES_BY_ARCH[arch].append(signature)# fill in LIBRARY_TO_SIGNATURES and STRING_TO_LIBRARIESforsigsinFLIRT_SIGNATURES_BY_ARCH.values():forsiginsigs:LIBRARY_TO_SIGNATURES[sig.sig_name].append(sig)ifsig.unique_strings:forusinsig.unique_strings:STRING_TO_LIBRARIES[us].add(sig.sig_name)