Python PE parsing module for analyzing Portable Executable (PE) files with comprehensive header, section, and directory entry support
—
Core functionality for loading, parsing, and accessing PE file structures including headers, sections, and data directories. The PE class serves as the main entry point for all PE file operations.
Creates a new PE instance by loading a PE file from disk or raw data in memory.
class PE:
def __init__(self, name=None, data=None, fast_load=None, max_symbol_exports=8192, max_repeated_symbol=120):
"""
Load and parse a PE file.
Args:
name (str, optional): Path to PE file to load
data (bytes, optional): Raw PE file data to parse
fast_load (bool, optional): Skip loading some directories for faster parsing
max_symbol_exports (int): Maximum number of export symbols to parse
max_repeated_symbol (int): Maximum repeated symbol count threshold
Note:
Must provide either 'name' or 'data', not both.
Can be used as context manager with 'with' statement.
"""
def __enter__(self):
"""
Enter context manager.
Returns:
PE: Self for context manager usage
"""
def __exit__(self, type, value, traceback):
"""
Exit context manager and clean up resources.
Args:
type: Exception type (if any)
value: Exception value (if any)
traceback: Exception traceback (if any)
"""Methods for managing file resources and cleaning up memory-mapped files.
def close(self):
"""
Close memory mapped file resources.
Should be called when done with PE file to free resources.
Automatically called when using PE as context manager.
"""
def full_load(self):
"""
Load all data directories if fast_load was used during initialization.
This method loads directory entries that were skipped during fast loading,
including imports, exports, resources, relocations, etc.
"""
def parse_rich_header(self):
"""
Parse Rich header information if present.
The Rich header contains compiler and linker information used during
PE file creation. This method populates the rich_header attribute.
"""Write modified PE files back to disk.
def write(self, filename=None):
"""
Write PE file to disk with any modifications.
Args:
filename (str, optional): Output filename. If None, overwrites original file.
Note:
This will write the PE file with any modifications made through
set_*_at_rva() or set_*_at_offset() methods.
"""Methods for accessing parsing information and warnings.
def get_warnings(self):
"""
Get list of parsing warnings encountered.
Returns:
list: List of warning strings
"""
def show_warnings(self):
"""Print warnings to stdout."""
def print_info(self, encoding="utf-8"):
"""
Print comprehensive PE file information to stdout.
Args:
encoding (str): Text encoding for output
"""
def dump_info(self, dump=None, encoding="ascii"):
"""
Return comprehensive PE file information as string.
Args:
dump (object, optional): Custom dump object
encoding (str): Text encoding for output
Returns:
str: Formatted PE file information
"""
def dump_dict(self):
"""
Return PE file information as dictionary.
Returns:
dict: PE file information in dictionary format
"""Methods to determine the type and characteristics of the PE file.
def is_exe(self):
"""
Check if PE file is an executable.
Returns:
bool: True if file is executable
"""
def is_dll(self):
"""
Check if PE file is a Dynamic Link Library.
Returns:
bool: True if file is DLL
"""
def is_driver(self):
"""
Check if PE file is a device driver.
Returns:
bool: True if file is driver
"""
def has_relocs(self):
"""
Check if PE file has relocation table.
Returns:
bool: True if file has relocations
"""
def has_dynamic_relocs(self):
"""
Check if PE file has dynamic relocations.
Returns:
bool: True if file has dynamic relocations
"""import pefile
# Load from file path
pe = pefile.PE('executable.exe')
# Check file type
if pe.is_exe():
print("This is an executable file")
elif pe.is_dll():
print("This is a DLL file")
# Access basic headers
print(f"Machine: {hex(pe.FILE_HEADER.Machine)}")
print(f"Sections: {pe.FILE_HEADER.NumberOfSections}")
print(f"Timestamp: {pe.FILE_HEADER.TimeDateStamp}")
# Clean up
pe.close()import pefile
# Automatic resource cleanup
with pefile.PE('executable.exe') as pe:
print(f"Entry point: {hex(pe.OPTIONAL_HEADER.AddressOfEntryPoint)}")
print(f"Image base: {hex(pe.OPTIONAL_HEADER.ImageBase)}")
# Check for warnings
warnings = pe.get_warnings()
if warnings:
print("Parsing warnings:")
for warning in warnings:
print(f" {warning}")import pefile
# Fast load - skip directories for speed
pe = pefile.PE('large_executable.exe', fast_load=True)
# Access basic info (available immediately)
print(f"Machine type: {pe.FILE_HEADER.Machine}")
# Load remaining directories when needed
pe.full_load()
# Now can access imports, exports, etc.
if hasattr(pe, 'DIRECTORY_ENTRY_IMPORT'):
print(f"Number of imports: {len(pe.DIRECTORY_ENTRY_IMPORT)}")
pe.close()import pefile
# Load PE data from memory
with open('executable.exe', 'rb') as f:
pe_data = f.read()
pe = pefile.PE(data=pe_data)
# Same functionality as file-based loading
print(f"Size of image: {pe.OPTIONAL_HEADER.SizeOfImage}")
pe.close()Install with Tessl CLI
npx tessl i tessl/pypi-pefile