Code: Select all
#include "pshn-img.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <math.h>
//#ifdef WORDS_BIGENDIAN
// Swap the bytes of an int for big-endian machines
static int swap_int(int n)
{
return ((n>>24)&0xff)|((n>>8)&0xff00)|((n<<8)&0xff0000)|((n<<24)&0xff000000);
}
//#endif
int fg;
/*
In future updates, the sections will have there own headers for the title, version, and data count.
and within the future in version 1.05, everything such as file sections, and plan sections will have there own header
*/
char *hexdec(char *str){
char *string = malloc(sizeof(str));
int i;
for(i=0;i<strlen(str);i++){
sprintf(string, "%02x", str[i]);
}
return string;
};
int verifyHeader(void){
char signature[]={0x50, 0x53, 0x48, 0x49, 0x4D, 0x47};
if(!memcmp(header.signature, signature, 6)){
return 1;
}
return 0;
}
void swapints(int *array, int ndx1, int ndx2)
{
int temp = array[ndx1];
array[ndx1] = array[ndx2];
array[ndx2] = temp;
}
char *crypt(const char *pszText, int iTextLen, const char *pszKey)
{
char *cipher; /* Output buffer */
int a, b, i=0, j=0, k; /* Ambiguously named counters */
int ilen; /* Length of a string */
int sbox[256]; /* Encryption array */
int key[256]; /* Numeric key values */
ilen = strlen(pszKey);
for (a=0; a < 256; a++)
{
key[a] = pszKey[a % ilen];
sbox[a] = a;
}
for (a=0, b=0; a < 256; a++)
{
b = (b + sbox[a] + key[a]) % 256;
swapints(sbox, a, b);
}
cipher = (char *)malloc(iTextLen);
for (a=0; a < iTextLen; a++)
{
i = (i + 1) % 256;
j = (j + sbox[i]) % 256;
swapints(sbox, i, j);
k = sbox[(sbox[i] + sbox[j]) % 256];
cipher[a] = pszText[a] ^ k;
}
return cipher;
}
char * triplecrypt(char *data){
char *string = malloc(sizeof(data));
string = crypt(data, strlen(data), header.keyset_1);
string = crypt(string, strlen(data), header.keyset_2);
string = crypt(string, strlen(data), header.keyset_3);
return string;
}
char * triplecryptReverse(char *data){
char *string = malloc(sizeof(data));
string = crypt(data, strlen(data), header.keyset_3);
string = crypt(string, strlen(data), header.keyset_2);
string = crypt(string, strlen(data), header.keyset_1);
return string;
}
//#ifdef PC_ENABLE
int pshnInit(FILE *fd, int flag){
switch(flag){
case 0://read
fread(&header, 1, sizeof(header), fd);
return verifyHeader();
case 1://write
fg = 1;
//memset(&header, 0, sizeof(header));
char signature[]={0x50, 0x53, 0x48, 0x49, 0x4D, 0x47};
int i;
for(i=0;i<6;i++){
header.signature[i] = signature[i];
}
header.version[0] = 0x01;
return 1;
break;
}
return 0;
}
int pshnAddOptional(FILE *fd, char firmware[4], char title[32], int mode,int key, int seed, int bytecode, int compress){
memcpy(header.firmware, firmware, 4);
memcpy(header.title, title, strlen(title));
header.mode = mode;
if(key == 1){
header.key = 1;
pshnGenerateKeyset(seed+0x4C, header.keyset_1);
pshnGenerateKeyset(seed+0x3C, header.keyset_2);
pshnGenerateKeyset(seed+0x2C, header.keyset_3);
}
header.bytecode = bytecode; //0 = nulll for now - bytecode use to execute commands built with your library
header.compress = compress; //0 = null for now - compress use to compress files to a smaller rate for easyier storage
fwrite(&header, 1, sizeof(header), fd);
return 0;
}
int pshnGenerateKeyset(int seed, char key[128]){
srand(seed+128);
int i;
for(i=0;i<128;i++){
key[i] = rand() % 255;
key[i] ^= seed & 128;
}
return 0;
}
int pshnAddSection(FILE *fd, char *section){
int secmd = 0x01;
fseek(fd, 1, SEEK_CUR);
fwrite(&secmd, 1, 4, fd);
char *sC = malloc(sizeof(section));
sC = crypt(section, strlen(section), header.keyset_1);
sC = crypt(sC, strlen(sC), header.keyset_2);
sC = crypt(sC, strlen(sC), header.keyset_3);
int len = strlen(sC);
fwrite(&len, 1, 4, fd);
fwrite(sC, 1, len, fd);
return len;
}
int pshnAddFile(FILE *fd, char *file){
int filecmd = 0x03;
fseek(fd, 1, SEEK_CUR);
fwrite(&filecmd, 1, 4, fd);
int len = strlen(file);
fwrite(&len, 1, 4, fd);
fwrite(file,1, len, fd);
char *buf;
FILE *in = fopen(file, "rb");
fseek(in, 0, SEEK_END);
int size = ftell(in);
fseek(in, 0, SEEK_SET);
buf = malloc(size);
fread(buf, 1, size, in);
fclose(in);
fwrite(&size, 1, 4, fd);
buf = crypt(buf, size, header.keyset_3);
fwrite(buf, 1, size, fd);
int endsec = 0x04;
fwrite(&endsec, 1, 4, fd);
return 0;
}
int pshnLoadSection(FILE *fd){
int count = 0, cmd, len, size = 0;
char *buf;
if(ftell(fd) != 0){
do{
fseek(fd, 1, SEEK_CUR);
//cmd = 0;
fread(&cmd, 1, 4, fd);
if(cmd <= 5){
printf("Command 0x%02x found at offset 0x%02x\n", cmd, ftell(fd));
if(cmd == 0x01){
printf("Found section\n");
fread(&len, 1, 4, fd);
buf = malloc(len);
fread(buf, 1, len, fd);
section[count].section = triplecryptReverse(buf);
free(buf);
len = 0;
printf("Section Name: %s\n", section[count].section);
count += 1;
cmd = 0;
}
if(cmd == 0x03){
printf("Filename found\n");
fread(&len, 1, 4, fd);
section[count].filename = malloc(len);
fread(section[count].filename, 1, len, fd);
printf("Filename: %s\n", section[count].filename);
cmd = 0;
}
}
}while(ftell(fd) != 0 && cmd != 0xFFFFFFFF && cmd < 5);
printf("PSHN Section Reader Exits\n");
}
return 0;
}
int pshnTerm(FILE *fd){
if(fg == 1){
int end = 0xFFFFFFFF;
fwrite(&end, 1, 4, fd);
}
return fclose(fd);
}
Code: Select all
#include <stdio.h>
#define u8 unsigned char
#define u16 unsigned short
#define u32 unsigned int
struct {
char signature[6];//PSHIMG
char version[4];//1.00
char firmware[4];//5.00 fw or use 0x00000000 for using on any firmware
char title[32];//128 byte Title of the image (for the game/app)
int mode; //user = 0, kernel = 0x1000 (use for future purposes only)
int key;//0 for no encryption key, 1 for usage of encryption key (XOR)
//keysets for encryption/decryption purpose only (xor encryption for now)
char keyset_1[128];//keyset 1 - 128 bytes
char keyset_2[128];//keyset 2 - 128 bytes
char keyset_3[128];//keyset 3 - 128 bytes
u8 hash[20];//hash of the data after the header
u8 enHash[20];//hash that was encrypted via xor 3 times using all 3 keys (will be NULL if header.key = 0)
int bytecode;//enable bytecode to use a bytecode like formate to parse and execute with your own code (only on 1.01)
int compress;//enable compression using zlib. 1 enable, else dont (only on 1.01)
int size;//size of the data after the header;
} header;
struct section_data {
char *section;//use to verify what files go where
char *filename;
char *buf;
int size;
};
struct var {
char *variable;
char *content;
};
struct section_data section[];
struct var storage[];
int pshnInit(FILE *fd, int flag);
int pshnAddOptional(FILE *fd, char firmware[4], char title[128], int mode,int key, int seed, int bytecode, int compress);
int pshnGenerateKeyset(int seed, char key[128]);
int pshnAddSection(FILE *fd, char *section);
int pshnEndSection(FILE *fd);
int pshnAddFile(FILE *fd, char *file);
int pshnAddByteCode(char bytecode[4], int prem, int (*handler)(int arg[4], void *data));
// int pshnWriteByteCode(FILE *fd, char bytecode[4], int prem, int arg[4], void *data);
int pshnAddVariable(char *var, void *content);
int pshnLoadSection(FILE *fd);
int pshnTerm(FILE *fd);