Merge noimportexport into main #1
9 changed files with 43 additions and 63 deletions
2
build.sh
2
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
|
||||
|
|
|
@ -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 VERSION_STRING "SynthXEX v0.0.1"
|
||||
|
||||
// Print constants
|
||||
#define PRINT_STEM "SynthXEX>"
|
||||
|
||||
// Return values
|
||||
#define SUCCESS 0
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
42
src/main.c
42
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);
|
||||
|
|
|
@ -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];
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue