[文档]classLoaderSerializer:""" Serialize/unserialize a CLE Loader object into/from an angr DB. Corner cases: - For certain backends (e.g., CART), we do not store the data of the main object. angr will unpack the CART file again after loading the database. """NO_MAINBIN_BACKENDS=[cle.backends.CARTFile]LOAD_ARG_BLACKLIST={"loader","is_main_bin"}backend2name={v:kfork,vincle.ALL_BACKENDS.items()}
[文档]@staticmethoddefdump(session,loader):main_object_in_db=loader.main_objectskip_mainbin,new_main_obj=LoaderSerializer.should_skip_main_binary(loader)ifskip_mainbinandnew_main_objisnotNone:main_object_in_db=new_main_objforobjinloader.all_objects:ifisinstance(obj,(cle.ExternObject,cle.TLSObject,cle.KernelObject,),):# skip dynamically created objectscontinue# should we skip the main object?ifskip_mainbinandloader.main_objectisobj:continue# does the object exist?exists=session.query(DbObject.id).filter_by(path=obj.binary).scalar()isnotNoneifexists:# it exists. skip.continuetry:content=obj.cached_contentifhasattr(obj,"cached_content")elseNoneifcontentisNone:# fall back to loading the file again from diskwithopen(obj.binary,"rb")asthe_file:content=the_file.read()exceptOSErrorasex:raiseAngrDBError(f"Failed to load content for file {obj.binary}.")fromex# save the objecto=DbObject(main_object=main_object_in_dbisobj,path=obj.binary,content=content,backend=LoaderSerializer.backend2name.get(obj.__class__),backend_args=LoaderSerializer.json_serialize_load_args(obj.load_args),)session.add(o)
[文档]@staticmethoddefload(session):all_objects={}# path to objectmain_object=Nonedb_objects:list[DbObject]=session.query(DbObject)load_args={}decoder=LoadArgsJSONDecoder()fordb_oindb_objects:all_objects[db_o.path]=db_oifdb_o.main_object:main_object=db_oload_args[db_o]=decoder.decode(db_o.backend_args)ifdb_o.backend_argselse{}ifmain_objectisNone:raiseAngrCorruptDBError("Corrupt database: No main object.")# build params# FIXME: Load other objectsloader=cle.Loader(BytesIO(main_object.content),main_opts=load_args[main_object])skip_mainbin,_=LoaderSerializer.should_skip_main_binary(loader)loader._main_binary_path=main_object.pathifnotskip_mainbin:# fix the binary name of the main binaryloader.main_object.binary=main_object.pathreturnloader