2019-03-21 22:54:06 +01:00
|
|
|
#include <sys/types.h>
|
|
|
|
#include <sys/stat.h>
|
|
|
|
#include <fcntl.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
|
2022-03-20 20:45:51 +01:00
|
|
|
#include <fxgxa.h>
|
2019-03-21 22:54:06 +01:00
|
|
|
|
|
|
|
/* invert_header(): Bit-invert a standard header
|
|
|
|
Part of the header is stored inverted in files for obfuscation purposes. */
|
2022-03-20 20:45:51 +01:00
|
|
|
static void invert_header(void *gxa)
|
2019-03-21 22:54:06 +01:00
|
|
|
{
|
2022-03-20 20:45:51 +01:00
|
|
|
uint8_t *data = gxa;
|
2019-03-21 22:54:06 +01:00
|
|
|
for(size_t i = 0; i < 0x20; i++) data[i] = ~data[i];
|
|
|
|
}
|
|
|
|
|
|
|
|
#define fail(msg, ...) { \
|
|
|
|
fprintf(stderr, "error: " msg ": %m\n", ##__VA_ARGS__); \
|
|
|
|
close(fd); \
|
|
|
|
free(data); \
|
|
|
|
return NULL; \
|
|
|
|
}
|
|
|
|
|
|
|
|
/* load(): Fully load a file into memory
|
|
|
|
Allocates a buffer with @prepend leading bytes initialized to zero. */
|
2022-03-20 20:45:51 +01:00
|
|
|
static void *load(const char *filename, size_t *size, int header, int footer)
|
2019-03-21 22:54:06 +01:00
|
|
|
{
|
|
|
|
int fd;
|
|
|
|
struct stat statbuf;
|
|
|
|
void *data = NULL;
|
|
|
|
size_t filesize;
|
|
|
|
|
|
|
|
fd = open(filename, O_RDONLY);
|
|
|
|
if(fd < 0) fail("cannot open %s", filename);
|
|
|
|
|
|
|
|
int x = fstat(fd, &statbuf);
|
|
|
|
if(x > 0) fail("cannot stat %s", filename);
|
|
|
|
|
|
|
|
filesize = statbuf.st_size;
|
2022-03-20 20:45:51 +01:00
|
|
|
data = malloc(header + filesize + footer);
|
2019-03-21 22:54:06 +01:00
|
|
|
if(!data) fail("cannot load %s", filename);
|
|
|
|
|
|
|
|
size_t remaining = filesize;
|
|
|
|
while(remaining > 0)
|
|
|
|
{
|
2022-03-20 20:45:51 +01:00
|
|
|
size_t offset = header + filesize - remaining;
|
2019-03-21 22:54:06 +01:00
|
|
|
ssize_t y = read(fd, data + offset, remaining);
|
|
|
|
|
|
|
|
if(y < 0) fail("cannot read from %s", filename);
|
|
|
|
remaining -= y;
|
|
|
|
}
|
|
|
|
close(fd);
|
|
|
|
|
2022-03-20 20:45:51 +01:00
|
|
|
memset(data, 0, header);
|
|
|
|
memset(data + header + filesize, 0, footer);
|
2019-03-21 22:54:06 +01:00
|
|
|
|
2022-03-20 20:45:51 +01:00
|
|
|
if(size) *size = header + filesize + footer;
|
2019-03-21 22:54:06 +01:00
|
|
|
return data;
|
|
|
|
}
|
|
|
|
|
2022-03-20 20:45:51 +01:00
|
|
|
void *load_gxa(const char *filename, size_t *size)
|
2019-03-21 22:54:06 +01:00
|
|
|
{
|
2022-03-20 20:45:51 +01:00
|
|
|
void *ret = load(filename, size, 0, 0);
|
2019-03-21 22:54:06 +01:00
|
|
|
if(ret) invert_header(ret);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2022-03-20 20:45:51 +01:00
|
|
|
void *load_binary(const char *filename, size_t *size, int header, int footer)
|
2019-03-21 22:54:06 +01:00
|
|
|
{
|
2022-03-20 20:45:51 +01:00
|
|
|
void *ret = load(filename, size, header, footer);
|
|
|
|
if(ret) invert_header(ret);
|
2019-03-21 22:54:06 +01:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
#undef fail
|
|
|
|
#define fail(msg, ...) { \
|
|
|
|
fprintf(stderr, "error: " msg ": %m\n", ##__VA_ARGS__); \
|
2022-03-20 20:45:51 +01:00
|
|
|
rc = 1; \
|
|
|
|
goto end; \
|
2019-03-21 22:54:06 +01:00
|
|
|
}
|
|
|
|
|
2022-03-20 20:45:51 +01:00
|
|
|
int save_gxa(const char *filename, void *gxa, size_t size)
|
2019-03-21 22:54:06 +01:00
|
|
|
{
|
|
|
|
/* Invert header before saving */
|
2022-03-20 20:45:51 +01:00
|
|
|
invert_header(gxa);
|
2019-03-21 22:54:06 +01:00
|
|
|
|
2022-03-20 20:45:51 +01:00
|
|
|
int rc = 0;
|
2019-03-21 22:54:06 +01:00
|
|
|
int fd = creat(filename, 0644);
|
|
|
|
if(fd < 0) fail("cannot open %s", filename);
|
|
|
|
|
|
|
|
ssize_t status;
|
|
|
|
size_t written = 0;
|
|
|
|
while(written < size)
|
|
|
|
{
|
2022-03-20 20:45:51 +01:00
|
|
|
status = write(fd, gxa + written, size - written);
|
2019-03-21 22:54:06 +01:00
|
|
|
if(status < 0) fail("cannot write to %s", filename);
|
|
|
|
written += status;
|
|
|
|
}
|
|
|
|
|
2022-03-20 20:45:51 +01:00
|
|
|
end:
|
2019-03-21 22:54:06 +01:00
|
|
|
/* Before returning, re-invert header for further use */
|
2022-03-20 20:45:51 +01:00
|
|
|
if(fd >= 0) close(fd);
|
|
|
|
invert_header(gxa);
|
|
|
|
return rc;
|
2019-03-21 22:54:06 +01:00
|
|
|
}
|