Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "pefile.h"
- // Konstruktoren
- PEFile::PEFile(void)
- {
- }
- PEFile::PEFile(const char *filename)
- {
- // Einlesen der über filename übergebenen Datei
- this->szFilename = new char[strlen(filename)+1];
- strncpy(this->szFilename, filename, strlen(filename));
- this->szFilename[strlen(filename)] = 0;
- FILE *fd = fopen(this->szFilename, "rb");
- if(fd == 0)
- fireError("Die Datei <%s> konnte nicht geoeffnet werden", this->szFilename);
- fseek(fd, 0, SEEK_END);
- this->dwFileSize = ftell(fd);
- fseek(fd, 0, SEEK_SET);
- this->pbRawData = new BYTE[this->dwFileSize];
- fread(this->pbRawData, 1, this->dwFileSize, fd);
- fclose(fd);
- this->gatherInformations(UPDATE_ALL);
- }
- // Destruktor
- PEFile::~PEFile()
- {
- delete this->szFilename;
- delete this->pbRawData;
- delete this->ppSectionHeader;
- }
- // Private Methoden
- DWORD PEFile::roNthSectionHeader(DWORD n)
- {
- return this->pImageDOSHeader->e_lfanew + sizeof(IMAGE_NT_HEADERS) + (n * sizeof(IMAGE_SECTION_HEADER));
- }
- void PEFile::gatherInformations(__in DWORD fUpdates)
- {
- // Speichern des DOS- und der NT-Header in den entsprechenden Eigenschaften
- this->pImageDOSHeader = (IMAGE_DOS_HEADER *) &this->pbRawData[0];
- this->pImageNTHeaders = (IMAGE_NT_HEADERS *) &this->pbRawData[this->pImageDOSHeader->e_lfanew];
- // Ermitteln der physikalischen Adressen der Section Header
- this->dwNumberOfSections = this->pImageNTHeaders->FileHeader.NumberOfSections;
- this->ppSectionHeader = new IMAGE_SECTION_HEADER *[this->dwNumberOfSections];
- for(DWORD n = 0; n < this->dwNumberOfSections; n++)
- this->ppSectionHeader[n] = (IMAGE_SECTION_HEADER *) &this->pbRawData[this->roNthSectionHeader(n)];
- // Untersuchen der PE-Datei auf die Anzahl der Section Header die
- // zwischen dem Ende der Header und dem Anfang der Daten passen
- this->dwNumberOfSectionHeaderFitInCave = SectionHeaderFitBetween(this->roNthSectionHeader(this->dwNumberOfSections), this->pImageNTHeaders->OptionalHeader.SizeOfHeaders);
- // Ermitteln von Informationen über den OEP
- this->dwSectionOfOEP = this->getSectionIdByRVA(this->pImageNTHeaders->OptionalHeader.AddressOfEntryPoint);
- this->roOEP = this->getRawOffsetByRVA(this->pImageNTHeaders->OptionalHeader.AddressOfEntryPoint);
- // Ermitteln, der Anzahl an RelocationBlocks
- DWORD dwSizeIBR = this->pImageNTHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size;
- this->roIBR = this->getRawOffsetByRVA(this->pImageNTHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress);
- if(dwSizeIBR != 0x00000000 && this->roIBR != 0x00000000)
- {
- DWORD roRelocBlock = this->roIBR;
- int iRelocBlockCounter = 0;
- DWORD dwCountBytes = 0;
- do
- {
- DWORD dwSizeRelocBlock = ReadDWORD(roRelocBlock + sizeof(DWORD));
- roRelocBlock += dwSizeRelocBlock;
- dwCountBytes += dwSizeRelocBlock;
- if(dwCountBytes <= dwSizeIBR)
- iRelocBlockCounter++;
- } while(dwCountBytes < dwSizeIBR);
- if(dwCountBytes == dwSizeIBR)
- this->dwNumRelocBlocks = iRelocBlockCounter;
- else
- this->dwNumRelocBlocks = 0, fireError("Die im IMAGE_DATA_DIRECTORY angegebene Groeße (%d Byte) der RelocTable ist falsch (%d Byte)", dwSizeIBR, dwCountBytes);
- }
- else
- this->dwNumRelocBlocks = 0;
- this->dwFreeBytesAfterRelocs = 0;
- DWORD roEndOfReloc = this->getRawOffsetByRVA(this->pImageNTHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress + this->pImageNTHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size);
- if(roEndOfReloc == 0) // Es ist keine RelocTable vorhanden, also wird einfach eine gemacht
- {
- addSection(".reloc", 0x200, 0x42000040);
- this->pImageNTHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = this->getSectionHeaderByName(".reloc")->VirtualAddress;
- roEndOfReloc = this->getSectionHeaderByName(".reloc")->PointerToRawData;
- }
- DWORD dwProbablyFreeBytes = BytesBetween(this->ppSectionHeader[this->getSectionIdByRawOffset(roEndOfReloc)]->SizeOfRawData, this->ppSectionHeader[this->getSectionIdByRawOffset(roEndOfReloc)]->Misc.VirtualSize);
- for(DWORD i = 0; i < dwProbablyFreeBytes; i++)
- {
- if(ReadBYTE(roEndOfReloc + i ) == 0x00)
- this->dwFreeBytesAfterRelocs++;
- else
- break;
- }
- // Eintragen aller Codecaves an Enden von Sections
- this->CaveArr = this->findCodeCaves(&this->dwNumCodeCaves);
- // ImportDir
- DWORD dwImportDirSize = this->pImageNTHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size;
- this->roImportDir = this->getRawOffsetByRVA(this->pImageNTHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
- if(dwImportDirSize)
- this->dwNumImportDescriptors = (dwImportDirSize / sizeof(IMAGE_IMPORT_DESCRIPTOR)) - 1;
- else
- this->dwNumImportDescriptors = 0;
- DWORD dwImpByNameCounter = 0;
- if(this->dwNumImportDescriptors)
- {
- this->dwNumImportsModule = new DWORD[this->dwNumImportDescriptors];
- IMAGE_IMPORT_DESCRIPTOR *iidArr = (IMAGE_IMPORT_DESCRIPTOR *) &this->pbRawData[this->roImportDir];
- for(DWORD i = 0; i < this->dwNumImportDescriptors; i++)
- {
- if(iidArr[i].FirstThunk == 0x00000000)
- break;
- //fireDebug("Name der DLL: %s, Adresse des OTD Arrays: 0x%08x", (char *) &this->pbRawData[this->getRawOffsetByRVA(iidArr[i].Name)], this->getRawOffsetByRVA(iidArr[i].FirstThunk));
- IMAGE_THUNK_DATA32 *itd32Arr = (IMAGE_THUNK_DATA32 *) &this->pbRawData[this->getRawOffsetByRVA(iidArr[i].FirstThunk)];
- for(this->dwNumImportsModule[i] = 0; itd32Arr[this->dwNumImportsModule[i]].u1.Function != 0x00000000; this->dwNumImportsModule[i]++);
- }
- }
- }
- // Caves
- CODE_CAVE *PEFile::findCodeCaves(__in DWORD *iNumCodeCaves)
- {
- int iCountCodeCave = 0;
- CODE_CAVE *ccbuffer = new CODE_CAVE[this->dwNumberOfSections];
- IMAGE_SECTION_HEADER *pNthHeader;
- for(DWORD n = 0; n < this->dwNumberOfSections; n++)
- {
- pNthHeader = this->ppSectionHeader[n];
- if(Align(pNthHeader->Misc.VirtualSize, this->pImageNTHeaders->OptionalHeader.FileAlignment) >= pNthHeader->Misc.VirtualSize
- && pNthHeader->Misc.VirtualSize != 0x0000
- && pNthHeader->PointerToRawData != 0x0000)
- {
- DWORD dwCaveSize = BytesBetween(Align(pNthHeader->Misc.VirtualSize, this->pImageNTHeaders->OptionalHeader.FileAlignment), pNthHeader->Misc.VirtualSize);
- DWORD RawOffset = pNthHeader->PointerToRawData + pNthHeader->Misc.VirtualSize;
- bool empty = true;
- for(DWORD i = 0; i < dwCaveSize; i++)
- {
- if(*((BYTE *) &this->pbRawData[RawOffset] + i))
- {
- empty = false;
- break;
- }
- }
- if(!empty)
- continue;
- ccbuffer[iCountCodeCave].RawOffset = RawOffset;
- ccbuffer[iCountCodeCave].dwCaveSize = dwCaveSize;
- iCountCodeCave++;
- }
- }
- CODE_CAVE *codecaves = new CODE_CAVE[iCountCodeCave];
- memcpy(codecaves, ccbuffer, iCountCodeCave * sizeof(CODE_CAVE));
- *iNumCodeCaves = iCountCodeCave;
- delete ccbuffer;
- return codecaves;
- }
- CODE_CAVE *PEFile::findNullPatterns(__in DWORD iMinPatternSize, __out DWORD *iNumNullPatterns)
- {
- CODE_CAVE *codecaves;
- DWORD dwNumCodeCaves = 0;
- DWORD *dwNumCCInSection = new DWORD[this->dwNumberOfSections];
- CODE_CAVE **pccbuffer = new CODE_CAVE *[this->dwNumberOfSections];
- for(DWORD n = 0; n < this->dwNumberOfSections; n++)
- {
- pccbuffer[n] = this->findNullPatternsInSection(iMinPatternSize, n, &dwNumCCInSection[n]);
- dwNumCodeCaves += dwNumCCInSection[n];
- }
- codecaves = new CODE_CAVE[dwNumCodeCaves];
- int index = 0;
- for(DWORD n = 0; n < this->dwNumberOfSections; n++)
- {
- memcpy(codecaves + index, pccbuffer[n], dwNumCCInSection[n] * sizeof(CODE_CAVE));
- index += dwNumCCInSection[n];
- }
- *iNumNullPatterns = dwNumCodeCaves;
- return codecaves;
- }
- CODE_CAVE *PEFile::findNullPatternsInSection(DWORD dwMinPatternSize, DWORD dwSectionID, __out DWORD *dwNumNullPatterns)
- {
- if(dwSectionID < 0 || dwSectionID >= this->dwNumberOfSections || this->ppSectionHeader[dwSectionID]->PointerToRawData == 0x00000000)
- return (CODE_CAVE *) NULL;
- //Variablen
- IMAGE_SECTION_HEADER *ish = this->ppSectionHeader[dwSectionID];
- DWORD dwRawSize = Align(ish->SizeOfRawData, this->pImageNTHeaders->OptionalHeader.FileAlignment);
- DWORD rvaStartOffset = ish->PointerToRawData;
- DWORD dwMaxCodeCaves = dwRawSize / (dwMinPatternSize + 1);
- CODE_CAVE *ccbuffer = new CODE_CAVE[dwMaxCodeCaves];
- DWORD dwCountCodeCaves = 0;
- DWORD dwByteCounter = 0;
- for(DWORD i = 0; i < dwRawSize; i++)
- {
- if(*((BYTE *) &this->pbRawData[rvaStartOffset + i]) == 0x00)
- dwByteCounter++;
- else if(dwByteCounter)
- {
- if(dwByteCounter >= dwMinPatternSize)
- {
- ccbuffer[dwCountCodeCaves].RawOffset = rvaStartOffset + (i - dwByteCounter);
- ccbuffer[dwCountCodeCaves].dwCaveSize = dwByteCounter;
- dwCountCodeCaves++;
- }
- dwByteCounter = 0;
- }
- }
- if(dwByteCounter >= dwMinPatternSize)
- {
- ccbuffer[dwCountCodeCaves].RawOffset = rvaStartOffset + (dwRawSize - dwByteCounter);
- ccbuffer[dwCountCodeCaves].dwCaveSize = dwByteCounter;
- dwCountCodeCaves++;
- }
- CODE_CAVE *codecaves = new CODE_CAVE[dwCountCodeCaves];
- memcpy(codecaves, ccbuffer, dwCountCodeCaves * sizeof(CODE_CAVE));
- delete ccbuffer;
- *dwNumNullPatterns = dwCountCodeCaves;
- return codecaves;
- }
- // Zurrück ans Zeichbrett :D
- bool PEFile::createCodecave(__in DWORD roCaveStart, __in DWORD dwCaveSize)
- {
- // Entweder will jemand in die Header schreiben oder über das Ziel hinaus schießen
- if(roCaveStart < this->pImageNTHeaders->OptionalHeader.SizeOfHeaders || roCaveStart >= this->dwFileSize)
- return false;
- // Vars
- DWORD dwNewFileSize;
- DWORD dwSectionOfCaveStart = this->getSectionIdByRawOffset(roCaveStart);
- bool bSectionendHasCave = false;
- CODE_CAVE *ccAffectedSection;
- // Gucken ob sich das zu erzeugende Cave in einer Section befindet, welche ein Cave an ihrem Ende hat
- for(DWORD i = 0; i < this->dwNumCodeCaves; i++)
- if(this->getSectionIdByRawOffset(this->CaveArr[i].RawOffset) == dwSectionOfCaveStart)
- bSectionendHasCave = true, ccAffectedSection = &this->CaveArr[i];
- if(bSectionendHasCave)
- {
- DWORD dwNewVirtualSize = this->ppSectionHeader[dwSectionOfCaveStart]->Misc.VirtualSize + dwCaveSize;
- DWORD dwNewRawSize = Align(dwNewVirtualSize, this->pImageNTHeaders->OptionalHeader.FileAlignment);
- // Ermitteln der neuen Dateigröße und ggf. der Anzahl an Bytes, um die die nachfolgenden Sections verschoben werden müssen
- DWORD dwDeltaFollowingSections = 0;
- if(ccAffectedSection->dwCaveSize < dwCaveSize)
- dwDeltaFollowingSections = Align(dwCaveSize - ccAffectedSection->dwCaveSize, this->pImageNTHeaders->OptionalHeader.FileAlignment);
- dwNewFileSize = this->dwFileSize + dwDeltaFollowingSections;
- // Schreiben der notwendigen Relocations
- RELOC_INTERVAL relIntervalAffectedSection = {roCaveStart, this->ppSectionHeader[dwSectionOfCaveStart]->PointerToRawData + dwNewRawSize, dwCaveSize};
- this->writeRelocationsForRawOffsetInterval(relIntervalAffectedSection);
- // Neue Parameter
- this->pImageNTHeaders->OptionalHeader.AddressOfEntryPoint = this->getRVAByRawOffset(this->roOEP + dwCaveSize);
- this->ppSectionHeader[dwSectionOfCaveStart]->SizeOfRawData = dwNewRawSize;
- this->ppSectionHeader[dwSectionOfCaveStart]->Misc.VirtualSize = dwNewVirtualSize;
- // Kopieren der ursprünglichen Daten und Einfügen des Caves
- BYTE *buffer = new BYTE[dwNewFileSize];
- memcpy(buffer, this->pbRawData, roCaveStart);
- for(DWORD i = 0; i < dwCaveSize; i++)
- buffer[roCaveStart + i] = 0x00;
- memcpy(
- &buffer[roCaveStart + dwCaveSize],
- &this->pbRawData[roCaveStart],
- ccAffectedSection->RawOffset - roCaveStart
- );
- for(DWORD i = 0; i < (dwNewRawSize - dwNewVirtualSize); i++)
- buffer[ccAffectedSection->RawOffset + dwCaveSize + i] = 0x00;
- memcpy(
- &buffer[this->ppSectionHeader[dwSectionOfCaveStart]->PointerToRawData + dwNewRawSize],
- &this->pbRawData[ccAffectedSection->RawOffset + ccAffectedSection->dwCaveSize],
- this->dwFileSize - (ccAffectedSection->RawOffset + ccAffectedSection->dwCaveSize)
- );
- if(dwDeltaFollowingSections)
- (void) 0;
- delete this->pbRawData;
- this->pbRawData = buffer;
- this->dwFileSize = dwNewFileSize;
- return true;
- }
- else
- {
- (void) 0;
- }
- }
- // Relocations
- bool PEFile::switchSections(__in DWORD dwSec1, __in DWORD dwSec2)
- {
- if(dwSec1 >= this->dwNumberOfSections || dwSec2 >= this->dwNumberOfSections)
- return false;
- if(dwSec1 == dwSec2)
- return true;
- IMAGE_SECTION_HEADER ishFirst;
- IMAGE_SECTION_HEADER ishSecond;
- ((this->ppSectionHeader[dwSec1]->PointerToRawData < this->ppSectionHeader[dwSec2]->PointerToRawData)
- ? (ishFirst = *this->ppSectionHeader[dwSec1], ishSecond = *this->ppSectionHeader[dwSec2])
- : (ishFirst = *this->ppSectionHeader[dwSec2], ishSecond = *this->ppSectionHeader[dwSec1])
- );
- this->switchSectionHeader(dwSec1, dwSec2);
- DWORD dwWrittenBytes = 0;
- BYTE *buffer = new BYTE[this->dwFileSize];
- memcpy(
- buffer,
- this->pbRawData,
- ishFirst.PointerToRawData
- );
- dwWrittenBytes += ishFirst.PointerToRawData;
- memcpy(
- &buffer[dwWrittenBytes],
- &this->pbRawData[ishSecond.PointerToRawData],
- ishSecond.SizeOfRawData
- );
- dwWrittenBytes += ishSecond.SizeOfRawData;
- memcpy(
- &buffer[dwWrittenBytes],
- &this->pbRawData[ishFirst.PointerToRawData + ishFirst.SizeOfRawData],
- BytesBetween(ishSecond.PointerToRawData, ishFirst.PointerToRawData + ishFirst.SizeOfRawData)
- );
- dwWrittenBytes += BytesBetween(ishSecond.PointerToRawData, ishFirst.PointerToRawData + ishFirst.SizeOfRawData);
- memcpy(
- &buffer[dwWrittenBytes],
- &this->pbRawData[ishFirst.PointerToRawData],
- ishFirst.SizeOfRawData
- );
- dwWrittenBytes += ishFirst.SizeOfRawData;
- memcpy(
- &buffer[dwWrittenBytes],
- &this->pbRawData[ishSecond.PointerToRawData + ishSecond.SizeOfRawData],
- this->dwFileSize - dwWrittenBytes
- );
- dwWrittenBytes += this->dwFileSize - dwWrittenBytes;
- delete this->pbRawData;
- this->pbRawData = buffer;
- //this->gatherInformations();
- return true;
- }
- bool PEFile::switchSectionHeader(__in DWORD dwSec1, __in DWORD dwSec2)
- {
- if(dwSec1 >= this->dwNumberOfSections || dwSec2 >= this->dwNumberOfSections)
- return false;
- if(dwSec1 == dwSec2)
- return true;
- IMAGE_SECTION_HEADER ishFirst;
- IMAGE_SECTION_HEADER ishSecond;
- ((this->ppSectionHeader[dwSec1]->PointerToRawData < this->ppSectionHeader[dwSec2]->PointerToRawData)
- ? (ishFirst = *this->ppSectionHeader[dwSec1], ishSecond = *this->ppSectionHeader[dwSec2])
- : (ishFirst = *this->ppSectionHeader[dwSec2], ishSecond = *this->ppSectionHeader[dwSec1])
- );
- int iRawSizeDelta = ishSecond.SizeOfRawData - ishFirst.SizeOfRawData;
- if(iRawSizeDelta)
- for(DWORD i = 0; i < this->dwNumberOfSections; i++)
- if(Min(dwSec1, dwSec2) < i && i <= Max(dwSec1, dwSec2))
- this->ppSectionHeader[i]->PointerToRawData += iRawSizeDelta;
- IMAGE_SECTION_HEADER temp = *this->ppSectionHeader[dwSec1];
- *this->ppSectionHeader[dwSec1] = *this->ppSectionHeader[dwSec2];
- *this->ppSectionHeader[dwSec2] = temp;
- this->ppSectionHeader[dwSec2]->PointerToRawData = this->ppSectionHeader[dwSec1]->PointerToRawData;
- this->ppSectionHeader[dwSec1]->PointerToRawData = temp.PointerToRawData;
- return true;
- }
- bool PEFile::writeAllRelocations(__in DWORD dwDelta)
- {
- if(this->dwNumRelocBlocks == 0)
- return true;
- DWORD roRelocBlock = this->roIBR;
- DWORD dwRelocBlockSize = ReadDWORD(roIBR + sizeof(DWORD));
- DWORD dwNumRelocs;
- for(DWORD i = 0; i < this->dwNumRelocBlocks; i++)
- {
- dwNumRelocs = (dwRelocBlockSize - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(WORD);
- for(DWORD j = 0; j < dwNumRelocs; j++)
- {
- DWORD roBaseReloc = roRelocBlock + sizeof(IMAGE_BASE_RELOCATION) + j * sizeof(WORD);
- WORD wBaseReloc = ReadWORD(roBaseReloc);
- if((wBaseReloc >> 12) & IMAGE_REL_BASED_HIGHLOW)
- {
- DWORD roRelocElem = this->getRawOffsetByRVA(ReadDWORD(roRelocBlock)) + (wBaseReloc & 0x0FFF);
- DWORD dwRelocElem = ReadDWORD(roRelocElem) + dwDelta;
- WriteDWORD(roRelocElem, dwRelocElem);
- }
- WriteWORD(roBaseReloc, (wBaseReloc & 0xF000) | ((wBaseReloc & 0x0FFF) + dwDelta));
- }
- roRelocBlock += dwRelocBlockSize;
- dwRelocBlockSize = ReadDWORD(roRelocBlock + sizeof(DWORD));
- }
- return true;
- }
- bool PEFile::writeRelocationsForRawOffsetInterval(__in RELOC_INTERVAL relInterval)
- {
- if(this->dwNumRelocBlocks == 0)
- return true;
- if(relInterval.roLowBoundary < relInterval.roLowBoundary
- || relInterval.dwDelta == 0
- || relInterval.roLowBoundary < this->pImageNTHeaders->OptionalHeader.SizeOfHeaders
- || relInterval.roHighBoundary >= this->dwFileSize
- )
- return false;
- DWORD roRelocBlock = this->roIBR;
- DWORD dwRelocBlockSize = ReadDWORD(roIBR + sizeof(DWORD));
- DWORD dwNumRelocs;
- for(DWORD i = 0; i < this->dwNumRelocBlocks; i++)
- {
- dwNumRelocs = (dwRelocBlockSize - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(WORD);
- for(DWORD j = 0; j < dwNumRelocs; j++)
- {
- DWORD roBaseReloc = roRelocBlock + sizeof(IMAGE_BASE_RELOCATION) + j * sizeof(WORD);
- WORD wBaseReloc = ReadWORD(roBaseReloc);
- DWORD roRelocElem = this->getRawOffsetByRVA(ReadDWORD(roRelocBlock)) + (wBaseReloc & 0x0FFF);
- DWORD dwRelocElem = ReadDWORD(roRelocElem);
- if((wBaseReloc >> 12) & IMAGE_REL_BASED_HIGHLOW)
- if(InInterval(this->getRawOffsetByRVA(dwRelocElem - this->pImageNTHeaders->OptionalHeader.ImageBase), sizeof(DWORD), relInterval))
- WriteDWORD(roRelocElem, dwRelocElem + relInterval.dwDelta);
- if(InInterval(roRelocElem, sizeof(WORD), relInterval))
- WriteWORD(roBaseReloc, (wBaseReloc & 0xF000) | ((wBaseReloc & 0x0FFF) + relInterval.dwDelta));
- }
- roRelocBlock += dwRelocBlockSize;
- dwRelocBlockSize = ReadDWORD(roRelocBlock + sizeof(DWORD));
- }
- return true;
- }
- bool PEFile::addRelocation(__in DWORD rvaRelocEntry, __in BYTE bRelocType)
- {
- DWORD roNextIBR = this->roIBR;
- DWORD dwAffectedIBR;
- DWORD dwWrittenBytes = 0;
- for(dwAffectedIBR = 0; dwAffectedIBR < this->dwNumRelocBlocks; dwAffectedIBR++)
- {
- if(ReadDWORD(roNextIBR) <= rvaRelocEntry && rvaRelocEntry <= ReadDWORD(roNextIBR) + 0xFFF)
- break;
- else
- roNextIBR += ReadDWORD(roNextIBR + sizeof(DWORD));
- }
- if(dwAffectedIBR == this->dwNumRelocBlocks)
- {
- if(this->dwFreeBytesAfterRelocs >= 2*sizeof(DWORD) + sizeof(WORD))
- {
- roNextIBR = this->getRawOffsetByRVA(this->pImageNTHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress + this->pImageNTHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size);
- WriteDWORD(roNextIBR, rvaRelocEntry & 0xFFFFF000);
- WriteDWORD(roNextIBR + sizeof(DWORD), 2 * sizeof(DWORD) + sizeof(WORD));
- WriteWORD(roNextIBR + 2 * sizeof(DWORD), ((WORD) bRelocType << 12) | (rvaRelocEntry & 0x00000FFF));
- dwWrittenBytes += 2 * sizeof(DWORD) + sizeof(WORD);
- this->dwFreeBytesAfterRelocs -= 2 * sizeof(DWORD) + sizeof(WORD);
- this->dwNumRelocBlocks++;
- }
- else return false;
- }
- else
- {
- printf("0x%08x\n", roNextIBR);
- if(dwAffectedIBR == this->dwNumRelocBlocks - 1 && this->dwFreeBytesAfterRelocs >= + sizeof(WORD)) // Man befindet sich im letzten RelocEntry
- {
- DWORD dwExistingRelocs = (ReadDWORD(roNextIBR + sizeof(DWORD)) - 2 * sizeof(DWORD)) / sizeof(WORD);
- WriteDWORD(roNextIBR + sizeof(DWORD), ReadDWORD(roNextIBR + sizeof(DWORD)) + sizeof(WORD));
- WriteWORD(roNextIBR + 2*sizeof(DWORD)+ dwExistingRelocs * sizeof(WORD), ((WORD) bRelocType << 12) | (rvaRelocEntry & 0x00000FFF));
- dwWrittenBytes += sizeof(WORD);
- }
- }
- this->pImageNTHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size += dwWrittenBytes;
- return true;
- }
- // Injections
- int PEFile::addSection(__in const char *sSecName, __in DWORD dwVirtualSize, __in DWORD dwCharacteristics)
- {
- // Kein Platz für einen neuen Header
- if(!this->dwNumberOfSectionHeaderFitInCave)
- return -1;
- DWORD dwSecId = this->dwNumberOfSections;
- // Festlegen der neuen SectionHeader Parameter
- IMAGE_SECTION_HEADER *ishNew = (IMAGE_SECTION_HEADER *) &this->pbRawData[this->roNthSectionHeader(dwSecId)];
- memcpy(&ishNew->Name, sSecName, Min(strlen(sSecName), 8));
- ishNew->Misc.VirtualSize = dwVirtualSize;
- ishNew->Characteristics = dwCharacteristics;
- ishNew->SizeOfRawData = Align(dwVirtualSize, this->pImageNTHeaders->OptionalHeader.FileAlignment);
- ishNew->PointerToRawData = this->ppSectionHeader[dwSecId - 1]->PointerToRawData + this->ppSectionHeader[dwSecId - 1]->SizeOfRawData;
- ishNew->VirtualAddress = this->ppSectionHeader[dwSecId - 1]->VirtualAddress + Align(this->ppSectionHeader[dwSecId - 1]->SizeOfRawData, this->pImageNTHeaders->OptionalHeader.SectionAlignment);
- // Sonstige zu verändernde Header
- this->pImageNTHeaders->OptionalHeader.SizeOfImage += Align(dwVirtualSize, this->pImageNTHeaders->OptionalHeader.SectionAlignment);
- this->pImageNTHeaders->FileHeader.NumberOfSections++;
- // Speichern der neuen Daten und updaten der Informationen
- BYTE *buffer = new BYTE[this->dwFileSize + ishNew->SizeOfRawData];
- memcpy(buffer, this->pbRawData, this->dwFileSize);
- for(DWORD i = 0; i < ishNew->SizeOfRawData; i++)
- buffer[ishNew->PointerToRawData + i] = 0x00;
- delete this->pbRawData;
- this->pbRawData = buffer;
- this->dwFileSize += ishNew->SizeOfRawData;
- this->dwNumberOfSections++;
- this->gatherInformations(UPDATE_ALL);
- return dwSecId;
- }
- int PEFile::insertCode(__in const char *secName, __in BYTE *data, __in DWORD size, __in DWORD fSettings)
- {
- if(this->dwNumberOfSectionHeaderFitInCave < 1)
- fireError("Es ist kein Platz fuer eine weitere Section");
- // Überprüfen ob sich Daten bei der Addresse des neuen SectionHeaders befinden
- IMAGE_SECTION_HEADER *ishNew = (IMAGE_SECTION_HEADER *) &this->pbRawData[this->roNthSectionHeader(this->dwNumberOfSections)];
- for(DWORD i = 0; i < sizeof(IMAGE_SECTION_HEADER); i++)
- if(*((BYTE *) ishNew + i))
- fireError("Es befinden sich Daten im vermeintlichen Cave");
- this->CaveArr = this->findCodeCaves(&this->dwNumCodeCaves);
- // Setzen des SectionHeaders
- strncpy((char *) ishNew->Name, secName, 8);
- ishNew->Misc.VirtualSize = size;
- return 0;
- }
- bool PEFile::deleteSectionById(DWORD dwSecId)
- {
- IMAGE_SECTION_HEADER *ish = this->getSectionHeaderById(dwSecId);
- IMAGE_SECTION_HEADER *ishLastSec = this->getSectionHeaderById(this->dwNumberOfSections - 1);
- DWORD dwBytesAfterSection = (ishLastSec->PointerToRawData + ishLastSec->SizeOfRawData) - (ish->PointerToRawData + ish->SizeOfRawData);
- this->pImageNTHeaders->FileHeader.NumberOfSections--;
- this->pImageNTHeaders->OptionalHeader.SizeOfImage -= Align(ish->Misc.VirtualSize, this->pImageNTHeaders->OptionalHeader.SectionAlignment);
- memcpy(&this->pbRawData[ish->PointerToRawData], &this->pbRawData[ish->PointerToRawData + ish->SizeOfRawData], dwBytesAfterSection);
- this->dwFileSize -= ish->SizeOfRawData;
- DWORD dwNumSecAfter = (this->dwNumberOfSections - 1) - dwSecId;
- for(DWORD i = 0; i < dwNumSecAfter; i++)
- this->switchSectionHeader(dwSecId + i, dwSecId + i + 1);
- for(DWORD i = 0; i < sizeof(IMAGE_SECTION_HEADER); i++)
- *((BYTE *)this->ppSectionHeader[this->dwNumberOfSections - 1] + i) = 0x00;
- this->dwNumberOfSections--;
- return true;
- }
- // Get'ter
- DWORD PEFile::getSectionIdByName(__in const char *name)
- {
- BYTE *buffer[IMAGE_SIZEOF_SHORT_NAME];
- if(strlen(name) < IMAGE_SIZEOF_SHORT_NAME)
- {
- memcpy(buffer, name, strlen(name));
- for(DWORD i = strlen(name); i < IMAGE_SIZEOF_SHORT_NAME; i++)
- buffer[i] = 0x00;
- }
- for(DWORD n = 0; n < this->dwNumberOfSections; n++)
- if(memcmp(this->ppSectionHeader[n]->Name, name, IMAGE_SIZEOF_SHORT_NAME) == 0)
- return n;
- return -1;
- }
- DWORD PEFile::getSectionIdByRVA(__in DWORD dwRVA)
- {
- for(DWORD n = 0; n < this->dwNumberOfSections; n++)
- if(this->ppSectionHeader[n]->VirtualAddress != 0x00000000 && this->ppSectionHeader[n]->VirtualAddress <= dwRVA && dwRVA < this->ppSectionHeader[n]->VirtualAddress + Align(this->ppSectionHeader[n]->Misc.VirtualSize, this->pImageNTHeaders->OptionalHeader.SectionAlignment))
- return n;
- return -1;
- }
- DWORD PEFile::getSectionIdByRawOffset(__in DWORD dwOffset)
- {
- for(DWORD n = 0; n < this->dwNumberOfSections; n++)
- if(this->ppSectionHeader[n]->PointerToRawData != 0x00000000 && this->ppSectionHeader[n]->PointerToRawData <= dwOffset && dwOffset < this->ppSectionHeader[n]->PointerToRawData + this->ppSectionHeader[n]->SizeOfRawData)
- return n;
- return -1;
- }
- DWORD PEFile::getRawOffsetOfSectionEnd(__in DWORD dwSectionId)
- {
- if(dwSectionId < 0 || dwSectionId > this->dwNumberOfSections -1)
- return 0x00000000;
- return this->ppSectionHeader[dwSectionId]->PointerToRawData + Align(this->ppSectionHeader[dwSectionId]->Misc.VirtualSize, this->pImageNTHeaders->OptionalHeader.FileAlignment);
- }
- DWORD PEFile::getRawOffsetByRVA(__in DWORD dwRVA)
- {
- if(dwRVA == 0x00000000)
- return 0x00000000;
- int iSectionId = this->getSectionIdByRVA(dwRVA);
- if(iSectionId == -1)
- return 0x00000000;
- DWORD dwSectionRVA = this->ppSectionHeader[iSectionId]->VirtualAddress;
- DWORD dwSectionRawOffset = this->ppSectionHeader[iSectionId]->PointerToRawData;
- int iDelta = BytesBetween(dwSectionRVA, dwRVA);
- return dwSectionRawOffset + iDelta;
- }
- DWORD PEFile::getRVAByRawOffset(__in DWORD dwRO)
- {
- if(dwRO == 0x00000000)
- return 0x00000000;
- int iSectionId = this->getSectionIdByRawOffset(dwRO);
- DWORD dwSectionRVA = this->ppSectionHeader[iSectionId]->VirtualAddress;
- DWORD dwSectionRawOffset = this->ppSectionHeader[iSectionId]->PointerToRawData;
- int iDelta = BytesBetween(dwSectionRawOffset, dwRO);
- return dwSectionRVA + iDelta;
- }
- IMAGE_NT_HEADERS *PEFile::getNTHeaders(void) { return this->pImageNTHeaders; }
- BYTE *PEFile::getPointerToDataByRO(__in DWORD dwRO) { return &this->pbRawData[dwRO]; }
- IMAGE_SECTION_HEADER *PEFile::getSectionHeaderById(__in DWORD dwID) { return this->ppSectionHeader[dwID]; }
- IMAGE_SECTION_HEADER *PEFile::getSectionHeaderByRO(__in DWORD dwRO) { return this->ppSectionHeader[this->getSectionIdByRawOffset(dwRO)]; }
- IMAGE_SECTION_HEADER *PEFile::getSectionHeaderByName(__in const char *sSecName) {return this->ppSectionHeader[this->getSectionIdByName(sSecName)]; }
- DWORD PEFile::getNumberOfSections() { return this->dwNumberOfSections; }
- DWORD PEFile::getFileSize() { return this->dwFileSize; }
- CODE_CAVE *PEFile::getSecEndCCByName(__in const char *SecName)
- {
- DWORD dwSecId = this->getSectionIdByName(SecName);
- if(dwSecId == -1)
- return NULL;
- for(DWORD i = 0; i < this->dwNumCodeCaves; i++)
- if(this->getSectionIdByRawOffset(this->CaveArr[i].RawOffset) == dwSecId)
- return &CaveArr[i];
- return NULL;
- }
- // Setter
- void PEFile::setFileSize(DWORD dwFileSize) { this->dwFileSize = dwFileSize; }
- // Output
- bool PEFile::writePEFile(const char *outputFilename)
- {
- HANDLE hFile = CreateFileA(outputFilename, GENERIC_WRITE, NULL, NULL, CREATE_ALWAYS, NULL, NULL);
- if (!hFile)
- return false;
- DWORD dWritten = 0;
- if (!WriteFile(hFile, this->pbRawData, this->dwFileSize, &dWritten, 0))
- return false;
- if (dWritten != this->dwFileSize)
- return false;
- CloseHandle(hFile);
- return true;
- }
- // Prints
- void fireError(const char *format, ...)
- {
- char buffer[500];
- va_list argumentlist;
- va_start(argumentlist, format);
- vsnprintf(buffer, sizeof(buffer) - 1, format, argumentlist);
- va_end(argumentlist);
- fprintf(stderr, "[Error] %s\n", buffer);
- exit(0);
- }
- void fireDebug(const char *format, ...)
- {
- char buffer[500];
- va_list argumentlist;
- va_start(argumentlist, format);
- vsnprintf(buffer, sizeof(buffer) - 1, format, argumentlist);
- va_end(argumentlist);
- printf("[Debug] %s\n", buffer);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement