This document is under construction. It may contain inaccuracies or be incomplete.
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.
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;
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;