{"id":6606,"library":"dnfile","title":"dnfile","description":"dnfile is a Python library designed to parse .NET executable files. It aims to parse as much as possible, even if the file is partially malformed, and provides an easy-to-use, object-oriented API developed with IDE autocompletion in mind. The current version is 0.18.0, with a release cadence of several updates per year.","status":"active","version":"0.18.0","language":"en","source_language":"en","source_url":"https://github.com/malwarefrank/dnfile","tags":["parsing",".net","executable","malware analysis","pefile","reverse engineering"],"install":[{"cmd":"pip install dnfile","lang":"bash","label":"Install stable version"}],"dependencies":[{"reason":"Used internally for PE file parsing capabilities, as .NET executables are a type of PE file.","package":"pefile"}],"imports":[{"note":"The primary entry point for parsing a .NET executable file.","symbol":"dnPE","correct":"from dnfile import dnPE"},{"note":"Commonly imported directly to access top-level functions and classes like dnfile.dnPE, dnfile.stream, etc.","symbol":"dnfile","correct":"import dnfile"}],"quickstart":{"code":"import sys\nimport dnfile\n\n# For demonstration, create a dummy file or use a path to a real .NET exe\n# Replace 'dummy.exe' with a path to an actual .NET executable for real parsing\n# For a runnable quickstart, we'll simulate a file existence check.\nfilepath = \"path/to/your/dotnet_executable.exe\" # Placeholder\n\ntry:\n    # In a real scenario, you'd ensure filepath points to a valid file.\n    # For this example, we'll just demonstrate the parsing attempt.\n    # A real application would handle FileNotFoundError or similar.\n    pe = dnfile.dnPE(filepath)\n    \n    # Check if the .NET header exists\n    if hasattr(pe, \"net\") and pe.net:\n        print(f\"Successfully parsed .NET executable: {filepath}\")\n        print(f\"CLR Runtime Header Version: {pe.net.struct.MajorRuntimeVersion}.{pe.net.struct.MinorRuntimeVersion}\")\n        \n        # Accessing metadata tables (example)\n        if hasattr(pe.net, \"mdtables\") and pe.net.mdtables:\n            print(f\"Number of Metadata Tables: {len(pe.net.mdtables.tables_list)}\")\n            # Example: Iterate through some streams\n            for s in pe.net.metadata.streams_list:\n                print(f\"  Stream Name: {s.name}, Size: {s.size}\")\n    else:\n        print(f\"File {filepath} does not appear to be a .NET executable or parsing failed.\")\n\nexcept Exception as e:\n    print(f\"An error occurred: {e}\")\n","lang":"python","description":"This quickstart demonstrates how to load and parse a .NET executable file using `dnfile`. It shows how to access the CLR header and iterate through some basic metadata streams. For a real use case, `filepath` should point to an actual .NET executable."},"warnings":[{"fix":"Ensure your project environment uses Python 3.8 or a newer compatible version.","message":"Starting with version 0.14.0, `dnfile` requires Python 3.8 or newer. Attempts to use it with older Python versions will result in `ImportError` or other compatibility issues.","severity":"breaking","affected_versions":">=0.14.0"},{"fix":"If you were expecting `bytes`, you'll now need to access the `.value` attribute of the returned `HeapItem` (e.g., `item.value`). Be aware that `HeapItemString.value` can be `None` if decoding fails.","message":"In version 0.15.0, the behavior of heap stream's `.get()` method changed. It now returns a `HeapItem` object (e.g., `HeapItemString`, `HeapItemBinary`) instead of raw bytes.","severity":"breaking","affected_versions":">=0.15.0"},{"fix":"When accessing specific fields, be prepared for attributes to be `None` or use the `.struct` attribute (e.g., `pe.net.struct.MajorRuntimeVersion`) to access raw structure values directly. Validate attribute existence and non-`None` values before use.","message":"As of version 0.10.0, structure attributes no longer exist by default, and objects' attributes always exist but may be `None`. This means direct access to fields might require checks or use of the `.struct` attribute for raw values.","severity":"breaking","affected_versions":">=0.10.0"},{"fix":"Always check for the existence and validity of attributes (e.g., `if hasattr(pe, 'net') and pe.net:`) after parsing, especially when dealing with untrusted or potentially malformed input files.","message":"dnfile is designed to parse as much as possible, even if the .NET executable is partially malformed. This means that parsing a corrupted file might result in a `dnPE` object with incomplete or `None` attributes rather than raising an immediate error.","severity":"gotcha","affected_versions":"*"}],"env_vars":null,"last_verified":"2026-04-15T00:00:00.000Z","next_check":"2026-07-14T00:00:00.000Z","problems":[]}