diff --git a/build.sh b/build.sh index c1dd036..4b428e2 100755 --- a/build.sh +++ b/build.sh @@ -2,4 +2,4 @@ # TEMP BUILD SCRIPT -gcc src/common/common.c src/getdata/getdata.c src/setdata/optheaders.c src/setdata/populateheaders.c src/setdata/pagedescriptors.c src/placer/placer.c src/write/writexex.c src/write/headerhash.c src/main.c -o synthxex -lnettle -Wno-multichar -g -fsanitize=address +gcc src/getdata/getdata.c src/setdata/optheaders.c src/setdata/populateheaders.c src/setdata/pagedescriptors.c src/placer/placer.c src/write/writexex.c src/write/headerhash.c src/main.c -o synthxex -lnettle -Wno-multichar -g -fsanitize=address diff --git a/src/common/common.c b/src/common/common.c deleted file mode 100644 index 63e23c6..0000000 --- a/src/common/common.c +++ /dev/null @@ -1,24 +0,0 @@ -// This file is part of SynthXEX, one component of the -// FreeChainXenon development toolchain -// -// Copyright (c) 2024 Aiden Isik -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program 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 Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -#include "common.h" - -void infoPrint(char *str) -{ - printf("SynthXEX> %s\n", str); -} diff --git a/src/common/common.h b/src/common/common.h index 1f7cd33..dc49447 100644 --- a/src/common/common.h +++ b/src/common/common.h @@ -29,6 +29,9 @@ #define COPYRIGHT "2024" #define VERSION_STRING "SynthXEX v0.0.1" +// Print constants +#define PRINT_STEM "SynthXEX>" + // Return values #define SUCCESS 0 diff --git a/src/getdata/getdata.c b/src/getdata/getdata.c index 3daac83..133c16a 100644 --- a/src/getdata/getdata.c +++ b/src/getdata/getdata.c @@ -152,15 +152,15 @@ int getSectionRwxFlags(FILE *pe, struct sections *sections) int getHdrData(FILE *pe, struct peData *peData, uint8_t flags) { // Get header data required for ANY XEX - // PE size - struct stat peStat; - fstat(fileno(pe), &peStat); - peData->size = peStat.st_size; - + // Getting PE header offset before we go any further.. fseek(pe, 0x3C, SEEK_SET); uint32_t peOffset = get32BitFromPE(pe); + // PE size + fseek(pe, peOffset + 0x50, SEEK_SET); + peData->size = get32BitFromPE(pe); + // Base address fseek(pe, peOffset + 0x34, SEEK_SET); peData->baseAddr = get32BitFromPE(pe); diff --git a/src/main.c b/src/main.c index f22be2a..38fd46f 100644 --- a/src/main.c +++ b/src/main.c @@ -102,7 +102,7 @@ int main(int argc, char **argv) free(xexfilePath); } - infoPrint("ERROR: Basefile input expected but not found. Aborting."); + printf("%s ERROR: Basefile input expected but not found. Aborting.", PRINT_STEM); return -1; } else if(!gotOutput) @@ -112,7 +112,7 @@ int main(int argc, char **argv) free(basefilePath); } - infoPrint("ERROR: Xexfile output expected but not found. Aborting."); + printf("%s ERROR: Xexfile output expected but not found. Aborting.", PRINT_STEM); return -1; } @@ -132,7 +132,7 @@ int main(int argc, char **argv) if(!validatePE(pe)) { - infoPrint("ERROR: Basefile is not Xbox 360 PE. Aborting."); + printf("%s ERROR: Basefile is not Xbox 360 PE. Aborting.", PRINT_STEM); fclose(pe); fclose(xex); return -1; @@ -140,31 +140,31 @@ int main(int argc, char **argv) if(getHdrData(pe, &peData, 0) != 0) { - infoPrint("ERROR: Unknown error in data retrieval from basefile. Aborting."); + printf("%s ERROR: Unknown error in data retrieval from basefile. Aborting.", PRINT_STEM); fclose(pe); fclose(xex); return -1; } // TEMPORARY: READ IN IMPORT HEADER DATA - FILE *importData = fopen("./import.bin", "r"); - - struct stat importStat; - fstat(fileno(importData), &importStat); - uint32_t importLen = importStat.st_size; - - fread(&(optHeaders.importLibraries.size), sizeof(uint8_t), 4, importData); - -#ifdef LITTLE_ENDIAN_SYSTEM - optHeaders.importLibraries.size = ntohl(optHeaders.importLibraries.size); -#endif +// FILE *importData = fopen("./import.bin", "r"); +// +// struct stat importStat; +// fstat(fileno(importData), &importStat); +// uint32_t importLen = importStat.st_size; +// +// fread(&(optHeaders.importLibraries.size), sizeof(uint8_t), 4, importData); +// +//#ifdef LITTLE_ENDIAN_SYSTEM +// optHeaders.importLibraries.size = ntohl(optHeaders.importLibraries.size); +//#endif - optHeaders.importLibraries.data = malloc(importLen - 0x4 * sizeof(uint8_t)); - fread(optHeaders.importLibraries.data, sizeof(uint8_t), importLen - 0x4, importData); + //optHeaders.importLibraries.data = malloc(importLen - 0x4 * sizeof(uint8_t)); + //fread(optHeaders.importLibraries.data, sizeof(uint8_t), importLen - 0x4, importData); // Setting final XEX data structs setXEXHeader(&xexHeader); - setSecInfoHeader(&secInfoHeader, &peData, 0x823DFC64); // TEMP EXPORT TABLE ADDR + setSecInfoHeader(&secInfoHeader, &peData); setPageDescriptors(pe, &peData, &secInfoHeader); setOptHeaders(&secInfoHeader, &peData, &optHeaderEntries, &optHeaders); @@ -174,19 +174,19 @@ int main(int argc, char **argv) // Write out all of the XEX data to file if(writeXEX(&xexHeader, &optHeaderEntries, &secInfoHeader, &optHeaders, &offsets, pe, xex) != 0) { - infoPrint("ERROR: Unknown error in XEX write routine. Aborting."); + printf("%s ERROR: Unknown error in XEX write routine. Aborting.", PRINT_STEM); fclose(pe); fclose(xex); return -1; } - free(optHeaders.importLibraries.data); + //free(optHeaders.importLibraries.data); // Final pass (sets & writes header hash) setHeaderSha1(xex); // TEMPORARY: Hashing will be moved to earlier on when imports are implemented - setImportsSha1(xex); + //setImportsSha1(xex); fclose(pe); fclose(xex); diff --git a/src/placer/placer.c b/src/placer/placer.c index e235ef7..4d1685b 100644 --- a/src/placer/placer.c +++ b/src/placer/placer.c @@ -91,7 +91,7 @@ void placeStructs(struct offsets *offsets, struct xexHeader *xexHeader, struct o struct importLibIdcs importLibIdcs; uint32_t importLibsIdx; // Entry in opt header entries of import libs setOptHeaderOffsets(offsets, optHeaderEntries, optHeaders, ¤tOffset, &importLibIdcs); - currentOffset += optHeaders->importLibraries.size; // Reserving bytes for imports + //currentOffset += optHeaders->importLibraries.size; // Reserving bytes for imports // PE basefile currentOffset = getNextAligned(currentOffset, 0x1000); // 4KiB alignment for basefile @@ -99,6 +99,6 @@ void placeStructs(struct offsets *offsets, struct xexHeader *xexHeader, struct o xexHeader->peOffset = currentOffset; // Imports, the end of this header is aligned to the start of the basefile, so they are a special case - offsets->optHeaders[importLibIdcs.header] = offsets->basefile - optHeaders->importLibraries.size; - optHeaderEntries->optHeaderEntry[importLibIdcs.entry].dataOrOffset = offsets->optHeaders[importLibIdcs.header]; + //offsets->optHeaders[importLibIdcs.header] = offsets->basefile - optHeaders->importLibraries.size; + //optHeaderEntries->optHeaderEntry[importLibIdcs.entry].dataOrOffset = offsets->optHeaders[importLibIdcs.header]; } diff --git a/src/setdata/optheaders.c b/src/setdata/optheaders.c index d19db6f..6011d9f 100644 --- a/src/setdata/optheaders.c +++ b/src/setdata/optheaders.c @@ -49,7 +49,7 @@ void setSysFlags(uint32_t *flags) void setOptHeaders(struct secInfoHeader *secInfoHeader, struct peData *peData, struct optHeaderEntries *optHeaderEntries, struct optHeaders *optHeaders) { // TODO: Dynamically select optional headers to use, instead of hard-coding - optHeaderEntries->count = 5; + optHeaderEntries->count = 4; optHeaderEntries->optHeaderEntry = calloc(5, sizeof(struct optHeaderEntry)); // First optional header (basefile format) @@ -61,13 +61,13 @@ void setOptHeaders(struct secInfoHeader *secInfoHeader, struct peData *peData, s optHeaderEntries->optHeaderEntry[1].dataOrOffset = secInfoHeader->baseAddr + peData->entryPoint; // Third optional header (import libs) - optHeaderEntries->optHeaderEntry[2].id = XEX_OPT_ID_IMPORT_LIBS; + //optHeaderEntries->optHeaderEntry[2].id = XEX_OPT_ID_IMPORT_LIBS; // Fourth optional header (tls info) - optHeaderEntries->optHeaderEntry[3].id = XEX_OPT_ID_TLS_INFO; + optHeaderEntries->optHeaderEntry[2].id = XEX_OPT_ID_TLS_INFO; setTLSInfo(&(optHeaders->tlsInfo)); // Fifth optional header (system flags) - optHeaderEntries->optHeaderEntry[4].id = XEX_OPT_ID_SYS_FLAGS; - setSysFlags(&(optHeaderEntries->optHeaderEntry[4].dataOrOffset)); + optHeaderEntries->optHeaderEntry[3].id = XEX_OPT_ID_SYS_FLAGS; + setSysFlags(&(optHeaderEntries->optHeaderEntry[3].dataOrOffset)); } diff --git a/src/setdata/populateheaders.c b/src/setdata/populateheaders.c index 5cedbda..9956f3e 100644 --- a/src/setdata/populateheaders.c +++ b/src/setdata/populateheaders.c @@ -23,10 +23,10 @@ void setXEXHeader(struct xexHeader *xexHeader) // Writing data into XEX header. strcpy(xexHeader->magic, "XEX2"); // Magic xexHeader->moduleFlags = XEX_MOD_FLAG_TITLE; // Hard-coding until more options supported - xexHeader->optHeaderCount = 0x5; // Hard-coding until more optional headers supported, then maybe it can be determined dynamically. + xexHeader->optHeaderCount = 0x4; // Hard-coding until more optional headers supported, then maybe it can be determined dynamically. } -void setSecInfoHeader(struct secInfoHeader *secInfoHeader, struct peData *peData, uint32_t TEMPEXPORTADDR) +void setSecInfoHeader(struct secInfoHeader *secInfoHeader, struct peData *peData) { // Getting page size, if base address is >= 0x90000000 4KiB pages are used, else 64KiB. bool smallPages = peData->baseAddr < 0x90000000 ? false : true; @@ -43,7 +43,8 @@ void setSecInfoHeader(struct secInfoHeader *secInfoHeader, struct peData *peData secInfoHeader->baseAddr = peData->baseAddr; memset(secInfoHeader->mediaID, 0, sizeof(secInfoHeader->mediaID)); // Null media ID memset(secInfoHeader->aesKey, 0, sizeof(secInfoHeader->aesKey)); // No encryption, null AES key - secInfoHeader->exportTableAddr = TEMPEXPORTADDR; + //secInfoHeader->exportTableAddr = TEMPEXPORTADDR; + secInfoHeader->exportTableAddr = 0; secInfoHeader->gameRegion = XEX_REG_FLAG_REGION_FREE; secInfoHeader->mediaTypes = 0xFFFFFFFF; // All flags set, can load from any type. secInfoHeader->pageDescCount = secInfoHeader->peSize / ((smallPages ? 4 : 64) * 1024); // Number of page descriptors following security info (same number of pages) diff --git a/src/setdata/populateheaders.h b/src/setdata/populateheaders.h index 4fab65c..2996e0b 100644 --- a/src/setdata/populateheaders.h +++ b/src/setdata/populateheaders.h @@ -22,4 +22,4 @@ #include "../common/datastorage.h" void setXEXHeader(struct xexHeader *xexHeader); -void setSecInfoHeader(struct secInfoHeader *secInfoHeader, struct peData *peData, uint32_t TEMPEXPORTADDR); +void setSecInfoHeader(struct secInfoHeader *secInfoHeader, struct peData *peData);