Merge noimportexport into main #1
8 changed files with 38 additions and 58 deletions
2
build.sh
2
build.sh
|
@ -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
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
42
src/main.c
42
src/main.c
|
@ -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;
|
||||||
|
// 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
|
||||||
|
|
||||||
struct stat importStat;
|
//optHeaders.importLibraries.data = malloc(importLen - 0x4 * sizeof(uint8_t));
|
||||||
fstat(fileno(importData), &importStat);
|
//fread(optHeaders.importLibraries.data, sizeof(uint8_t), importLen - 0x4, importData);
|
||||||
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);
|
|
||||||
|
|
||||||
// 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);
|
||||||
|
|
|
@ -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, ¤tOffset, &importLibIdcs);
|
setOptHeaderOffsets(offsets, optHeaderEntries, optHeaders, ¤tOffset, &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];
|
||||||
}
|
}
|
||||||
|
|
|
@ -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));
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue