Skip to content

coderforlife/pe-file

Repository files navigation

pe-file

Basic utility code for reading and modifying PE files (EXE, DLL, ...)

This is simply code and not a program. It could easily be compiled into a DLL and expose the PEFile class.

When compiling commenting out EXPOSE_DIRECT_RESOURCES causes direct resource access to be completely blocked and not expose the underlying resource classes. However resources are still accessible though other functions.

The interface is as follows:

class PE::File {
public:
    File(LPVOID data, size_t size, bool readonly = false); // data is freed when the PEFile is deleted
    File(LPCWSTR filename, bool readonly = false);
    ~File();
    bool isLoaded() const;
    bool isReadOnly() const;

    bool save(); // flushes

    bool is32bit() const;
    bool is64bit() const;
    ULONGLONG getImageBase() const;

    IMAGE_FILE_HEADER *getFileHeader();				// pointer can modify the file
    IMAGE_NT_HEADERS32 *getNtHeaders32();			// pointer can modify the file
    IMAGE_NT_HEADERS64 *getNtHeaders64();			// pointer can modify the file
    const IMAGE_FILE_HEADER *getFileHeader() const;
    const IMAGE_NT_HEADERS32 *getNtHeaders32() const;
    const IMAGE_NT_HEADERS64 *getNtHeaders64() const;

    DWORD getDataDirectoryCount() const;
    IMAGE_DATA_DIRECTORY *getDataDirectory(int i);	// pointer can modify the file
    const IMAGE_DATA_DIRECTORY *getDataDirectory(int i) const;

    IMAGE_SECTION_HEADER *getSectionHeader(int i);							// pointer can modify the file
    IMAGE_SECTION_HEADER *getSectionHeader(const char *str, int *i = NULL);	// pointer can modify the file
    IMAGE_SECTION_HEADER *getSectionHeaderByRVA(DWORD rva, int *i);			// pointer can modify the file
    IMAGE_SECTION_HEADER *getSectionHeaderByVA(ULONGLONG va, int *i);		// pointer can modify the file
    const IMAGE_SECTION_HEADER *getSectionHeader(int i) const;
    const IMAGE_SECTION_HEADER *getSectionHeader(const char *str, int *i = NULL) const;
    const IMAGE_SECTION_HEADER *getSectionHeaderByRVA(DWORD rva, int *i) const;
    const IMAGE_SECTION_HEADER *getSectionHeaderByVA(ULONGLONG va, int *i) const;
    int getSectionHeaderCount() const;

    IMAGE_SECTION_HEADER *getExpandedSectionHdr(int i, DWORD room);		// pointer can modify the file, invalidates all pointers returned by functions, flushes
    IMAGE_SECTION_HEADER *getExpandedSectionHdr(char *str, DWORD room);	// as above

#define CHARS_CODE_SECTION			IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_READ
#define CHARS_INIT_DATA_SECTION_R	IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ
#define CHARS_INIT_DATA_SECTION_RW	IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE

    IMAGE_SECTION_HEADER *createSection(int i, const char *name, DWORD room, DWORD chars);				// pointer can modify the file, invalidates all pointers returned by functions, flushes
    IMAGE_SECTION_HEADER *createSection(const char *str, const char *name, DWORD room, DWORD chars);	// as above, adds before the section named str
    IMAGE_SECTION_HEADER *createSection(const char *name, DWORD room, DWORD chars);						// as above, adds before ".reloc" if exists or at the very end

    size_t getSize() const;
    bool setSize(size_t dwSize, bool grow_only = true);				// invalidates all pointers returned by functions, flushes

    LPBYTE get(DWORD dwOffset = 0, DWORD *dwSize = NULL);			// pointer can modify the file
    const LPBYTE get(DWORD dwOffset = 0, DWORD *dwSize = NULL) const;
    bool set(const LPVOID lpBuffer, DWORD dwSize, DWORD dwOffset);	// shorthand for memcpy(f->get(dwOffset), lpBuffer, dwSize) with bounds checking
    bool zero(DWORD dwSize, DWORD dwOffset);						// shorthand for memset(f->get(dwOffset), 0, dwSize) with bounds checking
    bool move(DWORD dwOffset, DWORD dwSize, int dwDistanceToMove);	// shorthand for x = f->get(dwOffset); memmove(x+dwDistanceToMove, x, dwSize) with bounds checking
    bool shift(DWORD dwOffset, int dwDistanceToMove);				// shorthand for f->move(dwOffset, f->getSize() - dwOffset - dwDistanceToMove, dwDistanceToMove)
    bool flush();

    bool updatePEChkSum();				// flushes
    bool hasExtraData() const;
    LPVOID getExtraData(DWORD *size);	// pointer can modify the file, when first enabling it will flush
    bool clearCertificateTable();		// may invalidate all pointers returned by functions, flushes
    ULONGLONG getFileVersion() const;
    bool isAlreadyModified() const;
    bool setModifiedFlag();				// flushes
    bool removeRelocs(DWORD start, DWORD end, bool reverse = false);

#ifdef EXPOSE_DIRECT_RESOURCES
    Rsrc *getResources();
    const Rsrc *getResources() const;
#endif
    bool resourceExists(LPCWSTR type, LPCWSTR name, WORD lang) const;
    bool resourceExists(LPCWSTR type, LPCWSTR name, WORD* lang) const;
    LPVOID getResource (LPCWSTR type, LPCWSTR name, WORD lang, size_t* size) const;	// must be freed
    LPVOID getResource (LPCWSTR type, LPCWSTR name, WORD* lang, size_t* size) const;	// must be freed
    bool removeResource(LPCWSTR type, LPCWSTR name, WORD lang);
    bool addResource   (LPCWSTR type, LPCWSTR name, WORD lang, const LPVOID data, size_t size, DWORD overwrite = OVERWRITE_ALWAYS);

    static const LPVOID GetResourceDirect(const LPVOID data, LPCWSTR type, LPCWSTR name); // must be freed, massively performance enhanced for a single retrieval and no editing // lang? size?
    static bool UpdatePEChkSum(LPBYTE data, size_t dwSize, size_t peOffset, DWORD dwOldCheck);
    static bool GetVersionInfo(const LPVOID ver, LPCWSTR query, LPVOID *buffer, PUINT len);
    static VS_FIXEDFILEINFO *GetVersionInfo(const LPVOID ver);
    static void UnmapAllViewsOfFile(LPCWSTR file);
};

About

Basic utility code for reading and modifying PE files (EXE, DLL, ...)

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 2

  •  
  •  
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy