home *** CD-ROM | disk | FTP | other *** search
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <stdint.h>
-
- uint32_t toBigEndian_word(uint32_t num)
- {
- uint32_t b0 = (num & 0x000000ff) << 24u;
- uint32_t b1 = (num & 0x0000ff00) << 8u;
- uint32_t b2 = (num & 0x00ff0000) >> 8u;
- uint32_t b3 = (num & 0xff000000) >> 24u;
-
- uint32_t res = b0 | b1 | b2 | b3;
- return res;
- }
-
- uint16_t toBigEndian_halfword(uint16_t num)
- {
- uint16_t b0 = (num & 0x000000ff) << 8u;
- uint16_t b1 = (num & 0x0000ff00) >> 8u;
-
- uint16_t res = b0 | b1;
- return res;
- }
- int lw(FILE * stream, int address, short offset)
- {
- fseek(stream, address + offset, SEEK_SET);
- int res;
- fread(&res, 1, 4, stream);
- return res;
- }
-
- unsigned char lbu(FILE * stream, int address, short offset)
- {
- fseek(stream, address + offset, SEEK_SET);
- unsigned char res;
- fread(&res, 1, 1, stream);
- return res;
- }
-
- unsigned short lhu(FILE * stream, int address, short offset)
- {
- fseek(stream, address + offset, SEEK_SET);
- unsigned short res;
- fread(&res, 1, 2, stream);
- return res;
- }
-
- void sw(FILE *stream, int address, short offset, int value)
- {
- fseek(stream, address + offset, SEEK_SET);
- fwrite(&value, 1, 4, stream);
- }
-
- void sb(FILE *stream, int address, short offset, char value)
- {
- fseek(stream, address + offset, SEEK_SET);
- fwrite(&value, 1, 1, stream);
- }
-
- void process_POF0(FILE * f, char filename[], int POF0_offset=0x1D2E0, int POF0_size=0x0288, bool is_little=true)
- {
- int at;
- int v1;
- int a0=POF0_offset; // The Rock's POF0
- int a1=POF0_size; // Size of POF0
- int a2=0x08; // YOBJ size + 4
- int a3; // Start of POF0 String
- int t0;
- int t1;
- int t2;
- int t3;
- int t4;
-
- FILE * yobj_file = f;
- char new_filename[255];
- strcpy(new_filename, filename);
- strcat(new_filename, ".decrypted");
- FILE * output_file = fopen(new_filename, "wb+");
-
- // Get size of yobj
- fseek(yobj_file, 0L, SEEK_END);
- int yobj_size = ftell(yobj_file);
-
- char * buffer = (char *) malloc(yobj_size);
- rewind(yobj_file);
- fread(buffer, 1, yobj_size, yobj_file);
-
- fseek(output_file, 0L, SEEK_SET);
-
- fwrite(buffer, 1, yobj_size, output_file);
-
- free(buffer);
-
- while (true)
- {
- t0 = a0 + a1;
- at = a0 < t0;
- if (!at)
- break;
- t1 = a2;
- a1 = 0x80;
- v1 = 0x40;
- a3 = 0xC0;
- t3 = lbu(output_file, a0, 0x00);
- while (true)
- {
- //printf("Offset: %.8X\n", a0);
- t2 = t3 & 0xC0;
- //printf("%.8X %.2X\n", a0, t3);
- if (t2 == a3)
- {
- unsigned short sp;
- sp = 0;
- //*(i+3) =t3;
- sp |= (t3 & 0xFF) << 24;
- // case 3
- t4 = lbu(output_file, a0, 0x03);
- t3 = lbu(output_file, a0, 0x02);
- t2 = lbu(output_file, a0, 0x01);
-
- //*(i+0)= t4;
- //*(i+1)= t3;
- //*(i+2)= t2;
- sp |= t4 & 0xFF;
- sp |= (t3 & 0xFF) << 8;
- sp |= (t2 & 0xFF) << 16;
- t2 = sp;
-
- if (!is_little)
- t2 = toBigEndian_word(t2);
- a0 += 4;
- t2 <<= 2;
- t2 >>= 2;
- t2 <<= 2;
- a2 += t2;
- t2 = lw(output_file, a2, 0x00);
- if (!is_little)
- t2 = toBigEndian_word(t2);
- t2 += t1;
- // little Endian
- if (!is_little)
- t2 = toBigEndian_word(t2);
- sw(output_file, a2, 0x00, t2);
- if (!is_little)
- t2 = toBigEndian_word(t2);
- }
- else if (t2 == a1)
- {
- // case 2
- t2 = lbu(output_file, a0, 0x01);
- unsigned short sp;
- sp = 0;
- //*(i+1)=t3;
- //*(i+0)=t2;
- sp |= (t3 & 0xFF) << 8;
- sp |= t2 & 0xFF;
- t2 = sp;
- if (!is_little)
- t2 = toBigEndian_halfword(t2);
-
- a0 += 2;
- t2 &= 0x3FFF;
- t2 <<= 2;
- a2 += t2;
- t2 = lw(output_file, a2, 0x00);
- if (!is_little)
- t2 = toBigEndian_word(t2);
- t2 += t1;
- // little Endian
- if (!is_little)
- t2 = toBigEndian_word(t2);
- sw(output_file, a2, 0x00, t2);
- if (!is_little)
- t2 = toBigEndian_word(t2);
- }
- else if (t2 == v1)
- {
- // case 1
-
- t2 = t3 & 0x3F;
-
- t2 <<= 2;
-
-
- a2 += t2;
-
- t2 = lw(output_file, a2, 0x00);
- if (!is_little)
- t2 = toBigEndian_word(t2);
- //printf("%.8X\n", t2);
- a0 += 1;
- t2 += t1;
-
- if (!is_little)
- t2 = toBigEndian_word(t2);
-
- sw(output_file, a2, 0x00, t2);
- if (!is_little)
- t2 = toBigEndian_word(t2);
- }
- else
- a0 += 1;
-
- // 0x0890D2B8
- t2 = a0 < t0;
- if (t2)
- {
- t3 = lbu(output_file, a0, 0x0);
- continue;
- }
- break;
- }
- break;
- }
-
-
- fclose(output_file);
- return;
-
- }
- int main(int argc, char * argv[])
- {
- char filename[255];
- int POF0_offset;
- int POF0_size;
- char byteorder[8];
- printf("POF0 decoder by eatrawmeat391\n");
-
- if (argc != 4)
- {
- printf("Usage: POF0.exe infile POF0_offset POF0_size");
- return 0;
- }
-
- strcpy(filename, argv[1]);
- POF0_offset = (int) strtol(argv[2], NULL, 16);
- POF0_size = (int) strtol(argv[3], NULL, 16);
- //strcpy(byteorder, argv[4]);
- bool is_little;
- //if (strcmpi(byteorder, "little") == 0)
- //is_little = true;
- //else
- //is_little = false;
- is_little = true;
- FILE * yobj_file = fopen(filename, "rb");
- if (!yobj_file)
- {
- printf("Cannot open this file.\n");
- return 0;
- }
- process_POF0(yobj_file, filename, POF0_offset, POF0_size, is_little);
- fclose(yobj_file);
-
- printf("POF0 successfully decoded, the file %s.decrypted has been created.\n");
- getchar();
- return 0;
- }
-