123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163 |
- /* This file is part of DiDiExtract.
- *
- * DiDiExtract 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.
- *
- * DiDiExtract 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 > (size_t)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;
- }
|