dnfile
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.
Warnings
- breaking 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.
- breaking 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.
- breaking 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.
- gotcha 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.
Install
-
pip install dnfile
Imports
- dnPE
from dnfile import dnPE
- dnfile
import dnfile
Quickstart
import sys
import dnfile
# For demonstration, create a dummy file or use a path to a real .NET exe
# Replace 'dummy.exe' with a path to an actual .NET executable for real parsing
# For a runnable quickstart, we'll simulate a file existence check.
filepath = "path/to/your/dotnet_executable.exe" # Placeholder
try:
# In a real scenario, you'd ensure filepath points to a valid file.
# For this example, we'll just demonstrate the parsing attempt.
# A real application would handle FileNotFoundError or similar.
pe = dnfile.dnPE(filepath)
# Check if the .NET header exists
if hasattr(pe, "net") and pe.net:
print(f"Successfully parsed .NET executable: {filepath}")
print(f"CLR Runtime Header Version: {pe.net.struct.MajorRuntimeVersion}.{pe.net.struct.MinorRuntimeVersion}")
# Accessing metadata tables (example)
if hasattr(pe.net, "mdtables") and pe.net.mdtables:
print(f"Number of Metadata Tables: {len(pe.net.mdtables.tables_list)}")
# Example: Iterate through some streams
for s in pe.net.metadata.streams_list:
print(f" Stream Name: {s.name}, Size: {s.size}")
else:
print(f"File {filepath} does not appear to be a .NET executable or parsing failed.")
except Exception as e:
print(f"An error occurred: {e}")