CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-pefile

Python PE parsing module for analyzing Portable Executable (PE) files with comprehensive header, section, and directory entry support

Pending
Overview
Eval results
Files

data-access.mddocs/

Data Access and Modification

Methods for reading and writing data within PE files, including address translation between file offsets and relative virtual addresses (RVAs). These functions enable direct manipulation of PE file contents.

Capabilities

Address Translation

Convert between file offsets and relative virtual addresses (RVAs) for accurate data access.

def get_rva_from_offset(self, offset):
    """
    Convert file offset to relative virtual address (RVA).
    
    Args:
        offset (int): File offset
        
    Returns:
        int: RVA corresponding to the offset, or None if invalid
    """

def get_offset_from_rva(self, rva):
    """
    Convert relative virtual address (RVA) to file offset.
    
    Args:
        rva (int): Relative virtual address
        
    Returns:
        int: File offset corresponding to the RVA, or None if invalid
    """

def get_physical_by_rva(self, rva):
    """
    Get physical address from RVA.
    
    Args:
        rva (int): Relative virtual address
        
    Returns:
        int: Physical address
    """

Data Reading

Read raw data and strings from PE files at specific locations.

def get_data(self, rva=0, length=None):
    """
    Get data at RVA regardless of section boundaries.
    
    Args:
        rva (int): Relative virtual address to read from
        length (int, optional): Number of bytes to read. If None, reads to end.
        
    Returns:
        bytes: Data at the specified RVA
    """

def get_string_at_rva(self, rva, max_length=1048576):
    """
    Get null-terminated ASCII string at RVA.
    
    Args:
        rva (int): Relative virtual address
        max_length (int): Maximum string length to prevent excessive memory use
        
    Returns:
        bytes: ASCII string (without null terminator)
    """

def get_string_u_at_rva(self, rva, max_length=65536, encoding=None):
    """
    Get null-terminated Unicode string at RVA.
    
    Args:
        rva (int): Relative virtual address
        max_length (int): Maximum string length in characters
        encoding (str, optional): Text encoding to use
        
    Returns:
        str: Unicode string
    """

def get_bytes_from_data(self, offset, data):
    """
    Get bytes from data buffer starting at offset.
    
    Args:
        offset (int): Offset into data buffer
        data (bytes): Data buffer
        
    Returns:
        bytes: Extracted bytes
    """

def get_string_from_data(self, offset, data):
    """
    Get null-terminated ASCII string from data buffer.
    
    Args:
        offset (int): Offset into data buffer
        data (bytes): Data buffer
        
    Returns:
        bytes: ASCII string (without null terminator)
    """

Integer Data Access

Read and write integer values at specific addresses with various sizes.

def get_dword_at_rva(self, rva):
    """
    Get 32-bit unsigned integer at RVA.
    
    Args:
        rva (int): Relative virtual address
        
    Returns:
        int: 32-bit value at RVA
    """

def get_word_at_rva(self, rva):
    """
    Get 16-bit unsigned integer at RVA.
    
    Args:
        rva (int): Relative virtual address
        
    Returns:
        int: 16-bit value at RVA
    """

def get_qword_at_rva(self, rva):
    """
    Get 64-bit unsigned integer at RVA.
    
    Args:
        rva (int): Relative virtual address
        
    Returns:
        int: 64-bit value at RVA
    """

def set_dword_at_rva(self, rva, dword):
    """
    Set 32-bit unsigned integer at RVA.
    
    Args:
        rva (int): Relative virtual address
        dword (int): 32-bit value to write
    """

def set_word_at_rva(self, rva, word):
    """
    Set 16-bit unsigned integer at RVA.
    
    Args:
        rva (int): Relative virtual address
        word (int): 16-bit value to write
    """

def set_qword_at_rva(self, rva, qword):
    """
    Set 64-bit unsigned integer at RVA.
    
    Args:
        rva (int): Relative virtual address
        qword (int): 64-bit value to write
    """

def set_bytes_at_rva(self, rva, data):
    """
    Set bytes at RVA.
    
    Args:
        rva (int): Relative virtual address
        data (bytes): Data bytes to write
    """

def get_dword_from_offset(self, offset):
    """
    Get 32-bit unsigned integer at file offset.
    
    Args:
        offset (int): File offset
        
    Returns:
        int: 32-bit value at offset
    """

def set_dword_at_offset(self, offset, dword):
    """
    Set 32-bit unsigned integer at file offset.
    
    Args:
        offset (int): File offset
        dword (int): 32-bit value to write
    """

def get_word_at_rva(self, rva):
    """
    Get 16-bit unsigned integer at RVA.
    
    Args:
        rva (int): Relative virtual address
        
    Returns:
        int: 16-bit value at RVA
    """

def set_word_at_rva(self, rva, word):
    """
    Set 16-bit unsigned integer at RVA.
    
    Args:
        rva (int): Relative virtual address
        word (int): 16-bit value to write
    """

def get_word_from_offset(self, offset):
    """
    Get 16-bit unsigned integer at file offset.
    
    Args:
        offset (int): File offset
        
    Returns:
        int: 16-bit value at offset
    """

def set_word_at_offset(self, offset, word):
    """
    Set 16-bit unsigned integer at file offset.
    
    Args:
        offset (int): File offset
        word (int): 16-bit value to write
    """

def get_qword_at_rva(self, rva):
    """
    Get 64-bit unsigned integer at RVA.
    
    Args:
        rva (int): Relative virtual address
        
    Returns:
        int: 64-bit value at RVA
    """

def set_qword_at_rva(self, rva, qword):
    """
    Set 64-bit unsigned integer at RVA.
    
    Args:
        rva (int): Relative virtual address
        qword (int): 64-bit value to write
    """

def get_qword_from_offset(self, offset):
    """
    Get 64-bit unsigned integer at file offset.
    
    Args:
        offset (int): File offset
        
    Returns:
        int: 64-bit value at offset
    """

def set_qword_at_offset(self, offset, qword):
    """
    Set 64-bit unsigned integer at file offset.
    
    Args:
        offset (int): File offset
        qword (int): 64-bit value to write
    """

Byte Array Operations

Read and write arbitrary byte sequences at specific locations.

def set_bytes_at_rva(self, rva, data):
    """
    Set bytes at RVA.
    
    Args:
        rva (int): Relative virtual address
        data (bytes): Data to write
    """

def set_bytes_at_offset(self, offset, data):
    """
    Set bytes at file offset.
    
    Args:
        offset (int): File offset
        data (bytes): Data to write
    """

def set_data_bytes(self, offset, data):
    """
    Set bytes in internal PE data buffer.
    
    Args:
        offset (int): Offset into internal data
        data (bytes): Data to write
    """

Section Data Management

Manage modified section data and apply changes to the PE structure.

def merge_modified_section_data(self):
    """
    Update PE internal data with modified section data.
    
    This method applies any changes made to section data back to the
    main PE data structure, ensuring consistency between section objects
    and the underlying file data.
    """

Usage Examples

Reading String Data

import pefile

with pefile.PE('executable.exe') as pe:
    # Read ASCII string at specific RVA
    string_data = pe.get_string_at_rva(0x1000)
    print(f"ASCII string: {string_data}")
    
    # Read Unicode string
    unicode_string = pe.get_string_u_at_rva(0x2000)
    print(f"Unicode string: {unicode_string}")
    
    # Read raw data
    raw_data = pe.get_data(0x3000, 100)  # Read 100 bytes
    print(f"Raw data: {raw_data.hex()}")

Address Translation

import pefile

with pefile.PE('executable.exe') as pe:
    # Convert between file offset and RVA
    file_offset = 0x1000
    rva = pe.get_rva_from_offset(file_offset)
    print(f"File offset {hex(file_offset)} -> RVA {hex(rva)}")
    
    # Convert back
    back_to_offset = pe.get_offset_from_rva(rva)
    print(f"RVA {hex(rva)} -> File offset {hex(back_to_offset)}")

Modifying PE Data

import pefile

# Load PE file
pe = pefile.PE('executable.exe')

# Modify a DWORD value at specific RVA
original_value = pe.get_dword_at_rva(0x1000)
print(f"Original value: {hex(original_value)}")

pe.set_dword_at_rva(0x1000, 0x12345678)
new_value = pe.get_dword_at_rva(0x1000)
print(f"New value: {hex(new_value)}")

# Write modified PE file
pe.write('modified_executable.exe')

pe.close()

Working with Section Data

import pefile

with pefile.PE('executable.exe') as pe:
    # Access section by RVA
    section = pe.get_section_by_rva(0x1000)
    if section:
        print(f"Section name: {section.Name.decode('utf-8').strip()}")
        
        # Modify section data
        section_data = bytearray(section.get_data())
        section_data[0:4] = b'TEST'  # Replace first 4 bytes
        
        # Update section with modified data
        section.set_data(bytes(section_data))
        
        # Apply changes to PE structure
        pe.merge_modified_section_data()

Overlay Data Access

import pefile

with pefile.PE('executable.exe') as pe:
    # Check if file has overlay data
    overlay_start = pe.get_overlay_data_start_offset()
    if overlay_start:
        print(f"Overlay starts at offset: {hex(overlay_start)}")
        
        # Get overlay data
        overlay = pe.get_overlay()
        print(f"Overlay size: {len(overlay)} bytes")
        
        # Remove overlay and get clean PE
        clean_pe_data = pe.trim()
        with open('clean_executable.exe', 'wb') as f:
            f.write(clean_pe_data)

Install with Tessl CLI

npx tessl i tessl/pypi-pefile

docs

data-access.md

debug.md

hashing.md

import-export.md

index.md

memory.md

ordinal-lookups.md

packer-detection.md

pe-parsing.md

resources.md

sections.md

tile.json