ref: 3bc1ca00562af4c7c3d287ae44181f02c361adb3
dir: /src/pefile.c/
/* This file is part of REWise. * * REWise is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * REWise is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <https://www.gnu.org/licenses/>. */ #include <stdio.h> #include <errno.h> #include "reader.h" #include "pefile.h" #include "print.h" /* pefileGetOverlayOffset() - Get the overlay-offset of a PE file. * * @returns: The offset to overlay-data on success, <0 on error. */ long pefileGetOverlayOffset(const char * filePath) { long fileSize; FILE * fp; size_t noRead; long overlayOffset; // Open file fp = fopen(filePath, "rb"); // Failed to open file if (fp == NULL) { printError("pefileGetOverlayOffset failed to open '%s'\n", filePath); return -1; } // Determine file size if (fseek(fp, 0l, SEEK_END) != 0) { printError("pefileGetOverlayOffset failed to seek to end of file '%s'\n", filePath); fclose(fp); return -1; } if ((fileSize = ftell(fp)) < 1) { printError("pefileGetOverlayOffset failed to determine file size of file " "'%s'\n", filePath); fclose(fp); return -1; } // Set cursor back to start of the file if (fseek(fp, 0l, SEEK_SET) != 0) { printError("pefileGetOverlayOffset failed to seek to start of file '%s'\n", filePath); fclose(fp); return -1; } // Read MsDosHeader size_t readSize = sizeof(MsDosHeader); if (readSize > fileSize) { printError("pefileGetOverlayOffset file is to small to contain a MS Dos " "header. File: '%s'\n", filePath); fclose(fp); return -1; } MsDosHeader msDosHeader; noRead = fread(&msDosHeader, readSize, 1, fp); if (noRead != 1) { printError("pefileGetOverlayOffset failed to read the MS Dos header. " "noRead: %ld readSize: %ld\n", noRead, readSize); fclose(fp); return -1; } if (msDosHeader.signature != 0x5A4D) { printError("pefileGetOverlayOffset this is not a PE file for sure. The " "MS-DOS header signature doesn't match (not MZ).\n"); fclose(fp); return -1; } // Read e_lfanew (offset to PE file header) uint32_t e_lfanew; if (fseek(fp, 0x3C, SEEK_SET) != 0) { printError("pefileGetOverlayOffset failed to seek to 0x3C.\n"); printError("pefileGetOverlayOffset errno: %s\n", strerror(errno)); fclose(fp); return -1; } if (fread(&e_lfanew, 4, 1, fp) != 1) { printError("pefileGetOverlayOffset failed to read e_lfanew.\n"); fclose(fp); return -1; } if (e_lfanew >= fileSize) { printError("pefileGetOverlayOffset PE file offset is larger then file " "size.\n"); fclose(fp); return -1; } // Read PE File Header if (fseek(fp, (long)e_lfanew, SEEK_SET) != 0) { printError("pefileGetOverlayOffset failed to seek to e_lfanew.\n"); printError("pefileGetOverlayOffset errno: %s\n", strerror(errno)); fclose(fp); return -1; } PeFileHeader peFileHeader; if (fread(&peFileHeader, sizeof(PeFileHeader), 1, fp) != 1) { printError("pefileGetOverlayOffset failed to read PE File Header\n"); fclose(fp); return -1; } if ((peFileHeader.signature << 16) != 0x45500000) { printError("pefileGetOverlayOffset this is not a PE file for sure (2).\n"); fclose(fp); return -1; } // Skip optional header if (peFileHeader.optionalHeaderSize > 0) { if (fseek(fp, peFileHeader.optionalHeaderSize, SEEK_CUR) != 0) { printError("pefileGetOverlayOffset failed to skip over the optional " "header.\n"); printError("pefileGetOverlayOffset errno: %s\n", strerror(errno)); fclose(fp); return -1; } } // Read sections overlayOffset = 0l; for (uint32_t i=0; i< peFileHeader.numberOfSections; i++) { PeImageSectionHeader sectionHeader; if (fread(§ionHeader, sizeof(PeImageSectionHeader), 1, fp) != 1) { printError("pefileGetOverlayOffset failed to read section header.\n"); fclose(fp); return -1; } if ((sectionHeader.rawDataLocation + sectionHeader.rawDataSize) > overlayOffset) { overlayOffset = sectionHeader.rawDataLocation + sectionHeader.rawDataSize; } } fclose(fp); if (overlayOffset > fileSize) { printError("pefileGetOverlayOffset no overlay offset larger then file.\n"); return -1; } return overlayOffset; }