PeNet Documentation

repository·main·Indexed 20 days ago

https://github.com/secana/penet

PeNet is a pure C# parser for Windows Portable Executable (PE) files designed for security researchers and malware analysts. It allows for extracting metadata, computing hashes such as ImpHash and TypeRefHash (TRH), inspecting headers, and managing PE sections without native Windows dependencies. The library supports multiple parsing methods via byte arrays, streams, and memory-mapped files to optimize for performance and memory usage.

Tokens
4K
Snippets
17
Records
20
Agent score
71%

What's inside PeNet

  1. What is PeNet?

    main

    PeNet is a C# library designed for parsing Windows Portable Executable (PE) headers. It is a pure C# implementation that does not rely on native Windows APIs, making it portable.

    Key capabilities include:

    • Parsing PE file headers.
    • Generating Import Hashes (ImpHash), a common technique in malware analysis.
    • Extracting Certificate Revocation Lists (CRL).
    • Computing various hash sums for PE files.
  2. Choose a PE file parsing method based on file size and performance

    main

    PeNet provides several ways to open and parse a PE file. The best method depends on your requirements for memory usage, performance, and whether you intend to modify the file.

    1. Byte Array (Small Files / Modification)

    Best for very small files or when you want to write/change the PE file without affecting the original on disk. A full copy of the file is held in memory; changes are made to the copy, which you can then save to a new file.

    • Warning: Memory usage scales with file size. Performance decreases for files larger than 10 MB.

    2. Stream (Low Memory / Constant Usage)

    Best for keeping memory usage low and constant regardless of file size.

    • Warning: Performance is lower than other methods. If you modify the stream, changes are written directly to the original file, which may cause unwanted side-effects.

    3. Memory Mapped File (Large Files / High Performance)

    The fastest method for large files with the lowest memory consumption.

    • Warning: Like streams, all writes are applied directly to the original input file.
    // Byte Array
    var bin = File.ReadAllBytes(@"C:\Windows\System32\kernel32.dll");
    var peHeader = new PeNet.PeFile(bin);
    
    // Stream
    using var fileStream = File.OpenRead(@"C:\Windows\System32\kernel32.dll");
    var peHeader = new PeNet.PeFile(fileStream);
    
    // Memory Mapped File
    using var mmf = new PeNet.FileParser.MMFile(@"C:\Windows\System32\kernel32.dll");
    var peHeader = new PeNet.PeFile(mmf);
  3. Calculate the TypeRefHash (TRH) for a .NET PE file

    main

    The TypeRefHash (TRH) is a hash calculated over imported .NET namespaces and types. It is used to identify malware families that share code in scenarios where the ImpHash (Import Hash) is ineffective. You can retrieve the TRH as a hex-string from a PeFile instance using the TypeRefHash property.

    var peFile = new PeFile(file);
    
    // get the TRH as a hex-string.
    var trh = peFile.TypeRefHash;
    
    Console.WriteLine(trh);
    // prints for example the TRH:
    // > d633db771449e2c37e1689a8c291a4f4646ce156652a9dad5f67394c0d92a8c4
  4. Open and parse a PE file

    main

    You can initialize a PeNet.PeFile object by providing either a file path on disk or a byte array containing the PE file data.

    // Open a file from disk
    var peHeader1 = new PeNet.PeFile(@"C:\Windows\System32\kernel32.dll");
    
    // Parse a byte array
    var bin = File.ReadAllBytes(@"C:\Windows\System32\kernel32.dll");
    var peHeader2 = new PeNet.PeFile(bin);
  5. Access PeNet documentation and web analysis tools

    main

    For detailed technical specifications and method signatures, use the official API Reference. For a web-based interface to analyze PE files without writing code, use the PeNet web tool.

    API Reference: http://secana.github.io/PeNet
    Web Analysis: http://penet.secana.org
  6. Extract Code View PDB v7 information from a PE file

    main

    PeNet can extract Code View PDB v7 information from the debug directory of a PE file. This information includes the PdbFileName (useful for malware family identification) and the Signature GUID (useful for downloading matching symbols from the Microsoft public symbol server for memory forensics or debugging).

    To access this, iterate through the ImageDebugDirectory of a PeFile instance and locate the entry where CvInfoPdb70 is not null.

    using System;
    using System.Linq;
    using PeNet;
    
    namespace Pdb
    {
        class Program
        {
            static void Main(string[] args)
            {
                var peFile = new PeFile("peWithDbgInfo.exe");
    
                // Select the first debug directory with
                // PDB information available.
                var pdbInfo = peFile
                    .ImageDebugDirectory
                    .First(idb => idb.CvInfoPdb70 != null)
                    .CvInfoPdb70;
    
                // Print content of the Code View PDB v7 structure
                Console.WriteLine(pdbInfo);
            }
        }
    }
  7. Access PE header information

    main

    Once a PeFile is initialized, you can access various parts of the PE header through different modules and sub-modules. Common tasks include retrieving file alignment, import descriptors, and parsed function lists.

    // Get the file alignment of the PE file
    var fileAlignment = peHeader.WindowsSpecificFields.FileAlignment;
    
    // Get the import descriptors of the PE file
    var if = peHeader.DataDirectories.ImageImportDescriptors;
    
    // Get the imported and exported functions in a parsed form
    var importedFunctions = peHeader.ImportedFunctions;
    var exportedFunctions = peHeader.ExportedFunctions;
  8. Remove a section from a PE file

    main

    Use the RemoveSection method to delete a section from a PE file. You can control whether the actual data of the section is removed from the file or just the entry in the section table.

    Usage Modes:

    • Full Removal (Default): Removes the section from the section table AND deletes the section's content from the file.
    • Table-only Removal: By passing false as the second argument, you remove the section from the section table but keep the actual content within the file.

    Method Signature: peFile.RemoveSection(string sectionName, bool removeContent = true)

    var peFile = new PeFile("myapp.exe");
    
    // Remove the resource section from the section table and the content
    // of the section from the file.
    peFile.RemoveSection(".rsrc");
    
    // Alternatively you can only remove the section from the section table
    // and keep the content of the section in the file.
    peFile.RemoveSection(".rsrc", false);
  9. Access file hashes (MD5, SHA-1, SHA-256) from a PeFile

    main

    When working with PE files, you can retrieve cryptographic hashes to compare files for equality. PeNet provides direct properties on the PeFile instance to access MD5, SHA-1, and SHA-256 hashes.

    var pe = new PeNet.PeFile(@"c:\windows\system32\calc.exe");
    
    // Access individual hashes
    Console.WriteLine($"MD5: {pe.Md5}");
    Console.WriteLine($"SHA-1: {pe.Sha1}");
    Console.WriteLine($"SHA256: {pe.Sha256}");
  10. Access PE file section table entries

    main

    To inspect the sections within a Portable Executable (PE) file, use the ImageSectionHeaders property on a PeFile instance. This returns an array containing all section table entries.

    var peFile = new PeFile("myapp.exe");
    
    // Get array with all section table entries.
    var sections = peFile.ImageSectionHeaders;