Package: dnfile
dnfileParse .NET executable files.Free software: MIT licenseFeaturesParse as much as we can, even if the file is partially malformed.Easy to use.  Developed with IDE autocompletion in mind.Quick StartpipinstalldnfileThen create a simple program that loads a .NET binary, parses it, and displays
information about the streams and Metadata Tables.importsysimportdnfilefilepath=sys.argv[1]pe=dnfile.dnPE(filepath)pe.print_info()Everything is an object, and raw structure values are stored in an object’s “struct”
attribute.  The CLR directory entry object is accessible from the “net”
attribute of a dnPE object.importdnfileimporthashlibpe=dnfile.dnPE(FILEPATH)# access the directory entry raw structure valuespe.net.struct# access the metadata raw structure valuespe.net.metadata.struct# access the streamsforsinpe.net.metadata.streams_list:ifisinstance(s,dnfile.stream.MetaDataTables):# how many Metadata tables are defined in the binary?num_of_tables=len(s.tables_list)# the last Metadata tables stream can also be accessed by a shortcutnum_of_tables=len(pe.net.mdtables.tables_list)# create a set to hold the hashes of all resourcesres_hash=set()# access the resourcesforrinpe.net.resources:# if resource data is a simple byte streamifisinstance(r.data,bytes):# hash it and add the hash to the setres_hash.add(hashlib.sha256(r.data).hexdigest())# if resource data is a ResourceSet, a dotnet-specific datatypeelifisinstance(r.data,dnfile.resource.ResourceSet):# if there are no entriesifnotr.data.entries:# skip itcontinue# for each entry in the ResourceSetforentryinr.data.entries:# if it has dataifentry.data:# hash it and add the hash to the setres_hash.add(hashlib.sha256(entry.data).hexdigest())TODOmore testsDocumentation on readthedocsCreditsThis package was created withCookiecutterand theaudreyr/cookiecutter-pypackageproject template.History0.14.1 (2023)fix github workflow0.14.0 (2023)BREAKING CHANGE: Minimum required Python version is now 3.8BUGFIX: ValueError fired before UnicodeDecodeError when parsing assembly resourcesBUGFIX: mdtable row run-lists of size one were being ignoredBUGFIX: some struct file offsets were RVA valuesFEATURE: Addclr_lazy_loadoption for lazy loading Metadata tables and assembly resourcesmove from legacy setup.py to pyproject.toml and toxbump dev dependencies: mypy and isortupdate tests and examplesupdate README badge to use download statistics from pypistats0.13.0 (2022)BREAKING CHANGE: rename GenericMethod mdtable to MethodSpec per ECMA 335parse more resources, even if there are exceptions0.12.0 (2022)FEATURE: parse#Schemastream as MetaDataTablesBUGFIX: MDTableRow off-by-one for end of runBUGFIX: MethodSemanticsRow typo list of tables for the Method Indexmore test data0.11.0 (2022)FEATURE: access .NET resources (not same as PE resources!) by a shortcutBUGFIX: dnstrings examplemore attributes default to Noneupdate dev dependenciesremove some warnings0.10.0 (2022)BREAKING CHANGE: structure attributes no longer exist by defaultBREAKING CHANGE: objects’ attributes always exist, but may be NoneBUGFIX: use last stream if multiple of same nameCI: added mypy type checkingwhen duplicate stream names, behave like runtime and use last one for shortcutsadd user_strings shortcutable to access MetaDataTables like a 0-based list, with square bracketsadded use of logging module for warningsbetter type hints for IDEsmore better source commentsmore tests0.9.0 (2021)bugfix: row indices parsed in structures are one-based, not zero-basedbugfix: TypeDefRow was not parsing Extends coded indexbugfix: incorrect BLOBS_MASK and add EXTRA_DATA skip if flag setadded CI using github workflowadded tests and submodule dnfile-testfilesadded style consistency using pycodestyle and isortadded more examplesparse MetaData tables’ list-type indexes into lists of MDTableRow objects0.8.0 (2021)bugfix: Metadata Table indexes (i.e. indexes into other tables) were off by one0.7.1 (2021)bugfix: coded index always None0.7.0 (2021)bugfix: improper data length check0.6.0 (2021)bugfix: referenced wrong objectparse utf-16 strings in #US stream0.5.0 (2021-01-29)First release.