PECompact Interoperability

This document is under construction. It may contain inaccuracies or be incomplete.

Overview

Scanning of PECompact'd executables isn't very difficult, but it must be done correctly since PECompact supports usage of any number of CODEC plug-ins on a single executable, as well as third-party CODEC plug-ins. You should never assume compressed executables use only a single CODEC, or that they use only CODECs including in the PECompact product. Your scanner should iterate through the encoded blocks of the original executable, passing each one through the chain of decoders (through emulation or execution). Once you've got this accomplished, your support of PECompact will be top-notch.

Data structures

PEC_HOST_INFO

The PEC_HOST_INFO block is the primary data block that describes the compressed module and where to locate other data structures necessary to restore the compressed module to its original (uncompressed) state.

typedef struct _PEC_HOST_INFO
{
    WORD m_wStructSize;                 // size of this structure
    WORD m_wTotalDecoders;              // total decoders in decoder array
    DWORD m_dwDefaultImageBase;         // the default image base of the module
    DWORD m_dwActualImageBase;          // fixup entry for this..   
    DWORD m_dwOriginalEntryPoint;       // the original entry point RVA
    DWORD m_dwOriginalImportsSize;      // original import data directory size
    DWORD m_RVALoaderDecoder;           // the RVA of the decoder for the loader
    DWORD m_RVACOR20Header;             // the RVA of the COM+ descriptor
    DWORD m_ppLoadLibrary;              // **LoadLibraryA
    DWORD m_ppGetProcAddress;           // **GetProcAddress	
    DWORD m_RVADataBlock;				// Loader data block RVA (2.76+)
    WORD m_wTlsCallbackCount;			// todo: re-arrange so similar values adjacent
    WORD m_wUnused0002;
    DWORD m_dwWorkingMemoryRequired;    // reqd size of temporary working memory for reconstruction
    DWORD m_dwDecodeFuncArrayOffset;    // offset from beginning of PEC_HOST_INFO to decoder array
    DWORD m_dwRVAOriginalImportDirectory;  // RVA of original import dir. may have been modified to proprietary structs
    DWORD m_dwRVAOriginalRelocDirectory;   // RVA of original base reloc dir. may have been modified to proprietary structs 
    DWORD m_wNumberOfPecBlocks;         // number of PEC_BLOCK descriptors in block array.
    DWORD m_dwStubRVA;                  // RVA of loader stub 0 (SEH entry)
    DWORD m_dwRVAOriginalBytes;         // RVA of original bytes overwritten by loader stub 0 
    DWORD m_dwNewEntryInLastSection;    // 
    DWORD m_dwExtraBlockDataArrayOffset;// offset to array of relocated data (overkill/extra data) descriptors (expanded by encoders beyond section limits) 
} PEC_HOST_INFO, *PPEC_HOST_INFO;
  

PEC_BLOCK

A PEC_BLOCK describes a block of processed data. Just how it was processed is indicated by the m_wFlags variable.

typedef struct _PEC_BLOCK
{
    DWORD m_rvaSource;
    DWORD m_rvaDestination;
    DWORD m_nSize;
    DWORD m_dwOriginalSize;
    WORD m_wFlags;       // indicates block type (how it was processed or encoded)
    WORD m_wExtra;			// has different meanings depending on m_wFlags
    DWORD m_nOverkillSize;  // number of bytes that were stored elsewhere and must be pre-pended
                            // union with above	DWORD m_nChecksum32;	// when flags is PEC_BLOCK_FLAG_PREPROCESSED_CODE, holds 32bit checksum of original block data	
    WORD m_wOverkillIndex; // index number into overkill data array that this data can be found
    WORD m_wDecoderIndex;  // index to the decoder that should be used, if m_wFlags indicates encoding
} PEC_BLOCK, *PPEC_BLOCK;
  

note 0: this document not intended for full reconstruction of module to its fully original state (i.e. what an a full unpacker might do)