Merge noimportexport into main #1

Merged
Aiden-Isik merged 2 commits from noimportexport into main 2024-12-30 16:14:10 +00:00
9 changed files with 43 additions and 63 deletions

View file

@ -2,4 +2,4 @@
# TEMP BUILD SCRIPT # 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

View file

@ -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 <https://www.gnu.org/licenses/>.
#include "common.h"
void infoPrint(char *str)
{
printf("SynthXEX> %s\n", str);
}

View file

@ -29,6 +29,9 @@
#define COPYRIGHT "2024" #define COPYRIGHT "2024"
#define VERSION_STRING "SynthXEX v0.0.1" #define VERSION_STRING "SynthXEX v0.0.1"
// Print constants
#define PRINT_STEM "SynthXEX>"
// Return values // Return values
#define SUCCESS 0 #define SUCCESS 0

View file

@ -152,15 +152,15 @@ int getSectionRwxFlags(FILE *pe, struct sections *sections)
int getHdrData(FILE *pe, struct peData *peData, uint8_t flags) int getHdrData(FILE *pe, struct peData *peData, uint8_t flags)
{ {
// Get header data required for ANY XEX // 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.. // Getting PE header offset before we go any further..
fseek(pe, 0x3C, SEEK_SET); fseek(pe, 0x3C, SEEK_SET);
uint32_t peOffset = get32BitFromPE(pe); uint32_t peOffset = get32BitFromPE(pe);
// PE size
fseek(pe, peOffset + 0x50, SEEK_SET);
peData->size = get32BitFromPE(pe);
// Base address // Base address
fseek(pe, peOffset + 0x34, SEEK_SET); fseek(pe, peOffset + 0x34, SEEK_SET);
peData->baseAddr = get32BitFromPE(pe); peData->baseAddr = get32BitFromPE(pe);

View file

@ -102,7 +102,7 @@ int main(int argc, char **argv)
free(xexfilePath); 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; return -1;
} }
else if(!gotOutput) else if(!gotOutput)
@ -112,7 +112,7 @@ int main(int argc, char **argv)
free(basefilePath); 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; return -1;
} }
@ -132,7 +132,7 @@ int main(int argc, char **argv)
if(!validatePE(pe)) 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(pe);
fclose(xex); fclose(xex);
return -1; return -1;
@ -140,31 +140,31 @@ int main(int argc, char **argv)
if(getHdrData(pe, &peData, 0) != 0) 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(pe);
fclose(xex); fclose(xex);
return -1; return -1;
} }
// TEMPORARY: READ IN IMPORT HEADER DATA // TEMPORARY: READ IN IMPORT HEADER DATA
FILE *importData = fopen("./import.bin", "r"); // FILE *importData = fopen("./import.bin", "r");
//
struct stat importStat; // struct stat importStat;
fstat(fileno(importData), &importStat); // fstat(fileno(importData), &importStat);
uint32_t importLen = importStat.st_size; // uint32_t importLen = importStat.st_size;
//
fread(&(optHeaders.importLibraries.size), sizeof(uint8_t), 4, importData); // fread(&(optHeaders.importLibraries.size), sizeof(uint8_t), 4, importData);
//
#ifdef LITTLE_ENDIAN_SYSTEM //#ifdef LITTLE_ENDIAN_SYSTEM
optHeaders.importLibraries.size = ntohl(optHeaders.importLibraries.size); // optHeaders.importLibraries.size = ntohl(optHeaders.importLibraries.size);
#endif //#endif
optHeaders.importLibraries.data = malloc(importLen - 0x4 * sizeof(uint8_t)); //optHeaders.importLibraries.data = malloc(importLen - 0x4 * sizeof(uint8_t));
fread(optHeaders.importLibraries.data, sizeof(uint8_t), importLen - 0x4, importData); //fread(optHeaders.importLibraries.data, sizeof(uint8_t), importLen - 0x4, importData);
// Setting final XEX data structs // Setting final XEX data structs
setXEXHeader(&xexHeader); setXEXHeader(&xexHeader);
setSecInfoHeader(&secInfoHeader, &peData, 0x823DFC64); // TEMP EXPORT TABLE ADDR setSecInfoHeader(&secInfoHeader, &peData);
setPageDescriptors(pe, &peData, &secInfoHeader); setPageDescriptors(pe, &peData, &secInfoHeader);
setOptHeaders(&secInfoHeader, &peData, &optHeaderEntries, &optHeaders); setOptHeaders(&secInfoHeader, &peData, &optHeaderEntries, &optHeaders);
@ -174,19 +174,19 @@ int main(int argc, char **argv)
// Write out all of the XEX data to file // Write out all of the XEX data to file
if(writeXEX(&xexHeader, &optHeaderEntries, &secInfoHeader, &optHeaders, &offsets, pe, xex) != 0) 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(pe);
fclose(xex); fclose(xex);
return -1; return -1;
} }
free(optHeaders.importLibraries.data); //free(optHeaders.importLibraries.data);
// Final pass (sets & writes header hash) // Final pass (sets & writes header hash)
setHeaderSha1(xex); setHeaderSha1(xex);
// TEMPORARY: Hashing will be moved to earlier on when imports are implemented // TEMPORARY: Hashing will be moved to earlier on when imports are implemented
setImportsSha1(xex); //setImportsSha1(xex);
fclose(pe); fclose(pe);
fclose(xex); fclose(xex);

View file

@ -91,7 +91,7 @@ void placeStructs(struct offsets *offsets, struct xexHeader *xexHeader, struct o
struct importLibIdcs importLibIdcs; struct importLibIdcs importLibIdcs;
uint32_t importLibsIdx; // Entry in opt header entries of import libs uint32_t importLibsIdx; // Entry in opt header entries of import libs
setOptHeaderOffsets(offsets, optHeaderEntries, optHeaders, &currentOffset, &importLibIdcs); setOptHeaderOffsets(offsets, optHeaderEntries, optHeaders, &currentOffset, &importLibIdcs);
currentOffset += optHeaders->importLibraries.size; // Reserving bytes for imports //currentOffset += optHeaders->importLibraries.size; // Reserving bytes for imports
// PE basefile // PE basefile
currentOffset = getNextAligned(currentOffset, 0x1000); // 4KiB alignment for 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; xexHeader->peOffset = currentOffset;
// Imports, the end of this header is aligned to the start of the basefile, so they are a special case // 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; //offsets->optHeaders[importLibIdcs.header] = offsets->basefile - optHeaders->importLibraries.size;
optHeaderEntries->optHeaderEntry[importLibIdcs.entry].dataOrOffset = offsets->optHeaders[importLibIdcs.header]; //optHeaderEntries->optHeaderEntry[importLibIdcs.entry].dataOrOffset = offsets->optHeaders[importLibIdcs.header];
} }

View file

@ -49,7 +49,7 @@ void setSysFlags(uint32_t *flags)
void setOptHeaders(struct secInfoHeader *secInfoHeader, struct peData *peData, struct optHeaderEntries *optHeaderEntries, struct optHeaders *optHeaders) 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 // TODO: Dynamically select optional headers to use, instead of hard-coding
optHeaderEntries->count = 5; optHeaderEntries->count = 4;
optHeaderEntries->optHeaderEntry = calloc(5, sizeof(struct optHeaderEntry)); optHeaderEntries->optHeaderEntry = calloc(5, sizeof(struct optHeaderEntry));
// First optional header (basefile format) // 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; optHeaderEntries->optHeaderEntry[1].dataOrOffset = secInfoHeader->baseAddr + peData->entryPoint;
// Third optional header (import libs) // 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) // 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)); setTLSInfo(&(optHeaders->tlsInfo));
// Fifth optional header (system flags) // Fifth optional header (system flags)
optHeaderEntries->optHeaderEntry[4].id = XEX_OPT_ID_SYS_FLAGS; optHeaderEntries->optHeaderEntry[3].id = XEX_OPT_ID_SYS_FLAGS;
setSysFlags(&(optHeaderEntries->optHeaderEntry[4].dataOrOffset)); setSysFlags(&(optHeaderEntries->optHeaderEntry[3].dataOrOffset));
} }

View file

@ -23,10 +23,10 @@ void setXEXHeader(struct xexHeader *xexHeader)
// Writing data into XEX header. // Writing data into XEX header.
strcpy(xexHeader->magic, "XEX2"); // Magic strcpy(xexHeader->magic, "XEX2"); // Magic
xexHeader->moduleFlags = XEX_MOD_FLAG_TITLE; // Hard-coding until more options supported 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. // Getting page size, if base address is >= 0x90000000 4KiB pages are used, else 64KiB.
bool smallPages = peData->baseAddr < 0x90000000 ? false : true; bool smallPages = peData->baseAddr < 0x90000000 ? false : true;
@ -43,7 +43,8 @@ void setSecInfoHeader(struct secInfoHeader *secInfoHeader, struct peData *peData
secInfoHeader->baseAddr = peData->baseAddr; secInfoHeader->baseAddr = peData->baseAddr;
memset(secInfoHeader->mediaID, 0, sizeof(secInfoHeader->mediaID)); // Null media ID memset(secInfoHeader->mediaID, 0, sizeof(secInfoHeader->mediaID)); // Null media ID
memset(secInfoHeader->aesKey, 0, sizeof(secInfoHeader->aesKey)); // No encryption, null AES key 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->gameRegion = XEX_REG_FLAG_REGION_FREE;
secInfoHeader->mediaTypes = 0xFFFFFFFF; // All flags set, can load from any type. 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) secInfoHeader->pageDescCount = secInfoHeader->peSize / ((smallPages ? 4 : 64) * 1024); // Number of page descriptors following security info (same number of pages)

View file

@ -22,4 +22,4 @@
#include "../common/datastorage.h" #include "../common/datastorage.h"
void setXEXHeader(struct xexHeader *xexHeader); void setXEXHeader(struct xexHeader *xexHeader);
void setSecInfoHeader(struct secInfoHeader *secInfoHeader, struct peData *peData, uint32_t TEMPEXPORTADDR); void setSecInfoHeader(struct secInfoHeader *secInfoHeader, struct peData *peData);